diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml
deleted file mode 100644
index dd08457b..00000000
--- a/.github/FUNDING.yml
+++ /dev/null
@@ -1,13 +0,0 @@
-# These are supported funding model platforms
-
-github: [mccoderpy] # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
-patreon: # Replace with a single Patreon username
-open_collective: # Replace with a single Open Collective username
-ko_fi: # Replace with a single Ko-fi username
-tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
-community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
-liberapay: # Replace with a single Liberapay username
-issuehunt: # Replace with a single IssueHunt username
-otechie: # Replace with a single Otechie username
-lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry
-custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']
diff --git a/.github/ISSUE_TEMPLATE/ISSUE_TEMPLATE.yml b/.github/ISSUE_TEMPLATE/BUG_REPORT.yaml
similarity index 97%
rename from .github/ISSUE_TEMPLATE/ISSUE_TEMPLATE.yml
rename to .github/ISSUE_TEMPLATE/BUG_REPORT.yaml
index d9412993..a3ef121a 100644
--- a/.github/ISSUE_TEMPLATE/ISSUE_TEMPLATE.yml
+++ b/.github/ISSUE_TEMPLATE/BUG_REPORT.yaml
@@ -39,7 +39,7 @@ body:
   - type: input
     id: python-version
     attributes:
-      label: The Python version you are using.
+      label: The Python verion you are using.
       placeholder: Python v3.8.10-final
     validations:
       required: true
diff --git a/.github/ISSUE_TEMPLATE/FEATURE_REQUEST.yml b/.github/ISSUE_TEMPLATE/FEATURE_REQUEST.yml
deleted file mode 100644
index f4cfd57d..00000000
--- a/.github/ISSUE_TEMPLATE/FEATURE_REQUEST.yml
+++ /dev/null
@@ -1,51 +0,0 @@
-name: Feature Request
-description: Suggest a feature that should be added to discord4py
-title: "[Feature Request]:"
-labels: ["feature request"]
-assignees: ["mccoderpy"]
-body:
-  - type: input
-    attributes:
-      label: Summary
-      description: >
-        A short summary of what your feature request is about.
-    validations:
-      required: true
-  - type: dropdown
-    attributes:
-      multiple: false
-      label: What is the feature request for?
-      options:
-        - The core library
-        - discord.ext.commands
-        - discord.ext.tasks
-        - The documentation
-    validations:
-      required: true
-  - type: textarea
-    attributes:
-      label: The Problem
-      description: >
-        What problem is your feature trying to solve?
-        What becomes easier or possible when this feature is implemented?
-    validations:
-      required: true
-  - type: textarea
-    attributes:
-      label: The Ideal Solution
-      description: >
-        What is your ideal solution to the problem?
-        What would you like this feature to do?
-    validations:
-      required: true
-  - type: textarea
-    attributes:
-      label: The Current Solution
-      description: >
-        What is the current solution to the problem, if any?
-    validations:
-      required: false
-  - type: textarea
-    attributes:
-      label: Additional Context
-      description: If there is anything else to say, please do so here.
diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml
deleted file mode 100644
index 4195b6c7..00000000
--- a/.github/workflows/codeql-analysis.yml
+++ /dev/null
@@ -1,74 +0,0 @@
-# For most projects, this workflow file will not need changing; you simply need
-# to commit it to your repository.
-#
-# You may wish to alter this file to override the set of languages analyzed,
-# or to provide custom queries or build logic.
-#
-# ******** NOTE ********
-# We have attempted to detect the languages in your repository. Please check
-# the `language` matrix defined below to confirm you have the correct set of
-# supported CodeQL languages.
-#
-name: "CodeQL"
-
-on:
-  push:
-    branches: [ main ]
-  pull_request:
-    # The branches below must be a subset of the branches above
-    branches: [ main ]
-  schedule:
-    - cron: '35 9 * * 3'
-
-jobs:
-  analyze:
-    name: Analyze
-    runs-on: ubuntu-latest
-    permissions:
-      actions: read
-      contents: read
-      security-events: write
-
-    strategy:
-      fail-fast: false
-      matrix:
-        language: [ 'python' ]
-        # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ]
-        # Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support
-
-    steps:
-    - name: Checkout repository
-      uses: actions/checkout@v3
-
-    # Initializes the CodeQL tools for scanning.
-    - name: Initialize CodeQL
-      uses: github/codeql-action/init@v2
-      with:
-        languages: ${{ matrix.language }}
-        # If you wish to specify custom queries, you can do so here or in a config file.
-        # By default, queries listed here will override any specified in a config file.
-        # Prefix the list here with "+" to use these queries and those in the config file.
-        
-        # Details on CodeQL's query packs refer to : https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs
-        # queries: security-extended,security-and-quality
-
-        
-    # Autobuild attempts to build any compiled languages  (C/C++, C#, or Java).
-    # If this step fails, then you should remove it and run the build manually (see below)
-    - name: Autobuild
-      uses: github/codeql-action/autobuild@v2
-
-    # ℹ️ Command-line programs to run using the OS shell.
-    # 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
-
-    #   If the Autobuild fails above, remove it and uncomment the following three lines. 
-    #   modify them (or add more) to build your code if your project, please refer to the EXAMPLE below for guidance.
-
-    # - run: |
-    #   echo "Run, Build Application using script"
-    #   ./location_of_script_within_repo/buildscript.sh
-
-    - name: Perform CodeQL Analysis
-      uses: github/codeql-action/analyze@v2
-    - name: Setup Python
-      uses: actions/setup-python@v3.1.2
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 00000000..07d7cba1
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,19 @@
+todo.md
+test.py
+/local-tests/
+voice_test.py
+main-api.py
+cprint.py
+/cogs/
+/data/
+/exportToHTML/
+/dist/
+/docs/_build/
+./discord.py_message_components.egg-info
+/build/
+.idea
+__pycache__
+*.pyc
+# Default ignored files
+/shelf/
+workspace.xml
\ No newline at end of file
diff --git a/.sourcery.yaml b/.sourcery.yaml
new file mode 100644
index 00000000..43bb10a5
--- /dev/null
+++ b/.sourcery.yaml
@@ -0,0 +1,3 @@
+rule_settings:
+  disable:
+  - use-named-expression
diff --git a/LICENSE b/LICENSE
index bf85dba8..a5f0120f 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,21 +1,22 @@
-The MIT License (MIT)
-
-Copyright (c) 2015-2021 Rapptz & 2021-present mccoderpy
-
-Permission is hereby granted, free of charge, to any person obtaining a
-copy of this software and associated documentation files (the "Software"),
-to deal in the Software without restriction, including without limitation
-the rights to use, copy, modify, merge, publish, distribute, sublicense,
-and/or sell copies of the Software, and to permit persons to whom the
-Software is furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
-DEALINGS IN THE SOFTWARE.
+The MIT License (MIT)
+
+Copyright (c) 2015-2021 Rapptz & (c) 2021-present mccoderpy
+
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
\ No newline at end of file
diff --git a/MANIFEST.in b/MANIFEST.in
index 4362468c..a3b38e2b 100644
--- a/MANIFEST.in
+++ b/MANIFEST.in
@@ -1,6 +1,22 @@
-include README.rst
-include LICENSE.txt
-include discord/*
-include discord/bin/*.dll
-include discord/ext/commands/*
-include discord/ext/tasks/__init__.py
\ No newline at end of file
+include README.rst
+include LICENSE.txt
+include discord/*
+include discord/types/*
+include discord/oauth2/*
+include discord/bin/*.dll
+include discord/ext/commands/*
+include discord/ext/tasks/__init__.py
+
+prune .git
+prune docs
+prune examples
+prune tests
+exclude discord/bin/COPYING
+exclude .flake8
+exclude .gitignore
+exclude .pre-commit-config.yaml
+exclude .prettierrc
+exclude .readthedocs.yml
+exclude CHANGELOG.md
+exclude FUNDING.yml
+exclude requirements-dev.txt
\ No newline at end of file
diff --git a/README.rst b/README.rst
index e164d0d4..de887926 100644
--- a/README.rst
+++ b/README.rst
@@ -1,297 +1,641 @@
-.. |flag_ua| image:: https://mccoder-py-needs.to-sleep.xyz/r/ua.png
-
-|flag_ua| Welcome to discord.py-message-components'! |flag_ua|
-==============================================================
-
-.. figure:: https://cdn.discordapp.com/attachments/852872100073963532/854711446767796286/discord.py-message-components.png
-   :name: discord.py-message-components
-   :align: center
-   :alt: Name of the Project (discord.py-message-components)
-   
-   ..
-   .. image:: https://discord.com/api/guilds/852871920411475968/embed.png
-      :target: https://discord.gg/sb69muSqsg
-      :alt: Discord Server Invite
-
-   .. image:: https://img.shields.io/pypi/v/discord.py-message-components.svg
-      :target: https://pypi.python.org/pypi/discord.py-message-components
-      :alt: PyPI version info
-
-   .. image:: https://img.shields.io/pypi/pyversions/discord.py-message-components.svg
-      :target: https://pypi.python.org/pypi/discord.py-message-components
-      :alt: PyPI supported Python versions
-
-   .. image:: https://static.pepy.tech/personalized-badge/discord-py-message-components?period=total&units=international_system&left_color=grey&right_color=green&left_text=Downloads
-      :target: https://pepy.tech/project/discord.py-message-components
-      :alt: Total downloads for the project
-
-   .. image:: https://readthedocs.org/projects/discordpy-message-components/badge/?version=latest
-      :target: https://discordpy-message-components.readthedocs.io/en/latest/
-      :alt: Documentation Status
-
-   A "fork" of `discord.py <https://pypi.org/project/discord.py/1.7.3>`_ library made by `Rapptz <https://github.com/Rapptz>`_ with implemation of the `Discord-Message-Components <https://discord.com/developers/docs/interactions/message-components>`_ by `mccoderpy <https://github.com/mccoderpy/>`_ 
-
-+---------------------------------------------------------------------------------------------------------------------------------------------------+
-|                                                              **❗ℹIMPORTANTℹ❗**                                                                    |
-+===================================================================================================================================================+
-| This branch represents only the `PyPI <https://pypi.org>`_ version of this library,                                                               |
-| which is currently **not up to date** due to some (private) issues                                                                                |
-| (as soon as we have documented the new features and the developer branch is stable enough, this will be updated).                                 |
-|                                                                                                                                                   |
-| **To get the latest version with the newest features and bug(-fixes), please take a look at the** `developer <../../tree/developer>`_ **branch.** |
-+---------------------------------------------------------------------------------------------------------------------------------------------------+
-
-**NOTE:** 
-     This library will be further developed independently of discord.py.
-     New features are also implemented. It is not an extension!
-     The name only comes from the fact that the original purpose of the library was to add support for message components and we haven't found a better name yet. 
-
-.. figure:: https://github.com/mccoderpy/discord.py-message-components/raw/main/images/rtd-logo-wordmark-light.png
-   :name: discord.py-message-components documentation
-   :alt: Link to the documentation of discord.py-message-components
-   :align: center
-   :scale: 20%
-   :target: https://discordpy-message-components.readthedocs.io/en/latest/
-   
-   **Read the Documentation** `here <https://discordpy-message-components.readthedocs.io/en/latest/>`_
-
-You are in need of help or want to leave feedback?
-__________________________________________________
-
-Open a `issue <../../issues>`_/`pull request <../../pulls>`_, join the `support server <https://discord.gg/sb69muSqsg>`_ or send me a direct message on `Discord <https://discord.com/channels/@me>`_: ``mccuber04#2960``
-
-Installing
-__________
-
-**Python 3.5.3 or higher is required.**
-
-This library overwrites the original discord.py library (or any other that would be imported using `import discord`) so to be sure all will work fine
-first uninstall the original `discord.py <https://pypi.org/project/discord.py/1.7.3>`_ library if it is installed:
-
-.. code:: sh
-
-    # Linux/macOS
-    python3 -m pip uninstall discord.py
-
-    # Windows
-    py -3 -m pip uninstall discord.py
-
-Then install `this library <https://pypi.org/project/discord.py-message-components>`_ using:
-
-.. code:: sh
-
-    # Linux/macOS
-    python3 -m pip install -U discord.py-message-components
-
-    # Windows
-    py -3 -m pip install -U discord.py-message-components
-
-‼️To install it from the `developer branch <https://github.com/mccoderpy/discord.py-message-components/tree/developer>`_ of this library which is the **most up to date** and has **fewer bugs** use:
-
-.. code:: sh
-    
-    # Linux/macOS
-    python3 -m pip install -U git+https://github.com/mccoderpy/discord.py-message-components.git@developer
-    
-    # Windows
-    py -m pip install -U git+https://github.com/mccoderpy/discord.py-message-components.git@developer 
-
-Of course you nead to have git installed on your device. If you need help with this, take a look `here <https://github.com/git-guides/install-git>`_
-
-Examples
---------
-
-A command that sends you a message and edit it when you click a Button:
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-.. code-block:: python
-
-    import typing
-    import discord
-    from discord.ext import commands
-    from discord import ActionRow, Button, ButtonStyle
-
-    client = commands.Bot(command_prefix=commands.when_mentioned_or('.!'), intents=discord.Intents.all(), case_insensitive=True)
-
-    @client.command(name='buttons', description='sends you some nice Buttons')
-    async def buttons(ctx: commands.Context):
-        components = [ActionRow(Button(label='Option Nr.1',
-                                       custom_id='option1',
-                                       emoji="🆒",
-                                       style=ButtonStyle.green
-                                       ),
-                                Button(label='Option Nr.2',
-                                       custom_id='option2',
-                                       emoji="🆗",
-                                       style=ButtonStyle.blurple)),
-                      ActionRow(Button(label='A Other Row',
-                                       custom_id='sec_row_1st option',
-                                       style=ButtonStyle.red,
-                                       emoji='😀'),
-                                Button(url='https://www.youtube.com/watch?v=dQw4w9WgXcQ',
-                                       label="This is an Link",
-                                       style=ButtonStyle.url,
-                                       emoji='🎬'))
-                      ]
-        an_embed = discord.Embed(title='Here are some Button\'s', description='Choose an option', color=discord.Color.random())
-        msg = await ctx.send(embed=an_embed, components=components)
-
-        def _check(i: discord.Interaction, b):
-            return i.message == msg and i.member == ctx.author
-
-        interaction, button = await client.wait_for('button_click', check=_check)
-        button_id = button.custom_id
-
-        # This sends the Discord-API that the interaction has been received and is being "processed"
-        await interaction.defer()
-        # if this is not used and you also do not edit the message within 3 seconds as described below,
-        # Discord will indicate that the interaction has failed.
-
-        # If you use interaction.edit instead of interaction.message.edit, you do not have to defer the interaction,
-        # if your response does not last longer than 3 seconds.
-        await interaction.edit(embed=an_embed.add_field(name='Choose', value=f'Your Choose was `{button_id}`'),
-                               components=[components[0].disable_all_buttons(), components[1].disable_all_buttons()])
-
-        # The Discord API doesn't send an event when you press a link button so we can't "receive" that.
-
-
-    client.run('You Bot-Token here')
-
-
-Another more complex example where a small embed will be send; you can move a small white ⬜ with the buttons:
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-.. code-block:: python
-
-    pointers = []
-
-
-    class Pointer:
-        def __init__(self, guild: discord.Guild):
-            self.guild = guild
-            self._possition_x = 0
-            self._possition_y = 0
-
-        @property
-        def possition_x(self):
-            return self._possition_x
-
-        def set_x(self, x: int):
-            self._possition_x += x
-            return self._possition_x
-
-        @property
-        def possition_y(self):
-            return self._possition_y
-
-        def set_y(self, y: int):
-            self._possition_y += y
-            return self._possition_y
-
-
-    def get_pointer(obj: typing.Union[discord.Guild, int]):
-        if isinstance(obj, discord.Guild):
-            for p in pointers:
-                if p.guild.id == obj.id:
-                    return p
-            pointers.append(Pointer(obj))
-            return get_pointer(obj)
-
-        elif isinstance(obj, int):
-            for p in pointers:
-                if p.guild.id == obj:
-                    return p
-            guild = client.get_guild(obj)
-            if guild:
-                pointers.append(Pointer(guild))
-                return get_pointer(guild)
-            return None
-
-
-    def display(x: int, y: int):
-        base = [
-            [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
-            [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
-            [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
-            [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
-            [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
-            [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
-            [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
-            [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
-            [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
-            [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
-        ]
-        base[y][x] = 1
-        base.reverse()
-        return ''.join(f"\n{''.join([str(base[i][w]) for w in range(len(base[i]))]).replace('0', '⬛').replace('1', '⬜')}" for i in range(len(base)))
-
-
-    empty_button = discord.Button(style=discord.ButtonStyle.Secondary, label=" ", custom_id="empty", disabled=True)
-
-
-    def arrow_button():
-        return discord.Button(style=discord.ButtonStyle.Primary)
-
-
-    @client.command(name="start_game")
-    async def start_game(ctx: commands.Context):
-        pointer: Pointer = get_pointer(ctx.guild)
-        await ctx.send(embed=discord.Embed(title="Little Game",
-                                           description=display(x=0, y=0)),
-                       components=[discord.ActionRow(empty_button, arrow_button().set_label('↑').set_custom_id('up'), empty_button),
-                                   discord.ActionRow(arrow_button().update(disabled=True).set_label('←').set_custom_id('left').disable_if(pointer.possition_x <= 0),
-                                                     arrow_button().set_label('↓').set_custom_id('down').disable_if(pointer.possition_y <= 0),
-                                                     arrow_button().set_label('→').set_custom_id('right'))
-                                   ]
-                       )
-
-
-    @client.on_click()
-    async def up(i: discord.Interaction, button):
-        pointer: Pointer = get_pointer(interaction.guild)
-        pointer.set_y(1)
-        await i.edit(embed=discord.Embed(title="Little Game",
-                                         description=display(x=pointer.possition_x, y=pointer.possition_y)),
-                               components=[discord.ActionRow(empty_button, arrow_button().set_label('↑').set_custom_id('up').disable_if(pointer.possition_y >= 9), empty_button),
-                                           discord.ActionRow(arrow_button().set_label('←').set_custom_id('left').disable_if(pointer.possition_x <= 0),
-                                                             arrow_button().set_label('↓').set_custom_id('down'),
-                                                             arrow_button().set_label('→').set_custom_id('right').disable_if(pointer.possition_x >= 9))]
-                               )
-
-    @client.on_click()
-    async def down(i: discord.Interaction, button):
-        pointer: Pointer = get_pointer(interaction.guild)
-        pointer.set_y(-1)
-        await i.edit(embed=discord.Embed(title="Little Game",
-                                              description=display(x=pointer.possition_x, y=pointer.possition_y)),
-                               components=[discord.ActionRow(empty_button, arrow_button().set_label('↑').set_custom_id('up'), empty_button),
-                                           discord.ActionRow(arrow_button().set_label('←').set_custom_id('left').disable_if(pointer.possition_x <= 0),
-                                                             arrow_button().set_label('↓').set_custom_id('down').disable_if(pointer.possition_y <= 0),
-                                                             arrow_button().set_label('→').set_custom_id('right').disable_if(pointer.possition_x >= 9))]
-                               )
-
-    @client.on_click()
-    async def right(i: discord.Interaction, button):
-        pointer: Pointer = get_pointer(interaction.guild)
-        pointer.set_x(1)
-        await i.edit(embed=discord.Embed(title="Little Game",
-                                               description=display(x=pointer.possition_x, y=pointer.possition_y)),
-                               components=[discord.ActionRow(empty_button, arrow_button().set_label('↑').set_custom_id('up'), empty_button),
-                                           discord.ActionRow(arrow_button().set_label('←').set_custom_id('left'),
-                                                             arrow_button().set_label('↓').set_custom_id('down'),
-                                                             arrow_button().set_label('→').set_custom_id('right').disable_if(pointer.possition_x >= 9))]
-                               )
-
-    @client.on_click()
-    async def left(i: discord.Interaction, button):
-        pointer: Pointer = get_pointer(interaction.guild)
-        pointer.set_x(-1)
-        await i.edit(embed=discord.Embed(title="Little Game",
-                                               description=display(x=pointer.possition_x, y=pointer.possition_y)),
-                               components=[discord.ActionRow(empty_button, arrow_button().set_label('↑').set_custom_id('up'), empty_button),
-                                           discord.ActionRow(arrow_button().set_label('←').set_custom_id('left').disable_if(pointer.possition_x <= 0),
-                                                             arrow_button().set_label('↓').set_custom_id('down'),
-                                                             arrow_button().set_label('→').set_custom_id('right'))]
-                               )
-
-Please take a look at `the documentation <https://discordpy-message-components.readthedocs.io/en/latest/>`_ if you want to see more examples.
+.. |flag_ua| image:: ./images/flag_ua.png
+   :alt: Ukraine
+   :width: 30px
+   :height: 30px
+   :scale: 100%
+
+|flag_ua| Welcome to discord.py-message-components'! |flag_ua|
+==============================================================
+
+.. figure:: https://cdn.discordapp.com/attachments/852872100073963532/854711446767796286/discord.py-message-components.png
+   :name: discord.py-message-components
+   :align: center
+   :alt: Name of the Project (discord.py-message-components)
+
+   ..
+   .. image:: https://discord.com/api/guilds/852871920411475968/embed.png
+      :target: https://discord.gg/sb69muSqsg
+      :alt: Discord Server Invite
+
+   .. image:: https://img.shields.io/pypi/v/discord.py-message-components.svg
+      :target: https://pypi.python.org/pypi/discord.py-message-components
+      :alt: PyPI version info
+
+   .. image:: https://img.shields.io/pypi/pyversions/discord.py-message-components.svg
+      :target: https://pypi.python.org/pypi/discord.py-message-components
+      :alt: PyPI supported Python versions
+
+   .. image:: https://static.pepy.tech/personalized-badge/discord-py-message-components?period=total&units=international_system&left_color=grey&right_color=green&left_text=Downloads
+      :target: https://pepy.tech/project/discord.py-message-components
+      :alt: Total downloads for the project
+
+   .. image:: https://readthedocs.org/projects/discordpy-message-components/badge/?version=developer
+      :target: https://discordpy-message-components.readthedocs.io/en/developer/
+      :alt: Documentation Status
+
+   .. image:: https://img.shields.io/static/v1?label=Sponsor&message=%E2%9D%A4&logo=GitHub&color=%23fe8e86
+       :target: https://github.com/sponsors/mccoderpy
+       :alt: Sponsor button
+
+   A "fork" of `discord.py <https://pypi.org/project/discord.py/1.7.3>`_ library made by `Rapptz <https://github.com/Rapptz>`_ with implementation of the `Discord-Message-Components <https://discord.com/developers/docs/interactions/message-components>`_ & many other features by `mccoderpy <https://github.com/mccoderpy/>`_
+
+**NOTE:**
+     This library will be further developed independently of discord.py.
+     New features are also implemented. It's not an extension!
+     The name only comes from the fact that the original purpose of the library was to add support for message components and we haven't found a better one yet.
+
+**❗Some of the new features may be only documented in code currently❗**
+
+.. figure:: https://github.com/mccoderpy/discord.py-message-components/raw/main/images/rtd-logo-wordmark-light.png
+   :name: discord.py-message-components documentation
+   :alt: Link to the documentation of discord.py-message-components
+   :align: center
+   :scale: 20%
+   :target: https://discordpy-message-components.readthedocs.io/en/developer/
+
+   **Read the** `Documentation here <https://discordpy-message-components.readthedocs.io/en/developer/>`_
+
+You need help? Or have ideas/feedback?
+______________________________________
+
+Open a Issue/Pull request on `GitHub <https://github.com/mccoderpy/discord.py-message-components/pulls>`_, join the `support-server <https://discord.gg/sb69muSqsg>`_ or send me a direct-message on `Discord <https://discord.com/channels/@me>`_: ``mccuber04#2960``
+
+Installing
+__________
+
+**Python 3.5.3 or higher is required**
+
+This library overwrite the original `discord.py <https://pypi.org/project/discord.py/1.7.3>`_ library (or any other that would be imported using `import discord`) so to be sure all will work fine
+first uninstall the original discord.py Library if it is installed:
+
+.. code:: sh
+
+    # Linux/macOS
+    python3 -m pip uninstall discord.py
+
+    # Windows
+    py -3 -m pip uninstall discord.py
+
+Then install `this library <https://pypi.org/project/discord.py-message-components>`_ using:
+
+.. code:: sh
+
+    # Linux/macOS
+    python3 -m pip install -U discord.py-message-components
+
+    # Windows
+    py -3 -m pip install -U discord.py-message-components
+
+-----------------------------------------
+
+‼️To install it from the `developer-branch <https://github.com/mccoderpy/discord.py-message-components/tree/developer>`_ of this library which is the **most up to date** and has **fewer bugs** use:
+
+.. code:: sh
+
+    # Linux/macOS
+    python3 -m pip install -U git+https://github.com/mccoderpy/discord.py-message-components.git@developer
+
+    # Windows
+    py -m pip install -U git+https://github.com/mccoderpy/discord.py-message-components.git@developer 
+
+Of curse you need to have git installed on your device. If you need help with this take a look `here <https://github.com/git-guides/install-git>`_
+
+Examples
+________
+
+**ℹFor more examples take a look in the** `examples <https://github.com/mccoderpy/discord.py-message-components/tree/developer/examples>`_ **folder.**
+
+
+.. note::
+
+   All of these examples are not inside `Cogs <https://discordpy.readthedocs.io/en/v1.7.3/ext/commands/cogs.html>`_.
+   To use them inside of Cogs you must replace the ``client`` in the `decorators <https://wiki.python.org/moin/PythonDecorators#What_is_a_Decorator>`_ with ``commands.Cog``, set ``self`` as the first argument inside the functions and replace any use of ``client`` (except inside the decorators) with your bot variable.(e.g. ``self.bot`` or ``self.client``)
+
+Application Command Examples
+++++++++++++++++++++++++++++
+
+
++---------------------------------------------------------------------------------------------------+
+|   `sync_commands` of your `discord.Client` instance must bee set to `True`                        |
+|   Otherwise these commands will not be registered to discord and so not usable.                   |
++---------------------------------------------------------------------------------------------------+
+
+A Slash-Command(Chat-Input) which with that you can see the welcome screen of your guild and add new channels to it.
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. code-block:: python
+
+    import discord
+    from discord import SlashCommandOption as CommandOption, Permissions
+
+    client = discord.Client(sync_commands=True)
+
+    @client.slash_command(
+        base_name='welcome-screen',
+        base_desc='Shows or edit the welcome-screen of this guild.',
+        name='show',
+        guild_ids=[852871920411475968],
+        default_required_permissions=Permissions(manage_guild=True) # Only Members with Manage Guild Permission can use (see) this command and it sub-commands
+    )
+    async def show_welcome_screen(interaction: discord.ApplicationCommandInteraction):
+        """Shows the welcome-screen of this guild."""
+        w_c = await interaction.guild.welcome_screen()
+        if w_c:
+            wc_embed = discord.Embed(title=f'Welcome screen for {interaction.guild}',
+                                     description=f'```\n'
+                                                 f'{w_c.description or "No Description set"}\n'
+                                                 f'```')
+            for channel in w_c.welcome_channels:
+                wc_embed.add_field(name=channel.description,
+                                   value=f'{str(channel.emoji) if channel.emoji else ""} {channel.channel.mention}',
+                                   inline=False)
+            await interaction.respond(embed=wc_embed)
+        else:
+            await interaction.respond('This guild has no welcome-screen set.', hidden=True)
+
+    @client.slash_command(
+        base_name='welcome-screen',
+        base_desc='Shows or edit the welcome-screen of this guild.',
+        group_name='edit',
+        group_desc='Edit the welcome-screen of this guild.',
+        name='add-channel',
+        options=[
+            CommandOption(
+                option_type=discord.OptionType.channel,
+                name='channel',
+                description='The channel which the the welcome screen field goes to.',
+                channel_types=[discord.TextChannel]),
+            CommandOption(
+                option_type=str,
+                name='description',
+                description='The description for the welcome screen field.'
+            ),
+            CommandOption(
+                option_type=str,
+                name='emoji',
+                description='The emoji which shows in front of the channel.',
+                required=False
+            )
+        ],
+        guild_ids=[852871920411475968]
+    )
+    async def add_welcome_screen_channel(i: discord.ApplicationCommandInteraction, channel: discord.TextChannel, description: str, emoji: str = None):
+        """Add a channel to the welcome-screen of this guild."""
+        welcome_screen = await i.guild.welcome_screen()
+        if emoji:
+            try:
+                emoji = discord.PartialEmoji.from_string(emoji)
+            except ValueError:
+                pass
+
+        if len(welcome_screen.welcome_channels) == 5:
+            return await i.respond('The maximum of welcome-screen channels is reached, you can\'t add more.')
+        channels = welcome_screen.welcome_channels.copy()
+        channels.append(discord.WelcomeScreenChannel(channel=channel, description=description, emoji=emoji))
+        edited = await welcome_screen.edit(welcome_channels=channels, reason=f'{i.author} used the add-channel command')
+        wc_embed = discord.Embed(
+            title=f'The welcome-screen of {i.guild} is now:',
+            description=f'```\n'
+                        f'{emoji} {edited.description or "No Description set"}\n'
+                        f'```'
+        )
+
+        for w_channel in edited.welcome_channels:
+            wc_embed.add_field(
+                name=w_channel.description,
+                value=f'{str(w_channel.emoji) if w_channel.emoji else ""} {w_channel.channel.mention}',
+                inline=False
+            )
+
+        await i.respond(embed=wc_embed)
+
+    client.run('Your Bot-Token here')
+
+A Message Command that translate the corresponding Message in to the invokers locale language
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. code-block:: python
+
+    import discord
+    import asyncio
+    import translators # need to be installed using "py -m pip install translators" (Win) or "python3 -m pip install translators" (Linux/macOS)
+    from io import BytesIO
+
+    client = discord.Client(sync_commands=True)
+
+
+    @client.message_command(guild_ids=[852871920411475968]) # replace the guild id with your own or remove the parameter to make the command global
+    async def translate(self, interaction: discord.ApplicationCommandInteraction, message):
+       await interaction.defer(hidden=True)
+       translated = await asyncio.to_thread(
+           translators.google,
+           query_text=message.content,
+           to_language=interaction.author_locale.value,
+           sleep_seconds=4
+       )
+       if len(translated) > 2000:
+           # Message was send by a Nitro user which can send messages with up to 4000 characters.
+           # As we can't do this sent it as a file instead.
+           new_file = io.BytesIO()
+           file = new_file.write(translated)
+           return await interaction.respond(file=discord.File(file, filename=f'{interaction.id}_translated.txt'), hidden=True)
+
+    client.run('Your Bot-Token here')
+
+A User context-menu command which shows you information about the corresponding user
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.. code-block:: python
+
+    import discord
+
+    client = discord.Client(sync_commands=True)
+
+    @client.user_command(guild_ids=[852871920411475968])
+    async def userinfo(interaction: discord.ApplicationCommandInteraction, member: discord.Member):
+        _roles = member.roles.copy()
+        _roles.remove(member.guild.default_role) # skipp @everyone
+        _roles.reverse()
+
+        embed = discord.Embed(
+            title=f'Userinfo for {member}',
+            description=f'This is a Userinfo for {member.mention}.',
+            timestamp=datetime.utcnow(),
+            color=member.color
+            )
+
+        to_add = [
+            ('Name:', member.name, True),
+            ('Tag:', member.discriminator, True),
+            ('User-ID:', member.id, True),
+            ('Nitro:', '✅ Yes' if member.premium_since else '❔ Unknown', True),
+            ('Nick:', member.nick, True),
+            ('Created-at:', discord.utils.styled_timestamp(member.created_at, 'R'), True),
+            ('Joined at', discord.utils.styled_timestamp(member.joined_at, 'R'), True)
+        ]
+        if member.premium_since:
+            to_add.append(('Premium since:', discord.utils.styled_timestamp(member.premium_since, 'R'), True))
+        try:
+            roles_list = f'{_roles.pop(0)}'
+        except IndexError: # The Member don't has any roles
+            roles_list = '`None`'
+        else:
+            for role in _roles:
+                updated = f'{roles_list}, {role.mention}'
+                if updated > 1024:
+                    roles_list = updated
+                else:
+                    break
+        to_add.append((f'Roles: {len(member.roles) - 1}', roles_list, True))
+
+        for name, value, inline in to_add:
+            embed.add_field(name=name, value=value, inline=inline)
+
+        embed.set_author(name=member.display_name, icon_url=member.display_avatar_url, url=f'https://discord.com/users/{member.id}')
+        embed.set_footer(text=f'Requested by {interaction.author}', icon_url=interaction.author.display_avatar_url)
+        if not member.bot:
+            user = await client.fetch_user(member.id) # to get the banner data we need to fetch the user
+            if user.banner:
+                embed.add_field(name='Banner', value=f'See the [banner]({user.banner_url}) below', inline=False)
+            else:
+                embed.add_field(name='Banner Color', value=f'See the [banner-color](https://serux.pro/rendercolour?hex={hex(user.banner_color.value).replace("0x", "")}?width=500) below', inline=False)
+            if user.banner:
+                embed.set_image(url=user.banner_url)
+            else:
+                embed.set_image(url=f'https://serux.pro/rendercolour?hex={hex(user.banner_color.value).replace("0x", "")}&width=500')
+        await interaction.respond(embed=embed, hidden=True)
+
+    client.run('Your Bot-Token here')
+
+Buttons
++++++++
+
+A Command that sends you a Message and edit it when you click a Button:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. code-block:: python
+
+    import typing
+    import discord
+    from discord.ext import commands
+    from discord import ActionRow, Button, ButtonStyle
+
+    client = commands.Bot(command_prefix=commands.when_mentioned_or('.!'), intents=discord.Intents.all(), case_insensitive=True)
+
+    @client.command(name='buttons', description='sends you some nice Buttons')
+    async def buttons(ctx: commands.Context):
+        components = [ActionRow(Button(label='Option Nr.1',
+                                       custom_id='option1',
+                                       emoji="🆒",
+                                       style=ButtonStyle.green
+                                       ),
+                                Button(label='Option Nr.2',
+                                       custom_id='option2',
+                                       emoji="🆗",
+                                       style=ButtonStyle.blurple)),
+                      ActionRow(Button(label='A Other Row',
+                                       custom_id='sec_row_1st option',
+                                       style=ButtonStyle.red,
+                                       emoji='😀'),
+                                Button(url='https://www.youtube.com/watch?v=dQw4w9WgXcQ',
+                                       label="This is an Link",
+                                       style=ButtonStyle.url,
+                                       emoji='🎬'))
+                      ]
+        an_embed = discord.Embed(title='Here are some Button\'s', description='Choose an option', color=discord.Color.random())
+        msg = await ctx.send(embed=an_embed, components=components)
+
+        def _check(i: discord.Interaction, b):
+            return i.message == msg and i.member == ctx.author
+
+        interaction, button = await client.wait_for('button_click', check=_check)
+        button_id = button.custom_id
+
+        # This sends the Discord-API that the interaction has been received and is being "processed"
+        await interaction.defer()
+        # if this is not used and you also do not edit the message within 3 seconds as described below,
+        # Discord will indicate that the interaction has failed.
+
+        # If you use interaction.edit instead of interaction.message.edit, you do not have to defer the interaction,
+        # if your response does not last longer than 3 seconds.
+        await interaction.edit(embed=an_embed.add_field(name='Choose', value=f'Your Choose was `{button_id}`'),
+                               components=[components[0].disable_all_buttons(), components[1].disable_all_buttons()])
+
+        # The Discord API doesn't send an event when you press a link button so we can't "receive" that.
+
+
+    client.run('Your Bot-Token here')
+
+
+Another (complex) Example where a small Embed will be send; you can move a small white ⬜ with the Buttons:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. code-block:: python
+
+    pointers = []
+
+
+    class Pointer:
+        def __init__(self, guild: discord.Guild):
+            self.guild = guild
+            self._position_x = 0
+            self._position_y = 0
+
+        @property
+        def position_x(self):
+            return self._position_x
+
+        def set_x(self, x: int):
+            self._position_x += x
+            return self._position_x
+
+        @property
+        def position_y(self):
+            return self._position_y
+
+        def set_y(self, y: int):
+            self._position_y += y
+            return self._position_y
+
+
+    def get_pointer(obj: typing.Union[discord.Guild, int]):
+        if isinstance(obj, discord.Guild):
+            for p in pointers:
+                if p.guild.id == obj.id:
+                    return p
+            pointers.append(Pointer(obj))
+            return get_pointer(obj)
+
+        elif isinstance(obj, int):
+            for p in pointers:
+                if p.guild.id == obj:
+                    return p
+            guild = client.get_guild(obj)
+            if guild:
+                pointers.append(Pointer(guild))
+                return get_pointer(guild)
+            return None
+
+
+    def display(x: int, y: int):
+        base = [
+            [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
+            [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
+            [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
+            [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
+            [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
+            [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
+            [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
+            [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
+            [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
+            [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
+        ]
+        base[y][x] = 1
+        base.reverse()
+        return ''.join(f"\n{''.join([str(base[i][w]) for w in range(len(base[i]))]).replace('0', '⬛').replace('1', '⬜')}" for i in range(len(base)))
+
+
+    empty_button = discord.Button(style=discord.ButtonStyle.Secondary, label=" ", custom_id="empty", disabled=True)
+
+
+    def arrow_button():
+        return discord.Button(style=discord.ButtonStyle.Primary)
+
+
+    @client.command(name="start_game")
+    async def start_game(ctx: commands.Context):
+        pointer: Pointer = get_pointer(ctx.guild)
+        await ctx.send(embed=discord.Embed(title="Little Game",
+                                           description=display(x=0, y=0)),
+                       components=[discord.ActionRow(empty_button, arrow_button().set_label('↑').set_custom_id('up'), empty_button),
+                                   discord.ActionRow(arrow_button().update(disabled=True).set_label('←').set_custom_id('left').disable_if(pointer.position_x <= 0),
+                                                     arrow_button().set_label('↓').set_custom_id('down').disable_if(pointer.position_y <= 0),
+                                                     arrow_button().set_label('→').set_custom_id('right'))
+                                   ]
+                       )
+
+
+    @client.on_click()
+    async def up(i: discord.Interaction, button):
+        pointer: Pointer = get_pointer(interaction.guild)
+        pointer.set_y(1)
+        await i.edit(embed=discord.Embed(title="Little Game",
+                                         description=display(x=pointer.position_x, y=pointer.position_y)),
+                               components=[discord.ActionRow(empty_button, arrow_button().set_label('↑').set_custom_id('up').disable_if(pointer.position_y >= 9), empty_button),
+                                           discord.ActionRow(arrow_button().set_label('←').set_custom_id('left').disable_if(pointer.position_x <= 0),
+                                                             arrow_button().set_label('↓').set_custom_id('down'),
+                                                             arrow_button().set_label('→').set_custom_id('right').disable_if(pointer.position_x >= 9))]
+                               )
+
+    @client.on_click()
+    async def down(i: discord.Interaction, button):
+        pointer: Pointer = get_pointer(interaction.guild)
+        pointer.set_y(-1)
+        await i.edit(embed=discord.Embed(title="Little Game",
+                                              description=display(x=pointer.position_x, y=pointer.position_y)),
+                               components=[discord.ActionRow(empty_button, arrow_button().set_label('↑').set_custom_id('up'), empty_button),
+                                           discord.ActionRow(arrow_button().set_label('←').set_custom_id('left').disable_if(pointer.position_x <= 0),
+                                                             arrow_button().set_label('↓').set_custom_id('down').disable_if(pointer.position_y <= 0),
+                                                             arrow_button().set_label('→').set_custom_id('right').disable_if(pointer.position_x >= 9))]
+                               )
+
+    @client.on_click()
+    async def right(i: discord.Interaction, button):
+        pointer: Pointer = get_pointer(interaction.guild)
+        pointer.set_x(1)
+        await i.edit(embed=discord.Embed(title="Little Game",
+                                               description=display(x=pointer.position_x, y=pointer.position_y)),
+                               components=[discord.ActionRow(empty_button, arrow_button().set_label('↑').set_custom_id('up'), empty_button),
+                                           discord.ActionRow(arrow_button().set_label('←').set_custom_id('left'),
+                                                             arrow_button().set_label('↓').set_custom_id('down'),
+                                                             arrow_button().set_label('→').set_custom_id('right').disable_if(pointer.position_x >= 9))]
+                               )
+
+    @client.on_click()
+    async def left(i: discord.Interaction, button):
+        pointer: Pointer = get_pointer(interaction.guild)
+        pointer.set_x(-1)
+        await i.edit(embed=discord.Embed(title="Little Game",
+                                               description=display(x=pointer.position_x, y=pointer.position_y)),
+                               components=[discord.ActionRow(empty_button, arrow_button().set_label('↑').set_custom_id('up'), empty_button),
+                                           discord.ActionRow(arrow_button().set_label('←').set_custom_id('left').disable_if(pointer.position_x <= 0),
+                                                             arrow_button().set_label('↓').set_custom_id('down'),
+                                                             arrow_button().set_label('→').set_custom_id('right'))]
+                               )
+
+Select Menu & Modal (TextInput)
++++++++++++++++++++++++++++++++
+
+Sending-SelectMenu's and respond to them
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.. code-block:: python
+
+   import discord
+   from discord.ext import commands
+   from discord import Button, SelectMenu, SelectOption
+
+
+   client = commands.Bot(command_prefix=commands.when_mentioned_or('!'))
+
+
+   @client.command()
+   async def select(ctx):
+      msg_with_selects = await ctx.send('Hey here is an nice Select-Menu', components=[
+         [
+               SelectMenu(custom_id='_select_it', options=[
+                  SelectOption(emoji='1️⃣', label='Option Nr° 1', value='1', description='The first option'),
+                  SelectOption(emoji='2️⃣', label='Option Nr° 2', value='2', description='The second option'),
+                  SelectOption(emoji='3️⃣', label='Option Nr° 3', value='3', description='The third option'),
+                  SelectOption(emoji='4️⃣', label='Option Nr° 4', value='4', description='The fourth option')],
+                        placeholder='Select some Options', max_values=3)
+            ]])
+
+      def check_selection(i: discord.Interaction, select_menu):
+         return i.author == ctx.author and i.message == msg_with_selects
+
+      interaction, select_menu = await client.wait_for('selection_select', check=check_selection)
+
+      embed = discord.Embed(title='You have chosen:',
+                           description=f"You have chosen "+'\n'.join([f'\nOption Nr° {o}' for o in select_menu.values]),
+                           color=discord.Color.random())
+      await interaction.respond(embed=embed)
+
+   client.run('Your Bot-Token')
+
+A Select Menu that shows you the different response-types for an interaction
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. code-block:: python
+
+    import asyncio
+    import discord
+    from discord.ext import commands
+    from discord import Modal, TextInput
+    from discord import ActionRow, SelectMenu, SelectOption, Modal, TextInput
+
+    client = commands.Bot('!')
+
+
+    @client.command()
+    async def interaction_types(ctx):
+        components = [ActionRow(
+            SelectMenu(
+                custom_id='interaction_types_example',
+                placeholder='Select a interaction response type to show.',
+                options=
+                [
+                    SelectOption('msg_with_source', '4', 'Respond with a message', '4️⃣'),
+                    SelectOption('deferred_msg_with_source', '5', 'ACK an interaction[...]; user sees a loading state', '5️⃣'),
+                    SelectOption('deferred_update_msg', '6', 'ACK an interaction[...]; no loading state', '6️⃣'),
+                    SelectOption('update_msg', '7', 'Edit the message the component was attached to', '7️⃣'),
+                    SelectOption('show_modal', '9', 'Respond to the interaction by sending a popup modal', '9️⃣')
+                ]
+            )
+        )]
+
+        embed = discord.Embed(title='Interaction Callback Type', description='These are all interaction-callback-types you could use for slash-commands and message-components:', color=discord.Color.green())
+        await ctx.send(embed=embed, components=components)
+
+    @client.on_select()
+    async def interaction_types_example(i: discord.ComponentInteraction, s):
+        _type = s.values[0]
+        if _type == 4:
+            await i.respond('This is of type `4`')
+        elif _type == 5:
+            await i.defer(5)
+            await asyncio.sleep(5)
+            await i.respond('Yes this is of type `5`')
+        elif _type == 6:
+            await i.defer()
+            await asyncio.sleep(5)
+            await i.edit(embeds=[i.message.embeds[0], discord.Embed(title='This is of type `6`')])
+        elif _type == 7:
+            msg = await i.edit(embed=i.message.embeds[0].add_field(name=i.author, value='This is of type `7`'))
+            await asyncio.sleep(5)
+            msg.embeds[0].clear_fields()
+            await i.message.edit(embed=msg.embeds[0])
+        elif _type == 9:
+            await i.respond_with_modal(
+                Modal(
+                title='This is of type 9',
+                custom_id='response_types_example_modal',
+                components=[
+                    TextInput(
+                        style=1,
+                        label='This is a short(single-line) input',
+                        placeholder='Enter something in here.',
+                        custom_id='short_input'
+                    ),
+                    TextInput(
+                        style=2,
+                        label='This is a long(multi-line) input',
+                        placeholder='Enter something longer in here.',
+                        custom_id='long_input'
+                    )
+                ]
+            )
+        )
+        modal_interaction: discord.ModalSubmitInteraction = await client.wait_for('modal_submit', check=lambda mi: mi.author == i.author)
+        embed = discord.Embed(title='This was response type 9', color=discord.Color.green())
+        embed.add_field(
+            name='Content of short input:',
+            value=modal_interaction.get_field('short_input').value,
+            inline=False
+        )
+        embed.add_field(
+            name='Content of long input:',
+            value=modal_interaction.get_field('long_input').value,
+            inline=False
+        )
+
+        await modal_interaction.respond(embed=embed)
+
+
+    client.run('Your Bot-Token here')
+
+
+Take a look at `the documentation <https://discordpy-message-components.readthedocs.io/en/developer/>`_ to see more examples.
+
+.. figure:: https://api.visitorbadge.io/api/visitors?path=https%3A%2F%2Fgithub.com%2Fmccoderpy%2Fdiscord.py-message-components%2Ftree%2Fdeveloper%2F&countColor=%23263759&style=flat
+      :alt: Number(As image) how often this WebSite was visited
+      :align: center
+      :name: Visitor count
diff --git a/discord/__init__.py b/discord/__init__.py
index bdf9113f..fc7bf3c3 100644
--- a/discord/__init__.py
+++ b/discord/__init__.py
@@ -6,7 +6,7 @@
 
 A basic wrapper for the Discord API.
 
-:copyright: (c) 2015-present Rapptz
+:copyright: (c) 2015-2021 Rapptz & 2021-present mccoderpy
 :license: MIT, see LICENSE for more details.
 
 """
@@ -14,36 +14,36 @@
 __title__ = 'discord'
 __author__ = 'Rapptz & mccoderpy'
 __license__ = 'MIT'
-__copyright__ = 'Copyright 2015-present Rapptz'
-__version__ = '1.7.5.4'
+__copyright__ = 'Copyright 2015-2021 Rapptz & 2021-present mccoderpy'
+__version__ = '2.0a'
 
 __path__ = __import__('pkgutil').extend_path(__path__, __name__)
 
-from collections import namedtuple
 import logging
+from collections import namedtuple
 
-from .client import Client
 from .appinfo import AppInfo
-from .user import User, ClientUser, Profile
+from .automod import *
+from .client import Client
+from .user import User, ClientUser
 from .emoji import Emoji
 from .partial_emoji import PartialEmoji
 from .activity import *
 from .channel import *
-from .components import ActionRow, Button, SelectMenu, SelectOption
-from .guild import Guild
+from .components import *
+from .guild import *
 from .flags import *
-from .relationship import Relationship
 from .member import Member, VoiceState
 from .message import *
 from .asset import Asset
 from .errors import *
-from .calls import CallMessage, GroupCall
 from .permissions import Permissions, PermissionOverwrite
 from .role import Role, RoleTags
-from .file import File
+from .file import File, UploadFile
 from .colour import Color, Colour
 from .integrations import Integration, IntegrationAccount, BotIntegration, IntegrationApplication, StreamIntegration
-from .interactions import Interaction, ButtonClick, SelectionSelect
+from .application_commands import *
+from .interactions import *
 from .invite import Invite, PartialInviteChannel, PartialInviteGuild
 from .template import Template
 from .widget import Widget, WidgetMember, WidgetChannel
@@ -51,19 +51,30 @@
 from .reaction import Reaction
 from . import utils, opus, abc
 from .enums import *
-from .embeds import Embed
+from .embeds import *
 from .mentions import AllowedMentions
+from .onboarding import *
 from .shard import AutoShardedClient, ShardInfo
 from .player import *
 from .webhook import *
-from .voice_client import VoiceClient, VoiceProtocol
+from .welcome_screen import *
+from .voice_client import *
+from .sink import *
 from .audit_logs import AuditLogChanges, AuditLogEntry, AuditLogDiff
 from .raw_models import *
 from .team import *
-from .sticker import Sticker
+from .sticker import Sticker, GuildSticker, StickerPack
+from .scheduled_event import GuildScheduledEvent
+from .monetization import *
+
+
+MISSING = utils.MISSING
+Mentionable = abc.Mentionable
 
 VersionInfo = namedtuple('VersionInfo', 'major minor micro releaselevel serial')
 
-version_info = VersionInfo(major=1, minor=7, micro=2, releaselevel='final', serial=0)
+version_info: VersionInfo = VersionInfo(major=2, minor=0, micro=0, releaselevel='alpha', serial=0)
 
 logging.getLogger(__name__).addHandler(logging.NullHandler())
+
+del VersionInfo, namedtuple
diff --git a/discord/__main__.py b/discord/__main__.py
index 31c61553..41f25c69 100644
--- a/discord/__main__.py
+++ b/discord/__main__.py
@@ -3,7 +3,7 @@
 """
 The MIT License (MIT)
 
-Copyright (c) 2015-present Rapptz
+Copyright (c) 2015-2021 Rapptz & (c) 2021-present mccoderpy
 
 Permission is hereby granted, free of charge, to any person obtaining a
 copy of this software and associated documentation files (the "Software"),
@@ -29,21 +29,22 @@
 from pathlib import Path
 
 import discord
-import pkg_resources
+if sys.version_info <= (3, 7):
+    import importlib_metadata
+else:
+    import importlib.metadata as importlib_metadata
 import aiohttp
 import platform
 
 
 def show_version():
-    entries = []
-
-    entries.append('- Python v{0.major}.{0.minor}.{0.micro}-{0.releaselevel}'.format(sys.version_info))
+    entries = ['- Python v{0.major}.{0.minor}.{0.micro}-{0.releaselevel}'.format(sys.version_info)]
     version_info = discord.version_info
-    entries.append('- discord.py v{0.major}.{0.minor}.{0.micro}-{0.releaselevel}'.format(version_info))
+    entries.append('- discord.py-message-components v{0.major}.{0.minor}.{0.micro}-{0.releaselevel}'.format(version_info))
     if version_info.releaselevel != 'final':
-        pkg = pkg_resources.get_distribution('discord.py')
-        if pkg:
-            entries.append('    - discord.py pkg_resources: v{0}'.format(pkg.version))
+        version = importlib_metadata.version('discord.py-message-components')
+        if version:
+            entries.append('    - discord.py.message-components metadata: v{0}'.format(version))
 
     entries.append('- aiohttp v{0.__version__}'.format(aiohttp))
     uname = platform.uname()
diff --git a/discord/abc.py b/discord/abc.py
index a202f28c..a3ae353c 100644
--- a/discord/abc.py
+++ b/discord/abc.py
@@ -3,9 +3,7 @@
 """
 The MIT License (MIT)
 
-Copyright (c) 2015-present Rapptz
-
-Implementing of the Discord-Message-components made by mccoderpy (Discord-User mccuber04#2960)
+Copyright (c) 2015-2021 Rapptz & (c) 2021-present mccoderpy
 
 Permission is hereby granted, free of charge, to any person obtaining a
 copy of this software and associated documentation files (the "Software"),
@@ -25,33 +23,87 @@
 FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 DEALINGS IN THE SOFTWARE.
 """
+from __future__ import annotations
 
 import abc
-import json
-import sys
-import copy
 import asyncio
+import copy
+from typing import (
+    Any,
+    List,
+    Dict,
+    Union,
+    Mapping,
+    overload,
+    Optional,
+    Callable,
+    Coroutine,
+    TypeVar,
+    TYPE_CHECKING
+)
+
+from typing_extensions import (
+    Literal,
+    Protocol,
+    runtime_checkable
+)
 
-from .iterators import HistoryIterator
+
+
+from . import utils
 from .context_managers import Typing
-from .enums import try_enum, ChannelType, PermissionType
-from .errors import InvalidArgument, ClientException
+from .enums import ChannelType, InviteTargetType, try_enum
+from .errors import ClientException, InvalidArgument
+from .file import File
+from .flags import ChannelFlags
+from .http import handle_message_parameters
+from .invite import Invite
+from .iterators import HistoryIterator
 from .mentions import AllowedMentions
 from .permissions import PermissionOverwrite, Permissions
 from .role import Role
-from .invite import Invite
-from .file import File
-from .components import Button, SelectMenu, ActionRow
 from .voice_client import VoiceClient, VoiceProtocol
-from . import utils
-
-class _Undefined:
-    def __repr__(self):
-        return 'see-below'
-
-_undefined = _Undefined()
 
-class Snowflake(metaclass=abc.ABCMeta):
+T = TypeVar('T')
+VP = TypeVar('VP', bound=VoiceProtocol)
+
+if TYPE_CHECKING:
+    from datetime import datetime
+
+    from .types.channel import (
+        GuildChannel as GuildChannelData,
+        Overwrite as PermissionOverwriteData,
+        OverwriteType
+    )
+    from .client import Client
+    from .state import ConnectionState
+    from .embeds import Embed
+    from .sticker import GuildSticker
+    from .components import ActionRow, Button, BaseSelect
+    from .scheduled_event import GuildScheduledEvent
+    from .member import Member
+    from .message import Message, MessageReference
+    from .channel import CategoryChannel
+    from .guild import Guild
+    from .user import ClientUser
+
+    SnowflakeTime = Union["Snowflake", datetime]
+
+MISSING = utils.MISSING
+MSNG = utils._MISSING
+
+__all__ = (
+    'Snowflake',
+    'User',
+    'PrivateChannel',
+    'GuildChannel',
+    'Messageable',
+    'Connectable',
+    'Mentionable'
+)
+
+@runtime_checkable
+class Snowflake(Protocol):
     """An ABC that details the common operations on a Discord model.
 
     Almost all :ref:`Discord models <discord_api_models>` meet this
@@ -65,28 +117,13 @@ class Snowflake(metaclass=abc.ABCMeta):
     id: :class:`int`
         The model's unique ID.
     """
+    
     __slots__ = ()
+    id: int
 
-    @property
-    @abc.abstractmethod
-    def created_at(self):
-        """:class:`datetime.datetime`: Returns the model's creation time as a naive datetime in UTC."""
-        raise NotImplementedError
 
-    @classmethod
-    def __subclasshook__(cls, C):
-        if cls is Snowflake:
-            mro = C.__mro__
-            for attr in ('created_at', 'id'):
-                for base in mro:
-                    if attr in base.__dict__:
-                        break
-                else:
-                    return NotImplemented
-            return True
-        return NotImplemented
-
-class User(metaclass=abc.ABCMeta):
+@runtime_checkable
+class User(Snowflake, Protocol):
     """An ABC that details the common operations on a Discord user.
 
     The following implement this ABC:
@@ -99,8 +136,10 @@ class User(metaclass=abc.ABCMeta):
 
     Attributes
     -----------
-    name: :class:`str`
+    username: :class:`str`
         The user's username.
+    global_name: Optional[:class:`str`]
+        The users display name, if set.
     discriminator: :class:`str`
         The user's discriminator.
     avatar: Optional[:class:`str`]
@@ -108,37 +147,39 @@ class User(metaclass=abc.ABCMeta):
     bot: :class:`bool`
         If the user is a bot account.
     """
+    
     __slots__ = ()
-
+    username: str
+    global_name: Optional[str]
+    discriminator: str
+    avatar: Optional[str]
+    bot: bool
+    
+    @property
+    def name(self):
+        """:class:`str`: An alias for :attr:`name`."""
+        raise NotImplementedError
+    
     @property
-    @abc.abstractmethod
     def display_name(self):
         """:class:`str`: Returns the user's display name."""
         raise NotImplementedError
 
     @property
-    @abc.abstractmethod
+    def display_avatar(self):
+        """:class:`Asset`: Returns the user's display avatar.
+        For regular users this is just their default or uploaded avatar.
+        """
+        raise NotImplementedError
+
+    @property
     def mention(self):
         """:class:`str`: Returns a string that allows you to mention the given user."""
         raise NotImplementedError
 
-    @classmethod
-    def __subclasshook__(cls, C):
-        if cls is User:
-            if Snowflake.__subclasshook__(C) is NotImplemented:
-                return NotImplemented
-
-            mro = C.__mro__
-            for attr in ('display_name', 'mention', 'name', 'avatar', 'discriminator', 'bot'):
-                for base in mro:
-                    if attr in base.__dict__:
-                        break
-                else:
-                    return NotImplemented
-            return True
-        return NotImplemented
-
-class PrivateChannel(metaclass=abc.ABCMeta):
+
+@runtime_checkable
+class PrivateChannel(Snowflake, Protocol):
     """An ABC that details the common operations on a private Discord channel.
 
     The following implement this ABC:
@@ -155,29 +196,22 @@ class PrivateChannel(metaclass=abc.ABCMeta):
     """
     __slots__ = ()
 
-    @classmethod
-    def __subclasshook__(cls, C):
-        if cls is PrivateChannel:
-            if Snowflake.__subclasshook__(C) is NotImplemented:
-                return NotImplemented
+    me: ClientUser
 
-            mro = C.__mro__
-            for base in mro:
-                if 'me' in base.__dict__:
-                    return True
-            return NotImplemented
-        return NotImplemented
 
 class _Overwrites:
     __slots__ = ('id', 'allow', 'deny', 'type')
 
-    def __init__(self, **kwargs):
-        self.id = kwargs.pop('id')
-        self.allow = int(kwargs.pop('allow_new', 0))
-        self.deny = int(kwargs.pop('deny_new', 0))
-        self.type = sys.intern(kwargs.pop('type'))
+    ROLE = 0
+    MEMBER = 1
 
-    def _asdict(self):
+    def __init__(self, data: PermissionOverwriteData) -> None:
+        self.id: int = int(data['id'])
+        self.allow: int = int(data.get('allow', 0))
+        self.deny: int = int(data.get('deny', 0))
+        self.type: OverwriteType = data['type']
+
+    def _asdict(self) -> PermissionOverwriteData:
         return {
             'id': self.id,
             'allow': str(self.allow),
@@ -185,6 +219,13 @@ def _asdict(self):
             'type': self.type,
         }
 
+    def is_role(self) -> bool:
+        return self.type == self.ROLE
+
+    def is_member(self) -> bool:
+        return self.type == self.MEMBER
+
+
 class GuildChannel:
     """An ABC that details the common operations on a Discord guild channel.
 
@@ -209,20 +250,40 @@ class GuildChannel:
     """
     __slots__ = ()
 
-    def __str__(self):
+    id: int
+    name: str
+    guild: Guild
+    type: ChannelType
+    position: int
+    category_id: Optional[int]
+    flags: ChannelFlags
+    _state: ConnectionState
+    _overwrites: List[_Overwrites]
+
+    def __str__(self) -> str:
         return self.name
 
     @property
-    def _sorting_bucket(self):
+    def _sorting_bucket(self) -> int:
+        raise NotImplementedError
+
+    def _update(self, guild: Guild, data: dict[str, Any]) -> None:
         raise NotImplementedError
 
-    async def _move(self, position, parent_id=None, lock_permissions=False, *, reason):
+    async def _move(
+            self,
+            position: int,
+            parent_id: Optional[int] = None,
+            lock_permissions=False,
+            *,
+            reason: Optional[str]
+    ) -> None:
         if position < 0:
             raise InvalidArgument('Channel position cannot be less than 0.')
 
         http = self._state.http
         bucket = self._sorting_bucket
-        channels = [c for c in self.guild.channels if c._sorting_bucket == bucket]
+        channels: List[GuildChannel] = [c for c in self.guild.channels if c._sorting_bucket == bucket]
 
         channels.sort(key=lambda c: c.position)
 
@@ -239,21 +300,22 @@ async def _move(self, position, parent_id=None, lock_permissions=False, *, reaso
 
         payload = []
         for index, c in enumerate(channels):
-            d = {'id': c.id, 'position': index}
-            if parent_id is not _undefined and c.id == self.id:
+            d: Dict[str, Any] = {'id': c.id, 'position': index}
+            if parent_id is not MISSING and c.id == self.id:
                 d.update(parent_id=parent_id, lock_permissions=lock_permissions)
             payload.append(d)
 
         await http.bulk_channel_update(self.guild.id, payload, reason=reason)
+
         self.position = position
-        if parent_id is not _undefined:
+        if parent_id is not MISSING:
             self.category_id = int(parent_id) if parent_id else None
 
-    async def _edit(self, options, reason):
+    async def _edit(self, options: Dict[str, Any], reason: Optional[str]) -> None:
         try:
             parent = options.pop('category')
         except KeyError:
-            parent_id = _undefined
+            parent_id = MISSING
         else:
             parent_id = parent and parent.id
 
@@ -274,7 +336,7 @@ async def _edit(self, options, reason):
         try:
             position = options.pop('position')
         except KeyError:
-            if parent_id is not _undefined:
+            if parent_id is not MISSING:
                 if lock_permissions:
                     category = self.guild.get_channel(parent_id)
                     options['permission_overwrites'] = [c._asdict() for c in category._overwrites]
@@ -283,7 +345,8 @@ async def _edit(self, options, reason):
                 # if we're syncing permissions on a pre-existing channel category without changing it
                 # we need to update the permissions to point to the pre-existing category
                 category = self.guild.get_channel(self.category_id)
-                options['permission_overwrites'] = [c._asdict() for c in category._overwrites]
+                if category:
+                    options['permission_overwrites'] = [c._asdict() for c in category._overwrites]
         else:
             await self._move(position, parent_id=parent_id, lock_permissions=lock_permissions, reason=reason)
 
@@ -295,18 +358,15 @@ async def _edit(self, options, reason):
                     raise InvalidArgument('Expected PermissionOverwrite received {0.__name__}'.format(type(perm)))
 
                 allow, deny = perm.pair()
-                payload = {
-                    'allow': allow.value,
-                    'deny': deny.value,
-                    'id': target.id
-                }
-
-                if isinstance(target, Role):
-                    payload['type'] = 'role'
-                else:
-                    payload['type'] = 'member'
-
-                perms.append(payload)
+                perms.append(
+                    {
+                        'allow': allow.value,
+                        'deny': deny.value,
+                        'id': target.id,
+                        'type': _Overwrites.ROLE if isinstance(target, Role) else _Overwrites.MEMBER,
+                    }
+                )
+
             options['permission_overwrites'] = perms
 
         try:
@@ -318,26 +378,33 @@ async def _edit(self, options, reason):
                 raise InvalidArgument('type field must be of type ChannelType')
             options['type'] = ch_type.value
 
+        try:
+            icon_emoji = options['icon_emoji']
+        except KeyError:
+            pass
+        else:
+            if icon_emoji is None:
+                options['icon_emoji'] = None
+            else:
+                options['icon_emoji'] = icon_emoji.to_dict()
+
         if options:
             data = await self._state.http.edit_channel(self.id, reason=reason, **options)
-            self._update(self.guild, data)
+            return self._update(self.guild, data)
 
-    def _fill_overwrites(self, data):
-        self._overwrites = []
+    def _fill_overwrites(self, data: GuildChannelData) -> None:
+        self._overwrites = _overwrites = []
         everyone_index = 0
         everyone_id = self.guild.id
 
         for index, overridden in enumerate(data.get('permission_overwrites', [])):
-            overridden_type = try_enum(PermissionType, overridden.pop('type'))
-            if not overridden_type:
-                raise AttributeError('Type type should be 0 - member, or 1 - role not %s' % overridden_type)
-            overridden_id = int(overridden.pop('id'))
-            self._overwrites.append(_Overwrites(id=overridden_id, type=overridden_type.name, **overridden))
+            overwrite = _Overwrites(overridden)
+            _overwrites.append(overwrite)
 
-            if overridden_type.name == 'member':
+            if overridden['type'] == _Overwrites.MEMBER:
                 continue
 
-            if overridden_id == everyone_id:
+            if overwrite.id == everyone_id:
                 # the @everyone role is not guaranteed to be the first one
                 # in the list of permission overwrites, however the permission
                 # resolution code kind of requires that it is the first one in
@@ -356,7 +423,7 @@ def changed_roles(self):
         their default values in the :attr:`~discord.Guild.roles` attribute."""
         ret = []
         g = self.guild
-        for overwrite in filter(lambda o: o.type == 'role', self._overwrites):
+        for overwrite in filter(lambda o: o.is_role(), self._overwrites):
             role = g.get_role(overwrite.id)
             if role is None:
                 continue
@@ -367,16 +434,24 @@ def changed_roles(self):
         return ret
 
     @property
-    def mention(self):
+    def mention(self) -> str:
         """:class:`str`: The string that allows you to mention the channel."""
-        return '<#%s>' % self.id
+        return f'<#{self.id}>'
+
+    @property
+    def jump_url(self):
+        """:class:`str`: Returns a URL that allows the client to jump to the referenced channel.
+
+        .. versionadded:: 2.0
+        """
+        return f'https://discord.com/channels/{self.guild.id}/{self.id}'  # type: ignore
 
     @property
     def created_at(self):
         """:class:`datetime.datetime`: Returns the channel's creation time in UTC."""
         return utils.snowflake_time(self.id)
 
-    def overwrites_for(self, obj):
+    def overwrites_for(self, obj: Union[Role, User]) -> PermissionOverwrite:
         """Returns the channel-specific overwrites for a member or a role.
 
         Parameters
@@ -392,9 +467,9 @@ def overwrites_for(self, obj):
         """
 
         if isinstance(obj, User):
-            predicate = lambda p: p.type == 'member'
+            predicate = lambda p: p.is_member()
         elif isinstance(obj, Role):
-            predicate = lambda p: p.type == 'role'
+            predicate = lambda p: p.is_role()
         else:
             predicate = lambda p: True
 
@@ -407,7 +482,7 @@ def overwrites_for(self, obj):
         return PermissionOverwrite()
 
     @property
-    def overwrites(self):
+    def overwrites(self) -> Dict[Union[Role, Member], PermissionOverwrite]:
         """Returns all of the channel's overwrites.
 
         This is returned as a dictionary where the key contains the target which
@@ -424,10 +499,11 @@ def overwrites(self):
             allow = Permissions(ow.allow)
             deny = Permissions(ow.deny)
             overwrite = PermissionOverwrite.from_pair(allow, deny)
+            target = None
 
-            if ow.type == 'role':
+            if ow.is_role():
                 target = self.guild.get_role(ow.id)
-            elif ow.type == 'member':
+            elif ow.is_member():
                 target = self.guild.get_member(ow.id)
 
             # TODO: There is potential data loss here in the non-chunked
@@ -440,7 +516,7 @@ def overwrites(self):
         return ret
 
     @property
-    def category(self):
+    def category(self) -> Optional[CategoryChannel]:
         """Optional[:class:`~discord.CategoryChannel`]: The category this channel belongs to.
 
         If there is no category then this is ``None``.
@@ -448,7 +524,7 @@ def category(self):
         return self.guild.get_channel(self.category_id)
 
     @property
-    def permissions_synced(self):
+    def permissions_synced(self) -> bool:
         """:class:`bool`: Whether or not the permissions for this channel are synced with the
         category it belongs to.
 
@@ -459,7 +535,7 @@ def permissions_synced(self):
         category = self.guild.get_channel(self.category_id)
         return bool(category and category.overwrites == self.overwrites)
 
-    def permissions_for(self, member):
+    def permissions_for(self, member: Member, /) -> Permissions:
         """Handles permission resolution for the current :class:`~discord.Member`.
 
         This function takes into consideration the following cases:
@@ -529,7 +605,7 @@ def permissions_for(self, member):
 
         # Apply channel specific role permission overwrites
         for overwrite in remaining_overwrites:
-            if overwrite.type == 'role' and roles.has(overwrite.id):
+            if overwrite.is_role() and roles.has(overwrite.id):
                 denies |= overwrite.deny
                 allows |= overwrite.allow
 
@@ -537,7 +613,7 @@ def permissions_for(self, member):
 
         # Apply member specific permission overwrites
         for overwrite in remaining_overwrites:
-            if overwrite.type == 'member' and overwrite.id == member.id:
+            if overwrite.is_member() and overwrite.id == member.id:
                 base.handle_overwrite(allow=overwrite.allow, deny=overwrite.deny)
                 break
 
@@ -545,9 +621,13 @@ def permissions_for(self, member):
         # permissions as well
         if not base.send_messages:
             base.send_tts_messages = False
+            base.send_voice_messages = False
             base.mention_everyone = False
             base.embed_links = False
             base.attach_files = False
+            base.create_public_threads = False
+            base.create_private_threads = False
+            base.use_application_commands = False
 
         # if you can't read a channel then you have no permissions there
         if not base.read_messages:
@@ -555,7 +635,7 @@ def permissions_for(self, member):
             base.value &= ~denied.value
         return base
 
-    async def delete(self, *, reason=None):
+    async def delete(self, *, reason: Optional[str] = None) -> None:
         """|coro|
 
         Deletes the channel.
@@ -579,7 +659,13 @@ async def delete(self, *, reason=None):
         """
         await self._state.http.delete_channel(self.id, reason=reason)
 
-    async def set_permissions(self, target, *, overwrite=_undefined, reason=None, **permissions):
+    async def set_permissions(
+            self,
+            target: Union[Role, User],
+            *,
+            overwrite: Optional[PermissionOverwrite] = MISSING,
+            reason: Optional[str] = None,
+            **permissions):
         r"""|coro|
 
         Sets the channel specific permission overwrites for a target in the
@@ -651,18 +737,17 @@ async def set_permissions(self, target, *, overwrite=_undefined, reason=None, **
         elif isinstance(target, Role):
             perm_type = 'role'
         else:
-            raise InvalidArgument('target parameter must be either Member or Role')
+            raise InvalidArgument(f'target parameter must be either Member or Role, not {target.__class__.__name__}')
 
-        if isinstance(overwrite, _Undefined):
-            if len(permissions) == 0:
+        if overwrite is MISSING:
+            if not permissions:
                 raise InvalidArgument('No overwrite provided.')
             try:
                 overwrite = PermissionOverwrite(**permissions)
             except (ValueError, TypeError):
                 raise InvalidArgument('Invalid permissions given to keyword arguments.')
-        else:
-            if len(permissions) > 0:
-                raise InvalidArgument('Cannot mix overwrite and keyword arguments.')
+        elif permissions:
+            raise InvalidArgument('Cannot mix overwrite and keyword arguments.')
 
         # TODO: wait for event
 
@@ -674,12 +759,13 @@ async def set_permissions(self, target, *, overwrite=_undefined, reason=None, **
         else:
             raise InvalidArgument('Invalid overwrite type provided.')
 
-    async def _clone_impl(self, base_attrs, *, name=None, reason=None):
+    async def _clone_impl(self, base_attrs, *, name: Optional[str] = None, reason: Optional[str] = None):
         base_attrs['permission_overwrites'] = [
             x._asdict() for x in self._overwrites
         ]
         base_attrs['parent_id'] = self.category_id
         base_attrs['name'] = name or self.name
+        base_attrs['flags'] = getattr(self, 'flags', ChannelFlags()).value
         guild_id = self.guild.id
         cls = self.__class__
         data = await self._state.http.create_channel(guild_id, self.type.value, reason=reason, **base_attrs)
@@ -689,7 +775,7 @@ async def _clone_impl(self, base_attrs, *, name=None, reason=None):
         self.guild._channels[obj.id] = obj
         return obj
 
-    async def clone(self, *, name=None, reason=None):
+    async def clone(self: T, *, name: Optional[str] = None, reason: Optional[str] = None) -> T:
         """|coro|
 
         Clones this channel. This creates a channel with the same properties
@@ -722,7 +808,77 @@ async def clone(self, *, name=None, reason=None):
         """
         raise NotImplementedError
 
-    async def move(self, **kwargs):
+    @overload
+    async def move(
+            self,
+            *,
+            beginning: Literal[True] = ...,
+            end: Literal[False] = ...,
+            before: MSNG = ...,
+            after: MSNG = ...,
+            offset: int = 0,
+            category: Optional[Snowflake] = MISSING,
+            sync_permissions: bool = False,
+            reason: Optional[str] = None
+    ) -> None: ...
+
+    @overload
+    async def move(
+            self,
+            *,
+            beginning: Literal[False] = ...,
+            end: Literal[True] = ...,
+            before: MSNG = ...,
+            after: MSNG = ...,
+            offset: int = 0,
+            category: Optional[Snowflake] = MISSING,
+            sync_permissions: bool = False,
+            reason: Optional[str] = None
+    ) -> None:
+        ...
+
+    @overload
+    async def move(
+            self,
+            *,
+            beginning: Literal[False] = ...,
+            end: Literal[False] = ...,
+            before: Snowflake = ...,
+            after: MSNG = ...,
+            offset: int = 0,
+            category: Optional[Snowflake] = MISSING,
+            sync_permissions: bool = False,
+            reason: Optional[str] = None
+    ) -> None:
+        ...
+
+    @overload
+    async def move(
+            self,
+            *,
+            beginning: Literal[False] = ...,
+            end: Literal[False] = ...,
+            before: MSNG = ...,
+            after: Snowflake = ...,
+            offset: int = 0,
+            category: Optional[Snowflake] = MISSING,
+            sync_permissions: bool = False,
+            reason: Optional[str] = None
+    ) -> None:
+        ...
+
+    async def move(
+            self,
+            *,
+            beginning: bool = False,
+            end: bool = False,
+            before: Optional[Snowflake] = MISSING,
+            after: Optional[Snowflake] = MISSING,
+            offset: int = 0,
+            category: Optional[Snowflake] = MISSING,
+            sync_permissions: bool = False,
+            reason: Optional[str] = None
+    ):
         """|coro|
 
         A rich interface to help move a channel relative to other channels.
@@ -780,20 +936,14 @@ async def move(self, **kwargs):
         HTTPException
             Moving the channel failed.
         """
-
-        if not kwargs:
-            return
-
-        beginning, end = kwargs.get('beginning'), kwargs.get('end')
-        before, after = kwargs.get('before'), kwargs.get('after')
-        offset = kwargs.get('offset', 0)
         if sum(bool(a) for a in (beginning, end, before, after)) > 1:
             raise InvalidArgument('Only one of [before, after, end, beginning] can be used.')
 
+        parent_id = ... if category is MISSING else category.id
+
         bucket = self._sorting_bucket
-        parent_id = kwargs.get('category', ...)
         if parent_id not in (..., None):
-            parent_id = parent_id.id
+            parent_id = category.id
             channels = [
                 ch
                 for ch in self.guild.channels
@@ -818,13 +968,13 @@ async def move(self, **kwargs):
             pass
 
         index = None
-        if beginning:
+        if beginning is not MISSING:
             index = 0
-        elif end:
+        elif end is not MISSING:
             index = len(channels)
-        elif before:
+        elif before is not MISSING:
             index = next((i for i, c in enumerate(channels) if c.id == before.id), None)
-        elif after:
+        elif after is not MISSING:
             index = next((i + 1 for i, c in enumerate(channels) if c.id == after.id), None)
 
         if index is None:
@@ -832,18 +982,27 @@ async def move(self, **kwargs):
 
         channels.insert(max((index + offset), 0), self)
         payload = []
-        lock_permissions = kwargs.get('sync_permissions', False)
-        reason = kwargs.get('reason')
         for index, channel in enumerate(channels):
-            d = { 'id': channel.id, 'position': index }
+            d = {'id': channel.id, 'position': index}
             if parent_id is not ... and channel.id == self.id:
-                d.update(parent_id=parent_id, lock_permissions=lock_permissions)
+                d.update(parent_id=parent_id, lock_permissions=sync_permissions)
             payload.append(d)
 
         await self._state.http.bulk_channel_update(self.guild.id, payload, reason=reason)
 
-
-    async def create_invite(self, *, reason=None, **fields):
+    async def create_invite(
+            self,
+            *,
+            max_age: int = 0,
+            max_uses: int = 0,
+            temporary: bool = False,
+            unique: bool = True,
+            target_event: Optional[GuildScheduledEvent] = None,
+            target_type: Optional[InviteTargetType] = None,
+            target_user: Optional[User] = None,
+            target_application_id: Optional[int] = None,
+            reason: Optional[str] = None,
+    ) -> Invite:
         """|coro|
 
         Creates an instant invite from a text or voice channel.
@@ -853,19 +1012,46 @@ async def create_invite(self, *, reason=None, **fields):
 
         Parameters
         ------------
-        max_age: :class:`int`
+        max_age: Optional[:class:`int`]
             How long the invite should last in seconds. If it's 0 then the invite
             doesn't expire. Defaults to ``0``.
-        max_uses: :class:`int`
+        max_uses: Optional[:class:`int`]
             How many uses the invite could be used for. If it's 0 then there
             are unlimited uses. Defaults to ``0``.
-        temporary: :class:`bool`
+        temporary: Optional[:class:`bool`]
             Denotes that the invite grants temporary membership
             (i.e. they get kicked after they disconnect). Defaults to ``False``.
-        unique: :class:`bool`
+        unique: Optional[:class:`bool`]
             Indicates if a unique invite URL should be created. Defaults to True.
             If this is set to ``False`` then it will return a previously created
             invite.
+        target_type: Optional[:class:`InviteTargetType`]
+            The type of target for this voice channel invite, if any.
+
+            .. versionadded:: 2.0
+
+        target_user: Optional[:class:`int`]
+        	The user whose stream to display for this invite, required if `target_type` is :attr:`TargetType.stream`.
+            The user must be streaming in the channel.
+
+            .. versionadded:: 2.0
+
+        target_application_id: Optional[:class:`int`]
+            The id of the embedded application to open for this invite,
+            required if `target_type` is :attr:`InviteTargetType.embeded_application`,
+            the application must have the EMBEDDED flag.
+
+            .. versionadded:: 2.0
+
+        target_event: Optional[:class:`GuildScheduledEvent`]
+            The scheduled event object to link to the event.
+            Shortcut to :meth:`.Invite.set_scheduled_event`
+
+            See :meth:`.Invite.set_scheduled_event` for more
+            info on event invite linking.
+
+            .. versionadded:: 2.0
+
         reason: Optional[:class:`str`]
             The reason for creating this invite. Shows up on the audit log.
 
@@ -883,10 +1069,23 @@ async def create_invite(self, *, reason=None, **fields):
             The invite that was created.
         """
 
-        data = await self._state.http.create_invite(self.id, reason=reason, **fields)
-        return Invite.from_incomplete(data=data, state=self._state)
-
-    async def invites(self):
+        data = await self._state.http.create_invite(
+            self.id,
+            reason=reason,
+            max_age=max_age,
+            max_uses=max_uses,
+            temporary=temporary,
+            unique=unique,
+            target_type=int(target_type) if target_type else None,
+            target_user_id=target_user.id if target_user else None,
+            target_application_id=target_application_id,
+        )
+        invite = Invite.from_incomplete(data=data, state=self._state)
+        if target_event:
+            invite.set_scheduled_event(target_event)
+        return invite
+
+    async def invites(self) -> List[Invite]:
         """|coro|
 
         Returns a list of all active instant invites from this channel.
@@ -917,29 +1116,57 @@ async def invites(self):
 
         return result
 
-class Messageable(metaclass=abc.ABCMeta):
+
+class Messageable:
     """An ABC that details the common operations on a model that can send messages.
 
     The following implement this ABC:
 
     - :class:`~discord.TextChannel`
+    - :class:`~discord.VoiceChannel`
     - :class:`~discord.DMChannel`
     - :class:`~discord.GroupChannel`
     - :class:`~discord.User`
     - :class:`~discord.Member`
-    - :class:`~discord.ext.commands.Context`
+    - :class:`~discord.ext.sub_commands.Context`
     """
-
+    if TYPE_CHECKING:
+        _state: ConnectionState
+        id: int
+    
     __slots__ = ()
 
+    @property
+    def is_partial(self) -> bool:
+        """:class:`bool`: Whether this channel is considered as a partial one.
+        Default to ``False`` for all subclasses of :class:`~discord.abc.Messageable` except :class:`~discord.PartialMessageable`.
+        """
+        return False
+
     @abc.abstractmethod
     async def _get_channel(self):
         raise NotImplementedError
 
-    async def send(self, content=None, *, tts=False, embed=None, embeds=None, components=None, file=None,
-                                          files=None, delete_after=None, nonce=None,
-                                          allowed_mentions=None, reference=None,
-                                          mention_author=None, hidden=None, **kwargs):
+    async def send(
+            self,
+            content: Optional[utils.SupportsStr] = None,
+            *,
+            tts: bool = False,
+            embed: Optional[Embed] = None,
+            embeds: Optional[List[Embed]] = None,
+            components: Optional[List[Union[ActionRow, List[Union[Button, BaseSelect]]]]] = None,
+            file: Optional[File] = None,
+            files: Optional[List[File]] = None,
+            stickers: Optional[List[GuildSticker]] = None,
+            delete_after: Optional[float] = None,
+            nonce: Optional[int] = None,
+            allowed_mentions: Optional[AllowedMentions] = None,
+            reference: Optional[Union[Message, MessageReference]] = None,
+            mention_author: Optional[bool] = None,
+            suppress_embeds: bool = False,
+            suppress_notifications: bool = False,
+            voice_message: bool = False
+    ) -> Message:  # sourcery skip: raise-from-previous-error
         """|coro|
 
         Sends a message to the destination with the content given.
@@ -951,7 +1178,6 @@ async def send(self, content=None, *, tts=False, embed=None, embeds=None, compon
         To upload a single file, the ``file`` parameter should be used with a
         single :class:`~discord.File` object. To upload multiple files, the ``files``
         parameter should be used with a :class:`list` of :class:`~discord.File` objects.
-        **Specifying both parameters will lead to an exception**.
 
         If the ``embed`` parameter is provided, it must be of type :class:`~discord.Embed` and
         it must be a rich embed type.
@@ -966,12 +1192,15 @@ async def send(self, content=None, *, tts=False, embed=None, embeds=None, compon
             The rich embed for the content.
         embeds: List[:class:`~discord.Embed`]
             A list containing up to ten embeds
-        components: List[Union[:class:`ActionRow`, List[Union[:class:`Button`, :class:`SelectMenu`]]]]
-            A list of :type:`discord.ActionRow`'s or a list of :class:`Button`'s or :class:`SelectMenu`'
+        components: List[Union[:class:`~discord.ActionRow`, List[Union[:class:`~discord.Button`, :ref:`Select <select-like-objects>`]]]]
+            A list of up to five :class:`~discord.ActionRow`s or :class:`list`,
+            each containing up to five :class:`~discord.Button` or one :ref:`Select <select-like-objects>` like object.
         file: :class:`~discord.File`
             The file to upload.
         files: List[:class:`~discord.File`]
-            A list of files to upload. Must be a maximum of 10.
+            A :class:`list` of files to upload. Must be a maximum of 10.
+        stickers: List[:class:`~discord.GuildSticker`]
+            A list of up to 3 :class:`discord.GuildSticker` that should be sent with the message.
         nonce: :class:`int`
             The nonce to use for sending this message. If the message was successfully sent,
             then the message will have a nonce with this value.
@@ -1002,10 +1231,20 @@ async def send(self, content=None, *, tts=False, embed=None, embeds=None, compon
 
             .. versionadded:: 1.6
 
-        hidden: Optional[:class:`bool`]
-            If :bool:`True` the message will be only bee visible for the performer of the interaction.
-            If this isnt called within an :class:`RawInteractionCreateEvent` it will be ignored
-
+        suppress_embeds: :class:`bool`
+            Whether to supress embeds send with the message, default to :obj:`False`
+        
+        suppress_notifications: :class:`bool`
+            Whether to suppress desktop- & push-notifications for this message, default to :obj:`False`
+            
+            Users will still see a ping-symbol when they are mentioned in the message, or the message is in a dm channel.
+            
+            .. versionadded:: 2.0
+
+        voice_message: :class:`bool`
+            Whether to classify the attached file as a voice message, default to :obj:`False`
+            Voice messages require a single :class:`~discord.File` attachment with `waveform` and `duration` set.
+            
         Raises
         --------
         ~discord.HTTPException
@@ -1027,135 +1266,53 @@ async def send(self, content=None, *, tts=False, embed=None, embeds=None, compon
         channel = await self._get_channel()
         state = self._state
         content = str(content) if content is not None else None
+        previous_allowed_mentions = state.allowed_mentions
 
-        if embed is not None:
-            embed = embed.to_dict()
-        embed_list = []
-        if embed:
-            embed_list.append(embed)
-        if embeds:
-            embed_list.extend([e.to_dict() for e in embeds])
-        embeds = embed_list
-        if len(embeds) > 10:
-            raise InvalidArgument(f'The maximum number of embeds that can be send with a message is 10, got: {len(embeds)}')
-        if components:
-            _components = []
-            for component in ([components] if not isinstance(components, list) else components):
-                if isinstance(component, (Button, SelectMenu)):
-                    _components.extend(ActionRow(component).to_dict())
-                elif isinstance(component, ActionRow):
-                    _components.extend(component.to_dict())
-                elif isinstance(component, list):
-                    _components.extend(ActionRow(*[obj for obj in component if isinstance(obj, (Button, SelectMenu))]).to_dict())
-            components = _components
-
-        if allowed_mentions is not None:
-            if state.allowed_mentions is not None:
-                allowed_mentions = state.allowed_mentions.merge(allowed_mentions).to_dict()
-            else:
-                allowed_mentions = allowed_mentions.to_dict()
+        if stickers is not None:
+            sticker_ids = [str(sticker.id) for sticker in stickers]
         else:
-            allowed_mentions = state.allowed_mentions and state.allowed_mentions.to_dict()
-
-        if mention_author is not None:
-            allowed_mentions = allowed_mentions or AllowedMentions().to_dict()
-            allowed_mentions['replied_user'] = bool(mention_author)
+            sticker_ids = MISSING
 
         if reference is not None:
             try:
                 reference = reference.to_message_reference_dict()
             except AttributeError:
-                raise InvalidArgument('reference parameter must be Message or MessageReference') from None
-
-        if file is not None and files is not None:
-            raise InvalidArgument('cannot pass both file and files parameter to send()')
-
-        is_interaction_response = kwargs.pop('__is_interaction_response', False)
-        deferred = kwargs.pop('__deferred', False)
-        use_webhook = kwargs.pop('__use_webhook', False)
-        interaction_id = kwargs.pop('__interaction_id', None)
-        interaction_token = kwargs.pop('__interaction_token', None)
-        application_id = kwargs.pop('__application_id', None)
-        followup = kwargs.pop('followup', False)
-        if is_interaction_response:
-            if hidden and file or files:
-                raise AttributeError('An ephemeral(hidden) Message could not contain file(s)')
-        if file is not None:
-            if not isinstance(file, File):
-                raise InvalidArgument('file parameter must be File')
-
-            try:
-                if hidden is not None:
-                    data = await state.http.send_interaction_response(use_webhook=use_webhook,
-                                                                      interaction_id=interaction_id,
-                                                                      token=interaction_token,
-                                                                      application_id=application_id,
-                                                                      deferred=deferred,
-                                                                      files=[file], allowed_mentions=allowed_mentions,
-                                                                      content=content, tts=tts, embeds=embeds,
-                                                                      components=components,
-                                                                      nonce=nonce, message_reference=reference,
-                                                                      flags=64 if hidden is True else None,
-                                                                      followup=followup)
-                else:
-                    data = await state.http.send_files(channel.id, files=[file], allowed_mentions=allowed_mentions,
-                                                       content=content, tts=tts, embeds=embeds, components=components,
-                                                       nonce=nonce, message_reference=reference)
-            finally:
-                file.close()
-
-        elif files is not None:
-            if len(files) > 10:
-                raise InvalidArgument('files parameter must be a list of up to 10 elements')
-            elif not all(isinstance(file, File) for file in files):
-                raise InvalidArgument('files parameter must be a list of File')
-
-            try:
-                if hidden is not None:
-                    data = await state.http.send_interaction_response(use_webhook=use_webhook,
-                                                                      interaction_id=interaction_id,
-                                                                      token=interaction_token,
-                                                                      application_id=application_id,
-                                                                      deferred=deferred,
-                                                                      files=file, allowed_mentions=allowed_mentions,
-                                                                      content=content, tts=tts, embeds=embeds,
-                                                                      components=components,
-                                                                      nonce=nonce, message_reference=reference,
-                                                                      flags=64 if hidden is True else None,
-                                                                      followup=followup or deferred)
-                else:
-                    data = await state.http.send_files(channel.id, files=files, content=content, tts=tts,
-                                                       embeds=embeds, components=components, nonce=nonce,
-                                                       allowed_mentions=allowed_mentions, message_reference=reference)
-            finally:
-                for f in files:
-                    f.close()
+                raise InvalidArgument('reference parameter must be Message, PartialMessage or MessageReference')
         else:
-            if hidden is not None:
-                data = await state.http.send_interaction_response(use_webhook=use_webhook,
-                                                                  interaction_id=interaction_id,
-                                                                  token=interaction_token,
-                                                                  application_id=application_id,
-                                                                  deferred=deferred, allowed_mentions=allowed_mentions,
-                                                                  content=content, tts=tts, embeds=embeds,
-                                                                  components=components,
-                                                                  nonce=nonce, message_reference=reference,
-                                                                  flags=64 if hidden is True else None,
-                                                                  followup=followup)
-            else:
-                data = await state.http.send_message(channel.id, content, tts=tts, embeds=embeds, components=components,
-                                                                          nonce=nonce, allowed_mentions=allowed_mentions,
-                                                                          message_reference=reference)
-        if not hidden is True:
-            if not isinstance(data, dict) and not hidden is None:
-                """Thanks Discord that they dont return the message when we send the interaction callback"""
-                data = await state.http.get_original_interaction_response(application_id=application_id, interaction_token=interaction_token)
-            ret = state.create_message(channel=channel, data=data)
-            if (delete_after is not None) and (not hidden is True):
-                await ret.delete(delay=delete_after)
-            return ret
-
-    async def trigger_typing(self):
+            reference = MISSING
+
+        if suppress_embeds or suppress_notifications or voice_message:
+            from .flags import MessageFlags
+            flags = MessageFlags._from_value(0)
+            flags.suppress_embeds = suppress_embeds
+            flags.suppress_notifications = suppress_notifications
+            flags.is_voice_message = voice_message
+        else:
+            flags = MISSING
+
+        with handle_message_parameters(
+            content=content,
+            tts=tts,
+            nonce=nonce,
+            flags=flags,
+            file=file if file is not None else MISSING,
+            files=files if files is not None else MISSING,
+            embed=embed if embed is not None else MISSING,
+            embeds=embeds if embeds is not None else MISSING,
+            components=components,
+            allowed_mentions=allowed_mentions,
+            previous_allowed_mentions=previous_allowed_mentions,
+            message_reference=reference,
+            stickers=sticker_ids,
+            mention_author=mention_author
+        ) as params:
+            data = await state.http.send_message(channel.id, params=params)
+        ret = state.create_message(channel=channel, data=data)
+        if delete_after is not None:
+            await ret.delete(delay=delete_after)
+        return ret
+
+    async def trigger_typing(self) -> None:
         """|coro|
 
         Triggers a *typing* indicator to the destination.
@@ -1166,7 +1323,7 @@ async def trigger_typing(self):
         channel = await self._get_channel()
         await self._state.http.send_typing(channel.id)
 
-    def typing(self):
+    def typing(self) -> Typing:
         """Returns a context manager that allows you to type for an indefinite period of time.
 
         This is useful for denoting long computations in your bot.
@@ -1180,12 +1337,14 @@ def typing(self):
 
             async with channel.typing():
                 # do expensive stuff here
-                await channel.send('done!')
+                await asyncio.sleep(15)
+
+            await channel.send('done!')
 
         """
         return Typing(self)
 
-    async def fetch_message(self, id):
+    async def fetch_message(self, id: int, /) -> Message:
         """|coro|
 
         Retrieves a single :class:`~discord.Message` from the destination.
@@ -1216,7 +1375,7 @@ async def fetch_message(self, id):
         data = await self._state.http.get_message(channel.id, id)
         return self._state.create_message(channel=channel, data=data)
 
-    async def pins(self):
+    async def pins(self) -> List[Message]:
         """|coro|
 
         Retrieves all messages that are currently pinned in the channel.
@@ -1243,7 +1402,15 @@ async def pins(self):
         data = await state.http.pins_from(channel.id)
         return [state.create_message(channel=channel, data=m) for m in data]
 
-    def history(self, *, limit=100, before=None, after=None, around=None, oldest_first=None):
+    def history(
+            self,
+            *,
+            limit: Optional[int] = 100,
+            before: Optional[SnowflakeTime] = None,
+            after: Optional[SnowflakeTime] = None,
+            around: Optional[SnowflakeTime] = None,
+            oldest_first: Optional[bool] = None
+    ) -> HistoryIterator:
         """Returns an :class:`~discord.AsyncIterator` that enables receiving the destination's message history.
 
         You must have :attr:`~Permissions.read_message_history` permissions to use this.
@@ -1281,7 +1448,7 @@ def history(self, *, limit=100, before=None, after=None, around=None, oldest_fir
             Retrieve messages around this date or message.
             If a date is provided it must be a timezone-naive datetime representing UTC time.
             When using this argument, the maximum limit is 101. Note that if the limit is an
-            even number then this will return at most limit + 1 messages.
+            even number, then this will return at most limit + 1 messages.
         oldest_first: Optional[:class:`bool`]
             If set to ``True``, return messages in oldest->newest order. Defaults to ``True`` if
             ``after`` is specified, otherwise ``False``.
@@ -1300,25 +1467,46 @@ def history(self, *, limit=100, before=None, after=None, around=None, oldest_fir
         """
         return HistoryIterator(self, limit=limit, before=before, after=after, around=around, oldest_first=oldest_first)
 
-class Connectable(metaclass=abc.ABCMeta):
+
+class Connectable(Protocol):
     """An ABC that details the common operations on a channel that can
     connect to a voice server.
 
     The following implement this ABC:
 
     - :class:`~discord.VoiceChannel`
+    - :class:`~discord.StageChannel`
+
+    Note
+    ----
+    This ABC is not decorated with :func:`typing.runtime_checkable`, so will fail :func:`isinstance`/:func:`issubclass`
+    checks.
     """
     __slots__ = ()
+    _state: ConnectionState
 
-    @abc.abstractmethod
     def _get_voice_client_key(self):
         raise NotImplementedError
 
-    @abc.abstractmethod
     def _get_voice_state_pair(self):
         raise NotImplementedError
 
-    async def connect(self, *, timeout=60.0, reconnect=True, cls=VoiceClient):
+    def __call__(
+            self,
+            *,
+            timeout: float = 60.0,
+            reconnect: bool = True,
+            cls: VP = VoiceClient
+    ) -> Coroutine[None, None, VP]:
+        return self.connect(timeout=timeout, reconnect=reconnect, cls=cls)
+
+    async def connect(
+            self,
+            *,
+            timeout: float = 60.0,
+            reconnect: bool = True,
+            cls: VP = VoiceClient
+    ) -> VP:
         """|coro|
 
         Connects to voice and creates a :class:`VoiceClient` to establish
@@ -1376,3 +1564,13 @@ async def connect(self, *, timeout=60.0, reconnect=True, cls=VoiceClient):
             raise # re-raise
 
         return voice
+
+
+class Mentionable:
+    """This class can be used as an annotation for a slash-command option to allow both :class:`Member` and :class:`Role`"""
+    pass
+
+if TYPE_CHECKING:
+    class Mentionable(User, Member, Role):
+        """This class can be used as an annotation for an slash-command option to allow both :class:`Member` and :class:`Role`"""
+        pass
diff --git a/discord/activity.py b/discord/activity.py
index cf5192ad..15d71b3e 100644
--- a/discord/activity.py
+++ b/discord/activity.py
@@ -3,7 +3,7 @@
 """
 The MIT License (MIT)
 
-Copyright (c) 2015-present Rapptz
+Copyright (c) 2015-2021 Rapptz & (c) 2021-present mccoderpy
 
 Permission is hereby granted, free of charge, to any person obtaining a
 copy of this software and associated documentation files (the "Software"),
@@ -23,8 +23,18 @@
 FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 DEALINGS IN THE SOFTWARE.
 """
+from __future__ import annotations
 
 import datetime
+from typing import (
+    TYPE_CHECKING,
+    Any,
+    Dict,
+    List,
+    Union,
+    Optional,
+    overload
+)
 
 from .asset import Asset
 from .enums import ActivityType, try_enum
@@ -73,6 +83,13 @@
 sync_id: str
 session_id: str
 flags: int
+buttons: list[dict]
+    label: str (max: 32)
+    url: str (max: 512)
+last year
+
+NOTE: Bots cannot access a user's activity button URLs. When received through the
+gateway, the type of the buttons field will be list[str].
 
 There are also activity flags which are mostly uninteresting for the library atm.
 
@@ -83,9 +100,16 @@
     JOIN_REQUEST: 8,
     SYNC: 16,
     PLAY: 32
+    PARTY_PRIVACY_FRIENDS: 64
+    PARTY_PRIVACY_VOICE_CHANNEL: 128
+    EMBEDDED: 256
 }
 """
 
+if TYPE_CHECKING:
+    from .types.activity import Activity as ActivityData
+    from .types.activity import ActivityAssets, ActivityParty, ActivityTimestamps
+
 class BaseActivity:
     """The base activity that all user-settable activities inherit from.
     A user-settable activity is one that can be used in :meth:`Client.change_presence`.
@@ -107,10 +131,10 @@ class BaseActivity:
     __slots__ = ('_created_at',)
 
     def __init__(self, **kwargs):
-        self._created_at = kwargs.pop('created_at', None)
+        self._created_at: Optional[float] = kwargs.pop('created_at', None)
 
     @property
-    def created_at(self):
+    def created_at(self) -> Optional[datetime.datetime]:
         """Optional[:class:`datetime.datetime`]: When the user started doing this activity in UTC.
 
         .. versionadded:: 1.3
@@ -118,6 +142,10 @@ def created_at(self):
         if self._created_at is not None:
             return datetime.datetime.utcfromtimestamp(self._created_at / 1000)
 
+    def to_dict(self):
+        raise NotImplementedError()
+
+
 class Activity(BaseActivity):
     """Represents an activity in Discord.
 
@@ -168,31 +196,44 @@ class Activity(BaseActivity):
         - ``size``: A list of up to two integer elements denoting (current_size, maximum_size).
     emoji: Optional[:class:`PartialEmoji`]
         The emoji that belongs to this activity.
+    buttons: Union[List[Dict[:class:`str`, :class:`str`]], List[:class:`str`]]
+        A list of dictionaries representing custom buttons shown in a rich presence.
+        Each dictionary contains the following keys:
+
+        - ``label``: A string representing the text shown on the button.
+        - ``url``: A string representing the URL opened upon clicking the button.
+
+        .. note::
+
+            Bots cannot access a user's activity button URLs. Therefore, the type of this attribute
+            will be List[:class:`str`] when received through the gateway.
+
+        .. versionadded:: 2.0
+
     """
 
     __slots__ = ('state', 'details', '_created_at', 'timestamps', 'assets', 'party',
                  'flags', 'sync_id', 'session_id', 'type', 'name', 'url',
-                 'application_id', 'emoji')
+                 'application_id', 'buttons', 'emoji')
 
-    def __init__(self, **kwargs):
+    def __init__(self, **kwargs) -> None:
         super().__init__(**kwargs)
-        self.state = kwargs.pop('state', None)
-        self.details = kwargs.pop('details', None)
-        self.timestamps = kwargs.pop('timestamps', {})
-        self.assets = kwargs.pop('assets', {})
-        self.party = kwargs.pop('party', {})
-        self.application_id = _get_as_snowflake(kwargs, 'application_id')
-        self.name = kwargs.pop('name', None)
-        self.url = kwargs.pop('url', None)
-        self.flags = kwargs.pop('flags', 0)
-        self.sync_id = kwargs.pop('sync_id', None)
-        self.session_id = kwargs.pop('session_id', None)
-        self.type = try_enum(ActivityType, kwargs.pop('type', -1))
+        self.state: Optional[str] = kwargs.pop('state', None)
+        self.details: Optional[str] = kwargs.pop('details', None)
+        self.timestamps: ActivityTimestamps = kwargs.pop('timestamps', {})
+        self.assets: ActivityAssets = kwargs.pop('assets', {})
+        self.party: ActivityParty = kwargs.pop('party', {})
+        self.application_id: Optional[int] = _get_as_snowflake(kwargs, 'application_id')
+        self.name: Optional[str] = kwargs.pop('name', None)
+        self.url: Optional[str] = kwargs.pop('url', None)
+        self.flags: int = kwargs.pop('flags', 0)
+        self.sync_id: Optional[str] = kwargs.pop('sync_id', None)
+        self.session_id: Optional[str] = kwargs.pop('session_id', None)
+        self.type: ActivityType = try_enum(ActivityType, kwargs.pop('type', -1))
+        self.buttons: List[str] = kwargs.pop('buttons', [])
         emoji = kwargs.pop('emoji', None)
-        if emoji is not None:
-            self.emoji = PartialEmoji.from_dict(emoji)
-        else:
-            self.emoji = None
+
+        self.emoji: Optional[PartialEmoji] = PartialEmoji.from_dict(emoji) if emoji is not None else None
 
     def __repr__(self):
         attrs = (
@@ -205,9 +246,9 @@ def __repr__(self):
             'emoji',
         )
         mapped = ' '.join('%s=%r' % (attr, getattr(self, attr)) for attr in attrs)
-        return '<Activity %s>' % mapped
+        return f'<Activity {mapped}>'
 
-    def to_dict(self):
+    def to_dict(self) -> Dict[str, Any]:
         ret = {}
         for attr in self.__slots__:
             value = getattr(self, attr, None)
@@ -224,7 +265,7 @@ def to_dict(self):
         return ret
 
     @property
-    def start(self):
+    def start(self) -> Optional[datetime.datetime]:
         """Optional[:class:`datetime.datetime`]: When the user started doing this activity in UTC, if applicable."""
         try:
             return datetime.datetime.utcfromtimestamp(self.timestamps['start'] / 1000)
@@ -232,7 +273,7 @@ def start(self):
             return None
 
     @property
-    def end(self):
+    def end(self) -> Optional[datetime.datetime]:
         """Optional[:class:`datetime.datetime`]: When the user will stop doing this activity in UTC, if applicable."""
         try:
             return datetime.datetime.utcfromtimestamp(self.timestamps['end'] / 1000)
@@ -240,7 +281,7 @@ def end(self):
             return None
 
     @property
-    def large_image_url(self):
+    def large_image_url(self) -> Optional[str]:
         """Optional[:class:`str`]: Returns a URL pointing to the large image asset of this activity if applicable."""
         if self.application_id is None:
             return None
@@ -250,10 +291,10 @@ def large_image_url(self):
         except KeyError:
             return None
         else:
-            return Asset.BASE + '/app-assets/{0}/{1}.png'.format(self.application_id, large_image)
+            return f'{Asset.BASE}/app-assets/{self.application_id}/{large_image}.png'
 
     @property
-    def small_image_url(self):
+    def small_image_url(self) -> Optional[str]:
         """Optional[:class:`str`]: Returns a URL pointing to the small image asset of this activity if applicable."""
         if self.application_id is None:
             return None
@@ -263,14 +304,15 @@ def small_image_url(self):
         except KeyError:
             return None
         else:
-            return Asset.BASE + '/app-assets/{0}/{1}.png'.format(self.application_id, small_image)
+            return f'{Asset.BASE}/app-assets/{self.application_id}/{small_image}.png'
+
     @property
-    def large_image_text(self):
+    def large_image_text(self) -> Optional[str]:
         """Optional[:class:`str`]: Returns the large image asset hover text of this activity if applicable."""
         return self.assets.get('large_text', None)
 
     @property
-    def small_image_text(self):
+    def small_image_text(self) -> Optional[str]:
         """Optional[:class:`str`]: Returns the small image asset hover text of this activity if applicable."""
         return self.assets.get('small_text', None)
 
@@ -315,9 +357,9 @@ class Game(BaseActivity):
 
     __slots__ = ('name', '_end', '_start')
 
-    def __init__(self, name, **extra):
+    def __init__(self, name: str, **extra) -> None:
         super().__init__(**extra)
-        self.name = name
+        self.name: str = name
 
         try:
             timestamps = extra['timestamps']
@@ -332,12 +374,12 @@ def _extract_timestamp(self, data, key):
         try:
             dt = data[key]
         except KeyError:
-            setattr(self, '_' + key, 0)
+            setattr(self, f'_{key}', 0)
         else:
-            setattr(self, '_' + key, dt.timestamp() * 1000.0)
+            setattr(self, f'_{key}', dt.timestamp() * 1000.0)
 
     @property
-    def type(self):
+    def type(self) -> ActivityType:
         """:class:`ActivityType`: Returns the game's type. This is for compatibility with :class:`Activity`.
 
         It always returns :attr:`ActivityType.playing`.
@@ -345,26 +387,26 @@ def type(self):
         return ActivityType.playing
 
     @property
-    def start(self):
+    def start(self) -> Optional[datetime.datetime]:
         """Optional[:class:`datetime.datetime`]: When the user started playing this game in UTC, if applicable."""
         if self._start:
-            return datetime.datetime.utcfromtimestamp(self._start / 1000)
+            return datetime.datetime.fromtimestamp(self._start / 1000, tz=datetime.timezone.utc)
         return None
 
     @property
-    def end(self):
+    def end(self) -> Optional[datetime.datetime]:
         """Optional[:class:`datetime.datetime`]: When the user will stop playing this game in UTC, if applicable."""
         if self._end:
-            return datetime.datetime.utcfromtimestamp(self._end / 1000)
+            return datetime.datetime.fromtimestamp(self._end / 1000, tz=datetime.timezone.utc)
         return None
 
-    def __str__(self):
+    def __str__(self) -> str:
         return str(self.name)
 
-    def __repr__(self):
-        return '<Game name={0.name!r}>'.format(self)
+    def __repr__(self) -> str:
+        return f'<Game name={self.name!r}>'
 
-    def to_dict(self):
+    def to_dict(self) -> Dict[str, Any]:
         timestamps = {}
         if self._start:
             timestamps['start'] = self._start
@@ -378,15 +420,16 @@ def to_dict(self):
             'timestamps': timestamps
         }
 
-    def __eq__(self, other):
+    def __eq__(self, other: Any) -> bool:
         return isinstance(other, Game) and other.name == self.name
 
-    def __ne__(self, other):
+    def __ne__(self, other: Any) -> bool:
         return not self.__eq__(other)
 
-    def __hash__(self):
+    def __hash__(self) -> int:
         return hash(self.name)
 
+
 class Streaming(BaseActivity):
     """A slimmed down version of :class:`Activity` that represents a Discord streaming status.
 
@@ -429,36 +472,36 @@ class Streaming(BaseActivity):
     url: :class:`str`
         The stream's URL.
     assets: :class:`dict`
-        A dictionary comprising of similar keys than those in :attr:`Activity.assets`.
+        A dictionary comprising similar keys than those in :attr:`Activity.assets`.
     """
 
     __slots__ = ('platform', 'name', 'game', 'url', 'details', 'assets')
 
-    def __init__(self, *, name, url, **extra):
+    def __init__(self, *, name: Optional[str], url: str, **extra: Any) -> None:
         super().__init__(**extra)
-        self.platform = name
-        self.name = extra.pop('details', name)
-        self.game = extra.pop('state', None)
-        self.url = url
-        self.details = extra.pop('details', self.name) # compatibility
-        self.assets = extra.pop('assets', {})
+        self.platform: Optional[str] = name
+        self.name: Optional[str] = extra.pop('details', name)
+        self.game: Optional[str] = extra.pop('state', None)
+        self.url: str = url
+        self.details: Optional[str] = extra.pop('details', self.name)  # compatibility
+        self.assets: ActivityAssets = extra.pop('assets', {})
 
     @property
-    def type(self):
+    def type(self) -> ActivityType:
         """:class:`ActivityType`: Returns the game's type. This is for compatibility with :class:`Activity`.
 
         It always returns :attr:`ActivityType.streaming`.
         """
         return ActivityType.streaming
 
-    def __str__(self):
+    def __str__(self) -> str:
         return str(self.name)
 
-    def __repr__(self):
-        return '<Streaming name={0.name!r}>'.format(self)
+    def __repr__(self) -> str:
+        return f'<Streaming name={self.name!r}>'
 
     @property
-    def twitch_name(self):
+    def twitch_name(self) -> Optional[str]:
         """Optional[:class:`str`]: If provided, the twitch name of the user streaming.
 
         This corresponds to the ``large_image`` key of the :attr:`Streaming.assets`
@@ -472,7 +515,7 @@ def twitch_name(self):
         else:
             return name[7:] if name[:7] == 'twitch:' else None
 
-    def to_dict(self):
+    def to_dict(self) -> Dict[str, Any]:
         ret = {
             'type': ActivityType.streaming.value,
             'name': str(self.name),
@@ -483,15 +526,20 @@ def to_dict(self):
             ret['details'] = self.details
         return ret
 
-    def __eq__(self, other):
-        return isinstance(other, Streaming) and other.name == self.name and other.url == self.url
+    def __eq__(self, other: Any) -> bool:
+        return (
+                isinstance(other, Streaming)
+                and other.name == self.name
+                and other.url == self.url
+        )
 
-    def __ne__(self, other):
+    def __ne__(self, other: Any) -> bool:
         return not self.__eq__(other)
 
-    def __hash__(self):
+    def __hash__(self) -> int:
         return hash(self.name)
 
+
 class Spotify:
     """Represents a Spotify listening activity from Discord. This is a special case of
     :class:`Activity` that makes it easier to work with the Spotify integration.
@@ -518,18 +566,18 @@ class Spotify:
     __slots__ = ('_state', '_details', '_timestamps', '_assets', '_party', '_sync_id', '_session_id',
                  '_created_at')
 
-    def __init__(self, **data):
-        self._state = data.pop('state', None)
-        self._details = data.pop('details', None)
-        self._timestamps = data.pop('timestamps', {})
-        self._assets = data.pop('assets', {})
-        self._party = data.pop('party', {})
-        self._sync_id = data.pop('sync_id')
-        self._session_id = data.pop('session_id')
-        self._created_at = data.pop('created_at', None)
+    def __init__(self, **data) -> None:
+        self._state: str = data.pop('state', None)
+        self._details: str = data.pop('details', None)
+        self._timestamps: ActivityTimestamps = data.pop('timestamps', {})
+        self._assets: ActivityAssets = data.pop('assets', {})
+        self._party: ActivityParty = data.pop('party', {})
+        self._sync_id: str = data.pop('sync_id')
+        self._session_id: str = data.pop('session_id')
+        self._created_at: Optional[float] = data.pop('created_at', None)
 
     @property
-    def type(self):
+    def type(self) -> ActivityType:
         """:class:`ActivityType`: Returns the activity's type. This is for compatibility with :class:`Activity`.
 
         It always returns :attr:`ActivityType.listening`.
@@ -537,7 +585,7 @@ def type(self):
         return ActivityType.listening
 
     @property
-    def created_at(self):
+    def created_at(self) -> Optional[datetime.datetime]:
         """Optional[:class:`datetime.datetime`]: When the user started listening in UTC.
 
         .. versionadded:: 1.3
@@ -546,22 +594,24 @@ def created_at(self):
             return datetime.datetime.utcfromtimestamp(self._created_at / 1000)
 
     @property
-    def colour(self):
+    def colour(self) -> Colour:
         """:class:`Colour`: Returns the Spotify integration colour, as a :class:`Colour`.
 
-        There is an alias for this named :attr:`color`"""
+        There is an alias for this named :attr:`color`
+        """
         return Colour(0x1db954)
 
     @property
-    def color(self):
+    def color(self) -> Colour:
         """:class:`Colour`: Returns the Spotify integration colour, as a :class:`Colour`.
 
-        There is an alias for this named :attr:`colour`"""
+        This is an alias for :attr:`colour`.
+        """
         return self.colour
 
-    def to_dict(self):
+    def to_dict(self) -> Dict[str, Any]:
         return {
-            'flags': 48, # SYNC | PLAY
+            'flags': 48,  # SYNC | PLAY
             'name': 'Spotify',
             'assets': self._assets,
             'party': self._party,
@@ -573,38 +623,42 @@ def to_dict(self):
         }
 
     @property
-    def name(self):
+    def name(self) -> str:
         """:class:`str`: The activity's name. This will always return "Spotify"."""
         return 'Spotify'
 
-    def __eq__(self, other):
-        return (isinstance(other, Spotify) and other._session_id == self._session_id
-                and other._sync_id == self._sync_id and other.start == self.start)
+    def __eq__(self, other: Any) -> bool:
+        return (
+                isinstance(other, Spotify)
+                and other._session_id == self._session_id
+                and other._sync_id == self._sync_id
+                and other.start == self.start
+        )
 
-    def __ne__(self, other):
+    def __ne__(self, other: Any) -> bool:
         return not self.__eq__(other)
 
-    def __hash__(self):
+    def __hash__(self) -> int:
         return hash(self._session_id)
 
-    def __str__(self):
+    def __str__(self) -> str:
         return 'Spotify'
 
-    def __repr__(self):
-        return '<Spotify title={0.title!r} artist={0.artist!r} track_id={0.track_id!r}>'.format(self)
+    def __repr__(self) -> str:
+        return f'<Spotify title={self.title!r} artist={self.artist!r} track_id={self.track_id!r}>'
 
     @property
-    def title(self):
+    def title(self) -> str:
         """:class:`str`: The title of the song being played."""
         return self._details
 
     @property
-    def artists(self):
+    def artists(self) -> List[str]:
         """List[:class:`str`]: The artists of the song being played."""
         return self._state.split('; ')
 
     @property
-    def artist(self):
+    def artist(self) -> str:
         """:class:`str`: The artist of the song being played.
 
         This does not attempt to split the artist information into
@@ -618,39 +672,45 @@ def album(self):
         return self._assets.get('large_text', '')
 
     @property
-    def album_cover_url(self):
+    def album_cover_url(self) -> str:
         """:class:`str`: The album cover image URL from Spotify's CDN."""
         large_image = self._assets.get('large_image', '')
         if large_image[:8] != 'spotify:':
             return ''
         album_image_id = large_image[8:]
-        return 'https://i.scdn.co/image/' + album_image_id
+        return f'https://i.scdn.co/image/{album_image_id}'
 
     @property
-    def track_id(self):
+    def track_id(self) -> str:
         """:class:`str`: The track ID used by Spotify to identify this song."""
         return self._sync_id
 
     @property
-    def start(self):
+    def start(self) -> datetime.datetime:
         """:class:`datetime.datetime`: When the user started playing this song in UTC."""
-        return datetime.datetime.utcfromtimestamp(self._timestamps['start'] / 1000)
+        return datetime.datetime.fromtimestamp(self._timestamps['start'] / 1000, tz=datetime.timezone.utc)
 
     @property
-    def end(self):
+    def end(self) -> datetime.datetime:
         """:class:`datetime.datetime`: When the user will stop playing this song in UTC."""
-        return datetime.datetime.utcfromtimestamp(self._timestamps['end'] / 1000)
+        return datetime.datetime.fromtimestamp(self._timestamps['end'] / 1000, tz=datetime.timezone.utc)
 
     @property
-    def duration(self):
+    def duration(self) -> datetime.timedelta:
         """:class:`datetime.timedelta`: The duration of the song being played."""
         return self.end - self.start
 
     @property
-    def party_id(self):
+    def position(self) -> float:
+        """:class:`float`: The current position of the song being played."""
+        return (datetime.datetime.now(tz=datetime.timezone.utc) - self.start).total_seconds()
+
+    @property
+    def party_id(self) -> str:
         """:class:`str`: The party ID of the listening party."""
         return self._party.get('id', '')
 
+
 class CustomActivity(BaseActivity):
     """Represents a Custom activity from Discord.
 
@@ -684,13 +744,20 @@ class CustomActivity(BaseActivity):
 
     __slots__ = ('name', 'emoji', 'state')
 
-    def __init__(self, name, *, emoji=None, **extra):
+    def __init__(
+            self,
+            name: Optional[str],
+            *,
+            emoji: Optional[PartialEmoji] = None,
+            **extra: Any
+    ) -> None:
         super().__init__(**extra)
-        self.name = name
-        self.state = extra.pop('state', None)
+        self.name: Optional[str] = name
+        self.state: Optional[str] = extra.pop('state', None)
         if self.name == 'Custom Status':
             self.name = self.state
 
+        self.emoji: Optional[PartialEmoji]
         if emoji is None:
             self.emoji = emoji
         elif isinstance(emoji, dict):
@@ -700,17 +767,17 @@ def __init__(self, name, *, emoji=None, **extra):
         elif isinstance(emoji, PartialEmoji):
             self.emoji = emoji
         else:
-            raise TypeError('Expected str, PartialEmoji, or None, received {0!r} instead.'.format(type(emoji)))
+            raise TypeError(f'Expected str, PartialEmoji, or None, received {type(emoji)!r} instead.')
 
     @property
-    def type(self):
+    def type(self) -> ActivityType:
         """:class:`ActivityType`: Returns the activity's type. This is for compatibility with :class:`Activity`.
 
         It always returns :attr:`ActivityType.custom`.
         """
         return ActivityType.custom
 
-    def to_dict(self):
+    def to_dict(self) -> Dict[str, Any]:
         if self.name == self.state:
             o = {
                 'type': ActivityType.custom.value,
@@ -727,28 +794,40 @@ def to_dict(self):
             o['emoji'] = self.emoji.to_dict()
         return o
 
-    def __eq__(self, other):
-        return (isinstance(other, CustomActivity) and other.name == self.name and other.emoji == self.emoji)
+    def __eq__(self, other: Any) -> bool:
+        return (
+            isinstance(other, CustomActivity)
+            and other.name == self.name
+            and other.emoji == self.emoji
+        )
 
-    def __ne__(self, other):
+    def __ne__(self, other: Any) -> bool:
         return not self.__eq__(other)
 
-    def __hash__(self):
+    def __hash__(self) -> int:
         return hash((self.name, str(self.emoji)))
 
-    def __str__(self):
-        if self.emoji:
-            if self.name:
-                return '%s %s' % (self.emoji, self.name)
-            return str(self.emoji)
-        else:
+    def __str__(self) -> str:
+        if not self.emoji:
             return str(self.name)
+        return f'{self.emoji} {self.name}' if self.name else str(self.emoji)
 
-    def __repr__(self):
-        return '<CustomActivity name={0.name!r} emoji={0.emoji!r}>'.format(self)
+    def __repr__(self) -> str:
+        return f'<CustomActivity name={self.name!r} emoji={self.emoji!r}>'
+
+
+ActivityTypes = Union[Activity, Game, CustomActivity, Streaming, Spotify]
+
+
+@overload
+def create_activity(data: ActivityData) -> ActivityTypes: ...
+
+
+@overload
+def create_activity(data: None) -> None: ...
 
 
-def create_activity(data):
+def create_activity(data: Optional[ActivityData]) -> Optional[ActivityTypes]:
     if not data:
         return None
 
@@ -765,9 +844,11 @@ def create_activity(data):
         else:
             return CustomActivity(name=name, **data)
     elif game_type is ActivityType.streaming:
-        if 'url' in data:
-            return Streaming(**data)
-        return Activity(**data)
-    elif game_type is ActivityType.listening and 'sync_id' in data and 'session_id' in data:
+        return Streaming(**data) if 'url' in data else Activity(**data)
+    elif (
+            game_type is ActivityType.listening
+            and 'sync_id' in data
+            and 'session_id' in data
+    ):
         return Spotify(**data)
     return Activity(**data)
diff --git a/discord/appinfo.py b/discord/appinfo.py
index cbc00566..6132effc 100644
--- a/discord/appinfo.py
+++ b/discord/appinfo.py
@@ -3,7 +3,7 @@
 """
 The MIT License (MIT)
 
-Copyright (c) 2015-present Rapptz
+Copyright (c) 2015-2021 Rapptz & (c) 2021-present mccoderpy
 
 Permission is hereby granted, free of charge, to any person obtaining a
 copy of this software and associated documentation files (the "Software"),
@@ -23,11 +23,46 @@
 FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 DEALINGS IN THE SOFTWARE.
 """
+from __future__ import annotations
+
+from typing import (
+    TYPE_CHECKING,
+    Optional,
+    List,
+    NamedTuple
+)
+from typing_extensions import Literal
+
 
 from . import utils
 from .user import User
 from .asset import Asset
 from .team import Team
+from .flags import ApplicationFlags
+
+if TYPE_CHECKING:
+    from .state import ConnectionState
+    from .guild import Guild
+    from .types.appinfo import AppInfo as AppInfoPayload
+
+__all__ = (
+    'InstallParams',
+    'AppInfo',
+)
+
+
+class InstallParams(NamedTuple):
+    """Represents the default install-parameters for an application.
+
+    Attributes
+    -------------
+    scopes: List[:class:`str`]
+        The scopes to add the application to the server with
+    permissions: :class:`str`
+        The permissions to request for the bot role
+    """
+    scopes: List[str]
+    permissions: str
 
 
 class AppInfo:
@@ -62,8 +97,11 @@ class AppInfo:
     summary: :class:`str`
         If this application is a game sold on Discord,
         this field will be the summary field for the store page of its primary SKU.
-
+        
+        Deprecated: This field is deprecated and will be removed in API v11
+        
         .. versionadded:: 1.3
+        .. deprecated:: 2.0
 
     verify_key: :class:`str`
         The hex encoded key for verification in interactions and the
@@ -95,42 +133,69 @@ class AppInfo:
         this field will be the hash of the image on store embeds
 
         .. versionadded:: 1.3
+
+    custom_install_url: Optional[:class:`str`]
+        The default invite-url for the bot if its set.
+    
+    install_params: Optional[:class:`InstallParams`]
+        The settings for the application's default in-app authorization link, if enabled.
+    
+    privacy_policy_url: Optional[:class:`str`]
+        The link to this application's Privacy Policy if set.
+
+    terms_of_service_url: Optional[:class:`str`]
+        The link to this application's Terms of Service if set.
+
+    interactions_endpoint_url: Optional[:class:`str`]
+        The endpoint that will receive interactions with this app if its set.
     """
+
     __slots__ = ('_state', 'description', 'id', 'name', 'rpc_origins',
                  'bot_public', 'bot_require_code_grant', 'owner', 'icon',
                  'summary', 'verify_key', 'team', 'guild_id', 'primary_sku_id',
-                  'slug', 'cover_image')
-
-    def __init__(self, state, data):
-        self._state = state
-
-        self.id = int(data['id'])
-        self.name = data['name']
-        self.description = data['description']
-        self.icon = data['icon']
-        self.rpc_origins = data['rpc_origins']
-        self.bot_public = data['bot_public']
-        self.bot_require_code_grant = data['bot_require_code_grant']
-        self.owner = User(state=self._state, data=data['owner'])
+                 'slug', 'custom_install_url', 'tags', '_flags', 'cover_image',
+                 'privacy_policy_url', 'terms_of_service_url', 'install_params',
+                 'interactions_endpoint_url')
+
+    def __init__(self, *, state: ConnectionState, data: AppInfoPayload):
+        self._state: ConnectionState = state
+        self.id: int = int(data['id'])
+        self.name: str = data['name']
+        self.description: str = data['description']
+        self.icon: str = data['icon']
+        self.rpc_origins: Optional[List[str]] = data['rpc_origins']
+        self.bot_public: bool = data['bot_public']
+        self.bot_require_code_grant: bool = data['bot_require_code_grant']
+        self.custom_install_url: Optional[str] = data.get('custom_install_url', None)
+        install_params = data.get('install_params', None)
+        
+        self.install_params: Optional[InstallParams] = InstallParams(install_params['scopes'], install_params['permissions']) if install_params else None
+        
+        self.tags: List[str] = data.get('tags', [])
+        self._flags: int = data.get('flags', 0)
+        self.owner: User = User(state=self._state, data=data['owner'])
 
         team = data.get('team')
-        self.team = Team(state, team) if team else None
+        self.team: Optional[Team] = Team(state, team) if team else None
 
-        self.summary = data['summary']
-        self.verify_key = data['verify_key']
+        self.summary = ''  # Deprecated - Will be removed in API v11
+        self.verify_key: str = data['verify_key']
 
-        self.guild_id = utils._get_as_snowflake(data, 'guild_id')
+        self.guild_id: Optional[int] = utils._get_as_snowflake(data, 'guild_id')
 
-        self.primary_sku_id = utils._get_as_snowflake(data, 'primary_sku_id')
-        self.slug = data.get('slug')
-        self.cover_image = data.get('cover_image')
+        self.primary_sku_id: Optional[int] = utils._get_as_snowflake(data, 'primary_sku_id')
+        self.slug: Optional[str] = data.get('slug')
+        self.cover_image: Optional[str] = data.get('cover_image')
+        self.privacy_policy_url: Optional[str] = data.get('privacy_policy_url', None)
+        self.terms_of_service_url: Optional[str] = data.get('terms_of_service_url', None)
+        self.interactions_endpoint_url: Optional[str] = data.get('interactions_endpoint_url', None)
 
     def __repr__(self):
         return '<{0.__class__.__name__} id={0.id} name={0.name!r} description={0.description!r} public={0.bot_public} ' \
                'owner={0.owner!r}>'.format(self)
 
     @property
-    def icon_url(self):
+    def icon_url(self) -> Asset:
         """:class:`.Asset`: Retrieves the application's icon asset.
 
         This is equivalent to calling :meth:`icon_url_as` with
@@ -140,7 +205,12 @@ def icon_url(self):
         """
         return self.icon_url_as()
 
-    def icon_url_as(self, *, format='webp', size=1024):
+    def icon_url_as(
+            self,
+            *,
+            format: Literal['png', 'jpeg', 'jpg', 'webp'] = 'webp',
+            size=1024
+    ) -> Asset:
         """Returns an :class:`Asset` for the icon the application has.
 
         The format must be one of 'webp', 'jpeg', 'jpg' or 'png'.
@@ -167,9 +237,8 @@ def icon_url_as(self, *, format='webp', size=1024):
         """
         return Asset._from_icon(self._state, self, 'app', format=format, size=size)
 
-
     @property
-    def cover_image_url(self):
+    def cover_image_url(self) -> Asset:
         """:class:`.Asset`: Retrieves the cover image on a store embed.
 
         This is equivalent to calling :meth:`cover_image_url_as` with
@@ -179,7 +248,7 @@ def cover_image_url(self):
         """
         return self.cover_image_url_as()
 
-    def cover_image_url_as(self, *, format='webp', size=1024):
+    def cover_image_url_as(self, *, format='webp', size=1024) -> Asset:
         """Returns an :class:`Asset` for the image on store embeds
         if this application is a game sold on Discord.
 
@@ -208,10 +277,15 @@ def cover_image_url_as(self, *, format='webp', size=1024):
         return Asset._from_cover_image(self._state, self, format=format, size=size)
 
     @property
-    def guild(self):
+    def guild(self) -> Optional[Guild]:
         """Optional[:class:`Guild`]: If this application is a game sold on Discord,
         this field will be the guild to which it has been linked
 
         .. versionadded:: 1.3
         """
         return self._state._get_guild(int(self.guild_id))
+
+    @property
+    def flags(self) -> ApplicationFlags:
+        return ApplicationFlags._from_value(self._flags)
+
diff --git a/discord/application_commands.py b/discord/application_commands.py
new file mode 100644
index 00000000..e0fbe6a1
--- /dev/null
+++ b/discord/application_commands.py
@@ -0,0 +1,2492 @@
+# -*- coding: utf-8 -*-
+
+"""
+The MIT License (MIT)
+
+Copyright (c) 2021-present mccoderpy
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+"""
+from __future__ import annotations
+
+from typing import (
+    Any,
+    Awaitable,
+    Callable,
+    Coroutine,
+    Dict,
+    List,
+    Optional,
+    Type,
+    TYPE_CHECKING,
+    Union,
+    Set,
+)
+
+from typing_extensions import Literal
+
+import re
+import copy
+import asyncio
+import inspect
+import warnings
+from enum import Enum
+from types import FunctionType
+
+from .utils import async_all, find, get, snowflake_time, copy_doc, SupportsStr
+from .channel import PartialMessageable
+from .enums import (
+    Enum as DiscordEnum,
+    ApplicationCommandType,
+    AppCommandPermissionType,
+    AppIntegrationType,
+    ChannelType,
+    EntryPointHandlerType,
+    InteractionContextType,
+    Locale,
+    OptionType,
+    try_enum,
+)
+from .permissions import Permissions
+from .abc import GuildChannel
+
+if TYPE_CHECKING:
+    from datetime import datetime
+    from .guild import Guild
+    from .state import ConnectionState
+    from .ext.commands import Cog, Greedy, Converter
+    from .interactions import ApplicationCommandInteraction, AutocompleteInteraction, BaseInteraction
+    from .types import (
+        app_command
+    )
+
+    from .channel import ThreadChannel
+    from .abc import GuildChannel, Mentionable
+    from .member import Member
+    from .user import User
+    from .message import Attachment
+    from .role import Role
+
+    ValidOptionType = Union[
+        Type[str],
+        Type[bool],
+        Type[int],
+        Type[float],
+        Type[GuildChannel],
+        Type[ThreadChannel],
+        Type[Member],
+        Type[User],
+        Type[Attachment],
+        Type[Role],
+        Type[Mentionable],
+        OptionType,
+        Converter,
+        Type[Converter],
+        Type[Enum],
+        Type[DiscordEnum],
+    ]
+
+__all__ = (
+    'Localizations',
+    'ApplicationCommand',
+    'GuildAppCommandPermissions',
+    'AppCommandPermission',
+    'SlashCommand',
+    'GuildOnlySlashCommand',
+    'SlashCommandOption',
+    'SlashCommandOptionChoice',
+    'SubCommandGroup',
+    'GuildOnlySubCommandGroup',
+    'SubCommand',
+    'GuildOnlySubCommand',
+    'UserCommand',
+    'MessageCommand',
+    'generate_options'
+)
+
+api_docs = 'https://discord.com/developers/docs/'
+CHAT_COMMAND_NAME_REGEX = re.compile(r'^[-_\w0-9\u0901-\u097D\u0E00-\u0E7F]{1,32}$', flags=re.RegexFlag.UNICODE)
+
+# TODO: Add a (optional) feature for auto generated localizations by a translator
+
+
+class Localizations:
+    """
+    Represents a :class:`dict` with localized values.
+    These are used for application-commands, options and choices ``name_localizations`` and ``description_localizations``
+    
+    See :class:`~discord.Locale` for a list of available locals.
+    
+    Example
+    -------
+    
+    .. code-block:: python3
+        
+        Localizations(
+            en_US='Hello World!',
+            de='Hallo Welt!',
+            fr='Bonjour le monde!'
+            uk='Привіт світ!'
+        )
+    
+    Using the full language name is also possible.
+    
+    .. code-block:: python3
+    
+        Localizations(
+            english_us='Hello World!',
+            german='Hallo Welt!',
+            french='Bonjour le monde!'
+            ukrainian='Привіт світ!'
+        )
+    
+    Parameters
+    ----------
+    kwargs: Any
+
+        Keyword only arguments in format ``language='Value'``
+        As `language` you could use any of :class:`discord.Locale` s members. See table above.
+
+        .. note::
+
+            Values follow the same restrictions as the target they are used for. e.g. description, name, etc.
+
+    """
+
+    __slots__ = tuple([locale_name for locale_name in Locale._enum_member_map_] + ['__languages_dict__']
+                      )  # type: ignore
+
+    def __init__(self, **localizations) -> None:
+
+        self.__languages_dict__ = {}
+        for locale, localized_text in localizations.items():
+            try:
+                setattr(self, locale, localized_text)
+            except AttributeError:
+                raise ValueError(f'Unknown locale "{locale}". See {api_docs}reference#locales for a list of locales.')
+            else:
+                self.__languages_dict__[Locale[locale].value] = localized_text
+
+    def __repr__(self) -> str:
+        return '<Localizations: %s>' % (", ".join([Locale.try_value(locale).name for locale in self.__languages_dict__]
+                                                  ) if self.__languages_dict__ else 'None')
+
+    def __getitem__(self, item) -> Optional[str]:
+        if isinstance(item, Locale):
+            locale = Locale[item.name]
+        else:
+            locale = try_enum(Locale, str(item))
+        try:
+            return self.__languages_dict__[locale.value]
+        except KeyError:
+            # TODO: Find a better solution for this.
+            try:
+                maybe_them = (locale.name, locale.name.replace('_', '-'), locale.value.replace('_', '-'))
+                for i in maybe_them:
+                    try:
+                        return self.__languages_dict__[i]
+                    except KeyError:
+                        continue
+                raise KeyError
+            except:
+                raise
+        except (KeyError, AttributeError):
+            if (locale.value not in self.__slots__) if isinstance(locale, Locale) else (locale not in self.__slots__):
+                raise KeyError(f'Unknown locale "{locale}". See {api_docs}/reference#locales for a list of locales.')
+            raise KeyError(f'There is no locale value set for {locale.name}.')
+
+    def __setitem__(self, key: Union[Locale, str], value: str) -> None:
+        self.__languages_dict__[Locale[key].value] = value
+
+    def __bool__(self) -> bool:
+        return bool(self.__languages_dict__)
+
+    def to_dict(self) -> Dict[str, str]:
+        return self.__languages_dict__ if self.__languages_dict__ else None
+
+    @classmethod
+    def from_dict(cls, data: Optional[Dict[str, str]]) -> Localizations:
+        if not data:
+            return cls()
+        _data = {}
+        for key, value in data.items():
+            k: Union[Locale | str] = try_enum(Locale, key)
+            _data[k.name if isinstance(k, Locale) else k] = value
+        return cls(**_data)
+
+    def update(self, __m: Localizations) -> None:
+        """Similar to :meth:`dict.update`"""
+        self.__languages_dict__.update(__m.__languages_dict__)
+
+    def from_target(self, target: Union[Guild, BaseInteraction], *, default: Any = None):
+        """
+        Returns the value for the local of the object (if it's set), or :attr:`default`(:class:`None`)
+
+        Parameters
+        ----------
+        target: Union[:class:`~discord.Guild`, :class:`~discord.BaseInteraction`]
+            The target witch locale to use.
+            If it is of type :obj:`~discord.BaseInteraction` (or any subclass) it returns takes the local of the author.
+        default: Optional[Any]
+            The value or an object to return by default if there is no value for the locale of :attr:`target` set.
+            Default to :class:`None` or :class:`~discord.Locale.english_US`/:class:`~discord.Locale.english_GB`
+
+        Returns
+        -------
+        Union[:class:`str`, None]
+            The value of the locale or :obj:`None` if there is no value for the locale set.
+
+        Raises
+        ------
+        :exc:`TypeError`
+            If :attr:`target` is of the wrong type.
+        """
+        if hasattr(target, 'preferred_locale'):
+            try:
+                return self[target.preferred_locale.value]
+            except KeyError as exc:
+                # just the first letter because it's enough to identify which one it is
+                if exc.args and exc.args[0].startswith('U'):
+                    pass
+                return_default = True
+        elif hasattr(target, 'author_locale'):
+            try:
+                return self[target.author_locale.value]
+            except KeyError as exc:
+                # just the first letter because it's enough to identify which one it is
+                if exc.args and exc.args[0].startswith('U'):
+                    pass
+                return_default = True
+        else:
+            raise TypeError(
+                f'target must be either of type discord.Guild or discord.BaseInteraction, not {target.__class__.__name__}'
+            )
+        if return_default:
+            try:
+                return self[default.value if default is Locale else default]
+            except KeyError:
+                if default is None:
+                    return self.__languages_dict__.get('en-US', self.__languages_dict__.get('en-GB', None))
+                else:
+                    if (default.value if default is Locale else default) not in self.__slots__:
+                        return default
+                    else:
+                        try:
+                            self[default.value if default is Locale else default]
+                        except KeyError:  # not a locale so return it
+                            return default
+
+
+class ApplicationCommand:
+    """The base class for application commands"""
+
+    def __init__(self, type: int, *args, **kwargs):
+        self._type = type
+        self.name: str = kwargs.get('name', '')
+        self.is_nsfw: bool = kwargs.get('is_nsfw', False)
+        self._guild_ids = kwargs.get('guild_ids', None)
+        self._guild_id = kwargs.get('guild_id', None)
+        self._state_ = kwargs.get('state', None)
+        self._disabled = False
+        self.func = kwargs.pop('func', None)
+        self.cog = kwargs.get('cog', None)
+        self.integration_types: Optional[Set[AppIntegrationType]] = {
+            try_enum(AppIntegrationType, it) for it in i_types
+        } if (i_types := kwargs.get('integration_types')) else None
+        self.contexts: Set[InteractionContextType] = {
+            try_enum(InteractionContextType, ct) for ct in (kwargs.get('contexts', []) or [])
+        }
+        dp = kwargs.get('default_permission', None)
+        if dp is not None:
+            warnings.warn(
+                'default_permission is deprecated, use default_member_permissions and contexts instead.',
+                stacklevel=3,
+                category=DeprecationWarning
+            )
+        dmp = kwargs.get('default_member_permissions', None)
+        self.default_member_permissions: Optional[Permissions] = (
+            (Permissions(int(dmp)) if dmp is not None else None) if not isinstance(dmp, Permissions) else dmp
+        )
+        if (ad := kwargs.get('allow_dm', None)) is not None:
+            warnings.warn(
+                'allow_dm is deprecated, use default_member_permissions and contexts instead.',
+                stacklevel=3,
+                category=DeprecationWarning
+            )
+
+        self.allow_dm = ad or (InteractionContextType.bot_dm in self.contexts)
+        self.name_localizations: Localizations = kwargs.get('name_localizations', Localizations())
+        self.description_localizations: Localizations = kwargs.get('description_localizations', Localizations())
+
+    def __getitem__(self, item) -> Any:
+        return getattr(self, item)
+
+    @property
+    def _state(self):
+        return self._state_
+
+    @_state.setter
+    def _state(self, value):
+        setattr(self, '_state_', value)
+
+    @property
+    def type(self) -> ApplicationCommandType:
+        return try_enum(ApplicationCommandType, self._type)
+
+    @property
+    def cog(self) -> Optional[Cog]:
+        """Optional[:class:`~discord.ext.commands.Cog`]: The cog associated with this command if any."""
+        return getattr(self, '_cog', None)
+
+    @cog.setter
+    def cog(self, __cog: Cog) -> None:
+        setattr(self, '_cog', __cog)
+
+    @property
+    def disabled(self) -> bool:
+        return self._disabled
+
+    @disabled.setter
+    def disabled(self, value: bool) -> None:
+        self._disabled = value
+        if hasattr(self, 'sub_commands'):
+            for cmd in self.sub_commands:
+                cmd.disabled = value
+
+    def _set_cog(self, cog: Cog, recursive: bool = False) -> None:
+        self.cog = cog
+
+    def __call__(self, *args, **kwargs):
+        return super().__init__(self, *args, **kwargs)
+
+    def __repr__(self) -> str:
+        return '<%s name=%s, id=%s, disabled=%s>' % (self.__class__.__name__, self.name, self.id, self.disabled)
+
+    def __eq__(self, other) -> bool:
+        if isinstance(other, self.__class__):
+            other = other.to_dict()
+        if isinstance(other, dict):
+            def check_options(_options: list, _other: list):
+                if not len(_options) and not len(_other):
+                    return True
+                if len(_options) != len(_other):
+                    return False
+                for index, option in enumerate(_other):
+                    opt = find(lambda o: o['name'] == option['name'], _options)
+                    if not opt:
+                        return False
+                    try:
+                        if index != _options.index(opt) and opt['type'] not in (1, 2):
+                            return False
+                    except IndexError:
+                        return False
+                for index, option in enumerate(_options):
+                    opt = find(lambda o: option['name'] == o['name'], _other)
+                    try:
+                        if index != _other.index(opt) and opt['type'] not in (1, 2):
+                            return False
+                    except IndexError:
+                        return False
+                    if option['type'] in (1, 2):
+                        if not check_options(option.get('options', []), opt.get('options', [])):
+                            return False
+                    for key in ('type', 'name', 'name_localizations', 'description', 'description_localizations',
+                                'required', 'choices', 'min_value', 'max_value', 'min_length', 'max_length',
+                                'autocomplete'):
+                        current_value = option.get(key, None)
+                        if current_value != opt.get(key, None):
+                            return False
+                    if sorted(opt.get('channel_types', [])) != sorted(option.get('channel_types', [])):
+                        return False
+                return True
+
+            if hasattr(self, 'options') and self.options:
+                options = [o.to_dict() for o in self.options]
+            elif hasattr(self, 'sub_commands') and self.sub_commands:
+                options = [s.to_dict() for s in self.sub_commands]
+            else:
+                options = []
+            dmp = str(self.default_member_permissions.value) if self.default_member_permissions else None
+            return (
+                    int(self.type) == other.get('type') and self.name == other.get('name', None)
+                    and self.name_localizations.to_dict() == other.get('name_localizations', None)
+                    and getattr(self, 'description', '') == other.get('description', '')
+                    and self.description_localizations.to_dict() == other.get('description_localizations', None)
+                    and dmp == other.get('default_member_permissions', None)
+                    and self.allow_dm == other.get('dm_permission', True)
+                    and (
+                        not any((_other_ctxs := other.get('contexts'), self.contexts))
+                        or not {ctx.value for ctx in self.contexts}.symmetric_difference(_other_ctxs)
+                    )
+                    and (
+                        not any((_other_itg_tps := other.get('integration_types', set()), self.integration_types))
+                        or not {itg_type.value for itg_type in (self.integration_types or set())}
+                        .symmetric_difference(_other_itg_tps)
+                    )
+                    and check_options(options, other.get('options', []))
+            )
+        return False
+
+    def __ne__(self, other) -> bool:
+        return not self.__eq__(other)
+
+    def _fill_data(self, data) -> ApplicationCommand:
+        self._id = int(data.get('id', 0))
+        self._guild_id = int(data.get('guild_id', 0))
+        return self
+
+    async def can_run(self, *args, **kwargs) -> bool:
+        # if self.cog:
+        #    args = (self.cog, *args)
+        check_func = kwargs.pop('__func', self)
+        checks = getattr(check_func, '__commands_checks__', getattr(self.func, '__commands_checks__', []))
+        if not checks:
+            return True
+        return await async_all(check(args[0]) for check in checks)
+
+    async def invoke(self, interaction, *args, **kwargs):
+        if not self.func:
+            return
+        args = (interaction, *args)
+        try:
+            if await self.can_run(*args):
+                if self.cog:
+                    await self.func(self.cog, *args, **kwargs)
+                else:
+                    await self.func(*args, **kwargs)
+        except Exception as exc:
+            if hasattr(self, 'on_error'):
+                if self.cog is not None:
+                    await self.on_error(self.cog, interaction, exc)
+                else:
+                    await self.on_error(interaction, exc)
+            else:
+                self._state.dispatch('application_command_error', self, interaction, exc)
+
+    def error(self, coro: Callable[[ApplicationCommandInteraction, Exception], Coroutine]):
+        """A decorator to set an error handler for this command similar to :func:`on_application_command_error`
+        but only for this command
+
+        Parameters
+        ----------
+        coro: Callable[[:class:`~discord.ApplicationCommandInteraction`, :class:`Exception`], Coroutine]
+            The |coroutine_link|_ to use as an error handler.
+
+        Raises
+        ------
+        TypeError
+            If the error handler is not a coroutine.
+        """
+        if not asyncio.iscoroutinefunction(coro):
+            raise TypeError('The error handler must be a coroutine.')
+        self.on_error = coro
+        return coro
+
+    def to_dict(self) -> dict:
+        base = {
+            'type': int(self.type),
+            'name': str(self.name),
+            'nsfw': self.is_nsfw,
+            'contexts': [ctx.value for ctx in self.contexts] if self.contexts else None,
+            'integration_types': [it.value for it in self.integration_types] if self.integration_types else None,
+            'name_localizations': self.name_localizations.to_dict(),
+            'description': getattr(self, 'description', ''),
+            'description_localizations': self.description_localizations.to_dict(),
+            'default_member_permissions': str(self.default_member_permissions.value
+                                              ) if self.default_member_permissions else None
+        }
+
+        if not self.guild_id:
+            base['dm_permission'] = self.allow_dm
+        if hasattr(self, 'options'):
+            base['options'] = [o.to_dict() for o in self.options]
+        if hasattr(self, 'sub_commands') and self.sub_commands:
+            base['options'] = [sc.to_dict() for sc in self.sub_commands]
+        if hasattr(self, 'handler'):
+            base['handler'] = self.handler.value
+        return base
+
+    @property
+    def id(self) -> Optional[int]:
+        """Optional[:class:`int`]: The id of the command, only set if the bot is running"""
+        return getattr(self, '_id', None)
+
+    @property
+    def created_at(self) -> Optional[datetime]:
+        """
+        Optional[:class:`~datetime.datetime`]: The creation time of the command in UTC, only set if the bot is running
+        """
+        if self.id:
+            return snowflake_time(self.id)
+
+    @property
+    def guild_id(self) -> Optional[int]:
+        """Optional[:class:`int`]: Th id this command belongs to, if any"""
+        return self._guild_id
+
+    @property
+    def guild_ids(self) -> Optional[List[int]]:
+        return getattr(self, '_guild_ids', self.guild_id)
+
+    @property
+    def application_id(self) -> int:
+        return self._state._get_client().app.id
+
+    @classmethod
+    def _from_type(cls, state: ConnectionState, data: Dict[str, Any]):
+        command_type = data['type']
+        if command_type == 1:
+            return SlashCommand.from_dict(state, data)
+        elif command_type == 2:
+            return UserCommand.from_dict(state, data)
+        elif command_type == 3:
+            return MessageCommand.from_dict(state, data)
+        elif command_type == 4:
+            return ActivityEntryPointCommand.from_dict(state, data)
+
+    @staticmethod
+    def _sorted_by_type(commands):
+        sorted_dict = {'chat_input': [], 'user': [], 'message': []}
+        for cmd in commands:
+            if cmd['type'] == 1:
+                predicate = 'chat_input'
+            elif cmd['type'] == 2:
+                predicate = 'user'
+            elif cmd['type'] == 3:
+                predicate = 'message'
+            elif cmd['type'] == 4:
+                predicate = 'primary_entry_point'
+                sorted_dict[predicate] = [cmd]
+            else:  # Should not be the case
+                continue
+            sorted_dict[predicate].append(cmd)
+        return sorted_dict
+
+    async def delete(self) -> None:
+        """|coro|
+
+        Deletes the application command
+        """
+        if self.guild_id != 0:
+            guild_id = self.guild_id
+        else:
+            guild_id = None
+        await self._state.http.delete_application_command(self.application_id, self.id, guild_id)
+        if guild_id:
+            self._state._get_client()._remove_application_command(self, from_cache=True)
+
+
+class ActivityEntryPointCommand(ApplicationCommand):
+    """
+    The primary entry point command is required for users to be able to launch your Activity from the
+    :sup-art:`App Launcher menu <21334461140375-Using-Apps-on-Discord>` in Discord.
+
+    When you enable Activities in your app's settings, discord will automatically create a
+    :ddocs:`default Entry Point command </interactions/application-commands#default-entry-point-command>`
+
+    .. note::
+        By default discord will handle the command and launch the activity.
+        However, if you want to handle the command yourself to deside the response you can register a handler using
+        the :meth:`discord.Client.activity_primary_entry_point_command` decorator.
+
+    If you want to update the name, description, etc. you can do this by calling
+    :meth:`discord.Client.update_primary_entry_point_command`.
+
+    .. seealso::
+
+        - :meth:`discord.Client.activity_primary_entry_point_command`
+        - :meth:`discord.Client.get_primary_entry_point_command`
+        - :meth:`discord.Client.update_primary_entry_point_command`
+
+    Parameters
+    -----------
+    name: :class:`str`
+        The 1-32 characters long name of the command shows up in discord.
+    description: :class:`str`
+        The 1-100 characters long description of the command shows up in discord.
+    integration_types: Optional[List[:class:`~discord.AppIntegrationType`]]
+        The integration type context this command is available for.
+        Defaults to the integration types set in the discord developer portal.
+    contexts: Optional[List[:class:`~discord.InteractionContextType`]]
+        The contexts this command is available for. Defaults to all contexts.
+    name_localizations: Optional[:class:`~Localizations`]
+        Localized names for the command.
+    description_localizations: Optional[:class:`~Localizations`]
+        Localized descriptions for the command.
+    handler: :class:`~discord.EntryPointHandlerType`
+
+    """
+    def __init__(
+            self,
+            name: str,
+            description: str,
+            *,
+            integration_types: Optional[List[InteractionContextType]] = None,
+            contexts: Optional[List[InteractionContextType]] = None,
+            name_localizations: Optional[Localizations] = None,
+            description_localizations: Optional[Localizations] = None,
+            handler: EntryPointHandlerType = EntryPointHandlerType(2),
+            **kwargs
+    ):
+        super().__init__(
+            type=4,
+            name=name,
+            description=description,
+            integration_types=integration_types,
+            contexts=contexts,
+            name_localizations=name_localizations,
+            description_localizations=description_localizations,
+            **kwargs
+        )
+        self.handler: EntryPointHandlerType = try_enum(EntryPointHandlerType, handler)
+
+    @classmethod
+    def from_dict(cls, state: ConnectionState, data: Dict[str, Any]) -> ActivityEntryPointCommand:
+        return cls(
+            name=data['name'],
+            description=data['description'],
+            integration_types=data.get('integration_types', None),
+            contexts=data.get('contexts', None),
+            name_localizations=Localizations.from_dict(data.get('name_localizations', {})),
+            description_localizations=Localizations.from_dict(data.get('description_localizations', {})),
+            handler=try_enum(EntryPointHandlerType, data.get('handler', 2)),
+            state=state
+        )._fill_data(data)
+
+    async def _parse_arguments(self, interaction: ApplicationCommandInteraction) -> Any:
+        interaction._command = self
+        return await self.invoke(interaction)
+
+
+class SlashCommandOptionChoice:
+    """
+    A class representing a choice for a :class:`SlashCommandOption` or to use in :meth:`AutocompleteInteraction.send_choices`
+
+    Parameters
+    -----------
+    name: Union[:class:`str`, :class:`int`, :class:`float`]
+        The 1-100 characters long name that will show in the client.
+    value: Union[:class:`str`, :class:`int`, :class:`float`, :obj:`None`]
+        The value that will send as the options value.
+        Must be of the type the :class:`SlashCommandOption` is of (:class:`str`, :class:`int` or :class:`float`).
+
+        .. note::
+            If this is left empty it takes the :attr:`~SlashCommandOption.name` as value.
+
+    name_localizations: Optional[:class:`Localizations`]
+        Localized names for the choice.
+    """
+
+    def __init__(
+            self,
+            name: Union[str, int, float],
+            value: Union[str, int, float, None] = None,
+            name_localizations: Optional[Localizations] = Localizations()
+    ):
+
+        if 100 < len(str(name)) < 1:
+            raise ValueError(f'The name of a choice must bee between 1 and 100 characters long, got {len(name)}.')
+        self.name: str = str(name)
+        self.value: Union[str, int, float] = value if value is not None else name
+        self.name_localizations: Optional[Localizations] = name_localizations
+
+    def __repr__(self):
+        return '<SlashCommandOptionChoice name=%s, value=%s>' % (self.name, self.value)
+
+    def to_dict(self) -> Dict[str, Any]:
+        return {
+            'name': str(self.name),
+            'value': self.value,
+            'name_localizations': self.name_localizations.to_dict(),
+        }
+
+    @classmethod
+    def from_dict(cls, data) -> SlashCommandOptionChoice:
+        name_localizations = data.pop('name_localizations', None) or {}
+        return cls(name=data['name'], value=data['value'], name_localizations=Localizations(**name_localizations))
+
+
+class SlashCommandOption:
+    """
+    Representing an option for a :class:`SlashCommand`/:class:`SubCommand`.
+
+    Parameters
+    -----------
+    option_type: Union[:class:`OptionType`, :class:`int`, :class:`type`]
+        Could be any of :class:`OptionType`'s attributes, an integer between 0 and 10 or a :class:`type` like
+        :class:`discord.Member`, :class:`discord.TextChannel` or :class:`str`.
+
+        .. note::
+            If the :attr:`option_type` is a :class:`type`, that subclasses :class:`~discord.abc.GuildChannel` the type of the
+            channel would set as the default :attr:`~SlashCommandOption.channel_types`.
+
+    name: :class:`str`
+        The 1-32 characters long name of the option shows up in discord.
+        The name must be the same as the one of the parameter for the slash-command
+        or connected using :attr:`~SlashCommand.connector` of :class:`SlashCommand`/:class:`SubCommand` or the method
+        that generates one of these.
+    description: :class:`str`
+        The 1-100 characters long description of the option shows up in discord.
+    required: Optional[:class:`bool`]
+        Weather this option must be provided by the user, default :obj:`True`.
+        If :obj:`False`, the parameter of the slash-command that takes this option needs a default value.
+    choices: Optional[List[Union[:class:`SlashCommandOptionChoice`, :class:`str`, :class:`int`, :class:`float`]]]
+        A list of up to 25 choices the user could select. Only valid if the :attr:`option_type` is one of
+        :attr:`~OptionType.string`, :attr:`~OptionType.integer` or :attr:`~OptionType.number`.
+
+        .. note::
+            If you want to have values that are not the same as their name, you can use :class:`SlashCommandOptionChoice`
+
+        The :attr:`~SlashCommandOptionChoice.value`'s of the choices must be of the :attr:`~SlashCommandOption.option_type` of this option
+        (e.g. :class:`str`, :class:`int` or :class:`float`).
+        If choices are set they are the only options a user could pass.
+    autocomplete: Optional[:class:`bool`]
+        Whether to enable
+        `autocomplete <https://discord.com/developers/docs/interactions/application-commands#autocomplete>`_
+        interactions for this option, default ``False``.
+        With autocomplete, you can check the user's input and send matching choices to the client.
+
+        .. note::
+            Autocomplete can only be used with options of the type :attr:`~OptionType.string`, :attr:`~OptionType.integer` or :attr:`~OptionType.number`.
+            **If autocomplete is activated, the option cannot have** :attr:`~SlashCommandOption.choices` **.**
+
+    min_value: Optional[Union[:class:`int`, :class:`float`]]
+        If the :attr:`~SlashCommandOption.option_type` is one of :attr:`~OptionType.integer` or :attr:`~OptionType.number`
+        this is the minimum value the users input must be of.
+    max_value: Optional[Union[:class:`int`, :class:`float`]]
+        If the :attr:`option_type` is one of :attr:`~OptionType.integer` or :attr:`~OptionType.number`
+        this is the maximum value the users input could be of.
+    min_length: Optional[:class:`int`]
+        If the :attr:`option_type` is :attr:`~OptionType.string`, this is the minimum length (minimum of ``0``, maximum of ``6000``)
+    max_length: Optional[:class:`int`]
+        If the :attr:`option_type` is :attr:`~OptionType.string`, this is the maximum length (minimum of ``1``, maximum of ``6000``)
+    channel_types: Optional[List[Union[:class:`abc.GuildChannel`, :class:`ChannelType`, :class:`int`]]]
+        A list of :class:`ChannelType` or the type itself like ``TextChannel`` or ``StageChannel`` the user could select.
+        Only valid if :attr:`~SlashCommandOption.option_type` is :attr:`~OptionType.channel`.
+    default: Optional[Any]
+        The default value that should be passed to the function if the option is not provided, default ``None``.
+        Usually used for autocomplete callback.
+    converter: Optional[Union[:class:`discord.ext.commands.Greedy`, :class:`discord.ext.commands.Converter`]]
+        A subclass of :class:`~discord.ext.commands.Converter` to use for converting the value.
+        Only valid for option_type :attr:`~OptionType.string` or :attr:`~OptionType.integer`
+    ignore_conversion_failures: Optional[:class:`bool`]
+        Whether conversion failures should be ignored and the value should be passed without conversion instead.
+        Default ``False``
+    """
+
+    def __init__(
+            self,
+            option_type: ValidOptionType,
+            name: str,
+            description: str,
+            name_localizations: Optional[Localizations] = Localizations(),
+            description_localizations: Optional[Localizations] = Localizations(),
+            required: bool = True,
+            choices: Optional[List[Union[SlashCommandOptionChoice, str, int, float]]] = [],
+            autocomplete: bool = False,
+            min_value: Optional[Union[int, float]] = None,
+            max_value: Optional[Union[int, float]] = None,
+            min_length: Optional[int] = None,
+            max_length: Optional[int] = None,
+            channel_types: Optional[List[Union[type(GuildChannel), ChannelType, int]]] = None,
+            default: Optional[Any] = None,
+            converter: Optional[Union[Type[Converter], Greedy]] = None,
+            ignore_conversion_failures: Optional[bool] = False,
+            **kwargs
+    ) -> None:
+        from .ext.commands import Converter, Greedy
+        if not isinstance(option_type, OptionType):
+            channel_type = None
+
+            option_type_is_class = isinstance(option_type, type)
+            if option_type_is_class and issubclass(option_type, (Enum, DiscordEnum)):
+                if description is None:
+                    description = inspect.getdoc(option_type)
+                choices = [SlashCommandOptionChoice(e.name.translate({95: 0x20}), e.value) for e in option_type]
+                value_class = choices[0].value.__class__
+
+                if all(isinstance(elem.value, value_class) for elem in choices):
+                    option_type, _ = OptionType.from_type(choices[0].value.__class__)
+                else:
+                    choices = [SlashCommandOptionChoice(e.name.translate({95: 0x20}), str(e.value)) for e in option_type]
+                    option_type = OptionType.string
+            try:
+                option_type, channel_type = OptionType.from_type(option_type)
+            except TypeError:
+                pass
+            else:
+                if issubclass(type(option_type), Converter) or converter is Greedy:
+                    converter = copy.copy(option_type)
+                    option_type = OptionType.string
+
+            if not isinstance(option_type, OptionType):
+                raise TypeError(f'Discord does not has a option_type for {option_type.__class__.__name__!r}.')
+            if channel_type and not channel_types:
+                channel_types = channel_type
+
+        self.type = option_type
+
+        if not CHAT_COMMAND_NAME_REGEX.match(name):
+            raise ValueError(
+                r'Command names and options must follow the regex "^[-_\w0-9\u0901-\u097D\u0E00-\u0E7F]{1,32}$"'
+                f'{api_docs}/interactions/application-commands#application-command-object-application-command-naming.'
+                f'Got "{name}" with length {len(name)}.'
+            )
+        self.name: str = name
+        self.name_localizations: Localizations = name_localizations
+        if 100 < len(description) < 1:
+            raise ValueError(
+                f'The description must be between 1 and 100 characters long, got {len(description)}.'
+            )
+        self.description: str = description
+        self.description_localizations: Localizations = description_localizations
+        self.required: bool = required
+        options = kwargs.get('__options', [])
+        if self.type == 2 and (not options):
+            raise ValueError('You need to pass __options if the option_type is subcommand_group.')
+        self._options = options
+        self.autocomplete: bool = autocomplete
+        self.min_value: Optional[Union[int, float]] = min_value
+        self.max_value: Optional[Union[int, float]] = max_value
+        self.min_length: int = min_length
+        self.max_length: int = max_length
+        for index, choice in enumerate(copy.copy(choices)):  # TODO: find a more efficient way to do this
+            if not isinstance(choice, SlashCommandOptionChoice):
+                choices[index] = SlashCommandOptionChoice(choice)
+        self.choices: List[SlashCommandOptionChoice] = choices
+        self.channel_types: Optional[List[Union[GuildChannel, ChannelType, int]]] = channel_types
+        self.default: Optional[Any] = default
+        self.converter: Union[Greedy, Converter] = converter
+        self.ignore_conversion_failures: bool = ignore_conversion_failures
+
+    def __repr__(self) -> str:
+        return '<SlashCommandOption type=%s, name=%s, description=%s, required=%s, choices=%s>' \
+               % (self.type,
+                  self.name,
+                  self.description,
+                  self.required,
+                  self.choices)
+
+    @property
+    def autocomplete(self) -> bool:
+        """
+        Whether to enable
+        `autocomplete <https://discord.com/developers/docs/interactions/application-commands#autocomplete>`_
+        interactions for this option.
+        With autocomplete, you can check the user's input and send matching choices to the client.
+
+        .. note::
+            Autocomplete can only be used with options of the type :attr:`~OptionType.string`,
+            :attr:`~OptionType.integer` or :attr:`~OptionType.number`.
+            If autocomplete is activated, the option cannot have :attr:`choices`.
+        """
+        return getattr(self, '_autocomplete', False)
+
+    @autocomplete.setter
+    def autocomplete(self, value: bool) -> None:
+        if value:
+            if self.type not in (OptionType.string, OptionType.integer, OptionType.number):
+                raise TypeError('Only Options of type string, integer or number could have autocomplete.')
+            elif self.choices:
+                raise TypeError('Options with choices could not have autocomplete.')
+        self._autocomplete = value
+
+    @property
+    def choices(self) -> Optional[List[SlashCommandOptionChoice]]:
+        """
+        The choices that are set for this option
+
+        Returns
+        -------
+        Optional[List[:class:`SlashCommandOptionChoice`]]
+        """
+        return getattr(self, '_choices', None)
+
+    @choices.setter
+    def choices(self, value: Optional[List[SlashCommandOptionChoice]]) -> None:
+        if value:
+            if self.type not in (OptionType.string, OptionType.integer, OptionType.number):
+                raise TypeError('Only Options of type string, integer or number could have choices.')
+            elif self.autocomplete:
+                raise TypeError('Options with autocomplete could not have choices.')
+        if len(value) > 25:
+            raise ValueError('The maximum of choices per Option is 25, got %s.'
+                             'It is recommended to use autocomplete if you have more than 25 options.' % len(value)
+                             )
+        self._choices = value
+
+    @property
+    def min_value(self) -> Optional[Union[int, float]]:
+        """
+        The minimum value a user could enter that is set
+
+        Returns
+        -------
+        Optional[Union[:class:`int`, :class:`float`]]
+        """
+        return getattr(self, '_min_value', None)
+
+    @min_value.setter
+    def min_value(self, value) -> None:
+        if value is not None:
+            if self.type not in (OptionType.integer, OptionType.number):
+                raise TypeError('Only Options of type integer or number could have a min_value or/and max_value.')
+        self._min_value = value
+
+    @property
+    def max_value(self) -> Optional[Union[int, float]]:
+        """
+        The maximum value a user could enter that is set.
+
+        Returns
+        -------
+        Optional[Union[:class:`int`, :class:`float`]]
+        """
+        return getattr(self, '_max_value', None)
+
+    @max_value.setter
+    def max_value(self, value) -> None:
+        if value is not None:
+            if self.type not in (OptionType.integer, OptionType.number):
+                raise TypeError('Only Options of type integer or number could have a min_value or/and max_value.')
+        self._max_value = value
+
+    @property
+    def channel_types(self) -> Optional[List[ChannelType]]:
+        """
+        The types of channels that could be selected.
+
+        Returns
+        -------
+        Optional[List[:class:`ChannelType`]]
+        """
+        return getattr(self, '_channel_types')
+
+    @channel_types.setter
+    def channel_types(self, value) -> None:
+        if value is not None:
+            if self.type != OptionType.channel:
+                raise TypeError('Only options of type channel could have channel_types.')
+            for index, c in enumerate(value):
+                if not isinstance(c, ChannelType):
+                    value[index] = ChannelType.from_type(c)
+            if not any([isinstance(c, ChannelType) for c in value]):
+                raise ValueError('Only ChannelType Enums, integers or Channel classes allowed.')
+        self._channel_types = value
+
+    def to_dict(self) -> dict:
+        base = {
+            'type': int(self.type),
+            'name': str(self.name),
+            'name_localizations': self.name_localizations.to_dict(),
+            'description': str(self.description),
+            'description_localizations': self.description_localizations.to_dict()
+        }
+        if bool(self.required) is True:
+            base['required'] = bool(self.required)
+        if self.choices:
+            base['choices'] = [c.to_dict() for c in self.choices]
+        elif self.autocomplete:
+            base['autocomplete'] = True
+        elif self._options:
+            base['options'] = [o.to_dict() for o in self._options]
+        if self.min_value is not None:
+            base['min_value'] = self.min_value
+        if self.max_value is not None:
+            base['max_value'] = self.max_value
+        if self.type.string:
+            min_length = self.min_length
+            max_length = self.max_length
+            if min_length:
+                base['min_length'] = min_length
+            if max_length:
+                base['max_length'] = max_length
+        if self.channel_types:
+            base['channel_types'] = [int(ch_type) for ch_type in self.channel_types]
+        return base
+
+    @classmethod
+    def from_dict(cls, data) -> SlashCommandOption:
+        option_type: OptionType = try_enum(OptionType, data['type'])
+        if option_type.sub_command_group:
+            return SubCommandGroup.from_dict(data)
+        elif option_type.sub_command:
+            return SubCommand.from_dict(data)
+        return cls(
+            option_type=try_enum(OptionType, data['type']),
+            name=data['name'],
+            name_localizations=Localizations.from_dict(data.get('name_localizations', {})),
+            description=data.get('description', 'No description'),
+            description_localizations=Localizations.from_dict(data.get('description_localizations', {})),
+            required=data.get('required', False),
+            choices=[SlashCommandOptionChoice.from_dict(c) for c in data.get('choices', [])],
+            autocomplete=data.get('autocomplete', False),
+            min_value=data.get('min_value', None),
+            max_value=data.get('max_value', None),
+            min_length=data.get('min_length', None),
+            max_length=data.get('max_length', None)
+        )
+
+
+class SubCommand(SlashCommandOption):
+    def __init__(
+            self,
+            parent,
+            name: str,
+            description: str,
+            name_localizations: Optional[Localizations] = Localizations(),
+            description_localizations: Optional[Localizations] = Localizations(),
+            options: List[SlashCommandOption] = [],
+            **kwargs
+    ):
+        self.parent: Union[SubCommandGroup, SubCommand] = parent
+        if not CHAT_COMMAND_NAME_REGEX.match(name):
+            raise ValueError(
+                r'Command names and options must follow the regex "^[-_\w0-9\u0901-\u097D\u0E00-\u0E7F]{1,32}$"'
+                f'{api_docs}/interactions/application-commands#application-command-object-application-command-naming.'
+                f'Got "{name}" with length {len(name)}.'
+            )
+        self.name = name
+        if 100 < len(description) < 1:
+            raise ValueError(
+                'The description of the Sub-Command must be 1-100 characters long, got %s.' % len(description)
+                )
+        if len(options) > 25:
+            raise ValueError('The maximum of options per Sub-Command is 25, got %s.' % len(options))
+        self.options = options
+        self.func = kwargs.get('func', None)
+        self.cog = kwargs.get('cog', None)
+        self.connector = kwargs.get('connector', {})
+        self.guild_id = kwargs.get('guild_id', parent.guild_id)
+        self._disabled = False
+        self.autocomplete_func = None
+        super().__init__(OptionType.sub_command, name=name, description=description,
+                         name_localizations=name_localizations, description_localizations=description_localizations,
+                         __options=options
+                         )
+
+    @property
+    def _state(self):
+        return self.parent._state
+
+    @property
+    def disabled(self) -> bool:
+        return self._disabled
+
+    @disabled.setter
+    def disabled(self, value: bool) -> None:
+        self._disabled = value
+
+    def __repr__(self):
+        return '<SubCommand parent=%s, name=%s, description=%s, options=%s>' \
+               % (self.parent.name,
+                  self.name,
+                  self.description,
+                  self.options)
+
+    @property
+    def base_command(self) -> SlashCommand:
+        """
+        Returns the base command of the sub-command
+
+        For example if the command is ``/a b c`` or ``/a c`` the base command would be ``a``
+
+        Returns
+        -------
+        :class:`SlashCommand`
+            The base command of the sub-command
+        """
+
+        parent = self.parent
+        if not isinstance(parent, SlashCommand):
+            parent = parent.parent
+        return parent
+
+    @property
+    def is_nsfw(self) -> bool:
+        """
+        Whether this command is nsfw
+
+        .. note::
+
+            Currently, any sub command of a base-command that is nsfw will be nsfw too.
+
+        Returns
+        -------
+        :class:`bool`
+            Whether this command is nsfw or not
+        """
+        return self.base_command.is_nsfw
+
+    @property
+    def mention(self) -> str:
+        """
+        Returns a string the client renders as a mention of the command
+
+        .. note::
+
+            This requires that the bot is running and the command is cached
+
+        Returns
+        -------
+        The mention of the command
+
+        Raises
+        -------
+        :exc:`TypeError`
+            The bot is not running and so the id's not cached
+        """
+        base_command = self.base_command
+        if not base_command.id:
+            raise TypeError('The bot must be running in order to get the mention of a command')
+        return f'</{self.qualified_name}:{base_command.id}>'
+
+    @property
+    def qualified_name(self) -> str:
+        """
+        Returns a string representing the full name of the command
+
+        For example if the command is ``/a b c`` or ``/a c`` the qualified name would be ``a b c`` or ``a c``
+
+        Returns
+        -------
+        :class:`str`
+            The full name of the command
+        """
+
+        full_name = ''
+        parent = self.parent
+        if not isinstance(parent, SlashCommand):
+            full_name += f'{parent.parent.name} '
+        full_name += f'{parent.name} {self.name}'
+        return full_name
+
+    def to_dict(self):
+        base = {
+            'type': 1,
+            'name': str(self.name),
+            'name_localizations': self.name_localizations.to_dict(),
+            'description': str(self.description),
+            'description_localizations': self.description_localizations.to_dict(),
+            'options': [c.to_dict() for c in self.options]
+        }
+        return base
+
+    async def can_run(self, *args, **kwargs):
+        # if self.cog is not None:
+        #    args = (self.cog, *args)
+        check_func = kwargs.pop('__func', self)
+        checks = getattr(check_func, '__commands_checks__', getattr(self.func, '__commands_checks__', []))
+        if not checks:
+            return True
+        return await async_all(check(args[0]) for check in checks)
+
+    async def invoke(self, interaction, *args, **kwargs):
+        if not self.func:
+            return
+        args = (interaction, *args)
+        try:
+            if await self.can_run(*args):
+                if self.cog:
+                    await self.func(self.cog, *args, **kwargs)
+                else:
+                    await self.func(*args, **kwargs)
+        except Exception as exc:
+            if hasattr(self, 'on_error'):
+                if self.cog is not None:
+                    await self.on_error(self.cog, interaction, exc)
+                else:
+                    await self.on_error(interaction, exc)
+            else:
+                self._state.dispatch('application_command_error', self, interaction, exc)
+
+    def autocomplete_callback(self, coro: Callable[[AutocompleteInteraction, ...], Coroutine]):
+        """
+        A decorator that sets a |coroutine_link|_ function as the function that will be called
+        when discord sends an autocomplete interaction for this sub-command.
+
+        Parameters
+        ----------
+        coro: Callable[[:class:`AutocompleteInteraction`, ...], Coroutine]
+            The function that should be set as autocomplete_func for this command.
+            Must take the same amount of params the sub-command itself takes.
+
+        Raises
+        ------
+        TypeError
+            The function passed is not a coroutine.
+        """
+        if not asyncio.iscoroutinefunction(coro):
+            raise TypeError('The autocomplete callback function must be a coroutine.')
+        self.autocomplete_func = coro
+        return coro
+
+    async def invoke_autocomplete(self, interaction, *args, **kwargs):
+        if not self.autocomplete_func:
+            warnings.warn(
+                f'Sub-command {self.name} of {self.parent} has options with autocomplete enabled but no autocomplete function.'
+                )
+            return
+
+        args = (interaction, *args)
+        try:
+            if await self.can_run(*args, __func=self.autocomplete_func):
+                if self.cog is not None:
+                    await self.autocomplete_func(self.cog, *args, **kwargs)
+                else:
+                    await self.autocomplete_func(*args, **kwargs)
+        except Exception as exc:
+            if hasattr(self, 'on_error'):
+                if self.cog is not None:
+                    await self.on_error(self.cog, interaction, exc)
+                else:
+                    await self.on_error(interaction, exc)
+            else:
+                self.base_command._state.dispatch('application_command_error', self, interaction, exc)
+
+    @copy_doc(ApplicationCommand.error)
+    def error(self, coro: Callable[[ApplicationCommandInteraction, Exception], Coroutine]):
+        if not asyncio.iscoroutinefunction(coro):
+            raise TypeError('The error handler registered must be a coroutine.')
+        self.on_error = coro
+        return coro
+
+    @classmethod
+    def from_dict(cls, data):
+        return cls(
+            parent=data.get('parent', None),
+            name=data['name'],
+            name_localizations=Localizations.from_dict(data.get('name_localizations', {})),
+            description=data.get('description', 'No description'),
+            description_localizations=Localizations.from_dict(data.get('description_localizations', {})),
+            options=[SlashCommandOption.from_dict(c) for c in data.get('options', [])],
+        )
+
+
+class GuildOnlySubCommand(SubCommand):
+    """Represents a :class:`SubCommand` for multiple guilds with the same function."""
+
+    def __init__(self, *args, guild_ids: List[int] = None, **kwargs):
+        parent = kwargs.get('parent', None)
+        self.guild_ids = guild_ids or parent.guild_ids if parent else []
+        super().__init__(*args, **kwargs)
+        self._commands = kwargs.get('commands', [])
+        self._disabled = False
+
+    @property
+    def disabled(self) -> bool:
+        return self._disabled
+
+    @disabled.setter
+    def disabled(self, value: bool) -> None:
+        self._disabled = value
+        for cmd in self._commands:
+            cmd.disabled = value
+
+    def __repr__(self):
+        return '<GuildOnlySubCommand parent=%s, name=%s, description=%s, options=%s, guild_ids=%s>' \
+               % (self.parent.name,
+                  self.name,
+                  self.description,
+                  self.options,
+                  ', '.join([str(g) for g in self.guild_ids])
+                  )
+
+    def autocomplete_callback(self, coro: Callable[[AutocompleteInteraction, ...], Coroutine]):
+        """A decorator that sets a |coroutine_link|_ function as the function that will be called
+        when discord sends an autocomplete interaction for this command.
+
+
+        Parameters
+        ----------
+        coro: Callable[[:class:`AutocompleteInteraction`, ...], Coroutine]
+            The function that should be set as autocomplete_func for this command.
+            Must take the same amount of params the command itself takes.
+
+
+        Raises
+        ------
+        TypeError
+            The function passed is not a coroutine.
+        """
+        if not asyncio.iscoroutinefunction(coro):
+            raise TypeError('The autocomplete callback function must be a coroutine.')
+        self.autocomplete_func = coro
+        for cmd in self._commands:
+            cmd.autocomplete_func = coro
+        return coro
+
+    @copy_doc(ApplicationCommand.error)
+    def error(self, coro: Callable[[ApplicationCommandInteraction, Exception], Coroutine]):
+        if not asyncio.iscoroutinefunction(coro):
+            raise TypeError('The error handler registered must be a coroutine.')
+        for cmd in self._commands:
+            cmd.on_error = coro
+        return coro
+
+
+class SlashCommand(ApplicationCommand):
+    """
+    Represents a slash-command.
+
+    .. note::
+        You should use :func:`discord.Client.slash_command` or in cogs :func:`~discord.ext.commands.Cog.slash_command`
+        decorator by default to create this.
+
+    Parameters
+    -----------
+    name: :class:`str`
+        The name of the slash-command. Must be between 1 and 32 characters long and oly contain a-z, _ and -.
+    description: :class:`str`
+        The description of the command shows up in discord. Between 1 and 100 characters long.
+
+    default_member_permissions: Optional[Union[:class:`~discord.Permissions`, :class:`int`]]
+         Permissions that a Member needs by default to execute(see) the command.
+    allow_dm: Optional[:class:`bool`]
+        Indicates whether the command is available in DMs with the app, only for globally-scoped commands.
+        By default, commands are visible.
+    is_nsfw: :class:`bool`
+        Whether this command is an `NSFW command <https://support.discord.com/hc/en-us/articles/10123937946007>`_, default :obj:`False`
+
+        .. note::
+            Currently all sub-commands of a command that is marked as *NSFW* are NSFW too.
+
+    options: Optional[List[:class:`SlashCommandOption`]]
+        A list of max. 25 options for the command.
+        Required options **must** be listed before optional ones.
+    connector: Optional[Dict[:class:`str`, :class:`str`]]
+        A dictionary containing the name of function-parameters as keys and the name of the option as values.
+        Useful for using non-ascii Letters in your option names without getting ide-errors.
+    **kwargs:
+        Keyword arguments used for internal handling.
+    """
+
+    def __init__(
+            self,
+            name: str,
+            description: str,
+            name_localizations: Optional[Localizations] = Localizations(),
+            description_localizations: Optional[Localizations] = Localizations(),
+            default_member_permissions: Optional[Union[Permissions, int]] = None,
+            allow_dm: Optional[bool] = True,
+            integration_types: Optional[Set[AppIntegrationType]] = None,
+            contexts: Set[InteractionContextType] = set(),
+            is_nsfw: bool = False,
+            options: List[SlashCommandOption] = [],
+            connector: Dict[str, str] = {},
+            **kwargs
+    ):
+        self.autocomplete_func = None
+        super().__init__(
+            1,
+            name=name,
+            description=description,
+            name_localizations=name_localizations,
+            description_localizations=description_localizations,
+            default_member_permissions=default_member_permissions,
+            allow_dm=allow_dm,
+            integration_types=integration_types,
+            contexts=contexts,
+            is_nsfw=is_nsfw,
+            options=options,
+            connector=connector,
+            **kwargs
+        )
+        if not CHAT_COMMAND_NAME_REGEX.match(name):
+            raise ValueError(
+                r'Command names and options must follow the regex "^[-_\w0-9\u0901-\u097D\u0E00-\u0E7F]{1,32}$"'
+                f'{api_docs}/interactions/application-commands#application-command-object-application-command-naming.'
+                f'Got "{name}" with length {len(name)}.'
+            )
+        self.name = name
+        if 100 < len(description) < 1:
+            raise ValueError('The description must be between 1 and 100 characters long, got %s.' % len(description))
+        self.description = description
+        if len(options) > 25:
+            raise ValueError('The maximum of options per command is 25, got %s' % len(options))
+        self.connector: Dict[str, str] = connector
+        self._sub_commands = {command.name: command for command in options if OptionType.try_value(command.type) in (
+        OptionType.sub_command, OptionType.sub_command_group)}
+        if not self._sub_commands:
+            self._options = {option.name: option for option in options}
+        for sc in self.sub_commands:
+            sc.parent = self
+
+    def __repr__(self):
+        return '<SlashCommand name=%s, description=%s, default_member_permissions=%s, options=%s, guild_id=%s disabled=%s, id=%s>' \
+               % (self.name,
+                  self.description,
+                  self.default_member_permissions,
+                  self.options or self.sub_commands,
+                  self.guild_id or 'None',
+                  self.disabled,
+                  self.id)
+
+    @property
+    def _state(self):
+        return getattr(self, '_state_', None)
+
+    @_state.setter
+    def _state(self, value):
+        setattr(self, '_state_', value)
+        for sc in self.sub_commands:
+            sc.parent = self
+
+    @property
+    def parent(self):
+        return self
+
+    @property
+    def mention(self) -> str:
+        """
+        Returns a string the client renders as a mention of the command
+
+        .. note::
+
+            This requires that the bot is running and the command is cached
+
+        Returns
+        -------
+        The mention of the command
+
+        Raises
+        -------
+        :exc:`TypeError`
+            The bot is not running and so the id's not cached
+        """
+        if not self.id:
+            raise TypeError('The bot must be running in order to get the mention of a command')
+        return f'</{self.name}:{self.id}>'
+
+    @property
+    def qualified_name(self) -> str:
+        return self.name
+
+    @property
+    def cog(self) -> Optional['Cog']:
+        """Optional[:class:`ext.commands.Cog`]: The cog the slash command belongs to"""
+        return getattr(self, '_cog', None)
+
+    @cog.setter
+    def cog(self, __cog: 'Cog'):
+        setattr(self, '_cog', __cog)
+
+    def _set_cog(self, cog: 'Cog', recursive: bool = False):
+        self.cog = cog
+        if recursive:
+            for command in self.sub_commands:
+                if command.type.sub_command_group:
+                    for sub_command in command.sub_commands:
+                        sub_command.cog = cog
+                command.cog = cog
+
+    @property
+    def has_subcommands(self) -> bool:
+        """:class:`bool`: Whether the command has sub-commands or not"""
+        return bool(self.sub_commands)
+
+    def autocomplete_callback(self, coro: Callable[[AutocompleteInteraction, ...], Coroutine]):
+        """
+        A decorator that sets a |coroutine_link|_ function as the function that will be called
+        when discord sends an autocomplete interaction for this command.
+
+        Parameters
+        ----------
+        coro: Callable[[:class:`AutocompleteInteraction`, ...], Coroutine]
+            The function that should be set as :attr:`SlashCommand.autocomplete_func` for this command.
+            Must take the same amount of params the command itself takes.
+
+        Raises
+        ------
+        TypeError
+            The function passed is not a coroutine.
+        """
+        if not asyncio.iscoroutinefunction(coro):
+            raise TypeError('The autocomplete callback function must be a coroutine.')
+        self.autocomplete_func = coro
+        return coro
+
+    async def invoke_autocomplete(self, interaction, *args, **kwargs):
+        if self.autocomplete_func is None:
+            warnings.warn(
+                f'Application Command {self.name} has options with autocomplete enabled but no autocomplete function.'
+                )
+            return
+        args = (interaction, *args)
+
+        try:
+            if await self.can_run(*args, __func=self.autocomplete_func):
+                if self.cog is not None:
+                    await self.autocomplete_func(self.cog, *args, **kwargs)
+                else:
+                    await self.autocomplete_func(*args, **kwargs)
+        except Exception as exc:
+            if hasattr(self, 'on_error'):
+                if self.cog is not None:
+                    await self.on_error(self.cog, interaction, exc)
+                else:
+                    await self.on_error(interaction, exc)
+            else:
+                self._state.dispatch('application_command_error', self, interaction, exc)
+
+    @property
+    def sub_commands(self) -> List[Union[SubCommandGroup, SubCommand]]:
+        """List[Union[:class:`SubCommand`, :class:`SubCommandGroup`]: A list of sub-commands or sub-command groups the command has."""
+        return list(self._sub_commands.values())
+
+    @property
+    def options(self) -> Optional[List[SlashCommandOption]]:
+        """A :class:`list` of :class:`SlashCommandOption` the command has."""
+        return list(getattr(self, '_options', {}).values())
+
+    @classmethod
+    def from_dict(cls, state, data):
+        self: cls = cls.__new__(cls)
+        dmp = data.get('default_member_permissions', None)
+        self._type = ApplicationCommandType.chat_input
+        self.disabled = False
+        self.connector = {}
+        self.name = data.pop('name')
+        self.name_localizations = Localizations.from_dict(data.get('name_localizations', {}))
+        self.description = data.pop('description', 'No Description')
+        self.description_localizations = Localizations.from_dict(data.get('description_localizations', {}))
+        self.default_member_permissions = Permissions(int(dmp)) if dmp else None
+        self.integration_types: Optional[Set[AppIntegrationType]] = {
+            try_enum(AppIntegrationType, it) for it in i_types
+        } if (i_types := data.get('integration_types')) else None
+        self.contexts: Set[InteractionContextType] = {
+            try_enum(InteractionContextType, ct) for ct in (data.get('contexts', []) or [])
+        }
+        self.allow_dm = data.pop('dm_permission', (InteractionContextType.bot_dm in self.contexts))
+        self.is_nsfw = data.get('nsfw', False)
+        self._guild_id = int(data.get('guild_id', 0))
+        self._state_ = state
+        for opt in data.get('options', []):
+            opt['parent'] = self
+        options = [SlashCommandOption.from_dict({'parent': self, **opt}) for opt in data.pop('options', [])]
+        self._sub_commands = {command.name: command for command in options if OptionType.try_value(command.type) in
+                              (OptionType.sub_command, OptionType.sub_command_group)}
+        if not self._sub_commands:
+            self._options = {option.name: option for option in options}
+        self._fill_data(data)
+        return self
+
+    async def invoke(self, interaction, *args, **kwargs):
+        if not self.func:
+            return
+        args = (interaction, *args)
+        try:
+            if await self.can_run(*args):
+                if self.cog:
+                    await self.func(self.cog, *args, **kwargs)
+                else:
+                    await self.func(*args, **kwargs)
+        except Exception as exc:
+            if hasattr(self, 'on_error'):
+                if self.cog is not None:
+                    await self.on_error(self.cog, interaction, exc)
+                else:
+                    await self.on_error(interaction, exc)
+            else:
+                self._state.dispatch('application_command_error', self, interaction, exc)
+
+    async def _parse_arguments(self, interaction: ApplicationCommandInteraction) -> Any:
+        to_invoke = self
+        params = {}
+        options = interaction.data.options
+        if options:
+            if options[0].type in (OptionType.sub_command_group, OptionType.sub_command):
+                if options[0].type == OptionType.sub_command_group:
+                    command_group: SubCommandGroup = self._sub_commands[options[0].name]
+                    sub_command: SubCommand = command_group._sub_commands[options[0].options[0].name]
+                    options = options[0].options[0].options
+
+                else:
+                    sub_command: SubCommand = self._sub_commands[options[0].name]
+                    options = options[0].options
+                to_invoke = sub_command
+            connector = to_invoke.connector
+            resolved = getattr(interaction.data, 'resolved', None
+                               )  # speedup attribute access | None is when there are no options
+            for option in options:
+                # as we can't use - in argument names replace this by default,
+                # so you don't have to specify it in the connector for some-option -> some_option
+                name = connector.get(option.name) or option.name.replace('-', '_')
+                if option.type in (OptionType.string, OptionType.integer, OptionType.boolean, OptionType.number):
+                    origin_option = get(to_invoke.options, name=option.name)
+                    converter = origin_option.converter
+                    if converter:
+                        try:
+                            params[name] = await transform(interaction, origin_option, converter, str(option.value))
+                        except Exception as exc:
+                            if origin_option.ignore_conversion_failures:
+                                params[name] = option.value
+                            else:
+                                raise exc from exc
+                    else:
+                        params[name] = option.value
+                else:
+                    _id = int(option.value)
+                    if option.type == OptionType.user:
+                        params[name] = interaction.guild.get_member(_id) or resolved.members.get(_id, None) or resolved.users.get(_id, None) or _id
+                    elif option.type == OptionType.role:
+                        params[name] = resolved.roles[_id] or _id
+                    elif option.type == OptionType.channel:
+                        params[name] = interaction.guild.get_channel(_id) or resolved.channels[_id] or interaction._state.get_channel(_id)\
+                                       or PartialMessageable(interaction._state, _id, guild_id=interaction.guild)
+                    elif option.type == OptionType.mentionable:
+                        try:
+                            params[name] = resolved.roles[_id]
+                        except KeyError:
+                            params[name] = interaction.guild.get_member(_id) or resolved.members.get(_id, None) or resolved.users.get(_id, None) or _id
+                    elif option.type == OptionType.attachment:
+                        params[name] = resolved.attachments[_id] or _id
+
+        # pass the default values of the options to the params if they are not provided (usually used for autocomplete)
+        connector = to_invoke.connector
+        for o in to_invoke.options:
+            name = connector.get(o.name, o.name)
+            if (name not in params or params[name] is None) and o.default is not None:
+                params[name] = o.default
+
+        interaction._command = self
+        interaction.params = params
+        if interaction.type.ApplicationCommandAutocomplete:
+            interaction.focused = find(lambda opt: (opt.__getattribute__('focused') or None) is True, options)
+            return await to_invoke.invoke_autocomplete(interaction, **params)
+        return await to_invoke.invoke(interaction, **params)
+
+
+# TODO: Optimise and finish the conversion handling
+
+async def _actual_conversion(ctx, converter, argument, param):
+    from .ext.commands import CommandError, ConversionError, BadArgument, converter as converters
+    from .ext.commands.core import _convert_to_bool
+    if converter is bool:
+        return _convert_to_bool(argument)
+
+    try:
+        module = converter.__module__
+    except AttributeError:
+        pass
+    else:
+        if module is not None:
+            if module.startswith('discord.') and module.endswith('converter'):
+                pass
+            else:
+                converter = getattr(converters, converter.__name__ + 'Converter', converter)
+
+    try:
+        if inspect.isclass(converter):
+            if issubclass(converter, converters.Converter):
+                instance = converter()
+                ret = await instance.convert(ctx, argument)
+                return ret
+            else:
+                method = getattr(converter, 'convert', None)
+                if method is not None and inspect.ismethod(method):
+                    ret = await method(ctx, argument)
+                    return ret
+        elif isinstance(converter, converters.Converter):
+            ret = await converter.convert(ctx, argument)
+            return ret
+    except CommandError:
+        raise
+    except Exception as exc:
+        raise ConversionError(converter, exc) from exc
+
+    try:
+        return converter(argument)
+    except CommandError:
+        raise
+    except Exception as exc:
+        try:
+            name = converter.__name__
+        except AttributeError:
+            name = converter.__class__.__name__
+
+        raise BadArgument('Converting to "{}" failed for parameter "{}".'.format(name, param.name)) from exc
+
+
+async def do_conversion(interaction, converter, argument, param):
+    from .ext.commands import CommandError, BadUnionArgument
+    try:
+        origin = converter.__origin__
+    except AttributeError:
+        pass
+    else:
+        if origin is Union:
+            errors = []
+            _NoneType = type(None)
+            for conv in converter.__args__:
+                # if we got to this part in the code, then the previous conversions have failed,
+                # so we should just undo the view, return the default, and allow parsing to continue
+                # with the other parameters
+                if conv is _NoneType:
+                    return param.default or argument
+
+                try:
+                    value = await conv().convert(interaction, argument)
+                except CommandError as exc:
+                    errors.append(exc)
+                else:
+                    return value
+
+            # if we're  here, then we failed all the converters
+            raise BadUnionArgument(param, converter.__args__, errors)
+
+    return await _actual_conversion(interaction, converter, argument, param)
+
+
+async def _transform_greedy_pos(ctx, param, required, converter, value):
+    from .ext.commands import CommandError, ArgumentParsingError
+    from .ext.commands.view import StringView
+    view = StringView(value)
+    result = []
+    while not view.eof:
+        # for use with a manual undo
+        previous = view.index
+
+        view.skip_ws()
+        try:
+            argument = view.get_quoted_word()
+            value = await do_conversion(ctx, converter, argument, param)
+        except (CommandError, ArgumentParsingError):
+            view.index = previous
+            break
+        else:
+            result.append(value)
+
+    if not result and not required:
+        return param.default
+    return result
+
+
+async def transform(interaction: ApplicationCommandInteraction, param: SlashCommandOption, converter, value: Any) -> Any:
+    from .ext.commands.converter import _Greedy
+    if type(converter) is _Greedy:
+        return await _transform_greedy_pos(interaction, param, param.required, converter.converter, value)
+    return await do_conversion(interaction, converter, value, param)
+
+
+class GuildOnlySlashCommand(SlashCommand):
+    def __init__(self, *args, guild_ids: Optional[List[int]] = None, **kwargs):
+        super().__init__(*args, **kwargs, guild_ids=guild_ids)
+        self._commands = kwargs.get('commands', [])
+
+    @property
+    def disabled(self) -> bool:
+        return self._disabled
+
+    @disabled.setter
+    def disabled(self, value: bool):
+        self._disabled = value
+        for cmd in self._commands:
+            cmd.disabled = value
+
+    def __repr__(self):
+        return '<GuildOnlySlashCommand name=%s, description=%s, default_member_permissions=%s, options=%s, guild_ids=%s>' \
+               % (self.name,
+                  self.description,
+                  self.default_member_permissions,
+                  self.options,
+                  ', '.join([str(g) for g in self.guild_ids])
+                  )
+
+    def autocomplete_callback(self, coro: Callable[[AutocompleteInteraction, ...], Coroutine]):
+        """
+        A decorator that sets a |coroutine_link|_ function as the function that will be called
+        when discord sends an autocomplete interaction for this command.
+
+        Parameters
+        ----------
+        coro: Callable[[:class:`AutocompleteInteraction`, ...], Coroutine]
+            The function that should be set as autocomplete_func for this command.
+            Must take the same amount of params the command itself takes.
+
+        Raises
+        ------
+        TypeError
+            The function passed is not a coroutine.
+        """
+        if not asyncio.iscoroutinefunction(coro):
+            raise TypeError('The autocomplete callback function must be a coroutine.')
+        self.autocomplete_func = coro
+        for cmd in self._commands:
+            cmd.autocomplete_func = coro
+        return coro
+
+    @copy_doc(ApplicationCommand.error)
+    def error(self, coro: Callable[[ApplicationCommandInteraction, Exception], Coroutine]):
+        if not asyncio.iscoroutinefunction(coro):
+            raise TypeError('The error handler registered must be a coroutine.')
+        for cmd in self._commands:
+            cmd.on_error = coro
+        return coro
+
+
+class UserCommand(ApplicationCommand):
+    """
+    Represents a user context-menu command
+
+    .. note::
+        You should use :func:`discord.Client.user_command` or in cogs :func:`~discord.ext.commands.Cog.user_command`
+        decorator by default to create this.
+
+    Parameters
+    ----------
+    name: Optional[:class:`str`]
+        The name of the user-command, default to the functions name.
+        Must be between 1-32 characters long.
+    default_required_permissions: Optional[:class:`~discord.Permissions`]
+        Permissions that a Member needs by default to execute(see) the command.
+    allow_dm:  :class:`bool`
+        Indicates whether the command is available in DMs with the app, only for globally-scoped commands. By default, commands are visible.
+
+    """
+
+    def __init__(
+            self,
+            name: str,
+            name_localizations: Optional[Localizations] = None,
+            default_member_permissions: Optional[Union[Permissions, int]] = None,
+            allow_dm: Optional[bool] = True,
+            integration_types: Optional[Set[AppIntegrationType]] = None,
+            contexts: Set[InteractionContextType] = set(),
+            **kwargs
+            ):
+        if 32 < len(name) < 1:
+            raise ValueError('The name of the User-Command has to be 1-32 characters long, got %s.' % len(name))
+        super().__init__(2, name=name, name_localizations=name_localizations,
+                         default_member_permissions=default_member_permissions, allow_dm=allow_dm, integration_types=integration_types,
+                         contexts=contexts, **kwargs
+                         )
+
+    @classmethod
+    def from_dict(cls, state, data):
+        dmp = data.pop('default_member_permissions', None)
+        data.pop('type')
+        integration_types: Optional[Set[AppIntegrationType]] = {
+            try_enum(AppIntegrationType, it) for it in i_types
+        } if (i_types := data.get('integration_types')) else None
+        contexts: Set[InteractionContextType] = {
+            try_enum(InteractionContextType, ct) for ct in (data.get('contexts', []) or [])
+        }
+        allow_dm = data.pop('dm_permission', (InteractionContextType.bot_dm in contexts))
+        return cls(
+            name=data.pop('name'),
+            name_localizations=Localizations.from_dict(data.get('name_localizations', {})),
+            default_member_permissions=Permissions(int(dmp)) if dmp else None,
+            allow_dm=allow_dm,
+            integration_types=integration_types,
+            contexts=contexts,
+            state=state,
+            **data
+        )._fill_data(data)
+
+    async def _parse_arguments(self, interaction: ApplicationCommandInteraction):
+        await self.invoke(interaction, interaction.target)
+
+
+class MessageCommand(ApplicationCommand):
+    """
+    Represents a message context-menu command
+
+    .. note::
+        You should use :func:`discord.Client.message_command` or in cogs :func:`~discord.ext.commands.Cog.message_command`
+        decorator by default to create this.
+
+    Parameters
+    ----------
+    name: Optional[:class:`str`]
+        The name of the message-command, default to the functions name.
+        Must be between 1-32 characters long.
+    default_required_permissions: Optional[:class:`Permissions`]
+        Permissions that a Member needs by default to execute(see) the command.
+    allow_dm: Optional[:class:`~discord.Permissions`]
+        Indicates whether the command is available in DMs with the app, only for globally-scoped commands.
+        By default, commands are visible.
+    """
+
+    def __init__(
+            self,
+            name: str,
+            name_localizations: Optional[Localizations] = Localizations(),
+            default_member_permissions: Optional[Union[Permissions, int]] = None,
+            allow_dm: Optional[bool] = True,
+            integration_types: Optional[Set[AppIntegrationType]] = None,
+            contexts: Set[InteractionContextType] = set(),
+            **kwargs
+            ):
+        if 32 < len(name) < 1:
+            raise ValueError('The name of the Message-Command has to be 1-32 characters long, got %s.' % len(name))
+        super().__init__(3, name=name, name_localizations=name_localizations,
+                         default_member_permissions=default_member_permissions, allow_dm=allow_dm, integration_types=integration_types,
+                         contexts=contexts, **kwargs
+                         )
+
+    @classmethod
+    def from_dict(cls, state, data):
+        dmp = data.pop('default_member_permissions', None)
+        data.pop('type')
+        integration_types: Optional[Set[AppIntegrationType]] = {
+            try_enum(AppIntegrationType, it) for it in i_types
+        } if (i_types := data.get('integration_types')) else None
+        contexts: Set[InteractionContextType] = {
+            try_enum(InteractionContextType, ct) for ct in (data.get('contexts', []) or [])
+        }
+        allow_dm = data.pop('dm_permission', (InteractionContextType.bot_dm in contexts))
+        return cls(
+            name=data.pop('name'),
+            name_localizations=Localizations.from_dict(data.pop('name_localizations', {})),
+            default_member_permissions=Permissions(int(dmp)) if dmp else None,
+            allow_dm=allow_dm,
+            integration_types=integration_types,
+            contexts=contexts,
+            state=state,
+            **data
+        )._fill_data(data)
+
+    async def _parse_arguments(self, interaction: ApplicationCommandInteraction):
+        await self.invoke(interaction, interaction.target)
+
+
+class SubCommandGroup(SlashCommandOption):
+    def __init__(
+            self,
+            parent: Union[SlashCommand, GuildOnlySlashCommand],
+            name: str,
+            description: str,
+            name_localizations: Optional[Localizations] = Localizations(),
+            description_localizations: Optional[Localizations] = Localizations(),
+            commands: List[SubCommand] = [],
+            **kwargs
+            ):
+        self.cog = kwargs.get('cog', None)
+        if not CHAT_COMMAND_NAME_REGEX.match(name):
+            raise ValueError(
+                r'Command names and options must follow the regex "^[-_\w0-9\u0901-\u097D\u0E00-\u0E7F]{1,32}$"'
+                f'{api_docs}/interactions/application-commands#application-command-object-application-command-naming.'
+                f'Got "{name}" with length {len(name)}.'
+            )
+        self.name = name
+        if 100 < len(description) < 1:
+            raise ValueError(
+                'The description of the Sub-Command-Group must be 1-100 characters long, got %s.' % len(description)
+                )
+        if 25 < len(commands) < 1:
+            raise ValueError('A Sub-Command-Group needs 1-25 sub-sub_commands, got %s.' % len(commands))
+        self.guild_ids = kwargs.get('guild_ids', parent.guild_ids)
+        self.guild_id = kwargs.get('guild_id', parent.guild_id)
+        self.func = kwargs.get('func', None)
+        self._disabled = False
+        super().__init__(OptionType.sub_command_group, name=name, name_localizations=name_localizations,
+                         description=description, description_localizations=description_localizations,
+                         __options=commands
+                         )
+        self._sub_commands = {command.name: command for command in commands}
+        for sub_command in self.sub_commands:
+            sub_command.parent = self
+
+        self.parent = parent
+
+    def __repr__(self):
+        return '<SubCommandGroup parent=%s, name=%s, description=%s, sub_commands=%s>' % \
+               (self.parent.name,
+                self.name,
+                self.description,
+                ', '.join([sub_cmd.name for sub_cmd in self.sub_commands])
+                )
+
+    @property
+    def parent(self) -> SlashCommand:
+        return getattr(self, '_parent_', None)
+
+    @parent.setter
+    def parent(self, value) -> None:
+        setattr(self, '_parent_', value)
+        for sub_command in self.sub_commands:
+            sub_command.parent = self
+
+    @property
+    def _state(self):
+        return self.parent._state
+
+    @property
+    def disabled(self) -> bool:
+        return self._disabled
+
+    @disabled.setter
+    def disabled(self, value: bool) -> None:
+        self._disabled = value
+        for cmd in self.sub_commands:
+            cmd.disabled = value
+
+    @property
+    def sub_commands(self) -> List[SubCommand]:
+        """List[:class:`SubCommand`]: Returns a list of sub-commands the group has"""
+        return list(self._sub_commands.values())
+
+    def to_dict(self):
+        base = {
+            'type': 2,
+            'name': str(self.name),
+            'name_localizations': self.name_localizations.to_dict(),
+            'description': str(self.description),
+            'description_localizations': self.description_localizations.to_dict(),
+            'options': [c.to_dict() for c in self.sub_commands]
+        }
+        return base
+
+    @classmethod
+    def from_dict(cls, data):
+        parent = data.get('parent', None)
+        return cls(
+            parent=parent,
+            name=data['name'],
+            name_localizations=Localizations.from_dict(data.get('name_localizations', {})),
+            description=data.get('description', 'No description'),
+            description_localizations=Localizations.from_dict(data.get('description_localizations', {})),
+            options=[SubCommand.from_dict({'parent': parent, **c}) for c in data.get('options', [])]
+        )
+
+
+class GuildOnlySubCommandGroup(SubCommandGroup):
+    def __init__(self, *args, guild_ids: List[int] = None, **kwargs):
+        super().__init__(*args, **kwargs, guild_ids=guild_ids)
+
+    def __repr__(self):
+        return '<GuildOnlySubCommandGroup parent=%s, name=%s, description=%s, sub_commands=%s, guild_ids=%s>' % \
+               (self.parent.name,
+                self.name,
+                self.description,
+                ', '.join([sub_cmd.name for sub_cmd in self.sub_commands]),
+                ', '.join([str(g) for g in self.guild_ids])
+                )
+
+
+def generate_options(
+        func: FunctionType,
+        descriptions: dict = {},
+        descriptions_localizations: Dict[str, Localizations] = {},
+        connector: dict = {},
+        is_cog: bool = False
+):
+    """
+    This function is used to create the options for a :class:`SlashCommand`/:class:`SubCommand`
+    out of the parameters of a function if no options are provided in the decorator.
+
+    .. warning::
+        It is recommended to specify the options for the slash-command in the decorator.
+
+    Parameters
+    ----------
+    func: :class:`types.FunctionType`
+        The function from whose parameters and annotations the options for the slash-command are generated.
+    descriptions:  Optional[Dict[:class:`str`, :class:`str`]]
+        A dictionary with the name of the parameter as key and the description as value.
+        The default description would be "No Description".
+    descriptions_localizations: Optional[Dict[:class:`str`, :class:`Localizations`]]
+        A dictionary containing the parameter name as key and the localized descriptions as value.
+    connector: Optional[Dict[:class:`str`, :class:`str`]]
+        A dictionary containing the name of function-parameters as keys and the name of the option as values.
+        Useful for using non-ascii letters in your option names without getting (IDE-)errors.
+    is_cog: Optional[:class:`bool`]
+        Whether the :attr:`func` is inside a :class:`discord.exc.commands.Cog`. Used for Error handling.
+
+    Returns
+    -------
+    List[:class:`SlashCommandOption`]
+        The options that where created.
+
+    Raises
+    ------
+    TypeError:
+        The function/method specified at :attr:`func` is missing a parameter to which the interaction object is passed.
+    """
+    # TODO: Rewrite this completely
+    from .ext.commands import Converter, Greedy, converter as converters
+    from .ext.commands.converter import _Greedy
+    _NoneType = type(None)
+    options = []
+    parameters = inspect.signature(func).parameters.values()
+    if (not parameters) or is_cog and len(parameters) < 2:
+        raise TypeError(f'The {"method" if is_cog else "function"} for the slash-command must take at least '
+                        f'{"two parameters" if is_cog else "one parameter"}; {"self and " if is_cog else ""} a parameter'
+                        f'that takes the Interaction object.'
+                        )
+    parameters = parameters.__iter__()
+    if next(parameters).name in ('self', 'cls'):
+        next(parameters)
+
+    for param in parameters:
+        description_localizations = descriptions_localizations.get(connector.get(param.name, param.name),
+                                                                   Localizations()
+                                                                   )
+        description = descriptions.get(param.name, descriptions.get(connector.get(param.name, ''), 'No Description'))
+        _type = None
+        name = connector.get(param.name, param.name)
+        choices = []
+        channel_types = []
+        required = True
+        is_channel = False
+        default = None
+        converter = None
+
+        if param.kind in (param.VAR_POSITIONAL, param.VAR_KEYWORD):  # Skip parameters like *args and **kwargs
+            continue
+        if param.default is not inspect._empty:  # type: ignore
+            # If a default value for the parameter is set, then the option is not required.
+            required = False
+            default = param.default
+        # PEP-563 allows postponing evaluation of annotations with a __future__
+        # import. When postponed, Parameter.annotation will be a string and must
+        # be replaced with the real value for using them
+        if isinstance(param.annotation, str):
+            param: inspect.Parameter = param.replace(annotation=eval(param.annotation, func.__globals__))
+        annotation = param.annotation
+        if annotation is inspect._empty:  # type: ignore
+            # The parameter is not annotated.
+            # Since we can't know what the person wants, we assume it's a string, add the option and continue.
+            options.append(
+                SlashCommandOption(option_type=OptionType.string,
+                                   name=name,
+                                   description=description,
+                                   description_localizations=description_localizations,
+                                   required=required,
+                                   default=default
+                                   )
+            )
+            continue
+        if annotation is Greedy:
+            raise TypeError('Unparameterized Greedy[...] is disallowed in signature.')
+        if isinstance(annotation, SlashCommandOption):
+            # If you annotate a parameter with an instance of SlashCommandOption (not recommended)
+            # just add to the options and continue.
+            annotation.name = name
+            options.append(annotation)
+            continue
+        module = annotation.__module__
+        if type(annotation) is _Greedy:
+            converter = annotation
+
+        option_type_is_class = isinstance(annotation, type)
+        if option_type_is_class and issubclass(annotation, (Enum, DiscordEnum)):
+            if description is None:
+                description = inspect.getdoc(annotation)
+            choices = [SlashCommandOptionChoice(e.name.translate({95: 0x20}), e.value) for e in annotation]
+            value_class = choices[0].value.__class__
+
+            if all(isinstance(elem.value, value_class) for elem in choices):
+                option_type, _ = OptionType.from_type(
+                    choices[0].value.__class__
+                )
+            else:
+                choices = [SlashCommandOptionChoice(e.name.translate({95: 0x20}), str(e.value)) for e in annotation]
+                option_type = OptionType.string
+            options.append(
+                SlashCommandOption(
+                    option_type=option_type,
+                    name=name,
+                    description=description,
+                    description_localizations=description_localizations,
+                    required=required,
+                    choices=choices,
+                    default=default,
+                    converter=converter
+                )
+            )
+            continue
+        elif getattr(annotation, '__origin__', None) is Union:
+            # The parameter is annotated with a Union so multiple types are possible.
+            args = getattr(annotation, '__args__', [])
+            union: List[Any] = []
+            if isinstance(args, tuple):
+                args = list(args)
+            for index, arg in enumerate(args):
+                if arg is _NoneType:  # If one of the types is NoneType, then the option is also not required.
+                    required = False
+                elif issubclass(arg, GuildChannel) or isinstance(arg, ChannelType):
+                    # If you use Union to define the types of channels you can choose from.
+                    # For example only voice- and stage-channels.
+                    _type = ChannelType.from_type(arg)
+                    args[index] = _type
+                    channel_types.append(_type)
+                else:
+                    if issubclass(arg, Converter):
+                        union.append(arg)
+                        continue
+                    try:
+                        module = arg.__module__
+                    except AttributeError:
+                        pass
+                    else:
+                        if module is not None:
+                            if module.startswith('discord.') and module.endswith('converter'):
+                                pass
+                            else:
+                                if hasattr(arg, 'convert'):
+                                    union.append(arg)
+                                else:
+                                    try:
+                                        conv = getattr(converters, arg.__name__ + 'Converter')
+                                    except AttributeError:
+                                        _type, channel_types = OptionType.from_type(arg)
+                                    else:
+                                        union.append(conv)
+
+            # remove NoneType's
+            [args.remove(rn) for rn in args if rn is _NoneType]
+            if all([isinstance(a, ChannelType) for a in args]):
+                is_channel = True
+            if is_channel:
+                options.append(
+                    SlashCommandOption(option_type=OptionType.channel,
+                                       name=name,
+                                       required=required,
+                                       channel_types=channel_types,
+                                       description=description,
+                                       description_localizations=description_localizations,
+                                       default=default
+                                       )
+                )
+                continue
+            elif union and all([tp.__name__ in ['MemberConverter', 'UserConverter', 'RoleConverter'] for tp in union]):
+                pass
+            else:
+                if union:
+                    converter = Union[tuple(union)]  # type: ignore
+                options.append(
+                    SlashCommandOption(option_type=_type or OptionType.string,
+                                       name=name,
+                                       description=description,
+                                       description_localizations=description_localizations,
+                                       required=required,
+                                       choices=choices,
+                                       default=default,
+                                       converter=converter
+                                       )
+                )
+                continue
+        elif getattr(annotation, '__origin__', None) is Literal:
+            # Use Literal to specify choices in the annotation.
+            args = getattr(annotation, '__args__', [])
+            try:
+                # Get all the values for the choices
+                values = []
+                for a in args:
+                    if isinstance(a, dict):
+                        values.extend(list(a.values()))
+                    elif isinstance(a, (list, tuple)):
+                        values.append(a[1])
+                    else:
+                        values.append(a)
+            except Exception:
+                raise ValueError(
+                    'If you use Literal to declare choices for the Option you could only use the following schemas:'
+                    '[name, value], (name, value), {one_name: one_value, other_name: other_value, ...} or the values (will be used as name)'
+                    'The way you do it is not supportet.'
+                )
+            if all([isinstance(c, type(values[0])) for c in values]):
+                # Find out what type of option it is; string, integer or number. Default to string.
+                option_type: Union[str, int, float] = type(values[0]) if isinstance(values[0], (str, int, float)
+                                                                                    ) else str
+            else:
+                option_type = str
+            for arg in args:
+                if isinstance(arg, (list, tuple)):
+                    choices.append(SlashCommandOptionChoice(str(arg[0]), option_type(arg[1])))
+                elif isinstance(arg, dict):
+                    for k, v in arg.items():
+                        choices.append(SlashCommandOptionChoice(str(k), option_type(v)))
+                else:
+                    choices.append(SlashCommandOptionChoice(str(arg), option_type(arg)))
+            options.append(
+                SlashCommandOption(
+                    option_type=option_type,
+                    name=name,
+                    description=description,
+                    description_localizations=description_localizations,
+                    requiered=required,
+                    choices=choices,
+                    default=default
+                )
+            )
+            continue
+        elif isinstance(annotation, dict):
+            # Use a dictionary as annotation to declare choices for a option.
+            values = list(annotation.values())
+            if all([isinstance(v, type(values[0])) for v in values]):
+                # Find out what type of option it is; string, integer or number. Default to string.
+                option_type = type(values[0]) if isinstance(values[0], (str, int, float)) else str
+            else:
+                option_type = str
+            for k, v in annotation.items():
+                choices.append(SlashCommandOptionChoice(str(k), option_type(v)))
+            options.append(
+                SlashCommandOption(option_type=option_type,
+                                   name=name,
+                                   description=description,
+                                   description_localizations=description_localizations,
+                                   requiered=required,
+                                   choices=choices,
+                                   default=default
+                                   )
+            )
+            continue
+        _type, channel_types = OptionType.from_type(annotation) or (OptionType.string, None)
+        options.append(
+            SlashCommandOption(option_type=_type,
+                               name=name,
+                               description=description,
+                               description_localizations=description_localizations,
+                               required=required,
+                               choices=choices,
+                               channel_types=channel_types,
+                               default=default,
+                               converter=converter
+                               )
+        )
+    return options
+
+
+class GuildAppCommandPermissions:
+    """
+    Represents a list of permissions for an application command in a guild.
+    
+    Attributes
+    ----------
+    command_id: :class:`int`
+        The ID of the application command.
+    application_id: :class:`int`
+        The ID of the application.
+    guild_id: :class:`int`
+        The ID of the guild.
+    permissions: List[:class:`AppCommandPermission`]
+        The permissions for the guild's application commands.
+    """
+    def __init__(
+            self,
+            *,
+            command_id: int,
+            application_id: int,
+            guild_id: int,
+            permissions: List[AppCommandPermission]
+    ):
+        self.command_id: int = command_id
+        self.application_id: int = application_id
+        self.guild_id: int = guild_id
+        self.permissions: List[AppCommandPermission] = permissions
+        
+    def to_dict(self) -> dict:
+        return {
+            'id': self.guild_id,
+            'permissions': [p.to_dict() for p in self.permissions]
+        }
+
+    @classmethod
+    def from_dict(cls, data: dict) -> GuildAppCommandPermissions:
+        return cls(
+            command_id=int(data['id']),
+            application_id=int(data['application_id']),
+            guild_id=int(data['guild_id']),
+            permissions=[AppCommandPermission.from_dict(p) for p in data['permissions']]
+        )
+
+
+class AppCommandPermission:
+    """
+    Represents a permission for an application command.
+
+    Attributes
+    ----------
+    id: Union[:class:`str`, :class:`int`]
+        The ID of the role, user, or channel.
+        
+        .. note::
+             
+             This can be the guild ID for the default role (``@everyone``) or guild ID - 1 for all channels.
+             
+    type: :class:`AppCommandPermissionType`
+        The target this permission applies to.
+    permission: :class:`bool`
+        ``True`` to allow, ``False`` to disallow.
+    """
+    def __init__(
+            self,
+            id: Union[int, str],
+            type: AppCommandPermissionType,
+            permission: bool
+    ):
+        """
+        Represents a permission for an application command.
+        
+        Parameters
+        ----------
+        id: Union[:class:`str`, :class:`int`]
+            The ID of the role, user, or channel.
+            
+            .. note::
+                 
+                 This can be the guild ID for the default role (``@everyone``) or guild ID - 1 for all channels.
+        
+        type: :class:`AppCommandPermissionType`
+            The target this permission applies to.
+        permission: :class:`bool`
+            ``True`` to allow, ``False`` to disallow.
+        """
+        self.id: int = int(id)
+        self.type: AppCommandPermissionType = type
+        self.permission: bool = permission
+        
+    def to_dict(self) -> dict:
+        return {
+            'id': self.id,
+            'type': self.type.value,
+            'permission': self.permission
+        }
+
+    @classmethod
+    def from_dict(cls, data: app_command.ApplicationCommandPermission) -> AppCommandPermission:
+        return cls(int(data['id']), try_enum(AppCommandPermissionType, data['type']), data['permission'])
+    
+    @classmethod
+    async def all_channels(cls, guild_id: SupportsStr, permission: bool) -> AppCommandPermission:
+        """
+        Creates a new AppCommandPermission for all channels in a guild.
+        
+        This is equivalent to:
+        
+        .. code-block:: python3
+        
+            AppCommandPermission(guild_id - 1, AppCommandPermissionType.ROLE, permission)
+        
+        Parameters
+        ----------
+        guild_id: Union[:class:`str`, :class:`int`]
+            The guild ID.
+        permission: :class:`bool`
+            The permission.
+        
+        Returns
+        -------
+        :class:`AppCommandPermission`
+            The new AppCommandPermission.
+        """
+        return cls(int(guild_id) - 1, AppCommandPermissionType.ROLE, permission)
diff --git a/discord/asset.py b/discord/asset.py
index ea457297..f7ed8681 100644
--- a/discord/asset.py
+++ b/discord/asset.py
@@ -3,7 +3,7 @@
 """
 The MIT License (MIT)
 
-Copyright (c) 2015-present Rapptz
+Copyright (c) 2015-2021 Rapptz & (c) 2021-present mccoderpy
 
 Permission is hereby granted, free of charge, to any person obtaining a
 copy of this software and associated documentation files (the "Software"),
@@ -23,15 +23,49 @@
 FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 DEALINGS IN THE SOFTWARE.
 """
+from __future__ import annotations
 
 import io
-from .errors import DiscordException
-from .errors import InvalidArgument
+
+from typing import (
+    BinaryIO,
+    Optional,
+    TYPE_CHECKING,
+    Union
+)
+
+if TYPE_CHECKING:
+    from os import PathLike
+    from .state import ConnectionState
+    from .oauth2 import (
+        OAuth2Client,
+        PartialGuild,
+        GuildMember,
+        User as OAuth2User
+    )
+    from .user import User
+    from .member import Member
+    from .sticker import Sticker, GuildSticker, StickerPack
+    from .guild import Guild
+    from .emoji import Emoji
+    from .partial_emoji import PartialEmoji
+    from .scheduled_event import GuildScheduledEvent
+    from .types.snowflake import SnowflakeID
+    
+    HAS_HTTP_CONNECTION = Union[ConnectionState, OAuth2Client]
+
+
+from .errors import DiscordException, InvalidArgument
 from . import utils
 
+__all__ = (
+    'Asset',
+)
+
 VALID_STATIC_FORMATS = frozenset({"jpeg", "jpg", "webp", "png"})
 VALID_AVATAR_FORMATS = VALID_STATIC_FORMATS | {"gif"}
 
+
 class Asset:
     """Represents a CDN asset on Discord.
 
@@ -65,12 +99,24 @@ class Asset:
 
     BASE = 'https://cdn.discordapp.com'
 
-    def __init__(self, state, url=None):
-        self._state = state
-        self._url = url
+    def __init__(
+            self,
+            state: HAS_HTTP_CONNECTION,
+            url: Optional[str] = None
+    ):
+        self._state: HAS_HTTP_CONNECTION = state
+        self._url: Optional[str] = url
 
     @classmethod
-    def _from_avatar(cls, state, user, *, format=None, static_format='webp', size=1024):
+    def _from_avatar(
+            cls,
+            state: HAS_HTTP_CONNECTION,
+            user: Union[User, OAuth2User],
+            *,
+            format=None,
+            static_format='webp',
+            size=1024
+    ):
         if not utils.valid_icon_size(size):
             raise InvalidArgument("size must be a power of 2 between 16 and 4096")
         if format is not None and format not in VALID_AVATAR_FORMATS:
@@ -89,7 +135,122 @@ def _from_avatar(cls, state, user, *, format=None, static_format='webp', size=10
         return cls(state, '/avatars/{0.id}/{0.avatar}.{1}?size={2}'.format(user, format, size))
 
     @classmethod
-    def _from_icon(cls, state, object, path, *, format='webp', size=1024):
+    def _from_guild_avatar(
+            cls,
+            state: HAS_HTTP_CONNECTION,
+            member: Union[Member, GuildMember],
+            *,
+            format=None,
+            static_format='webp',
+            size=1024
+    ):
+        if not utils.valid_icon_size(size):
+            raise InvalidArgument("size must be a power of 2 between 16 and 4096")
+        if format is not None and format not in VALID_AVATAR_FORMATS:
+            raise InvalidArgument("format must be None or one of {}".format(VALID_AVATAR_FORMATS))
+        if format == "gif" and not member.is_guild_avatar_animated():
+            raise InvalidArgument("non animated avatars do not support gif format")
+        if static_format not in VALID_STATIC_FORMATS:
+            raise InvalidArgument("static_format must be one of {}".format(VALID_STATIC_FORMATS))
+
+        if member.guild_avatar is None:
+            return member.avatar_url
+
+        if format is None:
+            format = 'gif' if member.is_guild_avatar_animated() else static_format
+
+        return cls(
+            state,
+            '/guilds/{0.guild.id}/users/{0.id}/avatars/{0.guild_avatar}.{1}?size={2}'.format(member, format, size)
+        )
+
+    @classmethod
+    def _from_avatar_decoration(
+            cls,
+            state: HAS_HTTP_CONNECTION,
+            user: Union[User, OAuth2User],
+            *,
+            format=None,
+            static_format='webp',
+            size=1024
+    ):
+        if not utils.valid_icon_size(size):
+            raise InvalidArgument("size must be a power of 2 between 16 and 4096")
+        if format is not None and format not in VALID_AVATAR_FORMATS:
+            raise InvalidArgument(f"format must be None or one of {VALID_AVATAR_FORMATS}")
+        if static_format not in VALID_STATIC_FORMATS:
+            raise InvalidArgument(f"static_format must be one of {VALID_STATIC_FORMATS}")
+
+        if user.avatar_decoration is None:
+            return None
+
+        return cls(state, '/avatar-decoration-presets/{0.avatar_decoration}.{1}?size={2}'.format(user, format, size))
+
+    @classmethod
+    def _from_banner(
+            cls,
+            state: HAS_HTTP_CONNECTION,
+            user,
+            *,
+            format=None,
+            static_format='webp',
+            size=1024
+    ):
+        if not user.banner:
+            return None
+        if not utils.valid_icon_size(size):
+            raise InvalidArgument("size must be a power of 2 between 16 and 4096")
+        if format is not None and format not in VALID_AVATAR_FORMATS:
+            raise InvalidArgument("format must be None or one of {}".format(VALID_AVATAR_FORMATS))
+        if format == "gif" and not user.is_banner_animated():
+            raise InvalidArgument("non animated avatars do not support gif format")
+        if static_format not in VALID_STATIC_FORMATS:
+            raise InvalidArgument("static_format must be one of {}".format(VALID_STATIC_FORMATS))
+
+        if format is None:
+            format = 'gif' if user.is_banner_animated() else static_format
+
+        return cls(state, f'/banners/{user.id}/{user.banner}.{format}?size={size}')
+
+    @classmethod
+    def _from_guild_banner(
+            cls,
+            state: HAS_HTTP_CONNECTION,
+            member: Member,
+            *,
+            format=None,
+            static_format='webp',
+            size=1024
+    ):
+        if not member.guild_banner:
+            return None
+        if not utils.valid_icon_size(size):
+            raise InvalidArgument("size must be a power of 2 between 16 and 4096")
+        if format is not None and format not in VALID_AVATAR_FORMATS:
+            raise InvalidArgument("format must be None or one of {}".format(VALID_AVATAR_FORMATS))
+        if format == "gif" and not member.is_banner_animated():
+            raise InvalidArgument("non animated avatars do not support gif format")
+        if static_format not in VALID_STATIC_FORMATS:
+            raise InvalidArgument("static_format must be one of {}".format(VALID_STATIC_FORMATS))
+
+        if format is None:
+            format = 'gif' if member.is_banner_animated() else static_format
+
+        return cls(
+            state,
+            '/guilds/{0.guild.id}/users/{0.id}/banners/{0.guild_banner}.{1}?size={2}'.format(member, format, size)
+        )
+
+    @classmethod
+    def _from_icon(
+            cls,
+            state: HAS_HTTP_CONNECTION,
+            object,
+            path,
+            *,
+            format='webp',
+            size=1024
+    ):
         if object.icon is None:
             return cls(state)
 
@@ -102,7 +263,14 @@ def _from_icon(cls, state, object, path, *, format='webp', size=1024):
         return cls(state, url)
 
     @classmethod
-    def _from_cover_image(cls, state, obj, *, format='webp', size=1024):
+    def _from_cover_image(
+            cls,
+            state: HAS_HTTP_CONNECTION,
+            obj,
+            *,
+            format='webp',
+            size=1024
+    ):
         if obj.cover_image is None:
             return cls(state)
 
@@ -115,7 +283,16 @@ def _from_cover_image(cls, state, obj, *, format='webp', size=1024):
         return cls(state, url)
 
     @classmethod
-    def _from_guild_image(cls, state, id, hash, key, *, format='webp', size=1024):
+    def _from_guild_image(
+            cls,
+            state: HAS_HTTP_CONNECTION,
+            id: SnowflakeID,
+            hash: str,
+            key: str,
+            *,
+            format='webp',
+            size=1024
+    ):
         if not utils.valid_icon_size(size):
             raise InvalidArgument("size must be a power of 2 between 16 and 4096")
         if format not in VALID_STATIC_FORMATS:
@@ -128,7 +305,15 @@ def _from_guild_image(cls, state, id, hash, key, *, format='webp', size=1024):
         return cls(state, url.format(id, hash, format, size, key=key))
 
     @classmethod
-    def _from_guild_icon(cls, state, guild, *, format=None, static_format='webp', size=1024):
+    def _from_guild_icon(
+            cls,
+            state: HAS_HTTP_CONNECTION,
+            guild: Union[Guild, PartialGuild],
+            *,
+            format=None,
+            static_format='webp',
+            size=1024
+    ):
         if not utils.valid_icon_size(size):
             raise InvalidArgument("size must be a power of 2 between 16 and 4096")
         if format is not None and format not in VALID_AVATAR_FORMATS:
@@ -147,14 +332,38 @@ def _from_guild_icon(cls, state, guild, *, format=None, static_format='webp', si
         return cls(state, '/icons/{0.id}/{0.icon}.{1}?size={2}'.format(guild, format, size))
 
     @classmethod
-    def _from_sticker_url(cls, state, sticker, *, size=1024):
+    def _from_sticker(
+            cls,
+            state: HAS_HTTP_CONNECTION,
+            sticker: Union[Sticker, GuildSticker],
+            *,
+            format=None
+    ):
+        return cls(state, f'/stickers/{sticker.id}.{format}')
+
+    @classmethod
+    def _from_sticker_pack(
+            cls,
+            state: HAS_HTTP_CONNECTION,
+            sticker_pack: StickerPack,
+            format='png',
+            size=1024
+    ):
         if not utils.valid_icon_size(size):
             raise InvalidArgument("size must be a power of 2 between 16 and 4096")
-
-        return cls(state, '/stickers/{0.id}/{0.image}.png?size={2}'.format(sticker, format, size))
+        if format is not None and format not in VALID_STATIC_FORMATS:
+            raise InvalidArgument("format must be None or one of {}".format(VALID_AVATAR_FORMATS))
+        return cls(state, f'/app-assets/710982414301790216/store/{sticker_pack.banner_asset_id}.{format}?size={size}')
 
     @classmethod
-    def _from_emoji(cls, state, emoji, *, format=None, static_format='png'):
+    def _from_emoji(
+            cls,
+            state: HAS_HTTP_CONNECTION,
+            emoji: Union[Emoji, PartialEmoji],
+            *,
+            format=None,
+            static_format='png'
+    ):
         if format is not None and format not in VALID_AVATAR_FORMATS:
             raise InvalidArgument("format must be None or one of {}".format(VALID_AVATAR_FORMATS))
         if format == "gif" and not emoji.animated:
@@ -163,9 +372,26 @@ def _from_emoji(cls, state, emoji, *, format=None, static_format='png'):
             raise InvalidArgument("static_format must be one of {}".format(VALID_STATIC_FORMATS))
         if format is None:
             format = 'gif' if emoji.animated else static_format
-
         return cls(state, '/emojis/{0.id}.{1}'.format(emoji, format))
 
+    @classmethod
+    def _from_guild_event(
+            cls,
+            state: HAS_HTTP_CONNECTION,
+            event: GuildScheduledEvent,
+            *,
+            format=None,
+            static_format='png',
+            size=1024
+    ):
+        if not utils.valid_icon_size(size):
+            raise InvalidArgument("size must be a power of 2 between 16 and 4096")
+        if format is not None and format not in VALID_AVATAR_FORMATS:
+            raise InvalidArgument("format must be None or one of {}".format(VALID_AVATAR_FORMATS))
+        if static_format not in VALID_STATIC_FORMATS:
+            raise InvalidArgument("static_format must be one of {}".format(VALID_STATIC_FORMATS))
+        return cls(state, '/guild-events/{0.id}/{0.image}.{1}?size={2}'.format(event, format, size))
+
     def __str__(self):
         return self.BASE + self._url if self._url is not None else ''
 
@@ -189,7 +415,7 @@ def __ne__(self, other):
     def __hash__(self):
         return hash(self._url)
 
-    async def read(self):
+    async def read(self) -> bytes:
         """|coro|
 
         Retrieves the content of this asset as a :class:`bytes` object.
@@ -224,7 +450,7 @@ async def read(self):
 
         return await self._state.http.get_from_cdn(self.BASE + self._url)
 
-    async def save(self, fp, *, seek_begin=True):
+    async def save(self, fp: Union[BinaryIO, PathLike], *, seek_begin: bool = True) -> int:
         """|coro|
 
         Saves this asset into a file-like object.
diff --git a/discord/audit_logs.py b/discord/audit_logs.py
index 00706f89..e458fc21 100644
--- a/discord/audit_logs.py
+++ b/discord/audit_logs.py
@@ -3,7 +3,7 @@
 """
 The MIT License (MIT)
 
-Copyright (c) 2015-present Rapptz
+Copyright (c) 2015-2021 Rapptz & (c) 2021-present mccoderpy
 
 Permission is hereby granted, free of charge, to any person obtaining a
 copy of this software and associated documentation files (the "Software"),
@@ -82,7 +82,6 @@ def _transform_overwrites(entry, data):
             target = Object(id=ow_id)
 
         overwrites.append((target, ow))
-    print(overwrites)
     return overwrites
 
 class AuditLogDiff:
@@ -97,6 +96,8 @@ def __repr__(self):
         return '<AuditLogDiff %s>' % values
 
 class AuditLogChanges:
+    # TODO: Add ad transformers for all the other keys
+    #  See: https://discord.com/developers/docs/resources/audit-log#audit-log-change-object-audit-log-change-key
     TRANSFORMERS = {
         'verification_level':            (None, _transform_verification_level),
         'explicit_content_filter':       (None, _transform_explicit_content_filter),
@@ -187,6 +188,7 @@ def _handle_role(self, first, second, entry, elem):
 
         setattr(second, 'roles', data)
 
+
 class AuditLogEntry(Hashable):
     r"""Represents an Audit Log entry.
 
@@ -380,3 +382,37 @@ def _convert_target_emoji(self, target_id):
 
     def _convert_target_message(self, target_id):
         return self._get_member(target_id)
+
+    def _convert_target_stage(self, target_id):
+        stage = self.guild.get_channel(target_id)
+        if stage is None:
+            return Object(id=target_id)
+        return stage
+
+    def _convert_target_sticker(self, target_id):
+        sticker = self.guild.get_sticker(target_id)
+        if sticker is None:
+            return Object(id=target_id)
+        return sticker
+
+    def _convert_target_scheduled_event(self, target_id):
+        event = self.guild.get_event(target_id)
+        if event is None:
+            return Object(id=target_id)
+        return event
+
+    def _convert_target_thread(self, target_id):
+        thread = self.guild.get_channel(target_id)
+        if thread is None:
+            return Object(id=target_id)
+        return thread
+
+    def _convert_target_application_command(self, target_id):
+        cmd = self.guild.get_application_command(target_id)
+        if cmd is None:
+            cmd = self._state._get_client().get_application_command(target_id)
+            if not cmd:
+                return Object(id=target_id)
+        return cmd
+
+
diff --git a/discord/auto_updater.py b/discord/auto_updater.py
new file mode 100644
index 00000000..3c5a5bf7
--- /dev/null
+++ b/discord/auto_updater.py
@@ -0,0 +1,230 @@
+# -*- coding: utf-8 -*-
+
+"""
+The MIT License (MIT)
+
+Copyright (c) 2015-2021 Rapptz & (c) 2021-present mccoderpy
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+"""
+
+from __future__ import annotations
+
+from typing import (
+    TYPE_CHECKING,
+    Optional,
+    Union,
+    Dict,
+    Any
+
+)
+
+import re
+import sys
+import copy
+import json
+import aiohttp
+import logging
+import asyncio
+from collections import namedtuple
+
+if sys.version_info <= (3, 7):
+    import importlib_metadata
+else:
+    import importlib.metadata as importlib_metadata
+
+from . import utils, __version__
+from .errors import HTTPException
+
+
+if TYPE_CHECKING:
+    from .client import Client
+
+MISSING = utils.MISSING
+
+log = logging.getLogger(__name__)
+
+__all__ = (
+    'AutoUpdateChecker',
+)
+
+
+MinimalReleaseInfo = namedtuple('MinimalReleaseInfo', ('version', 'release', 'valid', 'use_instead'))
+GitReleaseInfo = namedtuple('GitReleaseInfo', ('branch', 'version', 'release', 'commit', 'valid', 'use_instead'))
+VERSION_REGEX = re.compile(r'\s*(\d+\.\d+(?:\.\d+)*(?:[-_.]?(?:alpha|beta|pre|preview|a|b|c|rc)(?:[-_.]?[0-9]+)?)?)(?:\+g([0-9a-f]{7,10}))?\s*')
+
+
+class AutoUpdateChecker:
+    """This internal class handels automatic request to the library api to check for updates."""
+    def __init__(self, client: Client) -> None:
+        self.loop: asyncio.AbstractEventLoop = asyncio.get_event_loop()
+        self.client = client
+        self.dispatch = client.dispatch
+        self.task: Optional[asyncio.Task] = None  # Will be set by the Client instance
+        self.__session: Optional[aiohttp.ClientSession] = None  # set this later in check_task
+        self._vcs_url: Optional[str] = None
+        self.current_release: Union[MinimalReleaseInfo, GitReleaseInfo, None] = None  # set this later in check_task
+        self.__last_check_result: Dict[str, Any] = {}
+        user_agent = 'DiscordBot (https://github.com/mccoderpy/discord.py-message-components {0}) Python/{1[0]}.{1[1]} aiohttp/{2}'
+        self.user_agent = user_agent.format(__version__, sys.version_info, aiohttp.__version__)
+        self.headers: Dict[str, str] = {
+            'User-Agent': self.user_agent,
+            'Accept': 'application/json'
+        }
+
+    @property
+    def last_check_result(self) -> Optional[Dict[str, Any]]:
+        return self.__last_check_result
+
+    @last_check_result.setter
+    def last_check_result(self, value) -> None:
+        raise NotImplementedError
+
+    def get_session(self) -> aiohttp.ClientSession:
+        if (not self.__session) or self.__session.closed:
+            self.__session = aiohttp.ClientSession('https://api.discord4py.dev')
+        return self.__session
+
+    async def request(
+            self,
+            method: str,
+            route: str,
+            data: Optional[Dict[str, Any]] = None
+    ) -> Any:
+        from .http import json_or_text  # circular imports
+
+        params = {}
+        headers = self.headers.copy()
+
+        if data is not None:
+            params['data'] = json.dumps(data)
+            headers['Content-Type'] = 'application/json'
+
+        params['headers'] = headers
+
+        for tries in range(5):
+            async with self.get_session() as session:
+                async with session.request(method, route, **params) as resp:
+                    data = await json_or_text(resp)
+                    if 400 > resp.status >= 200:
+                        return data
+                    elif resp.status >= 400:
+                        log.warning('%s %s status was not 200. Was %d', method, route, resp.status)
+                        error = HTTPException(resp, data)
+                        log.error(*error.args)
+                        await asyncio.sleep(5 + tries * 2)
+                        continue
+
+    async def get_current_release(self) -> Union[MinimalReleaseInfo, GitReleaseInfo]:
+        dist = importlib_metadata.distribution('discord.py-message-components')
+        version, release = VERSION_REGEX.match(dist.version).groups()
+        if release:
+            direct_url_file = dist.read_text('direct_url.json')
+            if direct_url_file:
+                direct_url = json.loads(direct_url_file)
+                self._vcs_url = vcs_url = direct_url['url']
+                url_is_valid = await self.validate_vcs_url(vcs_url)
+                vcs_info = direct_url['vcs_info']
+                branch = vcs_info.get('requested_revision', None)
+                commit_id = vcs_info.get('commit_id', None)
+                return GitReleaseInfo(branch, version, release, commit_id, url_is_valid, MISSING)
+            else:
+                info = await self.find_release(version, release)
+                if info is not None:
+                    return GitReleaseInfo(info['branch'], version, release, info['commit'], True, MISSING)
+                else:
+                    log.warning('Unknown release used. Version checks will not be performed')
+        else:
+            return MinimalReleaseInfo(version, release, True, MISSING)
+
+    async def validate_vcs_url(self, url: str) -> bool:
+        d = await self.request('POST', '/is-valid-vcs-url', data={'url': url})
+        return d['valid']
+
+    async def find_release(self, version: str, release: str) -> Optional[Dict[str, Any]]:
+        pass
+
+    async def check_task(self) -> None:
+        log.debug('Starting auto update checker task')
+        self.__session = aiohttp.ClientSession('https://api.discord4py.dev')
+        self.current_release = current_release = await self.get_current_release()
+        if current_release is not None:
+            self.headers['Discord4py-Version'] = current_release.version
+            self.headers['Discord4py-Release'] = current_release.release
+            self.headers['Discord4py-Branch'] = getattr(current_release, 'branch', 'unknown')
+        if current_release and current_release.valid:
+            if type(current_release) is GitReleaseInfo:
+                log.info(f'Running on version {current_release.version} ({current_release.release}) of branch {current_release.branch}')
+            else:
+                log.debug(f'Running on version {current_release.version}')
+            while self.loop.is_running():
+                await self.run_check()
+                await asyncio.sleep(300)
+        else:
+            await self.__session.close()
+            log.warning('Update checker task stopped')
+
+    async def run_check(self) -> None:
+        log.debug('Checking for updates')
+        data = await self.request('GET', f'/branch/{self.current_release.branch}/releases/latest')
+        if self.last_check_result == data:
+            return  # Why should we overwrite it here when it is equal?
+        self.__last_check_result = data
+
+        if not data['active']:
+            self.current_release.valid = False
+            self.current_release.use_instead = use_instead = data.get("use_instead", None)
+
+            log.warning(
+                f'You are using a branch of the library that has been deleted and will no longer receive updates!'
+                f'Consider updating to {use_instead + "branch instead" if use_instead else "an other branch"}.'
+            )
+            self.dispatch('used_branch_deleted', use_instead)
+            log.info('Stopped update checker task')
+            self.task.cancel()
+        else:
+            before = copy.copy(self.current_release)
+            version, release = data['v'], data['r']
+            if version != before.version or release != before.release:
+                self.dispatch('update_available', before, GitReleaseInfo(before.branch, version, release, MISSING, True, MISSING))
+                self.show_update_notice(
+                    f'{self.current_release.version} ({self.current_release.release})',
+                    f'{version} ({release})'
+                )
+
+    def show_update_notice(self, actual: str, latest: str) -> None:
+        stream_supports_color = utils.stream_supports_colour(sys.stdout)
+        if stream_supports_color:
+            fmt = f'[\x1b[94;1mNOTICE\x1b[0m] New version for discord4py available: \x1b[31m{actual}\x1b[0m -> \x1b[32m{latest}\x1b[0m\n' \
+                  f'[\x1b[94;1mNOTICE\x1b[0m] Update to the latest version using \x1b[92mpip install -U git+{self._vcs_url}@{self.current_release.branch}\x1b[0m'
+        else:
+            fmt = f'New version available: {actual} -> {latest}\n' \
+                  f'Update to the latest version using "pip install -U git+{self._vcs_url}@{self.current_release.branch}"'
+        print(fmt.format(actual=actual, latest=latest))
+
+    def start(self):
+        self.task = self.loop.create_task(self.check_task())
+    
+    async def close(self):
+        task = self.task
+        if not task.cancelled():
+            task.cancel()
+        if self.__session:
+            await self.__session.close()
+            await asyncio.sleep(0.025)  # wait for the connection to be released
diff --git a/discord/automod.py b/discord/automod.py
new file mode 100644
index 00000000..76c8cf13
--- /dev/null
+++ b/discord/automod.py
@@ -0,0 +1,820 @@
+# -*- coding: utf-8 -*-
+
+"""
+The MIT License (MIT)
+
+Copyright (c) 2021-present mccoderpy
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+"""
+
+from __future__ import annotations
+
+from typing import (
+    Any,
+    List,
+    Dict,
+    Union,
+    Optional,
+    TYPE_CHECKING,
+    Iterator
+)
+
+import datetime
+from re import Pattern, compile as _re_compile
+
+from . import utils
+from .role import Role
+from .object import Object
+from .abc import GuildChannel
+from .utils import SnowflakeList, MISSING
+from .errors import ClientException
+from .enums import AutoModEventType, AutoModKeywordPresetType, AutoModActionType, AutoModTriggerType, try_enum
+
+
+if TYPE_CHECKING:
+    from typing_extensions import Self
+    from .state import ConnectionState
+    from .guild import Guild
+    from .user import User
+    from .member import Member
+    from .types.snowflake import SnowflakeObject
+
+
+__all__ = (
+    'AutoModAction',
+    'AutoModTriggerMetadata',
+    'AutoModRule',
+    'AutoModActionPayload'
+)
+
+
+class AutoModAction:
+    """
+    Represents an action which will execute whenever a rule is triggered.
+
+    Attributes
+    -----------
+    type: :class:`AutoModActionType`
+        The type of action
+    channel_id: :class:`int`
+        The channel to which target user content should be logged.
+
+        .. note::
+            This field is only present if :attr:`~AutoModAction.type` is :attr:`~AutoModActionType.send_alert_message`
+        
+    timeout_duration: Union[:class:`int`, :class:`~datetime.timedelta`]
+        Duration in seconds (:class:`int`) or a timerange (:class:`~datetime.timedelta`)
+        for which the target user should be timeouted.
+
+        **The maximum value is** ``2419200`` **seconds (4 weeks)**
+
+        .. note::
+           This field is only present if :attr:`~AutoModAction.type` is :attr:`~AutoModActionType.timeout_user`
+    
+    custom_message: Optional[:class:`str`]
+        Additional explanation that will be shown to target users whenever their message is blocked.
+        **Max 150 characters**
+        
+        .. note::
+            This field might only be present if :attr:`~AutoModAction.type` is :attr:`~AutoModActionType.block_message`
+    """
+    def __init__(self, type: AutoModActionType, **metadata):
+        """
+        
+        Parameters
+        -----------
+        type: :class:`AutoModActionType`
+            The type of action
+        
+        channel_id: :class:`int`
+            The channel to which target user content should be logged.
+    
+            .. note::
+                This field is only required if :attr:`~AutoModAction.type` is
+                :attr:`~AutoModActionType.send_alert_message`
+            
+        timeout_duration: Union[:class:`int`, :class:`datetime.timedelta`]
+            Duration in seconds (:class:`int`) or a timerange (:class:`~datetime.timedelta`)
+            for which the user should be timeouted.
+    
+            **The maximum value is** ``2419200`` **seconds (4 weeks)**
+    
+            .. note::
+               This field is only required if :attr:`~AutoModAction.type` is :attr:`~AutoModActionType.timeout_user`
+        
+        custom_message: Optional[:class:`str`]
+            Additional explanation that will be shown to target users whenever their message is blocked.
+            **Max 150 characters**
+            
+            .. note::
+                This field is only allowed if :attr:`~AutoModAction.type` is :attr:`~AutoModActionType.block_message`
+        
+        Raises
+        -------
+        TypeError
+            If the type is :attr:`~AutoModActionType.send_alert_message` and no ``channel_id`` is provided,
+            or if the type is :attr:`~AutoModActionType.timeout_user` and no ``timeout_duration`` is provided.
+        ValueError
+            If the ``custom_message`` is longer than 150 characters,
+            or if the ``timeout_duration`` is longer than 4 weeks.
+        """
+        self.type: AutoModActionType = try_enum(AutoModActionType, type)
+        self.metadata = metadata  # maybe we need this later... idk
+        
+        action_type = self.type  # speedup attribute access
+        
+        if action_type == AutoModActionType.block_message:
+            try:
+                custom_message: Optional[str] = metadata['custom_message']
+            except KeyError:
+                pass
+            else:
+                if custom_message and len(custom_message) > 150:
+                    raise ValueError('The maximum length of the custom message is 150 characters.')
+                self.custom_message: Optional[str] = custom_message
+            
+        elif action_type == AutoModActionType.send_alert_message:
+            try:
+                self.channel_id: Optional[int] = metadata['channel_id']
+            except KeyError:
+                raise TypeError('If the type is send_alert_message you must specify a channel_id')
+        
+        elif action_type == AutoModActionType.timeout_user:
+            try:
+                timeout_duration: Optional[Union[int, datetime.timedelta]] = metadata['timeout_duration']
+            except KeyError:
+                raise TypeError('If the type is timeout_user you must specify a timeout_duration')
+            else:
+                if isinstance(timeout_duration, int):
+                    timeout_duration = datetime.timedelta(seconds=timeout_duration)
+                if timeout_duration.total_seconds() > 2419200:
+                    raise ValueError('The maximum timeout duration is 2419200 seconds (4 weeks).')
+                self.timeout_duration: Optional[datetime.timedelta] = timeout_duration
+
+    def to_dict(self) -> Dict[str, Any]:
+        base = {
+            'type': int(self.type)
+        }
+        metadata = {}
+        if self.type == AutoModActionType.block_message:
+            custom_message = getattr(self, 'custom_message', None)
+            if custom_message:
+                metadata['custom_message'] = self.custom_message
+        elif self.type == AutoModActionType.send_alert_message:
+            metadata['channel_id'] = self.channel_id
+        elif self.type == AutoModActionType.timeout_user:
+            metadata['duration_seconds'] = self.timeout_duration
+        base['metadata'] = metadata
+        return base
+
+    @classmethod
+    def from_dict(cls, data: Dict[str, Any]) -> Self:
+        action_type = try_enum(AutoModActionType, data['type'])
+        metadata = data['metadata']
+        if action_type == AutoModActionType.block_message:
+            metadata['custom_message'] = metadata.pop('custom_message', None)
+        elif action_type == AutoModActionType.timeout_user:
+            metadata['timeout_duration'] = metadata.pop('duration_seconds')
+        elif action_type == AutoModActionType.send_alert_message:
+            metadata['channel_id'] = int(metadata['channel_id'])
+        return cls(action_type, **metadata)
+
+
+class AutoModTriggerMetadata:
+    """Additional data used to determine whether a rule should be triggered.
+    Different fields are relevant based on the value of :attr:`AutoModRule.trigger_type`
+
+    Parameters
+    -----------
+    keyword_filter: Optional[List[:class:`str`]]
+        Substrings which will be searched for in content
+
+        .. note::
+            This field is only present if :attr:`~AutoModRule.trigger_type` is :attr:`AutoModTriggerType.keyword`
+
+    presets: Optional[List[:class:`AutoModKeywordPresetType`]]
+        The internally pre-defined word sets which will be searched for in content
+
+        .. note::
+            This field is only present if :attr:`~AutoModRule.trigger_type` is :attr:`AutoModTriggerType.keyword_preset`
+
+    exempt_words: Optional[List[:class:`str`]]
+        Substrings which should be excluded from the blacklist.
+
+        .. note::
+            This field is only present if :attr:`~AutoModRule.trigger_type` is :attr:`AutoModTriggerType.keyword_preset`
+
+    total_mentions_limit: Optional[:class:`int`]
+        Total number of unique role and user mentions allowed per message (Maximum of 50)
+
+        .. note::
+            This field is only present if :attr:`~AutoModRule.trigger_type` is :attr:`AutoModTriggerType.mention_spam`
+
+    mention_raid_protection_enabled: Optional[:class:`bool`]
+        Whether to automatically detect mention raids
+
+        .. note::
+            This field is only present if :attr:`~AutoModRule.trigger_type` is :attr:`AutoModTriggerType.mention_spam`
+    """
+    def __init__(
+            self,
+            keyword_filter: Optional[List[str]] = None,
+            regex_patterns: Optional[List[Union[str, Pattern]]] = None,
+            presets: Optional[List[AutoModKeywordPresetType]] = None,
+            exempt_words: Optional[List[str]] = None,
+            total_mentions_limit: Optional[int] = None,
+            mention_raid_protection_enabled: Optional[bool] = None
+    ) -> None:
+        """Additional data used to determine whether a rule should be triggered.
+        Different fields are relevant based on the value of :attr:`AutoModRule.trigger_type`
+
+        Parameters
+        -----------
+        keyword_filter: Optional[List[:class:`str`]]
+            Substrings which will be searched for in content
+
+            .. note::
+                This field is only allowed if :attr:`~AutoModRule.trigger_type` is :attr:`~AutoModTriggerType.keyword`
+
+        regex_patterns: Optional[List[Union[:class:`str`, :class`~re.Pattern`]]]
+            Regular expression patterns which will be matched against content
+            (Maximum of 10, each max. 260 characters long)
+
+            .. warning::
+                Only <Rust `https://docs.rs/regex/latest/regex/`>_ flowered RegEx patterns are currently supported
+                by Discord. So things like lookarounds are not allowed as they are not supported in Rust.
+
+            .. note::
+                This field is only allowed if :attr:`~AutoModRule.trigger_type` is :attr:`~AutoModTriggerType.keyword`
+
+        presets: Optional[List[:class:`AutoModKeywordPresetType`]]
+            The internally pre-defined word sets which will be searched for in content
+
+            .. note::
+                This field is only required if :attr:`~AutoModRule.trigger_type` is
+                :attr:`~AutoModTriggerType.keyword_preset`
+
+        exempt_words: Optional[List[:class:`str`]]
+            Substrings which should be excluded from the blacklist.
+
+            .. note::
+                This field is only allowed if :attr:`~AutoModRule.trigger_type` is
+                :attr:`~AutoModTriggerType.keyword_preset` :attr:`~AutoModTriggerType.keyword`
+
+        total_mentions_limit: Optional[:class:`int`]
+            Total number of unique role and user mentions allowed per message (Maximum of 50)
+
+            .. note::
+                This field is only allowed if :attr:`~AutoModRule.trigger_type`
+                is :attr:`AutoModTriggerType.mention_spam`
+
+        mention_raid_protection_enabled: Optional[:class:`bool`]
+            Whether to automatically detect mention raids
+
+            .. note::
+                This field is only allowed if :attr:`~AutoModRule.trigger_type`
+                is :attr:`AutoModTriggerType.mention_spam`
+
+        Raises
+        -------
+        :exc:`TypeError`
+            Both of keyword_filter and presets was passed
+        """
+        if keyword_filter and presets:
+            raise TypeError('Only one of keyword_filter or presets are accepted.')
+        self.keyword_filter: Optional[List[str]] = keyword_filter or []
+        if regex_patterns and presets:
+            raise TypeError('regex_patterns can only be used with AutoModRule\'s of type keyword')
+        self._regex_patterns: List[Union[str, Pattern]] = regex_patterns or []
+        self.presets: List[AutoModKeywordPresetType] = presets or []
+        if exempt_words and not (presets or keyword_filter):
+            raise TypeError('exempt_words can only be used with keyword_filter or preset')
+        self.exempt_words: Optional[List[str]] = exempt_words
+        self.total_mentions_limit: Optional[int] = total_mentions_limit
+        self.mention_raid_protection_enabled: Optional[bool] = mention_raid_protection_enabled
+
+    @utils.cached_slot_property('_cs_regex_patterns')
+    def regex_patterns(self) -> List[Pattern]:
+        """List[:class:`~re.Pattern`]: The compiled regex patterns for this rule, if any."""
+        return [
+            _re_compile(pattern) for pattern in getattr(self, '_regex_patterns', []) if not isinstance(pattern, Pattern)
+        ]
+
+    @property
+    def prefix_keywords(self) -> Iterator[str]:
+        """
+        Returns all keywords for words that must start with the keyword.
+
+        .. note::
+            This is equal to
+
+            .. code-block:: python3
+
+                for keyword in self.keyword_filter:
+                    if keyword[0] != '*' and keyword[-1] == '*':
+                        yield keyword
+                        
+        Yields
+        -------
+        :class:`str`
+            A keyword
+        """
+        for keyword in self.keyword_filter:
+            if keyword[0] != '*' and keyword[-1] == '*':
+                yield keyword
+
+    @property
+    def suffix_keywords(self) -> Iterator[str]:
+        """
+        Returns all keywords for words that must end with the keyword.
+
+        .. note::
+            This is equal to
+
+            .. code-block:: python3
+
+                for keyword in self.keyword_filter:
+                    if keyword[0] == '*' and keyword[-1] != '*':
+                        yield keyword
+
+        Yields
+        -------
+        :class:`str`
+            A keyword
+        """
+        for keyword in self.keyword_filter:
+            if keyword[0] != '*' and keyword[-1] == '*':
+                yield keyword
+
+    @property
+    def anywhere_keywords(self) -> Iterator[str]:
+        """
+        Returns all keywords which can appear anywhere in a word
+
+        .. note::
+            This is equal to
+
+            .. code-block:: python3
+
+                for keyword in self.keyword_filter:
+                    if keyword[0] == '*' and keyword[-1] == '*':
+                        yield keyword
+
+        Yields
+        -------
+        :class:`str`
+            A keyword
+        """
+        for keyword in self.keyword_filter:
+            if keyword[0] == '*' and keyword[-1] == '*':
+                yield keyword
+
+    @property
+    def whole_word_keywords(self) -> Iterator[str]:
+        """
+        Returns all keywords that must occur as a whole in a word or phrase and must be surrounded by spaces.
+
+        .. note::
+            This is equal to
+
+            .. code-block:: python3
+
+                for keyword in self.keyword_filter:
+                    if keyword[0] != '*' and keyword[-1] != '*':
+                        yield keyword
+
+        Yields
+        -------
+        :class:`str`
+            A keyword
+        """
+        for keyword in self.keyword_filter:
+            if keyword[0] != '*' and keyword[-1] != '*':
+                yield keyword
+
+    def to_dict(self) -> Dict[str, Any]:
+        if self.keyword_filter or self._regex_patterns:
+            base = {
+                'keyword_filter': self.keyword_filter,
+                'regex_patterns': [
+                    pattern.pattern if isinstance(pattern, Pattern) else pattern for pattern in self._regex_patterns
+                ]
+            }
+            if self.exempt_words is not None:
+                base['allow_list'] = self.exempt_words
+            return base
+        else:
+            if self.presets:
+                base = {
+                    'presets': [int(p) for p in self.presets]
+                }
+                if self.exempt_words is not None:
+                    base['allow_list'] = self.exempt_words
+                return base
+            elif self.total_mentions_limit:
+                return {
+                    'mention_total_limit': self.total_mentions_limit,
+                    'mention_raid_protection_enabled': self.mention_raid_protection_enabled
+                }
+
+    @classmethod
+    def from_dict(cls, data: Dict[str, Any]) -> Self:
+        self = cls.__new__(cls)
+        self.presets = presets = data.get('presets')
+        if presets:
+            self.exempt_words = data.get('allow_list', [])
+        else:
+            self.keyword_filter = data.get('keyword_filter')
+            self._regex_patterns = data.get('regex_patterns')
+            self.exempt_words = data.get('allow_list')
+        self.total_mentions_limit = data.get('mention_total_limit')
+        self.mention_raid_protection_enabled = data.get('mention_raid_protection_enabled')
+        return self
+
+
+class AutoModRule:
+    """
+    Represents a rule for auto moderation
+
+    .. warning::
+        Do not initialize this class directly. Use :meth:`~discord.Guild.create_automod_rule` instead.
+
+    Attributes
+    -----------
+    id: :class:`int`
+        The id of this rule
+    guild: :class:`~discord.Guild`
+        The guild  this rule belongs to
+    name: :class:`str`
+        The name of the rule
+    creator_id: :class:`int`
+        The id of the user which created this rule
+    event_type: :class:`AutoModEventType`
+        The event which will trigger this rule
+    trigger_type: :class:`AutoModEventType`
+        The type of content which will trigger the rule
+    trigger_metadata: :class:`AutoModTriggerMetadata`
+        Additional data used to determine whether a rule should be triggered.
+        Different fields are relevant based on the value of :attr:`.trigger_type`.
+    actions: List[:class:`AutoModAction`]
+        The actions which will execute when the rule is triggered
+    enabled: :class:`bool`
+        Whether the rule is enabled
+    """
+    def __init__(
+            self,
+            state: ConnectionState,
+            guild: Guild,
+            **data
+    ) -> None:
+        self._state: ConnectionState = state
+        self.guild: Guild = guild
+        self.id: int = int(data['id'])
+        self._update(data)
+
+    def _update(self: Self, data) -> Self:
+        self.name: str = data['name']
+        self.creator_id: int = int(data['creator_id'])
+        self.event_type: AutoModEventType = try_enum(AutoModEventType, data['event_type'])
+        self.trigger_type: AutoModTriggerType = try_enum(AutoModTriggerType, data['trigger_type'])
+        self.trigger_metadata: AutoModTriggerMetadata = AutoModTriggerMetadata.from_dict(data['trigger_metadata'])
+        self.actions: List[AutoModAction] = [AutoModAction.from_dict(action) for action in data['actions']]
+        self.enabled: bool = data['enabled']
+        self._exempt_roles: SnowflakeList = SnowflakeList(map(int, data['exempt_roles']))
+        self._exempt_channels: SnowflakeList = SnowflakeList(map(int, data['exempt_channels']))
+        return self
+
+    def __repr__(self) -> str:
+        return f'<AutoModRule "{self.name}" guild_id={self.guild.id} creator_id={self.creator_id}>'
+
+    @property
+    def exempt_roles(self) -> Iterator[Union[Role, Object]]:
+        """
+        Yields the roles that should not be affected by the rule (Maximum of 20)
+
+        .. note::
+            This is equal to
+
+            .. code-block:: python3
+
+                for role_id in self._exempt_roles:
+                    role = self.guild.get_role(int(role_id))
+                    yield role or Object(int(role_id))
+
+        Yields
+        -------
+        Union[:class:`~discord.Role`, :class:`~discord.Object`]
+            An excluded role or an object with the id if the role is not found
+        """
+        for role_id in self._exempt_roles:
+            role = self.guild.get_role(int(role_id))
+            yield role or Object(role_id, type=Role, state=self._state)
+
+    @property
+    def exempt_channels(self) -> Iterator[Union[GuildChannel, Object]]:
+        """
+        Yields the channels that should not be affected by the rule (Maximum of 20)
+
+        .. note::
+            This is equal to
+
+            .. code-block:: python3
+
+                for channel_id in self._exempt_channels:
+                    channel = self.guild.get_role(int(channel_id))
+                    yield channel or Object(channel_id, type=GuildChannel, state=self._state)
+
+        Yields
+        -------
+        Union[:class:`~discord.Role`, :class:`~discord.Object`]
+            An excluded channel or an :class:`~discord.object` with the id if the channel is not found
+        """
+        for channel_id in self._exempt_channels:
+            channel = self.guild.get_role(int(channel_id))
+            yield channel or Object(channel_id, type=GuildChannel, state=self._state)
+        
+    @property
+    def creator(self) -> Optional[Member]:
+        """
+        Returns the creator of the rule
+
+        .. note::
+            The :attr:`Intents.members` must be enabled, otherwise this may return `` None``
+        
+        Raises
+        -------
+        ClientException:
+            If the member is not found and :attr:`~Intents.members` intent is not enabled.
+        
+        Returns
+        --------
+        Optional[Member]
+            The member, that created the rule.
+        """
+        creator = self.guild.get_member(self.creator_id)
+        # If the member is not found and the members intent is disabled, then raise
+        if not creator and not self._state.intents.members:
+            raise ClientException('Intents.members must be enabled to use this')
+        return creator
+
+    @property
+    def created_at(self) -> datetime.datetime:
+        """:class:`datetime.datetime`: When the rule was created in UTC"""
+        return utils.snowflake_time(self.id)
+
+    async def delete(self, *, reason: Optional[str]) -> None:
+        """|coro|
+
+        Deletes the automod rule, this requires the :attr:`~Permissions.manage_server` permission.
+
+        Parameters
+        -----------
+        reason: Optional[:class:`str`]
+            The reason for deleting this rule. Shows up in the audit log.
+
+        Raises
+        ------
+        :exc:`discord.Forbidden`
+            The bot is missing permissions to delete the rule
+        :exc:`~discord.HTTPException`
+            Deleting the rule failed
+        """
+        await self._state.http.delete_automod_rule(self.guild.id, self.id, reason=reason)
+
+    async def edit(
+            self,
+            *,
+            name: str = MISSING,
+            event_type: AutoModEventType = MISSING,
+            trigger_type: AutoModTriggerType = MISSING,
+            trigger_metadata: AutoModTriggerMetadata = MISSING,
+            actions: List[AutoModAction] = MISSING,
+            enabled: bool = MISSING,
+            exempt_roles: List[SnowflakeObject] = MISSING,
+            exempt_channels: List[SnowflakeObject] = MISSING,
+            reason: Optional[str] = None,
+    ) -> AutoModRule:
+        """|coro|
+
+        Edits the automod rule, this requires the :attr:`~Permissions.manage_server` permission.
+        
+        You only need to provide the parameters you want to edit the.
+        
+        Parameters
+        ----------
+        name: :class:`str`
+            The name, the rule should have. Only valid if it's not a preset rule.
+        event_type: :class:`~discord.AutoModEventType`
+            Indicates in what event context a rule should be checked.
+        trigger_type: :class:`~discord.AutoModTriggerType`
+            Characterizes the type of content which can trigger the rule
+        trigger_metadata: :class:`~discord.AutoModTriggerMetadata`
+            Additional data used to determine whether a rule should be triggered.
+            Different fields are relevant based on the value of :attr:`~AutoModRule.trigger_type`.
+        actions: List[:class:`~discord.AutoModAction`]
+            The actions which will execute when the rule is triggered.
+        enabled: :class:`bool`
+            Whether the rule is enabled.
+        exempt_roles: List[:class:`.Snowflake`]
+            Up to 20 :class:`~discord.Role`'s, that should not be affected by the rule.
+        exempt_channels: List[:class:`.Snowflake`]
+            Up to 50 :class:`~discord.TextChannel`/:class:`~discord.VoiceChannel`/:class:`~discord.StageChannel`'s,
+            that should not be affected by the rule.
+        reason: Optional[:class:`str`]
+            The reason for editing the rule. Shows up in the audit log.
+
+        Raises
+        -------
+        :exc:`discord.Forbidden`
+            The bot is missing permissions to edit the rule
+        :exc:`~discord.HTTPException`
+            Editing the rule failed
+
+        Returns
+        -------
+        :class:`AutoModRule`
+            The updated rule on success.
+        """
+        payload = {}
+
+        if name is not MISSING:
+            payload['name'] = name
+
+        if event_type is not MISSING:
+            payload['event_type'] = event_type.value
+
+        if trigger_type is not MISSING:
+            payload['trigger_type'] = trigger_type.value
+        
+        if trigger_metadata is not MISSING:
+            payload['trigger_metadata'] = trigger_metadata.to_dict()
+
+        if actions is not MISSING:
+            payload['actions'] = [action.to_dict() for action in actions]
+        else:
+            actions = self.actions if exempt_channels is not MISSING else MISSING
+            
+        if enabled is not MISSING:
+            payload['enabled'] = enabled
+        
+        if exempt_roles is not MISSING:
+            payload['exempt_roles'] = [str(r.id) for r in exempt_roles]
+        
+        if exempt_channels is not MISSING:
+            payload['exempt_channels'] = _exempt_channels = [str(c.id) for c in exempt_channels]
+        else:
+            _exempt_channels = self._exempt_channels
+            
+        if actions is not MISSING:
+            for action in actions:  # Add the channels where messages should be logged to, to the exempted channels
+                if action.type.send_alert_message:
+                    channel_id = str(action.channel_id)
+                    if channel_id not in _exempt_channels:
+                        _exempt_channels.append(channel_id)
+        
+        data = await self._state.http.edit_automod_rule(self.guild.id, self.id, fields=payload, reason=reason)
+        return self._update(data)
+
+
+class AutoModActionPayload:
+    """Represents the payload for an :func:`on_automod_action` event
+
+    Attributes
+    -----------
+    guild_id: :class:`int`
+        The id of the guild in which action was executed
+    action: :class:`AutoModAction`
+        The action which was executed
+    rule_id: :class:`int`
+        The id of the rule which action belongs to
+    rule_trigger_type: :class:`~discord.AutoModTriggerType`
+        The trigger type of rule which was triggered
+    user_id: :class:`int`
+        The id of the user which generated the content which triggered the rule
+    channel_id: Optional[:class:`int`]
+        The id of the channel in which user content was posted
+    message_id: Optional[:class:`int`]
+        The id of any user message which content belongs to
+
+        .. note::
+            This wil not exists if message was blocked by automod or content was not part of any message
+
+    alert_system_message_id: Optional[:class:`int`]
+        The id of any system auto moderation messages posted as the result of this action
+
+        .. note::
+            This will only exist if the :attr:`~AutoModAction.type` of the :attr:`~AutoModActionPayload.action` is ``send_alert_message``
+
+    content: :class:`str`
+        The user generated text content
+
+        .. important::
+            The :attr:`Intents.message_content` intent is required to get a non-empty value for this field
+
+    matched_keyword: :class:`str`
+        The word ot phrase configured in the rule that triggered the rule
+    matched_content: :class:`str`
+        The substring in :attr:`~AutoModActionPayload.content` that triggered the rule
+
+         .. important::
+            The :attr:`~Intents.message_content` intent is required to get a non-empty value for this field
+
+    """
+    __slots__ = (
+        '_state', 'guild_id', 'action', 'rule_id', 'rule_trigger_type', 'user_id', 'channel_id', 'message_id',
+        'alert_system_message_id', 'content', 'matched_keyword', 'matched_content'
+    )
+
+    def __init__(self, state: ConnectionState, data: Dict[str, Any]) -> None:
+        self._state = state
+        self.guild_id: int = int(data['guild_id'])
+        self.action: AutoModAction = AutoModAction.from_dict(data['action'])
+        self.rule_id: int = int(data['rule_id'])
+        self.rule_trigger_type: AutoModTriggerType = try_enum(AutoModTriggerType, data['rule_trigger_type'])
+        self.user_id: int = int(data['user_id'])
+        self.channel_id: Optional[int] = int(data.get('channel_id', 0))
+        self.message_id: Optional[int] = int(data.get('message_id', 0))
+        self.alert_system_message_id: Optional[int] = int(data.get('alert_system_message_id', 0))
+        self.content: str = data['content']
+        self.matched_keyword: Optional[str] = data.get('matched_keyword', None)
+        self.matched_content: Optional[str] = data.get('matched_content', None)
+
+    @property
+    def guild(self) -> Guild:
+        """
+        The guild in which action was executed
+
+        Returns
+        --------
+        :class:`Guild`
+            The guild object
+        """
+        return self._state._get_guild(self.guild_id)
+
+    @property
+    def channel(self) -> Optional[GuildChannel]:
+        """
+        The channel in which user content was posted, if any.
+
+        Returns
+        --------
+        Optional[:class:`abc.GuildChannel`]
+            The :class:`TextChannel`, :class:`VoiceChannel` or :class:`ThreadChannel` the user content was posted in.
+        """
+        return self.guild.get_channel(self.channel_id)
+
+    @property
+    def user(self) -> Optional[User]:
+        """
+        The user which content triggered the rule
+
+        .. note::
+            This can return ``None`` if the user is not in the cache
+
+        Returns
+        --------
+        :class:`.User`
+            The user that triggered the rule
+        """
+        return self._state.get_user(self.user_id)
+
+    @property
+    def member(self) -> Optional[Member]:
+        """
+        The corresponding :class:`Member` of the :attr:`~AutoModActionPayload.user` in the :attr:`~AutoModActionPayload.guild`.
+
+        .. note::
+            :attr:`Intents.members` must be enabled in order to use this
+
+        Raises
+        -------
+        ClientException:
+            If the member is not found and :attr:`~Intents.members` intent is not enabled.
+
+        Returns
+        --------
+        Optional[Member]:
+            The guild member
+        """
+        member = self.guild.get_member(self.user_id)
+        # If the member is not found and the members intent is disabled, then raise
+        if not member and not self._state.intents.members:
+            raise ClientException('Intents.members must be enabled to use this')
+        return member
diff --git a/discord/backoff.py b/discord/backoff.py
index 0f49d155..fdb9f539 100644
--- a/discord/backoff.py
+++ b/discord/backoff.py
@@ -27,6 +27,7 @@
 import time
 import random
 
+
 class ExponentialBackoff:
     """An implementation of the exponential backoff algorithm
 
diff --git a/discord/calls.py b/discord/calls.py
deleted file mode 100644
index 2006b30a..00000000
--- a/discord/calls.py
+++ /dev/null
@@ -1,176 +0,0 @@
-# -*- coding: utf-8 -*-
-
-"""
-The MIT License (MIT)
-
-Copyright (c) 2015-present Rapptz
-
-Permission is hereby granted, free of charge, to any person obtaining a
-copy of this software and associated documentation files (the "Software"),
-to deal in the Software without restriction, including without limitation
-the rights to use, copy, modify, merge, publish, distribute, sublicense,
-and/or sell copies of the Software, and to permit persons to whom the
-Software is furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
-DEALINGS IN THE SOFTWARE.
-"""
-
-import datetime
-
-from . import utils
-from .enums import VoiceRegion, try_enum
-from .member import VoiceState
-
-class CallMessage:
-    """Represents a group call message from Discord.
-
-    This is only received in cases where the message type is equivalent to
-    :attr:`MessageType.call`.
-
-    .. deprecated:: 1.7
-
-    Attributes
-    -----------
-    ended_timestamp: Optional[:class:`datetime.datetime`]
-        A naive UTC datetime object that represents the time that the call has ended.
-    participants: List[:class:`User`]
-        The list of users that are participating in this call.
-    message: :class:`Message`
-        The message associated with this call message.
-    """
-
-    def __init__(self, message, **kwargs):
-        self.message = message
-        self.ended_timestamp = utils.parse_time(kwargs.get('ended_timestamp'))
-        self.participants = kwargs.get('participants')
-
-    @property
-    def call_ended(self):
-        """:class:`bool`: Indicates if the call has ended.
-
-        .. deprecated:: 1.7
-        """
-        return self.ended_timestamp is not None
-
-    @property
-    def channel(self):
-        r""":class:`GroupChannel`\: The private channel associated with this message.
-
-        .. deprecated:: 1.7
-        """
-        return self.message.channel
-
-    @property
-    def duration(self):
-        """Queries the duration of the call.
-
-        If the call has not ended then the current duration will
-        be returned.
-
-        .. deprecated:: 1.7
-
-        Returns
-        ---------
-        :class:`datetime.timedelta`
-            The timedelta object representing the duration.
-        """
-        if self.ended_timestamp is None:
-            return datetime.datetime.utcnow() - self.message.created_at
-        else:
-            return self.ended_timestamp - self.message.created_at
-
-class GroupCall:
-    """Represents the actual group call from Discord.
-
-    This is accompanied with a :class:`CallMessage` denoting the information.
-
-    .. deprecated:: 1.7
-
-    Attributes
-    -----------
-    call: :class:`CallMessage`
-        The call message associated with this group call.
-    unavailable: :class:`bool`
-        Denotes if this group call is unavailable.
-    ringing: List[:class:`User`]
-        A list of users that are currently being rung to join the call.
-    region: :class:`VoiceRegion`
-        The guild region the group call is being hosted on.
-    """
-
-    def __init__(self, **kwargs):
-        self.call = kwargs.get('call')
-        self.unavailable = kwargs.get('unavailable')
-        self._voice_states = {}
-
-        for state in kwargs.get('voice_states', []):
-            self._update_voice_state(state)
-
-        self._update(**kwargs)
-
-    def _update(self, **kwargs):
-        self.region = try_enum(VoiceRegion, kwargs.get('region'))
-        lookup = {u.id: u for u in self.call.channel.recipients}
-        me = self.call.channel.me
-        lookup[me.id] = me
-        self.ringing = list(filter(None, map(lookup.get, kwargs.get('ringing', []))))
-
-    def _update_voice_state(self, data):
-        user_id = int(data['user_id'])
-        # left the voice channel?
-        if data['channel_id'] is None:
-            self._voice_states.pop(user_id, None)
-        else:
-            self._voice_states[user_id] = VoiceState(data=data, channel=self.channel)
-
-    @property
-    def connected(self):
-        """List[:class:`User`]: A property that returns all users that are currently in this call.
-        
-        .. deprecated:: 1.7
-        """
-        ret = [u for u in self.channel.recipients if self.voice_state_for(u) is not None]
-        me = self.channel.me
-        if self.voice_state_for(me) is not None:
-            ret.append(me)
-
-        return ret
-
-    @property
-    def channel(self):
-        r""":class:`GroupChannel`\: Returns the channel the group call is in.
-
-        .. deprecated:: 1.7
-        """
-        return self.call.channel
-
-    @utils.deprecated()
-    def voice_state_for(self, user):
-        """Retrieves the :class:`VoiceState` for a specified :class:`User`.
-
-        If the :class:`User` has no voice state then this function returns
-        ``None``.
-
-        .. deprecated:: 1.7
-
-        Parameters
-        ------------
-        user: :class:`User`
-            The user to retrieve the voice state for.
-
-        Returns
-        --------
-        Optional[:class:`VoiceState`]
-            The voice state associated with this user.
-        """
-
-        return self._voice_states.get(user.id)
diff --git a/discord/channel.py b/discord/channel.py
index 067470bb..128e6dbc 100644
--- a/discord/channel.py
+++ b/discord/channel.py
@@ -3,7 +3,7 @@
 """
 The MIT License (MIT)
 
-Copyright (c) 2015-present Rapptz
+Copyright (c) 2015-2021 Rapptz & (c) 2021-present mccoderpy
 
 Permission is hereby granted, free of charge, to any person obtaining a
 copy of this software and associated documentation files (the "Software"),
@@ -23,54 +23,99 @@
 FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 DEALINGS IN THE SOFTWARE.
 """
+from __future__ import annotations
 
-import time
 import asyncio
+import datetime
+import time
 from typing import (
     Any,
     Callable,
+    Coroutine,
     Dict,
-    Iterable,
     List,
-    Mapping,
+    overload,
     Optional,
-    TYPE_CHECKING,
+    Sequence,
+    Iterable,
     Tuple,
-    Type,
-    TypeVar,
-    Union,
-    overload,
+    TYPE_CHECKING,
+    Union
 )
-import discord.abc
-from .permissions import Permissions
-from .enums import ChannelType, try_enum, VoiceRegion
-from .mixins import Hashable
-from . import utils
-from .object import Object
+from typing_extensions import Literal, Self
+
+from . import abc, utils
 from .asset import Asset
-from .errors import ClientException, NoMoreItems, InvalidArgument
+from .components import ActionRow, BaseSelect, Button
+from .enums import (
+    AutoArchiveDuration,
+    ChannelType,
+    PostSortOrder,
+    ForumLayout,
+    VoiceRegion,
+    VideoQualityMode,
+    PrivacyLevel,
+    try_enum
+)
+from .errors import ClientException, InvalidArgument, NoMoreItems, ThreadIsArchived
+from .flags import ChannelFlags, MessageFlags
+from .http import handle_message_parameters
+from .iterators import ThreadMemberIterator, ArchivedThreadIterator
+from .mixins import Hashable
+from .partial_emoji import PartialEmoji
+from .permissions import PermissionOverwrite, Permissions
 
 if TYPE_CHECKING:
+    from .types.channel import (
+        DMChannel as DMChannelData,
+        GroupChannel as GroupChannelData,
+        VoiceChannel as VoiceChannelData,
+        StageInstance as StageInstanceData,
+        StageChannel as StageChannelData,
+        ForumChannel as ForumChannelData,
+        ForumTag as ForumTagData,
+        DefaultReactionEmoji
+    )
     from .state import ConnectionState
+    from .mentions import AllowedMentions
+    from .file import File
+    from .embeds import Embed
+    from .member import Member, VoiceState
+    from .user import User, ClientUser
     from .message import Message, PartialMessage
+    from .guild import Guild
+    from .role import Role
+    from .webhook import Webhook
+    from .scheduled_event import GuildScheduledEvent
 
+MISSING = utils.MISSING
+MSNG = utils._MISSING
 
 __all__ = (
     'TextChannel',
+    'ThreadMember',
+    'ThreadChannel',
     'VoiceChannel',
     'StageChannel',
+    'StageInstance',
     'DMChannel',
     'CategoryChannel',
-    'StoreChannel',
     'GroupChannel',
+    'ForumPost',
+    'ForumChannel',
+    'ForumTag',
+    'PartialMessageable',
     '_channel_factory',
+    '_thread_factory',
 )
 
-async def _single_delete_strategy(messages):
+
+async def _single_delete_strategy(messages: List[Message], reason: Optional[str] = None) -> None:
     for m in messages:
-        await m.delete()
+        await m.delete(reason=reason)
+
 
-class TextChannel(discord.abc.Messageable, discord.abc.GuildChannel, Hashable):
+class TextChannel(abc.Messageable, abc.GuildChannel, Hashable):
     """Represents a Discord guild text channel.
 
     .. container:: operations
@@ -103,6 +148,8 @@ class TextChannel(discord.abc.Messageable, discord.abc.GuildChannel, Hashable):
         The category channel ID this channel belongs to, if applicable.
     topic: Optional[:class:`str`]
         The channel's topic. ``None`` if it doesn't exist.
+    icon_emoji: Optional[:class:`PartialEmoji`]
+        The channel's icon-emoji, if set.
     position: :class:`int`
         The position in the channel list. This is a number that starts at 0. e.g. the
         top channel is position 0.
@@ -116,14 +163,30 @@ class TextChannel(discord.abc.Messageable, discord.abc.GuildChannel, Hashable):
         :attr:`~Permissions.manage_messages` bypass slowmode.
     """
 
-    __slots__ = ('name', 'id', 'guild', 'topic', '_state', 'nsfw',
+    __slots__ = ('name', 'id', 'guild', 'topic', 'icon_emoji', '_state', '__deleted', 'nsfw',
                  'category_id', 'position', 'slowmode_delay', '_overwrites',
-                 '_type', 'last_message_id')
+                 '_type', 'last_message_id', '_threads', 'default_auto_archive_duration')
+
+    if TYPE_CHECKING:
+        _state: ConnectionState
+        guild: Guild
+        name: str
+        id: int
+        guild: Guild
+        nsfw: bool
+        position: int
+        slowmode_delay: int
+        icon_emoji: Optional[PartialEmoji]
+        category_id: Optional[int]
+        last_message_id: Optional[int]
+        default_auto_archive_duration: AutoArchiveDuration
+        topic: Optional[str]
 
     def __init__(self, *, state, guild, data):
-        self._state = state
+        self._state: ConnectionState = state
         self.id = int(data['id'])
         self._type = data['type']
+        self._threads = {}
         self._update(guild, data)
 
     def __repr__(self):
@@ -137,6 +200,12 @@ def __repr__(self):
         ]
         return '<%s %s>' % (self.__class__.__name__, ' '.join('%s=%r' % t for t in attrs))
 
+    def __del__(self):
+        if getattr(self, '_TextChannel__deleted', None) is True:
+            guild = self.guild
+            for thread in self.threads:
+                guild._remove_channel(thread)
+
     def _update(self, guild, data):
         self.guild = guild
         self.name = data['name']
@@ -144,26 +213,49 @@ def _update(self, guild, data):
         self.topic = data.get('topic')
         self.position = data['position']
         self.nsfw = data.get('nsfw', False)
-        # Does this need coercion into `int`? No idea yet.
         self.slowmode_delay = data.get('rate_limit_per_user', 0)
+        emoji = data.get('icon_emoji')
+        self.icon_emoji = PartialEmoji.with_state(self._state, animated=False, **emoji) if emoji else None
         self._type = data.get('type', self._type)
         self.last_message_id = utils._get_as_snowflake(data, 'last_message_id')
+        self.default_auto_archive_duration = try_enum(
+            AutoArchiveDuration, data.get('default_auto_archive_duration', 1440)
+        )
         self._fill_overwrites(data)
 
     async def _get_channel(self):
         return self
 
     @property
-    def type(self):
+    def type(self) -> ChannelType:
         """:class:`ChannelType`: The channel's Discord type."""
         return try_enum(ChannelType, self._type)
 
+    @staticmethod
+    def channel_type():
+        return ChannelType.text
+
     @property
     def _sorting_bucket(self):
         return ChannelType.text.value
 
-    @utils.copy_doc(discord.abc.GuildChannel.permissions_for)
-    def permissions_for(self, member):
+    def _add_thread(self, thread):
+        self._threads[thread.id] = thread
+
+    def _remove_thread(self, thread):
+        return self._threads.pop(thread.id, None)
+
+    def get_thread(self, id: int) -> Optional[ThreadChannel]:
+        """Optional[:class:`ThreadChannel`]: Returns the cached thread in this channel with the given ID if any, else :obj:`None`"""
+        return self._threads.get(id, None)
+
+    @property
+    def threads(self) -> List[ThreadChannel]:
+        """List[:class:`ThreadChannel`]: Returns a list of cached threads for this channel"""
+        return list(self._threads.values())
+
+    @utils.copy_doc(abc.GuildChannel.permissions_for)
+    def permissions_for(self, member: Member, /) -> Permissions:
         base = super().permissions_for(member)
 
         # text channels do not have voice related permissions
@@ -172,20 +264,20 @@ def permissions_for(self, member):
         return base
 
     @property
-    def members(self):
+    def members(self) -> List[Member]:
         """List[:class:`Member`]: Returns all members that can see this channel."""
         return [m for m in self.guild.members if self.permissions_for(m).read_messages]
 
-    def is_nsfw(self):
+    def is_nsfw(self) -> bool:
         """:class:`bool`: Checks if the channel is NSFW."""
         return self.nsfw
 
-    def is_news(self):
+    def is_news(self) -> bool:
         """:class:`bool`: Checks if the channel is a news channel."""
         return self._type == ChannelType.news.value
 
     @property
-    def last_message(self):
+    def last_message(self) -> Optional[Message]:
         """Fetches the last message from this channel in cache.
 
         The message might not be valid or point to an existing message.
@@ -205,7 +297,7 @@ def last_message(self):
         """
         return self._state._get_message(self.last_message_id) if self.last_message_id else None
 
-    async def edit(self, *, reason=None, **options):
+    async def edit(self, *, reason: Optional[str] = None, **options) -> None:
         """|coro|
 
         Edits the channel.
@@ -260,15 +352,18 @@ async def edit(self, *, reason=None, **options):
         """
         await self._edit(options, reason=reason)
 
-    @utils.copy_doc(discord.abc.GuildChannel.clone)
-    async def clone(self, *, name=None, reason=None):
+    @utils.copy_doc(abc.GuildChannel.clone)
+    async def clone(self, *, name: Optional[str] = None, reason: Optional[str] = None) -> TextChannel:
         return await self._clone_impl({
             'topic': self.topic,
+            # The API gives me a 500 error when I try to clone the icon emoji, so we leave it out for now
+            # 'icon_emoji': self.icon_emoji.to_dict() if self.icon_emoji else None,
             'nsfw': self.nsfw,
-            'rate_limit_per_user': self.slowmode_delay
+            'rate_limit_per_user': self.slowmode_delay,
+            'default_auto_archive_duration': self.default_auto_archive_duration.value
         }, name=name, reason=reason)
 
-    async def delete_messages(self, messages):
+    async def delete_messages(self, messages: Iterable[Message], reason: Optional[str] = None) -> None:
         """|coro|
 
         Deletes a list of messages. This is similar to :meth:`Message.delete`
@@ -290,6 +385,8 @@ async def delete_messages(self, messages):
         -----------
         messages: Iterable[:class:`abc.Snowflake`]
             An iterable of messages denoting which ones to bulk delete.
+        reason: Optional[:class:`str`]
+            The reason for deleting these messages. Shows up on the audit log.
 
         Raises
         ------
@@ -318,9 +415,20 @@ async def delete_messages(self, messages):
             raise ClientException('Can only bulk delete messages up to 100 messages')
 
         message_ids = [m.id for m in messages]
-        await self._state.http.delete_messages(self.id, message_ids)
-
-    async def purge(self, *, limit=100, check=None, before=None, after=None, around=None, oldest_first=False, bulk=True):
+        await self._state.http.delete_messages(self.id, message_ids, reason=reason)
+
+    async def purge(
+            self,
+            *,
+            limit: Optional[int] = 100,
+            check: Callable = None,
+            before: Optional[Union[abc.Snowflake, datetime.datetime]] = None,
+            after: Optional[Union[abc.Snowflake, datetime.datetime]] = None,
+            around: Optional[Union[abc.Snowflake, datetime.datetime]] = None,
+            oldest_first: Optional[bool] = False,
+            bulk: Optional[bool] = True,
+            reason: Optional[str] = None
+    ) -> List[Message]:
         """|coro|
 
         Purges a list of messages that meet the criteria given by the predicate
@@ -368,6 +476,8 @@ def is_me(m):
             a bot's own messages without :attr:`Permissions.manage_messages`. When ``True``, will
             fall back to single delete if current account is a user bot (now deprecated), or if messages are
             older than two weeks.
+        reason: Optional[:class:`str`]
+            The reason for deleting the messages. Shows up on the audit log.
 
         Raises
         -------
@@ -390,7 +500,7 @@ def is_me(m):
         count = 0
 
         minimum_time = int((time.time() - 14 * 24 * 60 * 60) * 1000.0 - 1420070400000) << 22
-        strategy = self.delete_messages if self._state.is_bot and bulk else _single_delete_strategy
+        strategy = self.delete_messages if bulk else _single_delete_strategy
 
         while True:
             try:
@@ -400,17 +510,17 @@ def is_me(m):
                 if count >= 2:
                     # more than 2 messages -> bulk delete
                     to_delete = ret[-count:]
-                    await strategy(to_delete)
+                    await strategy(to_delete, reason=reason)
                 elif count == 1:
                     # delete a single message
-                    await ret[-1].delete()
+                    await ret[-1].delete(reason=reason)
 
                 return ret
             else:
                 if count == 100:
                     # we've reached a full 'queue'
                     to_delete = ret[-100:]
-                    await strategy(to_delete)
+                    await strategy(to_delete, reason=reason)
                     count = 0
                     await asyncio.sleep(1)
 
@@ -418,10 +528,10 @@ def is_me(m):
                     if msg.id < minimum_time:
                         # older than 14 days old
                         if count == 1:
-                            await ret[-1].delete()
+                            await ret[-1].delete(reason=reason)
                         elif count >= 2:
                             to_delete = ret[-count:]
-                            await strategy(to_delete)
+                            await strategy(to_delete, reason=reason)
 
                         count = 0
                         strategy = _single_delete_strategy
@@ -429,7 +539,7 @@ def is_me(m):
                     count += 1
                     ret.append(msg)
 
-    async def webhooks(self):
+    async def webhooks(self) -> List[Webhook]:
         """|coro|
 
         Gets the list of webhooks from this channel.
@@ -451,7 +561,13 @@ async def webhooks(self):
         data = await self._state.http.channel_webhooks(self.id)
         return [Webhook.from_state(d, state=self._state) for d in data]
 
-    async def create_webhook(self, *, name, avatar=None, reason=None):
+    async def create_webhook(
+            self,
+            *,
+            name: str,
+            avatar: Optional[bytes] = None,
+            reason: Optional[str] = None
+    ) -> Webhook:
         """|coro|
 
         Creates a webhook for this channel.
@@ -488,10 +604,10 @@ async def create_webhook(self, *, name, avatar=None, reason=None):
         if avatar is not None:
             avatar = utils._bytes_to_base64_data(avatar)
 
-        data = await self._state.http.create_webhook(self.id, name=str(name), avatar=avatar, reason=reason)
+        data = await self._state.http.create_webhook(self.id, name=name, avatar=avatar, reason=reason)
         return Webhook.from_state(data, state=self._state)
 
-    async def follow(self, *, destination, reason=None):
+    async def follow(self, *, destination: TextChannel, reason: Optional[str] = None) -> Webhook:
         """
         Follows a channel using a webhook.
 
@@ -536,7 +652,7 @@ async def follow(self, *, destination, reason=None):
         data = await self._state.http.follow_webhook(self.id, webhook_channel_id=destination.id, reason=reason)
         return Webhook._as_follower(data, channel=destination, user=self._state.user)
 
-    def get_partial_message(self, message_id):
+    def get_partial_message(self, message_id: id) -> PartialMessage:
         """Creates a :class:`PartialMessage` from the message ID.
 
         This is useful if you want to work with a message and only have its ID without
@@ -558,1030 +674,3353 @@ def get_partial_message(self, message_id):
         from .message import PartialMessage
         return PartialMessage(channel=self, id=message_id)
 
-class VocalGuildChannel(discord.abc.Connectable, discord.abc.GuildChannel, Hashable):
-    __slots__ = ('name', 'id', 'guild', 'bitrate', 'user_limit',
-                 '_state', 'position', '_overwrites', 'category_id',
-                 'rtc_region')
+    async def create_thread(
+            self,
+            name: str,
+            auto_archive_duration: Optional[AutoArchiveDuration] = None,
+            slowmode_delay: int = 0,
+            private: bool = False,
+            invitable: bool = True,
+            *,
+            reason: Optional[str] = None
+    ) -> ThreadChannel:
+        """|coro|
 
-    def __init__(self, *, state, guild, data):
-        self._state = state
-        self.id = int(data['id'])
-        self._update(guild, data)
+        Creates a new thread in this channel.
 
-    def _get_voice_client_key(self):
-        return self.guild.id, 'guild_id'
+        You must have the :attr:`~Permissions.create_public_threads`,
+        or for private :attr:`~Permissions.create_private_threads` permission to
+        use this.
 
-    def _get_voice_state_pair(self):
-        return self.guild.id, self.id
+        Parameters
+        ----------
+        name: :class:`str`
+            The name of the thread.
+        auto_archive_duration: Optional[:class:`AutoArchiveDuration`]
+            Amount of time after that the thread will auto-hide from the channel list
+        slowmode_delay: :class:`int`
+            Amount of seconds a user has to wait before sending another message (0-21600)
+        private: :class:`bool`
+            Whether to create a private thread
+        invitable: :class:`bool`
+            For private-threads Whether non-moderators can add new members to the thread, default :obj`True`
+        reason: Optional[:class:`str`]
+            The reason for creating the thread. Shows up in the audit log.
 
-    def _update(self, guild, data):
-        self.guild = guild
-        self.name = data['name']
-        self.rtc_region = data.get('rtc_region')
-        if self.rtc_region:
-            self.rtc_region = try_enum(VoiceRegion, self.rtc_region)
-        self.category_id = utils._get_as_snowflake(data, 'parent_id')
-        self.position = data['position']
-        self.bitrate = data.get('bitrate')
-        self.user_limit = data.get('user_limit')
-        self._fill_overwrites(data)
+        Raises
+        ------
+        :exc:`TypeError`
+            The channel of the message is not a text or news channel,
+            or the message has already a thread,
+            or auto_archive_duration is not a valid member of :class:`AutoArchiveDuration`
+        :exc:`ValueError`
+            The ``name`` is of invalid length
+        :exc:`Forbidden`
+            The bot is missing permissions to create threads in this channel
+        :exc:`HTTPException`
+            Creating the thread failed
 
-    @property
-    def _sorting_bucket(self):
-        return ChannelType.voice.value
+        Returns
+        -------
+        :class:`ThreadChannel`
+            The created thread on success
+        """
+        if len(name) > 100 or len(name) < 1:
+            raise ValueError('The name of the thread must bee between 1-100 characters; got %s' % len(name))
+
+        payload = {
+            'name': name
+        }
+
+        if auto_archive_duration:
+            auto_archive_duration = try_enum(
+                AutoArchiveDuration, auto_archive_duration
+            )  # for the case someone passes a number
+            if not isinstance(auto_archive_duration, AutoArchiveDuration):
+                raise TypeError(
+                    f'auto_archive_duration must be a member of discord.AutoArchiveDuration, not {auto_archive_duration.__class__.__name__!r}'
+                )
+            payload['auto_archive_duration'] = auto_archive_duration.value
+
+        if slowmode_delay:
+            payload['rate_limit_per_user'] = slowmode_delay
+
+        if private:
+            payload['type'] = ChannelType.private_thread.value
+            if not invitable:
+                payload['invitable'] = False
+        elif self.is_news():
+            payload['type'] = ChannelType.news_thread.value
+        else:
+            payload['type'] = ChannelType.public_thread.value
+
+        data = await self._state.http.create_thread(self.id, payload=payload, reason=reason)
+        thread = ThreadChannel(state=self._state, guild=self.guild, data=data)
+        self.guild._add_channel(thread)
+        return thread
+
+    async def archived_threads(
+            self,
+            *,
+            private: bool = False,
+            joined_private: bool = True,
+            before: Optional[Union[abc.Snowflake, datetime.datetime]] = None,
+            limit: int = 100
+    ) -> ArchivedThreadIterator:
+        """|coro|
 
-    @property
-    def members(self):
-        """List[:class:`Member`]: Returns all members that are currently inside this voice channel."""
-        ret = []
-        for user_id, state in self.guild._voice_states.items():
-            if state.channel and state.channel.id == self.id:
-                member = self.guild.get_member(user_id)
-                if member is not None:
-                    ret.append(member)
-        return ret
+        Returns an :class:`abc.AsyncIterator` to retrieve archived threads from this channel.
 
-    @property
-    def voice_states(self):
-        """Returns a mapping of member IDs who have voice states in this channel.
+        Parameters
+        ----------
+        private: :class:`bool`
+            Whether to fetch all private threads instead of public ones. Defaults to ``False``.
+        joined_private: :class:`bool`
+            Whether to only fetch private threads the bot has joined. Defaults to ``True``.
 
-        .. versionadded:: 1.3
+            .. note::
+                The :meth:`~Permissions.manage_threads` permission is required
+                in order to fetch not-joined private threads.
 
-        .. note::
+        before: Optional[Union[:class:`abc.Snowflake`, :class:`datetime.datetime`]]
+            Only fetch threads created before this date or ID.
+        limit: :class:`int`
+            The maximum number of threads to fetch. Defaults to ``100``.
 
-            This function is intentionally low level to replace :attr:`members`
-            when the member cache is unavailable.
+        Raises
+        ------
+        Forbidden
+            The bot lacks permissions to fetch not-joined private threads.
+        HTTPException
+            Fetching the threads failed.
 
         Returns
-        --------
-        Mapping[:class:`int`, :class:`VoiceState`]
-            The mapping of member ID to a voice state.
+        -------
+        :class:`ArchivedThreadIterator`
+            An iterator to retrieve the archived threads.
         """
-        return {key: value for key, value in self.guild._voice_states.items() if value.channel.id == self.id}
+        return ArchivedThreadIterator(
+            channel=self,
+            private=private,
+            joined_private=joined_private,
+            before=before,
+            limit=limit
+        )
 
-    @utils.copy_doc(discord.abc.GuildChannel.permissions_for)
-    def permissions_for(self, member):
-        base = super().permissions_for(member)
 
-        # voice channels cannot be edited by people who can't connect to them
-        # It also implicitly denies all other voice perms
-        if not base.connect:
-            denied = Permissions.voice()
-            denied.update(manage_channels=True, manage_roles=True)
-            base.value &= ~denied.value
-        return base
+class ThreadMember:
+    """
+    Represents a minimal :class:`Member` that has joined a :class:`ThreadChannel` or :class:`ForumPost`
 
-class VoiceChannel(VocalGuildChannel):
-    """Represents a Discord guild voice channel.
+    Attributes
+    ----------
+    id: :class:`int`
+        The ID of the member
+    guild: :class:`Guild`
+        The guild the thread member belongs to
+    joined_at: :class:`datetime.datetime`
+        When the member joined the thread
+    thread_id: :class:`int`
+        The id of the thread the member belongs to
+    guild_id: :class:`int`
+        The ID of the guild the thread member belongs to
 
-    .. container:: operations
+    """
+    def __init__(self, *, state: ConnectionState, guild: Guild, data):
+        self._state: ConnectionState = state
+        self.guild: Guild = guild
+        self.thread_id: int = int(data.get('id', 0))
+        self.guild_id: int = int(data.get('guild_id', guild.id))
+        self.id: int = int(data.get('user_id', self._state.self_id))
+        self.joined_at: datetime.datetime = datetime.datetime.fromisoformat(data.get('join_timestamp'))
+        self.flags: int = int(data.get('flags'))
+
+    def __repr__(self) -> str:
+        return (
+            f'<ThreadMember ({self.as_guild_member}) id={self.id} '
+            f'thread_id={self.thread_id} guild_id={self.guild_id}>'
+        )
+
+    def __eq__(self, other):
+        return other.id == self.id
 
-        .. describe:: x == y
+    @classmethod
+    def _from_thread(cls, *, thread, data):
+        data['user_id'] = int(data.get('user_id', thread._state.self_id))
+        data['id'] = thread.id
+        return cls(state=thread._state, guild=thread.guild, data=data)
 
-            Checks if two channels are equal.
+    @property
+    def as_guild_member(self) -> Optional[Member]:
+        """Optional[:class:`Member`]: Returns the full guild member for the thread member if cached else :obj:`None`"""
+        return self.guild.get_member(self.id)
 
-        .. describe:: x != y
+    async def send(self, *args, **kwargs) -> Coroutine[Any, Any, Message]:
+        """
+        A shortcut to :meth:`Member.send`
+        """
+        member: abc.Messageable = self.as_guild_member or await self._state._get_client().fetch_user(self.id)
+        return member.send(*args, **kwargs)
 
-            Checks if two channels are not equal.
+    def permissions_in(self, channel: abc.GuildChannel) -> Permissions:
+        """
+        A shorthand method to :meth:`Member.permissions_in`
 
-        .. describe:: hash(x)
+        Raises
+        ------
+        TypeError
+            The associated guild member is not cached
+        """
+        member = self.as_guild_member
+        if not member:
+            raise TypeError('The guild member of this thread member is not cached')
+        return member.permissions_in(channel)
 
-            Returns the channel's hash.
+    @property
+    def mention(self) -> str:
+        """Returns a string the client renders as a mention of the user"""
+        return f'<@{self.id}>'
 
-        .. describe:: str(x)
 
-            Returns the channel's name.
+class ThreadChannel(abc.Messageable, Hashable):
+    """
+    Represents a thread in a guild
 
     Attributes
-    -----------
-    name: :class:`str`
-        The channel name.
-    guild: :class:`Guild`
-        The guild the channel belongs to.
+    ----------
     id: :class:`int`
-        The channel ID.
-    category_id: Optional[:class:`int`]
-        The category channel ID this channel belongs to, if applicable.
-    position: :class:`int`
-        The position in the channel list. This is a number that starts at 0. e.g. the
-        top channel is position 0.
-    bitrate: :class:`int`
-        The channel's preferred audio bitrate in bits per second.
-    user_limit: :class:`int`
-        The channel's limit for number of members that can be in a voice channel.
-    rtc_region: Optional[:class:`VoiceRegion`]
-        The region for the voice channel's voice communication.
-        A value of ``None`` indicates automatic voice region detection.
-
-        .. versionadded:: 1.7
+        The ID of the thread
+    type: :class:`ChannelType`
+        The type of the thread
     """
+    def __init__(self, *, state: ConnectionState, guild: Guild, data):
+        self._state: ConnectionState = state
+        self.id: int = int(data['id'])
+        self.type: ChannelType = ChannelType.try_value(data['type'])
+        self._members: Dict[int, ThreadMember] = {}
+        self._update(guild, data)
 
-    __slots__ = ()
-
-    def __repr__(self):
-        attrs = [
-            ('id', self.id),
-            ('name', self.name),
-            ('rtc_region', self.rtc_region),
-            ('position', self.position),
-            ('bitrate', self.bitrate),
-            ('user_limit', self.user_limit),
-            ('category_id', self.category_id)
-        ]
-        return '<%s %s>' % (self.__class__.__name__, ' '.join('%s=%r' % t for t in attrs))
+    @staticmethod
+    def channel_type():
+        return ChannelType.public_thread
 
     @property
-    def type(self):
-        """:class:`ChannelType`: The channel's Discord type."""
-        return ChannelType.voice
+    def _sorting_bucket(self):
+        return ChannelType.public_thread.value
+
+    def _update(self, guild: Guild, data: Dict[str, Any]):
+        self.guild: Guild = guild
+        self.parent_id: int = int(data['parent_id'])
+        self.owner_id: int = int(data['owner_id'])
+        if not self._members:
+            self._members = {self.owner_id: self.owner}
+        self.name: str = data['name']
+        self.flags: ChannelFlags = ChannelFlags._from_value(data['flags'])
+        self.message_count: int = data.get('message_count', 0)
+        self.total_message_sent: int = data.get('total_message_sent', self.message_count)
+        self.member_count = data.get('member_count', 0)
+        self.last_message_id: int = utils._get_as_snowflake(data, 'last_message_id')
+        self.slowmode_delay: int = int(data.get('rate_limit_per_user', 0))
+        self._thread_meta = data.get('thread_metadata', {})
+        me = data.get('member')
+        if me:
+            self._members[self._state.self_id] = ThreadMember._from_thread(thread=self, data=me)
+        return self
 
-    @utils.copy_doc(discord.abc.GuildChannel.clone)
-    async def clone(self, *, name=None, reason=None):
-        return await self._clone_impl({
-            'bitrate': self.bitrate,
-            'user_limit': self.user_limit
-        }, name=name, reason=reason)
+    @classmethod
+    def _from_partial(cls, state: ConnectionState, guild: Guild, data: Dict[str, Any]) -> ThreadChannel:
+        self = cls.__new__(cls)
+        self._state = state
+        self.id = int(data['id'])
+        self.guild = guild
+        self.type = try_enum(ChannelType, data['type'])
+        self.parent_id = int(data['parent_id'])
+        return self
 
-    async def edit(self, *, reason=None, **options):
-        """|coro|
+    def _sync_from_members_update(self, data: Dict[str, Any]) -> None:
+        self.member_count = data.get('member_count', self.member_count)
+        # joined = self._state.member_cache_flags.joined
+        for new_member in data.get('added_members', []):
+            self._add_member(ThreadMember(state=self._state, guild=self.guild, data=new_member))
+        for removed_id in data.get('removed_member_ids', []):
+            member = self.get_member(int(removed_id))
+            if member:
+                self._remove_member(member)
 
-        Edits the channel.
+    def _add_self(self, data: Dict[str, Any]) -> None:
+        self._add_member(ThreadMember(state=self._state, guild=self.guild, data=data))
 
-        You must have the :attr:`~Permissions.manage_channels` permission to
-        use this.
+    async def _get_channel(self) -> ThreadChannel:
+        return self
 
-        .. versionchanged:: 1.3
-            The ``overwrites`` keyword-only parameter was added.
+    def _add_member(self, member: ThreadMember) -> None:
+        self._members[member.id] = member
 
-        Parameters
-        ----------
-        name: :class:`str`
-            The new channel's name.
-        bitrate: :class:`int`
-            The new channel's bitrate.
-        user_limit: :class:`int`
-            The new channel's user limit.
-        position: :class:`int`
-            The new channel's position.
-        sync_permissions: :class:`bool`
-            Whether to sync permissions with the channel's new or pre-existing
-            category. Defaults to ``False``.
-        category: Optional[:class:`CategoryChannel`]
-            The new category for this channel. Can be ``None`` to remove the
-            category.
-        reason: Optional[:class:`str`]
-            The reason for editing this channel. Shows up on the audit log.
-        overwrites: :class:`dict`
-            A :class:`dict` of target (either a role or a member) to
-            :class:`PermissionOverwrite` to apply to the channel.
-        rtc_region: Optional[:class:`VoiceRegion`]
-            The new region for the voice channel's voice communication.
-            A value of ``None`` indicates automatic voice region detection.
+    def _remove_member(self, member: ThreadMember) -> None:
+        self._members.pop(member.id, None)
 
-            .. versionadded:: 1.7
+    @property
+    def starter_message(self) -> Optional[Message]:
+        """Optional[:class:`Message`]: The starter message of this thread if it was started from a message and the message is cached"""
+        return self._state._get_message(self.id)
 
-        Raises
-        ------
-        InvalidArgument
-            If the permission overwrite information is not in proper form.
-        Forbidden
-            You do not have permissions to edit the channel.
-        HTTPException
-            Editing the channel failed.
+    @property
+    def owner(self) -> Optional[Union[Member, ThreadMember]]:
         """
+        Returns the owner(creator) of the thread.
+        Depending on whether the associated guild member is cached, this returns the :class:`Member` instead of the :class:`ThreadMember`
 
-        await self._edit(options, reason=reason)
+        .. note::
 
-class StageChannel(VocalGuildChannel):
-    """Represents a Discord guild stage channel.
+            If the thread members are not fetched (can be done manually using :meth:`~ThreadChannel.fetch_members`)
+            and the guild member is not cached, this returns :obj:`None`.
 
-    .. versionadded:: 1.7
+        Returns
+        --------
+        Optional[Union[:class:`Member`, :class:`ThreadMember`]]
+            The thread owners' Member if cached, else the respective ThreadMember.
+        """
+        return self.guild.get_member(self.owner_id) or self.get_member(self.owner_id)
 
-    .. container:: operations
+    @property
+    def members(self) -> List[ThreadMember]:
+        """List[:class:`Member`]: Returns a list with cached members of this thread"""
+        return list(self._members.values())
+    
+    @property
+    def locked(self) -> bool:
+        """:class:`bool`: Whether the threads conversation is locked by a moderator.
+        If so, the thread can only be unarchived by a moderator
+        """
+        return self._thread_meta.get('locked', False)
 
-        .. describe:: x == y
+    @property
+    def auto_archive_duration(self) -> AutoArchiveDuration:
+        """:class:`AutoArchiveDuration`: The duration after which the thread will auto hide from the channel list"""
+        return try_enum(AutoArchiveDuration, self._thread_meta.get('auto_archive_duration', 0))
 
-            Checks if two channels are equal.
+    @property
+    def archived(self) -> bool:
+        """:class:`bool`: Whether the thread is archived (e.g. not showing in the channel list)"""
+        return self._thread_meta.get('archived', True)
 
-        .. describe:: x != y
+    @property
+    def invitable(self) -> bool:
+        """
+        Private threads only:
+        When :obj:`True` only the owner of the thread and members with :attr:`~Permissions.manage_threads` permissions
+        can add new members
 
-            Checks if two channels are not equal.
+        Returns
+        -------
+        :class:`bool`
+        """
+        return self._thread_meta.get('invitable', False)
 
-        .. describe:: hash(x)
+    @property
+    def archive_time(self) -> Optional[datetime.datetime]:
+        """
+        Optional[:class:`~datetime.datetime`]: When the thread's archive status was last changed,
+        used for calculating recent activity
+        """
+        archive_timestamp = self._thread_meta.get('archive_timestamp', None)
+        if archive_timestamp:
+            return datetime.datetime.fromisoformat(archive_timestamp)
 
-            Returns the channel's hash.
+    @property
+    def me(self) -> Optional[ThreadMember]:
+        """
+        Optional[:class:`ThreadMember`]: The thread member of the bot, or ``None`` if he is not a member of the thread.
+        """
+        return self.get_member(self._state.self_id)
 
-        .. describe:: str(x)
+    @property
+    def parent_channel(self) -> Union[TextChannel, ForumChannel]:
+        """Union[:class:`TextChannel`, :class:`ForumChannel`]: The parent channel of this thread"""
+        return self.guild.get_channel(self.parent_id)
 
-            Returns the channel's name.
+    @property
+    def category_id(self) -> Optional[int]:
+        """Optional[:class:`int`]: The ID of the threads parent channel category, if any"""
+        return self.parent_channel.category_id
 
-    Attributes
-    -----------
-    name: :class:`str`
-        The channel name.
-    guild: :class:`Guild`
-        The guild the channel belongs to.
-    id: :class:`int`
-        The channel ID.
-    topic: Optional[:class:`str`]
-        The channel's topic. ``None`` if it isn't set.
-    category_id: Optional[:class:`int`]
-        The category channel ID this channel belongs to, if applicable.
-    position: :class:`int`
-        The position in the channel list. This is a number that starts at 0. e.g. the
-        top channel is position 0.
-    bitrate: :class:`int`
-        The channel's preferred audio bitrate in bits per second.
-    user_limit: :class:`int`
-        The channel's limit for number of members that can be in a stage channel.
-    rtc_region: Optional[:class:`VoiceRegion`]
-        The region for the stage channel's voice communication.
-        A value of ``None`` indicates automatic voice region detection.
-    """
-    __slots__ = ('topic',)
+    @property
+    def created_at(self) -> Optional[datetime.datetime]:
+        """Optional[:class:`datetime.datetime`]: An aware timestamp of when the thread was created in UTC.
 
-    def __repr__(self):
-        attrs = [
-            ('id', self.id),
-            ('name', self.name),
-            ('topic', self.topic),
-            ('rtc_region', self.rtc_region),
-            ('position', self.position),
-            ('bitrate', self.bitrate),
-            ('user_limit', self.user_limit),
-            ('category_id', self.category_id)
-        ]
-        return '<%s %s>' % (self.__class__.__name__, ' '.join('%s=%r' % t for t in attrs))
+        .. note::
 
-    def _update(self, guild, data):
-        super()._update(guild, data)
-        self.topic = data.get('topic')
+            This timestamp only exists for threads created after 9 January 2022, otherwise returns ``None``.
+        """
+        create_timestamp = self._thread_meta.get('create_timestamp', None)
+        if create_timestamp:
+            return datetime.datetime.fromisoformat(create_timestamp)
 
     @property
-    def requesting_to_speak(self):
-        """List[:class:`Member`]: A list of members who are requesting to speak in the stage channel."""
-        return [member for member in self.members if member.voice.requested_to_speak_at is not None]
+    def mention(self) -> str:
+        """:class:`str`: The string that allows you to mention the thread."""
+        return f'<#{self.id}>'
 
     @property
-    def type(self):
-        """:class:`ChannelType`: The channel's Discord type."""
-        return ChannelType.stage_voice
+    def jump_url(self) -> str:
+        """:class:`str`: Returns a URL that allows the client to jump to the referenced thread."""
+        return f'https://discord.com/channels/{self.guild.id}/{self.id}'
 
-    @utils.copy_doc(discord.abc.GuildChannel.clone)
-    async def clone(self, *, name=None, reason=None):
-        return await self._clone_impl({
-            'topic': self.topic,
-        }, name=name, reason=reason)
+    def get_member(self, id) -> Optional[ThreadMember]:
+        """:class:`ThreadMember`: Returns the thread member with the given ID, or :obj:`None` if he is not a member of the thread."""
+        return self._members.get(id, None)
 
-    async def edit(self, *, reason=None, **options):
-        """|coro|
+    def permissions_for(self, member: Member) -> Permissions:
+        """Handles permission resolution for the current :class:`~discord.Member`.
 
-        Edits the channel.
+        .. note::
+            threads inherit their permissions from their parent channel.
 
-        You must have the :attr:`~Permissions.manage_channels` permission to
-        use this.
+        This function takes into consideration the following cases:
+
+        - Guild owner
+        - Guild roles
+        - Channel overrides
+        - Member overrides
 
         Parameters
         ----------
-        name: :class:`str`
-            The new channel's name.
-        topic: :class:`str`
-            The new channel's topic.
-        position: :class:`int`
-            The new channel's position.
-        sync_permissions: :class:`bool`
-            Whether to sync permissions with the channel's new or pre-existing
-            category. Defaults to ``False``.
-        category: Optional[:class:`CategoryChannel`]
-            The new category for this channel. Can be ``None`` to remove the
-            category.
-        reason: Optional[:class:`str`]
-            The reason for editing this channel. Shows up on the audit log.
-        overwrites: :class:`dict`
-            A :class:`dict` of target (either a role or a member) to
-            :class:`PermissionOverwrite` to apply to the channel.
-        rtc_region: Optional[:class:`VoiceRegion`]
-            The new region for the stage channel's voice communication.
-            A value of ``None`` indicates automatic voice region detection.
+        member: :class:`~discord.Member`
+            The member to resolve permissions for.
 
-        Raises
-        ------
-        InvalidArgument
-            If the permission overwrite information is not in proper form.
-        Forbidden
-            You do not have permissions to edit the channel.
-        HTTPException
-            Editing the channel failed.
+        Returns
+        -------
+        :class:`~discord.Permissions`
+            The resolved permissions for the member.
         """
+        return self.parent_channel.permissions_for(member)
 
-        await self._edit(options, reason=reason)
-
-class CategoryChannel(discord.abc.GuildChannel, Hashable):
-    """Represents a Discord channel category.
-
-    These are useful to group channels to logical compartments.
+    def is_nsfw(self):
+        """:class:`bool`: Whether the parent channel of this thread has NSFW enabled."""
+        return self.parent_channel.is_nsfw()
 
-    .. container:: operations
+    async def join(self):
+        """|coro|
 
-        .. describe:: x == y
+        Adds the current user to the thread.
 
-            Checks if two channels are equal.
+        .. note::
+            Also requires the thread is **not archived**.
 
-        .. describe:: x != y
+        This will fire a :func:`discord.thread_members_update` event.
+        """
 
-            Checks if two channels are not equal.
+        if self.archived:
+            raise ThreadIsArchived(self.join)
+        if self.me:
+            raise ClientException('You\'r already a member of this thread.')
 
-        .. describe:: hash(x)
+        return await self._state.http.add_thread_member(channel_id=self.id)
 
-            Returns the category's hash.
+    async def leave(self):
+        """|coro|
 
-        .. describe:: str(x)
+        Removes the current user from the thread.
 
-            Returns the category's name.
+        .. note::
+            Also requires the thread is **not archived**.
 
-    Attributes
-    -----------
-    name: :class:`str`
-        The category name.
-    guild: :class:`Guild`
-        The guild the category belongs to.
-    id: :class:`int`
-        The category channel ID.
-    position: :class:`int`
-        The position in the category list. This is a number that starts at 0. e.g. the
-        top category is position 0.
-    """
+        This will fire a :func:`discord.thread_members_update` event.
+        """
 
-    __slots__ = ('name', 'id', 'guild', 'nsfw', '_state', 'position', '_overwrites', 'category_id')
+        if self.archived:
+            raise ThreadIsArchived(self.leave)
+        if not self.me:
+            raise ClientException('You cannot leave a thread if you are not a member of it.')
 
-    def __init__(self, *, state, guild, data):
-        self._state = state
-        self.id = int(data['id'])
-        self._update(guild, data)
+        return await self._state.http.remove_thread_member(channel_id=self.id)
 
-    def __repr__(self):
-        return '<CategoryChannel id={0.id} name={0.name!r} position={0.position} nsfw={0.nsfw}>'.format(self)
+    async def add_member(self, member: Union[Member, int]):
+        """|coro|
 
-    def _update(self, guild, data):
-        self.guild = guild
-        self.name = data['name']
-        self.category_id = utils._get_as_snowflake(data, 'parent_id')
-        self.nsfw = data.get('nsfw', False)
-        self.position = data['position']
-        self._fill_overwrites(data)
+        Adds another member to the thread.
 
-    @property
-    def _sorting_bucket(self):
-        return ChannelType.category.value
+        .. note::
+            Requires the ability to send messages in the thread.\n
+            Also requires the thread is **not archived**.
 
-    @property
-    def type(self):
-        """:class:`ChannelType`: The channel's Discord type."""
-        return ChannelType.category
+        This will fire a ``thread_members_update`` event.
 
-    def is_nsfw(self):
-        """:class:`bool`: Checks if the category is NSFW."""
-        return self.nsfw
+        Parameters
+        ----------
+        member: Union[:class:`discord.Member`, :class:`int`]
+            The member that should be added to the thread; could be a :class:`discord.Member` or his :attr:`id` (e.g. an :class:`int`)
+        """
+        if self.archived:
+            raise ThreadIsArchived(self.add_member)
+        member_id = member if isinstance(member, int) else member.id
+        if self.get_member(member_id):
+            raise ClientException('The user %s is already a Member of this thread.' % member)
 
-    @utils.copy_doc(discord.abc.GuildChannel.clone)
-    async def clone(self, *, name=None, reason=None):
-        return await self._clone_impl({
-            'nsfw': self.nsfw
-        }, name=name, reason=reason)
+        return await self._state.http.add_thread_member(channel_id=self.id, member_id=member_id)
 
-    async def edit(self, *, reason=None, **options):
+    async def remove_member(self, member: Union[Member, int]):
         """|coro|
 
-        Edits the channel.
+        Removes a member from the thread.
 
-        You must have the :attr:`~Permissions.manage_channels` permission to
-        use this.
+        .. note::
+            This requires the ``MANAGE_THREADS`` permission, or to be the creator of the thread if it is a ``PRIVATE_THREAD``.\n
+            Also requires the thread is **not archived**.
 
-        .. versionchanged:: 1.3
-            The ``overwrites`` keyword-only parameter was added.
+        This will fire a ``thread_members_update`` event.
 
         Parameters
         ----------
-        name: :class:`str`
-            The new category's name.
-        position: :class:`int`
-            The new category's position.
-        nsfw: :class:`bool`
-            To mark the category as NSFW or not.
-        reason: Optional[:class:`str`]
-            The reason for editing this category. Shows up on the audit log.
-        overwrites: :class:`dict`
-            A :class:`dict` of target (either a role or a member) to
-            :class:`PermissionOverwrite` to apply to the channel.
-
-        Raises
-        ------
-        InvalidArgument
-            If position is less than 0 or greater than the number of categories.
-        Forbidden
-            You do not have permissions to edit the category.
-        HTTPException
-            Editing the category failed.
+        member: Union[:class:`discord.Member`, :class:`int`]
+            The member that should be removed from the thread; could be a :class:`discord.Member` or his :attr:`id` (e.g. an :class:`int`)
         """
 
-        await self._edit(options=options, reason=reason)
+        if self.archived:
+            raise ThreadIsArchived(self.remove_member)
+        member_id = member if isinstance(member, int) else member.id
+        if not self.get_member(member_id):
+            raise ClientException('The user %s is not a member of this thread yet, so you could not remove him.' % member)
 
-    @utils.copy_doc(discord.abc.GuildChannel.move)
-    async def move(self, **kwargs):
-        kwargs.pop('category', None)
-        await super().move(**kwargs)
+        return await self._state.http.remove_thread_member(channel_id=self.id, member_id=member_id)
 
-    @property
-    def channels(self):
-        """List[:class:`abc.GuildChannel`]: Returns the channels that are under this category.
+    def fetch_members(
+            self,
+            limit: int = 100,
+            after: Union[abc.Snowflake, datetime.datetime] = None,
+            
+    ) -> ThreadMemberIterator:
+        """Returns a :class:`ThreadMemberIterator` that allows to retrieve the currently joined members of this thread.
 
-        These are sorted by the official Discord UI, which places voice channels below the text channels.
-        """
-        def comparator(channel):
-            return (not isinstance(channel, TextChannel), channel.position)
+        .. note::
+            This requires the :func:`~Intents.members` intent to be enabled and will also add the members retrieved to :attr:`members`
+        
+        Examples
+        ---------
+        
+        Usage ::
 
-        ret = [c for c in self.guild.channels if c.category_id == self.id]
-        ret.sort(key=comparator)
-        return ret
+            print(f"The thread {channel.name} has the following members:\\n")
+            async for member in thread.fetch_members(limit=200):
+                print(member)
 
-    @property
-    def text_channels(self):
-        """List[:class:`TextChannel`]: Returns the text channels that are under this category."""
-        ret = [c for c in self.guild.channels
-            if c.category_id == self.id
-            and isinstance(c, TextChannel)]
-        ret.sort(key=lambda c: (c.position, c.id))
-        return ret
 
-    @property
-    def voice_channels(self):
-        """List[:class:`VoiceChannel`]: Returns the voice channels that are under this category."""
-        ret = [c for c in self.guild.channels
-            if c.category_id == self.id
-            and isinstance(c, VoiceChannel)]
-        ret.sort(key=lambda c: (c.position, c.id))
-        return ret
+        Flattening into a list ::
 
-    @property
-    def stage_channels(self):
-        """List[:class:`StageChannel`]: Returns the voice channels that are under this category.
+            messages = await thread.fetch_members(limit=123).flatten()
+            # messages is now a list of ThreadMember...
 
-        .. versionadded:: 1.7
+
+        All parameters are optional.
+        
+        Parameters
+        ----------
+        limit: :class:`int`
+            The limit of thread members to retrieve - defaults to 100
+        after: Union[:class:`int`, :class:`datetime.datetime`]
+            Get thread members after this user ID
+        
+        Raises
+        ------
+        ~discord.ClientException
+            The :attr:`~Intents.members` intent is not enabled.
+        
+        Yields
+        -------
+        :class:`~discord.ThreadMember`
+            A member of this thread
         """
-        ret = [c for c in self.guild.channels
-            if c.category_id == self.id
-            and isinstance(c, StageChannel)]
-        ret.sort(key=lambda c: (c.position, c.id))
-        return ret
+        if not self._state.intents.members:
+            raise ClientException('You need to enable the GUILD_MEMBERS Intent to use this API-call.')
+        return ThreadMemberIterator(thread=self, limit=limit, after=after)
 
-    async def create_text_channel(self, name, *, overwrites=None, reason=None, **options):
+    async def delete(self, *, reason: Optional[str] = None) -> None:
         """|coro|
 
-        A shortcut method to :meth:`Guild.create_text_channel` to create a :class:`TextChannel` in the category.
+        Deletes the thread channel.
 
-        Returns
+        The bot must have :attr:`~Permissions.manage_channels` permission to use this.
+
+        Parameters
+        -----------
+        reason: Optional[:class:`str`]
+            The reason for deleting this thread.
+            Shows up on the audit log.
+
+        Raises
         -------
-        :class:`TextChannel`
-            The channel that was just created.
+        Forbidden
+            The bot is missing permissions to delete the thread.
+        NotFound
+            The thread was not found or was already deleted.
+        HTTPException
+            Deleting the thread failed.
         """
-        return await self.guild.create_text_channel(name, overwrites=overwrites, category=self, reason=reason, **options)
+        await self._state.http.delete_channel(self.id, reason=reason)
 
-    async def create_voice_channel(self, name, *, overwrites=None, reason=None, **options):
+    async def create_invite(self, *, reason=None, **fields):
         """|coro|
 
-        A shortcut method to :meth:`Guild.create_voice_channel` to create a :class:`VoiceChannel` in the category.
+        Creates an instant invite from this thread.
 
-        Returns
+        You must have the :attr:`~Permissions.create_instant_invite` permission to
+        do this.
+
+        Parameters
+        ------------
+        max_age: :class:`int`
+            How long the invite should last in seconds. If it's 0 then the invite
+            doesn't expire. Defaults to ``0``.
+        max_uses: :class:`int`
+            How many uses the invite could be used for. If it's 0 then there
+            are unlimited uses. Defaults to ``0``.
+        temporary: :class:`bool`
+            Denotes that the invite grants temporary membership
+            (i.e. they get kicked after they disconnect). Defaults to ``False``.
+        unique: :class:`bool`
+            Indicates if a unique invite URL should be created. Defaults to True.
+            If this is set to ``False`` then it will return a previously created
+            invite.
+        reason: Optional[:class:`str`]
+            The reason for creating this invite. Shows up on the audit log.
+
+        Raises
         -------
-        :class:`VoiceChannel`
-            The channel that was just created.
+        ~discord.HTTPException
+            Invite creation failed.
+
+        Returns
+        --------
+        :class:`~discord.Invite`
+            The invite that was created.
         """
-        return await self.guild.create_voice_channel(name, overwrites=overwrites, category=self, reason=reason, **options)
+        from .invite import Invite
+        data = await self._state.http.create_invite(self.id, reason=reason, **fields)
+        return Invite.from_incomplete(data=data, state=self._state)
 
-    async def create_stage_channel(self, name, *, overwrites=None, reason=None, **options):
+    async def invites(self):
         """|coro|
 
-        A shortcut method to :meth:`Guild.create_stage_channel` to create a :class:`StageChannel` in the category.
+        Returns a list of all active instant invites from this thread.
 
-        .. versionadded:: 1.7
+        You must have :attr:`~Permissions.manage_channels` to get this information.
+
+        Raises
+        -------
+        ~discord.Forbidden
+            You do not have proper permissions to get the information.
+        ~discord.HTTPException
+            An error occurred while fetching the information.
 
         Returns
         -------
-        :class:`StageChannel`
-            The channel that was just created.
+        List[:class:`~discord.Invite`]
+            The list of invites that are currently active.
         """
-        return await self.guild.create_stage_channel(name, overwrites=overwrites, category=self, reason=reason, **options)
+        from .invite import Invite
+
+        state = self._state
+        data = await state.http.invites_from_channel(self.id)
+        result = []
+
+        for invite in data:
+            invite['channel'] = self
+            invite['guild'] = self.guild
+            result.append(Invite(state=state, data=invite))
+
+        return result
+
+    async def edit(
+            self,
+            *,
+            name: str = MISSING,
+            archived: bool = MISSING,
+            auto_archive_duration: AutoArchiveDuration = MISSING,
+            locked: bool = MISSING,
+            invitable: bool = MISSING,
+            slowmode_delay: int = MISSING,
+            reason: Optional[str] = None
+    ) -> ThreadChannel:
+        """|coro|
 
-class StoreChannel(discord.abc.GuildChannel, Hashable):
-    """Represents a Discord guild store channel.
+        Edits the thread. In order to unarchive it, you must already be a member of it.
 
-    .. container:: operations
+        Parameters
+        ----------
+        name: Optional[:class:`str`]
+            The channel name. Must be 1-100 characters long
+        auto_archive_duration: Optional[:class:`AutoArchiveDuration`]
+            Duration in minutes to automatically archive the thread after recent activity
+        archived: Optional[:class:`bool`]
+            Whether the thread is archived
+        locked: Optional[:class:`bool`]
+            Whether the thread is locked; when a thread is locked, only users with :attr:`Permissions.manage_threads` can unlock it
+        invitable: Optional[:class:`bool`]
+            Whether non-moderators can add other non-moderators to a thread; only available on private threads
+        slowmode_delay: :Optional[:class:`int`]
+            Amount of seconds a user has to wait before sending another message (0-21600);
+            bots, as well as users with the permission :attr:`Permissions.manage_messages`,
+            :attr:`Permissions.manage_thread`, or :attr:`Permissions.manage_channel`, are unaffected
+        reason: Optional[:class:`str`]
+            The reason for editing the channel. Shows up on the audit log.
 
-        .. describe:: x == y
+        Raises
+        ------
+        InvalidArgument:
+            The ``auto_archive_duration`` is not a valid member of :class:`AutoArchiveDuration`
+        Forbidden:
+            The bot missing permissions to edit the thread or the specific field
+        HTTPException:
+            Editing the thread failed
+
+        Returns
+        -------
+        ThreadChannel:
+            The updated thread on success
+        """
+        payload = {}
+
+        if name is not MISSING:
+            payload['name'] = name
+
+        if archived is not MISSING:
+            payload['archived'] = archived
+
+        if auto_archive_duration is not MISSING:
+            auto_archive_duration = try_enum(AutoArchiveDuration, auto_archive_duration)
+            if not isinstance(auto_archive_duration, AutoArchiveDuration):
+                raise InvalidArgument('%s is not a valid auto_archive_duration' % auto_archive_duration)
+            else:
+                payload['auto_archive_duration'] = auto_archive_duration.value
+
+        if locked is not MISSING:
+            payload['locked'] = locked
+
+        if invitable is not MISSING:
+            payload['invitable'] = invitable
+
+        if slowmode_delay is not MISSING:
+            payload['rate_limit_per_user'] = slowmode_delay
+
+        data = await self._state.http.edit_channel(self.id, reason=reason, **payload)
+        self._update(self.guild, data)
+        return self
+
+    async def delete_messages(self, messages: Iterable[Message], *, reason: Optional[str] = None) -> None:
+        """|coro|
+
+        Deletes a list of messages. This is similar to :meth:`Message.delete`
+        except it bulk deletes multiple messages.
+
+        As a special case, if the number of messages is 0, then nothing
+        is done. If the number of messages is 1 then single message
+        delete is done. If it's more than two, then bulk delete is used.
+
+        You cannot bulk delete more than 100 messages or messages that
+        are older than 14 days old.
+
+        You must have the :attr:`~Permissions.manage_messages` permission to
+        use this.
+
+        Usable only by bot accounts.
+
+        Parameters
+        -----------
+        messages: Iterable[:class:`abc.Snowflake`]
+            An iterable of messages denoting which ones to bulk delete.
+        reason: Optional[:class:`str`]
+            The reason for deleting these messages. Shows up on the audit log.
+
+        Raises
+        ------
+        ClientException
+            The number of messages to delete was more than 100.
+        Forbidden
+            You do not have proper permissions to delete the messages or
+            you're not using a bot account.
+        NotFound
+            If single delete, then the message was already deleted.
+        HTTPException
+            Deleting the messages failed.
+        """
+        if not isinstance(messages, (list, tuple)):
+            messages = list(messages)
+
+        if len(messages) == 0:
+            return # do nothing
+
+        if len(messages) == 1:
+            message_id = messages[0].id
+            await self._state.http.delete_message(self.id, message_id)
+            return
+
+        if len(messages) > 100:
+            raise ClientException('Can only bulk delete messages up to 100 messages')
+
+        message_ids = [m.id for m in messages]
+        await self._state.http.delete_messages(self.id, message_ids, reason=reason)
+
+    async def purge(
+            self,
+            *,
+            limit: Optional[int] = 100,
+            check: Callable = None,
+            before: Optional[Union[abc.Snowflake, datetime.datetime]] = None,
+            after: Optional[Union[abc.Snowflake, datetime.datetime]] = None,
+            around: Optional[Union[abc.Snowflake, datetime.datetime]] = None,
+            oldest_first: Optional[bool] = False,
+            bulk: Optional[bool] = True,
+            reason: Optional[str] = None
+    ) -> List[Message]:
+        """|coro|
+
+        Purges a list of messages that meet the criteria given by the predicate
+        ``check``. If a ``check`` is not provided then all messages are deleted
+        without discrimination.
+
+        You must have the :attr:`~Permissions.manage_messages` permission to
+        delete messages even if they are your own (unless you are a user
+        account). The :attr:`~Permissions.read_message_history` permission is
+        also needed to retrieve message history.
+
+        Internally, this employs a different number of strategies depending
+        on the conditions met such as if a bulk delete is possible or if
+        the account is a user bot or not.
+
+        Examples
+        ---------
+
+        Deleting bot's messages ::
+
+            def is_me(m):
+                return m.author == client.user
+
+            deleted = await channel.purge(limit=100, check=is_me)
+            await channel.send('Deleted {} message(s)'.format(len(deleted)))
+
+        Parameters
+        -----------
+        limit: Optional[:class:`int`]
+            The number of messages to search through. This is not the number
+            of messages that will be deleted, though it can be.
+        check: Callable[[:class:`Message`], :class:`bool`]
+            The function used to check if a message should be deleted.
+            It must take a :class:`Message` as its sole parameter.
+        before: Optional[Union[:class:`abc.Snowflake`, :class:`datetime.datetime`]]
+            Same as ``before`` in :meth:`history`.
+        after: Optional[Union[:class:`abc.Snowflake`, :class:`datetime.datetime`]]
+            Same as ``after`` in :meth:`history`.
+        around: Optional[Union[:class:`abc.Snowflake`, :class:`datetime.datetime`]]
+            Same as ``around`` in :meth:`history`.
+        oldest_first: Optional[:class:`bool`]
+            Same as ``oldest_first`` in :meth:`history`.
+        bulk: :class:`bool`
+            If ``True``, use bulk delete. Setting this to ``False`` is useful for mass-deleting
+            a bot's own messages without :attr:`Permissions.manage_messages`. When ``True``, will
+            fall back to single delete if current account is a user bot (now deprecated), or if messages are
+            older than two weeks.
+        reason: Optional[:class:`str`]
+            The reason for deleting the messages. Shows up on the audit log.
+
+        Raises
+        -------
+        Forbidden
+            You do not have proper permissions to do the actions required.
+        HTTPException
+            Purging the messages failed.
+
+        Returns
+        --------
+        List[:class:`.Message`]
+            The list of messages that were deleted.
+        """
+
+        if check is None:
+            check = lambda m: True
+
+        iterator = self.history(limit=limit, before=before, after=after, oldest_first=oldest_first, around=around)
+        ret = []
+        count = 0
+
+        minimum_time = int((time.time() - 14 * 24 * 60 * 60) * 1000.0 - 1420070400000) << 22
+        strategy = self.delete_messages if bulk else _single_delete_strategy
+
+        while True:
+            try:
+                msg = await iterator.next()
+            except NoMoreItems:
+                # no more messages to poll
+                if count >= 2:
+                    # more than 2 messages -> bulk delete
+                    to_delete = ret[-count:]
+                    await strategy(to_delete, reason=reason)
+                elif count == 1:
+                    # delete a single message
+                    await ret[-1].delete(reason=reason)
+
+                return ret
+            else:
+                if count == 100:
+                    # we've reached a full 'queue'
+                    to_delete = ret[-100:]
+                    await strategy(to_delete, reason=reason)
+                    count = 0
+                    await asyncio.sleep(1)
+
+                if check(msg):
+                    if msg.id < minimum_time:
+                        # older than 14 days old
+                        if count == 1:
+                            await ret[-1].delete(reason=reason)
+                        elif count >= 2:
+                            to_delete = ret[-count:]
+                            await strategy(to_delete, reason=reason)
+
+                        count = 0
+                        strategy = _single_delete_strategy
+
+                    count += 1
+                    ret.append(msg)
+
+
+class VocalGuildChannel(abc.Connectable, abc.GuildChannel, abc.Messageable):
+    __slots__ = ('name', 'id', 'guild', 'bitrate', 'user_limit', 'icon_emoji',
+                 '_state', 'position', '_overwrites', 'category_id',
+                 'rtc_region', 'slowmode_delay', 'last_message_id',
+                 'nsfw', 'video_quality_mode')
+
+    if TYPE_CHECKING:
+        id: int
+        guild: Guild
+        name: str
+        nsfw: bool
+        slowmode_delay: int
+        position: int
+        icon_emoji: Optional[PartialEmoji]
+        rtc_region: Optional[VoiceRegion]
+        video_quality_mode: VideoQualityMode
+        category_id: Optional[int]
+        bitrate: Optional[int]
+        user_limit: Optional[int]
+        last_message_id: Optional[int]
+
+    def __init__(
+            self,
+            *,
+            state: ConnectionState,
+            guild: Guild,
+            data: Union[VoiceChannelData, StageChannelData]
+    ) -> None:
+        self._state = state
+        self.id = int(data['id'])
+        self._update(guild, data)
+
+    def _get_voice_client_key(self) -> Tuple[int, str]:
+        return self.guild.id, 'guild_id'
+
+    def _get_voice_state_pair(self) -> Tuple[int, int]:
+        return self.guild.id, self.id
+
+    def _update(self, guild: Guild, data: Union[VoiceChannelData, StageChannelData]) -> None:
+        self.guild = guild
+        self.name = data['name']
+        rtc_region = data.get('rtc_region')
+        if rtc_region:
+            self.rtc_region = try_enum(VoiceRegion, rtc_region)
+        self.video_quality_mode = try_enum(VideoQualityMode, data.get('video_quality_mode'))
+        self.category_id = utils._get_as_snowflake(data, 'parent_id')
+        self.position = data['position']
+        self.bitrate = data.get('bitrate')
+        self.user_limit = data.get('user_limit')
+        self.nsfw = data.get('nsfw', False)
+        self.slowmode_delay = data.get('rate_limit_per_user', 0)
+        emoji = data.get('icon_emoji')
+        self.icon_emoji = PartialEmoji.with_state(self._state, animated=False, **emoji) if emoji else None
+        self._fill_overwrites(data)
+
+    @property
+    def _sorting_bucket(self) -> int:
+        return ChannelType.voice.value
+
+    @staticmethod
+    def channel_type() -> ChannelType:
+        return ChannelType.voice
+
+    @property
+    def members(self) -> List[Member]:
+        """List[:class:`Member`]: Returns all members that are currently inside this voice channel."""
+        ret = []
+        for user_id, state in self.guild._voice_states.items():
+            if state.channel and state.channel.id == self.id:
+                member = self.guild.get_member(user_id)
+                if member is not None:
+                    ret.append(member)
+        return ret
+
+    @property
+    def voice_states(self) -> Dict[int, VoiceState]:
+        """Returns a mapping of member IDs who have voice states in this channel.
+
+        .. versionadded:: 1.3
+
+        .. note::
+
+            This function is intentionally low level to replace :attr:`members`
+            when the member cache is unavailable.
+
+        Returns
+        --------
+        Mapping[:class:`int`, :class:`VoiceState`]
+            The mapping of member ID to a voice state.
+        """
+        return {key: value for key, value in self.guild._voice_states.items() if value.channel.id == self.id}
+
+    def is_nsfw(self) -> bool:
+        """:class:`bool`: Checks if the channel is NSFW."""
+        return self.nsfw
+
+    @utils.copy_doc(abc.GuildChannel.permissions_for)
+    def permissions_for(self, member: Member, /) -> Permissions:
+        base = super().permissions_for(member)
+
+        # voice channels cannot be edited by people who can't connect to them,
+        # It also implicitly denies all other voice perms
+        if not base.connect:
+            denied = Permissions.voice()
+            denied.update(manage_channels=True, manage_roles=True)
+            base.value &= ~denied.value
+        return base
+
+    async def delete_messages(self, messages: Iterable[Message], *, reason: Optional[str] = None) -> None:
+        """|coro|
+
+        Deletes a list of messages. This is similar to :meth:`Message.delete`
+        except it bulk deletes multiple messages.
+
+        As a special case, if the number of messages is 0, then nothing
+        is done. If the number of messages is 1 then single message
+        delete is done. If it's more than two, then bulk delete is used.
+
+        You cannot bulk delete more than 100 messages or messages that
+        are older than 14 days old.
+
+        You must have the :attr:`~Permissions.manage_messages` permission to
+        use this.
+
+        Usable only by bot accounts.
+
+        Parameters
+        -----------
+        messages: Iterable[:class:`abc.Snowflake`]
+            An iterable of messages denoting which ones to bulk delete.
+        reason: Optional[:class:`str`]
+            The reason for deleting these messages. Shows up on the audit log.
+
+        Raises
+        ------
+        ClientException
+            The number of messages to delete was more than 100.
+        Forbidden
+            You do not have proper permissions to delete the messages or
+            you're not using a bot account.
+        NotFound
+            If single delete, then the message was already deleted.
+        HTTPException
+            Deleting the messages failed.
+        """
+        if not isinstance(messages, (list, tuple)):
+            messages = list(messages)
+
+        if len(messages) == 0:
+            return # do nothing
+
+        if len(messages) == 1:
+            message_id = messages[0].id
+            await self._state.http.delete_message(self.id, message_id)
+            return
+
+        if len(messages) > 100:
+            raise ClientException('Can only bulk delete messages up to 100 messages')
+
+        message_ids = [m.id for m in messages]
+        await self._state.http.delete_messages(self.id, message_ids, reason=reason)
+
+    async def purge(
+            self,
+            *,
+            limit: Optional[int] = 100,
+            check: Callable = None,
+            before: Optional[Union[abc.Snowflake, datetime.datetime]] = None,
+            after: Optional[Union[abc.Snowflake, datetime.datetime]] = None,
+            around: Optional[Union[abc.Snowflake, datetime.datetime]] = None,
+            oldest_first: Optional[bool] = False,
+            bulk: Optional[bool] = True,
+            reason: Optional[str] = None
+    ) -> List[Message]:
+        """|coro|
+
+        Purges a list of messages that meet the criteria given by the predicate
+        ``check``. If a ``check`` is not provided then all messages are deleted
+        without discrimination.
+
+        You must have the :attr:`~Permissions.manage_messages` permission to
+        delete messages even if they are your own (unless you are a user
+        account). The :attr:`~Permissions.read_message_history` permission is
+        also needed to retrieve message history.
+
+        Internally, this employs a different number of strategies depending
+        on the conditions met such as if a bulk delete is possible or if
+        the account is a user bot or not.
+
+        Examples
+        ---------
+
+        Deleting bot's messages ::
+
+            def is_me(m):
+                return m.author == client.user
+
+            deleted = await channel.purge(limit=100, check=is_me)
+            await channel.send('Deleted {} message(s)'.format(len(deleted)))
+
+        Parameters
+        -----------
+        limit: Optional[:class:`int`]
+            The number of messages to search through. This is not the number
+            of messages that will be deleted, though it can be.
+        check: Callable[[:class:`Message`], :class:`bool`]
+            The function used to check if a message should be deleted.
+            It must take a :class:`Message` as its sole parameter.
+        before: Optional[Union[:class:`abc.Snowflake`, :class:`datetime.datetime`]]
+            Same as ``before`` in :meth:`history`.
+        after: Optional[Union[:class:`abc.Snowflake`, :class:`datetime.datetime`]]
+            Same as ``after`` in :meth:`history`.
+        around: Optional[Union[:class:`abc.Snowflake`, :class:`datetime.datetime`]]
+            Same as ``around`` in :meth:`history`.
+        oldest_first: Optional[:class:`bool`]
+            Same as ``oldest_first`` in :meth:`history`.
+        bulk: :class:`bool`
+            If ``True``, use bulk delete. Setting this to ``False`` is useful for mass-deleting
+            a bot's own messages without :attr:`Permissions.manage_messages`. When ``True``, will
+            fall back to single delete if current account is a user bot (now deprecated), or if messages are
+            older than two weeks.
+        reason: Optional[:class:`str`]
+            The reason for deleting the messages. Shows up on the audit log.
+
+        Raises
+        -------
+        Forbidden
+            You do not have proper permissions to do the actions required.
+        HTTPException
+            Purging the messages failed.
+
+        Returns
+        --------
+        List[:class:`.Message`]
+            The list of messages that were deleted.
+        """
+
+        if check is None:
+            check = lambda m: True
+
+        iterator = self.history(limit=limit, before=before, after=after, oldest_first=oldest_first, around=around)
+        ret = []
+        count = 0
+
+        minimum_time = int((time.time() - 14 * 24 * 60 * 60) * 1000.0 - 1420070400000) << 22
+        strategy = self.delete_messages if bulk else _single_delete_strategy
+
+        while True:
+            try:
+                msg = await iterator.next()
+            except NoMoreItems:
+                # no more messages to poll
+                if count >= 2:
+                    # more than 2 messages -> bulk delete
+                    to_delete = ret[-count:]
+                    await strategy(to_delete, reason=reason)
+                elif count == 1:
+                    # delete a single message
+                    await ret[-1].delete(reason=reason)
+
+                return ret
+            else:
+                if count == 100:
+                    # we've reached a full 'queue'
+                    to_delete = ret[-100:]
+                    await strategy(to_delete, reason=reason)
+                    count = 0
+                    await asyncio.sleep(1)
+
+                if check(msg):
+                    if msg.id < minimum_time:
+                        # older than 14 days old
+                        if count == 1:
+                            await ret[-1].delete(reason=reason)
+                        elif count >= 2:
+                            to_delete = ret[-count:]
+                            await strategy(to_delete, reason=reason)
+
+                        count = 0
+                        strategy = _single_delete_strategy
+
+                    count += 1
+                    ret.append(msg)
+
+    async def webhooks(self) -> List[Webhook]:
+        """|coro|
+
+        Gets the list of webhooks from this channel.
+
+        Requires :attr:`~.Permissions.manage_webhooks` permissions.
+
+        Raises
+        -------
+        Forbidden
+            You don't have permissions to get the webhooks.
+
+        Returns
+        --------
+        List[:class:`Webhook`]
+            The webhooks for this channel.
+        """
+
+        from .webhook import Webhook
+        data = await self._state.http.channel_webhooks(self.id)
+        return [Webhook.from_state(d, state=self._state) for d in data]
+
+    async def create_webhook(
+            self,
+            *,
+            name: str,
+            avatar: Optional[bytes] = None,
+            reason: Optional[str] = None
+    ) -> Webhook:
+        """|coro|
+
+        Creates a webhook for this channel.
+
+        Requires :attr:`~.Permissions.manage_webhooks` permissions.
+
+        .. versionchanged:: 1.1
+            Added the ``reason`` keyword-only parameter.
+
+        Parameters
+        -------------
+        name: :class:`str`
+            The webhook's name.
+        avatar: Optional[:class:`bytes`]
+            A :term:`py:bytes-like object` representing the webhook's default avatar.
+            This operates similarly to :meth:`~ClientUser.edit`.
+        reason: Optional[:class:`str`]
+            The reason for creating this webhook. Shows up in the audit logs.
+
+        Raises
+        -------
+        HTTPException
+            Creating the webhook failed.
+        Forbidden
+            You do not have permissions to create a webhook.
+
+        Returns
+        --------
+        :class:`Webhook`
+            The created webhook.
+        """
+
+        from .webhook import Webhook
+        if avatar is not None:
+            avatar = utils._bytes_to_base64_data(avatar)
+
+        data = await self._state.http.create_webhook(self.id, name=name, avatar=avatar, reason=reason)
+        return Webhook.from_state(data, state=self._state)
+
+
+
+class VoiceChannel(VocalGuildChannel, abc.Messageable):
+    """Represents a Discord guild voice channel.
+
+    .. container:: operations
+
+        .. describe:: x == y
+
+            Checks if two channels are equal.
+
+        .. describe:: x != y
+
+            Checks if two channels are not equal.
+
+        .. describe:: hash(x)
+
+            Returns the channel's hash.
+
+        .. describe:: str(x)
+
+            Returns the channel's name.
+
+    Attributes
+    -----------
+    name: :class:`str`
+        The channel name.
+    guild: :class:`Guild`
+        The guild the channel belongs to.
+    id: :class:`int`
+        The channel ID.
+    category_id: Optional[:class:`int`]
+        The category channel ID this channel belongs to, if applicable.
+    position: :class:`int`
+        The position in the channel list. This is a number that starts at 0. e.g. the
+        top channel is position 0.
+    icon_emoji: Optional[:class:`PartialEmoji`]
+        The channel's icon-emoji, if set.
+    bitrate: :class:`int`
+        The channel's preferred audio bitrate in bits per second.
+    user_limit: :class:`int`
+        The channel's limit for number of members that can be in a voice channel.
+    rtc_region: Optional[:class:`VoiceRegion`]
+        The region for the voice channel's voice communication.
+        A value of ``None`` indicates automatic voice region detection.
+
+        .. versionadded:: 1.7
+    slowmode_delay: :class:`int`
+        The channel's slowmode delay in seconds. A value of ``0`` indicates that slowmode is disabled.
+
+        .. versionadded:: 2.0
+    nsfw: :class:`bool`
+        Whether the channel is marked as NSFW.
+
+        .. versionadded:: 2.0
+    """
+
+    __slots__ = ('last_message_id', '_status')
+
+    def __init__(self, *, state: ConnectionState, guild: Guild, data: VoiceChannelData) -> None:
+        super().__init__(state=state, guild=guild, data=data)
+        self._status: Optional[str] = data.get('status')
+
+    def __repr__(self) -> str:
+        attrs = [
+            ('id', self.id),
+            ('name', self.name),
+            ('rtc_region', self.rtc_region),
+            ('position', self.position),
+            ('bitrate', self.bitrate),
+            ('user_limit', self.user_limit),
+            ('category_id', self.category_id)
+        ]
+        return '<%s %s>' % (self.__class__.__name__, ' '.join('%s=%r' % t for t in attrs))
+
+    @staticmethod
+    def channel_type() -> ChannelType:
+        return ChannelType.voice
+
+    async def _get_channel(self) -> VoiceChannel:
+        return self
+
+    @property
+    def type(self) -> ChannelType:
+        """:class:`ChannelType`: The channel's Discord type."""
+        return ChannelType.voice
+
+    @property
+    def status(self) -> Optional[str]:
+        """Optional[:class:`str`]: The current channel "status" (0-500 characters) if any."""
+        return self._status
+
+    @utils.copy_doc(abc.GuildChannel.clone)
+    async def clone(self, *, name: Optional[str] = None, reason: Optional[str] = None) -> VoiceChannel:
+        return await self._clone_impl({
+            'nsfw': self.nsfw,
+            'rtc_region': self.rtc_region,
+            # The API gives me a 500 error when I try to clone the icon emoji, so we leave it out for now
+            # 'icon_emoji': self.icon_emoji.to_dict() if self.icon_emoji else None,
+            'bitrate': self.bitrate,
+            'user_limit': self.user_limit,
+            'rate_limit_per_user': self.slowmode_delay,
+        }, name=name, reason=reason)
+
+    async def edit(self, *, reason: Optional[str] = None, **options):
+        """|coro|
+
+        Edits the channel.
+
+        You must have the :attr:`~Permissions.manage_channels` permission to
+        use this.
+
+        .. versionchanged:: 1.3
+            The ``overwrites`` keyword-only parameter was added.
+
+        Parameters
+        ----------
+        name: :class:`str`
+            The new channel's name.
+        bitrate: :class:`int`
+            The new channel's bitrate.
+        user_limit: :class:`int`
+            The new channel's user limit.
+        position: :class:`int`
+            The new channel's position.
+        sync_permissions: :class:`bool`
+            Whether to sync permissions with the channel's new or pre-existing
+            category. Defaults to ``False``.
+        category: Optional[:class:`CategoryChannel`]
+            The new category for this channel. Can be ``None`` to remove the
+            category.
+        reason: Optional[:class:`str`]
+            The reason for editing this channel. Shows up on the audit log.
+        overwrites: :class:`dict`
+            A :class:`dict` of target (either a role or a member) to
+            :class:`PermissionOverwrite` to apply to the channel.
+        rtc_region: Optional[:class:`VoiceRegion`]
+            The new region for the voice channel's voice communication.
+            A value of ``None`` indicates automatic voice region detection.
+
+            .. versionadded:: 1.7
+        slowmode_delay: :class:`int`
+            The new slowmode delay for this channel in seconds. A value of ``0`` disables slowmode.
+
+            .. versionadded:: 2.0
+        nsfw: :class:`bool`
+            Whether the channel is NSFW. This can only be set by guild administrators.
+        icon_emoji: Optional[:class:`PartialEmoji`]
+            The channels new icon-emoji.
+            **Note that custom emojis are only allowed when the guild has boost level 2 or higher.**
+
+        Raises
+        ------
+        InvalidArgument
+            If the permission overwrite information is not in proper form.
+        Forbidden
+            You do not have permissions to edit the channel.
+        HTTPException
+            Editing the channel failed.
+        """
+
+        await self._edit(options, reason=reason)
+
+    # TODO: Add/remove this when we got a statement from Discord why bots can't set the channel status
+    # async def set_status(self, status: Optional[str], reason: Optional[str] = None) -> None:
+    #     """|coro|
+    #
+    #     Sets the channels status (for example the current conversation topic or game being played).
+    #     This requires being connected to the voice channel.
+    #
+    #     Parameters
+    #     ----------
+    #     status: Optional[:class:`str`]
+    #         The new status of the channel. Pass ``None`` to remove the status.
+    #     reason: Optional[:class:`str`] = None
+    #         The reason for editing this channel. Shows up on the audit log.
+    #
+    #     Raises
+    #     ------
+    #     Forbidden
+    #         You do not have permissions to edit the channel.
+    #     HTTPException
+    #         Editing the channel status failed.
+    #     """
+    #
+    #     await self._state.http.set_voice_channel_status(self.id, status=status, reason=reason)
+
+
+class StageChannel(VocalGuildChannel, abc.Messageable):
+    """Represents a Discord guild stage channel.
+
+    .. versionadded:: 1.7
+
+    .. container:: operations
+
+        .. describe:: x == y
+
+            Checks if two channels are equal.
+
+        .. describe:: x != y
+
+            Checks if two channels are not equal.
+
+        .. describe:: hash(x)
+
+            Returns the channel's hash.
+
+        .. describe:: str(x)
+
+            Returns the channel's name.
+
+    Attributes
+    -----------
+    name: :class:`str`
+        The channel name.
+    guild: :class:`Guild`
+        The guild the channel belongs to.
+    id: :class:`int`
+        The channel ID.
+    topic: Optional[:class:`str`]
+        The channel's topic. ``None`` if it isn't set.
+    icon_emoji: Optional[:class:`PartialEmoji`]
+        The channel's icon-emoji, if set.
+    category_id: Optional[:class:`int`]
+        The category channel ID this channel belongs to, if applicable.
+    position: :class:`int`
+        The position in the channel list. This is a number that starts at 0. e.g. the
+        top channel is position 0.
+    bitrate: :class:`int`
+        The channel's preferred audio bitrate in bits per second.
+    user_limit: :class:`int`
+        The channel's limit for number of members that can be in a stage channel.
+    rtc_region: Optional[:class:`VoiceRegion`]
+        The region for the stage channel's voice communication.
+        A value of ``None`` indicates automatic voice region detection.
+    slowmode_delay: :class:`int`
+        The channel's slowmode delay in seconds. A value of ``0`` indicates that slowmode is disabled.
+
+        .. versionadded:: 2.0
+    nsfw: :class:`bool`
+        Whether the channel is marked as NSFW.
+
+        .. versionadded:: 2.0
+    """
+    __slots__ = ('topic', 'last_message_id')
+
+    def __repr__(self):
+        attrs = [
+            ('id', self.id),
+            ('name', self.name),
+            ('topic', self.topic),
+            ('rtc_region', self.rtc_region),
+            ('position', self.position),
+            ('bitrate', self.bitrate),
+            ('user_limit', self.user_limit),
+            ('category_id', self.category_id)
+        ]
+        return '<%s %s>' % (self.__class__.__name__, ' '.join('%s=%r' % t for t in attrs))
+
+    def _update(self, guild: Guild, data: StageChannelData):
+        super()._update(guild, data)
+        self.topic = data.get('topic')
+
+
+    @staticmethod
+    def channel_type() -> ChannelType:
+        return ChannelType.stage_voice
+
+    async def _get_channel(self) -> StageChannel:
+        return self
+
+    @property
+    def requesting_to_speak(self) -> List[Member]:
+        """List[:class:`Member`]: A list of members who are requesting to speak in the stage channel."""
+        return [member for member in self.members if member.voice.requested_to_speak_at is not None]
+
+    @property
+    def type(self) -> ChannelType:
+        """:class:`ChannelType`: The channel's Discord type."""
+        return ChannelType.stage_voice
+
+    @property
+    def has_instance(self) -> bool:
+        """:class:`bool`: Whether the channel has an associated stage instance."""
+        return self.guild._stage_instances.get(self.id) is not None
+
+    def get_instance(self) -> Optional[StageInstance]:
+        """Optional[:class:`StageInstance`]: Returns the associated stage instance, if any."""
+        return self.guild._stage_instances.get(self.id)
+
+    @utils.copy_doc(abc.GuildChannel.clone)
+    async def clone(self, *, name: Optional[str] = None, reason: Optional[str] = None) -> StageChannel:
+        return await self._clone_impl({
+            'nsfw': self.nsfw,
+            'topic': self.topic,
+            # The API gives me a 500 error when I try to clone the icon emoji, so we leave it out for now
+            # 'icon_emoji': self.icon_emoji.to_dict() if self.icon_emoji else None,
+            'bitrate': self.bitrate,
+            'user_limit': self.user_limit,
+            'rate_limit_per_user': self.slowmode_delay
+        }, name=name, reason=reason)
+
+    async def edit(self, *, reason: Optional[str] = None, **options) -> None:
+        """|coro|
+
+        Edits the channel.
+
+        You must have the :attr:`~Permissions.manage_channels` permission to
+        use this.
+
+        Parameters
+        ----------
+        name: :class:`str`
+            The new channel's name.
+        topic: :class:`str`
+            The new channel's topic.
+        icon_emoji: Optional[:class:`PartialEmoji`]
+            The new channel's icon-emoji.
+            **Note that custom emojis are only allowed when the guild has boost level 2 or higher.**
+        position: :class:`int`
+            The new channel's position.
+        sync_permissions: :class:`bool`
+            Whether to sync permissions with the channel's new or pre-existing
+            category. Defaults to ``False``.
+        category: Optional[:class:`CategoryChannel`]
+            The new category for this channel. Can be ``None`` to remove the
+            category.
+        reason: Optional[:class:`str`]
+            The reason for editing this channel. Shows up on the audit log.
+        overwrites: :class:`dict`
+            A :class:`dict` of target (either a role or a member) to
+            :class:`PermissionOverwrite` to apply to the channel.
+        rtc_region: Optional[:class:`VoiceRegion`]
+            The new region for the stage channel's voice communication.
+            A value of ``None`` indicates automatic voice region detection.
+
+        Raises
+        ------
+        InvalidArgument
+            If the permission overwrite information is not in proper form.
+        Forbidden
+            You do not have permissions to edit the channel.
+        HTTPException
+            Editing the channel failed.
+        """
+
+        await self._edit(options, reason=reason)
+
+    async def start_instance(
+            self,
+            topic: str,
+            send_start_notification: bool = False,
+            *,
+            reason: Optional[str] = None
+    ) -> StageInstance:
+        """|coro|
+        Starts a new stage instance for this stage channel (e.g. make it go live).
+
+        You must have the :attr:`~Permissions.manage_channels` permission to use this.
+
+        Parameters
+        ----------
+        topic: :class:`str`
+            The topic of the stage instance.
+        send_start_notification: :class:`bool`
+            Whether to send a notification to everyone in the guild that the stage is live.
+
+            This requires the :attr:`~Permissions.mention_everyone` permission.
+        reason: Optional[:class:`str`]
+            The reason for starting the stage instance. Shows up on the audit log.
+
+        Raises
+        ------
+        Forbidden
+            You do not have permissions to start the stage instance.
+        HTTPException
+            Starting the stage instance failed.
+
+        Returns
+        -------
+        :class:`StageInstance`
+            The created stage instance.
+        """
+        data = await self._state.http.create_stage_instance(
+            self.id,
+            topic,
+            PrivacyLevel.guild_only,
+            send_start_notification,
+            reason=reason
+        )
+        instance = StageInstance(state=self._state, channel=self, data=data)
+        self.guild._add_stage_instance(instance) # temporary add to cache
+        return instance
+
+
+class StageInstance(Hashable):
+    """Represents a live instance of a :class:`StageChannel`.
+
+    .. versionadded:: 2.0
+
+    Attributes
+    ----------
+    channel: :class:`StageChannel`
+        The stage channel associated with this instance.
+    privacy_level: :class:`PrivacyLevel`
+        The privacy level of the stage instance. (As of now, this is always :attr:`PrivacyLevel.guild_only`.)
+    topic: :class:`str`
+        The topic of the stage instance.
+    guild_id: :class:`int`
+        The guild ID of the stage instance.
+    id: :class:`int`
+        The ID of the stage instance.
+    event_id: Optional[:class:`int`]
+        The ID of the associated guild scheduled event, if any.
+    """
+    __slots__ = ('_state', 'channel', 'privacy_level', 'topic', 'guild_id', 'id', 'event_id')
+
+    if TYPE_CHECKING:
+        privacy_level: PrivacyLevel
+        topic: str
+
+    def __init__(self, *, state: ConnectionState, channel: StageChannel, data: StageInstanceData):
+        self._state: ConnectionState = state
+        self.channel: StageChannel = channel
+        self.guild_id: int = int(data['guild_id'])
+        self.id: int = int(data['id'])
+        self.event_id: Optional[int] = utils._get_as_snowflake(data, 'guild_scheduled_event_id')
+        self._update(data)
+
+    def __repr__(self) -> str:
+        return f'<StageInstance channel={self.channel!r} topic={self.topic!r} privacy_level={self.privacy_level!r}>'
+
+    def _update(self, data: StageInstanceData) -> None:
+        self.privacy_level = try_enum(PrivacyLevel, data['privacy_level'])
+        self.topic = data['topic']
+
+    def created_at(self) -> datetime.datetime:
+        """:class:`datetime.datetime`: Returns the stage instance's creation time in UTC."""
+        return utils.snowflake_time(self.id)
+
+    @property
+    def event(self) -> Optional[GuildScheduledEvent]:
+        """Optional[:class:`GuildScheduledEvent`]: The event associated with this stage instance, if any, and it is cached."""
+        return self.channel.guild.get_event(self.event_id)
+
+    async def edit(
+            self,
+            *,
+            topic: Optional[str] = None,
+            reason: Optional[str] = None
+    ) -> Self:
+        """|coro|
+
+        Edits the stage instance.
+
+        Parameters
+        ----------
+        topic: Optional[:class:`str`]
+            The new topic of the stage instance.
+        reason: Optional[:class:`str`]
+            The reason for editing the stage instance. Shows up on the audit log.
+
+        Raises
+        ------
+        Forbidden
+            You do not have permissions to edit the stage instance.
+        HTTPException
+            Editing the stage instance failed.
+
+        Returns
+        -------
+        :class:`StageInstance`
+            The edited stage instance.
+        """
+        data = await self._state.http.edit_stage_instance(self.channel.id, topic=topic, reason=reason)
+        self._update(data)
+        return self
+
+
+    async def delete(self, *, reason: Optional[str] = None) -> None:
+        """|coro|
+
+        Deletes the stage instance. (Close the stage)
+
+        You must have the :attr:`~Permissions.manage_channels` permission to use this.
+
+        Parameters
+        ----------
+        reason: Optional[:class:`str`]
+            The reason for deleting the stage instance. Shows up on the audit log.
+
+        Raises
+        ------
+        Forbidden
+            You do not have permissions to delete the stage instance.
+        HTTPException
+            Deleting the stage instance failed.
+        """
+        await self._state.http.delete_stage_instance(self.channel.id, reason=reason)
+
+
+class CategoryChannel(abc.GuildChannel, Hashable):
+    """Represents a Discord channel category.
+
+    These are useful to group channels to logical compartments.
+
+    .. container:: operations
+
+        .. describe:: x == y
+
+            Checks if two channels are equal.
+
+        .. describe:: x != y
+
+            Checks if two channels are not equal.
+
+        .. describe:: hash(x)
+
+            Returns the category's hash.
+
+        .. describe:: str(x)
+
+            Returns the category's name.
+
+    Attributes
+    -----------
+    name: :class:`str`
+        The category name.
+    guild: :class:`Guild`
+        The guild the category belongs to.
+    id: :class:`int`
+        The category channel ID.
+    position: :class:`int`
+        The position in the category list. This is a number that starts at 0. e.g. the
+        top category is position 0.
+    """
+
+    __slots__ = ('name', 'id', 'guild', 'nsfw', '_state', 'position', '_overwrites', 'category_id')
+
+    def __init__(self, *, state, guild, data):
+        self._state = state
+        self.id = int(data['id'])
+        self._update(guild, data)
+
+    def __repr__(self):
+        return '<CategoryChannel id={0.id} name={0.name!r} position={0.position} nsfw={0.nsfw}>'.format(self)
+
+    def _update(self, guild, data):
+        self.guild = guild
+        self.name = data['name']
+        self.category_id = utils._get_as_snowflake(data, 'parent_id')
+        self.nsfw = data.get('nsfw', False)
+        self.position = data['position']
+        self._fill_overwrites(data)
+
+    @staticmethod
+    def channel_type():
+        return ChannelType.category
+
+    @property
+    def _sorting_bucket(self):
+        return ChannelType.category.value
+
+    @property
+    def type(self) -> ChannelType:
+        """:class:`ChannelType`: The channel's Discord type."""
+        return ChannelType.category
+
+    @property
+    def jump_url(self) -> str:
+        """:class:`str`: Returns an empty string as you can't jump to a category."""
+        return ''
+
+    def is_nsfw(self) -> bool:
+        """:class:`bool`: Checks if the category is NSFW."""
+        return self.nsfw
+
+    @utils.copy_doc(abc.GuildChannel.clone)
+    async def clone(self, *, name=None, reason=None):
+        return await self._clone_impl({
+            'nsfw': self.nsfw
+        }, name=name, reason=reason)
+
+    async def edit(self, *, reason: Optional[str] = None, **options) -> None:
+        """|coro|
+
+        Edits the channel.
+
+        You must have the :attr:`~Permissions.manage_channels` permission to
+        use this.
+
+        .. versionchanged:: 1.3
+            The ``overwrites`` keyword-only parameter was added.
+
+        Parameters
+        ----------
+        name: :class:`str`
+            The new category's name.
+        position: :class:`int`
+            The new category's position.
+        nsfw: :class:`bool`
+            To mark the category as NSFW or not.
+        reason: Optional[:class:`str`]
+            The reason for editing this category. Shows up on the audit log.
+        overwrites: :class:`dict`
+            A :class:`dict` of target (either a role or a member) to
+            :class:`PermissionOverwrite` to apply to the channel.
+
+        Raises
+        ------
+        InvalidArgument
+            If position is less than 0 or greater than the number of categories.
+        Forbidden
+            You do not have permissions to edit the category.
+        HTTPException
+            Editing the category failed.
+        """
+
+        await self._edit(options=options, reason=reason)
+
+    @overload
+    async def move(
+            self,
+            *,
+            beginning: Literal[True] = ...,
+            end: Literal[False] = ...,
+            before: MSNG = ...,
+            after: MSNG = ...,
+            offset: int = 0,
+            category: None = MISSING,
+            sync_permissions: bool = False,
+            reason: Optional[str] = None
+    ) -> None: ...
+
+    @overload
+    async def move(
+            self,
+            *,
+            beginning: Literal[False] = ...,
+            end: Literal[True] = ...,
+            before: MSNG = ...,
+            after: MSNG = ...,
+            offset: int = 0,
+            category: None = MISSING,
+            sync_permissions: bool = False,
+            reason: Optional[str] = None
+    ) -> None:
+        ...
+
+    @overload
+    async def move(
+            self,
+            *,
+            beginning: Literal[False] = ...,
+            end: Literal[False] = ...,
+            before: abc.Snowflake = ...,
+            after: MSNG = ...,
+            offset: int = 0,
+            category: None = MISSING,
+            sync_permissions: bool = False,
+            reason: Optional[str] = None
+    ) -> None:
+        ...
+
+    @overload
+    async def move(
+            self,
+            *,
+            beginning: Literal[False] = ...,
+            end: Literal[False] = ...,
+            before: MSNG = ...,
+            after: abc.Snowflake = ...,
+            offset: int = 0,
+            category: None = MISSING,
+            sync_permissions: bool = False,
+            reason: Optional[str] = None
+    ) -> None:
+        ...
+
+    @utils.copy_doc(abc.GuildChannel.move)
+    async def move(self, **kwargs):
+        kwargs.pop('category', None)
+        await super().move(**kwargs)
+
+    @property
+    def channels(self):
+        """List[:class:`abc.GuildChannel`]: Returns the channels that are under this category.
+
+        These are sorted by the official Discord UI, which places voice channels below the text channels.
+        """
+        def comparator(channel):
+            return (
+                0 if isinstance(channel, VocalGuildChannel) else 1,
+                *((channel.position,) if hasattr(channel, 'position') else (channel.parent_channel.position, channel.id))
+            )
+
+        ret = [c for c in self.guild.channels if c.category_id == self.id]
+        ret.sort(key=comparator)
+        return ret
+
+    @property
+    def text_channels(self) -> List[TextChannel]:
+        """List[:class:`TextChannel`]: Returns the text channels that are under this category."""
+        ret = [c for c in self.guild.channels
+            if c.category_id == self.id
+            and isinstance(c, TextChannel)]
+        ret.sort(key=lambda c: (c.position, c.id))
+        return ret
+
+    @property
+    def thread_channels(self) -> List[ThreadChannel]:
+        """List[:class:`ThreadChannel`]: Returns the thread channels that are under this category.
+         Only includes public threads and threads that the authorized bot has joined.
+
+         .. note::
+            This also includes forum-posts as they are threads too.
+        """
+        ret = [c for c in self.guild.channels
+            if c.category_id == self.id
+            and isinstance(c, ThreadChannel)]
+        ret.sort(key=lambda c: (c.position, c.id))
+        return ret
+
+    @property
+    def voice_channels(self) -> List[VoiceChannel]:
+        """List[:class:`VoiceChannel`]: Returns the voice channels that are under this category."""
+        ret = [c for c in self.guild.channels
+            if c.category_id == self.id
+            and isinstance(c, VoiceChannel)]
+        ret.sort(key=lambda c: (c.position, c.id))
+        return ret
+
+    @property
+    def stage_channels(self) -> List[StageChannel]:
+        """List[:class:`StageChannel`]: Returns the voice channels that are under this category.
+
+        .. versionadded:: 1.7
+        """
+        ret = [c for c in self.guild.channels
+            if c.category_id == self.id
+            and isinstance(c, StageChannel)]
+        ret.sort(key=lambda c: (c.position, c.id))
+        return ret
+
+    @property
+    def forum_channels(self) -> List[ForumChannel]:
+        """List[:class:`ForumChannel`]: Returns the forum channels that are under this category."""
+        ret = [c for c in self.guild.channels
+               if c.category_id == self.id
+               and isinstance(c, ForumChannel)]
+        ret.sort(key=lambda c: (c.position, c.id))
+        return ret
+
+    async def create_text_channel(
+            self,
+            name: str,
+            *,
+            overwrites: Optional[Dict[abc.Snowflake, PermissionOverwrite]] = None,
+            reason: Optional[str] = None,
+            **options
+    ) -> TextChannel:
+        """|coro|
+
+        A shortcut method to :meth:`Guild.create_text_channel` to create a :class:`TextChannel` in the category.
+
+        Returns
+        -------
+        :class:`TextChannel`
+            The channel that was just created.
+        """
+        return await self.guild.create_text_channel(name, overwrites=overwrites, category=self, reason=reason, **options)
+
+    async def create_voice_channel(
+            self,
+            name: str,
+            *,
+            overwrites: Optional[Dict[abc.Snowflake, PermissionOverwrite]] = None,
+            reason: Optional[str] = None,
+            **options
+    ) -> VoiceChannel:
+        """|coro|
+
+        A shortcut method to :meth:`Guild.create_voice_channel` to create a :class:`VoiceChannel` in the category.
+
+        Returns
+        -------
+        :class:`VoiceChannel`
+            The channel that was just created.
+        """
+        return await self.guild.create_voice_channel(name, overwrites=overwrites, category=self, reason=reason, **options)
+
+    async def create_stage_channel(
+            self,
+            name: str,
+            *,
+            overwrites: Optional[Dict[abc.Snowflake, PermissionOverwrite]] = None,
+            reason: Optional[str] = None,
+            **options
+    ) -> StageChannel:
+        """|coro|
+
+        A shortcut method to :meth:`Guild.create_stage_channel` to create a :class:`StageChannel` in the category.
+
+        .. versionadded:: 1.7
+
+        Returns
+        -------
+        :class:`StageChannel`
+            The channel that was just created.
+        """
+        return await self.guild.create_stage_channel(name, overwrites=overwrites, category=self, reason=reason, **options)
+
+    async def create_forum_channel(
+            self,
+            name: str,
+            *,
+            topic: Optional[str] = None,
+            slowmode_delay: Optional[int] = None,
+            default_post_slowmode_delay: Optional[int] = None,
+            default_auto_archive_duration: Optional[AutoArchiveDuration] = None,
+            overwrites: Optional[Dict[abc.Snowflake, PermissionOverwrite]] = None,
+            nsfw: Optional[bool] = None,
+            position: Optional[int] = None,
+            reason: Optional[str] = None
+    ) -> ForumChannel:
+        """|coro|
+
+        A shortcut method to :meth:`Guild.create_forum_channel` to create a :class:`ForumChannel` in the category.
+
+        Returns
+        -------
+        :class:`ForumChannel`
+            The channel that was just created
+        """
+        return await self.guild.create_forum_channel(
+            name=name,
+            topic=topic,
+            slowmode_delay=slowmode_delay,
+            default_post_slowmode_delay=default_post_slowmode_delay,
+            default_auto_archive_duration=default_auto_archive_duration,
+            overwrites=overwrites,
+            nsfw=nsfw,
+            position=position,
+            reason=reason
+        )
+
+
+class DMChannel(abc.Messageable, Hashable):
+    """Represents a Discord direct message channel.
+
+    .. container:: operations
+
+        .. describe:: x == y
+
+            Checks if two channels are equal.
+
+        .. describe:: x != y
+
+            Checks if two channels are not equal.
+
+        .. describe:: hash(x)
+
+            Returns the channel's hash.
+
+        .. describe:: str(x)
+
+            Returns a string representation of the channel
+
+    Attributes
+    ----------
+    recipient: :class:`User`
+        The user you are participating with in the direct message channel.
+    me: :class:`ClientUser`
+        The user presenting yourself.
+    id: :class:`int`
+        The direct message channel ID.
+    """
+
+    __slots__ = ('id', 'recipient', 'last_message_id', 'me', '_state')
+
+    def __init__(self, *, me: ClientUser, state: ConnectionState, data: DMChannelData) -> None:
+        self._state: ConnectionState = state
+        self.recipient = state.store_user(data['recipients'][0])
+        self.me: ClientUser = me
+        self.id: int = int(data['id'])
+
+    async def _get_channel(self) -> DMChannel:
+        return self
+
+    def __str__(self) -> str:
+        return f'Direct Message with {self.recipient}'
+
+    def __repr__(self) -> str:
+        return f'<DMChannel id={self.id} recipient={self.recipient!r}>'
+
+    @staticmethod
+    def channel_type() -> ChannelType:
+        return ChannelType.private
+
+    @property
+    def type(self) -> ChannelType:
+        """:class:`ChannelType`: The channel's Discord type."""
+        return ChannelType.private
+
+    @property
+    def created_at(self) -> datetime.datetime:
+        """:class:`datetime.datetime`: Returns the direct message channel's creation time in UTC."""
+        return utils.snowflake_time(self.id)
+
+    def permissions_for(self, user: Optional[abc.Snowflake] = None) -> Permissions:
+        """Handles permission resolution for a :class:`User`.
+
+        This function is there for compatibility with other channel types.
+
+        Actual direct messages do not really have the concept of permissions.
+
+        This returns all the Text related permissions set to ``True`` except:
+
+        - :attr:`~Permissions.send_tts_messages`: You cannot send TTS messages in a DM.
+        - :attr:`~Permissions.manage_messages`: You cannot delete others messages in a DM.
+
+        Parameters
+        -----------
+        user: :class:`User`
+            The user to check permissions for. This parameter is ignored
+            but kept for compatibility.
+
+        Returns
+        --------
+        :class:`Permissions`
+            The resolved permissions.
+        """
+
+        base = Permissions.text()
+        base.send_tts_messages = False
+        base.manage_messages = False
+        return base
+
+    def get_partial_message(self, message_id: int) -> PartialMessage:
+        """Creates a :class:`PartialMessage` from the message ID.
+
+        This is useful if you want to work with a message and only have its ID without
+        doing an unnecessary API call.
+
+        .. versionadded:: 1.6
+
+        Parameters
+        ------------
+        message_id: :class:`int`
+            The message ID to create a partial message for.
+
+        Returns
+        ---------
+        :class:`PartialMessage`
+            The partial message.
+        """
+
+        from .message import PartialMessage
+        return PartialMessage(channel=self, id=message_id)
+
+
+class GroupChannel(abc.Messageable, Hashable):
+    """Represents a Discord group channel.
+
+    .. container:: operations
+
+        .. describe:: x == y
 
             Checks if two channels are equal.
 
         .. describe:: x != y
 
-            Checks if two channels are not equal.
+            Checks if two channels are not equal.
+
+        .. describe:: hash(x)
+
+            Returns the channel's hash.
+
+        .. describe:: str(x)
+
+            Returns a string representation of the channel
+
+    Attributes
+    ----------
+    recipients: List[:class:`User`]
+        The users you are participating with in the group channel.
+    me: :class:`ClientUser`
+        The user presenting yourself.
+    id: :class:`int`
+        The group channel ID.
+    owner: :class:`User`
+        The user that owns the group channel.
+    icon: Optional[:class:`str`]
+        The group channel's icon hash if provided.
+    name: Optional[:class:`str`]
+        The group channel's name if provided.
+    """
+
+    __slots__ = ('id', 'recipients', 'owner', 'icon', 'name', 'last_message_id', 'me', '_state')
+
+    if TYPE_CHECKING:
+        icon: Optional[str]
+        name: Optional[str]
+        owner: User
+        recipients: List[User]
+
+    def __init__(self, *, me: ClientUser, state: ConnectionState, data: GroupChannelData) -> None:
+        self._state: ConnectionState = state
+        self.id: int = int(data['id'])
+        self.me: ClientUser = me
+        self._update_group(data)
+
+    def _update_group(self, data):
+        owner_id = utils._get_as_snowflake(data, 'owner_id')
+        self.icon = data.get('icon')
+        self.name = data.get('name')
+
+        try:
+            self.recipients = [self._state.store_user(u) for u in data['recipients']]
+        except KeyError:
+            pass
+
+        if owner_id == self.me.id:
+            self.owner = self.me
+        else:
+            self.owner = utils.find(lambda u: u.id == owner_id, self.recipients)
+
+    async def _get_channel(self) -> GroupChannel:
+        return self
+
+    def __str__(self) -> str:
+        if self.name:
+            return self.name
+
+        if len(self.recipients) == 0:
+            return 'Unnamed'
+
+        return ', '.join(map(lambda x: x.name, self.recipients))
+
+    def __repr__(self) -> str:
+        return f'<GroupChannel id={self.id} name={self.name!r}>'
+
+    @staticmethod
+    def channel_type() -> ChannelType:
+        return ChannelType.group
+
+    @property
+    def type(self) -> ChannelType:
+        """:class:`ChannelType`: The channel's Discord type."""
+        return ChannelType.group
+
+    @property
+    def icon_url(self) -> Asset:
+        """:class:`Asset`: Returns the channel's icon asset if available.
+
+        This is equivalent to calling :meth:`icon_url_as` with
+        the default parameters ('webp' format and a size of 1024).
+        """
+        return self.icon_url_as()
+
+    def icon_url_as(
+            self,
+            *,
+            format: Literal['webp', 'jpeg', 'jpg', 'png'] = 'webp',
+            size: int = 1024
+    ) -> Asset:
+        """Returns an :class:`Asset` for the icon the channel has.
+
+        The format must be one of 'webp', 'jpeg', 'jpg' or 'png'.
+        The size must be a power of 2 between 16 and 4096.
+
+        .. versionadded:: 2.0
+
+        Parameters
+        -----------
+        format: :class:`str`
+            The format to attempt to convert the icon to. Defaults to 'webp'.
+        size: :class:`int`
+            The size of the image to display.
+
+        Raises
+        ------
+        InvalidArgument
+            Bad image format passed to ``format`` or invalid ``size``.
+
+        Returns
+        --------
+        :class:`Asset`
+            The resulting CDN asset.
+        """
+        return Asset._from_icon(self._state, self, 'channel', format=format, size=size)
+
+    @property
+    def created_at(self) -> datetime.datetime:
+        """:class:`datetime.datetime`: Returns the channel's creation time in UTC."""
+        return utils.snowflake_time(self.id)
+
+    def permissions_for(self, user: User) -> Permissions:
+        """Handles permission resolution for a :class:`User`.
+
+        This function is there for compatibility with other channel types.
+
+        Actual direct messages do not really have the concept of permissions.
+
+        This returns all the Text related permissions set to ``True`` except:
+
+        - :attr:`~Permissions.send_tts_messages`: You cannot send TTS messages in a DM.
+        - :attr:`~Permissions.manage_messages`: You cannot delete others messages in a DM.
+
+        This also checks the kick_members permission if the user is the owner.
+
+        Parameters
+        -----------
+        user: :class:`User`
+            The user to check permissions for.
+
+        Returns
+        --------
+        :class:`Permissions`
+            The resolved permissions for the user.
+        """
+
+        base = Permissions.text()
+        base.send_tts_messages = False
+        base.manage_messages = False
+        base.mention_everyone = True
+
+        if user.id == self.owner.id:
+            base.kick_members = True
+
+        return base
+
+    @utils.deprecated()
+    async def add_recipients(self, *recipients):
+        r"""|coro|
+
+        Adds recipients to this group.
+
+        A group can only have a maximum of 10 members.
+        Attempting to add more ends up in an exception. To
+        add a recipient to the group, you must have a relationship
+        with the user of type :attr:`RelationshipType.friend`.
+
+        .. deprecated:: 1.7
+
+        Parameters
+        -----------
+        \*recipients: :class:`User`
+            An argument list of users to add to this group.
+
+        Raises
+        -------
+        HTTPException
+            Adding a recipient to this group failed.
+        """
+
+        # TODO: wait for the corresponding WS event
+
+        req = self._state.http.add_group_recipient
+        for recipient in recipients:
+            await req(self.id, recipient.id)
+
+    @utils.deprecated()
+    async def remove_recipients(self, *recipients):
+        r"""|coro|
+
+        Removes recipients from this group.
+
+        .. deprecated:: 1.7
+
+        Parameters
+        -----------
+        \*recipients: :class:`User`
+            An argument list of users to remove from this group.
+
+        Raises
+        -------
+        HTTPException
+            Removing a recipient from this group failed.
+        """
+
+        # TODO: wait for the corresponding WS event
+
+        req = self._state.http.remove_group_recipient
+        for recipient in recipients:
+            await req(self.id, recipient.id)
+
+    @utils.deprecated()
+    async def edit(self, **fields):
+        """|coro|
+
+        Edits the group.
+
+        .. deprecated:: 1.7
+
+        Parameters
+        -----------
+        name: Optional[:class:`str`]
+            The new name to change the group to.
+            Could be ``None`` to remove the name.
+        icon: Optional[:class:`bytes`]
+            A :term:`py:bytes-like object` representing the new icon.
+            Could be ``None`` to remove the icon.
+
+        Raises
+        -------
+        HTTPException
+            Editing the group failed.
+        """
+
+        try:
+            icon_bytes = fields['icon']
+        except KeyError:
+            pass
+        else:
+            if icon_bytes is not None:
+                fields['icon'] = utils._bytes_to_base64_data(icon_bytes)
+
+        data = await self._state.http.edit_group(self.id, **fields)
+        self._update_group(data)
+
+    async def leave(self):
+        """|coro|
+
+        Leave the group.
+
+        If you are the only one in the group, this deletes it as well.
+
+        Raises
+        -------
+        HTTPException
+            Leaving the group failed.
+        """
 
-        .. describe:: hash(x)
+        await self._state.http.leave_group(self.id)
 
-            Returns the channel's hash.
 
-        .. describe:: str(x)
+class ForumPost(ThreadChannel):
+    """
+    Represents a post in a :class:`ForumChannel`, this is very similar to a :class:`ThreadChannel`
 
-            Returns the channel's name.
+    .. versionadded:: 2.0
 
     Attributes
-    -----------
-    name: :class:`str`
-        The channel name.
+    ----------
     guild: :class:`Guild`
-        The guild the channel belongs to.
+        The guild this post belongs to
     id: :class:`int`
-        The channel ID.
-    category_id: :class:`int`
-        The category channel ID this channel belongs to.
-    position: :class:`int`
-        The position in the channel list. This is a number that starts at 0. e.g. the
-        top channel is position 0.
+        The ID of the post
     """
-    __slots__ = ('name', 'id', 'guild', '_state', 'nsfw',
-                 'category_id', 'position', '_overwrites',)
-
-    def __init__(self, *, state, guild, data):
-        self._state = state
-        self.id = int(data['id'])
-        self._update(guild, data)
+    def __init__(self, *, state, guild, data: dict) -> None:
+        super().__init__(state=state, guild=guild, data=data)
+        self._state: ConnectionState = state
+        self._applied_tags: utils.SnowflakeList = utils.SnowflakeList(map(int, data.get("applied_tags",[])))
 
-    def __repr__(self):
-        return '<StoreChannel id={0.id} name={0.name!r} position={0.position} nsfw={0.nsfw}>'.format(self)
 
-    def _update(self, guild, data):
-        self.guild = guild
-        self.name = data['name']
-        self.category_id = utils._get_as_snowflake(data, 'parent_id')
-        self.position = data['position']
-        self.nsfw = data.get('nsfw', False)
-        self._fill_overwrites(data)
+    @staticmethod
+    def channel_type():
+        return ChannelType.public_thread
 
-    @property
-    def _sorting_bucket(self):
-        return ChannelType.text.value
+    def _update(self, guild, data) -> ForumPost:
+        try:
+            self._applied_tags = utils.SnowflakeList(map(int, data['applied_tags']))
+        except KeyError:
+            pass
+        super()._update(guild, data)
+        return self
 
     @property
-    def type(self):
-        """:class:`ChannelType`: The channel's Discord type."""
-        return ChannelType.store
-
-    @utils.copy_doc(discord.abc.GuildChannel.permissions_for)
-    def permissions_for(self, member):
-        base = super().permissions_for(member)
-
-        # store channels do not have voice related permissions
-        denied = Permissions.voice()
-        base.value &= ~denied.value
-        return base
+    def applied_tags(self) -> List[ForumTag]:
+        """List[:class:`ForumTag`]: Returns a list of tags applied to this post."""
+        tags = []
+        for tag_id in self._applied_tags:
+            tags.append(self.parent_channel.get_tag(tag_id))
+        return tags
+
+    async def edit_tags(self, *tags: ForumTag) -> ForumPost:
+        """|coro|
 
-    def is_nsfw(self):
-        """:class:`bool`: Checks if the channel is NSFW."""
-        return self.nsfw
+        Edits the tags of the post
 
-    @utils.copy_doc(discord.abc.GuildChannel.clone)
-    async def clone(self, *, name=None, reason=None):
-        return await self._clone_impl({
-            'nsfw': self.nsfw
-        }, name=name, reason=reason)
+        Parameters
+        ----------
+        tags: Tuple[:class:`ForumTag`]
+            Tags to keep as well as new tags to add
 
-    async def edit(self, *, reason=None, **options):
+        Returns
+        -------
+        ForumPost
+            The updated post
+        """
+        return await self.edit(tags=tags)
+
+    async def edit(
+            self,
+            *,
+            name: str = MISSING,
+            tags: Sequence[ForumTag] = MISSING,
+            pinned: bool = MISSING,
+            auto_archive_duration: AutoArchiveDuration = MISSING,
+            archived: bool = MISSING,
+            locked: bool = MISSING,
+            slowmode_delay: int = MISSING,
+            reason: Optional[str] = None
+    ) -> ForumPost:
         """|coro|
 
-        Edits the channel.
-
-        You must have the :attr:`~Permissions.manage_channels` permission to
-        use this.
+        Edits the post, all parameters are optional
 
         Parameters
-        ----------
+        -----------
         name: :class:`str`
-            The new channel name.
-        position: :class:`int`
-            The new channel's position.
-        nsfw: :class:`bool`
-            To mark the channel as NSFW or not.
-        sync_permissions: :class:`bool`
-            Whether to sync permissions with the channel's new or pre-existing
-            category. Defaults to ``False``.
-        category: Optional[:class:`CategoryChannel`]
-            The new category for this channel. Can be ``None`` to remove the
-            category.
+            The new name of the post
+        tags: Sequence[:class:`ForumPost`]
+            Tags to keep as well as new tags to add
+        pinned: :class:`bool`
+            Whether the post is pinned to the top of the parent forum.
+
+            .. note::
+
+                Per forum, only one post can be pinned.
+
+        auto_archive_duration: :class:`AutoArchiveDuration`
+            The new amount of minutes after that the post will stop showing in the channel list
+            after ``auto_archive_duration`` minutes of inactivity.
+        locked: :class:`bool`
+            Whether the post is locked;
+            when a post is locked, only users with :func:~Permissions.manage_threads` permissions can unlock it
+        archived: :class:`bool`
+            Whether the post is archived.
+        slowmode_delay: Optional[:class:`str`]
+            Amount of seconds a user has to wait before sending another message (0-21600);
+            bots, as well as users with the permission manage_messages, manage_thread, or manage_channel, are unaffected
         reason: Optional[:class:`str`]
-            The reason for editing this channel. Shows up on the audit log.
-        overwrites: :class:`dict`
-            A :class:`dict` of target (either a role or a member) to
-            :class:`PermissionOverwrite` to apply to the channel.
-
-            .. versionadded:: 1.3
-
-        Raises
-        ------
-        InvalidArgument
-            If position is less than 0 or greater than the number of channels, or if
-            the permission overwrite information is not in proper form.
-        Forbidden
-            You do not have permissions to edit the channel.
-        HTTPException
-            Editing the channel failed.
+            The reason for editing the post, shows up in the audit log.
         """
-        await self._edit(options, reason=reason)
-
-class DMChannel(discord.abc.Messageable, Hashable):
-    """Represents a Discord direct message channel.
-
-    .. container:: operations
+        payload = {}
 
-        .. describe:: x == y
+        if name is not MISSING:
+            payload[name] = name
 
-            Checks if two channels are equal.
+        if tags is not MISSING:
+            payload['applied_tags'] = [str(tag.id) for tag in tags]
 
-        .. describe:: x != y
+        if pinned is not MISSING:
+            flags = ChannelFlags._from_value(self.flags.value)
+            flags.pinned = pinned
+            payload['flags'] = flags.value
 
-            Checks if two channels are not equal.
+        if auto_archive_duration is not MISSING:
+            auto_archive_duration = try_enum(AutoArchiveDuration, auto_archive_duration)
+            if not isinstance(auto_archive_duration, AutoArchiveDuration):
+                raise InvalidArgument('%s is not a valid auto_archive_duration' % auto_archive_duration)
+            else:
+                payload['auto_archive_duration'] = auto_archive_duration.value
+        
+        if archived is not MISSING:
+            payload['archived'] = archived
+        
+        if locked is not MISSING:
+            payload['locked'] = locked
 
-        .. describe:: hash(x)
+        if slowmode_delay is not MISSING:
+            payload['rate_limit_per_user'] = slowmode_delay
 
-            Returns the channel's hash.
+        data = await self._state.http.edit_channel(self.id, reason=reason, **payload)
+        return self._update(self.guild, data)
 
-        .. describe:: str(x)
 
-            Returns a string representation of the channel
+class ForumTag(Hashable):
+    """
+    Represents a tag in a :class:`ForumChannel`.
+    
+    .. note::
+    
+        The ``id`` and ``guild`` attributes are only available if the instance is not self created.
 
     Attributes
-    ----------
-    recipient: :class:`User`
-        The user you are participating with in the direct message channel.
-    me: :class:`ClientUser`
-        The user presenting yourself.
+    -----------
     id: :class:`int`
-        The direct message channel ID.
+        The ID of the tag
+    guild: :class:`Guild`
+        The guild the tag belongs to.
+    name: :class:`str`
+        The name of the tag.
+    emoji_id: :class:`int`
+        The ID of the custom-emoji the tag uses if any.
+    emoji_name: :class:`str`
+        The default-emoji the tag uses if any.
+    moderated: :class:`bool`
+        Whether only moderators can apply this tag to a post.
     """
+    __slots__ = ('id', 'name', 'moderated', 'emoji_id', 'emoji_name', 'guild', '_state')
+
+    if TYPE_CHECKING:
+        guild: Guild
+        _state: ConnectionState
+        id: int
+        name: str
+        moderated: bool
+        emoji_id: Optional[int]
+        emoji_name: Optional[str]
+
+    def __init__(
+            self,
+            name: str,
+            moderated: bool = False,
+            emoji_id: Optional[int] = None,
+            emoji_name: Optional[str] = None
+    ):
+        self.name = name
+        self.moderated = moderated
+        self.emoji_id = emoji_id
+        self.emoji_name = emoji_name
+
+    def __repr__(self) -> str:
+        attrs = [
+            ('id', self.id),
+            ('name', self.name),
+            ('emoji_id', self.emoji_id),
+            ('emoji_name', self.emoji_name),
+            ('moderated', self.moderated)
+        ]
+        return '<%s %s>' % (self.__class__.__name__, ' '.join('%s=%r' % t for t in attrs))
 
-    __slots__ = ('id', 'recipient', 'me', '_state')
-
-    def __init__(self, *, me, state, data):
-        self._state = state
-        self.recipient = state.store_user(data['recipients'][0])
-        self.me = me
-        self.id = int(data['id'])
-
-    async def _get_channel(self):
-        return self
-
-    def __str__(self):
-        return 'Direct Message with %s' % self.recipient
-
-    def __repr__(self):
-        return '<DMChannel id={0.id} recipient={0.recipient!r}>'.format(self)
+    def __str__(self) -> str:
+        return self.name
 
+    @property
+    def emoji(self) -> Optional[PartialEmoji]:
+        """Optional[:class:`PartialEmoji`]: The emoji that is set for this post, if any"""
+        if not (self.emoji_name or self.emoji_id):
+            return None
+        return PartialEmoji(name=self.emoji_name, id=self.emoji_id)
+    
     @classmethod
-    def _from_message(cls, state, channel_id: int):
+    def _with_state(cls, state: ConnectionState, guild: Guild, data: ForumTagData) -> ForumTag:
         self = cls.__new__(cls)
         self._state = state
-        self.id = channel_id
-        self.recipient = None
-        # state.user won't be None here
-        self.me = state.user  # type: ignore
+        self.guild = guild
+        self.id = int(data['id'])
+        self.name = data['name']
+        self.moderated = data.get('moderated', False)
+        self.emoji_id = utils._get_as_snowflake(data, 'emoji_id')
+        self.emoji_name = data.get('emoji_name')
         return self
 
-    @property
-    def type(self):
-        """:class:`ChannelType`: The channel's Discord type."""
-        return ChannelType.private
-
-    @property
-    def created_at(self):
-        """:class:`datetime.datetime`: Returns the direct message channel's creation time in UTC."""
-        return utils.snowflake_time(self.id)
-
-    def permissions_for(self, user=None):
-        """Handles permission resolution for a :class:`User`.
+    def to_dict(self) -> ForumTagData:
+        base = {
+            'name': self.name,
+            'moderated': self.moderated
+        }
+        if self.emoji_id:
+            base['emoji_id'] = self.emoji_id
+        elif self.emoji_name:
+            base['emoji_name'] = self.emoji_name
+        return base
 
-        This function is there for compatibility with other channel types.
 
-        Actual direct messages do not really have the concept of permissions.
+class ForumChannel(abc.GuildChannel, Hashable):
+    """Represents a forum channel.
 
-        This returns all the Text related permissions set to ``True`` except:
+        .. container:: operations
 
-        - :attr:`~Permissions.send_tts_messages`: You cannot send TTS messages in a DM.
-        - :attr:`~Permissions.manage_messages`: You cannot delete others messages in a DM.
+            .. describe:: x == y
 
-        Parameters
-        -----------
-        user: :class:`User`
-            The user to check permissions for. This parameter is ignored
-            but kept for compatibility.
+                Checks if two channels are equal.
 
-        Returns
-        --------
-        :class:`Permissions`
-            The resolved permissions.
-        """
+            .. describe:: x != y
 
-        base = Permissions.text()
-        base.send_tts_messages = False
-        base.manage_messages = False
-        return base
+                Checks if two channels are not equal.
 
-    def get_partial_message(self, message_id):
-        """Creates a :class:`PartialMessage` from the message ID.
+            .. describe:: hash(x)
 
-        This is useful if you want to work with a message and only have its ID without
-        doing an unnecessary API call.
+                Returns the channel's hash.
 
-        .. versionadded:: 1.6
+            .. describe:: str(x)
 
-        Parameters
-        ------------
-        message_id: :class:`int`
-            The message ID to create a partial message for.
+                Returns the channel's name.
 
-        Returns
-        ---------
-        :class:`PartialMessage`
-            The partial message.
+        Attributes
+        -----------
+        name: :class:`str`
+            The channel name.
+        guild: :class:`Guild`
+            The guild the channel belongs to.
+        id: :class:`int`
+            The channel ID.
+        category_id: Optional[:class:`int`]
+            The category channel ID this channel belongs to, if applicable.
+        topic: Optional[:class:`str`]
+            The channel's topic. ``None`` if it doesn't exist.
+        template: Optional[:class:`str`]
+            The channel's template. ``None`` if it doesn't exist.
+
+            Currently, this field is only available on some selected guilds.
+        icon_emoji: Optional[:class:`PartialEmoji`]
+            The channel's icon-emoji, if set.
+        flags: :class:`ChannelFlags`
+            The channel's flags.
+        default_reaction_emoji: Optional[:class:`PartialEmoji`]
+            The default emoji for reacting to a post in this forum
+        position: :class:`int`
+            The position in the channel list. This is a number that starts at 0. e.g. the
+            top channel is position 0.
+        nsfw: :class:`bool`
+            Whether the channel is marked as NSFW.
+        last_post_id: Optional[:class:`int`]
+            The ID of the last post that was created in this forum, this may
+            *not* point to an existing or valid post.
+        slowmode_delay: :class:`int`
+            The number of seconds a member must wait between sending messages
+            in posts inside this channel. A value of `0` denotes that it is disabled.
+            Bots and users with :attr:`~Permissions.manage_channels` or
+            :attr:`~Permissions.manage_messages` bypass slowmode.
+        post_slowmode_delay: :class:`int`
+            The number of seconds a member must wait between creating new posts.
+        default_auto_archive_duration: :class:`AutoArchiveDuration`
+            The default duration for which threads in this channel are automatically archived.
+        default_sort_order: :class:`PostSortOrder`
+            The default sort order for posts in this channel.
+        default_forum_layout: :class:`ForumLayout`
+            The default layout for posts in this channel.
         """
 
-        from .message import PartialMessage
-        return PartialMessage(channel=self, id=message_id)
-
-class GroupChannel(discord.abc.Messageable, Hashable):
-    """Represents a Discord group channel.
-
-    .. container:: operations
-
-        .. describe:: x == y
+    __slots__ = ('name', 'id', 'guild', 'topic', 'template', 'icon_emoji', '_state', '__deleted',
+                 'nsfw', 'category_id', 'position', 'slowmode_delay', 'post_slowmode_delay',
+                 '_overwrites', '_type', 'last_message_id', 'default_auto_archive_duration',
+                 '_posts', '_tags', 'flags', 'default_reaction_emoji', 'last_post_id',
+                 'default_sort_order', 'default_forum_layout',)
+
+    if TYPE_CHECKING:
+        guild: Guild
+        name: str
+        position: int
+        nsfw: bool
+        flags: ChannelFlags
+        slowmode_delay: int
+        post_slowmode_delay: int
+        default_sort_order: PostSortOrder
+        default_auto_archive_duration: AutoArchiveDuration
+        category_id: Optional[int]
+        topic: Optional[str]
+        icon_emoji: Optional[PartialEmoji]
+        template: Optional[str]
+        default_reaction_emoji: Optional[PartialEmoji]
+        last_message_id: Optional[int]
+
+
+    def __init__(self, *, state: ConnectionState, guild: Guild, data) -> None:
+        self._state: ConnectionState = state
+        self.id: int = int(data['id'])
+        self._type = data["type"]
+        self._posts: Dict[int, ForumPost] = {}
+        self._tags: Dict[int, ForumTag] = {}
+        self.last_post_id: Optional[int] = None
+        self._update(guild, data)
 
-            Checks if two channels are equal.
+    def __repr__(self):
+        attrs = [
+            ('id', self.id),
+            ('name', self.name),
+            ('position', self.position),
+            ('nsfw', self.nsfw),
+            ('category_id', self.category_id)
+        ]
+        return '<%s %s>' % (self.__class__.__name__, ' '.join('%s=%r' % t for t in attrs))
 
-        .. describe:: x != y
+    def __del__(self):
+        if getattr(self, '_ForumChannel__deleted', None) is True:
+            guild = self.guild
+            for post in self.posts:
+                guild._remove_channel(post)
 
-            Checks if two channels are not equal.
+    def _update(self, guild: Guild, data: ForumChannelData):
+        self.guild = guild
+        self.name = data['name']
+        self.position = data['position']
+        self.category_id = utils._get_as_snowflake(data, 'parent_id')
+        self.topic = data.get('topic')
+        self.template = data.get('template') or None
+        emoji = data.get('icon_emoji')
+        self.icon_emoji = PartialEmoji.with_state(self._state, animated=False, **emoji) if emoji else None
+        self.flags = ChannelFlags._from_value(data['flags'])
+        emoji: Optional[DefaultReactionEmoji]  = data.get('default_reaction_emoji')
+        if emoji:
+            self.default_reaction_emoji = PartialEmoji(
+                name=emoji.get('emoji_name'),
+                id=utils._get_as_snowflake(emoji, 'emoji_id')
+            )
+        elif not hasattr(self, 'default_reaction_emoji'):
+            self.default_reaction_emoji = None
+        self.position: int = data['position']
+        self.nsfw: bool = data.get('nsfw', False)
+        # Does this need coercion into `int`? No idea yet.
+        self.slowmode_delay: int = data.get('default_thread_rate_limit_per_user', 0)
+        self.post_slowmode_delay: int = data.get('rate_limit_per_user', 0)
+        self._type = data.get('type', self._type)
+        self.last_post_id: int = utils._get_as_snowflake(data, 'last_message_id')
+        self.default_auto_archive_duration = try_enum(
+            AutoArchiveDuration,
+            data.get('default_auto_archive_duration', 1440)
+        )
+        self.default_sort_order: Optional[PostSortOrder] = try_enum(
+            PostSortOrder, data.get('default_sort_order', 0) or 0
+        )
+        self.default_forum_layout: Optional[ForumLayout] = try_enum(
+            ForumLayout, data.get('default_forum_layout', 0) or 0
+        )
+        self._fill_overwrites(data)
+        self._fill_tags(data)
 
-        .. describe:: hash(x)
+    def _fill_tags(self, data: Dict[str, Any]) -> None:
+        tags = data.get('available_tags', [])
+        guild = self.guild
+        state = self._state
+        for t in tags:
+            self._tags[int(t['id'])] = ForumTag._with_state(state=state, guild=guild, data=t)
 
-            Returns the channel's hash.
+    async def _get_channel(self) -> ForumChannel:
+        return self
 
-        .. describe:: str(x)
+    @property
+    def type(self) -> ChannelType:
+        """:class:`ChannelType`: The channel's type."""
+        return try_enum(ChannelType, self._type)
 
-            Returns a string representation of the channel
+    @staticmethod
+    def channel_type() -> ChannelType:
+        return ChannelType.forum_channel
 
-    Attributes
-    ----------
-    recipients: List[:class:`User`]
-        The users you are participating with in the group channel.
-    me: :class:`ClientUser`
-        The user presenting yourself.
-    id: :class:`int`
-        The group channel ID.
-    owner: :class:`User`
-        The user that owns the group channel.
-    icon: Optional[:class:`str`]
-        The group channel's icon hash if provided.
-    name: Optional[:class:`str`]
-        The group channel's name if provided.
-    """
+    @property
+    def _sorting_bucket(self) -> int:
+        return ChannelType.forum_channel.value
 
-    __slots__ = ('id', 'recipients', 'owner', 'icon', 'name', 'me', '_state')
+    def _add_post(self, post: ForumPost) -> None:
+        self._posts[post.id] = post
 
-    def __init__(self, *, me, state, data):
-        self._state = state
-        self.id = int(data['id'])
-        self.me = me
-        self._update_group(data)
+    def _remove_post(self, post: ForumPost) -> Optional[ForumPost]:
+        return self._posts.pop(post.id, None)
 
-    def _update_group(self, data):
-        owner_id = utils._get_as_snowflake(data, 'owner_id')
-        self.icon = data.get('icon')
-        self.name = data.get('name')
+    def get_post(self, id: int) -> Optional[ForumPost]:
+        """Optional[:class:`ForumPost`]: Returns a post in the forum with the given ID. or None when not found."""
+        return self._posts.get(id, None)
 
-        try:
-            self.recipients = [self._state.store_user(u) for u in data['recipients']]
-        except KeyError:
-            pass
+    @property
+    def posts(self) -> List[ForumPost]:
+        """List[:class:`ForumPost`]: A list of all cached posts in the forum."""
+        return list(self._posts.values())
 
-        if owner_id == self.me.id:
-            self.owner = self.me
-        else:
-            self.owner = utils.find(lambda u: u.id == owner_id, self.recipients)
+    def _add_tag(self, tag: ForumTag) -> None:
+        self._tags[tag.id] = tag
 
-    async def _get_channel(self):
-        return self
+    def _remove_tag(self, tag: ForumTag) -> None:
+        return self._tags.pop(tag.id, None)
 
-    def __str__(self):
-        if self.name:
-            return self.name
+    def get_tag(self, tag_id: int) -> Optional[ForumTag]:
+        """Optional[:class:`ForumTag`]: Returns a tag with the given ID in the forum, or :obj:`None` when not found."""
+        return self._tags.get(tag_id, None)
 
-        if len(self.recipients) == 0:
-            return 'Unnamed'
+    @property
+    def available_tags(self) -> List[ForumTag]:
+        """List[:class:`ForumTag`]: A list of all tags available in the forum."""
+        return list(self._tags.values())
 
-        return ', '.join(map(lambda x: x.name, self.recipients))
+    @utils.copy_doc(abc.GuildChannel.permissions_for)
+    def permissions_for(self, member: Member, /) -> Permissions:
+        base = super().permissions_for(member)
 
-    def __repr__(self):
-        return '<GroupChannel id={0.id} name={0.name!r}>'.format(self)
+        # forum channels do not have voice related permissions
+        denied = Permissions.voice()
+        base.value &= ~denied.value
+        return base
 
     @property
-    def type(self):
-        """:class:`ChannelType`: The channel's Discord type."""
-        return ChannelType.group
+    def members(self) -> List[Member]:
+        """List[:class:`Member`]: Returns all members that can see this channel."""
+        return [m for m in self.guild.members if self.permissions_for(m).read_messages]
+
+    def is_nsfw(self) -> bool:
+        """:class:`bool`: Checks if the channel is NSFW."""
+        return self.nsfw
 
     @property
-    def icon_url(self):
-        """:class:`Asset`: Returns the channel's icon asset if available.
+    def last_post(self) -> Optional[ForumPost]:
+        """Fetches the last post from this channel in cache.
 
-        This is equivalent to calling :meth:`icon_url_as` with
-        the default parameters ('webp' format and a size of 1024).
-        """
-        return self.icon_url_as()
+        The post might not be valid or point to an existing post.
 
-    def icon_url_as(self, *, format='webp', size=1024):
-        """Returns an :class:`Asset` for the icon the channel has.
+        Returns
+        ---------
+        Optional[:class:`ForumPost`]
+            The last post in this channel or :obj:`None` if not found.
+        """
+        return self._posts.get(self.last_post_id) if self.last_post_id else None
+
+    async def edit(
+            self,
+            *,
+            name: str = MISSING,
+            topic: str = MISSING,
+            available_tags: Sequence[ForumTag] = MISSING,
+            tags_required: bool = MISSING,
+            default_post_sort_order: Optional[PostSortOrder] = MISSING,
+            default_forum_layout: Optional[ForumLayout] = MISSING,
+            default_reaction_emoji: Optional[PartialEmoji] = MISSING,
+            position: int = MISSING,
+            nsfw: bool = MISSING,
+            sync_permissions: bool = False,
+            category: Optional[CategoryChannel] = MISSING,
+            slowmode_delay: int = MISSING,
+            post_slowmode_delay: int = MISSING,
+            overwrites: Dict[Union[Member, Role], PermissionOverwrite] = MISSING,
+            icon_emoji: Optional[PartialEmoji] = MISSING,
+            reason: Optional[str] = None
+    ) -> None:
+        """|coro|
 
-        The format must be one of 'webp', 'jpeg', 'jpg' or 'png'.
-        The size must be a power of 2 between 16 and 4096.
+        Edits the channel.
 
-        .. versionadded:: 2.0
+        You must have the :attr:`~Permissions.manage_channels` permission to
+        use this.
 
         Parameters
-        -----------
-        format: :class:`str`
-            The format to attempt to convert the icon to. Defaults to 'webp'.
-        size: :class:`int`
-            The size of the image to display.
+        ----------
+        name: :class:`str`
+            The new channel name.
+        topic: :class:`str`
+            The new channel's topic.
+        available_tags: Sequence[:class:`ForumTag`]
+            An iterable of tags to keep as well of new tags.
+            You can use this to reorder the tags.
+        tags_required: :class:`bool`
+            Whether new created post require at least one tag provided on creation
+        default_post_sort_order: Optional[:class:`PostSortOrder`]
+            How the posts in the forum will be sorted for users by default.
+        default_forum_layout: Optional[:class:`ForumLayout`]
+        	The default forum layout view used to display posts to users.
+        default_reaction_emoji: Optional[:class:`PartialEmoji`]
+            The default emoji used to react to posts in the forum.
+        position: :class:`int`
+            The new channel's position.
+        nsfw: :class:`bool`
+            To mark the channel as NSFW or not.
+        sync_permissions: :class:`bool`
+            Whether to sync permissions with the channel's new or pre-existing
+            category. Defaults to ``False``.
+        category: Optional[:class:`CategoryChannel`]
+            The new category for this channel. Can be ``None`` to remove the
+            category.
+        slowmode_delay: :class:`int`
+            The number of seconds (max. ``21600``) a member must wait between sending messages
+            in posts inside this channel. A value of `0` denotes that it is disabled.
+            Bots and users with :attr:`~Permissions.manage_channels` or
+            :attr:`~Permissions.manage_messages` bypass slowmode.
+        post_slowmode_delay: :class:`int`
+            The number of seconds (max. ``21600``) a member must wait between creating new posts.
+        overwrites: :class:`dict`
+            A :class:`dict` of target (either a role or a member) to
+            :class:`PermissionOverwrite` to apply to the channel.
+        icon_emoji: Optional[:class:`PartialEmoji`]
+            The new icon-emoji for the channel.
+            **Note that setting custom emojis require the guild to have boost level 2 or higher.**
+        reason: Optional[:class:`str`]
+            The reason for editing this channel. Shows up on the audit log.
+
 
         Raises
         ------
         InvalidArgument
-            Bad image format passed to ``format`` or invalid ``size``.
-
-        Returns
-        --------
-        :class:`Asset`
-            The resulting CDN asset.
+            If position is less than 0 or greater than the number of channels, or if
+            the permission overwrite information is not in proper form.
+        Forbidden
+            You do not have permissions to edit the channel.
+        HTTPException
+            Editing the channel failed.
         """
-        return Asset._from_icon(self._state, self, 'channel', format=format, size=size)
+        payload = {}
 
-    @property
-    def created_at(self):
-        """:class:`datetime.datetime`: Returns the channel's creation time in UTC."""
-        return utils.snowflake_time(self.id)
+        if name is not MISSING:
+            payload['name'] = name
 
-    def permissions_for(self, user):
-        """Handles permission resolution for a :class:`User`.
+        if topic is not MISSING:
+            payload['topic'] = topic
 
-        This function is there for compatibility with other channel types.
+        if available_tags is not MISSING:
+            payload['available_tags'] = [tag.to_dict() for tag in available_tags]
 
-        Actual direct messages do not really have the concept of permissions.
+        if tags_required is not MISSING:
+            flags = ChannelFlags._from_value(self.flags.value)
+            flags.require_tags = tags_required
+            payload['flags'] = flags
 
-        This returns all the Text related permissions set to ``True`` except:
+        if default_post_sort_order is not MISSING:
+            payload['default_sort_order'] = default_post_sort_order.value if default_post_sort_order else None
 
-        - :attr:`~Permissions.send_tts_messages`: You cannot send TTS messages in a DM.
-        - :attr:`~Permissions.manage_messages`: You cannot delete others messages in a DM.
+        if default_forum_layout is not MISSING:
+            payload['default_forum_layout'] = default_forum_layout.value if default_forum_layout else None
 
-        This also checks the kick_members permission if the user is the owner.
+        if default_reaction_emoji is not MISSING:
+            payload['default_reaction_emoji'] = default_reaction_emoji.to_dict() if default_reaction_emoji else None
 
-        Parameters
-        -----------
-        user: :class:`User`
-            The user to check permissions for.
+        if position is not MISSING:
+            payload['position'] = position
 
-        Returns
-        --------
-        :class:`Permissions`
-            The resolved permissions for the user.
-        """
+        if nsfw is not MISSING:
+            payload['nsfw'] = nsfw
 
-        base = Permissions.text()
-        base.send_tts_messages = False
-        base.manage_messages = False
-        base.mention_everyone = True
+        if sync_permissions:
+            payload['sync_permissions'] = sync_permissions
 
-        if user.id == self.owner.id:
-            base.kick_members = True
+        if category is not MISSING:
+            payload['category'] = category
 
-        return base
+        if slowmode_delay is not MISSING:
+            payload['default_thread_rate_limit_per_user'] = slowmode_delay
 
-    @utils.deprecated()
-    async def add_recipients(self, *recipients):
-        r"""|coro|
+        if post_slowmode_delay is not MISSING:
+            payload['rate_limit_per_user'] = post_slowmode_delay
 
-        Adds recipients to this group.
+        if overwrites is not MISSING:
+            payload['overwrites'] = overwrites
 
-        A group can only have a maximum of 10 members.
-        Attempting to add more ends up in an exception. To
-        add a recipient to the group, you must have a relationship
-        with the user of type :attr:`RelationshipType.friend`.
+        if icon_emoji is not MISSING:
+            payload['icon_emoji'] = icon_emoji
 
-        .. deprecated:: 1.7
+        return await self._edit(options=payload, reason=reason)
 
-        Parameters
-        -----------
-        \*recipients: :class:`User`
-            An argument list of users to add to this group.
+    @utils.copy_doc(abc.GuildChannel.clone)
+    async def clone(self, *, name: Optional[str] = None, reason: Optional[str] = None) -> ForumChannel:
+        react_emoji = self.default_reaction_emoji
+        if react_emoji and react_emoji.is_unicode_emoji():
+            react_emoji = {'emoji_name': react_emoji.name}
+        elif react_emoji and react_emoji.is_custom_emoji():
+            react_emoji = {'emoji_id': react_emoji.id}
+
+        return await self._clone_impl({
+            'topic': self.topic,
+            'template': self.template,
+            # The API gives me a 500 error when I try to clone the icon emoji, so we leave it out for now
+            # 'icon_emoji': self.icon_emoji.to_dict() if self.icon_emoji else None,
+            'nsfw': self.nsfw,
+            'available_tags': [t.to_dict() for t in self.available_tags],
+            'default_reaction_emoji': react_emoji,
+            'rate_limit_per_user': self.post_slowmode_delay,
+            'default_thread_rate_limit_per_user': self.slowmode_delay,
+            'default_sort_order': self.default_sort_order.value,
+            'default_forum_layout': self.default_forum_layout.value,
+            'default_auto_archive_duration': self.default_auto_archive_duration.value
+        }, name=name, reason=reason)
+
+    async def webhooks(self) -> List[Webhook]:
+        """|coro|
+
+        Gets the list of webhooks from this channel.
+
+        Requires :attr:`~.Permissions.manage_webhooks` permissions.
 
         Raises
         -------
-        HTTPException
-            Adding a recipient to this group failed.
-        """
+        Forbidden
+            You don't have permissions to get the webhooks.
 
-        # TODO: wait for the corresponding WS event
+        Returns
+        --------
+        List[:class:`Webhook`]
+            The webhooks for this channel.
+        """
 
-        req = self._state.http.add_group_recipient
-        for recipient in recipients:
-            await req(self.id, recipient.id)
+        from .webhook import Webhook
+        data = await self._state.http.channel_webhooks(self.id)
+        return [Webhook.from_state(d, state=self._state) for d in data]
 
-    @utils.deprecated()
-    async def remove_recipients(self, *recipients):
-        r"""|coro|
+    async def create_webhook(
+            self,
+            *,
+            name: str,
+            avatar: Optional[bytes] = None,
+            reason: Optional[str] = None
+    ) -> Webhook:
+        """|coro|
 
-        Removes recipients from this group.
+        Creates a webhook for this channel.
 
-        .. deprecated:: 1.7
+        Requires :attr:`~.Permissions.manage_webhooks` permissions.
 
         Parameters
-        -----------
-        \*recipients: :class:`User`
-            An argument list of users to remove from this group.
+        -------------
+        name: :class:`str`
+            The webhook's name.
+        avatar: Optional[:class:`bytes`]
+            A :term:`py:bytes-like object` representing the webhook's default avatar.
+            This operates similarly to :meth:`~ClientUser.edit`.
+        reason: Optional[:class:`str`]
+            The reason for creating this webhook. Shows up in the audit logs.
 
         Raises
         -------
         HTTPException
-            Removing a recipient from this group failed.
+            Creating the webhook failed.
+        Forbidden
+            You do not have permissions to create a webhook.
+
+        Returns
+        --------
+        :class:`Webhook`
+            The created webhook.
         """
 
-        # TODO: wait for the corresponding WS event
+        from .webhook import Webhook
+        if avatar is not None:
+            avatar = utils._bytes_to_base64_data(avatar)
 
-        req = self._state.http.remove_group_recipient
-        for recipient in recipients:
-            await req(self.id, recipient.id)
+        data = await self._state.http.create_webhook(
+            self.id, name=name, avatar=avatar, reason=reason
+        )
+        return Webhook.from_state(data, state=self._state)
 
-    @utils.deprecated()
-    async def edit(self, **fields):
+    async def create_post(
+            self,
+            *,
+            name: str,
+            tags: Optional[List[ForumTag]] = None,
+            content: Any = None,
+            embed: Optional[Embed] = None,
+            embeds: Sequence[Embed] = None,
+            components: Optional[List[Union[ActionRow, List[Union[Button, BaseSelect]]]]] = None,
+            file: Optional[File] = None,
+            files: Sequence[File] = None,
+            allowed_mentions: Optional[AllowedMentions] = None,
+            suppress_embeds: bool = False,
+            supress_notifications: bool = False,
+            auto_archive_duration: Optional[AutoArchiveDuration] = None,
+            slowmode_delay: int = 0,
+            reason: Optional[str] = None
+    ) -> ForumPost:
         """|coro|
 
-        Edits the group.
-
-        .. deprecated:: 1.7
+        Creates a new post in this forum. Requires the :attr:`~Permissions.create_posts` permission.
 
         Parameters
         -----------
-        name: Optional[:class:`str`]
-            The new name to change the group to.
-            Could be ``None`` to remove the name.
-        icon: Optional[:class:`bytes`]
-            A :term:`py:bytes-like object` representing the new icon.
-            Could be ``None`` to remove the icon.
+        name: :class:`str`
+            The name of the post.
+        tags: Optional[List[:class:`ForumTag`]]
+            The list of up to 5 tags that should be added to the post.
+            These tags must be from the parent channel (forum).
+        content: :class:`str`
+            The content of the post starter-message.
+        embed: Optional[:class:`Embed`]
+            A embed of the post starter-message.
+        embeds: List[:class:`Embed`]
+            A list of up to 10 embeds to include in the post starter-message.
+        components: List[Union[:class:`~discord.ActionRow`, List[Union[:class:`~discord.Button`, :ref:`Select <select-like-objects>`]]]]
+            A list of up to five :class:`~discord.ActionRow`s or :class:`list`,
+            each containing up to five :class:`~discord.Button` or one :ref:`Select <select-like-objects>` like object.
+        file: Optional[class:`File`]
+            A file to include in the post starter-message.
+        files: List[:class:`File`]
+            A list of files to include in the post starter-message.
+        allowed_mentions: Optional[:class:`AllowedMentions`]
+            The allowed mentions for the post.
+        suppress_embeds: Optional[:class:`bool`]
+            Whether to suppress embeds in the post starter-message.
+        supress_notifications: Optional[:class:`bool`]
+            Whether to suppress desktop- & push-notifications for the post starter-message.
+            
+            Users will still see a ping-symbol when they are mentioned in the message, or the message is in a dm channel.
+        auto_archive_duration: Optional[:class:`AutoArchiveDuration`]
+            The duration after the post will be archived automatically when inactive.
+        slowmode_delay: Optional[:class:`int`]
+            The amount of seconds a user has to wait before sending another message (0-21600)
+        reason: Optional[:class:`str`]
+            The reason for creating this post. Shows up in the audit logs.
 
         Raises
         -------
-        HTTPException
-            Editing the group failed.
+        :exc:`InvalidArgument`
+            The forum requires ``tags`` on post creation but no tags where provided,
+            or ``name`` is of invalid length,
+            or ``auto_archive_duration`` is not of valid type.
+        :exc:`Forbidden`
+            The bot does not have permissions to create posts in this channel
+        :exe:`HTTPException`
+            Creating the post failed
         """
 
-        try:
-            icon_bytes = fields['icon']
-        except KeyError:
-            pass
-        else:
-            if icon_bytes is not None:
-                fields['icon'] = utils._bytes_to_base64_data(icon_bytes)
+        state = self._state
+        content = str(content) if content is not None else None
 
-        data = await self._state.http.edit_group(self.id, **fields)
-        self._update_group(data)
+        if self.flags.require_tags and not tags:
+            raise InvalidArgument('This forum requires at least one tag provided when creating a post.')
 
-    async def leave(self):
+        if suppress_embeds or supress_notifications:
+            flags = MessageFlags._from_value(0)
+            flags.suppress_embeds = suppress_embeds
+            flags.suppress_notifications = supress_notifications
+        else:
+            flags = MISSING
+
+        if len(name) > 100 or len(name) < 1:
+            raise InvalidArgument('The name of the post must bee between 1-100 characters; got %s' % len(name))
+        if auto_archive_duration:
+            auto_archive_duration = try_enum(AutoArchiveDuration, auto_archive_duration)
+            if not isinstance(auto_archive_duration, AutoArchiveDuration):
+                raise InvalidArgument('%s is not a valid auto_archive_duration' % auto_archive_duration)
+            else:
+                auto_archive_duration = auto_archive_duration.value
+
+        channel_payload = {
+            'name': name,
+            'rate_limit_per_user': slowmode_delay,
+            'auto_archive_duration': auto_archive_duration,
+            'applied_tags': [str(tag.id) for tag in tags] if tags is not None else None
+        }
+
+        with handle_message_parameters(
+            content=content,
+            embed=embed if embed else MISSING,
+            embeds=embeds if embeds else MISSING,
+            components=components if components else MISSING,
+            file=file if file else MISSING,
+            files=files if files else MISSING,
+            flags=flags,
+            allowed_mentions=allowed_mentions,
+            previous_allowed_mentions=state.allowed_mentions,
+            channel_payload=channel_payload,
+        ) as params:
+            data = await state.http.create_post(
+                channel_id=self.id,
+                params=params,
+                reason=reason
+            )
+        post = ForumPost(state=self._state, guild=self.guild, data=data)
+        self._add_post(post)
+        # TODO: wait for ws event
+        return post
+
+    async def archived_posts(
+            self,
+            *,
+            before: Optional[Union[abc.Snowflake, datetime.datetime]] = None,
+            limit: int = 100
+    ) -> ArchivedThreadIterator:
         """|coro|
 
-        Leave the group.
+        Returns an :class:`abc.AsyncIterator` to retrieve archived posts from this channel.
 
-        If you are the only one in the group, this deletes it as well.
+        Parameters
+        ----------
+        before: Optional[Union[:class:`abc.Snowflake`, :class:`datetime.datetime`]]
+            Only fetch posts created before this date or ID.
+        limit: :class:`int`
+            The maximum number of posts to fetch. Defaults to ``100``.
 
         Raises
-        -------
+        ------
+        Forbidden
+            The bot lacks permissions to fetch not-joined private posts.
         HTTPException
-            Leaving the group failed.
-        """
+            Fetching the posts failed.
 
-        await self._state.http.leave_group(self.id)
+        Returns
+        -------
+        :class:`ArchivedThreadIterator`
+            An iterator to retrieve the archived threads.
+        """
+        return ArchivedThreadIterator(
+            channel=self,
+            private=False,
+            joined_private=False,
+            before=before,
+            limit=limit
+        )
 
 
-class PartialMessageable(discord.abc.Messageable, Hashable):
+class PartialMessageable(abc.Messageable, Hashable):
     """Represents a partial messageable to aid with working messageable channels when
-    only a channel ID are present.
+    only a channel ID is present.
+
     The only way to construct this class is through :meth:`Client.get_partial_messageable`.
-    Note that this class is trimmed down and has no rich attributes.
-    .. versionadded:: 2.0
+
+    .. note::
+        This class is trimmed down and has no rich attributes.
+        However, sometimes there might be partial (raw) data available you can access through :attr:`.partial_data`.
+
     .. container:: operations
         .. describe:: x == y
             Checks if two partial messageables are equal.
@@ -1589,31 +4028,104 @@ class PartialMessageable(discord.abc.Messageable, Hashable):
             Checks if two partial messageables are not equal.
         .. describe:: hash(x)
             Returns the partial messageable's hash.
+
     Attributes
     -----------
     id: :class:`int`
         The channel ID associated with this partial messageable.
     type: Optional[:class:`ChannelType`]
         The channel type associated with this partial messageable, if given.
+    guild_id: Optional[:class:`int`]
+        The guild ID associated with this partial messageable, if given.
+    partial_data: Dict[:class:`str`, Any]
+        A dictionary of partial (raw) api data that might be available for this partial messageable.
+
+        .. seealso::
+
+            See discord api docs :ddocs:`channel object <resources/channel#channel-object>` for more information.
     """
 
-    def __init__(self, state: 'ConnectionState', id: int, type: Optional[ChannelType] = None):
+    @property
+    def is_partial(self) -> bool:
+        """:class:`bool`: Returns ``True`` for this class."""
+        return True
+
+    def __init__(
+            self,
+            state: ConnectionState,
+            id: int,
+            type: Optional[ChannelType] = None,
+            *,
+            guild_id: int = None,
+            partial_data: Dict[str, Any] = {},
+    ):
         self._state: ConnectionState = state
-        self._channel: Object = Object(id=id)
         self.id: int = id
+        self.guild_id: Optional[int] = guild_id
         self.type: Optional[ChannelType] = type
+        self.partial_data: Dict[str, Any] = partial_data
+    
+    def __repr__(self) -> str:
+        return f'<PartialMessageable id={self.id} type={self.type!r}{f" guild_id={self.guild_id}" if self.guild_id else ""}>'
+
+    async def _get_channel(self) -> PartialMessageable:
+        return self
+
+    @property
+    def guild(self) -> Optional[Guild]:
+        """Optional[:class:`~discord.Guild`]: The guild this partial messageable belongs to if any."""
+        return self._state._get_guild(self.guild_id)
+
+    @property
+    def jump_url(self) -> str:
+        """:class:`str`: Returns an url that allows the client to jump to the partial messageable (channel)"""
+        if self.guild_id:
+            return f'https://discord.com/channels/{self.guild_id}/{self.id}'
+        return f'https://discord.com/channels/@me/{self.id}'
+
+    @property
+    def mention(self) -> str:
+        """:class:`str`: Returns a string that allows the client to mention the channel"""
+        return f'<#{self.id}>'
+
+    @property
+    def created_at(self) -> datetime.datetime:
+        """:class:`datetime.datetime`: Returns the channel's creation time in UTC."""
+        return utils.snowflake_time(self.id)
+
+    def permissions_for(self, obj: User = None) -> Permissions:
+        """Handles permission resolution for a :class:`User`.
+        This function is there for compatibility with other channel types.
+        Since partial messageables cannot reasonably have the concept of
+        permissions, this will always return :meth:`Permissions.none`.
+
+        To check permissions including overwrites, fetch the channel and use :func:`~discord.Member.permissions_in`.
+        However, the raw `overwrites` might be available in :attr:`partial_data`.
+
+        Parameters
+        -----------
+        obj: :class:`User`
+            The user to check permissions for. This parameter is ignored
+            but kept for compatibility with other ``permissions_for`` methods.
+
+        Returns
+        --------
+        :class:`Permissions`
+            The resolved permissions. Always none for partial messageables.
+        """
 
-    async def _get_channel(self) -> Object:
-        return self._channel
+        return Permissions.none()
 
-    def get_partial_message(self, message_id: int, /):
+    def get_partial_message(self, message_id: int) -> PartialMessage:
         """Creates a :class:`PartialMessage` from the message ID.
         This is useful if you want to work with a message and only have its ID without
         doing an unnecessary API call.
+
         Parameters
         ------------
         message_id: :class:`int`
             The message ID to create a partial message for.
+
         Returns
         ---------
         :class:`PartialMessage`
@@ -1625,6 +4137,18 @@ def get_partial_message(self, message_id: int, /):
         return PartialMessage(channel=self, id=message_id)
 
 
+def _thread_factory(guild: Guild, state: ConnectionState, data) -> Union[ThreadChannel, ForumPost]:
+    parent_id = utils._get_as_snowflake(data, 'parent_id')
+    try:
+        parent_channel = guild.get_channel(parent_id)
+    except AttributeError:
+        # parent channel not in cache or guild is a discord.Object
+        parent_channel = None
+    if (parent_channel and isinstance(parent_channel, ForumChannel)) or 'applied_tags' in data:
+        return ForumPost(state=state, guild=guild, data=data)
+    # This doesn't guarantee that the channel is not a forum channel, but it's the best we can do
+    return ThreadChannel(state=state, guild=guild, data=data)
+
 
 def _channel_factory(channel_type):
     value = try_enum(ChannelType, channel_type)
@@ -1640,9 +4164,19 @@ def _channel_factory(channel_type):
         return GroupChannel, value
     elif value is ChannelType.news:
         return TextChannel, value
-    elif value is ChannelType.store:
-        return StoreChannel, value
     elif value is ChannelType.stage_voice:
         return StageChannel, value
+    elif value is ChannelType.public_thread:
+        return _thread_factory, value
+    elif value is ChannelType.private_thread:
+        return _thread_factory, value
+    elif value is ChannelType.forum_channel:
+        return ForumChannel, value
     else:
         return None, value
+
+
+def _check_channel_type(obj, types) -> bool:
+    """Just something to check channel instances without circular imports."""
+    types = tuple([_channel_factory(t)[0] for t in types])
+    return isinstance(obj, types)
diff --git a/discord/client.py b/discord/client.py
index 632a5beb..b1fbcdfa 100644
--- a/discord/client.py
+++ b/discord/client.py
@@ -3,7 +3,7 @@
 """
 The MIT License (MIT)
 
-Copyright (c) 2015-present Rapptz
+Copyright (c) 2015-2021 Rapptz & (c) 2021-present mccoderpy
 
 Permission is hereby granted, free of charge, to any person obtaining a
 copy of this software and associated documentation files (the "Software"),
@@ -23,38 +23,100 @@
 FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 DEALINGS IN THE SOFTWARE.
 """
+from __future__ import annotations
 
+import aiohttp
 import asyncio
+import copy
+import inspect
 import logging
 import signal
 import sys
+import re
 import traceback
-
-import aiohttp
-
-from .user import User, Profile
+import warnings
+
+from typing import (
+    Any,
+    Dict,
+    List,
+    Union,
+    Tuple,
+    AnyStr,
+    TypeVar,
+    Iterator,
+    Optional,
+    Callable,
+    Awaitable,
+    Coroutine,
+    TYPE_CHECKING
+)
+
+from typing_extensions import Literal
+
+from .application_commands import ActivityEntryPointCommand
+from .auto_updater import AutoUpdateChecker
+from .sticker import StickerPack
+from .user import ClientUser, User
 from .invite import Invite
 from .template import Template
 from .widget import Widget
 from .guild import Guild
-from .channel import _channel_factory
-from .enums import ChannelType
+from .channel import _channel_factory, PartialMessageable
+from .enums import ChannelType, ApplicationCommandType, Locale, InteractionContextType, AppIntegrationType, \
+    EntryPointHandlerType
 from .mentions import AllowedMentions
+from .monetization import Entitlement, SKU
 from .errors import *
 from .enums import Status, VoiceRegion
 from .gateway import *
 from .activity import BaseActivity, create_activity
-from .voice_client import VoiceClient
+from .voice_client import VoiceRegionInfo, VoiceClient
 from .http import HTTPClient
 from .state import ConnectionState
 from . import utils
 from .object import Object
 from .backoff import ExponentialBackoff
 from .webhook import Webhook
-from .iterators import GuildIterator
+from .iterators import GuildIterator, EntitlementIterator
 from .appinfo import AppInfo
+from .application_commands import *
+
+if TYPE_CHECKING:
+    import datetime
+    from re import Pattern
+
+    from .abc import (
+        GuildChannel,
+        Messageable,
+        PrivateChannel,
+        VoiceProtocol,
+        Snowflake
+    )
+    from .components import Button, Select
+    from .emoji import Emoji
+    from .flags import Intents
+    from .interactions import ApplicationCommandInteraction, ComponentInteraction, ModalSubmitInteraction
+    from .member import Member
+    from .message import Message
+    from .permissions import Permissions
+    from .sticker import Sticker
+
+    _ClickCallback = Callable[[ComponentInteraction, Button], Coroutine[Any, Any, Any]]
+    _SelectCallback = Callable[[ComponentInteraction, Select], Coroutine[Any, Any, Any]]
+    _SubmitCallback = Callable[[ModalSubmitInteraction], Coroutine[Any, Any, Any]]
+
+
+T = TypeVar('T')
+Coro = TypeVar('Coro', bound=Callable[..., Coroutine[Any, Any, Any]])
 
 log = logging.getLogger(__name__)
+MISSING = utils.MISSING
+
+__all__ = (
+    'Client',
+)
+
 
 def _cancel_tasks(loop):
     try:
@@ -85,6 +147,7 @@ def _cancel_tasks(loop):
                 'task': task
             })
 
+
 def _cleanup_loop(loop):
     try:
         _cancel_tasks(loop)
@@ -94,6 +157,7 @@ def _cleanup_loop(loop):
         log.info('Closing the event loop.')
         loop.close()
 
+
 class _ClientEventTask(asyncio.Task):
     def __init__(self, original_coro, event_name, coro, *, loop):
         super().__init__(coro, loop=loop)
@@ -110,6 +174,7 @@ def __repr__(self):
             info.append(('exception', repr(self._exception)))
         return '<ClientEventTask {}>'.format(' '.join('%s=%s' % t for t in info))
 
+
 class Client:
     r"""Represents a client connection that connects to Discord.
     This class is used to interact with the Discord WebSocket and API.
@@ -139,17 +204,18 @@ class Client:
     shard_count: Optional[:class:`int`]
         The total number of shards.
     intents: :class:`Intents`
-        The intents that you want to enable for the session. This is a way of
+        The intents that you want to enable for the _session. This is a way of
         disabling and enabling certain gateway events from triggering and being sent.
         If not given, defaults to a regularly constructed :class:`Intents` class.
-
-        .. versionadded:: 1.5
+    gateway_version: :class:`int`
+        The gateway and api version to use. Defaults to ``v10``.
+    api_error_locale: :class:`discord.Locale`
+        The locale language to use for api errors. This will be applied to the ``X-Discord-Local`` header in requests.
+        Default to :attr:`Locale.en_US`
     member_cache_flags: :class:`MemberCacheFlags`
         Allows for finer control over how the library caches members.
         If not given, defaults to cache as much as possible with the
         currently selected intents.
-
-        .. versionadded:: 1.5
     fetch_offline_members: :class:`bool`
         A deprecated alias of ``chunk_guilds_at_startup``.
     chunk_guilds_at_startup: :class:`bool`
@@ -157,16 +223,12 @@ class Client:
         at start-up if necessary. This operation is incredibly slow for large
         amounts of guilds. The default is ``True`` if :attr:`Intents.members`
         is ``True``.
-
-        .. versionadded:: 1.5
     status: Optional[:class:`.Status`]
         A status to start your presence with upon logging on to Discord.
     activity: Optional[:class:`.BaseActivity`]
         An activity to start your presence with upon logging on to Discord.
     allowed_mentions: Optional[:class:`AllowedMentions`]
         Control how the client handles mentions by default on every message sent.
-
-        .. versionadded:: 1.4
     heartbeat_timeout: :class:`float`
         The maximum numbers of seconds before timing out and restarting the
         WebSocket in the case of not receiving a HEARTBEAT_ACK. Useful if
@@ -178,13 +240,13 @@ class Client:
 
         .. versionadded:: 1.4
     guild_subscriptions: :class:`bool`
-        Whether to dispatch presence or typing events. Defaults to ``True``.
+        Whether to dispatch presence or typing events. Defaults to :obj:`True`.
 
         .. versionadded:: 1.3
 
         .. warning::
 
-            If this is set to ``False`` then the following features will be disabled:
+            If this is set to :obj:`False` then the following features will be disabled:
 
                 - No user related updates (:func:`on_user_update` will not dispatch)
                 - All member related events will be disabled.
@@ -217,6 +279,27 @@ class Client:
 
         .. versionadded:: 1.3
 
+    sync_commands: :class:`bool`
+        Whether to sync application-commands on startup, default :obj:`False`.
+
+        This will register global and guild application-commands(slash-, user- and message-commands)
+        that are not registered yet, update changes and remove application-commands that could not be found
+        in the code anymore if :attr:`delete_not_existing_commands` is set to :obj:`True` what it is by default.
+
+    delete_not_existing_commands: :class:`bool`
+        Whether to remove global and guild-only application-commands that are not in the code anymore, default :obj:`True`.
+
+    auto_check_for_updates: :class:`bool`
+        Whether to check for available updates automatically, default :obj:`False` for legal reasons.
+        For more info see :func:`discord.on_update_available`.
+
+        .. note::
+
+            For now, this may only work on the original repository, **not on forks**.
+            This is because it uses an internal API that listens to a private application that is on the original repo.
+
+            In the future this API might be open-sourced, or it will be possible to add your forks URL as a valid source.
+
     Attributes
     -----------
     ws
@@ -224,10 +307,21 @@ class Client:
     loop: :class:`asyncio.AbstractEventLoop`
         The event loop that the client uses for HTTP requests and websocket operations.
     """
-    def __init__(self, *, loop=None, **options):
-        self.ws = None
-        self.loop = asyncio.get_event_loop() if loop is None else loop
+    def __init__(self, *, loop: Optional[asyncio.AbstractEventLoop] = None, **options):
+        self.ws: DiscordWebSocket = None
+        self.loop: asyncio.AbstractEventLoop = asyncio.get_event_loop() if loop is None else loop
         self._listeners = {}
+        self.sync_commands: bool = options.get('sync_commands', False)
+        self.delete_not_existing_commands: bool = options.get('delete_not_existing_commands', True)
+        self._application_commands_by_type: Dict[
+            str,
+            Dict[str, Union[SlashCommand, UserCommand, MessageCommand, ActivityEntryPointCommand]]
+        ] = {
+            'chat_input': {}, 'message': {}, 'user': {}, 'primary_entry_point': {}
+        }
+        self._guild_specific_application_commands: Dict[
+            int, Dict[str, Dict[str, Union[SlashCommand, UserCommand, MessageCommand]]]] = {}
+        self._application_commands: Dict[int, ApplicationCommand] = {}
         self.shard_id = options.get('shard_id')
         self.shard_count = options.get('shard_count')
 
@@ -235,10 +329,23 @@ def __init__(self, *, loop=None, **options):
         proxy = options.pop('proxy', None)
         proxy_auth = options.pop('proxy_auth', None)
         unsync_clock = options.pop('assume_unsync_clock', True)
-        self.http = HTTPClient(connector, proxy=proxy, proxy_auth=proxy_auth, unsync_clock=unsync_clock, loop=self.loop)
+        self.gateway_version: int = options.get('gateway_version', 10)
+        self.api_error_locale: Locale = options.pop('api_error_locale', 'en-US')
+        self.auto_check_for_updates: bool = options.pop('auto_check_for_updates', False)
+        self.http = HTTPClient(
+            connector,
+            proxy=proxy,
+            proxy_auth=proxy_auth,
+            unsync_clock=unsync_clock,
+            loop=self.loop,
+            api_version=self.gateway_version,
+            api_error_locale=self.api_error_locale
+        )
 
         self._handlers = {
-            'ready': self._handle_ready
+            'ready': self._handle_ready,
+            'connect': lambda: self._ws_connected.set(),
+            'resumed': lambda: self._ws_connected.set()
         }
 
         self._hooks = {
@@ -249,15 +356,19 @@ def __init__(self, *, loop=None, **options):
         self._connection.shard_count = self.shard_count
         self._closed = False
         self._ready = asyncio.Event()
+        self._ws_connected = asyncio.Event()
         self._connection._get_websocket = self._get_websocket
         self._connection._get_client = lambda: self
 
         if VoiceClient.warn_nacl:
             VoiceClient.warn_nacl = False
             log.warning("PyNaCl is not installed, voice will NOT be supported")
+        if self.auto_check_for_updates:
+            self._auto_update_checker: Optional[AutoUpdateChecker] = AutoUpdateChecker(client=self)
+        else:
+            self._auto_update_checker: Optional[AutoUpdateChecker] = None
 
     # internals
-
     def _get_websocket(self, guild_id=None, *, shard_id=None):
         return self.ws
 
@@ -272,7 +383,7 @@ def _handle_ready(self):
         self._ready.set()
 
     @property
-    def latency(self):
+    def latency(self) -> float:
         """:class:`float`: Measures latency between a HEARTBEAT and a HEARTBEAT_ACK in seconds.
 
         This could be referred to as the Discord WebSocket protocol latency.
@@ -280,7 +391,7 @@ def latency(self):
         ws = self.ws
         return float('nan') if not ws else ws.latency
 
-    def is_ws_ratelimited(self):
+    def is_ws_ratelimited(self) -> bool:
         """:class:`bool`: Whether the websocket is currently rate limited.
 
         This can be useful to know when deciding whether you should query members
@@ -293,22 +404,27 @@ def is_ws_ratelimited(self):
         return False
 
     @property
-    def user(self):
+    def user(self) -> ClientUser:
         """Optional[:class:`.ClientUser`]: Represents the connected client. ``None`` if not logged in."""
         return self._connection.user
 
     @property
-    def guilds(self):
+    def guilds(self) -> List[Guild]:
         """List[:class:`.Guild`]: The guilds that the connected client is a member of."""
         return self._connection.guilds
 
     @property
-    def emojis(self):
+    def emojis(self) -> List[Emoji]:
         """List[:class:`.Emoji`]: The emojis that the connected client has."""
         return self._connection.emojis
 
     @property
-    def cached_messages(self):
+    def stickers(self) -> List[Sticker]:
+        """List[:class:`.Sticker`]: The stickers that the connected client has."""
+        return self._connection.stickers
+
+    @property
+    def cached_messages(self) -> utils.SequenceProxy[Message]:
         """Sequence[:class:`.Message`]: Read-only list of messages the connected client has cached.
 
         .. versionadded:: 1.1
@@ -316,7 +432,7 @@ def cached_messages(self):
         return utils.SequenceProxy(self._connection._messages or [])
 
     @property
-    def private_channels(self):
+    def private_channels(self) -> List[PrivateChannel]:
         """List[:class:`.abc.PrivateChannel`]: The private channels that the connected client is participating on.
 
         .. note::
@@ -327,18 +443,18 @@ def private_channels(self):
         return self._connection.private_channels
 
     @property
-    def voice_clients(self):
+    def voice_clients(self) -> List[VoiceProtocol]:
         """List[:class:`.VoiceProtocol`]: Represents a list of voice connections.
 
         These are usually :class:`.VoiceClient` instances.
         """
         return self._connection.voice_clients
 
-    def is_ready(self):
+    def is_ready(self) -> bool:
         """:class:`bool`: Specifies if the client's internal cache is ready for use."""
         return self._ready.is_set()
 
-    async def _run_event(self, coro, event_name, *args, **kwargs):
+    async def _run_event(self, coro: Coro, event_name: str, *args, **kwargs):
         try:
             await coro(*args, **kwargs)
         except asyncio.CancelledError:
@@ -349,12 +465,12 @@ async def _run_event(self, coro, event_name, *args, **kwargs):
             except asyncio.CancelledError:
                 pass
 
-    def _schedule_event(self, coro, event_name, *args, **kwargs):
+    def _schedule_event(self, coro: Coro, event_name: str, *args, **kwargs) -> _ClientEventTask:
         wrapped = self._run_event(coro, event_name, *args, **kwargs)
         # Schedules the task
         return _ClientEventTask(original_coro=coro, event_name=event_name, coro=wrapped, loop=self.loop)
 
-    def dispatch(self, event, *args, **kwargs):
+    def dispatch(self, event: str, *args, **kwargs) -> None:
         log.debug('Dispatching event %s', event)
         method = 'on_' + event
 
@@ -392,7 +508,6 @@ def dispatch(self, event, *args, **kwargs):
                     if result:
                         self._schedule_event(future, method, *args, **kwargs)
 
-
         try:
             coro = getattr(self, method)
         except AttributeError:
@@ -400,18 +515,201 @@ def dispatch(self, event, *args, **kwargs):
         else:
             self._schedule_event(coro, method, *args, **kwargs)
 
-    async def on_error(self, event_method, *args, **kwargs):
+    async def on_error(self, event_method: str, *args, **kwargs) -> None:
         """|coro|
 
         The default error handler provided by the client.
 
-        By default this prints to :data:`sys.stderr` however it could be
+        By default, this prints to :data:`sys.stderr` however it could be
         overridden to have a different implementation.
         Check :func:`~discord.on_error` for more details.
         """
         print('Ignoring exception in {}'.format(event_method), file=sys.stderr)
         traceback.print_exc()
 
+    async def on_application_command_error(
+            self,
+            cmd: ApplicationCommand,
+            interaction: ApplicationCommandInteraction,
+            exception: BaseException
+    ) -> None:
+        """|coro|
+
+        The default error handler when an Exception was raised when invoking an application-command.
+
+        By default, this prints to :data:`sys.stderr` however it could be
+        overridden to have a different implementation.
+        Check :func:`~discord.on_application_command_error` for more details.
+        """
+        if hasattr(cmd, 'on_error'):
+            return
+        if isinstance(cmd, (SlashCommand, SubCommand)):
+            name = cmd.qualified_name
+        else:
+            name = cmd.name
+        print('Ignoring exception in {type} command "{name}" ({id})'.format(
+            type=str(interaction.command.type).upper(),
+            name=name,
+            id=interaction.command.id
+        ),
+            file=sys.stderr
+        )
+        traceback.print_exception(type(exception), exception, exception.__traceback__, file=sys.stderr)
+
+    async def _request_sync_commands(self, is_cog_reload: bool = False, *, reload_failed: bool = False) -> None:
+        """Used to sync commands if the ``GUILD_CREATE`` stream is over or a :class:`~discord.ext.commands.Cog` was reloaded.
+
+        .. warning::
+            **DO NOT OVERWRITE THIS METHOD!!!
+            IF YOU DO SO, THE APPLICATION-COMMANDS WILL NOT BE SYNCED AND NO COMMAND REGISTERED WILL BE DISPATCHED.**
+        """
+        if not hasattr(self, 'app'):
+            await self.application_info()
+        if (is_cog_reload and not reload_failed and getattr(self, 'sync_commands_on_cog_reload', False) is True) or (
+                not is_cog_reload and self.sync_commands is True
+        ):
+            return await self._sync_commands()
+        state = self._connection  # Speedup attribute access
+        if not is_cog_reload:
+            app_id = self.app.id
+            log.info('Collecting global application-commands for application %s (%s)', self.app.name, self.app.id)
+
+            self._minimal_registered_global_commands_raw = minimal_registered_global_commands_raw = []
+            get_commands = self.http.get_application_commands
+            global_registered_raw = await get_commands(app_id)
+
+            for raw_command in global_registered_raw:
+                command_type = str(ApplicationCommandType.try_value(raw_command['type']))
+                minimal_registered_global_commands_raw.append({'id': int(raw_command['id']), 'type': command_type, 'name': raw_command['name']})
+                try:
+                    command = self._application_commands_by_type[command_type][raw_command['name']]
+                except KeyError:
+                    command = ApplicationCommand._from_type(state, data=raw_command)
+                    command.func = None
+                    self._application_commands[command.id] = self._application_commands_by_type[command_type][command.name] = command
+                else:
+                    command._fill_data(raw_command)
+                    command._state = state
+                    self._application_commands[command.id] = command
+
+            log.info(
+                'Done! Cached %s global application-commands',
+                sum([len(cmds) for cmds in self._application_commands_by_type.values()])
+            )
+            log.info('Collecting guild-specific application-commands for application %s (%s)', self.app.name, app_id)
+
+            self._minimal_registered_guild_commands_raw = minimal_registered_guild_commands_raw = {}
+
+            for guild in self.guilds:
+                try:
+                    registered_guild_commands_raw = await get_commands(app_id, guild_id=guild.id)
+                except Forbidden:
+                    log.info(
+                        'Missing access to guild %s (%s) or don\'t have the application.commands scope in there, '
+                        'skipping!' % (guild.name, guild.id))
+                    continue
+                except HTTPException:
+                    raise
+                if registered_guild_commands_raw:
+                    minimal_registered_guild_commands_raw[guild.id] = minimal_registered_guild_commands = []
+                    try:
+                        guild_commands = self._guild_specific_application_commands[guild.id]
+                    except KeyError:
+                        self._guild_specific_application_commands[guild.id] = guild_commands = {
+                            'chat_input': {}, 'user': {}, 'message': {}
+                        }
+                    for raw_command in registered_guild_commands_raw:
+                        command_type = str(ApplicationCommandType.try_value(raw_command['type']))
+                        minimal_registered_guild_commands.append(
+                            {'id': int(raw_command['id']), 'type': command_type, 'name': raw_command['name']}
+                        )
+                        try:
+                            command = guild_commands[command_type][raw_command['name']]
+                        except KeyError:
+                            command = ApplicationCommand._from_type(state, data=raw_command)
+                            command.func = None
+                            self._application_commands[command.id] = guild._application_commands[command.id] \
+                                = guild_commands[command_type][command.name] = command
+                        else:
+                            command._fill_data(raw_command)
+                            command._state = state
+                            self._application_commands[command.id] = guild._application_commands[command.id] = command
+
+            log.info(
+                'Done! Cached %s commands for %s guilds',
+                sum([
+                    len(commands) for commands in list(minimal_registered_guild_commands_raw.values())
+                ]),
+                len(minimal_registered_guild_commands_raw.keys())
+            )
+
+        else:
+            # re-assign metadata to the commands (for commands added from cogs)
+            log.info('Re-assigning metadata to commands')
+            # For logging purposes
+            no_longer_in_code_global = 0
+            no_longer_in_code_guild_specific = 0
+            no_longer_in_code_guilds = set()
+
+            for raw_command in self._minimal_registered_global_commands_raw:
+                command_type = raw_command['type']
+                try:
+                    command = self._application_commands_by_type[command_type][raw_command['name']]
+                except KeyError:
+                    no_longer_in_code_global += 1
+                    self._application_commands[raw_command['id']].func = None
+                    continue  # Should already be cached in self._application_commands so skip that part here
+                else:
+                    if command.disabled:
+                        no_longer_in_code_global += 1
+                    else:
+                        command._fill_data(raw_command)
+                        command._state = state
+                        self._application_commands[command.id] = command
+            for guild_id, raw_commands in self._minimal_registered_guild_commands_raw.items():
+                try:
+                    guild_commands = self._guild_specific_application_commands[guild_id]
+                except KeyError:
+                    no_longer_in_code_guilds.add(guild_id)
+                    no_longer_in_code_guild_specific += len(raw_commands)
+                    continue  # Should already be cached in self._application_commands so skip that part here again
+                else:
+                    guild = self.get_guild(guild_id)
+                    for raw_command in raw_commands:
+                        command_type = raw_command['type']
+                        try:
+                            command = guild_commands[command_type][raw_command['name']]
+                        except KeyError:
+                            if guild_id not in no_longer_in_code_guilds:
+                                no_longer_in_code_guilds.add(guild_id)
+                            no_longer_in_code_guild_specific += 1
+                            self._application_commands[raw_command['id']].func = None
+                            pass  # Should already be cached in self._application_commands so skip that part here another once again
+                        else:
+                            if command.disabled:
+                                no_longer_in_code_guild_specific += 1
+                            else:
+                                command._fill_data(raw_command)
+                                command._state = state
+                                self._application_commands[command.id] = guild._application_commands[command.id] = command
+            log.info('Done!')
+            if no_longer_in_code_global:
+                log.warning(
+                    '%s global application-commands where removed from code but are still registered in discord',
+                    no_longer_in_code_global
+                )
+            if no_longer_in_code_guild_specific:
+                log.warning(
+                    'In total %s guild-specific application-commands from %s guild(s) where removed from code '
+                    'but are still registered in discord', no_longer_in_code_guild_specific,
+                    len(no_longer_in_code_guilds)
+                )
+            if no_longer_in_code_global or no_longer_in_code_guild_specific:
+                log.warning(
+                    'To prevent the above, set `sync_commands_on_cog_reload` of %s to True',
+                    self.__class__.__name__
+                )
+
     @utils.deprecated('Guild.chunk')
     async def request_offline_members(self, *guilds):
         r"""|coro|
@@ -454,10 +752,10 @@ async def _call_before_identify_hook(self, shard_id, *, initial=False):
         # toes of those who need to override their own hook.
         await self.before_identify_hook(shard_id, initial=initial)
 
-    async def before_identify_hook(self, shard_id, *, initial=False):
+    async def before_identify_hook(self, shard_id: int, *, initial: bool = False):
         """|coro|
 
-        A hook that is called before IDENTIFYing a session. This is useful
+        A hook that is called before IDENTIFYing a _session. This is useful
         if you wish to have more control over the synchronization of multiple
         IDENTIFYing clients.
 
@@ -478,30 +776,19 @@ async def before_identify_hook(self, shard_id, *, initial=False):
 
     # login state management
 
-    async def login(self, token, *, bot=True):
+    async def login(self, token: str) -> None:
         """|coro|
 
         Logs in the client with the specified credentials.
 
         This function can be used in two different ways.
 
-        .. warning::
-
-            Logging on with a user token is against the Discord
-            `Terms of Service <https://support.discord.com/hc/en-us/articles/115002192352>`_
-            and doing so might potentially get your account banned.
-            Use this at your own risk.
 
         Parameters
         -----------
         token: :class:`str`
             The authentication token. Do not prefix this token with
             anything as the library will do it for you.
-        bot: :class:`bool`
-            Keyword argument that specifies if the account logging on is a bot
-            token or not.
-
-            .. deprecated:: 1.7
 
         Raises
         ------
@@ -514,15 +801,14 @@ async def login(self, token, *, bot=True):
         """
 
         log.info('logging in using static token')
-        await self.http.static_login(token.strip(), bot=bot)
-        self._connection.is_bot = bot
+        await self.http.static_login(token.strip())
 
     @utils.deprecated('Client.close')
     async def logout(self):
         """|coro|
 
         Logs out of Discord and closes all connections.
-        
+
         .. deprecated:: 1.7
 
         .. note::
@@ -533,7 +819,7 @@ async def logout(self):
         """
         await self.close()
 
-    async def connect(self, *, reconnect=True):
+    async def connect(self, *, reconnect: bool = True) -> None:
         """|coro|
 
         Creates a websocket connection and lets the websocket listen
@@ -563,6 +849,8 @@ async def connect(self, *, reconnect=True):
             'initial': True,
             'shard_id': self.shard_id,
         }
+        if self.auto_check_for_updates:
+            self._auto_update_checker.start()
         while not self.is_closed():
             try:
                 coro = DiscordWebSocket.from_client(self, **ws_params)
@@ -572,8 +860,14 @@ async def connect(self, *, reconnect=True):
                     await self.ws.poll_event()
             except ReconnectWebSocket as e:
                 log.info('Got a request to %s the websocket.', e.op)
+                self._ws_connected.clear()
                 self.dispatch('disconnect')
-                ws_params.update(sequence=self.ws.sequence, resume=e.resume, session=self.ws.session_id)
+                ws_params.update(
+                    sequence=self.ws.sequence,
+                    resume=e.resume,
+                    session=self.ws.session_id,
+                    resume_gateway_url=self.ws.resume_gateway_url if e.resume else None
+                )
                 continue
             except (OSError,
                     HTTPException,
@@ -581,7 +875,7 @@ async def connect(self, *, reconnect=True):
                     ConnectionClosed,
                     aiohttp.ClientError,
                     asyncio.TimeoutError) as exc:
-
+                self._ws_connected.clear()
                 self.dispatch('disconnect')
                 if not reconnect:
                     await self.close()
@@ -595,29 +889,44 @@ async def connect(self, *, reconnect=True):
 
                 # If we get connection reset by peer then try to RESUME
                 if isinstance(exc, OSError) and exc.errno in (54, 10054):
-                    ws_params.update(sequence=self.ws.sequence, initial=False, resume=True, session=self.ws.session_id)
+                    ws_params.update(
+                        sequence=self.ws.sequence,
+                        initial=False,
+                        resume=True,
+                        session=self.ws.session_id,
+                        resume_gateway_url=self.ws.resume_gateway_url
+                    )
                     continue
 
                 # We should only get this when an unhandled close code happens,
                 # such as a clean disconnect (1000) or a bad state (bad token, no sharding, etc)
-                # sometimes, discord sends us 1000 for unknown reasons so we should reconnect
+                # sometimes, discord sends us 1000 for unknown reasons, so we should reconnect
                 # regardless and rely on is_closed instead
                 if isinstance(exc, ConnectionClosed):
                     if exc.code == 4014:
-                        raise PrivilegedIntentsRequired(exc.shard_id) from None
+                        if self.shard_count and self.shard_count > 0:
+                            raise PrivilegedIntentsRequired(exc.shard_id)
+                        else:
+                            sys.stderr.write(str(PrivilegedIntentsRequired(exc.shard_id)))
                     if exc.code != 1000:
                         await self.close()
-                        raise
+                        if not exc.code == 4014:
+                            raise
 
                 retry = backoff.delay()
                 log.exception("Attempting a reconnect in %.2fs", retry)
                 await asyncio.sleep(retry)
                 # Always try to RESUME the connection
-                # If the connection is not RESUME-able then the gateway will invalidate the session.
+                # If the connection is not RESUME-able then the gateway will invalidate the _session.
                 # This is apparently what the official Discord client does.
-                ws_params.update(sequence=self.ws.sequence, resume=True, session=self.ws.session_id)
-
-    async def close(self):
+                ws_params.update(
+                    sequence=self.ws.sequence,
+                    resume=True,
+                    session=self.ws.session_id,
+                    resume_gateway_url=self.ws.resume_gateway_url
+                )
+
+    async def close(self) -> None:
         """|coro|
 
         Closes the connection to Discord.
@@ -625,22 +934,25 @@ async def close(self):
         if self._closed:
             return
 
-        await self.http.close()
-        self._closed = True
-
         for voice in self.voice_clients:
             try:
-                await voice.disconnect()
+                await voice.disconnect()  # type: ignore
             except Exception:
                 # if an error happens during disconnects, disregard it.
                 pass
 
+        await self.http.close()
+        if self._auto_update_checker:
+            await self._auto_update_checker.close()
+        self._closed = True
+
         if self.ws is not None and self.ws.open:
             await self.ws.close(code=1000)
 
+        self._ws_connected.clear()
         self._ready.clear()
 
-    def clear(self):
+    def clear(self) -> None:
         """Clears the internal state of the bot.
 
         After this, the bot can be considered "re-opened", i.e. :meth:`is_closed`
@@ -649,10 +961,11 @@ def clear(self):
         """
         self._closed = False
         self._ready.clear()
+        self._ws_connected.clear()
         self._connection.clear()
         self.http.recreate()
 
-    async def start(self, *args, **kwargs):
+    async def start(self, token: str, reconnect: bool = True) -> None:
         """|coro|
 
         A shorthand coroutine for :meth:`login` + :meth:`connect`.
@@ -662,16 +975,19 @@ async def start(self, *args, **kwargs):
         TypeError
             An unexpected keyword argument was received.
         """
-        bot = kwargs.pop('bot', True)
-        reconnect = kwargs.pop('reconnect', True)
-
-        if kwargs:
-            raise TypeError("unexpected keyword argument(s) %s" % list(kwargs.keys()))
-
-        await self.login(*args, bot=bot)
+        await self.login(token)
         await self.connect(reconnect=reconnect)
 
-    def run(self, *args, **kwargs):
+    def run(
+        self,
+        token: str,
+        reconnect: bool = True,
+        *,
+        log_handler: Optional[logging.Handler] = MISSING,
+        log_formatter: logging.Formatter = MISSING,
+        log_level: int = MISSING,
+        root_logger: bool = False
+    ) -> None:
         """A blocking call that abstracts away the event loop
         initialisation from you.
 
@@ -689,11 +1005,43 @@ def run(self, *args, **kwargs):
             finally:
                 loop.close()
 
+        This function also sets up the `:mod:`logging` library to make it easier
+        for beginners to know what is going on with the library. For more
+        advanced users, this can be disabled by passing :obj:`None` to
+        the ``log_handler`` parameter.
+
         .. warning::
 
             This function must be the last function to call due to the fact that it
             is blocking. That means that registration of events or anything being
             called after this function call will not execute until it returns.
+
+        Parameters
+        -----------
+        token: :class:`str`
+            The authentication token. **Do not prefix this token with anything as the library will do it for you.**
+        reconnect: :class:`bool`
+            If we should attempt reconnecting, either due to internet
+            failure or a specific failure on Discord's part. Certain
+            disconnects that lead to bad state will not be handled (such as
+            invalid sharding payloads or bad tokens).
+        log_handler: Optional[:class:`logging.Handler`]
+            The log handler to use for the library's logger. If this is :obj:`None`
+            then the library will not set up anything logging related. Logging
+            will still work if :obj:`None` is passed, though it is your responsibility
+            to set it up.
+            The default log handler if not provided is :class:`logging.StreamHandler`.
+        log_formatter: :class:`logging.Formatter`
+            The formatter to use with the given log handler. If not provided then it
+            defaults to a colour based logging formatter (if available).
+        log_level: :class:`int`
+            The default log level for the library's logger. This is only applied if the
+            ``log_handler`` parameter is not :obj:`None`. Defaults to :attr:`logging.INFO`.
+        root_logger: :class:`bool`
+            Whether to set up the root logger rather than the library logger.
+            By default, only the library logger (``'discord'``) is set up. If this
+            is set to :obj:`True` then the root logger is set up as well.
+            Defaults to :obj:`False`.
         """
         loop = self.loop
 
@@ -705,11 +1053,19 @@ def run(self, *args, **kwargs):
 
         async def runner():
             try:
-                await self.start(*args, **kwargs)
+                await self.start(token, reconnect)
             finally:
                 if not self.is_closed():
                     await self.close()
 
+        if log_handler is not None:
+            utils.setup_logging(
+                handler=log_handler,
+                formatter=log_formatter,
+                level=log_level,
+                root=root_logger
+            )
+
         def stop_loop_on_completion(f):
             loop.stop()
 
@@ -733,19 +1089,19 @@ def stop_loop_on_completion(f):
 
     # properties
 
-    def is_closed(self):
+    def is_closed(self) -> bool:
         """:class:`bool`: Indicates if the websocket connection is closed."""
         return self._closed
 
     @property
-    def activity(self):
+    def activity(self) -> Optional[BaseActivity]:
         """Optional[:class:`.BaseActivity`]: The activity being used upon
         logging in.
         """
         return create_activity(self._connection._activity)
 
     @activity.setter
-    def activity(self, value):
+    def activity(self, value: Optional[BaseActivity]):
         if value is None:
             self._connection._activity = None
         elif isinstance(value, BaseActivity):
@@ -754,7 +1110,7 @@ def activity(self, value):
             raise TypeError('activity must derive from BaseActivity.')
 
     @property
-    def allowed_mentions(self):
+    def allowed_mentions(self) -> Optional[AllowedMentions]:
         """Optional[:class:`~discord.AllowedMentions`]: The allowed mention configuration.
 
         .. versionadded:: 1.4
@@ -762,14 +1118,14 @@ def allowed_mentions(self):
         return self._connection.allowed_mentions
 
     @allowed_mentions.setter
-    def allowed_mentions(self, value):
+    def allowed_mentions(self, value: Optional[AllowedMentions]):
         if value is None or isinstance(value, AllowedMentions):
             self._connection.allowed_mentions = value
         else:
             raise TypeError('allowed_mentions must be AllowedMentions not {0.__class__!r}'.format(value))
 
     @property
-    def intents(self):
+    def intents(self) -> Intents:
         """:class:`~discord.Intents`: The intents configured for this connection.
 
         .. versionadded:: 1.5
@@ -779,11 +1135,15 @@ def intents(self):
     # helpers/getters
 
     @property
-    def users(self):
+    def users(self) -> List[User]:
         """List[:class:`~discord.User`]: Returns a list of all the users the bot can see."""
         return list(self._connection._users.values())
 
-    def get_channel(self, id):
+    def get_message(self, id: int) -> Optional[Message]:
+        """Returns a :class:`~discord.Message` with the given ID if it exists in the cache, else :obj:`None`"""
+        return self._connection._get_message(id)
+
+    def get_channel(self, id: int) -> Optional[Union[Messageable, GuildChannel]]:
         """Returns a channel with the given ID.
 
         Parameters
@@ -798,7 +1158,37 @@ def get_channel(self, id):
         """
         return self._connection.get_channel(id)
 
-    def get_guild(self, id):
+    def get_partial_messageable(
+            self,
+            id: int,
+            *,
+            guild_id: Optional[int] = None,
+            type: Optional[ChannelType] = None
+    ) -> PartialMessageable:
+        """Returns a :class:`~discord.PartialMessageable` with the given channel ID.
+        This is useful if you have the ID of a channel but don't want to do an API call
+        to send messages to it.
+
+        Parameters
+        -----------
+        id: :class:`int`
+            The channel ID to create a :class:`~discord.PartialMessageable` for.
+        guild_id: Optional[:class:`int`]
+            The optional guild ID to create a :class:`~discord.PartialMessageable` for.
+            This is not required to actually send messages, but it does allow the
+            :meth:`~discord.PartialMessageable.jump_url` and
+            :attr:`~discord.PartialMessageable.guild` properties to function properly.
+        type: Optional[:class:`.ChannelType`]
+            The underlying channel type for the :class:`~discord.PartialMessageable`.
+
+        Returns
+        --------
+        :class:`.PartialMessageable`
+            The partial messageable created
+        """
+        return PartialMessageable(state=self._connection, id=id, guild_id=guild_id, type=type)
+
+    def get_guild(self, id: int) -> Optional[Guild]:
         """Returns a guild with the given ID.
 
         Parameters
@@ -813,7 +1203,7 @@ def get_guild(self, id):
         """
         return self._connection._get_guild(id)
 
-    def get_user(self, id):
+    def get_user(self, id: int) -> Optional[User]:
         """Returns a user with the given ID.
 
         Parameters
@@ -828,7 +1218,7 @@ def get_user(self, id):
         """
         return self._connection.get_user(id)
 
-    def get_emoji(self, id):
+    def get_emoji(self, id: int) -> Optional[Emoji]:
         """Returns an emoji with the given ID.
 
         Parameters
@@ -843,7 +1233,7 @@ def get_emoji(self, id):
         """
         return self._connection.get_emoji(id)
 
-    def get_all_channels(self):
+    def get_all_channels(self) -> Iterator[GuildChannel]:
         """A generator that retrieves every :class:`.abc.GuildChannel` the client can 'access'.
 
         This is equivalent to: ::
@@ -868,7 +1258,7 @@ def get_all_channels(self):
             for channel in guild.channels:
                 yield channel
 
-    def get_all_members(self):
+    def get_all_members(self) -> Iterator[Member]:
         """Returns a generator with every :class:`.Member` the client can see.
 
         This is equivalent to: ::
@@ -888,14 +1278,20 @@ def get_all_members(self):
 
     # listeners/waiters
 
-    async def wait_until_ready(self):
+    async def wait_until_ready(self) -> None:
         """|coro|
 
         Waits until the client's internal cache is all ready.
         """
         await self._ready.wait()
 
-    def wait_for(self, event, *, check=None, timeout=None):
+    def wait_for(
+            self,
+            event: str,
+            *,
+            check: Optional[Callable[[Any, ...], bool]] = None,
+            timeout: Optional[float] = None
+    ) -> Coroutine[Any, Any, Any]:
         """|coro|
 
         Waits for a WebSocket event to be dispatched.
@@ -967,7 +1363,7 @@ def check(reaction, user):
         Raises
         -------
         asyncio.TimeoutError
-            If a timeout is provided and it was reached.
+            If a timeout is provided, and it was reached.
 
         Returns
         --------
@@ -994,7 +1390,7 @@ def _check(*args):
 
     # event registration
 
-    def event(self, coro):
+    def event(self, coro: Coro) -> Coro:
         """A decorator that registers an event to listen to.
 
         You can find more info about the events on the :ref:`documentation below <discord-api-events>`.
@@ -1003,7 +1399,6 @@ def event(self, coro):
 
         Example
         ---------
-
         .. code-block:: python3
 
             @client.event
@@ -1022,48 +1417,128 @@ async def on_ready():
         setattr(self, coro.__name__, coro)
         log.debug('%s has successfully been registered as an event', coro.__name__)
         return coro
-    
-    def on_click(self, custom_id=None):
+
+    def once(
+            self, name: str = MISSING, check: Callable[..., bool] | None = None
+    ) -> Coro:
+        """A decorator that registers an event to listen to only once.
+        For example if you want to perform a database connection once the bot is ready.
+
+        You can find more info about the events on the :ref:`documentation below <discord-api-events>`.
+
+        The events must be a :ref:`coroutine <coroutine>`, if not, :exc:`TypeError` is raised.
+
+        Parameters
+        ----------
+        name: :class:`str`
+            The name of the event we want to listen to. This is passed to
+            :meth:`~discord.Client.wait_for`. Defaults to ``func.__name__``.
+        check: Optional[Callable[..., :class:`bool`]]
+            A predicate to check what to wait for. The arguments must meet the
+            parameters of the event being waited for.
+
+        Raises
+        ------
+        TypeError
+            The coroutine passed is not actually a coroutine.
+
+        Example
+        -------
+
+        .. code-block:: python
+
+            @client.once()
+            async def ready():
+                print('Beep bop, I\\'m ready!')
+
+            @client.once(check=lambda msg: msg.author.id == 693088765333471284)
+            async def message(message):
+                await message.reply('Hey there, how are you?')
         """
-        A decorator that registers a raw_button_click event that checks on execution if the ``custom_id's`` are the same; if so, the :func:`func` is called..
 
-        The function this is attached to must take the same parameters as a
-        `raw_button_click-Event <https://discordpy-message-components.rtfd.io/en/latest/addition.html#on_raw_button_click>`_.
+        def decorator(func: Coro) -> Coro:
+            if not asyncio.iscoroutinefunction(func):
+                raise TypeError("event registered must be a coroutine function")
+
+            async def wrapped() -> None:
+                nonlocal name
+                nonlocal check
+
+                name = func.__name__ if name is MISSING else name
+                if name[:3] == 'on_':
+                    name = name[3:]
+
+                args = await self.wait_for(name, check=check)
+
+                arg_len = func.__code__.co_argcount
+                if arg_len == 0 and args is None:
+                    await func()
+                elif arg_len == 1:
+                    await func(args)
+                else:
+                    await func(*args)
+
+            self.loop.create_task(wrapped())
+            return func
+
+        return decorator
+
+    def on_click(
+            self,
+            custom_id: Optional[Union[Pattern[AnyStr], AnyStr]] = None
+    ) -> Callable[[_ClickCallback], _ClickCallback]:
+        """
+         A decorator with which you can assign a function to a specific :class:`~discord.Button` (or its custom_id).
 
         .. important::
+            The function this is attached to must take the same parameters as a
+            :func:`~discord.on_raw_button_click` event.
+
+        .. warning::
             The func must be a coroutine, if not, :exc:`TypeError` is raised.
 
         Parameters
         ----------
-        custom_id: Optional[str]
-            If the :attr:`custom_id` of the :class:`discord.Button` could not use as an function name
+        custom_id: Optional[Union[Pattern[AnyStr], AnyStr]]
+            If the :attr:`custom_id` of the :class:`~discord.Button` could not be used as a function name,
             or you want to give the function a different name then the custom_id use this one to set the custom_id.
+            You can also specify a regex and if the custom_id matches it, the function will be executed.
+
+            .. note::
+                As the ``custom_id`` is converted to a |pattern_object| put ``^`` in front and ``$`` at the end
+                of the :attr:`custom_id` if you want that the custom_id must exactly match the specified value.
+                Otherwise, something like 'cool blue Button is blue' will let the function bee invoked too.
 
         Example
         -------
-
         .. code-block:: python
 
-            # the Button
+            # the button
             Button(label='Hey im a cool blue Button',
                     custom_id='cool blue Button',
                     style=ButtonStyle.blurple)
 
-            # function that's called when the Button pressed
-            @client.on_click(custom_id='cool blue Button')
-            async def cool_blue_button(i: discord.Interaction, button):
+            # function that's called when the button pressed
+            @client.on_click(custom_id='^cool blue Button$')
+            async def cool_blue_button(i: discord.ComponentInteraction, button: Button):
                 await i.respond(f'Hey you pressed a {button.custom_id}!', hidden=True)
 
-        Raises
-        ------
-        TypeError
+        Returns
+        -------
+        The decorator for the function called when the button clicked
+
+        Raise
+        -----
+        :exc:`TypeError`
             The coroutine passed is not actually a coroutine.
         """
-        def decorator(func):
+        def decorator(func: _ClickCallback) -> _ClickCallback:
             if not asyncio.iscoroutinefunction(func):
                 raise TypeError('event registered must be a coroutine function')
 
-            _name = custom_id if custom_id is not None else func.__name__
+            _custom_id = re.compile(custom_id) if (
+                    custom_id is not None and not isinstance(custom_id, re.Pattern)
+            ) else re.compile(f'^{func.__name__}$')
 
             try:
                 listeners = self._listeners['raw_button_click']
@@ -1071,31 +1546,46 @@ def decorator(func):
                 listeners = []
                 self._listeners['raw_button_click'] = listeners
 
-            listeners.append((func, lambda i, c: str(c.custom_id) == str(custom_id)))
+            def _check(i: ComponentInteraction, c: Button) -> bool:
+                match = _custom_id.match(str(c.custom_id))
+                if match:
+                    i.match = match
+                    return True
+                return False
+
+            listeners.append((func, _check))
             return func
 
         return decorator
-    
-    def on_select(self, custom_id=None):
+
+    def on_select(
+            self,
+            custom_id: Optional[Union[Pattern[AnyStr], AnyStr]] = None
+    ) -> Callable[[_SelectCallback], _SelectCallback]:
         """
-        A decorator with which you can assign a function to a specific :class:`discord.SelectMenu` (or its custom_id).
-        
-        The function this is attached to must take the same parameters as a
-        `raw_selection_select-Event <https://discordpy-message-components.rtfd.io/en/latest/addition.html#on_raw_selection_select>`_.
+        A decorator with which you can assign a function to a specific :class:`~discord.SelectMenu` (or its custom_id).
 
         .. important::
+            The function this is attached to must take the same parameters as a
+            :func:`~discord.on_raw_selection_select` event.
+
+        .. warning::
             The func must be a coroutine, if not, :exc:`TypeError` is raised.
 
         Parameters
         -----------
-        custom_id: Optional[str]
-            If the :attr:`custom_id` of the :class:`discord.SelectMenu` could not use as an function name
+        custom_id: Optional[Union[Pattern[AnyStr], AnyStr]] = None
+            If the `custom_id` of the :class:`~discord.SelectMenu` could not be used as a function name,
             or you want to give the function a different name then the custom_id use this one to set the custom_id.
+            You can also specify a regex and if the custom_id matches it, the function will be executed.
 
+            .. note::
+                As the ``custom_id`` is converted to a |pattern_object| put ``^`` in front and ``$`` at the end
+                of the :attr:`custom_id` if you want that the custom_id must exactly match the specified value.
+                Otherwise, something like 'choose_your_gender later' will let the function bee invoked too.
 
         Example
         -------
-
         .. code-block:: python
 
             # the SelectMenu
@@ -1112,15 +1602,17 @@ async def choose_your_gender(i: discord.Interaction, select_menu):
                 await i.respond(f'You selected `{select_menu.values[0]}`!', hidden=True)
 
         Raises
-        --------
-        TypeError
+        -------
+        :exc:`TypeError`
             The coroutine passed is not actually a coroutine.
         """
-        def decorator(func):
+        def decorator(func: _SelectCallback) -> _SelectCallback:
             if not asyncio.iscoroutinefunction(func):
                 raise TypeError('event registered must be a coroutine function')
 
-            _custom_id = custom_id if custom_id is not None else func.__name__
+            _custom_id = re.compile(custom_id) if (
+                    custom_id is not None and not isinstance(custom_id, re.Pattern)
+            ) else re.compile(f'^{func.__name__}$')
 
             try:
                 listeners = self._listeners['raw_selection_select']
@@ -1128,18 +1620,1017 @@ def decorator(func):
                 listeners = []
                 self._listeners['raw_selection_select'] = listeners
 
-            listeners.append((func, lambda i, c: str(c.custom_id) == str(_custom_id)))
+            def _check(i: ComponentInteraction, c: Button) -> bool:
+                match = _custom_id.match(str(c.custom_id))
+                if match:
+                    i.match = match
+                    return True
+                return False
+
+            listeners.append((func, _check))
             return func
 
         return decorator
-        
 
+    def on_submit(
+            self,
+            custom_id: Optional[Union[Pattern[AnyStr], AnyStr]] = None
+    ) -> Callable[[_SubmitCallback], _SubmitCallback]:
+        """
+         A decorator with which you can assign a function to a specific :class:`~discord.Modal` (or its custom_id).
+
+        .. important::
+            The function this is attached to must take the same parameters as a
+            :func:`~discord.on_modal_submit` event.
+
+        .. warning::
+            The func must be a coroutine, if not, :exc:`TypeError` is raised.
+
+
+        Parameters
+        ----------
+        custom_id: Optional[Union[Pattern[AnyStr], AnyStr]]
+            If the :attr:`~discord.Modal.custom_id` of the modal could not be used as a function name,
+            or you want to give the function a different name then the custom_id use this one to set the custom_id.
+            You can also specify a regex and if the custom_id matches it, the function will be executed.
+
+            .. note::
+                As the ``custom_id`` is converted to a |pattern_object| put ``^`` in front and ``$`` at the end
+                of the :attr:`custom_id` if you want that the custom_id must exactly match the specified value.
+                Otherwise, something like 'suggestions_modal_submit_private' will let the function bee invoked too.
+
+            .. tip::
+                The resulting |match_object| object will be
+                available under the :class:`~discord.ModalSubmitInteraction.match` attribute of the interaction.
 
-    async def change_presence(self, *, activity=None, status=None, afk=False):
+                **See example below.**
+
+        Examples
+        --------
+        .. code-block:: python
+            :caption: Simple example of a Modal with a custom_id and a function that's called when the Modal is submitted.
+            :emphasize-lines: 9, 14
+
+            # the Modal
+            Modal(
+                title='Create a new suggestion',
+                custom_id='suggestions_modal',
+                components=[...]
+            )
+
+            # function that's called when the Modal is submitted
+            @client.on_submit(custom_id='^suggestions_modal$')
+            async def suggestions_modal_callback(i: discord.ModalSubmitInteraction):
+                ...
+
+            # This can also be done based on the function name
+            @client.on_submit()
+            async def suggestions_modal(i: discord.ModalSubmitInteraction):
+                ...
+
+
+        .. code-block:: python
+            :caption: You can also use a more advanced RegEx containing groups to easily allow dynamic custom-id's
+            :emphasize-lines: 1, 3
+
+            @client.on_submit(custom_id='^ticket_answer:(?P<id>[0-9]+)$')
+            async def ticket_answer_callback(i: discord.ModalSubmitInteraction):
+                user_id = int(i.match['id'])
+                user = client.get_user(user_id) or await client.fetch_user(user_id)
+
+        Raises
+        ------
+        :exc:`TypeError`
+            The coroutine passed is not actually a coroutine.
+        """
+        def decorator(func: _SubmitCallback) -> _SubmitCallback:
+            if not asyncio.iscoroutinefunction(func):
+                raise TypeError('event registered must be a coroutine function')
+
+            _custom_id = re.compile(custom_id) if (
+                    custom_id is not None and not isinstance(custom_id, re.Pattern)
+            ) else re.compile(f'^{func.__name__}$')
+
+            try:
+                listeners = self._listeners['modal_submit']
+            except KeyError:
+                listeners = []
+                self._listeners['modal_submit'] = listeners
+
+            def _check(i: ModalSubmitInteraction) -> bool:
+                match = _custom_id.match(str(i.custom_id))
+                if match:
+                    i.match = match
+                    return True
+                return False
+
+            listeners.append((func, _check))
+            return func
+
+        return decorator
+
+    def slash_command(
+            self,
+            name: Optional[str] = None,
+            name_localizations: Optional[Localizations] = Localizations(),
+            description: Optional[str] = None,
+            description_localizations: Optional[Localizations] = Localizations(),
+            allow_dm: bool = MISSING,
+            allowed_contexts: Optional[List[InteractionContextType]] = MISSING,
+            allowed_integration_types: Optional[List[AppIntegrationType]] = MISSING,
+            is_nsfw: bool = MISSING,
+            default_required_permissions: Optional[Permissions] = None,
+            options: Optional[List] = [],
+            guild_ids: Optional[List[int]] = None,
+            connector: Optional[dict] = {},
+            option_descriptions: Optional[dict] = {},
+            option_descriptions_localizations: Optional[Dict[str, Localizations]] = {},
+            base_name: Optional[str] = None,
+            base_name_localizations: Optional[Localizations] = Localizations(),
+            base_desc: Optional[str] = None,
+            base_desc_localizations: Optional[Localizations] = Localizations(),
+            group_name: Optional[str] = None,
+            group_name_localizations: Optional[Localizations] = Localizations(),
+            group_desc: Optional[str] = None,
+            group_desc_localizations: Optional[Localizations] = Localizations()
+    ) -> Callable[
+        [Awaitable[Any]],
+        Union[SlashCommand, GuildOnlySlashCommand, SubCommand, GuildOnlySubCommand]
+    ]:
+        """A decorator that adds a slash-command to the client. The function this is attached to must be a :ref:`coroutine <coroutine>`.
+
+        .. warning::
+            :attr:`~discord.Client.sync_commands` of the :class:`Client` instance  must be set to :obj:`True`
+            to register a command if it does not already exist and update it if changes where made.
+
+        .. note::
+            Any of the following parameters are only needed when the corresponding target was not used before
+            (e.g. there is already a command in the code that has these parameters set) - otherwise it will replace the previous value or update it for iterables.
+
+            - ``allow_dm``
+            - ``allowed_contexts`` (update)
+            - ``allowed_integration_types`` (update)
+            - ``is_nsfw``
+            - ``base_name_localizations``
+            - ``base_desc``
+            - ``base_desc_localizations``
+            - ``group_name_localizations``
+            - ``group_desc``
+            - ``group_desc_localizations``
+
+        Parameters
+        -----------
+        name: Optional[:class:`str`]
+            The name of the command. Must only contain a-z, _ and - and be 1-32 characters long.
+            Default to the functions name.
+        name_localizations: Optional[:class:`~discord.Localizations`]
+            Localizations object for name field. Values follow the same restrictions as :attr:`name`
+        description: Optional[:class:`str`]
+            The description of the command shows up in the client. Must be between 1-100 characters long.
+            Default to the functions docstring or "No Description".
+        description_localizations: Optional[:class:`~discord.Localizations`]
+            Localizations object for description field. Values follow the same restrictions as :attr:`description`
+        allow_dm: Optional[:class:`bool`]
+            **Deprecated**: Use :attr:`allowed_contexts` instead.
+            Indicates whether the command is available in DMs with the app, only for globally-scoped commands.
+            By default, commands are visible.
+        allowed_contexts: Optional[List[:class:`~discord.InteractionContextType`]]
+            **global commands only**: The contexts in which the command is available.
+            By default, commands are available in all contexts.
+        allowed_integration_types: Optional[List[:class:`~discord.AppIntegrationType`]]
+            **global commands only**: The types of app integrations where the command is available.
+            Default to the app's :ddocs:`configured integration types <resources/application#setting-supported-installation-contexts>`
+        is_nsfw: :class:`bool`
+            Whether this command is an :sup-art:`NSFW command <10123937946007-Age-Restricted-Commands>` , default :obj:`False`.
+
+            .. note::
+                Currently all sub-commands of a command that is marked as *NSFW* are NSFW too.
+
+        default_required_permissions: Optional[:class:`~discord.Permissions`]
+             Permissions that a Member needs by default to execute(see) the command.
+        options: Optional[List[:class:`~discord.SlashCommandOption`]]
+            A list of max. 25 options for the command. If not provided the options will be generated
+            using :meth:`generate_options` that creates the options out of the function parameters.
+            Required options **must** be listed before optional ones.
+            Use :attr:`options` to connect non-ascii option names with the parameter of the function.
+        guild_ids: Optional[List[:class:`int`]]
+            ID's of guilds this command should be registered in. If empty, the command will be global.
+        connector: Optional[Dict[:class:`str`, :class:`str`]]
+            A dictionary containing the name of function-parameters as keys and the name of the option as values.
+            Useful for using non-ascii Letters in your option names without getting ide-errors.
+        option_descriptions: Optional[Dict[:class:`str`, :class:`str`]]
+            Descriptions the :func:`generate_options` should take for the Options that will be generated.
+            The keys are the :attr:`~discord.SlashCommandOption.name` of the option and the value the :attr:`~discord.SlashCommandOption.description`.
+
+            .. note::
+                This will only be used if ``options`` is not set.
+
+        option_descriptions_localizations: Optional[Dict[:class:`str`, :class:`~discord.Localizations`]]
+            Localized :attr:`~discord.SlashCommandOption.description` for the options.
+            In the format ``{'option_name': Localizations(...)}``
+        base_name: Optional[:class:`str`]
+            The name of the base-command(a-z, _ and -, 1-32 characters) if you want the command
+            to be in a command-/sub-command-group.
+            If the base-command does not exist yet, it will be added.
+        base_name_localizations: Optional[:class:`~discord.Localizations`]
+            Localized ``base_name``'s for the command.
+        base_desc: Optional[:class:`str`]
+            The description of the base-command(1-100 characters).
+        base_desc_localizations: Optional[:class:`~discord.Localizations`]
+            Localized ``base_description``'s for the command.
+        group_name: Optional[:class:`str`]
+            The name of the command-group(a-z, _ and -, 1-32 characters) if you want the command to be in a sub-command-group.
+        group_name_localizations: Optional[:class:`~discord.Localizations`]
+            Localized ``group_name``'s for the command.
+        group_desc: Optional[:class:`str`]
+            The description of the sub-command-group(1-100 characters).
+        group_desc_localizations: Optional[:class:`~discord.Localizations`]
+            Localized ``group_desc``'s for the command.
+
+        Raises
+        ------
+        :exc:`TypeError`:
+            The function the decorator is attached to is not actual a :ref:`coroutine <coroutine>`
+            or a parameter passed to :class:`SlashCommandOption` is invalid for the ``option_type`` or the ``option_type``
+            itself is invalid.
+        :exc:`~discord.InvalidArgument`:
+            You passed ``group_name`` but no ``base_name``.
+        :exc:`ValueError`:
+            Any of ``name``, ``description``, ``options``, ``base_name``, ``base_desc``, ``group_name`` or ``group_desc`` is not valid.
+
+        Returns
+        -------
+        Union[:class:`SlashCommand`, :class:`GuildOnlySlashCommand`, :class:`SubCommand`, :class:`GuildOnlySubCommand`]:
+            - If neither ``guild_ids`` nor ``base_name`` passed: An instance of :class:`~discord.SlashCommand`.
+            - If ``guild_ids`` and no ``base_name`` where passed: An instance of :class:`~discord.GuildOnlySlashCommand` representing the guild-only slash-commands.
+            - If ``base_name`` and no ``guild_ids`` where passed: An instance of :class:`~discord.SubCommand`.
+            - If ``base_name`` and ``guild_ids`` passed: instance of :class:`~discord.GuildOnlySubCommand` representing the guild-only sub-commands.
+        """
+
+        def decorator(func: Awaitable[Any]) -> Union[SlashCommand, GuildOnlySlashCommand, SubCommand, GuildOnlySubCommand]:
+            """
+
+            Parameters
+            ----------
+            func: Awaitable[Any]
+                The function for the decorator. This must be a :ref:`coroutine <coroutine>`.
+
+            Returns
+            -------
+            The slash-command registered.
+                - If neither ``guild_ids`` nor ``base_name`` passed: An instance of :class:`~discord.SlashCommand`.
+                - If ``guild_ids`` and no ``base_name`` where passed: An instance of :class:`~discord.GuildOnlySlashCommand` representing the guild-only slash-commands.
+                - If ``base_name` and no ``guild_ids`` where passed: An instance of :class:`~discord.SubCommand`.
+                - If ``base_name`` and ``guild_ids`` passed: instance of :class:`~discord.GuildOnlySubCommand` representing the guild-only sub-commands.
+            """
+            if not asyncio.iscoroutinefunction(func):
+                raise TypeError('The slash-command registered  must be a coroutine.')
+            _name = (name or func.__name__).lower()
+            _description = description if description else (inspect.cleandoc(func.__doc__)[:100] if func.__doc__ else 'No Description')
+            _options = options or generate_options(
+                func,
+                descriptions=option_descriptions,
+                descriptions_localizations=option_descriptions_localizations,
+                connector=connector
+            )
+            if group_name and not base_name:
+                raise InvalidArgument(
+                    'You have to provide the `base_name` parameter if you want to create a sub-command or sub-command-group.'
+                )
+            guild_cmds = []
+            if guild_ids:
+                guild_app_cmds = self._guild_specific_application_commands
+                for guild_id in guild_ids:
+                    base, base_command, sub_command_group = None, None, None
+                    try:
+                        guild_app_cmds[guild_id]
+                    except KeyError:
+                        guild_app_cmds[guild_id] = {'chat_input': {}, 'message': {}, 'user': {}}
+                    if base_name:
+                        try:
+                            base_command = guild_app_cmds[guild_id]['chat_input'][base_name]
+                        except KeyError:
+                            base_command = guild_app_cmds[guild_id]['chat_input'][base_name] = SlashCommand(
+                                name=base_name,
+                                name_localizations=base_name_localizations,
+                                description=base_desc or 'No Description',
+                                description_localizations=base_desc_localizations,
+                                default_member_permissions=default_required_permissions,
+                                is_nsfw=is_nsfw if is_nsfw is not MISSING else False,
+                                guild_id=guild_id
+                            )
+                        else:
+
+                            if base_desc:
+                                base_command.description = base_command.description
+                            if is_nsfw is not MISSING:
+                                base_command.is_nsfw = is_nsfw
+                            if allow_dm is not MISSING:
+                                base_command.allow_dm = allow_dm
+                            base_command.name_localizations.update(base_name_localizations)
+                            base_command.description_localizations.update(base_desc_localizations)
+                        base = base_command
+                    if group_name:
+                        try:
+                            sub_command_group = guild_app_cmds[guild_id]['chat_input'][base_name]._sub_commands[group_name]
+                        except KeyError:
+                            sub_command_group = guild_app_cmds[guild_id]['chat_input'][base_name]._sub_commands[group_name] = SubCommandGroup(
+                                parent=base_command,
+                                name=group_name,
+                                name_localizations=group_name_localizations,
+                                description=group_desc or 'No Description',
+                                description_localizations=group_desc_localizations,
+                                guild_id=guild_id
+                            )
+                        else:
+                            if group_desc:
+                                sub_command_group.description = group_desc
+                            sub_command_group.name_localizations.update(group_name_localizations)
+                            sub_command_group.description_localizations.update(group_desc_localizations)
+                        base = sub_command_group
+                    if base:
+                        base._sub_commands[_name] = SubCommand(
+                            parent=base,
+                            name=_name,
+                            name_localizations=name_localizations,
+                            description=_description,
+                            description_localizations=description_localizations,
+                            options=_options,
+                            connector=connector,
+                            func=func
+                        )
+                        guild_cmds.append(base._sub_commands[_name])
+                    else:
+                        guild_app_cmds[guild_id]['chat_input'][_name] = SlashCommand(
+                            func=func,
+                            guild_id=guild_id,
+                            name=_name,
+                            name_localizations=name_localizations,
+                            description=_description,
+                            description_localizations=description_localizations,
+                            default_member_permissions=default_required_permissions,
+                            is_nsfw=is_nsfw if is_nsfw is not MISSING else False,
+                            options=_options,
+                            connector=connector
+                        )
+                        guild_cmds.append(guild_app_cmds[guild_id]['chat_input'][_name])
+                if base_name:
+                    base = GuildOnlySlashCommand(
+                        client=self,
+                        guild_ids=guild_ids,
+                        name=_name,
+                        description=_description,
+                        default_member_permissions=default_required_permissions,
+                        is_nsfw=is_nsfw if is_nsfw is not MISSING else False,
+                        options=_options
+                    )
+                    if group_name:
+                        base = GuildOnlySubCommandGroup(
+                            client=self,
+                            parent=base,
+                            guild_ids=guild_ids,
+                            name=_name,
+                            description=_description,
+                            default_member_permissions=default_required_permissions,
+                            options=_options
+                        )
+                    return GuildOnlySubCommand(
+                        client=self,
+                        parent=base,
+                        func=func,
+                        guild_ids=guild_ids,
+                        commands=guild_cmds,
+                        name=_name,
+                        description=_description,
+                        options=_options,
+                        connector=connector
+                    )
+                return GuildOnlySlashCommand(
+                    client=self,
+                    func=func,
+                    guild_ids=guild_ids,
+                    commands=guild_cmds,
+                    name=_name,
+                    description=_description,
+                    default_member_permission=default_required_permissions,
+                    is_nsfw=is_nsfw if is_nsfw is not MISSING else False,
+                    options=_options,
+                    connector=connector
+                )
+            else:
+                app_cmds = self._application_commands_by_type
+                base, base_command, sub_command_group = None, None, None
+                if base_name:
+                    try:
+                        base_command = app_cmds['chat_input'][base_name]
+                    except KeyError:
+                        base_command = app_cmds['chat_input'][base_name] = SlashCommand(
+                            name=base_name,
+                            name_localizations=base_name_localizations,
+                            description=base_desc or 'No Description',
+                            description_localizations=base_desc_localizations,
+                            default_member_permissions=default_required_permissions,
+                            allow_dm=allow_dm if allow_dm is not MISSING else True,
+                            is_nsfw=is_nsfw if is_nsfw is not MISSING else False,
+                            integration_types=allowed_integration_types if allowed_integration_types is not MISSING else None,
+                            contexts=allowed_contexts if allowed_contexts is not MISSING else None
+                        )
+                    else:
+                        if base_desc:
+                            base_command.description = base_desc
+                        if is_nsfw is not MISSING:
+                            base_command.is_nsfw = is_nsfw
+                        if allow_dm is not MISSING:
+                            base_command.allow_dm = allow_dm
+                        if allowed_integration_types is not MISSING:
+                            base_command.integration_types.update(allowed_integration_types)
+                        if allowed_contexts is not MISSING:
+                            base_command.contexts.update(allowed_contexts)
+                        base_command.name_localizations.update(base_name_localizations)
+                        base_command.description_localizations.update(base_desc_localizations)
+                    base = base_command
+                if group_name:
+                    try:
+                        sub_command_group = app_cmds['chat_input'][base_name]._sub_commands[group_name]
+                    except KeyError:
+                        sub_command_group = app_cmds['chat_input'][base_name]._sub_commands[group_name] = SubCommandGroup(
+                            parent=base_command,
+                            name=group_name,
+                            name_localizations=group_name_localizations,
+                            description=group_desc or 'No Description',
+                            description_localizations=group_desc_localizations
+                        )
+                    else:
+                        if group_desc:
+                            sub_command_group.description = group_desc
+                        sub_command_group.name_localizations.update(group_name_localizations)
+                        sub_command_group.description_localizations.update(group_desc_localizations)
+                    base = sub_command_group
+                if base:
+                    command = base._sub_commands[_name] = SubCommand(
+                        parent=base,
+                        func=func,
+                        name=_name,
+                        name_localizations=name_localizations,
+                        description=_description,
+                        description_localizations=description_localizations,
+                        options=_options,
+                        connector=connector
+                    )
+                else:
+                    command = app_cmds['chat_input'][_name] = SlashCommand(
+                        func=func,
+                        name=_name,
+                        name_localizations=name_localizations,
+                        description=_description or 'No Description',
+                        description_localizations=description_localizations,
+                        default_member_permissions=default_required_permissions,
+                        allow_dm=allow_dm if allow_dm is not MISSING else True,
+                        integration_types=allowed_integration_types if allowed_integration_types is not MISSING else None,
+                        contexts=allowed_contexts if allowed_contexts is not MISSING else None,
+                        is_nsfw=is_nsfw if is_nsfw is not MISSING else False,
+                        options=_options,
+                        connector=connector
+                    )
+
+                return command
+        return decorator
+
+    def activity_primary_entry_point_command(
+            self,
+            name: Optional[str] = 'launch',
+            name_localizations: Localizations = Localizations(),
+            description: Optional[str] = '',
+            description_localizations: Localizations = Localizations(),
+            default_required_permissions: Optional[Permissions] = None,
+            allowed_contexts: Optional[List[InteractionContextType]] = None,
+            allowed_integration_types: Optional[List[AppIntegrationType]] = None,
+            is_nsfw: bool = False,
+    ) -> Callable[[Awaitable[Any]], SlashCommand]:
+        """
+        A decorator that sets the handler function for the
+        :ddocs:`primary entry point <interactions/application-commands#entry-point-commands>` of an activity.
+
+        **This overwrites the default activity command created by Discord.**
+
+        .. note::
+            If you only want to change the name, description, permissions, etc. of the default activity command,
+            use :meth:`update_activity_command` instead.
+
+        Parameters
+        ----------
+        name: Optional[:class:`str`]
+            The name of the activity command. Default to 'launch'.
+        name_localizations: :class:`Localizations`
+            Localized ``name``'s.
+        description: :class:`str`
+            The description of the activity command.
+        description_localizations: :class:`Localizations`
+            Localized ``description``'s.
+        default_required_permissions: Optional[:class:`Permissions`]
+            Permissions that a member needs by default to execute(see) the command.
+        allowed_contexts: Optional[List[:class:`~discord.InteractionContextType`]]
+            The contexts in which the command is available.
+            By default, commands are available in all contexts.
+        allowed_integration_types: Optional[List[:class:`~discord.AppIntegrationType`]]
+            **global commands only**: The types of app integrations where the command is available.
+            Default to the app's :ddocs:`configured integration types <resources/application#setting-supported-installation-contexts>`
+        is_nsfw: :class:`bool`
+            Whether this command is an :sup-art:`NSFW command <10123937946007-Age-Restricted-Commands>`, default :obj:`False`.
+
+        Returns
+        -------
+        ~discord.ActivityEntryPointCommand:
+            The activity command to be registered as the primary entry point.
+
+        Raises
+        ------
+        :exc:`TypeError`:
+            The function the decorator is attached to is not actual a :ref:`coroutine <coroutine>`.
+        """
+
+        def decorator(func: Awaitable[Any]) -> SlashCommand:
+            if not asyncio.iscoroutinefunction(func):
+                raise TypeError('The activity command function registered must be a coroutine.')
+            _name = name or func.__name__
+            cmd = SlashCommand(
+                func=func,
+                name=_name,
+                name_localizations=name_localizations,
+                description=description,
+                description_localizations=description_localizations,
+                default_member_permissions=default_required_permissions,
+                contexts=allowed_contexts,
+                integration_types=allowed_integration_types,
+                is_nsfw=is_nsfw
+            )
+            self._application_commands_by_type['primary_entry_point'][_name] = cmd
+            self._activity_primary_entry_point_command = cmd
+            return cmd
+        return decorator
+
+    def message_command(
+            self,
+            name: Optional[str] = None,
+            name_localizations: Localizations = Localizations(),
+            default_required_permissions: Optional[Permissions] = None,
+            allow_dm: bool = True,
+            allowed_contexts: Optional[List[InteractionContextType]] = MISSING,
+            allowed_integration_types: Optional[List[AppIntegrationType]] = MISSING,
+            is_nsfw: bool = False,
+            guild_ids: Optional[List[int]] = None
+    ) -> Callable[[Awaitable[Any]], MessageCommand]:
+        """
+        A decorator that registers a :class:`MessageCommand` (shows up under ``Apps`` when right-clicking on a message)
+        to the client. The function this is attached to must be a :ref:`coroutine <coroutine>`.
+
+        .. note::
+
+            :attr:`~discord.Client.sync_commands` of the :class:`~discord.Client` instance  must be set to :obj:`True`
+            to register a command if it does not already exit and update it if changes where made.
+
+        Parameters
+        ----------
+        name: Optional[:class:`str`]
+            The name of the message-command, default to the functions name.
+            Must be between 1-32 characters long.
+        name_localizations: :class:`Localizations`
+            Localized ``name``'s.
+        default_required_permissions: Optional[:class:`Permissions`]
+            Permissions that a member needs by default to execute(see) the command.
+        allow_dm: :class:`bool`
+            **Deprecated**: Use :attr:`allowed_contexts` instead.
+            Indicates whether the command is available in DMs with the app, only for globally-scoped commands.
+            By default, commands are visible.
+        allowed_contexts: Optional[List[:class:`~discord.InteractionContextType`]]
+            **global commands only**: The contexts in which the command is available.
+            By default, commands are available in all contexts.
+        allowed_integration_types: Optional[List[:class:`~discord.AppIntegrationType`]]
+            **global commands only**: The types of app integrations where the command is available.
+            Default to the app's :ddocs:`configured integration types <resources/application#setting-supported-installation-contexts>`
+        is_nsfw: :class:`bool`
+            Whether this command is an :sup-art:`NSFW command <10123937946007-Age-Restricted-Commands>` , default :obj:`False`.
+        guild_ids: Optional[List[:class:`int`]]
+            ID's of guilds this command should be registered in. If empty, the command will be global.
+
+        Returns
+        -------
+        ~discord.MessageCommand:
+            The message-command registered.
+
+        Raises
+        ------
+        :exc:`TypeError`:
+            The function the decorator is attached to is not actual a :ref:`coroutine <coroutine>`.
+        """
+        def decorator(func: Awaitable[Any]) -> MessageCommand:
+            if not asyncio.iscoroutinefunction(func):
+                raise TypeError('The message-command function registered  must be a coroutine.')
+            _name = name or func.__name__
+            cmd = MessageCommand(
+                guild_ids=guild_ids,
+                func=func,
+                name=_name,
+                name_localizations=name_localizations,
+                default_member_permissions=default_required_permissions,
+                allow_dm=allow_dm,
+                integration_types=allowed_integration_types if allowed_integration_types is not MISSING else None,
+                contexts=allowed_contexts if allowed_contexts is not MISSING else None,
+                is_nsfw=is_nsfw
+            )
+            if guild_ids:
+                for guild_id in guild_ids:
+                    guild_cmd = MessageCommand(
+                        guild_id=guild_id,
+                        func=func,
+                        name=_name,
+                        name_localizations=name_localizations,
+                        default_member_permissions=default_required_permissions,
+                        allow_dm=allow_dm,
+                        is_nsfw=is_nsfw
+                    )
+                    try:
+                        self._guild_specific_application_commands[guild_id]['message'][_name] = guild_cmd
+                    except KeyError:
+                        self._guild_specific_application_commands[guild_id] = {
+                            'chat_input': {},
+                            'message': {_name: guild_cmd},
+                            'user': {}
+                        }
+            else:
+                self._application_commands_by_type['message'][_name] = cmd
+
+            return cmd
+        return decorator
+
+    def user_command(
+            self,
+            name: Optional[str] = None,
+            name_localizations: Localizations = Localizations(),
+            default_required_permissions: Optional[Permissions] = None,
+            allow_dm: bool = True,
+            allowed_contexts: Optional[List[InteractionContextType]] = MISSING,
+            allowed_integration_types: Optional[List[AppIntegrationType]] = MISSING,
+            is_nsfw: bool = False,
+            guild_ids: Optional[List[int]] = None
+    ) -> Callable[[Awaitable[Any]], UserCommand]:
+        """
+        A decorator that registers a :class:`UserCommand` (shows up under ``Apps`` when right-clicking on a user) to the client.
+        The function this is attached to must be a :ref:`coroutine <coroutine>`.
+
+        .. note::
+            :attr:`~discord.Client.sync_commands` of the :class:`~discord.Client` instance  must be set to :obj:`True`
+            to register a command if it does not already exist and update it if changes where made.
+
+        Parameters
+        ----------
+        name: Optional[:class:`str`]
+            The name of the user-command, default to the functions name.
+            Must be between 1-32 characters long.
+        name_localizations: :class:`Localizations`
+            Localized ``name``'s.
+        default_required_permissions: Optional[:class:`Permissions`]
+            Permissions that a member needs by default to execute(see) the command.
+        allow_dm: :class:`bool`
+            **Deprecated**: Use :attr:`allowed_contexts` instead.
+            Indicates whether the command is available in DMs with the app, only for globally-scoped commands.
+            By default, commands are visible.
+        allowed_contexts: Optional[List[:class:`~discord.InteractionContextType`]]
+            **global commands only**: The contexts in which the command is available.
+            By default, commands are available in all contexts.
+        allowed_integration_types: Optional[List[:class:`~discord.AppIntegrationType`]]
+            **global commands only**: The types of app integrations where the command is available.
+            Default to the app's :ddocs:`configured integration types <resources/application#setting-supported-installation-contexts>`
+        is_nsfw: :class:`bool`
+            Whether this command is an :sup-art:`NSFW command <10123937946007-Age-Restricted-Commands>` , default :obj:`False`.
+        guild_ids: Optional[List[:class:`int`]]
+            ID's of guilds this command should be registered in. If empty, the command will be global.
+
+        Returns
+        -------
+        ~discord.UserCommand:
+            The user-command registered.
+
+        Raises
+        ------
+        :exc:`TypeError`:
+            The function the decorator is attached to is not actual a :ref:`coroutine <coroutine>`.
+        """
+        def decorator(func: Awaitable[Any]) -> UserCommand:
+            if not asyncio.iscoroutinefunction(func):
+                raise TypeError('The user-command function registered  must be a coroutine.')
+            _name = name or func.__name__
+            cmd = UserCommand(
+                guild_ids=guild_ids,
+                func=func,
+                name=_name,
+                name_localizations=name_localizations,
+                default_member_permissions=default_required_permissions,
+                allow_dm=allow_dm,
+                integration_types=allowed_integration_types if allowed_integration_types is not MISSING else None,
+                contexts=allowed_contexts if allowed_contexts is not MISSING else None,
+                is_nsfw=is_nsfw
+            )
+            if guild_ids:
+                for guild_id in guild_ids:
+                    guild_cmd = UserCommand(
+                        guild_id=guild_id,
+                        func=func,
+                        name=_name,
+                        name_localizations=name_localizations,
+                        default_member_permissions=default_required_permissions,
+                        allow_dm=allow_dm,
+                        is_nsfw=is_nsfw
+                    )
+                    try:
+                        self._guild_specific_application_commands[guild_id]['user'][_name] = guild_cmd
+                    except KeyError:
+                        self._guild_specific_application_commands[guild_id] = {
+                            'chat_input': {},
+                            'message': {},
+                            'user': {_name: guild_cmd}
+                        }
+            else:
+                self._application_commands_by_type['user'][_name] = cmd
+
+            return cmd
+        return decorator
+
+    async def _sync_commands(self) -> None:
+        if not hasattr(self, 'app'):
+            await self.application_info()
+        state = self._connection  # Speedup attribute access
+        get_commands = self.http.get_application_commands
+        application_id = self.app.id
+
+        to_send = []
+        to_cep = []
+        to_maybe_remove = []
+
+        any_changed = False
+        has_update = False
+
+        log.info('Checking for changes on application-commands for application %s (%s)...', self.app.name, application_id)
+
+        global_registered_raw: List[Dict] = await get_commands(application_id)
+        global_registered: Dict[str, List[ApplicationCommand]] = ApplicationCommand._sorted_by_type(global_registered_raw)
+        self._minimal_registered_global_commands_raw = minimal_registered_global_commands_raw = []
+
+        for x, commands in global_registered.items():
+            for command in commands:
+                if command['name'] in self._application_commands_by_type[x].keys():
+                    cmd = self._application_commands_by_type[x][command['name']]
+                    if cmd != command:
+                        any_changed = has_update = True
+                        c = cmd.to_dict()
+                        c['id'] = command['id']
+                        to_send.append(c)
+                    else:
+                        to_cep.append(command)
+                else:
+                    to_maybe_remove.append(command)
+                    any_changed = True
+            cmd_names = [c['name'] for c in commands]
+            for command in self._application_commands_by_type[x].values():
+                if command.name not in cmd_names:
+                    any_changed = True
+                    to_send.append(command.to_dict())
+
+        if any_changed is True:
+            updated = None
+            if (to_send_count := len(to_send)) == 1 and has_update and not to_maybe_remove:
+                log.info('Detected changes on global application-command %s, updating.', to_send[0]['name'])
+                updated = await self.http.edit_application_command(application_id, to_send[0]['id'], to_send[0])
+            elif len == 1 and not has_update and not to_maybe_remove:
+                log.info('Registering one new global application-command %s.', to_send[0]['name'])
+                updated = await self.http.create_application_command(application_id, to_send[0])
+            else:
+                if to_send_count > 0:
+                    log.info(
+                        f'Detected %s updated/new global application-commands, bulk overwriting them...',
+                        to_send_count
+                    )
+                if not self.delete_not_existing_commands:
+                    to_send.extend(to_maybe_remove)
+                else:
+                    if (to_maybe_remove_count := len(to_maybe_remove)) > 0:
+                        log.info(
+                            'Removing %s global application-command(s) that isn\'t/arent used in this code anymore.'
+                            ' To prevent this set `delete_not_existing_commands` of %s to False',
+                            to_maybe_remove_count,
+                            self.__class__.__name__
+                        )
+                to_send.extend(to_cep)
+                global_registered_raw = await self.http.bulk_overwrite_application_commands(application_id, to_send)
+            if updated:
+                global_registered_raw = await self.http.get_application_commands(application_id)
+            log.info('Synced global application-commands.')
+        else:
+            log.info('No changes on global application-commands found.')
+
+        for updated in global_registered_raw:
+            command_type = str(ApplicationCommandType.try_value(updated['type']))
+            minimal_registered_global_commands_raw.append({'id': int(updated['id']), 'type': command_type, 'name': updated['name']})
+            try:
+                command = self._application_commands_by_type[command_type][updated['name']]
+            except KeyError:
+                command = ApplicationCommand._from_type(state, data=updated)
+                command.func = None
+                self._application_commands[command.id] = command
+            else:
+                command._fill_data(updated)
+                command._state = state
+                self._application_commands[command.id] = command
+
+        log.info('Checking for changes on guild-specific application-commands...')
+
+        any_guild_commands_changed = False
+        self._minimal_registered_guild_commands_raw = minimal_registered_guild_commands_raw = {}
+
+        for guild_id, command_types in self._guild_specific_application_commands.items():
+            to_send = []
+            to_cep = []
+            to_maybe_remove = []
+            any_changed = False
+            has_update = False
+            try:
+                registered_guild_commands_raw = await self.http.get_application_commands(
+                    application_id,
+                    guild_id=guild_id
+                )
+            except HTTPException:
+                warnings.warn(
+                    'Missing access to guild %s or don\'t have the application.commands scope in there, skipping!'
+                    % guild_id
+                )
+                continue
+            minimal_registered_guild_commands_raw[int(guild_id)] = minimal_registered_guild_commands = []
+            registered_guild_commands = ApplicationCommand._sorted_by_type(registered_guild_commands_raw)
+
+            for x, commands in registered_guild_commands.items():
+                for command in commands:
+                    if command['name'] in self._guild_specific_application_commands[guild_id][x].keys():
+                        cmd = self._guild_specific_application_commands[guild_id][x][command['name']]
+                        if cmd != command:
+                            any_changed = has_update = any_guild_commands_changed = True
+                            c = cmd.to_dict()
+                            c['id'] = command['id']
+                            to_send.append(c)
+                        else:
+                            to_cep.append(command)
+                    else:
+                        to_maybe_remove.append(command)
+                        any_changed = True
+                cmd_names = [c['name'] for c in commands]
+                for command in self._guild_specific_application_commands[guild_id][x].values():
+                    if command.name not in cmd_names:
+                        any_changed = True
+                        to_send.append(command.to_dict())
+
+            if any_changed is True:
+                updated = None
+                if len(to_send) == 1 and has_update and not to_maybe_remove:
+                    log.info(
+                        'Detected changes on application-command %s in guild %s (%s), updating.',
+                        to_send[0]['name'],
+                        self.get_guild(int(guild_id)),
+                        guild_id
+                    )
+                    updated = await self.http.edit_application_command(
+                        application_id,
+                        to_send[0]['id'],
+                        to_send[0],
+                        guild_id
+                    )
+                elif len(to_send) == 1 and not has_update and not to_maybe_remove:
+                    log.info(
+                        'Registering one new application-command %s in guild %s (%s).',
+                        to_send[0]['name'],
+                        self.get_guild(int(guild_id)),
+                        guild_id
+                    )
+                    updated = await self.http.create_application_command(application_id, to_send[0], guild_id)
+                else:
+                    if not self.delete_not_existing_commands:
+                        if to_send:
+                            to_send.extend(to_maybe_remove)
+                    else:
+                        if len(to_maybe_remove) > 0:
+                            log.info(
+                                'Removing %s application-command(s) from guild %s (%s) that isn\'t/arent used in this code anymore.'
+                                'To prevent this set `delete_not_existing_commands` of %s to False',
+                                len(to_maybe_remove),
+                                self.get_guild(int(guild_id)),
+                                guild_id,
+                                self.__class__.__name__
+                            )
+                    if len(to_send) != 0:
+                        log.info(
+                            'Detected %s updated/new application-command(s) for guild %s (%s), bulk overwriting them...',
+                            len(to_send),
+                            self.get_guild(int(guild_id)),
+                            guild_id
+                        )
+                    to_send.extend(to_cep)
+                    registered_guild_commands_raw = await self.http.bulk_overwrite_application_commands(
+                        application_id,
+                        to_send,
+                        guild_id
+                    )
+                if updated:
+                    registered_guild_commands_raw = await self.http.get_application_commands(
+                        application_id,
+                        guild_id=guild_id
+                    )
+                log.info('Synced application-commands for %s (%s).' % (guild_id, self.get_guild(int(guild_id))))
+                any_guild_commands_changed = True
+
+            for updated in registered_guild_commands_raw:
+                command_type = str(ApplicationCommandType.try_value(updated['type']))
+                minimal_registered_guild_commands.append({'id': int(updated['id']), 'type': command_type, 'name': updated['name']})
+                try:
+                    command = self._guild_specific_application_commands[int(guild_id)][command_type][updated['name']]
+                except KeyError:
+                    command = ApplicationCommand._from_type(state, data=updated)
+                    command.func = None
+                    self._application_commands[command.id] = command
+                    self.get_guild(int(guild_id))._application_commands[command.id] = command
+                else:
+                    command._fill_data(updated)
+                    command._state = self._connection
+                    self._application_commands[command.id] = command
+
+        if not any_guild_commands_changed:
+            log.info('No changes on guild-specific application-commands found.')
+
+        log.info('Successful synced all global and guild-specific application-commands.')
+
+    def _get_application_command(self, cmd_id: int) -> Optional[ApplicationCommand]:
+        return self._application_commands.get(cmd_id)
+
+    def _remove_application_command(self, command: ApplicationCommand, from_cache: bool = True):
+        if isinstance(command, GuildOnlySlashCommand):
+            for guild_id in command.guild_ids:
+                try:
+                    cmd = self._guild_specific_application_commands[guild_id][command.type.name][command.name]
+                except KeyError:
+                    continue
+                else:
+                    if from_cache:
+                        del cmd
+                    else:
+                        cmd.disabled = True
+                        self._application_commands[cmd.id] = copy.copy(cmd)
+                        del cmd
+            del command
+        else:
+            if from_cache:
+                del command
+            else:
+                command.disabled = True
+                self._application_commands[command.id] = copy.copy(command)
+                if command.guild_id:
+                    self._guild_specific_application_commands[command.guild_id][command.type.name].pop(command.name, None)
+                else:
+                    self._application_commands_by_type[command.type.name].pop(command.name, None)
+
+    @property
+    def application_commands(self) -> List[ApplicationCommand]:
+        """List[:class:`ApplicationCommand`]: Returns a list of any application command that is registered for the bot`"""
+        return list(self._application_commands.values())
+
+    @property
+    def global_application_commands(self) -> List[ApplicationCommand]:
+        """
+        Returns a list of all global application commands that are registered for the bot
+
+        .. note::
+            This requires the bot running and all commands cached, otherwise the list will be empty
+
+        Returns
+        --------
+        List[:class:`ApplicationCommand`]
+            A list of registered global application commands for the bot
+        """
+        commands = []
+        for command in self.application_commands:
+            if not command.guild_id:
+                commands.append(command)
+        return commands
+
+    async def change_presence(
+            self,
+            *,
+            activity: Optional[BaseActivity] = None,
+            status: Optional[Status] = 'online'
+    ) -> None:
         """|coro|
 
         Changes the client's presence.
 
+        .. versionchanged:: 2.0
+                Removed the ``afk`` parameter
+
         Example
         ---------
 
@@ -1155,10 +2646,6 @@ async def change_presence(self, *, activity=None, status=None, afk=False):
         status: Optional[:class:`.Status`]
             Indicates what status to change to. If ``None``, then
             :attr:`.Status.online` is used.
-        afk: Optional[:class:`bool`]
-            Indicates if you are going AFK. This allows the discord
-            client to know how to handle push notifications better
-            for you in case you are actually idle and not lying.
 
         Raises
         ------
@@ -1176,7 +2663,7 @@ async def change_presence(self, *, activity=None, status=None, afk=False):
             status_enum = status
             status = str(status)
 
-        await self.ws.change_presence(activity=activity, status=status, afk=afk)
+        await self.ws.change_presence(activity=activity, status=status)
 
         for guild in self._connection.guilds:
             me = guild.me
@@ -1192,7 +2679,13 @@ async def change_presence(self, *, activity=None, status=None, afk=False):
 
     # Guild stuff
 
-    def fetch_guilds(self, *, limit=100, before=None, after=None):
+    def fetch_guilds(
+            self,
+            *,
+            limit: Optional[int] = 100,
+            before: Union[Snowflake, datetime.datetime, None] = None,
+            after: Union[Snowflake, datetime.datetime, None] = None
+    ) -> GuildIterator:
         """Retrieves an :class:`.AsyncIterator` that enables receiving your guilds.
 
         .. note::
@@ -1235,7 +2728,7 @@ def fetch_guilds(self, *, limit=100, before=None, after=None):
 
         Raises
         ------
-        :exc:`.HTTPException`
+        discord.HTTPException
             Getting the guilds failed.
 
         Yields
@@ -1245,7 +2738,7 @@ def fetch_guilds(self, *, limit=100, before=None, after=None):
         """
         return GuildIterator(self, limit=limit, before=before, after=after)
 
-    async def fetch_template(self, code):
+    async def fetch_template(self, code: Union[Template, str]) -> Template:
         """|coro|
 
         Gets a :class:`.Template` from a discord.new URL or code.
@@ -1271,7 +2764,7 @@ async def fetch_template(self, code):
         data = await self.http.get_template(code)
         return Template(data=data, state=self._connection)
 
-    async def fetch_guild(self, guild_id):
+    async def fetch_guild(self, guild_id: int) -> Guild:
         """|coro|
 
         Retrieves a :class:`.Guild` from an ID.
@@ -1305,7 +2798,14 @@ async def fetch_guild(self, guild_id):
         data = await self.http.get_guild(guild_id)
         return Guild(data=data, state=self._connection)
 
-    async def create_guild(self, name, region=None, icon=None, *, code=None):
+    async def create_guild(
+            self,
+            name: str,
+            region: Optional[VoiceRegion] = None,
+            icon: Optional[bytes] = None,
+            *,
+            code: Optional[str] = None
+    ) -> Guild:
         """|coro|
 
         Creates a :class:`.Guild`.
@@ -1354,7 +2854,7 @@ async def create_guild(self, name, region=None, icon=None, *, code=None):
 
     # Invite management
 
-    async def fetch_invite(self, url, *, with_counts=True):
+    async def fetch_invite(self, url: Union[Invite, str], *, with_counts: bool = True) -> Invite:
         """|coro|
 
         Gets an :class:`.Invite` from a discord.gg URL or ID.
@@ -1391,7 +2891,7 @@ async def fetch_invite(self, url, *, with_counts=True):
         data = await self.http.get_invite(invite_id, with_counts=with_counts)
         return Invite.from_incomplete(state=self._connection, data=data)
 
-    async def delete_invite(self, invite):
+    async def delete_invite(self, invite: Union[Invite, str]) -> None:
         """|coro|
 
         Revokes an :class:`.Invite`, URL, or ID to an invite.
@@ -1419,7 +2919,7 @@ async def delete_invite(self, invite):
 
     # Miscellaneous stuff
 
-    async def fetch_widget(self, guild_id):
+    async def fetch_widget(self, guild_id: int) -> Widget:
         """|coro|
 
         Gets a :class:`.Widget` from a guild ID.
@@ -1449,7 +2949,7 @@ async def fetch_widget(self, guild_id):
 
         return Widget(state=self._connection, data=data)
 
-    async def application_info(self):
+    async def application_info(self) -> AppInfo:
         """|coro|
 
         Retrieves the bot's application information.
@@ -1467,7 +2967,8 @@ async def application_info(self):
         data = await self.http.application_info()
         if 'rpc_origins' not in data:
             data['rpc_origins'] = None
-        return AppInfo(self._connection, data)
+        self.app = app = AppInfo(state=self._connection, data=data)
+        return app
 
     async def fetch_user(self, user_id):
         """|coro|
@@ -1501,52 +3002,7 @@ async def fetch_user(self, user_id):
         data = await self.http.get_user(user_id)
         return User(state=self._connection, data=data)
 
-    @utils.deprecated()
-    async def fetch_user_profile(self, user_id):
-        """|coro|
-
-        Gets an arbitrary user's profile.
-
-        .. deprecated:: 1.7
-
-        .. note::
-
-            This can only be used by non-bot accounts.
-
-        Parameters
-        ------------
-        user_id: :class:`int`
-            The ID of the user to fetch their profile for.
-
-        Raises
-        -------
-        :exc:`.Forbidden`
-            Not allowed to fetch profiles.
-        :exc:`.HTTPException`
-            Fetching the profile failed.
-
-        Returns
-        --------
-        :class:`.Profile`
-            The profile of the user.
-        """
-
-        state = self._connection
-        data = await self.http.get_user_profile(user_id)
-
-        def transform(d):
-            return state._get_guild(int(d['id']))
-
-        since = data.get('premium_since')
-        mutual_guilds = list(filter(None, map(transform, data.get('mutual_guilds', []))))
-        user = data['user']
-        return Profile(flags=user.get('flags', 0),
-                       premium_since=utils.parse_time(since),
-                       mutual_guilds=mutual_guilds,
-                       user=User(data=user, state=state),
-                       connected_accounts=data['connected_accounts'])
-
-    async def fetch_channel(self, channel_id):
+    async def fetch_channel(self, channel_id: int):
         """|coro|
 
         Retrieves a :class:`.abc.GuildChannel` or :class:`.abc.PrivateChannel` with the specified ID.
@@ -1588,7 +3044,7 @@ async def fetch_channel(self, channel_id):
 
         return channel
 
-    async def fetch_webhook(self, webhook_id):
+    async def fetch_webhook(self, webhook_id: int):
         """|coro|
 
         Retrieves a :class:`.Webhook` with the specified ID.
@@ -1609,3 +3065,295 @@ async def fetch_webhook(self, webhook_id):
         """
         data = await self.http.get_webhook(webhook_id)
         return Webhook.from_state(data, state=self._connection)
+
+    async def fetch_all_nitro_stickers(self) -> List[StickerPack]:
+        """|coro|
+
+        Retrieves a :class:`list` with all build-in :class:`~discord.StickerPack` 's.
+
+        Returns
+        --------
+        :class:`~discord.StickerPack`
+            A list containing all build-in sticker-packs.
+        """
+        data = await self.http.get_all_nitro_stickers()
+        packs = [StickerPack(state=self._connection, data=d) for d in data['sticker_packs']]
+        return packs
+
+    async def fetch_voice_regions(self) -> List[VoiceRegionInfo]:
+        """|coro|
+
+        Returns a list of :class:`.VoiceRegionInfo` that can be used when creating or editing a
+        :attr:`VoiceChannel` or :attr:`StageChannel`\'s region.
+
+        .. note::
+
+            This method is an API call.
+            For general usage, consider using the :class:`VoiceRegion` enum instead.
+
+        Returns
+        --------
+        List[:class:`.VoiceRegionInfo`]
+            The voice regions that can be used.
+        """
+        data = await self.http.get_voice_regions()
+        return [VoiceRegionInfo(data=d) for d in data]
+
+    async def create_test_entitlement(
+            self,
+            sku_id: int,
+            target: Union[User, Guild, Snowflake],
+            owner_type: Optional[Literal['guild', 'user']] = MISSING
+    ) -> Entitlement:
+        """|coro|
+
+        .. note::
+
+            This method is only temporary and probably will be removed with or even before a stable v2 release
+            as discord is already redesigning the testing system based on developer feedback.
+
+            See https://github.com/discord/discord-api-docs/pull/6502 for more information.
+
+        Creates a test entitlement to a given :class:`SKU` for a given guild or user.
+        Discord will act as though that user or guild has entitlement to your premium offering.
+
+        After creating a test entitlement, you'll need to reload your Discord client.
+        After doing so, you'll see that your server or user now has premium access.
+
+        Parameters
+        ----------
+        sku_id: :class:`int`
+            The ID of the SKU to create a test entitlement for.
+        target: Union[:class:`User`, :class:`Guild`, :class:`Snowflake`]
+            The target to create a test entitlement for.
+
+            This can be a user, guild or just the ID, if so the owner_type parameter must be set.
+        owner_type: :class:`str`
+            The type of the ``target``, could be ``guild`` or ``user``.
+
+        Returns
+        --------
+        :class:`Entitlement`
+            The created test entitlement.
+        """
+        target = target.id
+
+        if isinstance(target, Guild):
+            owner_type = 1
+        elif isinstance(target, User):
+            owner_type = 2
+        else:
+            if owner_type is MISSING:
+                raise TypeError('owner_type must be set if target is not a Guild or user-like object.')
+            else:
+                owner_type = 1 if owner_type == 'guild' else 2
+
+        data = await self.http.create_test_entitlement(
+            self.app.id,
+            sku_id=sku_id,
+            owner_id=target,
+            owner_type=owner_type
+        )
+        return Entitlement(data=data, state=self._connection)
+
+    async def delete_test_entitlement(self, entitlement_id: int) -> None:
+        """|coro|
+
+        .. note::
+
+            This method is only temporary and probably will be removed with or even before a stable v2 release
+            as discord is already redesigning the testing system based on developer feedback.
+
+            See https://github.com/discord/discord-api-docs/pull/6502 for more information.
+
+        Deletes a currently-active test entitlement.
+        Discord will act as though that user or guild no longer has entitlement to your premium offering.
+
+        Parameters
+        ----------
+        entitlement_id: :class:`int`
+            The ID of the entitlement to delete.
+        """
+        await self.http.delete_test_entitlement(self.app.id, entitlement_id)
+
+    async def fetch_entitlements(
+            self,
+            *,
+            limit: int = 100,
+            user: Optional[User] = None,
+            guild: Optional[Guild] = None,
+            sku_ids: Optional[List[int]] = None,
+            before: Optional[Union[datetime.datetime, Snowflake]] = None,
+            after: Optional[Union[datetime.datetime, Snowflake]] = None,
+            exclude_ended: bool = False
+    ) -> EntitlementIterator:
+        """|coro|
+
+        Parameters
+        ----------
+        limit: :class:`int`
+            The maximum amount of entitlements to fetch.
+            Defaults to ``100``.
+        user: Optional[:class:`User`]
+            The user to fetch entitlements for.
+        guild: Optional[:class:`Guild`]
+            The guild to fetch entitlements for.
+        sku_ids: Optional[List[:class:`int`]]
+            Optional list of SKU IDs to check entitlements for
+        before: Optional[Union[:class:`datetime.datetime`, :class:`Snowflake`]]
+            Retrieve entitlements before this date or object.
+            If a date is provided it must be a timezone-naive datetime representing UTC time.
+        after: Optional[Union[:class:`datetime.datetime`, :class:`Snowflake`]]
+            Retrieve entitlements after this date or object.
+            If a date is provided it must be a timezone-naive datetime representing UTC time.
+        exclude_ended: :class:`bool`
+            Whether ended entitlements should be fetched or not. Defaults to ``False``.
+
+        Return
+        ------
+        :class:`AsyncIterator`
+            An iterator to fetch all entitlements for the current application.
+        """
+        return EntitlementIterator(
+            state=self._connection,
+            limit=limit,
+            user_id=user.id,
+            guild_id=guild.id,
+            sku_ids=sku_ids,
+            before=before,
+            after=after,
+            exclude_ended=exclude_ended
+        )
+
+    async def consume_entitlement(self, entitlement_id: int) -> None:
+        """|coro|
+
+        For one-time purchase :attr:`~discord.SKUType.consumable` SKUs,
+        marks a given entitlement for the user as consumed.
+        :attr:`~discord.Entitlement.consumed` will be ``False`` for this entitlement
+        when using :meth:`.fetch_entitlements`.
+
+        Parameters
+        ----------
+        entitlement_id: :class:`int`
+            The ID of the entitlement to consume.
+        """
+        await self.http.consume_entitlement(self.app.id, entitlement_id)
+
+    async def update_primary_entry_point_command(
+            self,
+            name: Optional[str] = MISSING,
+            name_localizations: Localizations = MISSING,
+            description: Optional[str] = MISSING,
+            description_localizations: Localizations = MISSING,
+            default_required_permissions: Optional[Permissions] = MISSING,
+            allowed_contexts: Optional[List[InteractionContextType]] = MISSING,
+            allowed_integration_types: Optional[List[AppIntegrationType]] = MISSING,
+            is_nsfw: bool = MISSING,
+            handler: EntryPointHandlerType = MISSING
+    ):
+        """|coro|
+
+        Update the :ddocs:`primary entry point command <interactions/application-commands#entry-point-commands>`_ of the application.
+
+        If you don't want to handle the command, set ``handler`` to :attr:`EntryPointHandlerType.discord`
+
+        Parameters
+        ----------
+        name: Optional[:class:`str`]
+            The name of the activity command.
+        name_localizations: :class:`Localizations`
+            Localized ``name``'s.
+        description: Optional[:class:`str`]
+            The description of the activity command.
+        description_localizations: :class:`Localizations`
+            Localized ``description``'s.
+        default_required_permissions: Optional[:class:`Permissions`]
+            Permissions that a member needs by default to execute(see) the command.
+        allowed_contexts: Optional[List[:class:`~discord.InteractionContextType`]]
+            The contexts in which the command is available.
+            By default, commands are available in all contexts.
+        allowed_integration_types: Optional[List[:class:`~discord.AppIntegrationType`]]
+            The types of app integrations where the command is available.
+            Default to the app's :ddocs:`configured integration types <resources/application#setting-supported-installation-contexts>`
+        is_nsfw: :class:`bool`
+            Whether this command is an :sup-art:`NSFW command <10123937946007-Age-Restricted-Commands>` , default :obj:`False`.
+        handler: :class:`EntryPointHandlerType`
+            The handler for the primary entry point command.
+            Default to :attr:`EntryPointHandlerType.discord`, unless :attr:`.activity_primary_entry_point_command` is set.
+
+        Returns
+        -------
+        :class:`~discord.ActivityEntryPointCommand`
+            The updated primary entry point command.
+
+        Raises
+        ------
+        :exc:`~discord.HTTPException`
+            Editing the command failed.
+        """
+
+        try:
+            primary_entry_point_command = list(self._application_commands_by_type['primary_entry_point'].values())[0]
+        except IndexError:
+            #  Request global application commands to get the primary entry point command
+
+            # Update this if discord adds a way to get the primary entry point command directly
+            commands_raw = await self.http.get_application_commands(self.app.id)
+            commands_sorted = ApplicationCommand._sorted_by_type(commands_raw)
+            try:
+                primary_entry_point_command = commands_sorted['primary_entry_point'][0]
+            except IndexError:
+                # create a primary entry point command if it does not exist
+                primary_entry_point_command = ActivityEntryPointCommand(
+                    name='launch' if name is MISSING else name,
+                    name_localizations=None if name_localizations is MISSING else name_localizations,
+                    description='launch tis activity' if description is MISSING else description,
+                    description_localizations=None if description_localizations is MISSING else description_localizations,
+                    default_member_permissions=None if default_required_permissions is MISSING else default_required_permissions,
+                    contexts=None if allowed_contexts is MISSING else allowed_contexts,
+                    integration_types=None if allowed_integration_types is MISSING else allowed_integration_types,
+                    is_nsfw=False if is_nsfw is MISSING else is_nsfw,
+                    handler=EntryPointHandlerType.discord if handler is MISSING else handler
+                )
+
+                self._application_commands_by_type['primary_entry_point'][primary_entry_point_command.name] = primary_entry_point_command
+
+                # Register the primary entry point command
+                data = await self.http.create_application_command(
+                    self.app.id,
+                    primary_entry_point_command.to_dict()
+                )
+                primary_entry_point_command._fill_data(data)
+                self._application_commands[primary_entry_point_command.id] = primary_entry_point_command
+                return primary_entry_point_command
+
+        data = {}
+        if name is not MISSING:
+            data['name'] = name
+        if name_localizations is not MISSING:
+            data['name_localizations'] = name_localizations.to_dict() if name_localizations else None
+        if description is not MISSING:
+            data['description'] = description
+        if description_localizations is not MISSING:
+            data['description_localizations'] = description_localizations.to_dict() if description_localizations else None
+        if default_required_permissions is not MISSING:
+            data['default_member_permissions'] = default_required_permissions.value
+        if allowed_contexts is not MISSING:
+            data['contexts'] = [ctx.value for ctx in allowed_contexts]
+        if allowed_integration_types is not MISSING:
+            data['integration_types'] = [integration_type.value for integration_type in allowed_integration_types]
+        if is_nsfw is not MISSING:
+            data['is_nsfw'] = is_nsfw
+        if handler is not MISSING:
+            data['handler'] = handler.value
+
+        response = await self.http.edit_application_command(self.app.id, primary_entry_point_command.id, data)
+        new_command = primary_entry_point_command.from_dict(self._connection, response)
+
+        if (callback := primary_entry_point_command.func) and handler != EntryPointHandlerType.discord:
+            new_command.func = callback
+
+        self._application_commands_by_type['primary_entry_point'][new_command.name] = new_command
+        self._application_commands[new_command.id] = new_command
+        return new_command
diff --git a/discord/colour.py b/discord/colour.py
index fbf9aaef..aefd7041 100644
--- a/discord/colour.py
+++ b/discord/colour.py
@@ -3,7 +3,7 @@
 """
 The MIT License (MIT)
 
-Copyright (c) 2015-present Rapptz
+Copyright (c) 2015-2021 Rapptz & (c) 2021-present mccoderpy
 
 Permission is hereby granted, free of charge, to any person obtaining a
 copy of this software and associated documentation files (the "Software"),
diff --git a/discord/components.py b/discord/components.py
index f20e5a78..d980ff4b 100644
--- a/discord/components.py
+++ b/discord/components.py
@@ -1,783 +1,1800 @@
-# -*- coding: utf-8 -*-
-
-"""
-The MIT License (MIT)
-
-Copyright (c) 2015-present mccuber04#2960
-
-Permission is hereby granted, free of charge, to any person obtaining a
-copy of this software and associated documentation files (the "Software"),
-to deal in the Software without restriction, including without limitation
-the rights to use, copy, modify, merge, publish, distribute, sublicense,
-and/or sell copies of the Software, and to permit persons to whom the
-Software is furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
-DEALINGS IN THE SOFTWARE.
-"""
-
-import typing
-from .enums import ComponentType, ButtonStyle
-from .emoji import Emoji
-from typing import Union
-from .partial_emoji import PartialEmoji
-from .errors import InvalidArgument, InvalidButtonUrl, URLAndCustomIDNotAlowed, EmptyActionRow
-
-__all__ = ('Button', 'SelectMenu', 'ActionRow', 'SelectOption')
-
-
-class Button:
-    """
-    Represents an `Discord-Button <https://discord.com/developers/docs/interactions/message-components#button-object>`_
-
-    Read more in the `Documentation <https://discordpy-message-components.readthedocs.io/en/latest/components.html#Button>`_
-
-    Parameters
-    ----------
-    label: Optional[:class:`str`] = None
-        text that appears on the button, max 80 characters
-    custom_id: Optional[Union[:class:`str`, :class:`int`]] = None
-        a developer-defined identifier for the button, max 100 characters
-    style: Optional[Union[:class:`ButtonStyle`, :class:`int`]] = ButtonStyle.grey
-        The Style the Button should have
-    emoji: Optional[Union[:class:`discord.PartialEmoji`, :class:`discord.Emoji`, :class:`str`]] = None
-        The Emoji that will be displayed on the left side of the Button.
-    url: Optional[:class:`str`]
-        a url for link-style buttons
-    disabled: Optional[:class:`bool`] = False
-        whether the button is disabled (default False)
-
-    """
-
-    def __init__(self, label: str = None,
-                 custom_id: Union[str, int] = None,
-                 style: Union[ButtonStyle, int] = ButtonStyle.grey,
-                 emoji: Union[PartialEmoji, Emoji, str] = None,
-                 url: str = None,
-                 disabled: bool = False):
-        if url and not url.startswith(('http', 'discord://')):
-            raise InvalidButtonUrl(url)
-        self.url = url
-        if isinstance(style, int):
-            style = ButtonStyle.from_value(style)
-        if not isinstance(style, ButtonStyle):
-            raise InvalidArgument(
-                "The Style of an discord.Button have to be an Object of discord.ButtonStyle, discord.ButtonColor or usually an Integer between 1 and 5")
-        self.style = style
-        if self.style == ButtonStyle.url and not self.url:
-            raise InvalidArgument('You must also pass a URL if the ButtonStyle is a link.')
-        if self.url and int(self.style) != 5:
-            self.style = ButtonStyle.Link_Button
-        if custom_id and len(custom_id) > 100:
-            raise InvalidArgument(
-                'The maximum length of Button-custom_id\'s are 100; your one is %s long. (%s Characters to long)' % (
-                len(custom_id), len(custom_id) - 100))
-        if isinstance(custom_id, str) and custom_id.isdigit():
-            self.custom_id = int(custom_id)
-        else:
-            self.custom_id = custom_id
-        if self.custom_id is not None and self.url:
-            raise URLAndCustomIDNotAlowed(self.custom_id)
-        if label and len(label) > 80:
-            raise InvalidArgument(
-                'The maximum length of Button-Labels\'s are 80; your one is %s long. (%s Characters to long)' % (
-                len(label), len(label) - 80))
-        self.label = label
-        if isinstance(emoji, Emoji):
-            self.emoji = PartialEmoji(name=emoji.name, animated=emoji.animated, id=emoji.id)
-        elif isinstance(emoji, PartialEmoji):
-            self.emoji = emoji
-        elif isinstance(emoji, str):
-            if emoji[0] == '<':
-                self.emoji = PartialEmoji.from_string(emoji)
-            else:
-                self.emoji = PartialEmoji(name=emoji)
-        else:
-            self.emoji = None
-        self.disabled = disabled
-
-    def __repr__(self) -> str:
-        return f'<Button {", ".join(["%s=%s" % (k, str(v)) for k, v in self.__dict__.items()])}>'
-
-    def __len__(self):
-        if self.label:
-            return len(self.label)
-        return len(self.emoji)
-
-    def set_label(self, label: str):
-        """
-        Sets the Label of the :class:`Button`
-
-        :param label: str
-            The label to replace th old one with.
-
-        :return: discord.Button
-        """
-        if len(label) > 80:
-            raise InvalidArgument(
-                'The maximum length of Button-Labels\'s are 80; your one is %s long. (%s Characters to long)' % (
-                len(label), len(label) - 80))
-        self.label = label
-        return self
-
-    def set_url(self, url: str):
-        """
-        Sets the url of the :class:`Button`
-
-        :param url: str
-            The url to replace the old one with
-
-        :return: discord.Button
-
-        """
-        if not url.startswith('http'):
-            raise InvalidButtonUrl(url)
-        self.url = url
-        return self
-
-    def update(self, **kwargs):
-        self.__dict__.update((k, v) for k, v in kwargs.items() if k in self.__dict__.keys())
-        return self
-
-    def set_custom_id(self, custom_id: Union[str, int]):
-        """
-        Sets the custom_id of the :class:`Button`
-
-        :param custom_id: Union[:class:`str`, :class:`int`]
-            The custom_id to replace the old one with
-
-        :return: discord.Button
-
-        """
-        if self.url:
-            raise URLAndCustomIDNotAlowed(custom_id)
-        if len(custom_id) > 100:
-            raise InvalidArgument(
-                'The maximum length of Button-custom_id\'s are 100; your one is %s long. (%s Characters to long)' % (
-                len(custom_id), len(custom_id) - 100))
-        if isinstance(custom_id, str) and custom_id.isdigit():
-            self.custom_id = int(custom_id)
-        else:
-            self.custom_id = custom_id
-        return self
-
-    def disable_if(self, check: typing.Union[bool, typing.Callable], *args):
-        """
-        Disables the :class:`discord.Button` if the passed :attr:`check` returns :bool:`True`.
-
-        Parameters
-        ----------
-        check: Union[:class:`bool`, :type:`typing.Callable`]
-            The check could be an :class:`bool` or usually any :type:`Callable` that returns an :class:`bool`.
-        *args: Any
-            Arguments that should passed in to the :attr:`check` if it is an :type:`Callable`.
-
-        :return: discord.Button
-         """
-        try:
-            check = check(*args)
-        except TypeError:
-            pass
-        if check is True:
-            self.disabled = True
-        return self
-
-    def set_style_if(self, check: Union[bool, typing.Callable], style: ButtonStyle, *args):
-        """
-        Sets the style of the :class:`Button` to the specified one if the specified check returns True.
-
-        Parameters
-        ----------
-        check: Union[:class:`bool`, :type:`typing.Callable`]
-            The check could be an :class:`bool` or usually any :type:`Callable` that returns an :class:`bool`
-        style: discord.ButtonStyle
-            The style the :class:`Button` should have when the :attr:`check` returns True
-        *args: Any
-            Arguments that should passed in to the :attr:`check` if it is an :type:`Callable`.
-
-        :return: discord.Button
-
-        """
-        try:
-            check = check(*args)
-        except TypeError:
-            pass
-        if check is True:
-            self.style = style
-        return self
-
-    def to_dict(self):
-        base = {'type': 2, 'label': self.label, 'style': int(self.style), 'disabled': self.disabled}
-        if self.custom_id is not None:
-            base['custom_id'] = str(self.custom_id)
-        elif self.url:
-            base['url'] = self.url
-        if self.emoji:
-            base['emoji'] = self.emoji.to_dict()
-        return base
-
-    @classmethod
-    def from_dict(cls, data: dict):
-        style = data.get('style', None)
-        label = data.get('label', None)
-        emoji = data.get('emoji')
-        custom_id = data.get('custom_id', None)
-        url = data.get('url', None)
-        disabled = data.get('disabled', None)
-
-        if emoji and isinstance(emoji, dict):
-            emoji = PartialEmoji.from_dict(emoji)
-        return cls(style=style, label=label, emoji=emoji, custom_id=custom_id, url=url, disabled=disabled)
-
-
-class SelectOption:
-    """
-    A class that creates an option for a :class:`SelectMenu`
-    and represents it in a :class:`SelectMenu` in the components of a :class:`discord.Message`.
-
-    Read more in the `Documentation <https://discordpy-message-components.readthedocs.io/en/latest/components.html#SelectOption>`_
-
-    Parameters
-    ----------
-    label: :class:`str`
-        the user-facing name of the option, max 25 characters
-    value: :class:`str`
-        the dev-define value of the option, max 100 characters
-    description: Optional[:class:`str`] = None
-        an additional description of the option, max 50 characters
-    emoji: Union[:class:`PartialEmoji`, :class:`Emoji`, :class:`str`] = None
-        an Emoji that will shown on the left side of the option.
-    default: Optional[:class:`bool`] = False
-        will render this option as selected by default
-
-    """
-
-    def __init__(self, label: str,
-                 value: str,
-                 description: str = None,
-                 emoji: Union[PartialEmoji, Emoji, str] = None,
-                 default: bool = False):
-        if len(label) > 100:
-            raise AttributeError('The maximum length of the label is 100 characters.')
-        self.label = label
-        if len(value) > 100:
-            raise AttributeError('The maximum length of the value is 100 characters.')
-        self.value = value
-        if description and len(description) > 100:
-            raise AttributeError('The maximum length of the description is 100 characters.')
-        self.description = description
-        if isinstance(emoji, PartialEmoji):
-            self.emoji = emoji
-        elif isinstance(emoji, Emoji):
-            self.emoji = PartialEmoji(name=emoji.name, animated=emoji.animated, id=emoji.id)
-        elif isinstance(emoji, str):
-            if emoji[0] == '<':
-                self.emoji = PartialEmoji.from_string(emoji)
-            else:
-                self.emoji = PartialEmoji(name=emoji)
-        else:
-            self.emoji = None
-        self.default = default
-
-    def __repr__(self):
-        return f'<SelectOption {", ".join(["%s=%s" % (k, v) for (k, v) in self.__dict__.items()])}>'
-
-    def set_default(self, value: bool):
-        self.default = value
-        return self
-
-    def to_dict(self):
-        base = {'label': str(self.label),
-                'value': str(self.value),
-                'default': bool(self.default)}
-        if self.description:
-            base['description'] = str(self.description)
-        if self.emoji:
-            base['emoji'] = self.emoji.to_dict()
-        return base
-
-    @classmethod
-    def from_dict(cls, data):
-        emoji = data.pop('emoji', None)
-        if emoji:
-            emoji = PartialEmoji.from_dict(emoji)
-        return cls(label=data.pop('label'),
-                   value=data.pop('value'),
-                   description=data.pop('description', None),
-                   emoji=emoji,
-                   default=data.pop('default', False))
-
-
-class SelectMenu:
-    """
-    Represents a `Select-Menu <https://discord.com/developers/docs/interactions/message-components#select-menus>`_
-
-    Read more in the `Documentation <https://discordpy-message-components.readthedocs.io/en/latest/components.html#SelectMenu>`_
-
-    Parameters
-    ----------
-    custom_id: str or int
-        A developer-defined identifier for the :class:`SelectMenu`, max. 100 characters.
-    options: List[:class:`SelectOption`]
-        A :class:`list` of choices(:class:`SelectOption`) the :class:`SelectMenu` should have, max. 25.
-    placeholder: Optional[:class:`str`] = None
-        Custom placeholder text if nothing is selected, max. 100 characters.
-    min_values: Optional[:class:`int`] = 1
-        The minimum number of items that must be chosen; default 1, min. 0, max. 25.
-    max_values: Optional[:class:`int`] = 1
-        The maximum number of items that can be chosen; default 1, max. 25.
-    disabled: Optional[:class:`bool`] ) = False
-        disable the SelectMenu, default False
-    """
-
-    def __init__(self, custom_id: Union[str, int],
-                 options: typing.List[SelectOption],
-                 placeholder: str = None,
-                 min_values: int = 1,
-                 max_values: int = 1,
-                 disabled: bool = False):
-        if not any([isinstance(obj, SelectOption) for obj in options]):
-            raise InvalidArgument("SelectMenu.options must be a list of discord.SelectOption")
-        if len(options) > 25:
-            raise InvalidArgument('The maximum number of options in a SelectMenu is 25.')
-        self.options = options
-        if len(custom_id) > 100:
-            raise ValueError(
-                'The maximum length of a custom_id is 100 characters; your one is %s long (%s to long).' % (
-                len(custom_id), len(custom_id) - 100))
-        if isinstance(custom_id, str) and custom_id.isdigit():
-            self.custom_id = int(custom_id)
-        else:
-            self.custom_id = custom_id
-        if placeholder and len(placeholder) > 100:
-            raise AttributeError(
-                'The maximum length of a the placeholder is 100 characters; your one is %s long (%s to long).' % (
-                len(placeholder), len(placeholder) - 100))
-        self.placeholder = placeholder
-        if 25 < min_values < 0:
-            raise ValueError('The minimum number of elements to be selected must be between 1 and 25.')
-        self.min_values = min_values
-        if 25 < max_values <= 0:
-            raise ValueError('The maximum number of elements to be selected must be between 0 and 25.')
-        self.max_values = max_values
-        self.disabled = disabled
-        self._values = None
-
-    def __repr__(self):
-        return f'<SelectMenu {", ".join(["%s=%s" % (k, v) for k, v in self.__dict__.items()])}>'
-
-    @property
-    def all_option_values(self):
-        """
-        All values of the :attr:`options`
-
-        If the value is a number it is returned as an integer, otherwise as string
-
-        .. note::
-            This is equal to
-
-            .. code-block:: python3
-
-                for option in self.options:
-                    if option.value.isdigit():
-                        yield int(option.value)
-                    else:
-                        yield option.value
-        """
-        for option in self.options:
-            if option.value.isdigit():
-                yield int(option.value)
-            else:
-                yield option.value
-
-    def to_dict(self) -> dict:
-        base = {
-            'type': 3,
-            'custom_id': str(self.custom_id),
-            'options': [o.to_dict() for o in self.options if isinstance(o, SelectOption)],
-            'placeholder': self.placeholder,
-            'min_values': self.min_values,
-            'max_values': self.max_values
-        }
-        if self.disabled is True:
-            base['disabled'] = True
-        return base
-
-    @property
-    def values(self):
-        """
-        The options that were selected
-
-        .. note::
-            This only exists if the :class:`SelectMenu` is passed as a parameter in an interaction.
-
-        If the value is a number it is returned as an integer, otherwise as string
-
-        :return: List[Union[int, str]]
-        """
-        values = []
-        _values = getattr(self, '_values', [])
-        for value in _values:
-            if value.isdigit():
-                values.append(int(value))
-            else:
-                values.append(value)
-        return values
-
-    @property
-    def not_selected(self):
-        """
-        The options that were **not** selected
-
-        .. note::
-            This only exists if the :class:`SelectMenu` is passed as a parameter in an interaction.
-
-        If the value is a number it is returned as an integer, otherwise as string
-
-        :return: List[Union[int, str]]
-        """
-        _not_selected = []
-        values = self.values
-        for value in self.all_option_values:
-            if value not in values:
-                _not_selected.append(value)
-        return _not_selected
-
-    def update(self, **kwargs):
-        self.__dict__.update((k, v) for k, v in kwargs.items() if k in self.__dict__.keys())
-        return self
-
-    def set_custom_id(self, custom_id: Union[str, int]):
-        """
-        Set the custom_id of the :class:`SelectMenu`
-
-        :param custom_id: Union[:class:`str`, :class:`int`]
-            The custom_id to replace the old one with
-
-        :return: discord.SelectMenu
-        """
-        if len(custom_id) > 100:
-            raise InvalidArgument(
-                'The maximum length of SelectMenu-custom_id\'s are 100; your one is %s long. (%s Characters to long)' % (
-                len(custom_id), len(custom_id) - 100))
-        if isinstance(custom_id, str) and custom_id.isdigit():
-            self.custom_id = int(custom_id)
-        else:
-            self.custom_id = custom_id
-        return self
-
-    def disable_if(self, check: typing.Union[bool, typing.Callable], *args):
-        """
-        Disables the :class:`discord.SelectMenu` if the passed :attr:`check` returns :bool:`True`.
-
-        Parameters
-        ----------
-        check: Union[:class:`bool`, :type:`typing.Callable`]
-            The check could be an :class:`bool` or usually any :obj:`Callable` that returns an :class:`bool`.
-        *args: Any
-            Arguments that should passed in to the :param:`check` if it is an :type:`Callable`.
-
-        :return: discord.SelectMenu
-         """
-        try:
-            check = check(*args)
-        except TypeError:
-            pass
-        if check is True:
-            self.disabled = True
-        return self
-
-    @classmethod
-    def from_dict(cls, data: dict):
-        return cls(custom_id=data.pop('custom_id'),
-                   options=[SelectOption.from_dict(o) for o in data.pop('options')],
-                   placeholder=data.pop('placeholder', None),
-                   min_values=data.pop('min_values', 1),
-                   max_values=data.pop('max_values', 1))
-
-
-class ActionRow:
-    """
-    Represents an ActionRow-Part for the components of an :class:`discord.Message`.
-
-    Read more in the `Documentation <https://discordpy-message-components.readthedocs.io/en/latest/components.html#ActionRow>`_
-
-    Parameters
-    ----------
-    *components: *Union[:class:`Button, :class:`SelectMenu`]
-        The components the :class:`ActionRow` should have. It could contain at least 5 :class:`Button`or 1 :class:`SelectMenu`.
-
-    .. note ::
-        For more information about ActionRow's visit the `Discord-APIMethodes Documentation <https://discord.com/developers/docs/interactions/message-components#actionrow>`_.
-    """
-
-    def __init__(self, *components):
-        self.components = []
-        for component in components:
-            if isinstance(component, (Button, SelectMenu)):
-                self.components.append(component)
-            elif isinstance(component, dict):
-                if not component.get('type', None) in [2, 3]:
-                    raise InvalidArgument(
-                        'If you use an Dict instead of Button or SelectMenu you have to pass an type between 2 or 3')
-                self.components.append(
-                    {2: Button.from_dict(component), 3: SelectMenu.from_dict(component)}.get(component.get('type')))
-
-    def __repr__(self):
-        return f'<ActionRow components={self.components}>'
-
-    def __iter__(self):
-        for component in self.components:
-            yield component
-
-    def to_dict(self) -> Union[list, EmptyActionRow]:
-        base = []
-        base.extend([{'type': 1, 'components': [obj.to_dict() for obj in self.components[five:5:]]} for five in
-                     range(0, len(self.components), 5)])
-        objects = len([i['components'] for i in base])
-        if any([any([part['type'] == 2]) and any([part['type'] == 3]) for part in base]):
-            raise InvalidArgument('An ActionRow containing a select menu cannot also contain buttons')
-        if any([any([part['type'] == 3]) and len(part) > 1 for part in base]):
-            raise InvalidArgument('An ActionRow can contain only one SelectMenu')
-        if any([len(ar['components']) < 1 for ar in base]):
-            raise EmptyActionRow from base
-        elif len(base) > 5 or objects > 25:
-            raise InvalidArgument(
-                f"The maximum number of ActionRow's per message is 5 and they can only contain 5 Buttons or 1 Select-Menu each; you have {len(base)} ActionRow's passed with {objects} objects")
-        return base
-
-    def __len__(self):
-        return len(self.components)
-
-    def __invert__(self):
-        return self.components
-
-    def __getitem__(self, item) -> Union[Button, SelectMenu, None]:
-        return self.components.get(item, None)
-
-    def __setitem__(self, index, component):
-        return self.set_component_at(index, component)
-
-    def __reversed__(self):
-        return reversed(self.components)
-
-    def add_component(self, component: Union[Button, SelectMenu]):
-        """
-        Adds a component to the :class:`ActionRow`.
-
-        Parameters
-        ----------
-        component: Union[:class:`Button`, :class:`SelectMenu`]
-            The component to add to the ActionRow.
-
-        :return: discord.ActionRow
-        """
-        self.components.append(component)
-        return self
-
-    def insert_component_at(self, index, component: Union[Button, SelectMenu]):
-        """
-        Inserts a component before a specified index to the :class:`ActionRow`.
-
-        Parameters
-        -----------
-        index: :class:`int`
-            The index of where to insert the component.
-        component: Union[:class:`Button`, :class:`SelectMenu`]
-            The component to insert.
-
-        :return: discord.ActionRow
-        """
-        self.components.insert(index, component)
-        return self
-
-    def set_component_at(self, index, component: Union[Button, SelectMenu]):
-        """
-        Modifies a component to the ActionRow object.
-
-        The index must point to a valid pre-existing component.
-
-        Parameters
-        ----------
-        index: :class:`int`
-            The index of the component to modify.
-        component: Union[:class:`Button`, :class:`SelectMenu`]
-            The component to replace the old one with.
-
-        Raises
-        -------
-        IndexError
-            An invalid index was provided.
-
-        :return: discord.ActionRow
-        """
-        try:
-            _component = self.components[index]
-        except IndexError:
-            raise IndexError('component index %s out of range' % index)
-        _component = component
-        return self
-
-    def disable_component_at(self, index):
-        """
-        Disables the component at the specified position.
-
-        Parameters
-        ----------
-        index: int
-            The position of the component to be deactivated in the ActionRow.
-
-        Raises
-        ------
-        IndexError
-            The specified index is outside the length of the actionRow.
-
-        :return: discord.ActionRow
-        """
-        try:
-            component = self.components[index]
-        except IndexError:
-            raise IndexError('component index %s out of range' % index)
-        component.disabled = True
-        return self
-
-    def add_components(self, *components: Union[Button, SelectMenu]):
-        """
-        Adds multiple components to the :class:`ActionRow`.
-
-        Parameters
-        ----------
-        *components: *Union[:class:`Button`, :class:`SelectMenu`]
-            The components to add to the ActionRow.
-
-        :return: discord.ActionRow
-        """
-        self.components.extend(*components)
-        return self
-
-    def disable_all_components(self):
-        """
-        Disables all component's in this :class:`ActionRow`.
-
-        :return: discord.ActionRow
-        """
-        [obj.__setattr__('disabled', True) for obj in self.components]
-        return self
-
-    def disable_all_components_if(self, check: Union[bool, typing.Callable], *args: typing.Any):
-        """
-        Disables all :attr:`components` in this :class:`ActionRow` if the passed :attr:`check` returns :bool:`True`.
-
-        Parameters
-        -----------
-        check: Union[:class:`bool`, :type:`typing.Callable`]
-            Could be an bool or usually any Callable that returns a bool.
-        *args: Any
-            Arguments that should passed in to the check if it is a Callable.
-
-        :return: discord.ActionRow
-        """
-        if not isinstance(check, (bool, typing.Callable)):
-            raise AttributeError(
-                'The check must bee a bool or any callable that returns one. Not {0.__class__.__name__}'.format(check))
-        try:
-            check = check(*args)
-        except TypeError:
-            pass
-        if check is True:
-            [obj.__setattr__('disabled', True) for obj in self.components]
-        return self
-
-    def disable_all_buttons(self):
-        """
-        Disables all ::class:`discord.Button`'s in this :class:`ActionRow`.
-
-        :return: discord.ActionRow
-        """
-        [obj.__setattr__('disabled', True) for obj in self.components if isinstance(obj, Button)]
-        return self
-
-    def disable_all_buttons_if(self, check: Union[bool, typing.Callable], *args: typing.Any):
-        """
-        Disables all :class:`discord.Button`'s in this :class:`ActionRow` if the passed :attr:`check` returns :bool:`True`.
-
-        Parameters
-        -----------
-        check: Union[:class:`bool`, :type:`typing.Callable`]
-            Could be an bool or usually any Callable that returns a bool.
-        *args: Any
-            Arguments that should passed in to the check if it is a Callable.
-
-        :return: discord.ActionRow
-        """
-        if not isinstance(check, (bool, typing.Callable)):
-            raise AttributeError(
-                'The check must bee a bool or any callable that returns one. Not {0.__class__.__name__}'.format(check))
-        try:
-            check = check(*args)
-        except TypeError:
-            pass
-        if check is True:
-            [obj.__setattr__('disabled', True) for obj in self.components if isinstance(obj, Button)]
-        return self
-
-    def disable_all_select_menus(self):
-        """
-        Disables all :class:`discord.SelectMenu`'s in this :class:`ActionRow`.
-
-        :return: discord.ActionRow
-        """
-        [obj.__setattr__('disabled', True) for obj in self.components if isinstance(obj, SelectMenu)]
-        return self
-
-    def disable_all_select_menus_if(self, check: Union[bool, typing.Callable], *args: typing.Any):
-        """
-        Disables all :class:`SelectMenu`'s in this :class:`ActionRow` if the passed :attr:`check` returns :bool:`True`.
-
-        Parameters
-        ----------
-        check: Union[:class:`bool`, :class:`typing.Callable`]
-            could be an :class:`bool` or usually any :type:`Callable` that returns a :class:`bool`
-        *args: Any
-            Arguments that should passed in to the :param:`check` if it is a :type:`Callable`.
-
-        :return: discord.ActionRow
-        """
-        if not isinstance(check, (bool, typing.Callable)):
-            raise AttributeError(
-                'The check must bee a bool or any callable that returns one. Not {0.__class__.__name__}'.format(check))
-        try:
-            check = check(*args)
-        except TypeError:
-            pass
-        if check is True:
-            [obj.__setattr__('disabled', True) for obj in self.components if isinstance(obj, SelectMenu)]
-        return self
-
-    @classmethod
-    def from_dict(cls, data):
-        if data.get('type', None) != 1:
-            return InvalidArgument("%s could not be implemented as an ActionRow" % data)
-        else:
-            components = [_component_factory(component) for component in data.get('components', [])]
-            return cls(*components)
-
-
-def _component_factory(data):
-    component_type = data.get('type', None)
-    if component_type == ComponentType.ActionRow:
-        return ActionRow.from_dict(data)
-    elif component_type == ComponentType.Button:
-        return Button.from_dict(data)
-    elif component_type == ComponentType.SelectMenu:
-        return SelectMenu.from_dict(data)
-    else:
-        return None
+# -*- coding: utf-8 -*-
+
+"""
+The MIT License (MIT)
+
+Copyright (c) 2021-present mccoderpy
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+"""
+from __future__ import annotations
+
+from . import utils, abc
+from .enums import try_enum, ComponentType, ButtonStyle, TextInputStyle, ChannelType, SelectDefaultValueType
+from .emoji import Emoji
+from .partial_emoji import PartialEmoji
+from .errors import InvalidArgument, URLAndCustomIDNotAlowed
+
+from typing import (
+    Any,
+    Callable,
+    Dict,
+    Generic,
+    Iterator,
+    List,
+    Optional,
+    overload,
+    Tuple,
+    Type,
+    TypeVar,
+    TYPE_CHECKING,
+    Union,
+)
+
+from typing_extensions import Literal, Self, TypeAlias
+
+if TYPE_CHECKING:
+    from typing_extensions import ParamSpec
+    from .types.message import (
+        MessageComponent as Component,
+        ActionRow as ActionRowPayload,
+        Button as ButtonPayload,
+        SelectMenu as SelectMenuPayload,
+        SelectOption as SelectOptionPayload,
+        SelectDefaultValue as SelectDefaultValuePayload,
+        TextInput as TextInputPayload,
+        Modal as ModalPayload
+    )
+    from .role import Role
+    from .user import User
+    from .member import Member
+    from .abc import GuildChannel, Messageable
+    from .interactions import ComponentInteraction
+    
+    P = ParamSpec('P')
+    Select: TypeAlias = Union['SelectMenu', 'UserSelect', 'RoleSelect', 'MentionableSelect', 'ChannelSelect']
+
+
+__all__ = (
+    'ActionRow',
+    'Button',
+    'SelectMenu',
+    'SelectOption',
+    'SelectDefaultValue',
+    'TextInput',
+    'UserSelect',
+    'RoleSelect',
+    'MentionableSelect',
+    'ChannelSelect',
+    'Modal'
+)
+
+T = TypeVar('T')
+
+class BaseComponent:
+    """
+    The base class for all components.
+    """
+    _custom_id: Union[str, int]
+    _disabled: bool
+
+    def __init__(
+            self,
+            custom_id: Union[str, int] = None,
+            disabled: bool = False
+    ) -> None:
+        self.custom_id = int(custom_id) if custom_id and custom_id.isdigit() else custom_id
+        self.disabled = disabled
+
+    @property
+    def type(self) -> ComponentType:
+        """:class:`~discord.ComponentType`: The type this component is of"""
+        raise NotImplementedError()
+
+    @property
+    def custom_id(self) -> Union[str, int]:
+        """
+        Union[:class:`str`, :class:`int`] (depending on whether it is completely numeric or not):
+
+        A developer defined ID for this component. **This must be unique per** :class:`~discord.Message`/:class:`~discord.Modal`
+        Max. 100 characters long.
+
+        .. note::
+            The custom ID is a good place to store any additional data.
+            For example if you want to make a check in the callback whether the author is a specific user just store the user-id in the custom_id like
+
+            .. code-block:: python3
+
+                # The custom_id
+                custom_id=f'some-prefix:{ctx.author.id}'
+
+                # Now you can extract this information again in the callback by splitting it at the separator.
+                _, author_id = custom_id.split(':')  # Note that the author_id is still a string here, not an integer!
+
+            Of course, you can store any and as much data in it as you want. (As long as it does not exceed the max. length)
+        """
+        return self._custom_id
+
+    @custom_id.setter
+    def custom_id(self, value: Union[str, int]):
+        length = len(str(value))
+        if 1 > length > 100:
+            raise ValueError('The custom_id must be between 1 and 100 in length; got %s' % length)
+        self._custom_id = value
+
+    @property
+    def disabled(self) -> bool:
+        """:class:`bool`: Whether this component can be used or not. If :obj:`True` it is greyed out in the client."""
+        return self._disabled
+
+    @disabled.setter
+    def disabled(self, value: bool):
+        self._disabled = bool(value)
+
+    def to_dict(self) -> Dict[str, Any]:
+        raise NotImplementedError()
+
+    @classmethod
+    def from_dict(cls, data: Dict[str, Any]) -> BaseComponent:
+        raise NotImplementedError()
+
+
+class Button(BaseComponent):
+    """Represents a :ddocs:`Discord-Button <interactions/message-components#button-object>`_"""
+    __slots__ = ('_label', '_custom_id', '_style', '_url', '_disabled', '_sku_id')
+
+    def __init__(
+            self,
+            label: Optional[str] = None,
+            custom_id: Optional[Union[str, int]] = None,
+            style: Union[ButtonStyle, int] = ButtonStyle.grey,
+            emoji: Union[PartialEmoji, Emoji, str] = None,
+            url: Optional[str] = None,
+            sku_id: Optional[int] = None,
+            disabled: bool = False
+    ) -> None:
+        """
+        Represents a :ddocs:`Discord-Button <interactions/message-components#button-object>`_ component.
+
+        Parameters
+        ----------
+        label: Optional[:class:`str`]:
+            Text that appears on the button, max 80 characters
+        custom_id: Optional[Union[:class:`str`, :class:`int`]
+            See :attr:`BaseComponent.custom_id`
+        style: Optional[Union[:class:`ButtonStyle`, :class:`int`]]
+            The :class:`~discord.ButtonStyle` the button should have, defaults to :attr:`~discord.ButtonStyle.grey`
+        emoji: Optional[Union[:class:`~discord.PartialEmoji`, :class:`~discord.Emoji`, :class:`str`]]:
+            An emoji that will be displayed on the left side of the button.
+        url: Optional[:class:`str`]
+            An URL for the button if it is of type :attr:`ButtonStyle.url`
+        sku_id: Optional[:class:`int`]
+            The purchasable SKU's identifier when using :attr:`ButtonStyle.Premium`. Note that a premium
+            button can **only** have this attribute as well as :attr:`Button.disabled` set and can **not** have a
+            custom_id, label, url or emoji.
+        """
+        super().__init__(custom_id=custom_id, disabled=disabled)
+        self.style: ButtonStyle = try_enum(ButtonStyle, style)
+        if self.style.Premium and not sku_id:
+            raise InvalidArgument("An sku_id must be specified for premium buttons")
+        elif sku_id and not self.style.Premium:
+            raise InvalidArgument("sku_id can only be used with discord.ButtonStyle.premium")
+        elif sku_id and any((label, custom_id, emoji, url,)):
+            raise InvalidArgument('A premium button can only have parameters sku_id and (optionally) disabled')
+
+        if not emoji and not label and not self.style.Premium:
+            raise InvalidArgument('Non-premium buttons must have at least one of label or emoji set')
+        elif self.style.url and not url:
+            raise InvalidArgument('An url is required for url buttons')
+        elif url and not self.style.url:
+            self.style = ButtonStyle.url
+
+        if url and custom_id:
+            raise URLAndCustomIDNotAlowed(self.custom_id)
+        elif not url and custom_id is None and not sku_id:
+            raise InvalidArgument('A custom_id must be specified for non-url and non-premium buttons')
+
+        self.url: Optional[str] = url
+        self.label: str = label
+        self.emoji = emoji
+        self.sku_id = sku_id
+
+    def __repr__(self) -> str:
+        return f'<Button {", ".join(["%s=%s" % (k, str(v)) for k, v in self.__dict__.items()])}>'
+
+    def __len__(self):
+        if self.label:
+            return len(self.label)
+        return len(self.emoji)
+
+    @property
+    def type(self) -> ComponentType:
+        return ComponentType.Button
+
+    @property
+    def style(self) -> ButtonStyle:
+        """Optional[Union[:class:`~discord.ButtonStyle`, :class:`int`]]: The :class:`~discord.ButtonStyle` the button should have, defaults to :attr:`~discord.ButtonStyle.grey`"""
+        return self._style
+
+    @style.setter
+    def style(self, value: Union[int, ButtonStyle]):
+        if isinstance(value, int):
+            value = ButtonStyle(value)
+        self._style = value
+
+    @property
+    def label(self) -> Optional[str]:
+        """Optional[:class:`str`]: Text that appears on the button, max 80 characters"""
+        return self._label
+
+    @label.setter
+    def label(self, value: Optional[str]):
+        if value and len(value) > 80:
+            raise InvalidArgument('The max. length of Button labels is 80, got %s' % value)
+        self._label = value
+
+    @property
+    def emoji(self) -> Optional[PartialEmoji]:
+        """
+        Optional[Union[:class:`~discord.PartialEmoji`, :class:`~discord.Emoji`, :class:`str`]]: An emoji that will be displayed on the left side of the button.
+        """
+        return getattr(self, '_emoji', None)
+
+    @emoji.setter
+    def emoji(self, value: Optional[Union[PartialEmoji, Emoji, str]]):
+        if isinstance(value, Emoji):
+            self._emoji = PartialEmoji(name=value.name, animated=value.animated, id=value.id)
+        elif isinstance(value, PartialEmoji):
+            self._emoji = value
+        elif isinstance(value, str):
+            if value[0] == '<':
+                self._emoji = PartialEmoji.from_string(value)
+            else:
+                self._emoji = PartialEmoji(name=value)
+
+    @property
+    def url(self) -> Optional[str]:
+        """Optional[:class:`str`]: An URL for the button if it is of type :attr:`ButtonStyle.url`"""
+        return getattr(self, '_url', None)
+
+    @url.setter
+    def url(self, value: Optional[str]):
+        if value and not value.startswith(('http://', 'https://', 'discord://')):
+            raise ValueError(f'"{value}" is not a valid protocol. Only http(s) or discord protocol is supported')
+        self._url = value
+
+    @property
+    def sku_id(self) -> Optional[int]:
+        """
+        Optional[:class:`int`]: The purchasable SKU's identifier when :attr:`~Button.style` is set to :attr:`ButtonStyle.Premium`
+        """
+        return self._sku_id
+
+    @sku_id.setter
+    def sku_id(self, value: Optional[int]):
+        self._sku_id = value
+
+    @utils.deprecated('label setter')
+    def set_label(self, label: str):
+        """
+        Sets the Label of the :class:`Button`
+
+        label: :class:`str`
+            The label to replace th old one with.
+
+        Returns
+        -------
+        :class:`~discord.Button`
+            The updated instance
+        """
+        self.label = label
+        return self
+
+    @utils.deprecated('url setter')
+    def set_url(self, url: Optional[str]) -> Button:
+        """
+        Sets the url of the :class:`Button`
+
+        url: Optional[:class:`str`]
+            The url to replace the old one with
+
+        Returns
+        -------
+        :class:`~discord.Button`
+            The updated instance
+        """
+        self.url = url
+        return self
+
+    def update(self, **kwargs):
+        self.__dict__.update((k, v) for k, v in kwargs.items() if k in self.__dict__.keys())
+        return self
+
+    @utils.deprecated('custom_id setter')
+    def set_custom_id(self: Self, custom_id: Union[str, int]) -> Self:
+        """
+        Sets the custom_id of the :class:`Button`
+
+        custom_id: Union[:class:`str`, :class:`int`]
+            The custom_id to replace the old one with
+
+        Returns
+        --------
+        :class:`~discord.Button`
+            The updated instance
+        """
+        if self.url:
+            raise URLAndCustomIDNotAlowed(custom_id)
+        if len(custom_id) > 100:
+            raise InvalidArgument(
+                'The maximum length of Button-custom_id\'s are 100; your one is %s long. (%s Characters to long)' % (len(custom_id), len(custom_id) - 100))
+        if isinstance(custom_id, str) and custom_id.isdigit():
+            self.custom_id = int(custom_id)
+        else:
+            self.custom_id = custom_id
+        return self
+
+    def disable_if(self: Self, check: Union[bool, Callable[[P, ...], bool]], *args: P.args, **kwargs: P.kwargs) -> Self:
+        """
+        Disables the :class:`~discord.Button` if the passed ``check`` returns :obj:`True` and return itself.
+
+        Parameters
+        ----------
+        check: Union[:class:`bool`, Callable[[Any, ...], :class:`bool` ]]
+            Could be an :class:`bool` or usually any :obj:`~typing.Callable` that returns a :class:`bool`
+        *args: Any
+            Positional arguments that should be passed in to the ``check`` if it is a :obj:`~typing.Callable`
+        **kwargs: Any
+            Keyword-only arguments that should be passed in to the ``check`` if it is a :obj:`~typing.Callable`
+
+        Returns
+        -------
+        :class:`~discord.Button`
+            The updated instance
+         """
+        if callable(check):
+            check = check(*args, **kwargs)
+
+        if not isinstance(check, bool):
+            raise AttributeError(
+                'The check must bee a bool or any callable that returns one. Not {0.__class__.__name__}'.format(check)
+            )
+
+        if check is True:
+            self.disabled = True
+        return self
+
+    def set_style_if(self: Self, check: Union[bool, Callable[P, bool]], style: ButtonStyle, *args: P.args, **kwargs: P.kwargs) -> Self:
+        """
+        Sets the style of the :class:`~discord.Button` to the specified one if the specified ``check`` returns :obj:`True`.
+
+        Parameters
+        ----------
+        check: Union[:class:`bool`, Callable[[Any, ...], :class:`bool`]]
+            Could be an :class:`bool` or usually any :obj:`~typing.Callable` that returns a :class:`bool`
+        style: discord.ButtonStyle
+            The style the :class:`Button` should have when the ``check`` returns True
+        *args: Any
+            Positional arguments that should be passed in to the ``check`` if it is a :obj:`~typing.Callable`
+        **kwargs: Any
+            Keyword-only arguments that should be passed in to the ``check`` if it is a :obj:`~typing.Callable`
+
+        Returns
+        -------
+        :class:`~discord.Button`
+            The updated instance
+        """
+        if callable(check):
+            check = check(*args, **kwargs)
+
+        if not isinstance(check, bool):
+            raise AttributeError(
+                'The check must bee a bool or any callable that returns one. Not {0.__class__.__name__}'.format(check)
+            )
+
+        if check is True:
+            self.style = style
+        return self
+
+    def to_dict(self) -> ButtonPayload:
+        base = {
+            'type': 2,
+            'style': int(self.style),
+            'disabled': self.disabled
+        }
+        if self.label:
+            base['label'] = self.label
+        if self.custom_id is not None:
+            base['custom_id'] = str(self.custom_id)
+        elif self.url:
+            base['url'] = self.url
+        if self.emoji:
+            base['emoji'] = self.emoji.to_dict()
+        if self.sku_id:
+            base['sku_id'] = str(self.sku_id)
+        return base
+    
+    @classmethod
+    def from_dict(cls, data: ButtonPayload) -> Button:
+        emoji = data.pop('emoji', None)
+        if emoji and isinstance(emoji, dict):
+            emoji = PartialEmoji.from_dict(emoji)
+        return cls(
+            emoji=emoji,
+            label=data.get('label'),
+            custom_id=data.get('custom_id'),
+            style=data['style'],
+            url=data.get('url'),
+            disabled=data.get('disabled', False),
+            sku_id=data.get('sku_id'),
+        )
+
+
+class SelectOption:
+    """
+    A class that represents an option for a :class:`SelectMenu`
+
+    Attributes
+    ----------
+    label: :class:`str`
+        the user-facing name of the option, max 25 characters
+    value: :class:`str`
+        the dev-define value of the option, max 100 characters
+    description: Optional[:class:`str`] = None
+        an additional description of the option, max 50 characters
+    emoji: Union[:class:`PartialEmoji`, :class:`Emoji`, :class:`str`] = None
+        an Emoji that will be shown on the left side of the option.
+    default: Optional[:class:`bool`] = False
+        will render this option as selected by default
+    
+    Raises
+    ------
+    :exc:`ValueError`
+        One of ``label``, ``value`` or ``description`` is too long.
+    """
+    def __init__(
+            self,
+            label: str,
+            value: str,
+            description: Optional[str] = None,
+            emoji: Union[PartialEmoji, Emoji, str] = None,
+            default: bool = False
+    ) -> None:
+        if len(label) > 100:
+            raise ValueError('The maximum length of the label is 100 characters.')
+        self.label: str = label
+        if len(value) > 100:
+            raise ValueError('The maximum length of the value is 100 characters.')
+        self.value: str = value
+        if description and len(description) > 100:
+            raise ValueError('The maximum length of the description is 100 characters.')
+        self.description: Optional[str] = description
+        if isinstance(emoji, PartialEmoji):
+            self.emoji = emoji
+        elif isinstance(emoji, Emoji):
+            self.emoji: Optional[PartialEmoji] = PartialEmoji(name=emoji.name, animated=emoji.animated, id=emoji.id)
+        elif isinstance(emoji, str):
+            if emoji[0] == '<':
+                self.emoji: Optional[PartialEmoji] = PartialEmoji.from_string(emoji)
+            else:
+                self.emoji: Optional[PartialEmoji] = PartialEmoji(name=emoji)
+        else:
+            self.emoji = None
+        self.default: bool = default
+
+    def __repr__(self):
+        return f'<SelectOption {", ".join(["%s=%s" % (k, v) for (k, v) in self.__dict__.items()])}>'
+
+    def set_default(self, value: bool):
+        self.default = value
+        return self
+
+    def to_dict(self) -> SelectOptionPayload:
+        base = {
+            'label': str(self.label),
+            'value': str(self.value),
+            'default': bool(self.default)
+        }
+        if self.description:
+            base['description'] = str(self.description)
+        if self.emoji:
+            base['emoji'] = self.emoji.to_dict()
+        return base
+
+    @classmethod
+    def from_dict(cls, data: SelectOptionPayload) -> SelectOption:
+        emoji = data.pop('emoji', None)
+        if emoji:
+            emoji = PartialEmoji.from_dict(emoji)
+        return cls(
+            label=data['label'],
+            value=data['value'],
+            description=data.get('description'),
+            emoji=emoji,
+            default=data.get('default', False)
+        )
+
+
+class BaseSelect(BaseComponent):
+    __slots__ = ('_custom_id', '_placeholder', '_min_values', '_max_values', '_disabled', '_values', '_interaction')
+    _interaction: Optional[ComponentInteraction]
+
+    def __init__(
+            self,
+            custom_id: Union[str, int],
+            placeholder: Optional[str] = None,
+            min_values: int = 1,
+            max_values: int = 1,
+            disabled: bool = False,
+    ) -> None:
+        super().__init__(custom_id=custom_id, disabled=disabled)
+        self.placeholder: Optional[str] = placeholder
+        self.min_values: int = min_values
+        self.max_values: int = max_values
+
+    @property
+    def placeholder(self) -> Optional[str]:
+        """Optional[:class:`str`]: Custom placeholder text if nothing is selected, max. 100 characters."""
+        return self._placeholder
+
+    @placeholder.setter
+    def placeholder(self, value: str):
+        if value and len(value) > 150:
+            raise AttributeError(
+                'The maximum length of a the placeholder is 100 characters; your one is %d long (%d to long).' %
+                (len(value), len(value) - 100)
+            )
+        self._placeholder = value
+
+    @property
+    def min_values(self) -> int:
+        """:class:`int`: The minimum number of items that must be chosen; default 1, min. 0, max. 25."""
+        return self._min_values
+
+    @min_values.setter
+    def min_values(self, value: int):
+        if 25 < value < 0:
+            raise ValueError('The minimum number of elements to be selected must be between 1 and 25.')
+        self._min_values = value
+
+    @property
+    def max_values(self) -> int:
+        """:class:`int`: The maximum number of items that can be chosen; default 1, max. 25."""
+        return self._max_values
+
+    @max_values.setter
+    def max_values(self, value: int):
+        if 25 < value <= 0:
+            raise ValueError('The maximum number of elements to be selected must be between 0 and 25.')
+        self._max_values = value
+
+    @utils.cached_property
+    def values(self) -> Optional[List[Any]]:
+        if not hasattr(self, '_values'):
+            return None
+        values = []
+        interaction = self._interaction
+        resolved = interaction.data.resolved
+        getter = None
+        if self.type.UserSelect:
+            if interaction.guild:
+                def getter(v):
+                    return interaction.guild.get_member(v) or resolved.members[v] or resolved.users[v]
+            else:
+                def getter(v):
+                    return resolved.users[v]
+        elif self.type.RoleSelect:
+            def getter(v):
+                return resolved.roles.get(v)
+        elif self.type.MentionableSelect:
+            def getter(v):
+                try:
+                    return resolved.roles[v]
+                except KeyError:
+                    return interaction.guild.get_member(v) or resolved.members[v] or resolved.users[v]
+        elif self.type.ChannelSelect:
+            def getter(v):
+                return interaction.guild.get_channel(v) or resolved.channels[v] or interaction._state.get_channel(v)
+
+        for _id in self._values:
+            values.append(getter(int(_id)))
+        return values
+
+    def update(self: Self, **kwargs) -> Self:
+        self.__dict__.update((k, v) for k, v in kwargs.items() if k in self.__dict__.keys())
+        return self
+
+    @utils.deprecated('custom_id setter')
+    def set_custom_id(self: Self, custom_id: Union[str, int]) -> Self:
+        """
+        Set the custom_id of the Select
+
+        Parameters
+        ----------
+        custom_id: Union[:class:`str`, :class:`int`]
+            The custom_id to replace the old one with
+
+        Returns
+        -------
+        Union[:class:`.SelectMenu`, :class:`.UserSelect`, :class:`.RoleSelect`, :class:`.MentionableSelect`, :class:`.ChannelSelect`]
+            The instance with the updated custom_id
+        """
+        self.custom_id = custom_id
+        return self
+
+    def disable_if(self: Self, check: Union[bool, Callable[[P, ...], bool]], *args: P.args, **kwargs: P.kwargs) -> Self:
+        """
+        Disables the Select if the passed ``check`` returns :obj:`True` and returns itself.
+
+
+        Parameters
+        ----------
+        check: Union[:class:`bool`, Callable[[Any, ...], :class:`bool` ]]
+            Could be an :class:`bool` or usually any :obj:`~typing.Callable` that returns a :class:`bool`
+        *args: Any
+            Positional arguments that should be passed in to the ``check`` if it is a :obj:`~typing.Callable`
+        **kwargs: Any
+            Keyword-only arguments that should be passed in to the ``check`` if it is a :obj:`~typing.Callable`
+
+        Returns
+        -------
+        Union[:class:`SelectMenu`, :class:`UserSelect`, :class:`RoleSelect`, :class:`MentionableSelect`, :class:`ChannelSelect`]
+            The updated instance
+        """
+        if callable(check):
+            check = check(*args, **kwargs)
+
+        if not isinstance(check, bool):
+            raise AttributeError(
+                'The check must bee a bool or any callable that returns one. Not {0.__class__.__name__}'.format(check)
+            )
+
+        if check is True:
+            self.disabled = True
+        return self
+
+    def to_dict(self) -> SelectMenuPayload:
+        return {
+            'type': self.type.value,
+            'custom_id': str(self.custom_id),
+            'min_values': self.min_values,
+            'max_values': self.max_values,
+            'placeholder': self.placeholder,
+            'disabled': self.disabled
+        }
+
+    @classmethod
+    def from_dict(cls: Type[T], data: SelectMenuPayload) -> T:
+        return cls(
+            custom_id=data['custom_id'],
+            placeholder=data.get('placeholder'),
+            min_values=data.get('min_values', 1),
+            max_values=data.get('max_values', 1),
+            disabled=data.get('disabled', False)
+        )
+
+
+class SelectMenu(BaseSelect):
+    __slots__ = ('_custom_id', '_options', '_placeholder', '_min_values', '_max_values', '_disabled', '_values', '_interaction')
+
+    def __init__(
+            self,
+            custom_id: Union[str, int],
+            options: List[SelectOption],
+            placeholder: Optional[str] = None,
+            min_values: int = 1,
+            max_values: int = 1,
+            disabled: bool = False
+    ) -> None:
+        """
+        Represents a `Select-Menu <https://discord.com/developers/docs/interactions/message-components#select-menus>`_
+
+        Parameters
+        ----------
+        custom_id: Union[:class:`str`, :class:`int`]
+            A developer-defined identifier for the :class:`SelectMenu`, max. 100 characters
+        options: List[:class:`SelectOption`]
+            A :class:`list` of options to choose from, max. 25
+        placeholder: Optional[:class:`str`]
+            Custom placeholder text if nothing is selected, max. 100 characters
+        min_values: Optional[:class:`int`]
+            The minimum number of items that must be chosen; default 1, min. 0, max. 25
+        max_values: Optional[:class:`int`]
+            The maximum number of items that can be chosen; default 1, max. 25
+        disabled: Optional[:class:`bool`]
+            Disables the SelectMenu, default :obj:`False`
+        """
+        super().__init__(
+            custom_id=custom_id,
+            placeholder=placeholder,
+            min_values=min_values,
+            max_values=max_values,
+            disabled=disabled
+        )
+        self.options = options
+
+    def __repr__(self):
+        return f'<SelectMenu {", ".join(["%s=%s" % (k, v) for k, v in self.__dict__.items()])}>'
+
+    @property
+    def type(self) -> ComponentType:
+        return ComponentType.StringSelect
+
+    @property
+    def options(self) -> List[SelectOption]:
+        """
+        List[:class:`.SelectOption`]: A :class:`list` of options to choose from, max. 25.
+
+        .. note::
+            This must include at least the amount of :attr:`~SelectMenu.min_values`/:attr:`~SelectMenu.max_values`
+        """
+        return getattr(self, '_options', [])
+
+    @options.setter
+    def options(self, options: List[SelectOption]):
+        if self.min_values > len(options) > min(self.max_values, 25):
+            raise InvalidArgument('At least %d options must be provided and max. amount of options is 25', self.min_values)
+        for index, o in enumerate(options):
+            if not isinstance(o, SelectOption):
+                raise InvalidArgument("At SelectMenu.options[%d]: options must be a list of discord.SelectOption, got %s" % (index, o.__class__.__name__))
+        self._options = list(options)
+
+    @utils.cached_property
+    def all_option_values(self) -> Iterator[Union[int, str]]:
+        """
+        All values of the :attr:`options` of the SelectMenu.
+
+        .. warning::
+            If the :attr:`~discord.SelectOption.value` is a number it is returned as an :class:`int`, otherwise as :class:`str`!
+
+        .. note::
+            This is equal to
+
+            .. code-block:: python3
+
+                for option in self.options:
+                    if option.value.isdigit():
+                        yield int(option.value)
+                    else:
+                        yield option.value
+
+        """
+        for option in self.options:
+            if option.value.isdigit():
+                yield int(option.value)
+            else:
+                yield option.value
+
+    @utils.cached_property
+    def values(self) -> List[Union[int, str]]:
+        """
+        The values of the :attr:`options` that were selected
+
+        .. note::
+            This only exists if the :class:`SelectMenu` is passed as an argument in an interaction.
+
+        .. warning::
+            If the :attr:`~discord.SelectOption.value` is a number it is returned as an :class:`int`, otherwise as :class:`str`!
+
+        Raises
+        ------
+        TypeError
+            The SelectMenu was not passed as an argument for an interaction-callback
+
+        Returns
+        --------
+        List[Union[:class:`int`, :class:`str`]]
+            A list containing the values of the selected options
+        """
+        values = []
+        try:
+            _values = self._values
+        except AttributeError:
+            raise TypeError('You only can use this when the SelectMenu was passed as an argument in an interaction-callback')
+        for value in _values:
+            if value.isdigit():
+                values.append(int(value))
+            else:
+                values.append(value)
+        return values
+
+    @utils.cached_property
+    def not_selected(self) -> List[Union[int, str]]:
+        """
+        The options that were **not** selected
+
+        .. note::
+            This only exists if the :class:`SelectMenu` is passed as a parameter in an interaction.
+
+        .. warning::
+            If the :attr:`~discord.SelectOption.value` is a number it is returned as an :class:`int`, otherwise as :class:`str`!
+
+        Raises
+        ------
+        TypeError
+            The SelectMenu was not passed as an argument for an interaction-callback
+
+        Returns
+        --------
+        List[Union[:class:`int`, :class:`str`]]
+            A list containing the values of all **not** selected options
+        """
+        values = self.values
+        return [value for value in self.all_option_values if value not in values]
+
+    def to_dict(self) -> Dict[str, Any]:
+        base = super().to_dict()
+        base['options'] = [o.to_dict() for o in self.options]
+        return base
+
+    @classmethod
+    def from_dict(cls, data:SelectMenuPayload) -> SelectMenu:
+        return cls(
+            custom_id=data['custom_id'],
+            options=[SelectOption.from_dict(o) for o in data.pop('options')],
+            min_values=data.pop('min_values', 1),
+            max_values=data.pop('max_values', 1),
+            disabled=data.pop('disabled', False),
+            placeholder=data.get('placeholder'),
+        )
+
+
+class Modal:
+    """
+    Represents a `Modal <https://discord.com/developers/docs/interactions/receiving-and-responding#interaction-response-object-modal>`_
+
+    Parameters
+    ----------
+    custom_id: :class:`str`
+        A developer-defined identifier for the component, max 100 characters
+    title: :class:`str`
+        The title of the popup modal, max 45 characters
+    components: List[Union[:class:`ActionRow`, List[:class:`TextInput`], :class:`TextInput`]]
+        Between 1 and 5 (inclusive) components that make up the modal.
+    """
+    def __init__(
+            self,
+            title: str,
+            custom_id: str,
+            components: List[Union[ActionRow, List[TextInput]]]
+    ) -> None:
+        # TODO: Add Error handling
+        self.title: str = title
+        self.custom_id: str = custom_id
+        _components = []
+        for c in components:
+            if isinstance(c, list):
+                c = ActionRow(*c)
+            elif isinstance(c, TextInput):
+                c = ActionRow(c)
+            _components.append(c)
+        self.components: List[ActionRow] = _components
+
+    def to_dict(self) -> ModalPayload:
+        components = []
+        for a in self.components:
+            components.extend(a.to_dict())
+        return {
+            'custom_id': self.custom_id,
+            'title': self.title,
+            'components': components
+        }
+
+    @classmethod
+    def from_dict(cls, data: ModalPayload) -> Modal:
+        return cls(
+            custom_id=data['custom_id'],
+            title=data['title'],
+            components=[
+                _component_factory(a) for a in data['components']
+            ]
+        )
+
+
+class TextInput(BaseComponent):
+    def __init__(
+            self,
+            label: str,
+            custom_id: str,
+            style: Union[TextInputStyle, Literal[1, 2]] = 1,
+            min_length: Optional[int] = None,
+            max_length: Optional[int] = None,
+            required: Optional[bool] = True,
+            value: Optional[str] = None,
+            placeholder: Optional[str] = None
+    ) -> None:
+        """
+        Represents a `TextInput <https://discord.com/developers/docs/interactions/message-components#text-inputs>`_
+
+
+        Parameters
+        ----------
+        custom_id: Optional[Union[:class:`str`, :class:`int`]]
+            A developer-defined identifier for the input, max 100 characters
+        style: Optional[Union[:class:`TextInputStyle`, :class:`int`]] = TextInputStyle.short
+            The Style of the TextInput; so single- or multi-line
+        label: :class:`str`
+            The label for this component, max 45 characters
+        min_length: Optional[:class:`int`]
+            The minimum input length for a text input, min 0, max 4000
+        max_length: Optional[:class:`int`]
+            The maximum input length for a text input, min 1, max 4000
+        required: Optional[:class:`bool`] = True
+            Whether this component is required to be filled, default True
+        value: Optional[:class:`str`]
+            A pre-filled value for this component, max 4000 characters
+        placeholder: Optional[:class:`str`]
+            Custom placeholder text if the input is empty, max 100 characters
+        """
+        super().__init__(custom_id=custom_id)
+        self.label: Optional[str] = label
+        self.style: Union[TextInputStyle, Literal[1, 2]] = try_enum(TextInputStyle, style)
+        self.min_length: Optional[int] = min_length
+        self.max_length: Optional[int] = max_length
+        self.required: bool = required
+        self.value: Optional[str] = value
+        self.placeholder: Optional[str] = placeholder
+    
+    def __str__(self) -> str:
+        return self.value
+    
+    def __repr__(self) -> str:
+        return f'<TextInput {", ".join(["%s=%s" % (k, str(v)) for k, v in self.__dict__.items()])}>'
+    
+    @property
+    def type(self) -> ComponentType:
+        return ComponentType.TextInput
+
+    def to_dict(self) -> TextInputPayload:
+        return {
+            'type': 4,
+            'label': self.label,
+            'custom_id': self.custom_id,
+            'style': int(self.style),
+            'min_length': self.min_length,
+            'max_length': self.max_length,
+            'required': self.required,
+            'value': self.value,
+            'placeholder': self.placeholder
+        }
+
+    @classmethod
+    def from_dict(cls, data: TextInputPayload) -> TextInput:
+        new = cls.__new__(cls)
+        for attr in ('label', 'custom_id', 'style', 'min_length', 'max_length', 'required', 'value', 'placeholder'):
+            try:
+                setattr(new, attr, data[attr])
+            except KeyError:
+                continue
+        return new
+
+
+class SelectDefaultValue:
+    def __init__(self, id: Union[int, str, abc.Snowflake], type: Union[SelectDefaultValueType, str] = None) -> None:
+        """
+        A default value for a :class:`UserSelect`, :class:`RoleSelect`, :class:`MentionableSelect` or :class:`ChannelSelect`
+
+        .. note::
+            As all of those select types except :class:`MentionableSelect` accept only one type of value,
+            you can for those just use instances of the mentioned type or
+            a :class:`int`/:class:`str`/:class:`discord.Object` and the library will convert them to default values for you.
+            However, this might be slower than just providing instances of this class.
+
+        Parameters
+        ----------
+        id: Union[:class:`int`, :class:`str`, :class:`discord.Object`]
+            The ID of a user, role, or channel
+        type: Optional[:class:`SelectDefaultValueType`]
+            The type of the value that ``id`` represents.
+            If not passed, it will be tried to be inferred from the type of ``id``. (Must be not an int/str then)
+        """
+        self.id: int = getattr(id, 'id', int(id))
+        self.type: SelectDefaultValueType = try_enum(SelectDefaultValueType, type) or SelectDefaultValueType.from_type(
+            id
+        )
+
+    def to_dict(self) -> SelectDefaultValuePayload:
+        return {
+            'type': str(self.type),
+            'id': str(self.id)
+        }
+
+    @classmethod
+    def from_dict(cls, data: SelectDefaultValuePayload) -> SelectDefaultValue:
+        return cls(
+            id=data['id'],
+            type=data['type']
+        )
+
+
+class UserSelect(BaseSelect):
+    """
+    Very similar to :class:`SelectMenu` but you can select from a list of :class:`~discord.Member`/:class:`~discord.User`
+
+    .. note::
+        :attr:`~SelectMenu.options` can't be set for this type.
+        But you can set :attr:`~UserSelect.default_values` to a list of :class:`~discord.Member`/:class:`~discord.User`
+        to set the default values.
+
+        .. seealso::
+            :class:`SelectDefaultValue`
+    """
+    __slots__ = BaseSelect.__slots__ + ('_default_values',)
+
+    def __init__(
+            self,
+            custom_id: Union[str, int],
+            placeholder: Optional[str] = None,
+            min_values: int = 1,
+            max_values: int = 1,
+            disabled: bool = False,
+            default_values: Optional[List[Union[User, Member, abc.Snowflake, int, str, SelectDefaultValue]]] = None
+    ) -> None:
+        super().__init__(
+            custom_id=custom_id,
+            placeholder=placeholder,
+            min_values=min_values,
+            max_values=max_values,
+            disabled=disabled
+        )
+        self.default_values = default_values
+
+    @property
+    def default_values(self) -> Optional[List[SelectDefaultValue]]:
+        """List[:class:`SelectDefaultValue`]: A list of values to select by default,
+        must be within the range of :attr:`~UserSelect.min_values` and :attr:`~UserSelect.max_values`
+        """
+        return getattr(self, '_default_values', None)
+
+    @default_values.setter
+    def default_values(self, values: Optional[List[Union[Member, User, abc.Snowflake, int, str]]]):
+        if not values:
+            self._default_values = None
+            return
+        self._default_values = [
+            (v if isinstance(v, SelectDefaultValue) else SelectDefaultValue(v, SelectDefaultValueType.user))
+            for v in values
+        ]
+
+    @property
+    def type(self) -> ComponentType:
+        return ComponentType.UserSelect
+
+    @utils.cached_property
+    def values(self) -> Optional[List[Union[Member, User]]]:
+        """
+        The members/users that were selected
+
+        .. note::
+            This only exists if the :class:`UserSelect` is passed as a parameter in an interaction.
+
+        Returns
+        --------
+        List[Union[:class:`Member`, :class:`User`]]
+            A list of selected members or user if the member is not found
+        """
+        return super().values
+
+    def to_dict(self) -> SelectMenuPayload:
+        base = super().to_dict()
+        if self.default_values:
+            base['default_values'] = [v.to_dict() for v in self.default_values]
+        return base
+
+    @classmethod
+    def from_dict(cls, data: SelectMenuPayload) -> UserSelect:
+        return cls(
+            custom_id=data['custom_id'],
+            placeholder=data.get('placeholder'),
+            min_values=data.get('min_values', 1),
+            max_values=data.get('max_values', 1),
+            disabled=data.get('disabled', False),
+            default_values=[SelectDefaultValue.from_dict(v) for v in data.get('default_values', [])]
+        )
+
+
+class RoleSelect(BaseSelect):
+    """
+    Very similar to :class:`SelectMenu` but you can select from a list of :class:`~discord.Role`
+
+    .. note::
+        :attr:`~discord.SelectMenu.options` can't be set for this type.
+        But you can set :attr:`~RoleSelect.default_values` to a list of :class:`~discord.Role`
+        to set the default values.
+
+        .. seealso::
+            :class:`SelectDefaultValue`
+    """
+    __slots__ = BaseSelect.__slots__ + ('_default_values',)
+
+    def __init__(
+            self,
+            custom_id: Union[str, int],
+            placeholder: Optional[str] = None,
+            min_values: int = 1,
+            max_values: int = 1,
+            disabled: bool = False,
+            default_values: Optional[List[Union[User, Member, abc.Snowflake, int, str, SelectDefaultValue]]] = None
+    ) -> None:
+        super().__init__(
+            custom_id=custom_id,
+            placeholder=placeholder,
+            min_values=min_values,
+            max_values=max_values,
+            disabled=disabled
+        )
+        self.default_values = default_values
+
+    @property
+    def default_values(self) -> Optional[List[SelectDefaultValue]]:
+        """List[:class:`SelectDefaultValue`]: A list of roles to select by default, must be within the range of
+        :attr:`~RoleSelect.min_values` and :attr:`~RoleSelect.max_values`
+        """
+        return getattr(self, '_default_values', None)
+
+    @default_values.setter
+    def default_values(self, values: Optional[List[Union[Role, abc.Snowflake, int, str]]]):
+        if not values:
+            self._default_values = None
+            return
+        self._default_values = [
+            (v if isinstance(v, SelectDefaultValue) else SelectDefaultValue(v, SelectDefaultValueType.role))
+            for v in values
+        ]
+
+    @property
+    def type(self) -> ComponentType:
+        return ComponentType.RoleSelect
+
+    @utils.cached_property
+    def values(self) -> Optional[List[Role]]:
+        """
+        The roles that were selected
+
+        .. note::
+            This only exists if the :class:`RoleSelect` is passed as a parameter in an interaction.
+
+        Returns
+        --------
+        List[:class:`Role`]
+            A list of selected roles
+        """
+        return super().values
+
+    def to_dict(self) -> SelectMenuPayload:
+        base = super().to_dict()
+        if self.default_values:
+            base['default_values'] = [v.to_dict() for v in self.default_values]
+        return base
+
+    @classmethod
+    def from_dict(cls, data: SelectMenuPayload) -> RoleSelect:
+        return cls(
+            custom_id=data['custom_id'],
+            placeholder=data.get('placeholder'),
+            min_values=data.get('min_values', 1),
+            max_values=data.get('max_values', 1),
+            disabled=data.get('disabled', False),
+            default_values=[SelectDefaultValue.from_dict(v) for v in data.get('default_values', [])]
+        )
+
+
+class MentionableSelect(BaseSelect):
+    """
+    Very similar to :class:`SelectMenu` but you can select from a list of both
+    :class:`~discord.Member`/:class:`~discord.User` and :class:`~discord.Role`
+
+    .. note::
+        :attr:`~SelectMenu.options` can't be set for this type.
+        But you can set :attr:`~MentionableSelect.default_values` to a list of
+        :class:`~discord.Member`/:class:`~discord.User`/:class:`~discord.Role` to set the default values.
+
+        .. seealso::
+            :class:`SelectDefaultValue`
+    """
+    __slots__ = BaseSelect.__slots__ + ('_default_values',)
+
+    def __init__(
+            self,
+            custom_id: Union[str, int],
+            placeholder: Optional[str] = None,
+            min_values: int = 1,
+            max_values: int = 1,
+            disabled: bool = False,
+            default_values: Optional[List[Union[User, Member, Role, SelectDefaultValue]]] = None
+    ) -> None:
+        super().__init__(
+            custom_id=custom_id,
+            placeholder=placeholder,
+            min_values=min_values,
+            max_values=max_values,
+            disabled=disabled
+        )
+        self.default_values = default_values
+
+    @property
+    def default_values(self) -> Optional[List[SelectDefaultValue]]:
+        """List[:class:`SelectDefaultValue`]: A list of values to select by default, must be within the range of
+        :attr:`~MentionableSelect.min_values` and :attr:`~MentionableSelect.max_values`
+        """
+        return getattr(self, '_default_values', None)
+
+    @default_values.setter
+    def default_values(self, values: Optional[List[Union[User, Member, Role, SelectDefaultValue]]]):
+        if not values:
+            self._default_values = None
+            return
+        self._default_values = [
+            (v if isinstance(v, SelectDefaultValue) else SelectDefaultValue(v)) for v in values
+        ]
+
+    @property
+    def type(self) -> ComponentType:
+        return ComponentType.MentionableSelect
+
+    @utils.cached_property
+    def values(self) -> Optional[List[Union[Member, User, Role]]]:
+        """
+        The members/users and roles that were selected
+
+        .. note::
+            This only exists if the :class:`MentionableSelect` is passed as a parameter in an interaction.
+
+        Returns
+        --------
+        List[Union[:class:`Member`, :class:`User`, :class:`Role`]]
+            A list of selected members/users and roles
+        """
+        return super().values
+
+    def to_dict(self) -> SelectMenuPayload:
+        base = super().to_dict()
+        if self.default_values:
+            base['default_values'] = [v.to_dict() for v in self.default_values]
+        return base
+
+    @classmethod
+    def from_dict(cls, data: SelectMenuPayload) -> MentionableSelect:
+        return cls(
+            custom_id=data['custom_id'],
+            placeholder=data.get('placeholder'),
+            min_values=data.get('min_values', 1),
+            max_values=data.get('max_values', 1),
+            disabled=data.get('disabled', False),
+            default_values=[SelectDefaultValue.from_dict(v) for v in data.get('default_values', [])]
+        )
+
+
+class ChannelSelect(BaseSelect):
+    """
+    Very similar to :class:`SelectMenu` but you can select from a list of channels.
+
+    For this type there is an additional parameter ``channel_types``
+    which can be a list of :class:`ChannelType` (or the type itself like :class:`TextChannel` or :class:`StageChannel`)
+    that specify
+    from what channel types the user could choose.
+
+    .. note::
+        :attr:`~SelectMenu.options` can't be set for this type.
+        But you can set :attr:`~ChannelSelect.default_values` to a list of channels to set as the default values.
+
+        .. seealso::
+            :class:`SelectDefaultValue`
+    """
+    __slots__ = BaseSelect.__slots__ + ('_channel_types', '_default_values')
+
+    def __init__(
+            self,
+            custom_id: Union[str, int],
+            channel_types: Optional[List[Union[ChannelType, abc.GuildChannel]]] = None,
+            default_values: Optional[List[Union[abc.GuildChannel, abc.Snowflake, int, str, SelectDefaultValue]]] = None,
+            placeholder: Optional[str] = None,
+            min_values: int = 1,
+            max_values: int = 1,
+            disabled: bool = False
+    ) -> None:
+        super().__init__(
+            custom_id=custom_id,
+            placeholder=placeholder,
+            min_values=min_values,
+            max_values=max_values,
+            disabled=disabled
+        )
+        self.channel_types = channel_types
+        self.default_values = default_values
+
+    @property
+    def type(self) -> ComponentType:
+        return ComponentType.ChannelSelect
+
+    @property
+    def channel_types(self) -> Optional[List[ChannelType]]:
+        return getattr(self, '_channel_types', None)
+
+    @channel_types.setter
+    def channel_types(self, value: Optional[List[Union[ChannelType, abc.GuildChannel]]]):
+        types = None
+        if value is not None:
+            types = []
+            for c in value:
+                if not isinstance(c, ChannelType):
+                    types.append(ChannelType.from_type(c)[-1])
+                else:
+                    types.append(c)
+        self._channel_types = types
+
+    @property
+    def default_values(self) -> Optional[List[abc.GuildChannel]]:
+        """List[:class:`~discord.abc.GuildChannel`]:
+        A list of channels to select by default, must be within the range of
+        :attr:`~ChannelSelect.min_values` and :attr:`~ChannelSelect.max_values`
+        """
+        return getattr(self, '_default_values', None)
+
+    @default_values.setter
+    def default_values(self, values: Optional[List[Union[abc.GuildChannel, abc.Snowflake, int, str]]]):
+        if not values:
+            self._default_values = None
+            return
+        self._default_values = [
+            (v if isinstance(v, SelectDefaultValue) else SelectDefaultValue(v, SelectDefaultValueType.channel))
+            for v in values
+        ]
+
+    @utils.cached_property
+    def values(self) -> Optional[List[Union[GuildChannel, Messageable]]]:
+        """
+        The channels that were selected
+
+        .. note::
+            This only exists if the :class:`ChannelSelect` is passed as a parameter in an interaction.
+
+        Returns
+        --------
+        List[Union[:class:`GuildChannel`, :class:`Messageable`]]
+            A list of selected channels
+        """
+        return super().values
+
+    def to_dict(self) -> SelectMenuPayload:
+        base = super().to_dict()
+        if self.channel_types:
+            base['channel_types'] = [int(t) for t in self.channel_types]
+        if self.default_values:
+            base['default_values'] = [v.to_dict() for v in self.default_values]
+        return base
+
+    @classmethod
+    def from_dict(cls, data: SelectMenuPayload) -> ChannelSelect:
+        return cls(
+            custom_id=data['custom_id'],
+            channel_types=[ChannelType(t) for t in data.get('channel_types', [])],
+            placeholder=data.get('placeholder'),
+            min_values=data.get('min_values', 1),
+            max_values=data.get('max_values', 1),
+            disabled=data.get('disabled', False),
+            default_values=[SelectDefaultValue.from_dict(v) for v in data.get('default_values', [])]
+        )
+
+
+class ActionRow(Generic[T]):
+    """
+    Represents an ActionRow-Part for the components of a :class:`~discord.Message` or :class:`Modal`.
+
+    Attributes
+    ----------
+    components: List[Union[:class:`Button`, :ref:`Select <select-like-objects>`, :class:`TextInput`]]
+        The components the :class:`~discord.ActionRow` holds.
+        This could be up to **five** :class:`Button`, **one** :ref:`Select <select-like-objects>` like object
+        or **one** :class:`TextInput`.
+    """
+
+    @overload
+    def __init__(self, *components: Button) -> None: ...
+
+    @overload
+    def __init__(self, components: BaseSelect) -> None: ...
+
+    @overload
+    def __init__(self, components: TextInput) -> None: ...
+
+    def __init__(self, *components: T) -> None:
+        """
+        Represents an ActionRow-Part for the components of a :class:`~discord.Message`.
+
+        Parameters
+        ----------
+        *components: Union[:class:`Button`, :ref:`Select <select-like-objects>`, :class:`TextInput`]
+            This could be up to **five** :class:`Button`, **one** :ref:`Select <select-like-objects>` like object
+            or **one** :class:`TextInput`.
+        """
+        self.components: List[T] = list(components)
+
+    @overload
+    def __class_getitem__(cls, item: Type[Button]) -> ActionRow[Button]:
+        ...
+
+    @overload
+    def __class_getitem__(cls, item: Tuple[Type[Button], ...]) -> ActionRow[Button, ...]: ...
+
+    @overload
+    def __class_getitem__(cls, item: Type[BaseSelect]) -> ActionRow[BaseSelect]: ...
+
+    @overload
+    def __class_getitem__(cls, item: Type[TextInput]) -> ActionRow[TextInput]: ...
+
+    def __class_getitem__(cls, item: Type[T]) -> ActionRow[T]:
+        return ActionRow(*item) if isinstance(item, tuple) else ActionRow(item)
+
+    def __repr__(self) -> str:
+        return f'<ActionRow components={self.components}>'
+
+    def __iter__(self) -> Iterator[T]:
+        for component in self.components:
+            yield component
+
+    @property
+    def type(self) -> ComponentType:
+        return ComponentType.ActionRow
+
+    def to_dict(self) -> ActionRowPayload:
+        # I know this looks complex but it just auto-wraps components in to a new ActionRow when users are too stupid to place them in different
+        rows = []
+        actual_row = []
+        rows.append(actual_row)
+        for c in self.components:
+            max_rows_reached = len(rows) == 5
+            if len(actual_row) >= 5:
+                if not max_rows_reached:
+                    if actual_row not in rows:
+                        rows.append(
+                            actual_row.copy()
+                        )
+                    else:
+                        rows[rows.index(actual_row)] = actual_row.copy()
+                    actual_row.clear()
+                    rows.append(actual_row)
+                else:
+                    raise InvalidArgument('A message could only contain up to 5 ActionRows')
+
+            t = c.type
+            if t.ActionRow:
+                raise ValueError('An ActionRow can not contain another ActionRow')
+            elif t.Button:
+                actual_row.append(c.to_dict())
+            elif t.value > 2:
+                if len(rows) >= 5:
+                    raise ValueError(
+                        'An ActionRow containing a %s cannot contain other components',
+                        t.name
+                    )
+                if not actual_row:
+                    rows[rows.index(actual_row)] = [c.to_dict()]
+                    actual_row.clear()
+                    rows.append(actual_row)
+                else:
+                    rows.append([c.to_dict()])
+
+        max_rows_reached = len(rows) == 5
+        if len(actual_row) > 0:
+            if not max_rows_reached:
+                if actual_row not in rows:
+                    rows.append(
+                        actual_row.copy()
+                    )
+                rows[rows.index(actual_row)] = actual_row.copy()
+            else:
+                raise InvalidArgument('A message could only contain up to 5 ActionRows')
+        return [{'type': 1, 'components': components} for components in rows if len(components)]
+
+    def __len__(self) -> int:
+        return len(self.components)
+
+    def __invert__(self) -> List[T]:
+        return self.components
+
+    def __getitem__(self, item: int) -> T:
+        return self.components[item]
+
+    def __setitem__(self, index: int, component: T) -> None:
+        self.set_component_at(index, component)
+
+    def add_component(self: Self, component: T) -> Self:
+        """
+        Adds a component to the :class:`~discord.ActionRow` and returns itself.
+
+        Parameters
+        ----------
+        component: Union[:class:`Button`, :ref:`Select <select-like-objects>`, :class:`TextInput`]
+            The component to add to the ActionRow.
+
+        Returns
+        -------
+        :class:`~discord.ActionRow`
+            The updated instance
+        """
+        self.components.append(component)
+        return self
+
+    def insert_component_at(self: Self, index, component: T) -> Self:
+        """
+        Inserts a component before a specified index to the :class:`~discord.ActionRow` and returns itself.
+
+        Parameters
+        -----------
+        index: :class:`int`
+            The index of where to insert the component.
+        component: Union[:class:`Button`, :ref:`Select <select-like-objects>`, :class:`TextInput`]
+            The component to insert.
+
+        Returns
+        -------
+        :class:`~discord.ActionRow`
+            The updated instance
+        """
+        self.components.insert(index, component)
+        return self
+
+    def set_component_at(self: Self, index: int, component: T) -> Self:
+        """
+        Modifies a component to the :class:`~discord.ActionRow` and returns itself.
+
+        .. note::
+            The index must point to a valid pre-existing component.
+
+        Parameters
+        ----------
+        index: :class:`int`
+            The index of the component to modify.
+        component: Union[:class:`Button`, :ref:`Select <select-like-objects>`, :class:`TextInput`]
+            The component to replace the old one with.
+
+        Raises
+        -------
+        IndexError
+            An invalid index was provided.
+
+        Returns
+        -------
+        :class:`~discord.ActionRow`
+            The updated instance
+        """
+        try:
+            self.components[index]
+        except IndexError:
+            raise IndexError('component index %d out of range' % index)
+        self.components[index] = component
+        return self
+
+    def disable_component_at(self: Self, index: int) -> Self:
+        """
+        Disables the component at the specified position of the :class:`~discord.ActionRow` and returns itself.
+
+        Parameters
+        ----------
+        index: :class:`int`
+            The position of the component to be deactivated in the ActionRow.
+
+        Raises
+        ------
+        :exc:`IndexError`
+            The specified index is outside the length of the actionRow.
+
+        Returns
+        -------
+        :class:`~discord.ActionRow`
+            The updated instance
+        """
+        try:
+            component = self.components[index]
+        except IndexError:
+            raise IndexError(f'component index {index} out of range')
+        component.disabled = True
+        return self
+
+    @overload
+    def add_components(self: Self, *components: Button) -> Self: ...
+
+    @overload
+    def add_components(self: Self, components: BaseSelect) -> Self: ...
+
+    @overload
+    def add_components(self: Self, components: TextInput) -> Self: ...
+
+    def add_components(self: Self, *components: T) -> Self:
+        """
+        Adds multiple components to the :class:`~discord.ActionRow` and returns itself.
+
+        Parameters
+        ----------
+        *components: Union[:class:`Button`, :ref:`Select <select-like-objects>`, :class:`TextInput`]
+            The components to add to the Action Row.
+
+        Returns
+        -------
+        :class:`~discord.ActionRow`
+            The updated instance
+        """
+        self.components.extend(*components)
+        return self
+
+    def disable_all_components(self: Self) -> Self:
+        """
+        Disables all components in this :class:`~discord.ActionRow` and returns itself.
+
+        Returns
+        -------
+        :class:`~discord.ActionRow`
+            The updated instance
+        """
+        [obj.__setattr__('disabled', True) for obj in self.components]
+        return self
+
+    def disable_all_components_if(self: Self, check: Union[bool, Callable[P, bool]], *args: P.args, **kwargs: P.kwargs) -> Self:
+        """
+        Disables all :attr:`components` in this :class:`~discord.ActionRow` if the passed ``check`` returns :obj:`True` and returns itself.
+
+        Parameters
+        ----------
+        check: Union[:class:`bool`, Callable[[Any, ...], :class:`bool` ]]
+            Could be an :class:`bool` or usually any :obj:`~typing.Callable` that returns a :class:`bool`
+        *args: Any
+            Positional arguments that should be passed in to the ``check`` if it is a :obj:`~typing.Callable`
+        **kwargs: Any
+            Keyword-only arguments that should be passed in to the ``check`` if it is a :obj:`~typing.Callable`
+
+        Returns
+        -------
+        :class:`~discord.ActionRow`
+            The updated instance
+        """
+        if callable(check):
+            check = check(*args, **kwargs)
+
+        if not isinstance(check, bool):
+            raise AttributeError(
+                'The check must bee a bool or any callable that returns one. Not {0.__class__.__name__}'.format(check)
+            )
+
+        if check is True:
+            [obj.__setattr__('disabled', True) for obj in self.components]
+        return self
+
+    def disable_all_buttons(self: Self) -> Self:
+        """
+        Disables any :class:`~discord.Button` in this :class:`~discord.ActionRow` and returns itself.
+
+        Returns
+        -------
+        :class:`~discord.ActionRow`
+            The updated instance
+        """
+        [obj.__setattr__('disabled', True) for obj in self.components if isinstance(obj, Button)]
+        return self
+
+    def disable_all_buttons_if(self: Self, check: Union[bool, Callable[P, bool]], *args: P.args, **kwargs: P.kwargs) -> Self:
+        """
+        Disables any :class:`~discord.Button` in this :class:`~discord.ActionRow` if the passed ``check`` returns :obj:`True` and returns itself.
+
+        Parameters
+        ----------
+        check: Union[:class:`bool`, Callable[[Any, ...], :class:`bool` ]]
+            Could be an :class:`bool` or usually any :obj:`~typing.Callable` that returns a :class:`bool`
+        *args: Any
+            Positional arguments that should be passed in to the ``check`` if it is a :obj:`~typing.Callable`
+        **kwargs: Any
+            Keyword-only arguments that should be passed in to the ``check`` if it is a :obj:`~typing.Callable`
+
+        Returns
+        -------
+        :class:`~discord.ActionRow`
+            The updated instance
+        """
+        if callable(check):
+            check = check(*args, **kwargs)
+
+        if not isinstance(check, bool):
+            raise AttributeError(
+                'The check must bee a bool or any callable that returns one. Not {0.__class__.__name__}'.format(check)
+            )
+
+        if check is True:
+            [obj.__setattr__('disabled', True) for obj in self.components if isinstance(obj, Button)]
+        return self
+
+    def disable_all_select_menus(self: Self) -> Self:
+        """
+        Disables all :ref:`Select <select-like-objects>` like objects in this :class:`~discord.ActionRow` and returns itself.
+
+        Returns
+        -------
+        :class:`~discord.ActionRow`
+            The updated instance
+        """
+        [obj.__setattr__('disabled', True) for obj in self.components if isinstance(obj, BaseSelect)]
+        return self
+
+    def disable_all_select_menus_if(self: Self, check: Union[bool, Callable[P, bool]], *args: P.args, **kwargs: P.kwargs) -> Self:
+        """
+        Disables all :ref:`Select <select-like-objects>` like objects in this :class:`~discord.ActionRow`
+        if the passed ``check`` returns :obj:`True` and returns itself.
+
+        Parameters
+        ----------
+        check: Union[:class:`bool`, Callable[[Any, ...], :class:`bool` ]]
+            Could be an :class:`bool` or usually any :obj:`~typing.Callable` that returns a :class:`bool`
+        *args: Any
+            Positional arguments that should be passed in to the ``check`` if it is a :obj:`~typing.Callable`
+        **kwargs: Any
+            Keyword-only arguments that should be passed in to the ``check`` if it is a :obj:`~typing.Callable`
+
+        Returns
+        -------
+        :class:`~discord.ActionRow`
+            The updated instance
+        """
+        if callable(check):
+            check = check(*args, **kwargs)
+
+        if not isinstance(check, bool):
+            raise AttributeError(
+                'The check must bee a bool or any callable that returns one. Not {0.__class__.__name__}'.format(check)
+            )
+
+        if check is True:
+            [obj.__setattr__('disabled', True) for obj in self.components if isinstance(obj, SelectMenu)]
+        return self
+
+    @classmethod
+    def from_dict(cls, data: ActionRowPayload) -> ActionRow:
+        """
+        Internal method to create a :class:`~discord.ActionRow` from the data given by discord.
+
+        Parameters
+        ----------
+        data: :class:`dict`
+            The raw data from the api.
+
+        Returns
+        -------
+        :class:`~discord.ActionRow`
+            The ActionRow created.
+        """
+        components = [_component_factory(component) for component in data.get('components', [])]
+        return cls(*components)
+
+
+def _component_factory(data: Union[ActionRowPayload, Component]) -> Union[ActionRow, BaseComponent]:
+    component_type = data.get('type')
+    if component_type == 1:
+        return ActionRow.from_dict(data)
+    elif component_type == 2:
+        return Button.from_dict(data)
+    elif component_type == 3:
+        return SelectMenu.from_dict(data)
+    elif component_type == 4:
+        return TextInput.from_dict(data)
+    elif component_type == 5:
+        return UserSelect.from_dict(data)
+    elif component_type == 6:
+        return RoleSelect.from_dict(data)
+    elif component_type == 7:
+        return MentionableSelect.from_dict(data)
+    elif component_type == 8:
+        return ChannelSelect.from_dict(data)
diff --git a/discord/embeds.py b/discord/embeds.py
index f8ae948a..06d55eea 100644
--- a/discord/embeds.py
+++ b/discord/embeds.py
@@ -3,7 +3,7 @@
 """
 The MIT License (MIT)
 
-Copyright (c) 2015-present Rapptz
+Copyright (c) 2015-2021 Rapptz & (c) 2021-present mccoderpy
 
 Permission is hereby granted, free of charge, to any person obtaining a
 copy of this software and associated documentation files (the "Software"),
@@ -23,12 +23,89 @@
 FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 DEALINGS IN THE SOFTWARE.
 """
+from __future__ import annotations
+
+from typing import (
+    Any,
+    Dict,
+    List,
+    Type,
+    Union,
+    Optional,
+    Protocol,
+    TYPE_CHECKING
+)
 
 import datetime
 
 from . import utils
 from .colour import Colour
 
+__all__ = (
+    'Embed',
+)
+
+
+class EmbedProxy:
+    def __init__(self, layer: Dict[str, Any]):
+        self.__dict__.update(layer)
+
+    def __len__(self) -> int:
+        return len(self.__dict__)
+
+    def __repr__(self) -> str:
+        return 'EmbedProxy(%s)' % ', '.join(('%s=%r' % (k, v) for k, v in self.__dict__.items() if not k.startswith('_')))
+
+    def __getattr__(self, attr: str):
+        return EmptyEmbed
+
+    def __eq__(self, other: object) -> bool:
+        return isinstance(other, EmbedProxy) and self.__dict__ == other.__dict__
+
+    @utils.deprecated()  # You should not try to edit a value by updating the proxy
+    def __setattr__(self, key: str, value: Any):
+        self.__dict__[key] = value
+
+
+if TYPE_CHECKING:
+    from typing_extensions import Self
+
+    class _EmbedMediaProxy(Protocol):
+        url: Optional[str]
+        proxy_url: Optional[str]
+        width: Optional[int]
+        height: Optional[int]
+
+
+    class _EmbedVideoProxy(Protocol):
+        url: Optional[str]
+        width: Optional[int]
+        height: Optional[int]
+
+
+    class _EmbedAuthorProxy(Protocol):
+        name: str
+        url: Optional[str]
+        proxy_icon_url: Optional[str]
+
+
+    class _EmbedFooterProxy(Protocol):
+        text: Optional[str]
+        icon_url: Optional[str]
+
+
+    class _EmbedProviderProxy(Protocol):
+        name: Optional[str]
+        url: Optional[str]
+
+
+    class _EmbedFieldProxy(Protocol):
+        name: Optional[str]
+        value: Optional[str]
+        inline: bool
+
+MISSING = utils.MISSING
+
 
 class _EmptyEmbed:
     def __bool__(self):
@@ -42,20 +119,7 @@ def __len__(self):
 
 
 EmptyEmbed = _EmptyEmbed()
-
-
-class EmbedProxy:
-    def __init__(self, layer):
-        self.__dict__.update(layer)
-
-    def __len__(self):
-        return len(self.__dict__)
-
-    def __repr__(self):
-        return 'EmbedProxy(%s)' % ', '.join(('%s=%r' % (k, v) for k, v in self.__dict__.items() if not k.startswith('_')))
-
-    def __getattr__(self, attr):
-        return EmptyEmbed
+StrOrEmpty = Union[utils.SupportsStr, _EmptyEmbed]
 
 
 class Embed:
@@ -66,7 +130,7 @@ class Embed:
         .. describe:: len(x)
 
             Returns the total size of the embed.
-            Useful for checking if it's within the 6000 character limit.
+            Useful for checking if it's within the 6000-character limit.
 
     Certain properties return an ``EmbedProxy``, a type
     that acts similar to a regular :class:`dict` except using dotted access,
@@ -75,7 +139,7 @@ class Embed:
     :attr:`Embed.Empty`.
 
     For ease of use, all parameters that expect a :class:`str` are implicitly
-    casted to :class:`str` for you.
+    cast to :class:`str` for you.
 
     Attributes
     -----------
@@ -109,37 +173,26 @@ class Embed:
 
     Empty = EmptyEmbed
 
-    def __init__(self, **kwargs):
-        # swap the colour/color aliases
-        try:
-            colour = kwargs['colour']
-        except KeyError:
-            colour = kwargs.get('color', EmptyEmbed)
-
-        self.colour = colour
-        self.title = kwargs.get('title', EmptyEmbed)
-        self.type = kwargs.get('type', 'rich')
-        self.url = kwargs.get('url', EmptyEmbed)
-        self.description = kwargs.get('description', EmptyEmbed)
-
-        if self.title is not EmptyEmbed:
-            self.title = str(self.title)
-
-        if self.description is not EmptyEmbed:
-            self.description = str(self.description)
-
-        if self.url is not EmptyEmbed:
-            self.url = str(self.url)
-
-        try:
-            timestamp = kwargs['timestamp']
-        except KeyError:
-            pass
-        else:
-            self.timestamp = timestamp
+    def __init__(
+            self,
+            *,
+            title: Union[utils.SupportsStr, _EmptyEmbed] = EmptyEmbed,
+            description: Union[utils.SupportsStr, _EmptyEmbed] = EmptyEmbed,
+            color: Union[Colour, int, _EmptyEmbed] = EmptyEmbed,
+            timestamp: Union[datetime.datetime, _EmptyEmbed] = EmptyEmbed,
+            url: Union[utils.SupportsStr, _EmptyEmbed] = EmptyEmbed,
+            type: utils.SupportsStr = 'rich',
+            colour: Union[Colour, int, _EmptyEmbed] = EmptyEmbed
+    ):
+        self.title: Union[str, _EmptyEmbed] = str(title) if title is not EmptyEmbed else title
+        self.description: Union[str, _EmptyEmbed] = str(description) if description is not EmptyEmbed else description
+        self.colour = color if color is not EmptyEmbed else colour
+        self.url: Union[str, _EmptyEmbed] = str(url) if url is not EmptyEmbed else url
+        self.timestamp = timestamp
+        self.type: str = str(type)
 
     @classmethod
-    def from_dict(cls, data):
+    def from_dict(cls: Type[Embed], data: Dict[str, Any]) -> Embed:
         """Converts a :class:`dict` to a :class:`Embed` provided it is in the
         format that Discord expects it to be in.
 
@@ -158,7 +211,6 @@ def from_dict(cls, data):
         self = cls.__new__(cls)
 
         # fill in the basic fields
-
         self.title = data.get('title', EmptyEmbed)
         self.type = data.get('type', EmptyEmbed)
         self.description = data.get('description', EmptyEmbed)
@@ -195,11 +247,11 @@ def from_dict(cls, data):
 
         return self
 
-    def copy(self):
+    def copy(self) -> Embed:
         """Returns a shallow copy of the embed."""
         return Embed.from_dict(self.to_dict())
 
-    def __len__(self):
+    def __len__(self) -> int:
         total = len(self.title) + len(self.description)
         for field in getattr(self, '_fields', []):
             total += len(field['name']) + len(field['value'])
@@ -221,11 +273,11 @@ def __len__(self):
         return total
 
     @property
-    def colour(self):
+    def colour(self) -> Union[Colour, _EmptyEmbed]:
         return getattr(self, '_colour', EmptyEmbed)
 
     @colour.setter
-    def colour(self, value):
+    def colour(self, value: Union[Colour, int, _EmptyEmbed]):
         if isinstance(value, (Colour, _EmptyEmbed)):
             self._colour = value
         elif isinstance(value, int):
@@ -236,27 +288,27 @@ def colour(self, value):
     color = colour
 
     @property
-    def timestamp(self):
+    def timestamp(self) -> Union[datetime.datetime, _EmptyEmbed]:
         return getattr(self, '_timestamp', EmptyEmbed)
 
     @timestamp.setter
-    def timestamp(self, value):
+    def timestamp(self, value: Union[datetime.datetime, _EmptyEmbed]):
         if isinstance(value, (datetime.datetime, _EmptyEmbed)):
             self._timestamp = value
         else:
             raise TypeError("Expected datetime.datetime or Embed.Empty received %s instead" % value.__class__.__name__)
 
     @property
-    def footer(self):
+    def footer(self) -> _EmbedFooterProxy:
         """Union[:class:`EmbedProxy`, :attr:`Empty`]: Returns an ``EmbedProxy`` denoting the footer contents.
 
         See :meth:`set_footer` for possible values you can access.
 
         If the attribute has no value then :attr:`Empty` is returned.
         """
-        return EmbedProxy(getattr(self, '_footer', {}))
+        return EmbedProxy(getattr(self, '_footer', {}))  # type: ignore
 
-    def set_footer(self, *, text=EmptyEmbed, icon_url=EmptyEmbed):
+    def set_footer(self, *, text: StrOrEmpty = EmptyEmbed, icon_url: StrOrEmpty = EmptyEmbed) -> Self:
         """Sets the footer for the embed content.
 
         This function returns the class instance to allow for fluent-style
@@ -280,7 +332,7 @@ def set_footer(self, *, text=EmptyEmbed, icon_url=EmptyEmbed):
         return self
 
     @property
-    def image(self):
+    def image(self) -> _EmbedMediaProxy:
         """Union[:class:`EmbedProxy`, :attr:`Empty`]: Returns an ``EmbedProxy`` denoting the image contents.
 
         Possible attributes you can access are:
@@ -292,9 +344,9 @@ def image(self):
 
         If the attribute has no value then :attr:`Empty` is returned.
         """
-        return EmbedProxy(getattr(self, '_image', {}))
+        return EmbedProxy(getattr(self, '_image', {}))  # type: ignore
 
-    def set_image(self, *, url):
+    def set_image(self, *, url: StrOrEmpty) -> Self:
         """Sets the image for the embed content.
 
         This function returns the class instance to allow for fluent-style
@@ -306,7 +358,8 @@ def set_image(self, *, url):
         Parameters
         -----------
         url: :class:`str`
-            The source URL for the image. Only HTTP(S) is supported.
+            The source URL for the image.
+            Only HTTP(S) and discords `attachment:// <https://discord.com/developers/docs/reference#uploading-files>`_ protocol is supported.
         """
 
         if url is EmptyEmbed:
@@ -322,7 +375,7 @@ def set_image(self, *, url):
         return self
 
     @property
-    def thumbnail(self):
+    def thumbnail(self) -> _EmbedMediaProxy:
         """Union[:class:`EmbedProxy`, :attr:`Empty`]: Returns an ``EmbedProxy`` denoting the thumbnail contents.
 
         Possible attributes you can access are:
@@ -334,9 +387,9 @@ def thumbnail(self):
 
         If the attribute has no value then :attr:`Empty` is returned.
         """
-        return EmbedProxy(getattr(self, '_thumbnail', {}))
+        return EmbedProxy(getattr(self, '_thumbnail', {}))  # type: ignore
 
-    def set_thumbnail(self, *, url):
+    def set_thumbnail(self, *, url: StrOrEmpty) -> Self:
         """Sets the thumbnail for the embed content.
 
         This function returns the class instance to allow for fluent-style
@@ -348,7 +401,7 @@ def set_thumbnail(self, *, url):
         Parameters
         -----------
         url: :class:`str`
-            The source URL for the thumbnail. Only HTTP(S) is supported.
+            The source URL for the thumbnail. Only HTTP(S) and discords `attachment://` protocol is supported.
         """
 
         if url is EmptyEmbed:
@@ -364,7 +417,7 @@ def set_thumbnail(self, *, url):
         return self
 
     @property
-    def video(self):
+    def video(self) -> _EmbedVideoProxy:
         """Union[:class:`EmbedProxy`, :attr:`Empty`]: Returns an ``EmbedProxy`` denoting the video contents.
 
         Possible attributes include:
@@ -375,29 +428,39 @@ def video(self):
 
         If the attribute has no value then :attr:`Empty` is returned.
         """
-        return EmbedProxy(getattr(self, '_video', {}))
+        return EmbedProxy(getattr(self, '_video', {}))  # type: ignore
+
+    @video.setter
+    def video(self, value: utils.SupportsStr):
+        self._video = str(value)
 
     @property
-    def provider(self):
+    def provider(self) -> _EmbedProviderProxy:
         """Union[:class:`EmbedProxy`, :attr:`Empty`]: Returns an ``EmbedProxy`` denoting the provider contents.
 
         The only attributes that might be accessed are ``name`` and ``url``.
 
         If the attribute has no value then :attr:`Empty` is returned.
         """
-        return EmbedProxy(getattr(self, '_provider', {}))
+        return EmbedProxy(getattr(self, '_provider', {}))  # type: ignore
 
     @property
-    def author(self):
+    def author(self) -> _EmbedAuthorProxy:
         """Union[:class:`EmbedProxy`, :attr:`Empty`]: Returns an ``EmbedProxy`` denoting the author contents.
 
         See :meth:`set_author` for possible values you can access.
 
         If the attribute has no value then :attr:`Empty` is returned.
         """
-        return EmbedProxy(getattr(self, '_author', {}))
-
-    def set_author(self, *, name, url=EmptyEmbed, icon_url=EmptyEmbed):
+        return EmbedProxy(getattr(self, '_author', {}))  # type: ignore
+
+    def set_author(
+            self,
+            *,
+            name: utils.SupportsStr,
+            url: StrOrEmpty = EmptyEmbed,
+            icon_url: StrOrEmpty = EmptyEmbed
+    ):
         """Sets the author for the embed content.
 
         This function returns the class instance to allow for fluent-style
@@ -425,7 +488,7 @@ def set_author(self, *, name, url=EmptyEmbed, icon_url=EmptyEmbed):
 
         return self
 
-    def remove_author(self):
+    def remove_author(self) -> Self:
         """Clears embed's author information.
 
         This function returns the class instance to allow for fluent-style
@@ -441,16 +504,16 @@ def remove_author(self):
         return self
 
     @property
-    def fields(self):
+    def fields(self) -> List[_EmbedFieldProxy]:
         """List[Union[``EmbedProxy``, :attr:`Empty`]]: Returns a :class:`list` of ``EmbedProxy`` denoting the field contents.
 
         See :meth:`add_field` for possible values you can access.
 
         If the attribute has no value then :attr:`Empty` is returned.
         """
-        return [EmbedProxy(d) for d in getattr(self, '_fields', [])]
+        return [EmbedProxy(d) for d in getattr(self, '_fields', [])]  # type: ignore
 
-    def add_field(self, *, name, value, inline=True):
+    def add_field(self, *, name: utils.SupportsStr, value: utils.SupportsStr, inline: bool = True) -> Self:
         """Adds a field to the embed object.
 
         This function returns the class instance to allow for fluent-style
@@ -479,7 +542,7 @@ def add_field(self, *, name, value, inline=True):
 
         return self
 
-    def insert_field_at(self, index, *, name, value, inline=True):
+    def insert_field_at(self, index: int, *, name: utils.SupportsStr, value: utils.SupportsStr, inline: bool = True):
         """Inserts a field before a specified index to the embed.
 
         This function returns the class instance to allow for fluent-style
@@ -512,14 +575,14 @@ def insert_field_at(self, index, *, name, value, inline=True):
 
         return self
 
-    def clear_fields(self):
+    def clear_fields(self) -> None:
         """Removes all fields from this embed."""
         try:
             self._fields.clear()
         except AttributeError:
             self._fields = []
 
-    def remove_field(self, index):
+    def remove_field(self, index: int) -> None:
         """Removes a field at a specified index.
 
         If the index is invalid or out of bounds then the error is
@@ -540,7 +603,7 @@ def remove_field(self, index):
         except (AttributeError, IndexError):
             pass
 
-    def set_field_at(self, index, *, name, value, inline=True):
+    def set_field_at(self, index: int, *, name: utils.SupportsStr, value: utils.SupportsStr, inline: bool = True):
         """Modifies a field to the embed object.
 
         The index must point to a valid pre-existing field.
@@ -575,7 +638,7 @@ def set_field_at(self, index, *, name, value, inline=True):
         field['inline'] = inline
         return self
 
-    def to_dict(self):
+    def to_dict(self) -> Dict[str, Any]:
         """Converts this embed object into a dict."""
 
         # add in the raw data into the dict
@@ -606,7 +669,7 @@ def to_dict(self):
                 else:
                     result['timestamp'] = timestamp.replace(tzinfo=datetime.timezone.utc).isoformat()
 
-        # add in the non raw attribute ones
+        # add in the non-raw attribute ones
         if self.type:
             result['type'] = self.type
 
@@ -618,5 +681,4 @@ def to_dict(self):
 
         if self.title:
             result['title'] = self.title
-
         return result
diff --git a/discord/emoji.py b/discord/emoji.py
index 02d31b24..3b20911b 100644
--- a/discord/emoji.py
+++ b/discord/emoji.py
@@ -3,7 +3,7 @@
 """
 The MIT License (MIT)
 
-Copyright (c) 2015-present Rapptz
+Copyright (c) 2015-2021 Rapptz & (c) 2021-present mccoderpy
 
 Permission is hereby granted, free of charge, to any person obtaining a
 copy of this software and associated documentation files (the "Software"),
@@ -105,7 +105,7 @@ def _iterator(self):
             if attr[0] != '_':
                 value = getattr(self, attr, None)
                 if value is not None:
-                    yield (attr, value)
+                    yield attr, value
 
     def __iter__(self):
         return self._iterator()
@@ -127,6 +127,9 @@ def __ne__(self, other):
     def __hash__(self):
         return self.id >> 22
 
+    def __len__(self):
+        return len(str(self))
+
     @property
     def created_at(self):
         """:class:`datetime.datetime`: Returns the emoji's creation time in UTC."""
@@ -158,7 +161,6 @@ def guild(self):
         """:class:`Guild`: The guild this emoji belongs to."""
         return self._state._get_guild(self.guild_id)
 
-
     def url_as(self, *, format=None, static_format="png"):
         """Returns an :class:`Asset` for the emoji's url.
 
@@ -190,7 +192,6 @@ def url_as(self, *, format=None, static_format="png"):
         """
         return Asset._from_emoji(self._state, self, format=format, static_format=static_format)
 
-
     def is_usable(self):
         """:class:`bool`: Whether the bot can use this emoji.
 
@@ -203,6 +204,10 @@ def is_usable(self):
         emoji_roles, my_roles = self._roles, self.guild.me._roles
         return any(my_roles.has(role_id) for role_id in emoji_roles)
 
+    def _as_partial(self):
+        from .partial_emoji import PartialEmoji
+        return PartialEmoji.with_state(self._state, animated=self.animated, name=self.name, id=self.id)
+
     async def delete(self, *, reason=None):
         """|coro|
 
diff --git a/discord/enums.py b/discord/enums.py
index 10cffda3..d7b2289b 100644
--- a/discord/enums.py
+++ b/discord/enums.py
@@ -3,7 +3,7 @@
 """
 The MIT License (MIT)
 
-Copyright (c) 2015-present Rapptz
+Copyright (c) 2015-2021 Rapptz & (c) 2021-present mccoderpy
 
 Permission is hereby granted, free of charge, to any person obtaining a
 copy of this software and associated documentation files (the "Software"),
@@ -23,27 +23,45 @@
 FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 DEALINGS IN THE SOFTWARE.
 """
+from __future__ import annotations
 
 import types
 from collections import namedtuple
+from typing import Union, List, Tuple, Any, Type
 
 __all__ = (
     'Enum',
     'ChannelType',
+    'PrivacyLevel',
+    'EventEntityType',
+    'EventStatus',
+    'ApplicationCommandType',
+    'AppCommandPermissionType',
     'ComponentType',
+    'SelectDefaultValueType',
     'ButtonColor',
     'ButtonStyle',
     'PermissionType',
+    'IntegrationType',
+    'InteractionType',
     'InteractionCallbackType',
+    'AppIntegrationType',
+    'InteractionContextType',
+    'EntryPointHandlerType',
+    'OptionType',
     'TimestampStyle',
+    'Locale',
+    'InviteTargetType',
+    'AutoArchiveDuration',
     'MessageType',
+    'ReactionType',
     'VoiceRegion',
+    'VideoQualityMode',
     'SpeakingState',
     'VerificationLevel',
     'ContentFilter',
     'Status',
     'DefaultAvatar',
-    'RelationshipType',
     'AuditLogAction',
     'AuditLogActionCategory',
     'UserFlags',
@@ -51,21 +69,44 @@
     'HypeSquadHouse',
     'NotificationLevel',
     'PremiumType',
-    'UserContentFilter',
     'FriendFlags',
     'TeamMembershipState',
+    'TeamRole',
+    'TextInputStyle',
     'Theme',
     'WebhookType',
     'ExpireBehaviour',
     'ExpireBehavior',
     'StickerType',
+    'AutoModActionType',
+    'AutoModEventType',
+    'AutoModTriggerType',
+    'AutoModKeywordPresetType',
+    'PostSortOrder',
+    'ForumLayout',
+    'OnboardingMode',
+    'OnboardingPromptType',
+    'SKUType',
+    'EntitlementType',
 )
 
 
-def _create_value_cls(name):
-    cls = namedtuple('_EnumValue_' + name, 'name value')
+def _create_value_cls(name) -> Type[tuple]:
+    cls = namedtuple(f'_EnumValue_{name}', 'name value')
     cls.__repr__ = lambda self: '<%s.%s: %r>' % (name, self.name, self.value)
-    cls.__str__ = lambda self: '%s.%s' % (name, self.name)
+    cls.__str__ = lambda self: f'{name}.{self.name}'
+
+    def __getattribute__(self, n) -> Union[bool, Any]:
+        # With this you can use something like some_channel.type.text to check if it is of this type
+        # It is similar to "some_channel.type == ChannelType.text"
+        if n in dir(cls):
+            return super(cls, self).__getattribute__(n)
+        else:
+            if n in self._actual_enum_cls_.__members__:
+                return self.name == n
+            raise AttributeError(f'{self.__class__.__name__} has no attribute {n}.')
+
+    cls.__getattribute__ = __getattribute__
     return cls
 
 
@@ -74,7 +115,7 @@ def _is_descriptor(obj):
 
 
 class EnumMeta(type):
-    def __new__(cls, name, bases, attrs):
+    def __new__(mcs, name, bases, attrs):
         value_mapping = {}
         member_mapping = {}
         member_names = []
@@ -97,7 +138,7 @@ def __new__(cls, name, bases, attrs):
             try:
                 new_value = value_mapping[value]
             except KeyError:
-                new_value = value_cls(name=key, value=value)
+                new_value = value_cls(name=key, value=value)  # type: ignore
                 value_mapping[value] = new_value
                 member_names.append(key)
 
@@ -107,34 +148,34 @@ def __new__(cls, name, bases, attrs):
         attrs['_enum_value_map_'] = value_mapping
         attrs['_enum_member_map_'] = member_mapping
         attrs['_enum_member_names_'] = member_names
-        actual_cls = super().__new__(cls, name, bases, attrs)
+        actual_cls = super().__new__(mcs, name, bases, attrs)
         value_cls._actual_enum_cls_ = actual_cls
         return actual_cls
 
     def __iter__(cls):
-        return (cls._enum_member_map_[name] for name in cls._enum_member_names_)
+        return (cls._enum_member_map_[name] for name in cls._enum_member_names_)  # type: ignore
 
     def __reversed__(cls):
-        return (cls._enum_member_map_[name] for name in reversed(cls._enum_member_names_))
+        return (cls._enum_member_map_[name] for name in reversed(cls._enum_member_names_))  # type: ignore
 
     def __len__(cls):
-        return len(cls._enum_member_names_)
+        return len(cls._enum_member_names_)  # type: ignore
 
     def __repr__(cls):
         return '<enum %r>' % cls.__name__
 
     @property
     def __members__(cls):
-        return types.MappingProxyType(cls._enum_member_map_)
+        return types.MappingProxyType(cls._enum_member_map_)  # type: ignore
 
     def __call__(cls, value):
         try:
-            return cls._enum_value_map_[value]
+            return cls._enum_value_map_[value]  # type: ignore
         except (KeyError, TypeError):
             raise ValueError("%r is not a valid %s" % (value, cls.__name__))
 
     def __getitem__(cls, key):
-        return cls._enum_member_map_[key]
+        return cls._enum_member_map_[key]  # type: ignore
 
     def __setattr__(cls, name, value):
         raise TypeError('Enums are immutable.')
@@ -146,7 +187,7 @@ def __instancecheck__(self, instance):
         # isinstance(x, Y)
         # -> __instancecheck__(Y, x)
         try:
-            return instance._actual_enum_cls_ is self
+            return instance._actual_enum_cls_ is self  # type: ignore
         except AttributeError:
             return False
 
@@ -155,44 +196,139 @@ class Enum(metaclass=EnumMeta):
     @classmethod
     def try_value(cls, value):
         try:
-            return cls._enum_value_map_[value]
+            return cls._enum_value_map_[value]  # type: ignore
         except (KeyError, TypeError):
             return value
 
+    def __str__(self) -> str:
+        return self.name
+
+    def __int__(self) -> int:
+        return self.value
+
+    @property
+    def name(self):
+        return getattr(self, 'name')
+
+    @property
+    def value(self):
+        return getattr(self, 'value')
+
 
 class ChannelType(Enum):
-    text           = 0
-    private        = 1
-    voice          = 2
-    group          = 3
-    category       = 4
-    news           = 5
-    store          = 6
-    news_thread    = 10
-    public_thread  = 11
-    private_thread = 12
-    stage_voice    = 13
+    text            = 0
+    private         = 1
+    voice           = 2
+    group           = 3
+    category        = 4
+    news            = 5
+    news_thread     = 10
+    public_thread   = 11
+    private_thread  = 12
+    stage_voice     = 13
+    guild_directory = 14  # don't think bots can access them but yea... to have all listed here
+    forum_channel   = 15
 
+    def __str__(self):
+        return getattr(self, 'name')
+
+    def __int__(self):
+        return getattr(self, 'value')
+
+    @classmethod
+    def from_type(cls, obj):
+        if isinstance(obj, int):
+            return cls.try_value(obj)
+        return obj.channel_type() if hasattr(obj, 'channel_type') else obj
+
+
+class PermissionType(Enum):
+    role   = 0
+    member = 1
 
     def __str__(self):
         return self.name
 
-class PermissionType(Enum):
-    member = 0
-    role   = 1
+    def __int__(self):
+        return self.value
+
+
+class PrivacyLevel(Enum):
+    public     = 1
+    guild_only = 2
+
+
+class EventEntityType(Enum):
+    stage    = 1
+    voice    = 2
+    external = 3
+
+    def __str__(self):
+        return getattr(self, 'name')
+
+    def __int__(self):
+        return getattr(self, 'value')
+
+EntityType = EventEntityType
+
+
+class EventStatus(Enum):
+    scheduled = 1
+    active    = 2
+    completed = 3
+    canceled  = 4
+
+
+class IntegrationType(Enum):
+    TWITCH = 'twitch'
+    YOUTUBE = 'youtube'
+    DISCORD = 'discord'
+    GUILD_SUBSCRIPTION = 'guild_subscription'
+
+
+class InteractionType(Enum):
+    PingAck                        = 1
+    ApplicationCommand             = 2
+    Component                      = 3
+    ApplicationCommandAutocomplete = 4
+    ModalSubmit                    = 5
+
+
+class ApplicationCommandType(Enum):
+    chat_input          = 1
+    user                = 2
+    message             = 3
+    primary_entry_point = 4
 
-    # i use :meth:`getattr` so `codacy` don't cry and *my own* code is as clean as possible.
     def __str__(self):
         return getattr(self, 'name')
 
     def __int__(self):
         return getattr(self, 'value')
 
+    def __eq__(self, other):
+        return self is other or int(self) == other or str(self) == other
+
+    @classmethod
+    def from_value(cls, value):
+        return try_enum(cls, value)
+
+
+class AppCommandPermissionType(Enum):
+    ROLE    = 1
+    USER    = 2
+    CHANNEL = 3
+
 
 class ComponentType(Enum):
-    ActionRow = 1
-    Button = 2
-    SelectMenu = 3
+    ActionRow         = 1
+    Button            = 2
+    StringSelect      = 3
+    TextInput         = 4
+    UserSelect        = 5
+    RoleSelect        = 6
+    MentionableSelect = 7
+    ChannelSelect     = 8
 
     def __str__(self):
         return getattr(self, 'name')
@@ -201,7 +337,7 @@ def __int__(self):
         return getattr(self, 'value')
 
     def __eq__(self, other):
-        return int(self) == other or str(self) == other
+        return self is other or int(self) == other or str(self) == other
 
 
 class ButtonStyle(Enum):
@@ -210,7 +346,7 @@ class ButtonStyle(Enum):
     Represents the Style for a :class:`discord.Button`
 
     .. note ::
-        For more information about the Button-Styles, visit the `Discord-API Documentation <https://discord.com/developers/docs/interactions/message-components#buttons-button-styles>`_.
+        For more information about the Button-Styles, visit the :ddocs:`Discord-API Documentation <interactions/message-components#buttons-button-styles>`_.
 
     """
 
@@ -226,7 +362,9 @@ class ButtonStyle(Enum):
     url         = 5
     link        = 5
     grey_url    = 5
+    gray_url    = 5
     Link_Button = 5
+    Premium     = 6
 
     @classmethod
     def from_value(cls, value):
@@ -245,16 +383,63 @@ class ButtonColor(ButtonStyle):
     :class:`ButtonColor`
 
     .. note ::
-        This is just an Aliase to :class:`ButtonStyle`.
+        This is just an alias to :class:`ButtonStyle`.
+    """
+
+
+class TextInputStyle(Enum):
+    """
+    :class:`TextInputStyle`
+
+    Represents the style for a :class:`discord.TTextInput`
     """
-    pass
+    short       = 1
+    singleline  = 1
+    paragraph   = 2
+    multiline   = 2
+
+    @classmethod
+    def from_value(cls, value):
+        return try_enum(cls, value)
+
+    # the same as in the class above.
+    def __str__(self):
+        return getattr(self, 'name')
+
+    def __int__(self):
+        return getattr(self, 'value')
+
+
+class SelectDefaultValueType(Enum):
+    user = 'user'
+    role = 'role'
+    channel = 'channel'
+
+    def __str__(self):
+        return self.value
+
+    @classmethod
+    def from_type(cls, t):
+        class_name = t.__class__.__name__
+        if class_name == 'Role':
+            return cls.role
+        elif 'User' in class_name or 'Member' in class_name:  # To support user objects like from the oauth2 module
+            return cls.user
+        else:
+            return cls.channel
+
 
 class InteractionCallbackType(Enum):
-    pong = 1
-    msg_with_source = 4
+    pong                     = 1
+    msg_with_source          = 4
     deferred_msg_with_source = 5
-    deferred_update_msg = 6
-    update_msg = 7
+    deferred_update_msg      = 6
+    update_msg               = 7
+    autocomplete_callback    = 8
+    modal                    = 9
+    premium_required         = 10  # deprecated
+    launch_activity          = 12
+
 
     @classmethod
     def from_value(cls, value):
@@ -268,6 +453,86 @@ def __int__(self):
         return getattr(self, 'value')
 
 
+class OptionType(Enum):
+    sub_command       = 1
+    sub_command_group = 2
+    string            = 3
+    integer           = 4
+    boolean           = 5
+    user              = 6
+    channel           = 7
+    role              = 8
+    mentionable       = 9
+    number            = 10
+    attachment        = 11
+
+    def __int__(self):
+        return getattr(self, 'value')
+
+    def __str__(self):
+        return getattr(self, 'name')
+
+    @classmethod
+    def from_type(cls, t) -> Tuple[OptionType, List[ChannelType]]:
+
+        if isinstance(t, tuple):  # typing.Union has been used
+            datatypes = [cls.from_type(op) for op in t if op is not type(None)]
+            if all(x == cls.channel for x, _ in datatypes):
+                return cls.channel, [c for _, c in datatypes]
+            elif {t for t, _ in datatypes} <= {cls.role, cls.user}:
+                return cls.mentionable
+            else:
+                raise TypeError("Invalid usage of typing.Union")
+
+        py_3_10_union_type = hasattr(types, "UnionType") and isinstance(t, types.UnionType)
+
+        if py_3_10_union_type or getattr(t, '__origin__', None) is Union:
+            return cls.from_type(t.__args__)
+
+        if isinstance(t, int):
+            return try_enum(cls, t), None
+        elif isinstance(t, str):
+            return cls[t], None
+
+        if issubclass(t, str):
+            return cls.string, None
+        elif issubclass(t, bool):
+            return cls.boolean, None
+        elif issubclass(t, int):
+            return cls.integer, None
+        elif issubclass(t, float):
+            return cls.number, None
+
+        t_name = t.__name__
+
+        if t_name in {"User", "Member"}:
+            return cls.user, None
+        elif t_name == "Role":
+            return cls.role, None
+
+        elif t_name in {
+            "GuildChannel",
+            "TextChannel",
+            "VoiceChannel",
+            "StageChannel",
+            "CategoryChannel",
+            "ForumChannel",
+            "ForumPost",
+            "DMChannel",
+        }:
+            if hasattr(t, 'channel_type'):
+                return cls.channel, [t.channel_type()]
+            else:
+                return cls.channel, None
+        elif t_name == "ThreadChannel":
+            return cls.channel, [ChannelType.public_thread, ChannelType.private_thread, ChannelType.news_thread]
+
+        elif t_name == "Attachment":
+            return cls.attachment, None
+
+        raise TypeError(f"Invalid class {t!r} used as an option type. ")
+
+
 class TimestampStyle(Enum):
     """
     The Style to use in :meth:`discord.utils.styled_timestamp`.
@@ -296,6 +561,120 @@ def from_value(cls, value):
         return try_enum(cls, value)
 
 
+class InviteTargetType(Enum):
+    stream = 1
+    embedded = 2
+    embedded_application = 2
+
+
+class VoiceActivityApplication(Enum):
+    WatchTogether       = 880218394199220334
+    PokerNight          = 755827207812677713
+    BetrayalIO          = 773336526917861400
+    FishingtonIO        = 814288819477020702
+    ChessInThePark      = 832012774040141894
+    SketchyArtist       = 879864070101172255
+    Awkword             = 879863881349087252
+    DoodleCrew          = 878067389634314250
+    SketchHeads         = 902271654783242291
+    LetterTile          = 879863686565621790
+    WordSnacks          = 879863976006127627
+    SpellCast           = 852509694341283871
+    CheckersInThePark   = 832013003968348200
+    CG3Prod             = CheckersInThePark
+    Blazing8s           = 832025144389533716
+    CG4Prod             = Blazing8s
+    Ocho                = Blazing8s
+    PuttParty           = 945737671223947305
+    LandIO              = 903769130790969345
+
+
+class Locale(Enum):
+    indonesian = 'id'
+    id = 'id'
+    english_US = 'en-US'
+    en_US = 'en-US'
+    english_GB = 'en-GB'
+    en_GB = 'en-GB'
+    bulgarian = 'bg'
+    bg = 'bg'
+    chinese_china = 'zh-CN'
+    zh_CN = 'zh-CN'
+    chinese_taiwan = 'zh-TW'
+    zh_TW = 'zh-TW'
+    croatian = 'hr'
+    hr = 'hr'
+    czech = 'cs'
+    cs = 'cs'
+    danish = 'da'
+    da = 'da'
+    dutch = 'nl'
+    nl = 'nl'
+    finnish = 'fi'
+    fi = 'fi'
+    french = 'fr'
+    fr = 'fr'
+    german = 'de'
+    de = 'de'
+    greek = 'el'
+    el = 'el'
+    hindi = 'hi'
+    hi = 'hi'
+    hungarian = 'hu'
+    hu = 'hu'
+    italian = 'it'
+    it = 'it'
+    japanese = 'ja'
+    ja = 'ja'
+    korean = 'ko'
+    ko = 'ko'
+    lithuanian = 'lt'
+    lt = 'lt'
+    norwegian = 'no'
+    no = 'no'
+    polish = 'pl'
+    pl = 'pl'
+    portuguese_brazil = 'pt-BR'
+    pt_BR = 'pt-BR'
+    romanian = 'ro'
+    ro = 'ro'
+    russian = 'ru'
+    ru = 'ru'
+    spanish_spain = 'es-ES'
+    es_ES = 'es-ES'
+    spanish_latin_america = 'es-419'
+    es_419 = 'es-419'
+    latam = 'es-419'
+    swedish = 'sv-SE'
+    sv_SE = 'sv-SE'
+    thai = 'th'
+    th = 'th'
+    turkish = 'tr'
+    tr = 'tr'
+    ukrainian = 'uk'
+    uk = 'uk'
+    vietnamese = 'vi'
+    vi = 'vi'
+    hebrew = 'he'
+    he = 'he'
+    arabic = 'ar'
+    ar = 'ar'
+
+
+class AutoArchiveDuration(Enum):
+    one_hour    = 60
+    one_day     = 1440
+    three_days  = 4320
+    seven_days  = 10080
+    one_week    = 10080
+
+    def __str__(self):
+        return getattr(self, 'name')
+
+    def __int__(self):
+        return getattr(self, 'value')
+
+
 class MessageType(Enum):
     default                                      = 0
     recipient_add                                = 1
@@ -317,9 +696,25 @@ class MessageType(Enum):
     guild_discovery_grace_period_final_warning   = 17
     thread_created                               = 18
     reply                                        = 19
-    application_command                          = 20
+    chat_input_command                           = 20
     thread_starter_message                       = 21
     guild_invite_reminder                        = 22
+    context_menu_command                         = 23
+    automoderation_action                        = 24
+    role_subscription_purchase                   = 25
+    interaction_premium_upsell                   = 26
+    stage_start                                  = 27
+    stage_end                                    = 28
+    stage_speaker_change                         = 29
+    stage_raise_hand                             = 30
+    stage_topic_change                           = 31
+    guild_application_premium_subscription       = 32
+
+
+class ReactionType(Enum):
+    normal = 0
+    burst  = 1
+    super  = 1
 
 
 class VoiceRegion(Enum):
@@ -350,6 +745,18 @@ class VoiceRegion(Enum):
     def __str__(self):
         return self.value
 
+
+class VideoQualityMode(Enum):
+    auto     = 1
+    full     = 2
+
+    def __str__(self):
+        return self.name
+
+    def __int__(self):
+        return self.value
+
+
 class SpeakingState(Enum):
     none       = 0
     voice      = 1
@@ -362,6 +769,7 @@ def __str__(self):
     def __int__(self):
         return self.value
 
+
 class VerificationLevel(Enum):
     none              = 0
     low               = 1
@@ -375,6 +783,7 @@ class VerificationLevel(Enum):
     def __str__(self):
         return self.name
 
+
 class ContentFilter(Enum):
     disabled    = 0
     no_role     = 1
@@ -383,10 +792,6 @@ class ContentFilter(Enum):
     def __str__(self):
         return self.name
 
-class UserContentFilter(Enum):
-    disabled    = 0
-    friends     = 1
-    all_messages = 2
 
 class FriendFlags(Enum):
     noone = 0
@@ -395,10 +800,12 @@ class FriendFlags(Enum):
     guild_and_friends = 3
     everyone = 4
 
+
 class Theme(Enum):
     light = 'light'
     dark = 'dark'
 
+
 class Status(Enum):
     online = 'online'
     offline = 'offline'
@@ -410,6 +817,7 @@ class Status(Enum):
     def __str__(self):
         return self.value
 
+
 class DefaultAvatar(Enum):
     blurple = 0
     grey    = 1
@@ -417,61 +825,88 @@ class DefaultAvatar(Enum):
     green   = 2
     orange  = 3
     red     = 4
+    pink    = 5
 
     def __str__(self):
         return self.name
 
-class RelationshipType(Enum):
-    friend           = 1
-    blocked          = 2
-    incoming_request = 3
-    outgoing_request = 4
 
 class NotificationLevel(Enum):
     all_messages  = 0
     only_mentions = 1
 
+
 class AuditLogActionCategory(Enum):
     create = 1
     delete = 2
     update = 3
 
+
 class AuditLogAction(Enum):
-    guild_update             = 1
-    channel_create           = 10
-    channel_update           = 11
-    channel_delete           = 12
-    overwrite_create         = 13
-    overwrite_update         = 14
-    overwrite_delete         = 15
-    kick                     = 20
-    member_prune             = 21
-    ban                      = 22
-    unban                    = 23
-    member_update            = 24
-    member_role_update       = 25
-    member_move              = 26
-    member_disconnect        = 27
-    bot_add                  = 28
-    role_create              = 30
-    role_update              = 31
-    role_delete              = 32
-    invite_create            = 40
-    invite_update            = 41
-    invite_delete            = 42
-    webhook_create           = 50
-    webhook_update           = 51
-    webhook_delete           = 52
-    emoji_create             = 60
-    emoji_update             = 61
-    emoji_delete             = 62
-    message_delete           = 72
-    message_bulk_delete      = 73
-    message_pin              = 74
-    message_unpin            = 75
-    integration_create       = 80
-    integration_update       = 81
-    integration_delete       = 82
+    guild_update                            = 1
+    channel_create                          = 10
+    channel_update                          = 11
+    channel_delete                          = 12
+    overwrite_create                        = 13
+    overwrite_update                        = 14
+    overwrite_delete                        = 15
+    kick                                    = 20
+    member_prune                            = 21
+    ban                                     = 22
+    unban                                   = 23
+    member_update                           = 24
+    member_role_update                      = 25
+    member_move                             = 26
+    member_disconnect                       = 27
+    bot_add                                 = 28
+    role_create                             = 30
+    role_update                             = 31
+    role_delete                             = 32
+    invite_create                           = 40
+    invite_update                           = 41
+    invite_delete                           = 42
+    webhook_create                          = 50
+    webhook_update                          = 51
+    webhook_delete                          = 52
+    emoji_create                            = 60
+    emoji_update                            = 61
+    emoji_delete                            = 62
+    message_delete                          = 72
+    message_bulk_delete                     = 73
+    message_pin                             = 74
+    message_unpin                           = 75
+    integration_create                      = 80
+    integration_update                      = 81
+    integration_delete                      = 82
+    stage_instance_create                   = 83
+    stage_instance_update                   = 84
+    stage_instance_delete                   = 85
+    sticker_create                          = 90
+    sticker_update                          = 91
+    sticker_delete                          = 92
+    scheduled_event_create                  = 100
+    scheduled_event_update                  = 101
+    scheduled_event_delete                  = 102
+    thread_create                           = 110
+    thread_update                           = 111
+    thread_delete                           = 112
+    application_command_permission_update   = 121
+    soundboard_sound_create                 = 130  # or is it general expression create?
+    soundboard_sound_update                 = 131
+    soundboard_sound_delete                 = 132
+    auto_moderation_rule_create             = 140
+    auto_moderation_rule_update             = 141
+    auto_moderation_rule_delete             = 142
+    auto_moderation_block_message           = 143
+    auto_moderation_flag_message            = 144
+    auto_moderation_user_communication_disabled = 145
+    onboarding_question_create              = 163
+    onboarding_question_update              = 164
+    onboarding_update                       = 167
+    server_guide_create                     = 190
+    server_guide_update                     = 191
+    voice_channel_status_update             = 192
+    voice_channel_status_clear              = 193
 
     @property
     def category(self):
@@ -511,6 +946,35 @@ def category(self):
             AuditLogAction.integration_create:  AuditLogActionCategory.create,
             AuditLogAction.integration_update:  AuditLogActionCategory.update,
             AuditLogAction.integration_delete:  AuditLogActionCategory.delete,
+            AuditLogAction.stage_instance_create: AuditLogActionCategory.create,
+            AuditLogAction.stage_instance_update: AuditLogActionCategory.update,
+            AuditLogAction.stage_instance_delete: AuditLogActionCategory.delete,
+            AuditLogAction.sticker_create:      AuditLogActionCategory.create,
+            AuditLogAction.sticker_update:      AuditLogActionCategory.update,
+            AuditLogAction.sticker_delete:      AuditLogActionCategory.delete,
+            AuditLogAction.scheduled_event_create: AuditLogActionCategory.create,
+            AuditLogAction.scheduled_event_update: AuditLogActionCategory.update,
+            AuditLogAction.scheduled_event_delete: AuditLogActionCategory.delete,
+            AuditLogAction.thread_create:           AuditLogActionCategory.create,
+            AuditLogAction.thread_update:           AuditLogActionCategory.update,
+            AuditLogAction.thread_delete:           AuditLogActionCategory.delete,
+            AuditLogAction.application_command_permission_update: AuditLogActionCategory.update,
+            AuditLogAction.soundboard_sound_create: AuditLogActionCategory.create,
+            AuditLogAction.soundboard_sound_update: AuditLogActionCategory.update,
+            AuditLogAction.soundboard_sound_delete: AuditLogActionCategory.delete,
+            AuditLogAction.auto_moderation_rule_create: AuditLogActionCategory.create,
+            AuditLogAction.auto_moderation_rule_update: AuditLogActionCategory.update,
+            AuditLogAction.auto_moderation_rule_delete: AuditLogActionCategory.delete,
+            AuditLogAction.auto_moderation_block_message: None,
+            AuditLogAction.auto_moderation_flag_message: None,
+            AuditLogAction.auto_moderation_user_communication_disabled: None,
+            AuditLogAction.onboarding_question_create: AuditLogActionCategory.create,
+            AuditLogAction.onboarding_question_update: AuditLogActionCategory.update,
+            AuditLogAction.onboarding_update: AuditLogActionCategory.update,
+            AuditLogAction.server_guide_create: AuditLogActionCategory.create,
+            AuditLogAction.server_guide_update: AuditLogActionCategory.update,
+            AuditLogAction.voice_channel_status_update: AuditLogActionCategory.update,
+            AuditLogAction.voice_channel_status_clear: AuditLogActionCategory.delete,
         }
         return lookup[self]
 
@@ -535,8 +999,34 @@ def target_type(self):
             return 'emoji'
         elif v < 80:
             return 'message'
-        elif v < 90:
+        elif v < 83:
             return 'integration'
+        elif v < 90:
+            return 'stage'
+        elif v < 100:
+            return 'sticker'
+        elif v < 110:
+            return 'scheduled_event'
+        elif v < 121:
+            return 'thread'
+        elif v < 130:
+            return 'application_command'
+        elif v < 133:
+            return 'soundboard_sound'
+        elif v < 143:
+            return 'auto_moderation_rule'
+        elif v < 146:
+            return 'auto_moderation_action'
+        elif v < 165:
+            return 'onboarding_question'
+        elif v < 168:
+            return 'onboarding'
+        elif 189 < v < 192:
+            return 'server_guide'
+        elif v < 194:
+            return 'voice_channel_status'
+
+
 
 class UserFlags(Enum):
     staff = 1
@@ -555,6 +1045,11 @@ class UserFlags(Enum):
     bug_hunter_level_2 = 16384
     verified_bot = 65536
     verified_bot_developer = 131072
+    certified_moderator = 262144
+    bot_http_interactions = 524288
+    spammer = 1048576
+    active_developer = 4194304
+
 
 class ActivityType(Enum):
     unknown = -1
@@ -568,22 +1063,37 @@ class ActivityType(Enum):
     def __int__(self):
         return self.value
 
+
 class HypeSquadHouse(Enum):
     bravery = 1
     brilliance = 2
     balance = 3
 
+
 class PremiumType(Enum):
+    none = 0
     nitro_classic = 1
     nitro = 2
+    nitro_basic = 3
+
 
 class TeamMembershipState(Enum):
     invited = 1
     accepted = 2
 
+
+class TeamRole(Enum):
+    owner = 'owner'
+    admin = 'admin'
+    developer = 'developer'
+    read_only = 'read_only'
+
+
 class WebhookType(Enum):
     incoming = 1
     channel_follower = 2
+    application = 3
+
 
 class ExpireBehaviour(Enum):
     remove_role = 0
@@ -591,18 +1101,121 @@ class ExpireBehaviour(Enum):
 
 ExpireBehavior = ExpireBehaviour
 
+
 class StickerType(Enum):
-    png = 1
-    apng = 2
-    lottie = 3
+    png     = 1
+    apng    = 2
+    lottie  = 3
+    gif     = 4
+
+    def __str__(self):
+        return getattr(self, 'name', None)
+
+
+class AutoModEventType(Enum):
+    message_send  = 1
+    member_update = 2
+
+
+class AutoModKeywordPresetType(Enum):
+    profanity       = 1
+    sexual_content  = 2
+    slurs           = 3
+
+
+class AutoModTriggerType(Enum):
+    keyword         = 1
+    spam            = 3
+    keyword_preset  = 4
+    mention_spam    = 5
+    member_profile  = 6
+
+
+class AutoModActionType(Enum):
+    block_message            = 1
+    send_alert_message       = 2
+    timeout_user             = 3
+    block_member_interaction = 4
+
+
+class PostSortOrder(Enum):
+    latest_activity = 0
+    creation_date   = 1
+
+
+class ForumLayout(Enum):
+    not_set       = 0
+    classic       = 1
+    list          = 1
+    list_view     = 1
+    grid          = 2
+    grid_view     = 2
+    gallery       = 2
+    gallery_view  = 2
+
+
+class OnboardingMode(Enum):
+    default  = 0
+    advanced = 1
+
+
+class OnboardingPromptType(Enum):
+    multiple_choice = 0
+    dropdown        = 1
+
+
+class SKUType(Enum):
+    application         = 1
+    durable             = 2
+    consumable          = 3
+    bundle              = 4
+    subscription        = 5
+    subscription_group  = 6
+
+
+class EntitlementType(Enum):
+    purchase                    = 1
+    premium_subscription        = 2
+    developer_gift              = 3  # not a feature yet
+    test_mode_purchase          = 4
+    free_purchase               = 5
+    user_gift                   = 6
+    premium_purchase            = 7
+    application_subscription    = 8
+
+
+class SubscriptionStatus(Enum):
+    active     = 0
+    ending     = 1
+    inactive   = 2
+
+class AppIntegrationType(Enum):
+    guild_install = 0
+    user_install  = 1
+
+
+class InteractionContextType(Enum):
+    guild           = 1
+    bot_dm          = 2
+    private_channel = 3
+    user_dm         = 3
+    group_dm        = 3
+
+
+class EntryPointHandlerType(Enum):
+    app_handler             = 1
+    self                    = 1
+    discord_launch_activity = 2
+    discord                 = 2
+
 
-def try_enum(cls, val):
+def try_enum(cls: Type[Enum], val: Any):
     """A function that tries to turn the value into enum ``cls``.
 
     If it fails it returns the value instead.
     """
 
-    # i use :meth:`getattr` so `codacy` don't cry and *my own* code is as clean as possible.
+    # I use :meth:`getattr` so `codacy` don't cry and *my own* code is as clean as possible.
     try:
         return getattr(cls, '_enum_value_map_')[val]
     except (KeyError, TypeError, AttributeError):
diff --git a/discord/errors.py b/discord/errors.py
index 1c64d0a2..9658be01 100644
--- a/discord/errors.py
+++ b/discord/errors.py
@@ -3,7 +3,7 @@
 """
 The MIT License (MIT)
 
-Copyright (c) 2015-present Rapptz
+Copyright (c) 2015-2021 Rapptz & (c) 2021-present mccoderpy
 
 Permission is hereby granted, free of charge, to any person obtaining a
 copy of this software and associated documentation files (the "Software"),
@@ -23,6 +23,33 @@
 FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 DEALINGS IN THE SOFTWARE.
 """
+import traceback
+
+__all__ = (
+    'AlreadyResponded',
+    'DiscordException',
+    'DiscordWarning',
+    'ClientException',
+    'NoMoreItems',
+    'GatewayNotFound',
+    'HTTPException',
+    'InvalidArgument',
+    'LoginFailure',
+    'ConnectionClosed',
+    'PrivilegedIntentsRequired',
+    'InvalidData',
+    'Unauthorized',
+    'Forbidden',
+    'NotFound',
+    'DiscordServerError',
+    'URLAndCustomIDNotAlowed',
+    'UnknownInteraction',
+    'EmptyActionRow',
+    'NotInVoiceChannel',
+    'RecordingException',
+    'ThreadIsArchived',
+    'MissingPermissionsToCreateThread'
+)
 
 
 class DiscordException(Exception):
@@ -37,6 +64,9 @@ class DiscordWarning(Warning):
     """Base warning class for discord.py
 
     Ideally speaking, this could be caught to handle any warnings thrown from this library.
+
+    .. note::
+        This inherits from :class:`Warning` instead of :class:`Exception`.
     """
     pass
 
@@ -123,6 +153,16 @@ def __init__(self, response, message):
         super().__init__(fmt.format(self.response, self.code, self.text))
 
 
+class Unauthorized(HTTPException):
+    """Exception that's thrown for when status code 401 occurs.
+    
+    Subclass of :exc:`HTTPException`
+    
+    .. versionadded:: 2.0
+    """
+    pass
+
+
 class Forbidden(HTTPException):
     """Exception that's thrown for when status code 403 occurs.
 
@@ -199,14 +239,15 @@ def __init__(self, socket, *, shard_id, code=None):
 
 
 class PrivilegedIntentsRequired(ClientException):
-    """Exception that's thrown when the gateway is requesting privileged intents
+    """Exception that's thrown when the gateway is requesting privileged intents,
     but they're not ticked in the developer page yet.
 
     Go to https://discord.com/developers/applications/ and enable the intents
-    that are required. Currently these are as follows:
+    that are required. Currently, these are as follows:
 
     - :attr:`Intents.members`
     - :attr:`Intents.presences`
+    - :attr:`Intents.message_content`
 
     Attributes
     -----------
@@ -216,49 +257,89 @@ class PrivilegedIntentsRequired(ClientException):
 
     def __init__(self, shard_id):
         self.shard_id = shard_id
-        msg = 'Shard ID %s is requesting privileged intents that have not been explicitly enabled in the ' \
-              'developer portal. It is recommended to go to https://discord.com/developers/applications/ ' \
-              'and explicitly enable the privileged intents within your application\'s page. If this is not ' \
-              'possible, then consider disabling the privileged intents instead.'
-        super().__init__(msg % shard_id)
+        msg = f'\n{f"Shard ID {shard_id}" if shard_id else "Default shard"} is requesting privileged intents ' \
+              f'that have not been explicitly enabled in the developer portal.' \
+              f'\n⚠ It is recommended to go to https://discord.com/developers/applications/ and explicitly enable ' \
+              f'the privileged intents within your application\'s page. ⚠\n' \
+              f'If this is not possible, then consider disabling the privileged intents in the code instead.\n\n'
+        super().__init__(msg)
+
+    def __str__(self):
+        return '\n'.join(self.args)
 
 
-class InvalidButtonUrl(DiscordException):
-    """Exception that's thrown when the URL passed in an :class:`discord.Button` do not match the Format ``http``
-    or ``https``
+class RecordingException(ClientException):
+    """Exception that's thrown when there is an error while trying to record
+    audio from a voice channel.
     """
-    def __init__(self, url):
-        self._inavlid_url = url
-        msg = "The specified URL %s does not match the format `http` or `https`."
-        super().__init__(msg % self._inavlid_url)
+    pass
+
+
+class NotInVoiceChannel(ClientException):
+    """
+    Exception that's thrown when trying to connect of a :class:`~discord.VoiceState`
+    using `await user.voice()` from a user that is not connected to a channel the bot has access to
+    """
+    def __init__(self):
+        super().__init__(
+            'Can\'t connect to channel because the user is not in one or the bot has no access to the channel.'
+        )
 
 
 class URLAndCustomIDNotAlowed(DiscordException):
-    """Exception that's thrown when there is an ``url`` and an ``custom_id`` passed in an :class:`discord.Button`,
+    """Exception that's thrown when there is an ``url`` and an ``custom_id`` passed in a :class:`discord.Button`,
     what is not supportet by the Discord-API.
 
     .. note ::
-         :class:`discord.Button` with the style :class:`discord.ButtonStyle.Link_Button` don't send any Interaction to Discord when they are clicked.
+         :class:`discord.Button` with the style :class:`discord.ButtonStyle.url` don't send any Interaction to Discord when they are clicked.
     """
     def __init__(self, custom_id):
-        msg = f"custom_id's ({custom_id}) are not alowed in :class:`discord.Button` with the style :class:`discord.ButtonStyle.Link_Button` because Discord don't send any Interaction when clicking on an Link-Button. For More Information visit the `Discord-API Documentation <https://discord.com/developers/docs/interactions/message-components#buttons>`_."
-        super().__init__(msg)
+        msg = f"custom_id's (%s) are not allowed in :class:`discord.Button` with the style :class:`discord.ButtonStyle.url` because Discord don't send any Interaction when clicking on a Link-Button." \
+              f"For More Information visit the `Discord-API Documentation <https://discord.com/developers/docs/interactions/message-components#buttons>`_."
+        super().__init__(msg % custom_id)
 
 
 class EmptyActionRow(DiscordException):
     """
-    Exception that's thrown when there is an empty :class:`discord.ActionRow` in your message.
+    Exception that's thrown when there is an empty :class:`~discord.ActionRow` in your message.
     """
     def __init__(self):
-        msg = 'The Discord-API does not allows you to send an empty ActionRow, you have to parse at least one component'
+        msg = 'The Discord-API does not allow you to send an empty ActionRow, you have to parse at least one component'
         super().__init__(msg)
 
 
-class UnknowInteraction(DiscordWarning):
+class UnknownInteraction(DiscordWarning):
     """
-    A warning that comes when you try to interact with an expired interacion.
+    A warning that comes when you try to interact with an expired interaction.
     """
     def __init__(self, interaction_id):
         msg = f'You have already respond to this interaction ({interaction_id}) ' \
               f'and/or 15 minutes have passed since the interaction, which is why Discord has deleted the interaction.'
         super().__init__(msg)
+
+
+class AlreadyResponded(DiscordException):
+    """
+    Exception thrown when attempting to send the callback for an interaction that has already been responded to.'
+    """
+    def __init__(self, interaction_id):
+        msg = f'You have already send a callback(using defer, respond or respond_with_modal) to this interaction ({interaction_id}) '
+        super().__init__(msg)
+
+
+class ThreadIsArchived(DiscordException):
+    """
+    Exception that's thrown when trying to use a method on a ThreadChannel that is archived and need's to be unarchived  first.
+    """
+    def __init__(self, method):
+        msg = f'You can\'t use %s when the Thread is archived. Un-archive it first.'
+        super().__init__(msg % method)
+
+
+class MissingPermissionsToCreateThread(DiscordException):
+    """
+    Exception that's thrown when trying to create a thread of a type you don't have the permission for to create.
+    """
+    def __init__(self, *permissions, type):
+        msg = f'You\'r missing (any of) %s permission(s) to create a thread of type %s.'
+        super().__init__(msg % (', '.join([str(p) for p in permissions]), type))
diff --git a/discord/ext/commands/__init__.py b/discord/ext/commands/__init__.py
index 92c7424a..f98d84ff 100644
--- a/discord/ext/commands/__init__.py
+++ b/discord/ext/commands/__init__.py
@@ -4,9 +4,9 @@
 discord.ext.commands
 ~~~~~~~~~~~~~~~~~~~~~
 
-An extension module to facilitate creation of bot commands.
+An extension module to facilitate creation of bot sub_commands.
 
-:copyright: (c) 2015-present Rapptz
+:copyright: (c) 2015-present Rapptz 2021 mccoder.py
 :license: MIT, see LICENSE for more details.
 """
 
diff --git a/discord/ext/commands/bot.py b/discord/ext/commands/bot.py
index 1d2493a6..6b98a7a1 100644
--- a/discord/ext/commands/bot.py
+++ b/discord/ext/commands/bot.py
@@ -3,7 +3,7 @@
 """
 The MIT License (MIT)
 
-Copyright (c) 2015-present Rapptz
+Copyright (c) 2015-2021 Rapptz & (c) 2021-present mccoderpy
 
 Permission is hereby granted, free of charge, to any person obtaining a
 copy of this software and associated documentation files (the "Software"),
@@ -25,12 +25,22 @@
 """
 
 import asyncio
-import collections
+import collections.abc
+import copy
 import inspect
 import importlib.util
+import re
 import sys
 import traceback
 import types
+from typing import (
+    Callable,
+    Optional,
+    Union,
+    Dict,
+    List,
+    Tuple
+)
 
 import discord
 
@@ -41,6 +51,7 @@
 from .help import HelpCommand, DefaultHelpCommand
 from .cog import Cog
 
+
 def when_mentioned(bot, msg):
     """A callable that implements a command prefix equivalent to being mentioned.
 
@@ -48,6 +59,7 @@ def when_mentioned(bot, msg):
     """
     return [bot.user.mention + ' ', '<@!%s> ' % bot.user.id]
 
+
 def when_mentioned_or(*prefixes):
     """A callable that implements when mentioned or other prefixes provided.
 
@@ -77,6 +89,7 @@ async def get_prefix(bot, message):
     ----------
     :func:`.when_mentioned`
     """
+
     def inner(bot, msg):
         r = list(prefixes)
         r = when_mentioned(bot, msg) + r
@@ -84,21 +97,25 @@ def inner(bot, msg):
 
     return inner
 
+
 def _is_submodule(parent, child):
     return parent == child or child.startswith(parent + ".")
 
+
 class _DefaultRepr:
     def __repr__(self):
         return '<default-help-command>'
 
+
 _default = _DefaultRepr()
 
+
 class BotBase(GroupMixin):
     def __init__(self, command_prefix, help_command=_default, description=None, **options):
         super().__init__(**options)
         self.command_prefix = command_prefix
-        self.extra_events = {}
-        self.extra_interaction_events = {}
+        self.extra_events: Dict[str, List[Callable[..., ...]]] = {}
+        self.extra_interaction_events: Dict[str, List[Tuple[Callable[..., ...], Callable[..., ...]]]] = {}
         self.__cogs = {}
         self.__extensions = {}
         self._checks = []
@@ -110,7 +127,9 @@ def __init__(self, command_prefix, help_command=_default, description=None, **op
         self.owner_id = options.get('owner_id')
         self.owner_ids = options.get('owner_ids', set())
         self.strip_after_prefix = options.get('strip_after_prefix', False)
-
+        self.sync_commands: bool = options.get('sync_commands', False)
+        self.delete_not_existing_commands: bool = options.get('delete_not_existing_commands', True)
+        self.sync_commands_on_cog_reload: bool = options.get('sync_commands_on_cog_reload', False)
         if self.owner_id and self.owner_ids:
             raise TypeError('Both owner_id and owner_ids are set.')
 
@@ -138,8 +157,11 @@ def dispatch(self, event_name, *args, **kwargs):
             if check(*args, **kwargs):
                 self._schedule_event(func, ev, *args, **kwargs)
 
-
     async def close(self):
+        """|coro|
+
+        This has the same behaviour as :meth:`discord.Client.close` except that it unload all extensions and cogs first.
+        """
         for extension in tuple(self.__extensions):
             try:
                 self.unload_extension(extension)
@@ -177,6 +199,26 @@ async def on_command_error(self, context, exception):
         print('Ignoring exception in command {}:'.format(context.command), file=sys.stderr)
         traceback.print_exception(type(exception), exception, exception.__traceback__, file=sys.stderr)
 
+    async def on_application_command_error(self, cmd, interaction, exception):
+        """|coro|
+
+        The default error handler when an Exception was raised when invoking an application-command.
+
+        By default this prints to :data:`sys.stderr` however it could be
+        overridden to have a different implementation.
+        Check :func:`~discord.on_application_command_error` for more details.
+        """
+        if self.extra_events.get('on_application_command_error', None):
+            return
+
+        if hasattr(cmd, 'on_error'):
+            return
+
+        cog: Cog = cmd.cog
+        if cog and Cog._get_overridden_method(cog.cog_application_command_error) is not None:
+            return
+        await super().on_application_command_error(cmd, interaction, exception)
+
     # global check registration
 
     def check(self, func):
@@ -396,102 +438,13 @@ def after_invoke(self, coro):
         self._after_invoke = coro
         return coro
 
-
-    def on_click(self, custom_id=None):
-        """
-        A decorator that registers a raw_button_click event that checks on execution if the ``custom_id's`` are the same; if so, the :func:`func` is called..
-
-        You can find more info about this in the `documentation <https://discordpy-message-components.readthedocs.io/en/latest/additions.html#on-click>`.
-
-        The func must be a :ref:`coroutine <coroutine>`, if not, :exc:`TypeError` is raised.
-
-        Example
-        -------
-
-        .. code-block:: python
-
-            # the Button
-            Button(label='Hey im a cool blue Button',
-                    custom_id='cool blue Button',
-                    style=ButtonColor.blurple)
-
-            # function that's called when the Button pressed
-            @client.on_click(custom_id='cool blue Button')
-            async def cool_blue_button(i: discord.Interaction):
-                await i.respond('Hey you pressed a `cool blue Button`!', hidden=True)
-
-        Raises
-        ------
-        :class:`TypeError`
-            The coroutine passed is not actually a coroutine.
-        """
-        def decorator(func):
-            if not asyncio.iscoroutinefunction(func):
-                raise TypeError('event registered must be a coroutine function')
-            _custom_id = custom_id if custom_id is not None else func.__name__
-            self.add_interaction_listener('raw_button_click', func, _custom_id)
-            return func
-        return decorator
-    
-    def on_select(self, custom_id=None):
-        """
-        A decorator with which you can assign a function to a specific :class:`SelectMenu` (or its custom_id).
-        
-        .. note::
-            This will always give exactly one Parameter of type `discord.Interaction <./interaction.html#discord-interaction>`_ like an `raw_selection_select-Event <#on-raw-button-click>`_.
-
-        .. important::
-            The Function this decorator attached to must be an corountine (means an awaitable)
-
-        Parameters
-        ----------
-        
-        :attr:`custom_id`: Optional[str]
-
-            If the :attr:`custom_id` of the SelectMenu could not use as an function name or you want to give the function a diferent name then the custom_id use this one to set the custom_id.
-
-
-        Example
-        -------
-
-        .. code-block:: python
-
-            # the SelectMenu
-            SelectMenu(custom_id='choose_your_gender',
-                    options=[
-                            select_option(label='Female', value='Female', emoji='♀️'),
-                            select_option(label='Male', value='Male', emoji='♂️'),
-                            select_option(label='Non Binary', value='Non Binary', emoji='⚧')
-                            ], placeholder='Choose your Gender')
-
-            # function that's called when the SelectMenu is used
-            @client.on_select()
-            async def choose_your_gender(i: discord.Interaction, select_menu):
-                await i.respond(f'You selected `{select_menu.values[0]}`!', hidden=True)
-
-        Raises
-        --------
-        TypeError
-            The coroutine passed is not actually a coroutine.
-        """
-        def decorator(func):
-            if not asyncio.iscoroutinefunction(func):
-                raise TypeError('event registered must be a coroutine function')
-            _custom_id = custom_id if custom_id is not None else func.__name__
-            self.add_interaction_listener('raw_selection_select', func, _custom_id)
-            return func
-
-        return decorator
-        
-    
     # listener registration
-
-    def add_interaction_listener(self, _type,  func, custom_id):
+    def add_interaction_listener(self, _type, func, custom_id: re.Pattern):
         """
         This adds an interaction(decorator) like :meth:`on_click` or :meth:`on_select` to the client listeners.
 
         .. note::
-            This should not use manuel; only cogs use this to register them.
+            This should not be used directly; it's used internal when a Cog is loaded.
 
         """
         try:
@@ -499,20 +452,36 @@ def add_interaction_listener(self, _type,  func, custom_id):
         except KeyError:
             listeners = []
             self.extra_interaction_events[_type] = listeners
-        
-        listeners.append((func, lambda i, c: c.custom_id == custom_id))
-
-    def remove_interaction_listener(self, _type,  func, custom_id):
+        if _type == 'modal_submit':
+            def _check(i):
+                match = custom_id.match(str(i.custom_id))
+                if match:
+                    i.match = match
+                    return True
+                return False
+        else:
+            def _check(i, b):
+                match = custom_id.match(str(b.custom_id))
+                if match:
+                    i.match = match
+                    return True
+                return False
+
+        # We store this in the function here, so we can remove it later easily
+        listener = (func, _check)
+        setattr(func.__func__, '__listener__', listener)
+        listeners.append(listener)
+
+    def remove_interaction_listener(self, _type, func):
         """
         This removes an interaction(decorator) like :meth:`on_click` or :meth:`on_select` from the client listeners.
 
         .. note::
-            This should not use manuel; only cogs use this to remove them.
-            
+            This should not be used directly; it's used internal when a Cog is un-loaded.
         """
         try:
             if _type in self.extra_interaction_events:
-                self.extra_interaction_events[_type].remove((func, lambda i, c: c.custom_id == custom_id))
+                self.extra_interaction_events[_type].remove(func.__listener__)
         except ValueError:
             pass
 
@@ -673,7 +642,7 @@ def remove_cog(self, name):
         cog._eject(self)
 
     @property
-    def cogs(self):
+    def cogs(self) -> Dict[str, Cog]:
         """Mapping[:class:`str`, :class:`Cog`]: A read-only mapping of cog name to cog."""
         return types.MappingProxyType(self.__cogs)
 
@@ -703,6 +672,15 @@ def _remove_module_references(self, name):
             for index in reversed(remove):
                 del event_list[index]
 
+        for event_list in self.extra_interaction_events.copy().values():
+            remove = []
+            for index, event in enumerate(event_list):
+                if event[0].__module__ is not None and _is_submodule(name, event[0].__module__):
+                    remove.append(index)
+
+            for index in reversed(remove):
+                del event_list[index]
+
     def _call_module_finalizers(self, lib, key):
         try:
             func = getattr(lib, 'teardown')
@@ -753,7 +731,7 @@ def _resolve_name(self, name, package):
         except ImportError:
             raise errors.ExtensionNotFound(name)
 
-    def load_extension(self, name, *, package=None):
+    def load_extension(self, name, *, package: Optional[str] = None):
         """Loads an extension.
 
         An extension is a python module that contains commands, cogs, or
@@ -800,7 +778,7 @@ def load_extension(self, name, *, package=None):
 
         self._load_from_module_spec(spec, name)
 
-    def unload_extension(self, name, *, package=None):
+    def unload_extension(self, name, *, package: Optional[str] = None):
         """Unloads an extension.
 
         When the extension is unloaded, all commands, listeners, and cogs are
@@ -841,7 +819,7 @@ def unload_extension(self, name, *, package=None):
         self._remove_module_references(lib.__name__)
         self._call_module_finalizers(lib, name)
 
-    def reload_extension(self, name, *, package=None):
+    def reload_extension(self, name, *, package: Optional[str] = None):
         """Atomically reloads an extension.
 
         This replaces the extension with the same extension, only refreshed. This is
@@ -875,7 +853,6 @@ def reload_extension(self, name, *, package=None):
         ExtensionFailed
             The extension setup function had an execution error.
         """
-
         name = self._resolve_name(name, package)
         lib = self.__extensions.get(name)
         if lib is None:
@@ -902,13 +879,221 @@ def reload_extension(self, name, *, package=None):
 
             # revert sys.modules back to normal and raise back to caller
             sys.modules.update(modules)
+
+            self.loop.create_task(
+                self._request_sync_commands(
+                    is_cog_reload=True,
+                    reload_failed=True
+                )
+            )
             raise
+        else:
+            self.loop.create_task(self._request_sync_commands(is_cog_reload=True))
+
+    def reload_extensions(self, *names: Tuple[str], package: Optional[str] = None) -> None:
+        """
+        Same behaviour as :meth:`.reload_extension` excepts that it reloads multiple extensions
+        and triggers application commands syncing after all has been reloaded
+        """
+        before_sync = copy.copy(self.sync_commands_on_cog_reload)
+        self.sync_commands_on_cog_reload = False
+        try:
+            for name in names:
+                self.reload_extension(name, package=package)
+        finally:
+            self.sync_commands_on_cog_reload = before_sync
+            self.loop.create_task(self._request_sync_commands(is_cog_reload=True))
 
     @property
     def extensions(self):
         """Mapping[:class:`str`, :class:`py:types.ModuleType`]: A read-only mapping of extension name to extension."""
         return types.MappingProxyType(self.__extensions)
 
+    def add_application_cmds_from_cog(self, cog: Cog):
+        """
+        Add all application-commands in the given cog to the internal list of application-commands.
+
+        Parameters
+        ----------
+        cog: :class:`.Cog`
+            The cog which application-commands should be added to the internal list of application-commands.
+        """
+
+        self.remove_application_cmds_from_cog(cog)  # to ensure that commands that aren't in the cog anymore get removed
+
+        for cmd_type, commands in cog.__application_commands_by_type__.items():
+
+            for command in commands.values():
+                # check if there is already a command with the same name
+                command._set_cog(cog, recursive=True)
+                if command.name in self._application_commands_by_type[cmd_type]:
+                    existing_command = self._application_commands_by_type[cmd_type][command.name]
+                    existing_command.disabled = False
+                    if cmd_type == 'chat_input':
+                        if command.has_subcommands:
+                            # if the command has subcommands add them to the existing one.
+                            for sub_command in command.sub_commands:
+                                sub_command.disabled = False
+                                if sub_command.type.sub_command_group:
+                                    # if the subcommand is a group that already exists, add the subcommands of it
+                                    # to the existing group
+                                    if sub_command.name in existing_command.sub_commands \
+                                            and existing_command._sub_commands[sub_command.name].type.sub_command_group:
+                                        existing_group = existing_command._sub_commands[sub_command.name]
+                                        for sub_cmd in sub_command.sub_commands:
+                                            # set the parent of the subcommand to the existing group
+                                            sub_cmd.parent = existing_group
+                                            sub_cmd.disabled = False
+                                            existing_group._sub_commands[sub_cmd.name] = sub_cmd
+                                        if command.description != 'No Description':
+                                            existing_command.description = command.description
+                                        existing_group.name_localizations.update(command.name_localizations)
+                                        existing_group.description_localizations.update(
+                                            command.description_localizations
+                                        )
+                                        # maybe remove the if-statement in the future
+                                        if command.default_required_permissions:
+                                            existing_group.default_required_permissions = command.default_required_permissions
+                                        continue
+                                    else:
+                                        for sub_cmd in sub_command.sub_commands:
+                                            sub_cmd.disabled = False
+                                        existing_command._sub_commands[sub_command.name] = sub_command
+
+                                # set the parent of the subcommand to the existing command
+                                sub_command.parent = existing_command
+                                existing_command._sub_commands[sub_command.name] = sub_command
+                        else:
+                            # Just overwrite the existing one
+                            self._application_commands_by_type[cmd_type][command.name] = command
+                            continue
+
+                    else:
+                        # if it's not a slash-command overwrite the existing one
+                        self._application_commands_by_type[cmd_type][command.name] = command
+                        continue
+
+                    if command.description != 'No Description':
+                        existing_command.description = command.description
+                    existing_command.name_localizations.update(command.name_localizations)
+                    existing_command.description_localizations.update(command.description_localizations)
+                    # maybe remove the if-statement in the future
+                    if command.default_member_permissions:
+                        existing_command.member_required_permissions = command.default_member_permissions
+
+                else:
+                    self._application_commands_by_type[cmd_type][command.name] = command
+
+        for guild_id, commands_by_type in cog.__guild_specific_application_commands__.items():
+            # Set the cog og the commands to the Cog isinstance
+            for cmd_type, commands in commands_by_type.items():
+                for command in commands.values():
+                    command._set_cog(cog, recursive=True)
+
+            if guild_id not in self._guild_specific_application_commands:
+                # There are no commands only for this guild yet. So skip the checks and just add them.
+                self._guild_specific_application_commands[guild_id] = commands_by_type
+                continue
+
+            for cmd_type, commands in commands_by_type.items():
+                for command in commands.values():
+                    if command.name in self._guild_specific_application_commands[guild_id][cmd_type]:
+                        existing_command = self._guild_specific_application_commands[guild_id][cmd_type][command.name]
+                        existing_command.disabled = False
+                        if cmd_type == 'chat_input':
+                            if command.has_subcommands:
+
+                                # if the command has subcommands add them to the existing one.
+                                for sub_command in command.sub_commands:
+                                    sub_command.disabled = False
+                                    if sub_command.type.sub_command_group:
+                                        # if the subcommand is a group that already exists, add the subcommands of it
+                                        # to the existing group
+                                        if sub_command.name in existing_command.sub_commands \
+                                                and existing_command._sub_commands[
+                                            sub_command.name].type.sub_command_group:
+                                            existing_group = existing_command._sub_commands[sub_command.name]
+                                            for sub_cmd in sub_command.sub_commands:
+                                                # set the parent of the subcommand to the existing group
+                                                sub_cmd.parent = existing_group
+                                                sub_cmd.disabled = False
+                                                existing_group._sub_commands[sub_cmd.name] = sub_cmd
+                                            existing_group.name_localizations.update(sub_command.name_localizations)
+                                            existing_group.description_localizations.update(
+                                                sub_command.description_localizations
+                                                )
+                                            continue
+                                        else:
+                                            for sub_cmd in sub_command.sub_commands:
+                                                sub_cmd.disabled = False
+                                            existing_command._sub_commands[sub_command.name] = sub_command
+
+                                    # set the parent of the subcommand to the existing command
+                                    sub_command.parent = existing_command
+                                    existing_command._sub_commands[sub_command.name] = sub_command
+                            else:
+                                # Just overwrite the existing one
+                                self._guild_specific_application_commands[guild_id][cmd_type][command.name] = command
+                        else:
+                            # If it's not a slash-command overwrite the existing one
+                            self._guild_specific_application_commands[guild_id][cmd_type][command.name] = command
+
+                            continue
+
+                        if command.description != 'No Description':
+                            existing_command.description = command.description
+                        existing_command.name_localizations.update(command.name_localizations)
+                        existing_command.description_localizations.update(command.description_localizations)
+                        # maybe remove the if-statement in the future
+                        if command.default_member_permissions:
+                            existing_command.default_member_permissions = command.default_member_permissions
+
+                    else:
+                        self._guild_specific_application_commands[guild_id][cmd_type][command.name] = command
+
+    def remove_application_cmds_from_cog(self, cog: Cog):
+        """
+        Removes all application-commands in the given cog from the internal list of application-commands.
+
+        Parameters
+        ----------
+        cog: :class:`.Cog`
+            The cog which application-commands should be removed from the internal list of application-commands.
+        """
+        to_remove = []
+        for t in self._application_commands_by_type.values():
+            for cmd in t.values():
+                if cmd.cog and cmd.cog == cog:
+                    to_remove.append(cmd)
+                    continue
+                # Remove all subcommands from this command if they are in the cog.
+                if cmd.type.chat_input and cmd.has_subcommands:
+                    for sub_command in cmd.sub_commands:
+                        if sub_command.type.sub_command_group:
+                            for sub_cmd in sub_command.sub_commands:
+                                if sub_cmd.cog and sub_cmd.cog == cog:
+                                    del sub_command._sub_commands[sub_cmd.name]
+                        if sub_command.cog and sub_command.cog == cog:
+                            del cmd._sub_commands[sub_command.name]
+
+        for guild_id, t in self._guild_specific_application_commands.items():
+            for commands in t.values():
+                for cmd in commands.values():
+                    if cmd.cog and cmd.cog == cog:
+                        to_remove.append(cmd)
+                        continue
+                    # Remove all subcommands from this command if they are in the cog.
+                    if cmd.type == 'chat_input' and cmd.has_subcommands:
+                        for sub_command in cmd.sub_commands:
+                            if sub_command.type.sub_command_group:
+                                for sub_cmd in sub_command.sub_commands:
+                                    if sub_cmd.cog and sub_cmd.cog == cog:
+                                        del sub_command._sub_commands[sub_cmd.name]
+                            if sub_command.cog and sub_command.cog == cog:
+                                del cmd._sub_commands[sub_command.name]
+        for cmd in to_remove:
+            self._remove_application_command(cmd, from_cache=False)
+
     # help command stuff
 
     @property
@@ -962,8 +1147,10 @@ async def get_prefix(self, message):
                 if isinstance(ret, collections.abc.Iterable):
                     raise
 
-                raise TypeError("command_prefix must be plain string, iterable of strings, or callable "
-                                "returning either of these, not {}".format(ret.__class__.__name__))
+                raise TypeError(
+                    "command_prefix must be plain string, iterable of strings, or callable "
+                    "returning either of these, not {}".format(ret.__class__.__name__)
+                )
 
             if not ret:
                 raise ValueError("Iterable command_prefix must contain at least one prefix")
@@ -1023,14 +1210,18 @@ class be provided, it must be similar enough to :class:`.Context`\'s
 
             except TypeError:
                 if not isinstance(prefix, list):
-                    raise TypeError("get_prefix must return either a string or a list of string, "
-                                    "not {}".format(prefix.__class__.__name__))
+                    raise TypeError(
+                        "get_prefix must return either a string or a list of string, "
+                        "not {}".format(prefix.__class__.__name__)
+                    )
 
                 # It's possible a bad command_prefix got us here.
                 for value in prefix:
                     if not isinstance(value, str):
-                        raise TypeError("Iterable command_prefix or list returned from get_prefix must "
-                                        "contain only strings, not {}".format(value.__class__.__name__))
+                        raise TypeError(
+                            "Iterable command_prefix or list returned from get_prefix must "
+                            "contain only strings, not {}".format(value.__class__.__name__)
+                        )
 
                 # Getting here shouldn't happen
                 raise
@@ -1101,6 +1292,7 @@ async def process_commands(self, message):
     async def on_message(self, message):
         await self.process_commands(message)
 
+
 class Bot(BotBase, discord.Client):
     """Represents a discord bot.
 
@@ -1174,9 +1366,21 @@ class Bot(BotBase, discord.Client):
         the ``command_prefix`` is set to ``!``. Defaults to ``False``.
 
         .. versionadded:: 1.7
+    sync_commands: :class:`bool`
+        Whether to sync application-commands on startup, default ``False``.
+
+        This will register global and guild application-commands(slash-, user- and message-commands)
+        that are not registered yet, update changes and remove application-commands that could not be found
+        in the code anymore if :attr:`delete_not_existing_commands` is set to ``True`` what it is by default.
+
+    delete_not_existing_commands: :class:`bool`
+        Whether to remove global and guild-only application-commands that are not in the code anymore, default ``True``.
+    sync_commands_on_cog_reload: :class:`bool`
+        Whether to sync global and guild-only application-commands when reloading an extension, default ``False``.
     """
     pass
 
+
 class AutoShardedBot(BotBase, discord.AutoShardedClient):
     """This is similar to :class:`.Bot` except that it is inherited from
     :class:`discord.AutoShardedClient` instead.
diff --git a/discord/ext/commands/cog.py b/discord/ext/commands/cog.py
index 90bd103e..24e8ec55 100644
--- a/discord/ext/commands/cog.py
+++ b/discord/ext/commands/cog.py
@@ -3,7 +3,7 @@
 """
 The MIT License (MIT)
 
-Copyright (c) 2015-present Rapptz
+Copyright (c) 2015-2021 Rapptz & (c) 2021-present mccoderpy
 
 Permission is hereby granted, free of charge, to any person obtaining a
 copy of this software and associated documentation files (the "Software"),
@@ -23,9 +23,28 @@
 FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 DEALINGS IN THE SOFTWARE.
 """
+from __future__ import annotations
 
-import inspect
+import re
 import copy
+import inspect
+
+from typing import (
+    Any,
+    AnyStr,
+    Awaitable,
+    Callable,
+    Coroutine,
+    Dict,
+    List,
+    Optional,
+    Pattern,
+    TypeVar,
+    TYPE_CHECKING,
+    Union,
+)
+from typing_extensions import TypeAlias
+
 from ._types import _BaseCommand
 
 __all__ = (
@@ -33,6 +52,25 @@
     'Cog',
 )
 
+from discord import MISSING, InvalidArgument, Permissions, InteractionContextType, AppIntegrationType
+from discord.application_commands import *
+
+if TYPE_CHECKING:
+    from discord.interactions import ApplicationCommandInteraction, ComponentInteraction, ModalSubmitInteraction
+    from discord.components import Button, Select
+    from discord.message import Message
+    from discord.user import User
+    from discord.member import Member
+
+    _Coro: TypeAlias = Coroutine[None, None, ...]
+    _SelectCallback: TypeAlias = Callable[[ComponentInteraction, Select], _Coro]
+    _ButtonCallback: TypeAlias = Callable[[ComponentInteraction, Button], _Coro]
+    _ModalCallback: TypeAlias = Callable[[ModalSubmitInteraction], _Coro]
+    _SlashCommandCallback: TypeAlias = Callable[[ApplicationCommandInteraction, ...], _Coro]
+    _MessageCommandCallback: TypeAlias = Callable[[ApplicationCommandInteraction, Message], _Coro]
+    _UserCommandCallback: TypeAlias = Callable[[ApplicationCommandInteraction, Union[User, Member]], _Coro]
+
+
 class CogMeta(type):
     """A metaclass for defining a cog.
 
@@ -92,6 +130,8 @@ async def foo(self, ctx):
                 async def bar(self, ctx):
                     pass # hidden -> False
     """
+    __application_commands_by_type__ = {'chat_input': {}, 'message': {}, 'user': {}}
+    __guild_specific_application_commands__ = {}
 
     def __new__(cls, *args, **kwargs):
         name, bases, attrs = args
@@ -105,7 +145,8 @@ def __new__(cls, *args, **kwargs):
 
         commands = {}
         listeners = {}
-        cog_interaction_listeners = {}
+        interaction_listeners = {}
+
         no_bot_cog = 'Commands or listeners must not start with cog_ or bot_ (in method {0.__name__}.{1})'
 
         new_cls = super().__new__(cls, name, bases, attrs, **kwargs)
@@ -125,6 +166,7 @@ def __new__(cls, *args, **kwargs):
                     if elem.startswith(('cog_', 'bot_')):
                         raise TypeError(no_bot_cog.format(base, elem))
                     commands[elem] = value
+
                 elif inspect.iscoroutinefunction(value):
                     try:
                         getattr(value, '__cog_listener__')
@@ -136,7 +178,7 @@ def __new__(cls, *args, **kwargs):
                         else:
                             if elem.startswith(('cog_', 'bot_')):
                                 raise TypeError(no_bot_cog.format(base, elem))
-                            cog_interaction_listeners[elem] = value
+                            interaction_listeners[elem] = value
                     else:
                         if elem.startswith(('cog_', 'bot_')):
                             raise TypeError(no_bot_cog.format(base, elem))
@@ -147,16 +189,17 @@ def __new__(cls, *args, **kwargs):
         listeners_as_list = []
         for listener in listeners.values():
             for listener_name in listener.__cog_listener_names__:
-                # I use __name__ instead of just storing the value so I can inject
+                # I use __name__ instead of just storing the value, so I can inject
                 # the self attribute when the time comes to add them to the bot
                 listeners_as_list.append((listener_name, listener.__name__))
 
+        new_cls.__cog_listeners__ = listeners_as_list
+
         interaction_listeners_as_list = []
-        for interaction_listener in cog_interaction_listeners.values():
-            for listener_name, custom_id in interaction_listener.__interaction_listener_names__:
-                interaction_listeners_as_list.append((listener_name, interaction_listener.__name__, custom_id))
+        for interaction_listener in interaction_listeners.values():
+            for listener_name, pattern in interaction_listener.__interaction_listener_names__:
+                interaction_listeners_as_list.append((listener_name, interaction_listener.__name__, pattern))
 
-        new_cls.__cog_listeners__ = listeners_as_list
         new_cls.__cog_interaction_listeners__ = interaction_listeners_as_list
 
         return new_cls
@@ -168,10 +211,12 @@ def __init__(self, *args, **kwargs):
     def qualified_name(cls):
         return cls.__cog_name__
 
+
 def _cog_special_method(func):
     func.__cog_special_method__ = None
     return func
 
+
 class Cog(metaclass=CogMeta):
     """The base class that all cogs must inherit from.
 
@@ -184,7 +229,7 @@ class Cog(metaclass=CogMeta):
     """
 
     def __new__(cls, *args, **kwargs):
-        # For issue 426, we need to store a copy of the command objects
+        # For :old-issue:`426`, we need to store a copy of the command objects
         # since we modify them to inject `self` to them.
         # To do this, we need to interfere with the Cog creation process.
         self = super().__new__(cls)
@@ -193,6 +238,16 @@ def __new__(cls, *args, **kwargs):
         # Either update the command with the cog provided defaults or copy it.
         self.__cog_commands__ = tuple(c._update_copy(cmd_attrs) for c in cls.__cog_commands__)
 
+        # set the functions of the commands to the method itself
+
+        self.__application_commands_by_type__ = copy.copy(cls.__application_commands_by_type__)
+
+        self.__guild_specific_application_commands__ = copy.copy(cls.__guild_specific_application_commands__)
+
+        # TODO: solve this thing on a better way
+        cls.__class__.__application_commands_by_type__ = {'chat_input': {}, 'message': {}, 'user': {}}
+        cls.__class__.__guild_specific_application_commands__ = {}
+
         lookup = {
             cmd.qualified_name: cmd
             for cmd in self.__cog_commands__
@@ -209,7 +264,6 @@ def __new__(cls, *args, **kwargs):
                 # Update our parent's reference to our self
                 parent.remove_command(command.name)
                 parent.add_command(command)
-
         return self
 
     def get_commands(self):
@@ -267,11 +321,11 @@ def get_listeners(self):
 
     @classmethod
     def _get_overridden_method(cls, method):
-        """Return None if the method is not overridden. Otherwise returns the overridden method."""
+        """Return None if the method is not overridden. Otherwise, returns the overridden method."""
         return getattr(method.__func__, '__cog_special_method__', method)
 
     @classmethod
-    def listener(cls, name=None):
+    def listener(cls, name: Optional[str] = None):
         """A decorator that marks a function as a listener.
 
         This is the cog equivalent of :meth:`.Bot.listen`.
@@ -312,35 +366,44 @@ def decorator(func):
         return decorator
     
     @classmethod
-    def on_click(cls, custom_id=None):
+    def on_click(
+            cls,
+            custom_id: Optional[Union[Pattern[AnyStr], AnyStr]] = None
+    ) -> Callable[[_ButtonCallback], _ButtonCallback]:
         """
-        A decorator that registers a raw_button_click event that checks on execution if the ``custom_id's`` are the same;
-        if so, the :func:`func` is called.
-
-        The function this is attached to must take the same parameters as a
-        `raw_button_click-Event <https://discordpy-message-components.rtfd.io/en/latest/addition.html#on_raw_button_click>`_.
+        A decorator with which you can assign a function to a specific :class:`~discord.Button` (or its custom_id).
 
         .. important::
+            The function this is attached to must take the same parameters as a
+            :func:`~discord.on_raw_button_click` event.
+
+        .. warning::
             The func must be a coroutine, if not, :exc:`TypeError` is raised.
 
         Parameters
         ----------
-        custom_id: Optional[str]
-            If the :attr:`custom_id` of the :class:`discord.Button` could not use as an function name
+        custom_id: Optional[Union[Pattern[AnyStr], AnyStr]]
+            If the :attr:`custom_id` of the :class:`discord.Button` could not use as a function name,
             or you want to give the function a different name then the custom_id use this one to set the custom_id.
+            You can also specify a regex and if the custom_id matches it, the function will be executed.
+
+            .. note::
+                As the ``custom_id`` is converted to a |pattern_object| put ``^`` in front and ``$`` at the end
+                of the :attr:`custom_id` if you want that the custom_id must exactly match the specified value.
+                Otherwise, something like 'cool blue Button is blue' will let the function bee invoked too.
 
         Example
         -------
         .. code-block:: python3
 
-            # the Button
+            # the button
             Button(label='Hey im a cool blue Button',
                    custom_id='cool blue Button',
-                   style=ButtonColor.blurple)
+                   style=ButtonStyle.blurple)
 
-            # function that's called when the Button pressed
-            @commands.Cog.on_click(custom_id='cool blue Button')
-            async def cool_blue_button(i: discord.Interaction, button):
+            # function that's called when the button pressed
+            @command.Cog.on_click(custom_id='cool blue Button')
+            async def cool_blue_button(self, i: discord.ComponentInteraction, button):
                 await i.respond(f'Hey you pressed a `{button.custom_id}`!', hidden=True)
 
         Raises
@@ -348,37 +411,49 @@ async def cool_blue_button(i: discord.Interaction, button):
         TypeError
             The coroutine passed is not actually a coroutine.
         """
-        def decorator(func):
+        def decorator(func: _ButtonCallback) -> _ButtonCallback:
             actual = func
             if isinstance(actual, staticmethod):
                 actual = actual.__func__
             if not inspect.iscoroutinefunction(actual):
                 raise TypeError('event registered must be a coroutine function')
             actual.__cog_interaction_listener__ = True
-            name = custom_id if custom_id else actual.__name__
+            pattern = re.compile(custom_id) if (
+                    custom_id is not None and not isinstance(custom_id, re.Pattern)
+            ) else re.compile(f'^{actual.__name__}$')
             try:
-                actual.__interaction_listener_names__.append(('raw_button_click', name))
+                actual.__interaction_listener_names__.append(('raw_button_click', pattern))
             except AttributeError:
-                actual.__interaction_listener_names__ = [('raw_button_click', name)]
+                actual.__interaction_listener_names__ = [('raw_button_click', pattern)]
             return func
         return decorator
 
     @classmethod
-    def on_select(cls, custom_id=None):
+    def on_select(
+            cls,
+            custom_id: Optional[Union[Pattern[AnyStr], AnyStr]] = None
+    ) -> Callable[[_SelectCallback], _SelectCallback]:
         """
-        A decorator with which you can assign a function to a specific :class:`SelectMenu` (or its custom_id).
-
-        The function this is attached to must take the same parameters as a
-        `raw_selection_select-Event <https://discordpy-message-components.rtfd.io/en/latest/addition.html#on_raw_selection_select>`_.
+        A decorator with which you can assign a function to a specific :class:`~discord.SelectMenu` (or its custom_id).
 
         .. important::
+            The function this is attached to must take the same parameters as a
+            :func:`~discord.on_raw_selection_select` event.
+
+        .. warning::
             The func must be a coroutine, if not, :exc:`TypeError` is raised.
 
         Parameters
         -----------
-        custom_id: Optional[str]
-            If the :attr:`custom_id` of the :class:`discord.SelectMenu` could not use as an function name
+        custom_id: Optional[Union[Pattern[AnyStr], AnyStr]]
+            If the :attr:`custom_id` of the :class:`~discord.SelectMenu` could not use as a function name,
             or you want to give the function a different name then the custom_id use this one to set the custom_id.
+            You can also specify a regex and if the custom_id matches it, the function will be executed.
+
+            .. note::
+                As the ``custom_id`` is converted to a |pattern_object| put ``^`` in front and ``$`` at the end
+                of the :attr:`custom_id` if you want that the custom_id must exactly match the specified value.
+                Otherwise, something like 'choose_your_gender later' will let the function bee invoked too.
 
         Example
         -------
@@ -395,7 +470,7 @@ def on_select(cls, custom_id=None):
 
             # function that's called when the SelectMenu is used
             @commands.Cog.on_select()
-            async def choose_your_gender(i: discord.Interaction, select_menu):
+            async def choose_your_gender(self, i: discord.ComponentInteraction, select_menu):
                 await i.respond(f'You selected `{select_menu.values[0]}`!', hidden=True)
 
         Raises
@@ -403,19 +478,673 @@ async def choose_your_gender(i: discord.Interaction, select_menu):
         TypeError
             The coroutine passed is not actually a coroutine.
         """
-        def decorator(func):
+        def decorator(func: _SelectCallback) -> _SelectCallback:
+            actual = func
+            if isinstance(actual, staticmethod):
+                actual = actual.__func__
+            if not inspect.iscoroutinefunction(actual):
+                raise TypeError('event registered must be a coroutine function')
+            actual.__cog_interaction_listener__ = True
+            pattern = re.compile(custom_id) if (
+                    custom_id is not None and not isinstance(custom_id, re.Pattern)
+            ) else re.compile(f'^{actual.__name__}$')
+            try:
+                actual.__interaction_listener_names__.append(('raw_selection_select', pattern))
+            except AttributeError:
+                actual.__interaction_listener_names__ = [('raw_selection_select', pattern)]
+            return func
+        return decorator
+
+    @classmethod
+    def on_submit(
+            cls,
+            custom_id: Optional[Union[Pattern[AnyStr], AnyStr]] = None
+    ) -> Callable[[_ModalCallback], _ModalCallback]:
+        """
+        A decorator with which you can assign a function to a specific :class:`~discord.Modal` (or its custom_id).
+
+        .. important::
+            The function this is attached to must take the same parameters as a
+            :func:`~discord.on_modal_submit` event.
+
+        .. warning::
+            The func must be a coroutine, if not, :exc:`TypeError` is raised.
+
+        Parameters
+        ----------
+        custom_id: Optional[Union[Pattern[AnyStr], AnyStr]]
+            If the :attr:`~discord.Modal.custom_id` of the modal could not use as a function name,
+            or you want to give the function a different name then the custom_id use this one to set the custom_id.
+            You can also specify a regex and if the custom_id matches it, the function will be executed.
+
+            .. note::
+                As the ``custom_id`` is converted to a |pattern_object| put ``^`` in front and ``$`` at the end
+                of the :attr:`custom_id` if you want that the custom_id must exactly match the specified value.
+                Otherwise, something like 'suggestions_modal_submit_private' will let the function bee invoked too.
+
+            .. tip::
+                The resulting |match_object| object will be
+                available under the :class:`~discord.ModalSubmitInteraction.match` attribute of the interaction.
+
+                **See example below.**
+
+        Example
+        -------
+        .. code-block:: python
+
+            # the Modal
+            Modal(title='Create a new suggestion',
+                  custom_id='suggestions_modal',
+                  components=[...])
+
+            # function that's called when the Modal is submitted
+            @commands.Cog.on_submit(custom_id='^suggestions_modal$')
+            async def suggestions_modal_callback(self, i: discord.ModalSubmitInteraction):
+                ...
+
+            # You can also use a more advanced RegEx containing groups to easily allow dynamic id's
+            @commands.Cog.on_submit(custom_id='^ticket_answer:(?P<id>[0-9]+)$')
+            async def ticket_answer_callback(i: discord.ModalSubmitInteraction):
+                user_id = int(i.match['id'])
+                user = client.get_user(user_id) or await client.fetch_user(user_id)
+
+
+        Raises
+        ------
+        TypeError
+            The coroutine passed is not actually a coroutine.
+        """
+
+        def decorator(func: _ModalCallback) -> _ModalCallback:
             actual = func
             if isinstance(actual, staticmethod):
                 actual = actual.__func__
             if not inspect.iscoroutinefunction(actual):
                 raise TypeError('event registered must be a coroutine function')
             actual.__cog_interaction_listener__ = True
-            name = custom_id if custom_id else actual.__name__
+            pattern = re.compile(custom_id) if (
+                    custom_id is not None and not isinstance(custom_id, re.Pattern)
+            ) else re.compile(f'^{actual.__name__}$')
             try:
-                actual.__interaction_listener_names__.append(('raw_selection_select', name))
+                actual.__interaction_listener_names__.append(('modal_submit', pattern))
             except AttributeError:
-                actual.__interaction_listener_names__ = [('raw_selection_select', name)]
+                actual.__interaction_listener_names__ = [('modal_submit', pattern)]
             return func
+
+        return decorator
+
+    @classmethod
+    def slash_command(
+            cls,
+            name: str = None,
+            name_localizations: Localizations = Localizations(),
+            description: Optional[str] = None,
+            description_localizations: Localizations = Localizations(),
+            allow_dm: bool = True,
+            allowed_contexts: Optional[List[InteractionContextType]] = MISSING,
+            allowed_integration_types: Optional[List[AppIntegrationType]] = MISSING,
+            is_nsfw: bool = MISSING,
+            default_required_permissions: Optional[Permissions] = None,
+            options: Optional[List] = [],
+            guild_ids: Optional[List[int]] = None,
+            connector: dict = {},
+            option_descriptions: dict = {},
+            option_descriptions_localizations: Dict[str, Localizations] = {},
+            base_name: Optional[str] = None,
+            base_name_localizations: Optional[Localizations] = Localizations(),
+            base_desc: Optional[str] = None,
+            base_desc_localizations: Optional[Localizations] = Localizations(),
+            group_name: Optional[str] = None,
+            group_name_localizations: Optional[Localizations] = Localizations(),
+            group_desc: Optional[str] = None,
+            group_desc_localizations: Optional[Localizations] = Localizations()
+    ) -> Callable[
+        [_SlashCommandCallback],
+        Union[SlashCommand, GuildOnlySlashCommand, SubCommand, GuildOnlySubCommand]
+    ]:
+        """
+        A decorator that adds a slash-command to the client. The method this is attached to must be a :ref:`coroutine <coroutine>`.
+
+        .. note::
+
+            :attr:`~discord.ext.commands.Bot.sync_commands` of the :class:`~discord.ext.commands.Bot` instance must be set to :obj:`True`
+            to register a command if it does not already exist and update it if changes where made.
+
+        .. note::
+            Any of the following parameters are only needed when the corresponding target was not used before
+            (e.g. there is already a command in the code that has these parameters set) - otherwise it will replace the previous value or update it for iterables:
+
+            - ``allow_dm``
+            - ``allowed_contexts`` (update)
+            - ``allowed_integration_types`` (update)
+            - ``is_nsfw``
+            - ``base_name_localizations``
+            - ``base_desc``
+            - ``base_desc_localizations``
+            - ``group_name_localizations``
+            - ``group_desc``
+            - ``group_desc_localizations``
+
+        Parameters
+        -----------
+        name: Optional[:class:`str`]
+            The name of the command. Must only contain a-z, _ and - and be 1-32 characters long.
+            Default to the functions name.
+        name_localizations: Optional[:class:`~discord.Localizations`]
+            Localizations object for name field. Values follow the same restrictions as :attr:`name`
+        description: Optional[:class:`str`]
+            The description of the command shows up in the client. Must be between 1-100 characters long.
+            Default to the functions docstring or "No Description".
+        description_localizations: Optional[:class:`~discord.Localizations`]
+            Localizations object for description field. Values follow the same restrictions as :attr:`description`
+        allow_dm: Optional[:class:`bool`]
+            **Deprecated**: Use :attr:`allowed_contexts` instead.
+            Indicates whether the command is available in DMs with the app, only for globally-scoped commands.
+            By default, commands are visible.
+        allowed_contexts: Optional[List[:class:`~discord.InteractionContextType`]]
+            **global commands only**: The contexts in which the command is available.
+            By default, commands are available in all contexts.
+        allowed_integration_types: Optional[List[:class:`~discord.AppIntegrationType`]]
+            **global commands only**: The types of app integrations where the command is available.
+            Default to the app's :ddocs:`configured integration types <resources/application#setting-supported-installation-contexts>`
+        is_nsfw: :class:`bool`
+            Whether this command is an :sup-art:`NSFW command <10123937946007-Age-Restricted-Commands>` , default :obj:`False`.
+
+            .. note::
+                Currently all sub-commands of a command that is marked as *NSFW* are NSFW too.
+
+        default_required_permissions: Optional[:class:`~discord.Permissions`]
+             Permissions that a Member needs by default to execute(see) the command.
+        options: Optional[List[:class:`~discord.SlashCommandOption`]]
+            A list of max. 25 options for the command. If not provided the options will be generated
+            using :meth:`generate_options` that creates the options out of the function parameters.
+            Required options **must** be listed before optional ones.
+            Use the ``connector`` parameter to connect non-ascii option names with the parameter of the function.
+        guild_ids: Optional[List[:class:`int`]]
+            ID's of guilds this command should be registered in. If empty, the command will be global.
+        connector: Optional[Dict[:class:`str`, :class:`str`]]
+            A dictionary containing the name of function-parameters as keys and the name of the option as values.
+            Useful for using non-ascii Letters in your option names without getting ide-errors.
+        option_descriptions: Optional[Dict[:class:`str`, :class:`str`]]
+            Descriptions the :func:`generate_options` should take for the Options that will be generated.
+            The keys are the :attr:`~discord.SlashCommandOption.name` of the option and the value the :attr:`~discord.SlashCommandOption.description`.
+
+            .. note::
+                This will only be used if ``options`` is not set.
+
+        option_descriptions_localizations: Optional[Dict[:class:`str`, :class:`~discord.Localizations`]]
+            Localized :attr:`~discord.SlashCommandOption.description` for the options.
+            In the format ``{'option_name': Localizations(...)}``
+        base_name: Optional[:class:`str`]
+            The name of the base-command(a-z, _ and -, 1-32 characters) if you want the command
+            to be in a command-/sub-command-group.
+            If the base-command does not exist yet, it will be added.
+        base_name_localizations: Optional[:class:`~discord.Localizations`]
+            Localized ``base_name``'s for the command.
+        base_desc: Optional[:class:`str`]
+            The description of the base-command(1-100 characters).
+        base_desc_localizations: Optional[:class:`~discord.Localizations`]
+            Localized ``base_description``'s for the command.
+        group_name: Optional[:class:`str`]
+            The name of the command-group(a-z, _ and -, 1-32 characters) if you want the command to be in a sub-command-group.
+        group_name_localizations: Optional[:class:`~discord.Localizations`]
+            Localized ``group_name``'s for the command.
+        group_desc: Optional[:class:`str`]
+            The description of the sub-command-group(1-100 characters).
+        group_desc_localizations: Optional[:class:`~discord.Localizations`]
+            Localized ``group_desc``'s for the command.
+
+        Raises
+        ------
+        :exc:`TypeError`:
+            The function the decorator is attached to is not actual a :ref:`coroutine <coroutine>`
+            or a parameter passed to :class:`SlashCommandOption` is invalid for the ``option_type`` or the ``option_type``
+            itself is invalid.
+        :exc:`~discord.InvalidArgument`:
+            You passed ``group_name`` but no ``base_name``.
+        :exc:`ValueError`:
+            Any of ``name``, ``description``, ``options``, ``base_name``, ``base_desc``, ``group_name`` or ``group_desc`` is not valid.
+
+        Returns
+        -------
+        The slash-command registered.
+            - If neither ``guild_ids`` nor ``base_name`` passed: An instance of :class:`~discord.SlashCommand`.
+            - If ``guild_ids`` and no ``base_name`` where passed: An instance of :class:`~discord.GuildOnlySlashCommand` representing the guild-only slash-commands.
+            - If ``base_name`` and no ``guild_ids`` where passed: An instance of :class:`~discord.SubCommand`.
+            - If ``base_name`` and ``guild_ids`` passed: instance of :class:`~discord.GuildOnlySubCommand` representing the guild-only sub-commands.
+        """
+
+        def decorator(func: _SlashCommandCallback) -> Union[
+            SlashCommand, GuildOnlySlashCommand, SubCommand, GuildOnlySubCommand
+        ]:
+            """
+
+            Parameters
+            ----------
+            func: Awaitable[Any]
+                The function for the decorator.
+
+            Returns
+            -------
+            Union[:class:`SlashCommand`, :class:`GuildOnlySlashCommand`, :class:`SubCommand`, :class:`GuildOnlySubCommand`]:
+                - If neither ``guild_ids`` nor ``base_name`` passed: An instance of :class:`~discord.SlashCommand`.
+                - If ``guild_ids`` and no ``base_name`` where passed: An instance of :class:`~discord.GuildOnlySlashCommand` representing the guild-only slash-commands.
+                - If ``base_name` and no ``guild_ids`` where passed: An instance of :class:`~discord.SubCommand`.
+                - If ``base_name`` and ``guild_ids`` passed: instance of :class:`~discord.GuildOnlySubCommand` representing the guild-only sub-commands.
+            """
+            actual = func
+            if isinstance(actual, staticmethod):
+                actual = actual.__func__
+            if not inspect.iscoroutinefunction(actual):
+                raise TypeError('The slash-command function registered  must be a coroutine.')
+            _name = (name or actual.__name__).lower()
+            _description = description or ((inspect.cleandoc(actual.__doc__)[:100]) if actual.__doc__ else 'No Description')
+            _options = options or generate_options(
+                actual,
+                descriptions=option_descriptions,
+                descriptions_localizations=option_descriptions_localizations,
+                connector=connector,
+                is_cog=True
+            )
+            if group_name and not base_name:
+                raise InvalidArgument('You have to provide the `base_name` parameter if you want to create a sub-command or sub-command-group.')
+            guild_cmds = []
+            if guild_ids:
+                guild_app_cmds = cls.__guild_specific_application_commands__
+                for guild_id in guild_ids:
+                    base, base_command, sub_command_group = None, None, None
+                    try:
+                        guild_app_cmds[guild_id]
+                    except KeyError:
+                        guild_app_cmds[guild_id] = {'chat_input': {}, 'message': {}, 'user': {}}
+                    if base_name:
+                        try:
+                            base_command = guild_app_cmds[guild_id]['chat_input'][base_name]
+                        except KeyError:
+                            base_command = guild_app_cmds[guild_id]['chat_input'][base_name] = SlashCommand(
+                                cog=cls,
+                                name=base_name,
+                                name_localizations=base_name_localizations,
+                                description=base_desc or 'No Description',
+                                description_localizations=base_desc_localizations,
+                                default_member_permissions=default_required_permissions,
+                                is_nsfw=is_nsfw if is_nsfw is not MISSING else False,
+                                guild_id=guild_id
+                            )
+                        else:
+                            if base_desc:
+                                base_command.description = base_desc
+                            base_command.name_localizations.update(base_name_localizations)
+                            base_command.description_localizations.update(base_desc_localizations)
+                        base = base_command
+                    if group_name:
+                        try:
+                            sub_command_group = guild_app_cmds[guild_id]['chat_input'][base_name]._sub_commands[group_name]
+                        except KeyError:
+                            sub_command_group = guild_app_cmds[guild_id]['chat_input'][base_name]._sub_commands[group_name] = SubCommandGroup(
+                                cog=cls,
+                                parent=base_command,
+                                name=group_name,
+                                name_localizations=group_name_localizations,
+                                description=group_desc or 'No Description',
+                                description_localizations=group_desc_localizations,
+                                guild_id=guild_id
+                            )
+                        else:
+                            if group_desc:
+                                sub_command_group.description = group_desc
+                            sub_command_group.name_localizations.update(group_name_localizations)
+                            sub_command_group.description_localizations.update(group_desc_localizations)
+                        base = sub_command_group
+                    if base:
+                        base._sub_commands[_name] = SubCommand(
+                            cog=cls,
+                            parent=base,
+                            func=actual,
+                            name=_name,
+                            name_localizations=name_localizations,
+                            description=_description,
+                            description_localizations=description_localizations,
+                            options=_options,
+                            connector=connector
+                        )
+                        guild_cmds.append(base._sub_commands[_name])
+                    else:
+                        guild_app_cmds[guild_id]['chat_input'][_name] = SlashCommand(
+                                cog=cls,
+                                guild_id=guild_id,
+                                func=actual,
+                                name=_name,
+                                name_localizations=name_localizations,
+                                description=_description,
+                                description_localizations=description_localizations,
+                                default_member_permissions=default_required_permissions,
+                                is_nsfw=is_nsfw if is_nsfw is not MISSING else False,
+                                options=_options,
+                                connector=connector
+                            )
+                        guild_cmds.append(guild_app_cmds[guild_id]['chat_input'][_name])
+
+                if base_name:
+                    base = GuildOnlySlashCommand(
+                        cog=cls,
+                        guild_ids=guild_ids,
+                        func=actual,
+                        name=_name,
+                        description=_description,
+                        default_member_permissions=default_required_permissions,
+                        is_nsfw=is_nsfw if is_nsfw is not MISSING else False,
+                        options=_options
+                    )
+                    if group_name:
+                        base = GuildOnlySubCommandGroup(
+                            cog=cls,
+                            guild_ids=guild_ids,
+                            parent=base,
+                            name=_name,
+                            description=_description,
+                            default_member_permissions=default_required_permissions,
+                            options=_options
+                        )
+                    return GuildOnlySubCommand(
+                        cog=cls,
+                        guild_ids=guild_ids,
+                        parent=base,
+                        func=actual,
+                        name=_name,
+                        description=_description,
+                        options=_options,
+                        connector=connector,
+                        commands=guild_cmds
+                    )
+                return GuildOnlySlashCommand(
+                    cog=cls,
+                    guild_ids=guild_ids,
+                    func=actual,
+                    name=_name,
+                    description=_description,
+                    default_member_permissions=default_required_permissions,
+                    options=_options,
+                    connector=connector,
+                    commands=guild_cmds
+                )
+            else:
+                app_cmds = cls.__application_commands_by_type__
+                base, base_command, sub_command_group = None, None, None
+                if base_name:
+                    try:
+                        base_command = app_cmds['chat_input'][base_name]
+                    except KeyError:
+                        base_command = app_cmds['chat_input'][base_name] = SlashCommand(
+                            cog=cls,
+                            name=base_name,
+                            name_localizations=base_name_localizations,
+                            description=base_desc or 'No Description',
+                            description_localizations=base_desc_localizations,
+                            default_member_permissions=default_required_permissions,
+                            allow_dm=allow_dm if allow_dm is not MISSING else True,
+                            is_nsfw=is_nsfw if is_nsfw is not MISSING else False,
+                            integration_types=allowed_integration_types if allowed_integration_types is not MISSING else None,
+                            contexts=allowed_contexts if allowed_contexts is not MISSING else None
+                        )
+                    else:
+                        if base_desc:
+                            base_command.description = base_desc
+                        if allow_dm is not MISSING:
+                            base_command.allow_dm = allow_dm
+                        if is_nsfw is not MISSING:
+                            base_command.is_nsfw = is_nsfw
+                        if allowed_integration_types is not MISSING:
+                            base_command.integration_types.update(allowed_integration_types)
+                        if allowed_contexts is not MISSING:
+                            base_command.contexts.update(allowed_contexts)
+                        base_command.name_localizations.update(base_name_localizations)
+                        base_command.description_localizations.update(base_desc_localizations)
+                    base = base_command
+                if group_name:
+                    try:
+                        sub_command_group = app_cmds['chat_input'][base_name]._sub_commands[group_name]
+                    except KeyError:
+                        sub_command_group = app_cmds['chat_input'][base_name]._sub_commands[group_name] = SubCommandGroup(
+                            parent=base_command,
+                            name=group_name,
+                            name_localizations=group_name_localizations,
+                            description=group_desc or 'No Description',
+                            description_localizations=group_desc_localizations
+                        )
+                    else:
+                        if group_desc:
+                            sub_command_group.description = group_desc
+                        sub_command_group.name_localizations.update(group_name_localizations)
+                        sub_command_group.description_localizations.update(group_desc_localizations)
+                    base = sub_command_group
+                if base:
+                    command = base._sub_commands[_name] = SubCommand(
+                        cog=cls,
+                        parent=base,
+                        func=actual,
+                        name=_name,
+                        name_localizations=name_localizations,
+                        description=_description,
+                        description_localizations=description_localizations,
+                        options=_options,
+                        connector=connector
+                    )
+                else:
+                    command = cls.__application_commands_by_type__['chat_input'][_name] = SlashCommand(
+                        cog=cls,
+                        func=actual,
+                        name=_name,
+                        name_localizations=name_localizations,
+                        description=_description or 'No Description',
+                        description_localizations=description_localizations,
+                        default_member_permissions=default_required_permissions,
+                        allow_dm=allow_dm if allow_dm is not MISSING else True,
+                        integration_types=allowed_integration_types if allowed_integration_types is not MISSING else None,
+                        contexts=allowed_contexts if allowed_contexts is not MISSING else None,
+                        is_nsfw=is_nsfw if is_nsfw is not MISSING else False,
+                        options=_options,
+                        connector=connector
+                    )
+
+                return command
+        return decorator
+
+    @classmethod
+    def message_command(
+            cls,
+            name: Optional[str] = None,
+            name_localizations: Localizations = Localizations(),
+            default_required_permissions: Optional[Permissions] = None,
+            allow_dm: bool = True,
+            allowed_contexts: Optional[List[InteractionContextType]] = MISSING,
+            allowed_integration_types: Optional[List[AppIntegrationType]] = MISSING,
+            is_nsfw: bool = False,
+            guild_ids: Optional[List[int]] = None
+    ) -> Callable[[_MessageCommandCallback], MessageCommand]:
+        """
+        A decorator that registers a :class:`~discord.MessageCommand` (shows up under ``Apps`` when right-clicking on a message)
+        to the client. The function this is attached to must be a :ref:`coroutine <coroutine>`.
+
+        .. note::
+            :attr:`~Bot.sync_commands` of the :class:`~discord.ext.commands.Bot` instance must be set to :obj:`True`
+            to register a command if it does not already exist and update it if changes where made.
+
+        Parameters
+        ----------
+        name: Optional[:class:`str`]
+            The name of the message-command, default to the functions name.
+            Must be between 1-32 characters long.
+        name_localizations: :class:`Localizations`
+            Localized ``name``'s.
+        default_required_permissions: Optional[:class:`Permissions`]
+            Permissions that a member needs by default to execute(see) the command.
+        allow_dm: :class:`bool`
+            **Deprecated**: Use :attr:`allowed_contexts` instead.
+            Indicates whether the command is available in DMs with the app, only for globally-scoped commands.
+            By default, commands are visible.
+        allowed_contexts: Optional[List[:class:`~discord.InteractionContextType`]]
+            **global commands only**: The contexts in which the command is available.
+            By default, commands are available in all contexts.
+        allowed_integration_types: Optional[List[:class:`~discord.AppIntegrationType`]]
+            **global commands only**: The types of app integrations where the command is available.
+            Default to the app's :ddocs:`configured integration types <resources/application#setting-supported-installation-contexts>`
+        is_nsfw: :class:`bool`
+            Whether this command is an :sup-art:`NSFW command <10123937946007-Age-Restricted-Commands>` , default :obj:`False`.
+        guild_ids: Optional[List[:class:`int`]]
+            ID's of guilds this command should be registered in. If empty, the command will be global.
+
+        Returns
+        -------
+        ~discord.MessageCommand:
+            The message-command registered.
+
+        Raises
+        ------
+        TypeError:
+            The function the decorator is attached to is not actual a :ref:`coroutine <coroutine>`.
+        """
+        def decorator(func: _MessageCommandCallback) -> MessageCommand:
+            actual = func
+            if isinstance(actual, staticmethod):
+                actual = actual.__func__
+            if not inspect.iscoroutinefunction(actual):
+                raise TypeError('The message-command function registered must be a coroutine.')
+            _name = name or actual.__name__
+            cmd = MessageCommand(
+                cog=cls,
+                guild_ids=guild_ids,
+                func=actual,
+                name=_name,
+                name_localizations=name_localizations,
+                default_member_permissions=default_required_permissions,
+                allow_dm=allow_dm,
+                integration_types=allowed_integration_types if allowed_integration_types is not MISSING else None,
+                contexts=allowed_contexts if allowed_contexts is not MISSING else None,
+                is_nsfw=is_nsfw
+            )
+            if guild_ids:
+                for guild_id in guild_ids:
+                    guild_cmd = MessageCommand(
+                        cog=cls,
+                        guild_id=guild_id,
+                        func=func,
+                        name=_name,
+                        name_localizations=name_localizations,
+                        default_member_permissions=default_required_permissions,
+                        allow_dm=allow_dm,
+                        is_nsfw=is_nsfw
+                    )
+                    try:
+                        cls.__guild_specific_application_commands__[guild_id]['message'][_name] = guild_cmd
+                    except KeyError:
+                        cls.__guild_specific_application_commands__[guild_id] = {
+                            'chat_input': {},
+                            'message': {_name: guild_cmd},
+                            'user': {}
+                        }
+            else:
+                cls.__application_commands_by_type__['message'][cmd.name] = cmd
+
+            return cmd
+        return decorator
+
+    @classmethod
+    def user_command(
+            cls,
+            name: str = None,
+            name_localizations: Localizations = Localizations(),
+            default_required_permissions: Optional[Permissions] = None,
+            allow_dm: bool = True,
+            allowed_contexts: Optional[List[InteractionContextType]] = MISSING,
+            allowed_integration_types: Optional[List[AppIntegrationType]] = MISSING,
+            is_nsfw: bool = False,
+            guild_ids: Optional[List[int]] = None
+    ) -> Callable[[_UserCommandCallback], UserCommand]:
+        """A decorator that registers a :class:`UserCommand` (shows up under ``Apps`` when right-clicking on a user) to the client.
+        The function this is attached to must be a :ref:`coroutine <coroutine>`.
+
+        .. note::
+            :attr:`~Bot.sync_commands` of the :class:`~discord.ext.commands.Bot` instance must be set to :obj:`True`
+            to register a command if he not already exists and update him if changes where made.
+
+        Parameters
+        ----------
+        name: Optional[:class:`str`]
+            The name of the user-command, default to the functions name.
+            Must be between 1-32 characters long.
+        name_localizations: :class:`Localizations`
+            Localized ``name``'s.
+        default_required_permissions: Optional[:class:`Permissions`]
+            Permissions that a member needs by default to execute(see) the command.
+        allow_dm: :class:`bool`
+            **Deprecated**: Use :attr:`allowed_contexts` instead.
+            Indicates whether the command is available in DMs with the app, only for globally-scoped commands.
+            By default, commands are visible.
+        allowed_contexts: Optional[List[:class:`~discord.InteractionContextType`]]
+            **global commands only**: The contexts in which the command is available.
+            By default, commands are available in all contexts.
+        allowed_integration_types: Optional[List[:class:`~discord.AppIntegrationType`]]
+            **global commands only**: The types of app integrations where the command is available.
+            Default to the app's :ddocs:`configured integration types <resources/application#setting-supported-installation-contexts>`
+        is_nsfw: :class:`bool`
+            Whether this command is an :sup-art:`NSFW command <10123937946007-Age-Restricted-Commands>` , default :obj:`False`.
+        guild_ids: Optional[List[:class:`int`]]
+            ID's of guilds this command should be registered in. If empty, the command will be global.
+
+        Returns
+        -------
+        ~discord.UserCommand:
+            The user-command registered.
+
+        Raises
+        ------
+        TypeError:
+            The function the decorator is attached to is not actual a :ref:`coroutine <coroutine>`.
+        """
+        def decorator(func: _UserCommandCallback) -> UserCommand:
+            actual = func
+            if isinstance(actual, staticmethod):
+                actual = actual.__func__
+            if not inspect.iscoroutinefunction(actual):
+                raise TypeError('The user-command function registered must be a coroutine.')
+            _name = name or actual.__name__
+            cmd = UserCommand(
+                cog=cls,
+                guild_ids=guild_ids,
+                func=actual,
+                name=_name,
+                name_localizations=name_localizations,
+                default_member_permissions=default_required_permissions,
+                allow_dm=allow_dm,
+                integration_types=allowed_integration_types if allowed_integration_types is not MISSING else None,
+                contexts=allowed_contexts if allowed_contexts is not MISSING else None,
+                is_nsfw=is_nsfw
+            )
+            if guild_ids:
+                for guild_id in guild_ids:
+                    guild_cmd = UserCommand(
+                        cog=cls,
+                        guild_id=guild_id,
+                        func=actual,
+                        name=_name,
+                        name_localizations=name_localizations,
+                        default_member_permissions=default_required_permissions,
+                        allow_dm=allow_dm,
+                        is_nsfw=is_nsfw
+                    )
+                    try:
+                        cls.__guild_specific_application_commands__[guild_id]['user'][_name] = guild_cmd
+                    except KeyError:
+                        cls.__guild_specific_application_commands__[guild_id] = {
+                            'chat_input': {},
+                            'message': {},
+                            'user': {_name: guild_cmd}
+                        }
+            else:
+                cls.__application_commands_by_type__['user'][_name] = cmd
+
+            return cmd
         return decorator
 
     def has_error_handler(self):
@@ -515,6 +1244,28 @@ async def cog_after_invoke(self, ctx):
         """
         pass
 
+    @_cog_special_method
+    async def cog_application_command_error(self, cmd, interaction, error):
+        """A special method that is called whenever an error
+
+        is dispatched inside this cog.
+
+        This is similar to :func:`.on_application_command_error` except only applying
+        to the application-commands inside this cog.
+
+        This **must** be a coroutine.
+
+        Parameters
+        -----------
+        cmd: Union[:class:`~discord.SlashCommand`, :class:`~discord.SubCommand`]
+            The invoked command.
+        interaction: :class:`discord.ApplicationCommandInteraction`
+            The interaction.
+        error: :class:`Exception`
+            The error that happened.
+        """
+        pass
+
     def _inject(self, bot):
         cls = self.__class__
 
@@ -544,13 +1295,15 @@ def _inject(self, bot):
         # while Bot.add_listener can raise if it's not a coroutine,
         # this precondition is already met by the listener decorator
         # already, thus this should never raise.
-        # Outside of, memory errors and the like...
+        # Outside of memory errors and the like...
         for name, method_name in self.__cog_listeners__:
             bot.add_listener(getattr(self, method_name), name)
 
         for (_type, method_name, custom_id) in self.__cog_interaction_listeners__:
             bot.add_interaction_listener(_type, getattr(self, method_name), custom_id)
 
+        bot.add_application_cmds_from_cog(self)
+
         return self
 
     def _eject(self, bot):
@@ -565,7 +1318,9 @@ def _eject(self, bot):
                 bot.remove_listener(getattr(self, method_name))
 
             for (_type, method_name, custom_id) in self.__cog_interaction_listeners__:
-                bot.remove_interaction_listener(_type, getattr(self, method_name), custom_id)
+                bot.remove_interaction_listener(_type, getattr(self, method_name))
+
+            bot.remove_application_cmds_from_cog(self)
 
             if cls.bot_check is not Cog.bot_check:
                 bot.remove_check(self.bot_check)
diff --git a/discord/ext/commands/converter.py b/discord/ext/commands/converter.py
index fdc7649b..95630f28 100644
--- a/discord/ext/commands/converter.py
+++ b/discord/ext/commands/converter.py
@@ -3,7 +3,7 @@
 """
 The MIT License (MIT)
 
-Copyright (c) 2015-present Rapptz
+Copyright (c) 2015-2021 Rapptz & (c) 2021-present mccoderpy
 
 Permission is hereby granted, free of charge, to any person obtaining a
 copy of this software and associated documentation files (the "Software"),
@@ -23,7 +23,7 @@
 FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 DEALINGS IN THE SOFTWARE.
 """
-
+import datetime
 import re
 import inspect
 import typing
@@ -49,6 +49,7 @@
     'StageChannelConverter',
     'EmojiConverter',
     'PartialEmojiConverter',
+    'StickerConverter',
     'CategoryChannelConverter',
     'IDConverter',
     'StoreChannelConverter',
@@ -121,8 +122,9 @@ class MemberConverter(IDConverter):
     1. Lookup by ID.
     2. Lookup by mention.
     3. Lookup by name#discrim
-    4. Lookup by name
-    5. Lookup by nickname
+    4. Lookup by display name (global_name)
+    5. Lookup by username
+    6. Lookup by nickname
 
     .. versionchanged:: 1.5
          Raise :exc:`.MemberNotFound` instead of generic :exc:`.BadArgument`
@@ -206,13 +208,14 @@ class UserConverter(IDConverter):
     1. Lookup by ID.
     2. Lookup by mention.
     3. Lookup by name#discrim
-    4. Lookup by name
+    4. Lookup by display name (global_name)
+    5. Lookup by username
 
     .. versionchanged:: 1.5
          Raise :exc:`.UserNotFound` instead of generic :exc:`.BadArgument`
 
     .. versionchanged:: 1.6
-        This converter now lazily fetches users from the HTTP APIs if an ID is passed
+        This converter now lazily fetches users from the HTTP APIs if an ID is passed,
         and it's not available in cache.
     """
     async def convert(self, ctx, argument):
@@ -247,7 +250,7 @@ async def convert(self, ctx, argument):
             if result is not None:
                 return result
 
-        predicate = lambda u: u.name == arg
+        predicate = lambda u: u.global_name == arg or  u.username == arg
         result = discord.utils.find(predicate, state._users.values())
 
         if result is None:
@@ -357,6 +360,34 @@ def check(c):
 
         return result
 
+class ThreadChannelConverter(IDConverter):
+    async def convert(self, ctx, argument):
+        bot = ctx.bot
+
+        match = self._get_id_match(argument) or re.match(r'<#([0-9]+)>$', argument)
+        result = None
+        guild = ctx.guild
+
+        if match is None:
+            # not a mention
+            if guild:
+                result = discord.utils.get(guild.thread_channels, name=argument)
+            else:
+                def check(c):
+                    return isinstance(c, discord.ThreadChannel) and c.name == argument
+                result = discord.utils.find(check, bot.get_all_channels())
+        else:
+            channel_id = int(match.group(1))
+            if guild:
+                result = guild.get_channel(channel_id)
+            else:
+                result = _get_from_guilds(bot, 'get_channel', channel_id)
+
+        if not isinstance(result, discord.ThreadChannel):
+            raise ChannelNotFound(argument)
+
+        return result
+
 class VoiceChannelConverter(IDConverter):
     """Converts to a :class:`~discord.VoiceChannel`.
 
@@ -745,6 +776,183 @@ async def convert(self, ctx, argument):
 
         raise PartialEmojiConversionFailure(argument)
 
+
+class StickerConverter(IDConverter):
+    """Converts to a :class:`~discord.Sticker`.
+
+    All lookups are done for the local guild first, if available. If that lookup
+    fails, then it checks the client's global cache.
+
+    The lookup strategy is as follows (in order):
+
+    1. Lookup by name.
+    2. Lookup by ID.
+    """
+    async def convert(self, ctx, argument):
+        match = self._get_id_match(argument)
+        result = None
+        bot = ctx.bot
+        guild = ctx.guild
+
+        if match is None:
+            # Try to get the sticker by name. Try local guild first.
+            if guild:
+                result = discord.utils.get(guild.stickers, name=argument)
+
+            if result is None:
+                result = discord.utils.get(bot.stickers, name=argument)
+        else:
+            sticker_id = int(match.group(1))
+
+            # Try to look up sticker by id.
+            if guild:
+                result = discord.utils.get(guild.stickers, id=sticker_id)
+
+            if result is None:
+                result = discord.utils.get(bot.stickers, id=sticker_id)
+
+        if result is None:
+            raise StickerNotFound(argument)
+
+        return result
+
+
+class datetimeConverter(Converter):
+    """Converts to a :class:`datetime.datetime`. Made by mccuber04#2960
+
+    Valid formats for the time(``H`` = hour | ``M`` = minute | ``S`` = second):
+        ``HH:MM:SS``,
+        ``HH:MM``
+
+        Each value can also be specified as a single digit.
+
+        All ``:`` could be ``-`` too.
+
+    Valid formats for the date(``d`` = day | ``m`` = month | ``y`` = year):
+        ``dd.mm.yyyy``,
+        ``dd.mm``,
+        ``dd``,
+        ``yyyy``
+        ``mm.yyyy``
+
+        Each value for day and month can also be specified as a single digit.
+
+        All ``.`` could be ``,``, ``-`` and ``/`` too.
+
+    .. note::
+        Values that are not specified are filled with those of the current time.
+
+        If you want to pass a time in 12h-format that is in the afternoon,
+        the ``pm`` must be after the time like ``08:42 pm 04.10.2022``.
+    """
+    time_regex = re.compile(
+        r'(?P<hour>'  # group for hour value
+        r'0?[0-9]'  # 0 to 9
+        r'|'  # or
+        r'1[0-9]'  # 10 to 19
+        r'|'  # or
+        r'2[0-3]'  # 20 to 23
+        r')'
+        r'[:\-]'  # brake could be : or -
+        r'(?P<minute>'  # group for minute value
+        r'[1-5][0-9]'  # 10 to 59
+        r'|'  # or
+        r'0?[0-9]'  # 0 to 9
+        r')'
+        r'('  # group for brake and second
+        r'[:\-]'  # brake could be : or -
+        r'(?P<second>'  # group for second value
+        r'[1-5][0-9]'  # 10 to 59
+        r'|'  # or
+        r'[0-9]'  # 0 to 9
+        r')'
+        r')?'  # mark the brake and second group as optional
+        r' ?' # a optional whitespace
+        r'(?P<am_or_pm>'  # group for am or pm value if it is in 12h-format
+        r'am' # am for ante mediteran (Morning), would be ignored
+        r'|'  # or
+        r'pm'  # pm for post mediteran (afternoon)
+        r')'
+    )
+    date_regex = re.compile(
+        r'(?P<day>'  # group for day value
+        r'3[0-1]'  # 31. or 30.
+        r'|'  # or
+        r'[1-2][0-9]'  # 10. to 29.
+        r'|'  # or
+        r'0?[1-9]'  # 1. to 9.
+        r')?'  # mark the day as optional
+        r'('  # group for brake and month
+        r'[.,\-/]'  # brake could be . or , or - or /
+        r'(?P<month>'  # group for month value
+        r'1[0-2]'  # october to december
+        r'|'  # or
+        r'0?[1-9]'  # january to september
+        r')'
+        r')?'  # mark the brake and month group as optional 
+        r'('  # group for brake and year
+        r'[.,\-/]'  # brake could be . or , or - or /
+        r'(?P<year>'  # group for year value
+        r'[1-9][0-9]{3}'  # any year from 1000 to 9999 in format yyyy
+        r'|'  # or
+        r'[0-9]{2}'   # any year from 2000 to 2099 in format YY (20YY)
+        r')'
+        r'(\s|$)' # to be shure that "1996telefon" is not valid there should be a whitespace or the end of the string after the year
+        r')?'  # mark the brake and year group as optional
+    )
+
+    async def convert(self, ctx, argument) -> datetime.datetime:
+        argument = argument.lower().rstrip()
+
+        now = datetime.datetime.utcnow()  # to set defaults for non provided parts
+        invalid = False
+
+        date = self.date_regex.search(argument)
+
+        if date and any(date.groups()):
+            day = int(date.group('day') or now.day)
+            month = int(date.group('month') or now.month)
+            year = date.group('year')
+
+            if year and len(year) == 2: # it is in YY (20YY) format, convert it to a full year (yyyy)
+                year = '20' + year
+
+            year = int(year or now.year)
+            # to make something like ``10.2022`` also valid
+            if date.group('day') and not date.group('month'):
+                month = day
+                day = now.day
+        else:
+            invalid = True
+            day, month, year = now.day, now.month, now.year
+
+        time = self.time_regex.search(argument)
+
+        if time and any(time.groups()):
+            invalid = False
+            pm = bool(time.group('am_or_pm') == 'pm')
+            hour = int(time.group('hour') or now.hour)
+            # if it is in 12-hour format and pm, just increase it by 12 so that it is in 24-hour format
+            if pm and hour <= 12:
+                hour += 12
+            minute = int(time.group('minute') or now.minute)
+            second = int(time.group('second') or now.second)
+
+        else:
+            # set the time to the current if no time provided
+            hour, minute, second = now.hour, now.minute, now.second
+
+        if invalid:
+            raise DatetimeConversionFailure(argument)
+
+        try:
+            result = datetime.datetime(year=year, month=month, day=day, hour=hour, minute=minute, second=second)
+        except Exception as exc:
+            raise DatetimeConversionFailure(argument, original_exception=exc)
+        else:
+            return result
+
+
 class clean_content(Converter):
     """Converts the argument to mention scrubbed version of
     said content.
diff --git a/discord/ext/commands/core.py b/discord/ext/commands/core.py
index 1c22ec0a..fc47acd6 100644
--- a/discord/ext/commands/core.py
+++ b/discord/ext/commands/core.py
@@ -27,7 +27,7 @@
 import asyncio
 import functools
 import inspect
-import typing
+from typing import Union, Optional, List, Tuple, Dict, Any, Callable
 import datetime
 
 import discord
@@ -441,8 +441,11 @@ async def _actual_conversion(self, ctx, converter, argument, param):
         except AttributeError:
             pass
         else:
-            if module is not None and (module.startswith('discord.') and not module.endswith('converter')):
-                converter = getattr(converters, converter.__name__ + 'Converter', converter)
+            if module is not None:
+                if module.startswith('discord.') and module.endswith('converter'):
+                    pass
+                else:
+                    converter = getattr(converters, converter.__name__ + 'Converter', converter)
 
         try:
             if inspect.isclass(converter):
@@ -481,7 +484,7 @@ async def do_conversion(self, ctx, converter, argument, param):
         except AttributeError:
             pass
         else:
-            if origin is typing.Union:
+            if origin is Union:
                 errors = []
                 _NoneType = type(None)
                 for conv in converter.__args__:
@@ -989,7 +992,7 @@ def _is_typing_optional(self, annotation):
         except AttributeError:
             return False
 
-        if origin is not typing.Union:
+        if origin is not Union:
             return False
 
         return annotation.__args__[-1] is type(None)
@@ -1155,6 +1158,30 @@ def add_command(self, command):
                 raise CommandRegistrationError(alias, alias_conflict=True)
             self.all_commands[alias] = command
 
+    def add_commands(self, *commands):
+        """
+        Similar to :meth:`.add_command` but you can pass multiple commands at once.
+
+        Parameters
+        ----------
+        commands: Tuple[:class:`.Command`]
+            The commands to add
+
+        Parameters
+        -----------
+        command: :class:`Command`
+            The command to add.
+
+        Raises
+        -------
+        :exc:`.CommandRegistrationError`
+            If any of the commands or its alias is already registered by different command.
+        TypeError
+            If any of the commands passed is not a subclass of :class:`.Command`.
+        """
+        for command in commands:
+            self.add_command(command)
+
     def remove_command(self, name):
         """Remove a :class:`.Command` from the internal list
         of commands.
@@ -1394,7 +1421,7 @@ async def reinvoke(self, ctx, *, call_hooks=False):
 
 # Decorators
 
-def command(name=None, cls=None, **attrs):
+def command(name=None, cls=None, **attrs) -> Union[Command, Group]:
     """A decorator that transforms a function into a :class:`.Command`
     or if called with :func:`.group`, :class:`.Group`.
 
@@ -1434,7 +1461,7 @@ def decorator(func):
 
     return decorator
 
-def group(name=None, **attrs):
+def group(name=None, **attrs) -> Group:
     """A decorator that transforms a function into a :class:`.Group`.
 
     This is similar to the :func:`.command` decorator but the ``cls``
@@ -1934,7 +1961,7 @@ def is_nsfw():
     """
     def pred(ctx):
         ch = ctx.channel
-        if ctx.guild is None or (isinstance(ch, discord.TextChannel) and ch.is_nsfw()):
+        if ctx.guild is None or (isinstance(ch, (discord.TextChannel, discord.ThreadChannel)) and ch.is_nsfw()):
             return True
         raise NSFWChannelRequired(ch)
     return check(pred)
diff --git a/discord/ext/commands/errors.py b/discord/ext/commands/errors.py
index d533d96a..05d9067b 100644
--- a/discord/ext/commands/errors.py
+++ b/discord/ext/commands/errors.py
@@ -53,7 +53,9 @@
     'RoleNotFound',
     'BadInviteArgument',
     'EmojiNotFound',
+    'StickerNotFound',
     'PartialEmojiConversionFailure',
+    'DatetimeConversionFailure',
     'BadBoolArgument',
     'MissingRole',
     'BotMissingRole',
@@ -390,6 +392,44 @@ def __init__(self, argument):
         self.argument = argument
         super().__init__('Couldn\'t convert "{}" to PartialEmoji.'.format(argument))
 
+class StickerNotFound(BadArgument):
+    """Exception raised when the bot can not find the sticker.
+
+    This inherits from :exc:`BadArgument`
+
+
+    Attributes
+    -----------
+    argument: :class:`str`
+        The sticker supplied by the caller that was not found
+    """
+    def __init__(self, argument):
+        self.argument = argument
+        super().__init__('Sticker "{}" not found.'.format(argument))
+
+class DatetimeConversionFailure(BadArgument):
+    """Exception raised when the conversion to a :class:`datetime.datetime` object failed
+
+    This inherits from :exc:`BadArgument`
+
+    Attributes
+    -----------
+    argument: :class: :class:`str`
+        The date/time supplied by the caller that could not converted.
+    original_exception: Optional[Any]
+        The original exception that was raised when trying to create the datetime.datetime object.
+    """
+    def __init__(self, argument, original_exception=None):
+        self.argument = argument
+        self.original_exception = original_exception
+        super().__init__(
+            '"{}" could not be converted to a datetime.datetime object. '
+            'The time should be in a format like H(H):M(M):S(S) '
+            'and date in a format like d(d).m(m).yyyy'.format(argument)
+        )
+
+
+
 class BadBoolArgument(BadArgument):
     """Exception raised when a boolean argument was not convertable.
 
diff --git a/discord/ext/commands/help.py b/discord/ext/commands/help.py
index f3324686..fd4b8f3d 100644
--- a/discord/ext/commands/help.py
+++ b/discord/ext/commands/help.py
@@ -259,7 +259,7 @@ class HelpCommand:
 
         Internally instances of this class are deep copied every time
         the command itself is invoked to prevent a race condition
-        mentioned in :issue:`2123`.
+        mentioned in :old-issue:`2123`.
 
         This means that relying on the state of this class to be
         the same between command invocations would not work as expected.
@@ -299,7 +299,7 @@ def __new__(cls, *args, **kwargs):
         # To prevent race conditions of a single instance while also allowing
         # for settings to be passed the original arguments passed must be assigned
         # to allow for easier copies (which will be made when the help command is actually called)
-        # see issue 2123
+        # see issue :old-issue:`2123`
         self = super().__new__(cls)
 
         # Shallow copies cannot be used in this case since it is not unusual to pass
diff --git a/discord/file.py b/discord/file.py
index 442931c3..bc5a31ff 100644
--- a/discord/file.py
+++ b/discord/file.py
@@ -3,7 +3,7 @@
 """
 The MIT License (MIT)
 
-Copyright (c) 2015-present Rapptz
+Copyright (c) 2015-2021 Rapptz & (c) 2021-present mccoderpy
 
 Permission is hereby granted, free of charge, to any person obtaining a
 copy of this software and associated documentation files (the "Software"),
@@ -23,9 +23,21 @@
 FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 DEALINGS IN THE SOFTWARE.
 """
+from __future__ import annotations
 
 import os.path
+
 import io
+from typing import Union, Optional, TYPE_CHECKING
+
+if TYPE_CHECKING:
+    from os import PathLike
+
+__all__ = (
+    'File',
+    'UploadFile',
+)
+
 
 class File:
     r"""A parameter object used for :meth:`abc.Messageable.send`
@@ -56,16 +68,27 @@ class File:
         a string then the ``filename`` will default to the string given.
     spoiler: :class:`bool`
         Whether the attachment is a spoiler.
+    description: Optional[:class:`str`:]
+        The file description can be set to attached images to show a alternative text.
     """
 
-    __slots__ = ('fp', 'filename', 'spoiler', '_original_pos', '_owner', '_closer')
-
-    def __init__(self, fp, filename=None, *, spoiler=False):
+    __slots__ = ('fp', 'filename', 'description', 'spoiler', 'duration', 'waveform', '_original_pos', '_owner', '_closer')
+
+    def __init__(
+            self,
+            fp: Union[io.IOBase, str, bytes, PathLike[str], PathLike[bytes], int],
+            filename: Optional[str] = None,
+            description: Optional[str] = None,
+            *,
+            spoiler: bool = False,
+            duration: Optional[float] = None,
+            waveform: Optional[str] = None
+    ):
         self.fp = fp
 
         if isinstance(fp, io.IOBase):
             if not (fp.seekable() and fp.readable()):
-                raise ValueError('File buffer {!r} must be seekable and readable'.format(fp))
+                raise ValueError('{!r.__class__.__name__} buffer {!r} must be seekable and readable'.format(self, fp))
             self.fp = fp
             self._original_pos = fp.tell()
             self._owner = False
@@ -89,10 +112,14 @@ def __init__(self, fp, filename=None, *, spoiler=False):
         else:
             self.filename = filename
 
+        self.description = description or None
+
         if spoiler and self.filename is not None and not self.filename.startswith('SPOILER_'):
             self.filename = 'SPOILER_' + self.filename
 
         self.spoiler = spoiler or (self.filename is not None and self.filename.startswith('SPOILER_'))
+        self.duration: Optional[float] = duration
+        self.waveform: Optional[str] = waveform
 
     def reset(self, *, seek=True):
         # The `seek` parameter is needed because
@@ -110,3 +137,37 @@ def close(self):
         self.fp.close = self._closer
         if self._owner:
             self._closer()
+
+    def to_dict(self, file_index: int) -> dict:
+        base = {
+            'id': file_index,
+            'description': self.description,
+            'filename': self.filename
+        }
+        if self.duration is not None:
+            base['duration_secs'] = self.duration
+        if self.waveform is not None:
+            base['waveform'] = self.waveform
+        return base
+            
+
+
+class UploadFile(File):
+    """An object used for uploading files like stickers.
+
+    Parameters
+    ----------
+    fp: Union[:class:`io.IOBase`, :class:`PathLike[str]`, :class:`PathLike[bytes]`]
+        A file-like object opened in binary mode and read mode
+        or a filename representing a file in the hard drive to
+        open.
+
+        .. note::
+
+            If the file-like object passed is opened via ``open`` then the
+            modes 'rb' should be used.
+
+            To pass binary data, consider usage of ``io.BytesIO``.
+    """
+    def __init__(self, fp: Union[io.IOBase, str, bytes, 'PathLike[str]', 'PathLike[bytes]', int]):
+        super().__init__(fp)
diff --git a/discord/flags.py b/discord/flags.py
index 6940bc31..36f88f23 100644
--- a/discord/flags.py
+++ b/discord/flags.py
@@ -3,9 +3,7 @@
 """
 The MIT License (MIT)
 
-Copyright (c) 2015-present Rapptz
-
-Implementing of the Discord-Message-components made by mccoderpy (Discord-User mccuber04#2960)
+Copyright (c) 2015-2021 Rapptz & (c) 2021-present mccoderpy
 
 Permission is hereby granted, free of charge, to any person obtaining a
 copy of this software and associated documentation files (the "Software"),
@@ -25,36 +23,59 @@
 FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 DEALINGS IN THE SOFTWARE.
 """
+from __future__ import annotations
 
 from .enums import UserFlags
 
+from typing import (
+    Union,
+    Dict,
+    Tuple,
+    Iterator,
+    TYPE_CHECKING
+)
+
+if TYPE_CHECKING:
+    from typing import Self
+
 __all__ = (
     'SystemChannelFlags',
+    'ChannelFlags',
     'MessageFlags',
     'PublicUserFlags',
+    'GuildMemberFlags',
     'Intents',
     'MemberCacheFlags',
+    'ApplicationFlags',
+    'SKUFlags',
 )
 
+
 class flag_value:
     def __init__(self, func):
-        self.flag = func(None)
-        self.__doc__ = func.__doc__
+        self.name: str = func.__name__
+        self.flag: int = func(None)
+        self.__doc__: str = func.__doc__
 
-    def __get__(self, instance, owner):
+    def __get__(self, instance: BaseFlags, owner) -> Union[Self, bool]:
         if instance is None:
             return self
         return instance._has_flag(self.flag)
 
-    def __set__(self, instance, value):
+    def __set__(self, instance: BaseFlags, value: bool) -> None:
         instance._set_flag(self.flag, value)
 
-    def __repr__(self):
+    def __repr__(self) -> str:
         return '<flag_value flag={.flag!r}>'.format(self)
 
+    def __str__(self) -> str:
+        return self.name
+
+
 class alias_flag_value(flag_value):
     pass
 
+
 def fill_with_flags(*, inverted=False):
     def decorator(cls):
         cls.VALID_FLAGS = {
@@ -72,8 +93,11 @@ def decorator(cls):
         return cls
     return decorator
 
+
 # n.b. flags must inherit from this and use the decorator above
 class BaseFlags:
+    DEFAULT_VALUE: int
+    VALID_FLAGS: Dict[str, int]
     __slots__ = ('value',)
 
     def __init__(self, **kwargs):
@@ -84,35 +108,35 @@ def __init__(self, **kwargs):
             setattr(self, key, value)
 
     @classmethod
-    def _from_value(cls, value):
+    def _from_value(cls, value) -> Self:
         self = cls.__new__(cls)
         self.value = value
         return self
 
-    def __eq__(self, other):
+    def __eq__(self, other) -> bool:
         return isinstance(other, self.__class__) and self.value == other.value
 
-    def __ne__(self, other):
+    def __ne__(self, other) -> bool:
         return not self.__eq__(other)
 
-    def __hash__(self):
+    def __hash__(self) -> int:
         return hash(self.value)
 
-    def __repr__(self):
+    def __repr__(self) -> str:
         return '<%s value=%s>' % (self.__class__.__name__, self.value)
 
-    def __iter__(self):
+    def __iter__(self) -> Iterator[Tuple[str, bool]]:
         for name, value in self.__class__.__dict__.items():
             if isinstance(value, alias_flag_value):
                 continue
 
             if isinstance(value, flag_value):
-                yield (name, self._has_flag(value.flag))
+                yield name, self._has_flag(value.flag)
 
-    def _has_flag(self, o):
+    def _has_flag(self, o) -> bool:
         return (self.value & o) == o
 
-    def _set_flag(self, o, toggle):
+    def _set_flag(self, o: int, toggle: bool) -> None:
         if toggle is True:
             self.value |= o
         elif toggle is False:
@@ -120,6 +144,7 @@ def _set_flag(self, o, toggle):
         else:
             raise TypeError('Value to set for %s must be a bool.' % self.__class__.__name__)
 
+
 @fill_with_flags(inverted=True)
 class SystemChannelFlags(BaseFlags):
     r"""Wraps up a Discord system channel flag value.
@@ -161,10 +186,10 @@ class SystemChannelFlags(BaseFlags):
     # Since this is counter-intuitive from an API perspective and annoying
     # these will be inverted automatically
 
-    def _has_flag(self, o):
+    def _has_flag(self, o: int) -> bool:
         return (self.value & o) != o
 
-    def _set_flag(self, o, toggle):
+    def _set_flag(self, o: int, toggle: bool) -> None:
         if toggle is True:
             self.value &= ~o
         elif toggle is False:
@@ -182,6 +207,118 @@ def premium_subscriptions(self):
         """:class:`bool`: Returns ``True`` if the system channel is used for Nitro boosting notifications."""
         return 2
 
+    @flag_value
+    def guild_reminder_notifications(self):
+        """:class:`bool`: Returns ``True`` if the system channel is used for server setup tips."""
+        return 4
+
+    @flag_value
+    def join_notification_replies(self):
+        """:class:`bool`: Returns ``True`` if sticker reply buttons should show under member join messages."""
+        return 8
+
+    @flag_value
+    def role_subscription_purchase_notifications(self):
+        """:class:`bool`: Returns ``True`` if the system channel is used for role subscription purchase and
+        renewal notifications."""
+        return 16
+
+    @flag_value
+    def role_subscription_purchase_notification_replies(self):
+        """:class:`bool`: Returns ``True`` if sticker reply buttons should show under role subscription purchase and
+        renewal messages."""
+        return 32
+
+
+@fill_with_flags()
+class ChannelFlags(BaseFlags):
+    r"""Wraps up a Discord Channel flag value"""
+    __slots__ = ()
+
+    @flag_value
+    def removed_from_guild_feed(self):
+        """:class:`bool`: Returns ``True`` if the channel is removed from the guild's home feed/from highlights."""
+        return 1 << 0
+
+    @alias_flag_value
+    def removed_from_home(self):
+        """:class:`bool`: An alias to :attr:`removed_from_guild_feed`."""
+        return 1 << 0
+
+    @flag_value
+    def pinned(self):
+        """:class:`bool`: Returns ``True`` if the channel is a :class:`ForumPost` pinned at the top of the parent forum."""
+        return 1 << 1
+
+    @flag_value
+    def removed_from_active_now(self):
+        """:class:`bool`: Returns ``True`` if the channel is removed from the active now section in the guild's feed."""
+        return 1 << 2
+
+    @flag_value
+    def require_tags(self):
+        """
+        :class:`bool`:
+        Returns ``True`` if this channel is a :class:`ForumChannel` that requires at least one tag when creating a post.
+        """
+        return 1 << 4
+
+    @flag_value
+    def is_spam(self):
+        """:class:`bool`: Returns ``True`` if the channel is marked as spam."""
+        return 1 << 5
+
+    @flag_value
+    def is_resource_channel(self):
+        """:class:`bool`: Returns ``True`` if the channel is a resource channel."""
+        return 1 << 7
+
+    @flag_value
+    def clyde_ai(self):
+        """:class:`bool`: Returns ``True`` if clyde has access to this thread.
+
+            .. experiment:: Clyde, Discord's AI Chatbot
+                :article: 13066317497239-Clyde-Discord-s-AI-Chatbot
+        """
+        return 1 << 8
+
+    # TODO: add IS_SCHEDULED_FOR_DELETION (1 << 9) flag when we get more info on it
+
+    @flag_value
+    def is_media_channel(self):
+        """:class:`bool`: Returns ``True`` if the channel is a media channel."""
+        return 1 << 10
+
+    @flag_value
+    def summaries_disabled(self):
+        """:class:`bool`: Returns ``True`` if AI summaries are disabled for this channel.
+
+            .. experiment:: AI powered summaries
+                :article: 12926016807575-Summaries-AI
+        """
+        return 1 << 11
+
+    # TODO: add APPLICATION_SHELF_CONSENT (1 << 12) flag when we get more info on it
+
+    @flag_value
+    def is_role_subscription_template_preview_channel(self):
+        """:class:`bool`: Returns ``True`` if the channel is part of a role subscription template preview.
+
+            .. experiment:: Role Subscription Template
+        """
+        return 1 << 13
+
+    # TODO: add IS_BROADCASTING (1 << 14) flag when we get more info on it
+
+    @flag_value
+    def hide_media_download_options(self):
+        """:class:`bool`: Returns ``True`` embedding media download options is disabled.
+
+        .. note::
+            Available only for media channels.
+    """
+        return 1 << 15
+
 
 @fill_with_flags()
 class MessageFlags(BaseFlags):
@@ -246,7 +383,7 @@ def urgent(self):
 
     @flag_value
     def has_thread(self):
-        """:class:`bool`: Returns ``True`` if the source message is associated with an thread.
+        """:class:`bool`: Returns ``True`` if the source message is associated with a thread.
 
         This message has an associated thread, with the same id as the message.
         """
@@ -262,12 +399,42 @@ def ephemeral(self):
 
     @flag_value
     def loading(self):
-        """:class:`bool`: Returns ``True`` if the message is an Interaction Response and the bot is "thinking".
+        """:class:`bool`: Returns ``True`` if the message is an interaction response and the bot is "thinking".
 
-        This message is an Interaction Response and the bot is "thinking"
+        This message is an interaction response and the bot is "thinking"
         """
         return 128
 
+    @flag_value
+    def failed_to_mention_some_roles_in_thread(self):
+        """:class:`bool`: Returns ``True`` if the message failed to mention some roles and add their members to the thread."""
+        return 256
+    
+    @flag_value
+    def show_link_not_discord_warning(self):
+        """:class:`bool`: Returns ``True`` if the message should show a warning that the link may not be safe.
+        
+        .. note::
+            Although this gets set by Discord for some embeds, and we receive a :func:`~discord.on_message_edit` event, it is not officially documented by Discord.
+            It's in the client but not used anywhere.
+        """
+        
+        return 1024
+    
+    @flag_value
+    def suppress_notifications(self):
+        """:class:`bool`: Returns ``True`` if the message is "silent".
+        
+        The user(s) will still see a mention in the channel, but no push or desktop notification will be sent.
+        """
+        return 4096
+    
+    @flag_value
+    def is_voice_message(self):
+        """:class:`bool`: Returns ``True`` if the message is a voice message."""
+        return 8192
+
+
 @fill_with_flags()
 class PublicUserFlags(BaseFlags):
     r"""Wraps up the Discord User Public flags.
@@ -374,11 +541,95 @@ def early_verified_bot_developer(self):
         """
         return UserFlags.verified_bot_developer.value
 
+    @flag_value
+    def certified_moderator(self):
+        """:class:`bool`: Returns ``True`` if the user is an Discord Certified Moderator."""
+        return UserFlags.certified_moderator.value
+
+    @flag_value
+    def bot_http_interactions(self):
+        """:class:`bool`: Returns ``True`` if a bot-user uses only HTTP interactions and is shown in the online member list"""
+        return UserFlags.bot_http_interactions.value
+
+    @flag_value
+    def spammer(self):
+        """:class:`bool`: Returns ``True`` if the user is flagged as a spammer by discord."""
+        return UserFlags.spammer.value
+
+    @flag_value
+    def active_developer(self):
+        """:class:`bool`: Returns ``True`` if the user is a developer of an active discord application."""
+        return UserFlags.active_developer.value
+
     def all(self):
         """List[:class:`UserFlags`]: Returns all public flags the user has."""
         return [public_flag for public_flag in UserFlags if self._has_flag(public_flag.value)]
 
 
+@fill_with_flags()
+class GuildMemberFlags(BaseFlags):
+    r"""Wraps up the Discord Guild Member flags.
+
+    .. container:: operations
+
+        .. describe:: x == y
+
+            Checks if two GuildMemberFlags are equal.
+        .. describe:: x != y
+
+            Checks if two GuildMemberFlags are not equal.
+        .. describe:: hash(x)
+
+            Return the flag's hash.
+        .. describe:: iter(x)
+
+            Returns an iterator of ``(name, value)`` pairs. This allows it
+            to be, for example, constructed as a dict or a list of pairs.
+            Note that aliases are not shown.
+
+    Attributes
+    -----------
+    value: :class:`int`
+        The raw value. This value is a bit array field of a 53-bit integer
+        representing the currently available flags. You should query
+        flags via the properties rather than using this raw value.
+    """
+    
+    __slots__ = ()
+    
+    @flag_value
+    def rejoined(self):
+        """:class:`bool`: Returns :obj:`True` if the member has left and rejoined the guild"""
+        return 1 << 0
+    
+    @flag_value
+    def completed_onboarding(self):
+        """:class:`bool`: Returns :obj:`True` if the member has completed onboarding"""
+        return 1 << 1
+    
+    @flag_value
+    def bypasses_verification(self):
+        """:class:`bool`: Returns :obj:`True` if the member is exempt from guild verification requirements
+        
+        .. note::
+            This flag is editable and allows a member who does not meet verification requirements to participate in a
+            server.
+
+            This requires either:
+
+             - :attr:`~discord.Permissions.manage_guild` OR
+             - :attr:`~discord.Permissions.manage_roles` OR
+             - :attr:`~discord.Permissions.moderate_members` AND :attr:`~discord.Permissions.kick_members` AND
+                :attr:`~discord.Permissions.ban_members` permissions.
+        """
+        return 1 << 2
+    
+    @flag_value
+    def started_onboarding(self):
+        """:class:`bool`: Returns :obj:`True` if the member has started onboarding"""
+        return 1 << 3
+
+
 @fill_with_flags()
 class Intents(BaseFlags):
     r"""Wraps up a Discord gateway intent flag.
@@ -429,29 +680,30 @@ def __init__(self, **kwargs):
             setattr(self, key, value)
 
     @classmethod
-    def all(cls):
+    def all(cls) -> Intents:
         """A factory method that creates a :class:`Intents` with everything enabled."""
         bits = max(cls.VALID_FLAGS.values()).bit_length()
-        value = (1 << bits) - 1
+        value = ((1 << bits) - 1) & ~(1 << 17 | 1 << 18 | 1 << 19)
         self = cls.__new__(cls)
         self.value = value
         return self
 
     @classmethod
-    def none(cls):
+    def none(cls) -> Intents:
         """A factory method that creates a :class:`Intents` with everything disabled."""
         self = cls.__new__(cls)
         self.value = self.DEFAULT_VALUE
         return self
 
     @classmethod
-    def default(cls):
+    def default(cls) -> Intents:
         """A factory method that creates a :class:`Intents` with everything enabled
-        except :attr:`presences` and :attr:`members`.
+        except :attr:`presences`, :attr:`members` and :attr:`message_content` (privileged intents).
         """
         self = cls.all()
         self.presences = False
         self.members = False
+        self.message_content = False
         return self
 
     @flag_value
@@ -808,6 +1060,80 @@ def dm_typing(self):
         """
         return 1 << 14
 
+    @flag_value
+    def message_content(self):
+        """:class:`bool`: Whether to receive the content, embeds, attachments and components of a message.
+
+        .. note::
+
+            The bot will still receive these fields when the message is in a privat chat with the bot,
+            or the bot is mentioned in the message.
+
+        This corresponds to the following events:
+
+        - :func:`on_message` (content, embeds, attachments, components)
+        - :func:`on_message_edit` (content, embeds, attachments, components)
+        - :func:`on_raw_message_edit` (cached_message)
+        - :func:`on_message_delete` (content, embeds, attachments, components)
+        - :func:`on_raw_message_delete` (cached_message)
+        - :func:`on_bulk_message_delete` (content, embeds, attachments, components)
+        - :func:`on_raw_bulk_message_delete` (cached_messages)
+        - :func:`on_auto_moderation_action` (content, matched_content)
+
+        This also corresponds to the following attributes and classes:
+
+        - :attr:`Message.content`
+        - :attr:`Message.embeds`
+        - :attr:`Message.attachments`
+        - :attr:`Message.components`
+
+        For more information go to the `message-content intent documentation <https://support-dev.discord.com/hc/en-us/articles/4404772028055>`_ .
+
+        .. note::
+
+            Currently, this requires opting in explicitly via the developer portal as well.
+            Bots in over 100 guilds will need to apply to Discord for verification.
+        """
+        return  1 << 15
+
+    @flag_value
+    def scheduled_events(self):
+        """:class:`bool`: Whether to receive events related to creating, updating and deleting scheduled events.
+        Also, whether to receive events when a user is added or removed (interested).
+
+        This corresponds to the following events:
+
+        - :func:`on_scheduled_event_create`
+        - :func:`on_scheduled_event_update`
+        - :func:`on_scheduled_event_delete`
+        - :func:`on_scheduled_event_user_add`
+        - :func:`on_scheduled_event_user_remove`
+        """
+        return 1 << 16
+
+    @flag_value
+    def auto_moderation_configurations(self):
+        """:class:`bool`: Whether to receive events related to creating, updating and deleting auto moderation rules.
+
+        This corresponds to the following events:
+
+        - :func:`on_auto_moderation_rule_create`
+        - :func:`on_auto_moderation_rule_update`
+        - :func:`on_auto_moderation_rule_delete`
+        """
+        return 1 << 20
+
+    @flag_value
+    def auto_moderation_actions(self):
+        """:class:`bool`: Whether to receive events when auto moderation actions are taken.
+
+        This corresponds to the following event:
+
+        - :func:`on_auto_moderation_action`
+        """
+        return 1 << 21
+
+
 @fill_with_flags()
 class MemberCacheFlags(BaseFlags):
     """Controls the library's cache policy when it comes to members.
@@ -862,7 +1188,7 @@ def __init__(self, **kwargs):
             setattr(self, key, value)
 
     @classmethod
-    def all(cls):
+    def all(cls) -> MemberCacheFlags:
         """A factory method that creates a :class:`MemberCacheFlags` with everything enabled."""
         bits = max(cls.VALID_FLAGS.values()).bit_length()
         value = (1 << bits) - 1
@@ -871,7 +1197,7 @@ def all(cls):
         return self
 
     @classmethod
-    def none(cls):
+    def none(cls) -> MemberCacheFlags:
         """A factory method that creates a :class:`MemberCacheFlags` with everything disabled."""
         self = cls.__new__(cls)
         self.value = self.DEFAULT_VALUE
@@ -964,3 +1290,225 @@ def _voice_only(self):
     @property
     def _online_only(self):
         return self.value == 1
+
+
+@fill_with_flags()
+class ApplicationFlags(BaseFlags):
+    r"""Wraps up the flags of an application.
+
+        .. container:: operations
+
+            .. describe:: x == y
+
+                Checks if two ApplicationFlags are equal.
+            .. describe:: x != y
+
+                Checks if two ApplicationFlags are not equal.
+            .. describe:: hash(x)
+
+                Return the flag's hash.
+            .. describe:: iter(x)
+
+                Returns an iterator of ``(name, value)`` pairs. This allows it
+                to be, for example, constructed as a dict or a list of pairs.
+                Note that aliases are not shown.
+
+
+        Attributes
+        -----------
+        value: :class:`int`
+            The raw value. This value is a bit array field of a 53-bit integer
+            representing the currently available flags. You should query
+            flags via the properties rather than using this raw value.
+    """
+    @flag_value
+    def managed_emoji(self):
+        """:class:`bool`: Returns ``True`` if the application is a managed emoji.
+        
+        .. versionadded:: 2.0
+        """
+        return 1 << 2
+
+    @flag_value
+    def group_dm_create(self):
+        """:class:`bool`: Returns ``True`` if the application can create group DMs.
+        
+        .. versionadded:: 2.0
+        """
+        return 1 << 5
+
+    @flag_value
+    def application_auto_moderation_rule_create_badge(self):
+        """:class:`bool`: Returns ``True`` if the application uses the Auto Moderation API.
+
+        .. versionadded:: 2.0
+        """
+        return 1 << 6
+
+    @flag_value
+    def rpc_has_connected(self):
+        """:class:`bool`: Returns ``True`` if the application has connected to RPC.
+        
+        .. versionadded:: 2.0
+        """
+        return 1 << 11
+    
+    @flag_value
+    def gateway_presence(self):
+        """:class:`bool`: Returns ``True`` if the application is approved for the privileged gateway presence-intent."""
+        return 1 << 12
+
+    @flag_value
+    def gateway_presence_limited(self):
+        """:class:`bool`: Returns ``True`` if the privileged gateway presence-intent
+        is enabled in the application in the developer-portal.
+        """
+        return 1 << 13
+
+    @flag_value
+    def gateway_guild_members(self):
+        """:class:`bool`: Returns ``True`` if the application is approved
+        for the privileged gateway guild-members-intent.
+        """
+        return 1 << 14
+
+    @flag_value
+    def gateway_guild_members_limited(self):
+        """:class:`bool`: Returns ``True`` if the privileged gateway guild-members-intent
+        is enabled in the application in the developer-portal.
+        """
+        return 1 << 15
+
+    @flag_value
+    def verification_pending_guild_limit(self):
+        """:class:`bool: Returns ``True`` if this application has reached the required number of guilds
+        to apply for verification. (76+ Guilds)
+        """
+        return 1 << 16
+
+    @flag_value
+    def embedded(self):
+        """:class:`bool`: Returns ``True`` if this application could have embedded invites.(usually  voice-activity's)
+        """
+        return 1 << 17
+
+    @flag_value
+    def gateway_message_content(self):
+        """:class:`bool`: Returns ``True`` if the application is approved
+        for the privileged gateway message-content-intent.
+        """
+        return 1 << 18
+
+    @flag_value
+    def gateway_message_content_limited(self):
+        """:class:`bool`: Returns ``True`` if the privileged gateway message-content-intent
+        is enabled in the application in the developer-portal.
+        """
+        return 1 << 19
+
+    @flag_value
+    def application_commands_badge(self):
+        """:class:`bool`: Returns ``True`` if the app has at least one global `application-command <application_commands>`_ registered."""
+        return 1 << 23
+
+    @flag_value
+    def active_application(self):
+        """:class:`bool`: Returns ``True`` is an active application (e.g. has at leas one app command executed in the last 30 days)."""
+        return 1 << 24
+
+
+@fill_with_flags()
+class SKUFlags(BaseFlags):
+    """Wraps up the flags of a :class:`SKU`.
+
+    .. container:: operations
+
+        .. describe:: x == y
+
+            Checks if two SKUFlags are equal.
+        .. describe:: x != y
+
+            Checks if two SKUFlags are not equal.
+        .. describe:: hash(x)
+
+            Return the flag's hash.
+        .. describe:: iter(x)
+
+            Returns an iterator of ``(name, value)`` pairs. This allows it
+            to be, for example, constructed as a dict or a list of pairs.
+            Note that aliases are not shown.
+
+    Attributes
+    -----------
+    value: :class:`int`
+        The raw value. This value is a bit array field of a 53-bit integer
+        representing the currently available flags. You should query
+        flags via the properties rather than using this raw value.
+    """
+
+    @flag_value
+    def premium_purchase(self):
+        """:class:`bool`: A premium purchase SKU"""
+        return 1 << 0
+
+    @flag_value
+    def has_free_premium_content(self):
+        """:class:`bool`: An SKU containing free premium content"""
+        return 1 << 1
+
+    @flag_value
+    def available(self):
+        """:class:`bool`: Whether the SKU is currently available for purchase"""
+        return 1 << 2
+
+    # @flag_value
+    # def premium_and_distribution(self):
+    #     """:class:`bool`: Undocumented"""
+    #     return 1 << 3
+
+    # @flag_value
+    # def sticker(self):
+    #     """":class:`bool`: Undocumented"""
+    #     return 1 << 4
+
+    @flag_value
+    def guild_role(self):
+        """:class:`bool`: A role that can be purchased for a guild"""
+        return 1 << 5
+
+    @flag_value
+    def available_for_subscription_gifting(self):
+        """:class:`bool`: An SKU that can be purchased as a gift for others."""
+        return 1 << 6
+
+    @flag_value
+    def app_guild_subscription(self):
+        """:class:`bool`: A recurring SKU that can be purchased by a user and applied to a single server.
+        Grants access to every user in that server."""
+        return 1 << 7
+
+    @flag_value
+    def app_user_subscription(self):
+        """:class:`bool`: Recurring SKU purchased by a user for themselves.
+        Grants access to the purchasing user in every server."""
+        return 1 << 8
+
+    # @flag_value
+    # def creator_monetization(self):
+    #     """:class:`bool`: Undocumented"""
+    #     return 1 << 9
+
+    @flag_value
+    def guild_product(self):
+        """:class:`bool`: A product in the guild store"""
+        return 1 << 10
+
+    # @flag_value
+    # def user_update_mask(self):
+    #     """:class:`bool`: Undocumented"""
+    #     return 0 << 0
+    #
+    # @flag_value
+    # def staff_create_subscription_group_listing_mask(self):
+    #     """:class:`bool`: Undocumented"""
+    #     return 384
diff --git a/discord/gateway.py b/discord/gateway.py
index 210a8822..9fc18479 100644
--- a/discord/gateway.py
+++ b/discord/gateway.py
@@ -3,7 +3,7 @@
 """
 The MIT License (MIT)
 
-Copyright (c) 2015-present Rapptz
+Copyright (c) 2015-2021 Rapptz & (c) 2021-present mccoderpy
 
 Permission is hereby granted, free of charge, to any person obtaining a
 copy of this software and associated documentation files (the "Software"),
@@ -23,9 +23,13 @@
 FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 DEALINGS IN THE SOFTWARE.
 """
+from typing import (
+    Union
+)
 
 import asyncio
 from collections import namedtuple, deque
+from color_pprint import color_dumps
 import concurrent.futures
 import json
 import logging
@@ -43,6 +47,8 @@
 from .enums import SpeakingState
 from .errors import ConnectionClosed, InvalidArgument
 
+from .types.gateway import GatewayPayload, VoiceGatewayPayload
+
 log = logging.getLogger(__name__)
 
 __all__ = (
@@ -53,6 +59,13 @@
     'ReconnectWebSocket',
 )
 
+# if you want to show your bot as online on mobile, change this to
+# BROWSER = 'discord'
+# DEVICE = 'android'
+BROWSER = 'discord4py'
+DEVICE = 'discord4py'
+
+
 class ReconnectWebSocket(Exception):
     """Signals to safely reconnect the websocket."""
     def __init__(self, shard_id, *, resume=True):
@@ -60,12 +73,15 @@ def __init__(self, shard_id, *, resume=True):
         self.resume = resume
         self.op = 'RESUME' if resume else 'IDENTIFY'
 
+
 class WebSocketClosure(Exception):
     """An exception to make up for the fact that aiohttp doesn't signal closure."""
     pass
 
+
 EventListener = namedtuple('EventListener', 'predicate event result future')
 
+
 class GatewayRatelimiter:
     def __init__(self, count=110, per=60.0):
         # The default is 110 to give room for at least 10 heartbeats per minute
@@ -190,6 +206,7 @@ def ack(self):
         if self.latency > 10:
             log.warning(self.behind_msg, self.shard_id, self.latency)
 
+
 class VoiceKeepAliveHandler(KeepAliveHandler):
     def __init__(self, *args, **kwargs):
         super().__init__(*args, **kwargs)
@@ -211,12 +228,14 @@ def ack(self):
         self.latency = ack_time - self._last_send
         self.recent_ack_latencies.append(self.latency)
 
+
 class DiscordClientWebSocketResponse(aiohttp.ClientWebSocketResponse):
     async def close(self, *, code: int = 4000, message: bytes = b'') -> bool:
         return await super().close(code=code, message=message)
 
+
 class DiscordWebSocket:
-    """Implements a WebSocket for Discord's gateway v6.
+    """Implements a WebSocket for Discord's gateway v10.
 
     Attributes
     -----------
@@ -226,7 +245,7 @@ class DiscordWebSocket:
         When received tells Discord to keep the connection alive.
         When sent asks if your connection is currently alive.
     IDENTIFY
-        Send only. Starts a new session.
+        Send only. Starts a new _session.
     PRESENCE
         Send only. Updates your presence.
     VOICE_STATE
@@ -240,7 +259,7 @@ class DiscordWebSocket:
     REQUEST_MEMBERS
         Send only. Asks for the full member list of a guild.
     INVALIDATE_SESSION
-        Receive only. Tells the client to optionally invalidate the session
+        Receive only. Tells the client to optionally invalidate the _session
         and IDENTIFY again.
     HELLO
         Receive only. Tells the client the heartbeat interval.
@@ -284,6 +303,7 @@ def __init__(self, socket, *, loop):
         # ws related stuff
         self.session_id = None
         self.sequence = None
+        self.resume_gateway_url = None
         self._zlib = zlib.decompressobj()
         self._buffer = bytearray()
         self._close_code = None
@@ -297,13 +317,18 @@ def is_ratelimited(self):
         return self._rate_limiter.is_ratelimited()
 
     @classmethod
-    async def from_client(cls, client, *, initial=False, gateway=None, shard_id=None, session=None, sequence=None, resume=False):
+    async def from_client(cls, client, *, initial=False, gateway=None, resume_gateway_url=None, shard_id=None, session=None, sequence=None, resume=False):
         """Creates a main websocket for Discord from a :class:`Client`.
 
         This is for internal use only.
         """
-        gateway = gateway or await client.http.get_gateway()
+        version = client.gateway_version
+        if resume is True and resume_gateway_url is not None:
+            gateway = resume_gateway_url
+        else:
+            gateway = gateway or await client.http.get_gateway(v=version)
         socket = await client.http.ws_connect(gateway)
+
         ws = cls(socket, loop=client.loop)
 
         # dynamically add attributes needed
@@ -312,6 +337,7 @@ async def from_client(cls, client, *, initial=False, gateway=None, shard_id=None
         ws._discord_parsers = client._connection.parsers
         ws._dispatch = client.dispatch
         ws.gateway = gateway
+        ws.resume_gateway_url = resume_gateway_url
         ws.call_hooks = client._connection.call_hooks
         ws._initial_identify = initial
         ws.shard_id = shard_id
@@ -367,11 +393,11 @@ async def identify(self):
             'd': {
                 'token': self.token,
                 'properties': {
-                    '$os': sys.platform,
-                    '$browser': 'discord.py',
-                    '$device': 'discord.py',
-                    '$referrer': '',
-                    '$referring_domain': ''
+                    'os': sys.platform,
+                    'browser': BROWSER,
+                    'device': DEVICE,
+                    'referrer': '',
+                    'referring_domain': ''
                 },
                 'compress': True,
                 'large_threshold': 250,
@@ -380,9 +406,6 @@ async def identify(self):
             }
         }
 
-        if not self._connection.is_bot:
-            payload['d']['synced_guilds'] = []
-
         if self.shard_id is not None and self.shard_count is not None:
             payload['d']['shard'] = [self.shard_id, self.shard_count]
 
@@ -416,7 +439,7 @@ async def resume(self):
         await self.send_as_json(payload)
         log.info('Shard ID %s has sent the RESUME payload.', self.shard_id)
 
-    async def received_message(self, msg):
+    async def received_message(self, msg: Union[bytes, str]):
         self._dispatch('socket_raw_receive', msg)
 
         if type(msg) is bytes:
@@ -427,7 +450,7 @@ async def received_message(self, msg):
             msg = self._zlib.decompress(self._buffer)
             msg = msg.decode('utf-8')
             self._buffer = bytearray()
-        msg = json.loads(msg)
+        msg: GatewayPayload = json.loads(msg)
 
         log.debug('For Shard ID %s: WebSocket Event: %s', self.shard_id, msg)
         self._dispatch('socket_response', msg)
@@ -444,7 +467,7 @@ async def received_message(self, msg):
         if op != self.DISPATCH:
             if op == self.RECONNECT:
                 # "reconnect" can only be handled by the Client
-                # so we terminate our connection and raise an
+                # , so we terminate our connection and raise an
                 # internal exception signalling to reconnect.
                 log.debug('Received RECONNECT opcode.')
                 await self.close()
@@ -476,7 +499,8 @@ async def received_message(self, msg):
 
                 self.sequence = None
                 self.session_id = None
-                log.info('Shard ID %s session has been invalidated.', self.shard_id)
+                self.resume_gateway_url = None
+                log.info('Shard ID %s _session has been invalidated.', self.shard_id)
                 await self.close(code=1000)
                 raise ReconnectWebSocket(self.shard_id, resume=False)
 
@@ -489,22 +513,50 @@ async def received_message(self, msg):
             self._trace = trace = data.get('_trace', [])
             self.sequence = msg['s']
             self.session_id = data['session_id']
+            self.resume_gateway_url = f'{data["resume_gateway_url"]}?{self.gateway.split("?")[-1]}'  # Weird way doing this but should prevent any future issues with that
             # pass back shard ID to ready handler
             data['__shard_id__'] = self.shard_id
-            log.info('Shard ID %s has connected to Gateway: %s (Session ID: %s).',
-                     self.shard_id, ', '.join(trace), self.session_id)
+            
+            handler = logging.getLogger('discord').handlers[-1]
+            handler_level = handler.level
+            is_debug_logging = handler_level == logging.DEBUG
+            
+            log.info(
+                f'Shard ID %s has connected to Gateway (Session ID: %s){" - Set loglevel to DEBUG to show trace" if not is_debug_logging else ""}',
+                self.shard_id,
+                self.session_id
+            )
+            if is_debug_logging:
+                if hasattr(handler, 'stream') and utils.stream_supports_colour(handler.stream):
+                    log.debug('Trace: %s', ', '.join([color_dumps(tp, indent=None) for tp in map(json.loads, trace)]))
+                else:
+                    log.debug('Trace: %s', ', '.join(trace))
 
         elif event == 'RESUMED':
             self._trace = trace = data.get('_trace', [])
             # pass back the shard ID to the resumed handler
             data['__shard_id__'] = self.shard_id
-            log.info('Shard ID %s has successfully RESUMED session %s under trace %s.',
-                     self.shard_id, self.session_id, ', '.join(trace))
+            
+            handler = logging.getLogger('discord').handlers[-1]
+            handler_level = handler.level
+            is_debug_logging = handler_level == logging.DEBUG
+
+            log.info(
+                f'Shard ID %s has resumed session %s{" - Set loglevel to DEBUG to show trace" if not is_debug_logging else ""}',
+                self.shard_id,
+                self.session_id
+            )
+            if is_debug_logging:
+                if hasattr(handler, 'stream') and utils.stream_supports_colour(handler.stream):
+                    log.debug('Trace: %s', ', '.join([color_dumps(tp, indent=None) for tp in map(json.loads, trace)]))
+                else:
+                    log.debug('Trace: %s', ', '.join(trace))
 
         try:
             func = self._discord_parsers[event]
         except KeyError:
             log.debug('Unknown event %s.', event)
+            log.info(f'Unknown event %s! Please report this to the library developers!', event)
         else:
             func(data)
 
@@ -586,7 +638,7 @@ async def send(self, data):
         self._dispatch('socket_raw_send', data)
         await self.socket.send_str(data)
 
-    async def send_as_json(self, data):
+    async def send_as_json(self, data: GatewayPayload):
         try:
             await self.send(utils.to_json(data))
         except RuntimeError as exc:
@@ -650,7 +702,6 @@ async def request_chunks(self, guild_id, query=None, *, limit, user_ids=None, pr
         if query is not None:
             payload['d']['query'] = query
 
-
         await self.send_as_json(payload)
 
     async def voice_state(self, guild_id, channel_id, self_mute=False, self_deaf=False):
@@ -675,13 +726,14 @@ async def close(self, code=4000):
         self._close_code = code
         await self.socket.close(code=code)
 
+
 class DiscordVoiceWebSocket:
     """Implements the websocket protocol for handling voice connections.
 
     Attributes
     -----------
     IDENTIFY
-        Send only. Starts a new voice session.
+        Send only. Starts a new voice _session.
     SELECT_PROTOCOL
         Send only. Tells discord what encryption mode and how to connect for voice.
     READY
@@ -695,7 +747,7 @@ class DiscordVoiceWebSocket:
     HEARTBEAT_ACK
         Receive only. Tells you your heartbeat has been acknowledged.
     RESUME
-        Sent only. Tells the client to resume its session.
+        Sent only. Tells the client to resume its _session.
     HELLO
         Receive only. Tells you that your websocket connection was acknowledged.
     RESUMED
@@ -719,12 +771,18 @@ class DiscordVoiceWebSocket:
     CLIENT_CONNECT      = 12
     CLIENT_DISCONNECT   = 13
 
-    def __init__(self, socket, loop):
+    def __init__(self, socket, loop, *, hook=None):
         self.ws = socket
         self.loop = loop
         self._keep_alive = None
         self._close_code = None
         self.secret_key = None
+        self.ssrc_map = {}
+        if hook:
+            self._hook = hook
+
+    async def _hook(self, *args):
+        pass
 
     async def send_as_json(self, data):
         log.debug('Sending voice websocket frame: %s.', data)
@@ -812,7 +870,7 @@ async def speak(self, state=SpeakingState.voice):
 
         await self.send_as_json(payload)
 
-    async def received_message(self, msg):
+    async def received_message(self, msg: VoiceGatewayPayload):
         log.debug('Voice websocket frame received: %s', msg)
         op = msg['op']
         data = msg.get('d')
@@ -830,6 +888,16 @@ async def received_message(self, msg):
             interval = data['heartbeat_interval'] / 1000.0
             self._keep_alive = VoiceKeepAliveHandler(ws=self, interval=min(interval, 5.0))
             self._keep_alive.start()
+        elif op == self.SPEAKING:
+            ssrc = data['ssrc']
+            user = int(data['user_id'])
+            speaking = data['speaking']
+            if ssrc in self.ssrc_map:
+                self.ssrc_map[ssrc]['speaking'] = speaking
+            else:
+                self.ssrc_map.update({ssrc: {'user_id': user, 'speaking': speaking}})
+
+        await self._hook(self, msg)
 
     async def initial_connection(self, data):
         state = self._connection
@@ -837,16 +905,16 @@ async def initial_connection(self, data):
         state.voice_port = data['port']
         state.endpoint_ip = data['ip']
 
-        packet = bytearray(70)
-        struct.pack_into('>H', packet, 0, 1) # 1 = Send
-        struct.pack_into('>H', packet, 2, 70) # 70 = Length
+        packet = bytearray(74)
+        struct.pack_into('>H', packet, 0, 1)  # 1 = Send
+        struct.pack_into('>H', packet, 2, 70)  # 70 = Length
         struct.pack_into('>I', packet, 4, state.ssrc)
         state.socket.sendto(packet, (state.endpoint_ip, state.voice_port))
-        recv = await self.loop.sock_recv(state.socket, 70)
+        recv = await self.loop.sock_recv(state.socket, 74)
         log.debug('received packet in initial_connection: %s', recv)
 
-        # the ip is ascii starting at the 4th byte and ending at the first null
-        ip_start = 4
+        # the ip is ascii starting at the 8th byte and ending at the first null
+        ip_start = 8
         ip_end = recv.index(0, ip_start)
         state.ip = recv[ip_start:ip_end].decode('ascii')
 
diff --git a/discord/guild.py b/discord/guild.py
index 51b11f35..23271a79 100644
--- a/discord/guild.py
+++ b/discord/guild.py
@@ -3,7 +3,7 @@
 """
 The MIT License (MIT)
 
-Copyright (c) 2015-present Rapptz
+Copyright (c) 2015-2021 Rapptz & (c) 2021-present mccoderpy
 
 Permission is hereby granted, free of charge, to any person obtaining a
 copy of this software and associated documentation files (the "Software"),
@@ -23,32 +23,233 @@
 FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 DEALINGS IN THE SOFTWARE.
 """
+from __future__ import annotations
 
 import copy
-from collections import namedtuple
+from datetime import datetime
+from typing import (
+    Union,
+    Optional,
+    overload,
+    List,
+    Tuple,
+    Dict,
+    Any,
+    Awaitable,
+    Iterable,
+    Iterator,
+    NamedTuple,
+    TYPE_CHECKING
+)
+from typing_extensions import Literal
+
+if TYPE_CHECKING:
+    from os import PathLike
+    from .types import guild as g
+    from .state import ConnectionState
+    from .abc import Snowflake, GuildChannel
+    from .ext.commands import Cog
+    from .automod import AutoModRule
+    from .voice_client import VoiceProtocol
+    from .template import Template
+    from .webhook import Webhook
+    from .application_commands import ApplicationCommand, SlashCommandOption, SubCommandGroup, SubCommand
 
 from . import utils
+from .file import UploadFile
 from .role import Role
 from .member import Member, VoiceState
 from .emoji import Emoji
 from .errors import InvalidData
-from .permissions import PermissionOverwrite
+from .permissions import PermissionOverwrite, Permissions
 from .colour import Colour
 from .errors import InvalidArgument, ClientException
 from .channel import *
-from .enums import VoiceRegion, ChannelType, try_enum, VerificationLevel, ContentFilter, NotificationLevel
+from .enums import (
+    VoiceRegion,
+    ChannelType,
+    Locale,
+    VerificationLevel,
+    ContentFilter,
+    NotificationLevel,
+    EventEntityType,
+    AuditLogAction,
+    AutoModTriggerType,
+    AutoModEventType,
+    AutoArchiveDuration,
+    IntegrationType,
+    OnboardingMode,
+    try_enum
+)
 from .mixins import Hashable
+from .scheduled_event import GuildScheduledEvent
 from .user import User
 from .invite import Invite
-from .iterators import AuditLogIterator, MemberIterator
+from .iterators import AuditLogIterator, MemberIterator, BanIterator, BanEntry
+from .onboarding import *
+from .welcome_screen import *
 from .widget import Widget
 from .asset import Asset
 from .flags import SystemChannelFlags
-from .integrations import BotIntegration, StreamIntegration, _integration_factory
+from .integrations import _integration_factory, Integration
+from .sticker import GuildSticker
+from .automod import AutoModRule, AutoModTriggerMetadata, AutoModAction
+from .application_commands import SlashCommand, MessageCommand, UserCommand, Localizations
 
+MISSING = utils.MISSING
 
-BanEntry = namedtuple('BanEntry', 'reason user')
-_GuildLimit = namedtuple('_GuildLimit', 'emoji bitrate filesize')
+__all__ = (
+    'GuildFeatures',
+    'Guild',
+)
+
+
+class _GuildLimit(NamedTuple):
+    emoji: int
+    sticker: int
+    bitrate: float
+    filesize: int
+
+
+async def default_callback(interaction, *args, **kwargs):
+    await interaction.respond(
+        'This command has no callback set.'
+        'Probably something is being tested with him and he is not yet fully developed.',
+        hidden=True
+    )
+
+
+class GuildFeatures(Iterable[str], dict):
+    """
+    Represents a guild's features.
+    
+    This class mainly exists to make it easier to edit a guild's features.
+    
+    .. versionadded:: 2.0
+    
+    .. container:: operations
+    
+        .. describe:: 'FEATURE_NAME' in features
+        
+            Checks if the guild has the feature.
+        
+        .. describe:: features.FEATURE_NAME
+        
+            Checks if the guild has the feature. Returns ``False`` if it doesn't.
+        
+        .. describe:: features.FEATURE_NAME = True
+        
+            Enables the feature in the features object, but does not enable it in the guild itself except if you pass it to :meth:`Guild.edit`.
+        
+        .. describe:: features.FEATURE_NAME = False
+        
+            Disables the feature in the features object, but does not disable it in the guild itself except if you pass it to :meth:`Guild.edit`.
+        
+        .. describe:: del features.FEATURE_NAME
+        
+            The same as ``features.FEATURE_NAME = False``
+        
+        .. describe:: features.parsed()
+        
+            Returns a list of all features that are/should be enabled.
+        
+        .. describe:: features.merge(other)
+        
+            Returns a new object with the features of both objects merged.
+            If a feature is missing in the other object, it will be ignored.
+        
+        .. describe:: features == other
+        
+            Checks if two feature objects are equal.
+        
+        .. describe:: features != other
+        
+            Checks if two feature objects are not equal.
+        
+        .. describe:: iter(features)
+        
+            Returns an iterator over the enabled features.
+    """
+    def __init__(self, /, initial: List[str] = [], **features: bool):
+        """
+        Parameters
+        -----------
+        initial: :class:`list`
+            The initial features to set.
+        **features: :class:`bool`
+            The features to set. If the value is ``True`` then the feature is/will be enabled.
+            If the value is ``False`` then the feature will be disabled.
+        """
+        for feature in initial:
+            features[feature] = True
+        self.__dict__.update(features)
+    
+    def __iter__(self) -> Iterator[str]:
+        return [feature for feature, value in self.__dict__.items() if value is True].__iter__()
+    
+    def __contains__(self, item: str) -> bool:
+        return item in self.__dict__ and self.__dict__[item] is True
+    
+    def __getattr__(self, item: str) -> bool:
+        return self.__dict__.get(item, False)
+    
+    def __setattr__(self, key: str, value: bool) -> None:
+        self.__dict__[key] = value
+    
+    def __delattr__(self, item: str) -> None:
+        self.__dict__[item] = False
+        
+    def __repr__(self) -> str:
+        return f'<GuildFeatures {self.__dict__!r}>'
+    
+    def __str__(self) -> str:
+        return str(self.__dict__)
+    
+    def keys(self) -> Iterator[str]:
+        return self.__dict__.keys().__iter__()
+    
+    def values(self) -> Iterator[bool]:
+        return self.__dict__.values().__iter__()
+    
+    def items(self) -> Iterator[Tuple[str, bool]]:
+        return self.__dict__.items().__iter__()
+    
+    def merge(self, other: GuildFeatures) -> GuildFeatures:
+        base = copy.copy(self.__dict__)
+        
+        for key, value in other.items():
+            base[key] = value
+            
+        return GuildFeatures(**base)
+    
+    def parsed(self) -> List[str]:
+        return [name for name, value in self.__dict__.items() if value is True]
+    
+    def __eq__(self, other: GuildFeatures) -> bool:
+        current = self.__dict__
+        other = other.__dict__
+        
+        all_keys = set(current.keys()) | set(other.keys())
+        
+        for key in all_keys:
+            try:
+                current_value = current[key]
+            except KeyError:
+                if other[key] is True:
+                    return False
+            else:
+                try:
+                    other_value = other[key]
+                except KeyError:
+                    pass
+                else:
+                    if current_value != other_value:
+                        return False
+        
+        return True
+    
+    def __ne__(self, other: GuildFeatures) -> bool:
+        return not self.__eq__(other)
 
 
 class Guild(Hashable):
@@ -80,9 +281,6 @@ class Guild(Hashable):
         The guild name.
     emojis: Tuple[:class:`Emoji`, ...]
         All emojis that the guild owns.
-    region: :class:`VoiceRegion`
-        The region the guild belongs on. There is a chance that the region
-        will be a :class:`str` if the value is not recognised by the enumerator.
     afk_timeout: :class:`int`
         The timeout to get sent to the AFK channel.
     afk_channel: Optional[:class:`VoiceChannel`]
@@ -95,7 +293,7 @@ class Guild(Hashable):
         The guild owner's ID. Use :attr:`Guild.owner` instead.
     unavailable: :class:`bool`
         Indicates if the guild is unavailable. If this is ``True`` then the
-        reliability of other attributes outside of :attr:`Guild.id` is slim and they might
+        reliability of other attributes outside of :attr:`Guild.id` is slim, and they might
         all be ``None``. It is best to not do anything with the guild if it is unavailable.
 
         Check the :func:`on_guild_unavailable` and :func:`on_guild_available` events.
@@ -116,7 +314,7 @@ class Guild(Hashable):
     description: Optional[:class:`str`]
         The guild's description.
     mfa_level: :class:`int`
-        Indicates the guild's two factor authorisation level. If this value is 0 then
+        Indicates the guild's two-factor authorisation level. If this value is 0 then
         the guild does not require 2FA for their administrative members. If the value is
         1 then they do.
     verification_level: :class:`VerificationLevel`
@@ -134,10 +332,10 @@ class Guild(Hashable):
         - ``VERIFIED``: Guild is a verified server.
         - ``PARTNERED``: Guild is a partnered server.
         - ``MORE_EMOJI``: Guild is allowed to have more than 50 custom emoji.
+        - ``MORE_STICKER``: Guild is allowed to have more than 60 custom sticker.
         - ``DISCOVERABLE``: Guild shows up in Server Discovery.
         - ``FEATURABLE``: Guild is able to be featured in Server Discovery.
         - ``COMMUNITY``: Guild is a community server.
-        - ``COMMERCE``: Guild can sell things using store channels.
         - ``PUBLIC``: Guild is a public guild.
         - ``NEWS``: Guild can create news channels.
         - ``BANNER``: Guild can upload and use a banner (i.e. :meth:`banner_url`).
@@ -154,54 +352,134 @@ class Guild(Hashable):
         The number goes from 0 to 3 inclusive.
     premium_subscription_count: :class:`int`
         The number of "boosts" this guild currently has.
-    preferred_locale: Optional[:class:`str`]
+    preferred_locale: Optional[:class:`Locale`]
         The preferred locale for the guild. Used when filtering Server Discovery
         results to a specific language.
     discovery_splash: :class:`str`
         The guild's discovery splash.
-
         .. versionadded:: 1.3
+    premium_progress_bar_enabled: :class:`bool`
+        Whether the guild has the boost progress bar enabled.
+    invites_disabled_until: Optional[:class:`~datetime.datetime`]
+        When this is set to a time in the future, then invites to the guild are disabled until that time.
+        .. versionadded:: 2.0
+    dms_disabled_until: Optional[:class:`~datetime.datetime`]
+        When this is set to a time in the future, then direct messages to members of the guild are disabled
+        (unless users are friends to each other) until that time.
+        .. versionadded:: 2.0
     """
 
-    __slots__ = ('afk_timeout', 'afk_channel', '_members', '_channels', 'icon',
-                 'name', 'id', 'unavailable', 'banner', 'region', '_state',
-                 '_roles', '_member_count', '_large',
+    __slots__ = ('afk_timeout', 'afk_channel', '_members', '_channels', '_stage_instances',
+                 'icon', 'name', 'id', 'unavailable', 'banner', 'region', '_state',
+                 '_application_commands', '_roles', '_events', '_member_count', '_large',
                  'owner_id', 'mfa_level', 'emojis', 'features',
                  'verification_level', 'explicit_content_filter', 'splash',
                  '_voice_states', '_system_channel_id', 'default_notifications',
                  'description', 'max_presences', 'max_members', 'max_video_channel_users',
                  'premium_tier', 'premium_subscription_count', '_system_channel_flags',
                  'preferred_locale', 'discovery_splash', '_rules_channel_id',
-                 '_public_updates_channel_id')
+                 '_public_updates_channel_id', '_safety_alerts_channel_id',
+                 'premium_progress_bar_enabled', '_welcome_screen',
+                 'stickers', '_automod_rules', 'invites_disabled_until', 'dms_disabled_until',)
 
     _PREMIUM_GUILD_LIMITS = {
-        None: _GuildLimit(emoji=50, bitrate=96e3, filesize=8388608),
-        0: _GuildLimit(emoji=50, bitrate=96e3, filesize=8388608),
-        1: _GuildLimit(emoji=100, bitrate=128e3, filesize=8388608),
-        2: _GuildLimit(emoji=150, bitrate=256e3, filesize=52428800),
-        3: _GuildLimit(emoji=250, bitrate=384e3, filesize=104857600),
+        None: _GuildLimit(emoji=50, sticker=5, bitrate=96e3, filesize=8388608),
+        0: _GuildLimit(emoji=50, sticker=5, bitrate=96e3, filesize=8388608),
+        1: _GuildLimit(emoji=100, sticker=15, bitrate=128e3, filesize=8388608),
+        2: _GuildLimit(emoji=150, sticker=30, bitrate=256e3, filesize=52428800),
+        3: _GuildLimit(emoji=250, sticker=60, bitrate=384e3, filesize=104857600),
     }
 
-    def __init__(self, *, data, state):
-        self._channels = {}
-        self._members = {}
-        self._voice_states = {}
-        self._state = state
+    if TYPE_CHECKING:
+        name: str
+        verification_level: VerificationLevel
+        default_notifications: NotificationLevel
+        explicit_content_filter: ContentFilter
+        afk_timeout: int
+        region: VoiceRegion
+        mfa_level: int
+        emojis: Tuple[Emoji, ...]
+        features: List[str]
+        splash: Optional[str]
+        banner: Optional[str]
+        icon: Optional[str]
+        id: int
+        owner_id: int
+        description: Optional[str]
+        max_presences: Optional[int]
+        max_members: Optional[int]
+        max_video_channel_users: Optional[int]
+        premium_tier: int
+        premium_subscription_count: int
+        preferred_locale: Locale
+        discovery_splash: Optional[str]
+        premium_progress_bar_enabled: bool
+        invites_disabled_until: Optional[datetime]
+        dms_disabled_until: Optional[datetime]
+        unavailable: bool
+        _roles: Dict[int, Role]
+        _system_channel_id: Optional[int]
+        _system_channel_flags: int
+        _rules_channel_id: Optional[int]
+        _public_updates_channel_id: Optional[int]
+        _safety_alerts_channel_id: Optional[int]
+        _welcome_screen: Optional[WelcomeScreen]
+        _member_count: Optional[int]
+        _large: Optional[bool]
+
+    def __init__(self, *, data, state: ConnectionState):
+        self._channels: Dict[int, Union[GuildChannel, ThreadChannel]] = {}
+        self._stage_instances: Dict[int, StageInstance] = {}
+        self._members: Dict[int, Member] = {}
+        self._events: Dict[int, GuildScheduledEvent] = {}
+        self._automod_rules: Dict[int, AutoModRule] = {}
+        self._voice_states: Dict[int, VoiceState] = {}
+        self._state: ConnectionState = state
+        self._application_commands: Dict[int, ApplicationCommand] = {}
         self._from_data(data)
 
-    def _add_channel(self, channel):
+    def _add_channel(self, channel: Union[GuildChannel, ThreadChannel]):
         self._channels[channel.id] = channel
+        if isinstance(channel, ThreadChannel):
+            parent = channel.parent_channel
+            addr = getattr(parent, '_add_thread', getattr(parent, '_add_post', None))
+            if addr is not None:
+                addr(channel)
 
-    def _remove_channel(self, channel):
+    def _remove_channel(self, channel: Union[GuildChannel, ThreadChannel]):
         self._channels.pop(channel.id, None)
+        if isinstance(channel, ThreadChannel):
+            remvr = getattr(
+                channel.parent_channel, '_remove_thread', getattr(channel.parent_channel, '_remove_post', None)
+            )
+            if remvr is not None:
+                remvr(channel)
+
+    def _add_event(self, event: GuildScheduledEvent):
+        self._events[event.id] = event
+
+    def _remove_event(self, event: GuildScheduledEvent):
+        self._events.pop(event.id, None)
+
+    def _add_stage_instance(self, instance: StageInstance):
+        self._stage_instances[instance.channel.id] = instance
+
+    def _remove_stage_instance(self, instance: StageInstance):
+        self._stage_instances.pop(instance.channel.id, None)
 
-    def _voice_state_for(self, user_id):
+    def _add_automod_rule(self, rule: AutoModRule):
+        self._automod_rules[rule.id] = rule
+
+    def _remove_automod_rule(self, rule: AutoModRule):
+        self._automod_rules.pop(rule.id, None)
+
+    def _voice_state_for(self, user_id: int):
         return self._voice_states.get(user_id)
 
-    def _add_member(self, member):
+    def _add_member(self, member: Member):
         self._members[member.id] = member
 
-    def _remove_member(self, member):
+    def _remove_member(self, member: Member):
         self._members.pop(member.id, None)
 
     def __str__(self):
@@ -242,7 +520,7 @@ def _update_voice_state(self, data, channel_id):
 
         return member, before, after
 
-    def _add_role(self, role):
+    def _add_role(self, role: Role):
         # roles get added to the bottom (position 1, pos 0 is @everyone)
         # so since self.roles has the @everyone role, we can't increment
         # its position because it's stuck at position 0. Luckily x += False
@@ -253,7 +531,7 @@ def _add_role(self, role):
 
         self._roles[role.id] = role
 
-    def _remove_role(self, role_id):
+    def _remove_role(self, role_id: int) -> Role:
         # this raises KeyError if it fails..
         role = self._roles.pop(role_id)
 
@@ -265,7 +543,7 @@ def _remove_role(self, role_id):
 
         return role
 
-    def _from_data(self, guild):
+    def _from_data(self, guild: g.Guild) -> None:
         # according to Stan, this is always available even if the guild is unavailable
         # I don't have this guarantee when someone updates the guild.
         member_count = guild.get('member_count', None)
@@ -273,7 +551,7 @@ def _from_data(self, guild):
             self._member_count = member_count
 
         self.name = guild.get('name')
-        self.region = try_enum(VoiceRegion, guild.get('region'))
+        self.region = try_enum(VoiceRegion, guild.get('region'))  # TODO: remove in 2.0 release
         self.verification_level = try_enum(VerificationLevel, guild.get('verification_level'))
         self.default_notifications = try_enum(NotificationLevel, guild.get('default_message_notifications'))
         self.explicit_content_filter = try_enum(ContentFilter, guild.get('explicit_content_filter', 0))
@@ -282,15 +560,16 @@ def _from_data(self, guild):
         self.banner = guild.get('banner')
         self.unavailable = guild.get('unavailable', False)
         self.id = int(guild['id'])
-        self._roles = {}
-        state = self._state # speed up attribute access
+        self._roles: Dict[int, Role] = {}
+        state = self._state  # speed up attribute access
         for r in guild.get('roles', []):
             role = Role(guild=self, data=r, state=state)
             self._roles[role.id] = role
-
+        for e in guild.get('guild_scheduled_events', []):
+            state.store_event(guild=self, data=e)
         self.mfa_level = guild.get('mfa_level')
         self.emojis = tuple(map(lambda d: state.store_emoji(self, d), guild.get('emojis', [])))
-        self.features = guild.get('features', [])
+        self.features = guild.get('features', [])  # TODO: make this a private attribute and add a features property that returns GuildFeatures
         self.splash = guild.get('splash')
         self._system_channel_id = utils._get_as_snowflake(guild, 'system_channel_id')
         self.description = guild.get('description')
@@ -300,11 +579,13 @@ def _from_data(self, guild):
         self.premium_tier = guild.get('premium_tier', 0)
         self.premium_subscription_count = guild.get('premium_subscription_count') or 0
         self._system_channel_flags = guild.get('system_channel_flags', 0)
-        self.preferred_locale = guild.get('preferred_locale')
+        self.preferred_locale = try_enum(Locale, guild.get('preferred_locale'))
         self.discovery_splash = guild.get('discovery_splash')
         self._rules_channel_id = utils._get_as_snowflake(guild, 'rules_channel_id')
         self._public_updates_channel_id = utils._get_as_snowflake(guild, 'public_updates_channel_id')
-
+        self._safety_alerts_channel_id = utils._get_as_snowflake(guild, 'safety_alerts_channel_id')
+        self.premium_progress_bar_enabled: bool = guild.get('premium_progress_bar_enabled', False)
+        self._handle_incidents_data(guild.get('incidents_data'))
         cache_online_members = self._state.member_cache_flags.online
         cache_joined = self._state.member_cache_flags.joined
         self_id = self._state.self_id
@@ -318,7 +599,12 @@ def _from_data(self, guild):
 
         self.owner_id = utils._get_as_snowflake(guild, 'owner_id')
         self.afk_channel = self.get_channel(utils._get_as_snowflake(guild, 'afk_channel_id'))
-
+        welcome_screen = guild.get('welcome_screen', None)
+        if welcome_screen:
+            self._welcome_screen = WelcomeScreen(guild=self, state=self._state, data=welcome_screen)
+        else:
+            self._welcome_screen = None
+        self.stickers: Tuple[GuildSticker] = tuple(map(lambda d: state.store_sticker(d), guild.get('stickers', [])))  # type: ignore
         for obj in guild.get('voice_states', []):
             self._update_voice_state(obj, int(obj['channel_id']))
 
@@ -328,27 +614,120 @@ def _sync(self, data):
         except KeyError:
             pass
 
-        empty_tuple = tuple()
         for presence in data.get('presences', []):
             user_id = int(presence['user']['id'])
             member = self.get_member(user_id)
             if member is not None:
-                member._presence_update(presence, empty_tuple)
+                member._presence_update(presence)
 
+        _state = self._state
         if 'channels' in data:
             channels = data['channels']
             for c in channels:
                 factory, ch_type = _channel_factory(c['type'])
                 if factory:
-                    self._add_channel(factory(guild=self, data=c, state=self._state))
+                    self._add_channel(factory(guild=self, data=c, state=_state))
+
+        if 'threads' in data:
+            threads = data['threads']
+            for t in threads:
+                factory, ch_type = _channel_factory(t['type'])
+                if factory:
+                    parent_channel = self.get_channel(int(t['parent_id']))
+                    if parent_channel is None:
+                        continue  # we don't know why this happens sometimes, we skipp this for now
+                    thread = factory(guild=self, data=t, state=_state)
+                    self._add_channel(thread)
+                    if isinstance(parent_channel, ForumChannel):
+                        parent_channel._add_post(thread)
+                    else:
+                        self._add_channel(thread)
+                        parent_channel._add_thread(thread)
+
+        if 'stage_instances' in data:
+            for i in data['stage_instances']:
+                stage = self.get_channel(int(i['channel_id']))
+                if stage is not None:
+                    self._add_stage_instance(StageInstance(state=_state, channel=stage, data=i))
+
+    def _handle_incidents_data(self, incidents_data: Optional[g.IncidentsData]):
+        if incidents_data:
+            if invites_disabled_until := incidents_data.get('invites_disabled_until'):
+                self.invites_disabled_until = datetime.fromisoformat(invites_disabled_until)
+            else:
+                self.invites_disabled_until = None
+            if dms_disabled_until := incidents_data.get('dms_disabled_until'):
+                self.dms_disabled_until = datetime.fromisoformat(dms_disabled_until)
+            else:
+                self.dms_disabled_until = None
+        else:
+            self.invites_disabled_until = None
+            self.dms_disabled_until = None
+
+    @property
+    def application_commands(self) -> List[ApplicationCommand]:
+        """List[:class:`~discord.ApplicationCommand`]: A list of application-commands from this application that are registered only in this guild.
+        """
+        return list(self._application_commands.values())
+
+    def get_application_command(self, id: int) -> Optional[ApplicationCommand]:
+        """Optional[:class:`~discord.ApplicationCommand`]: Returns an application-command from this application that are registered only in this guild with the given id"""
+        return self._application_commands.get(id, None)
 
     @property
-    def channels(self):
-        """List[:class:`abc.GuildChannel`]: A list of channels that belongs to this guild."""
+    def channels(self) -> List[Union[GuildChannel, ThreadChannel, ForumPost]]:
+        """List[:class:`abc.GuildChannel`, :class:`ThreadChannel`, :class:`ForumPost`]: A list of channels that belongs to this guild."""
         return list(self._channels.values())
 
+    def stage_instances(self) -> List[StageInstance]:
+        """List[:class:`~discord.StageInstance`]: A list of stage instances that belongs to this guild."""
+        return list(self._stage_instances.values())
+
+    @property
+    def server_guide_channels(self) -> List[GuildChannel]:
+        """List[:class:`abc.GuildChannel`]: A list of channels that are part of the servers guide."""
+        return [c for c in self._channels.values() if c.flags.is_resource_channel]
+
+    @property
+    def events(self) -> List[GuildScheduledEvent]:
+        """List[:class:`~discord.GuildScheduledEvent`]: A list of scheduled events that belong to this guild."""
+        return list(self._events.values())
+
+    scheduled_events = events
+
+    @property
+    def cached_automod_rules(self) -> List[AutoModRule]:
+        """
+        List[:class:`AutoModRules`]: A list of auto moderation rules that are cached.
+
+        .. admonition:: Reliable Fetching
+            :class: helpful
+            
+            This property is only reliable if :meth:`~Guild.automod_rules` was used before.
+            To ensure that the rules are up-to-date, use :meth:`~Guild.automod_rules` instead.
+        """
+        return list(self._automod_rules.values())
+
+    def get_event(self, id: int) -> Optional[GuildScheduledEvent]:
+        """
+        Returns a scheduled event with the given ID.
+
+        Parameters
+        ----------
+        id: :class:`int`
+            The ID of the event to get.
+
+        Returns
+        -------
+        Optional[:class:`~discord.GuildScheduledEvent`]
+            The scheduled event or ``None`` if not found.
+        """
+        return self._events.get(id)
+
+    get_scheduled_event = get_event
+
     @property
-    def large(self):
+    def large(self) -> bool:
         """:class:`bool`: Indicates if the guild is a 'large' guild.
 
         A large guild is defined as having more than ``large_threshold`` count
@@ -362,7 +741,7 @@ def large(self):
         return self._large
 
     @property
-    def voice_channels(self):
+    def voice_channels(self) -> List[VoiceChannel]:
         """List[:class:`VoiceChannel`]: A list of voice channels that belongs to this guild.
 
         This is sorted by the position and are in UI order from top to bottom.
@@ -372,7 +751,7 @@ def voice_channels(self):
         return r
 
     @property
-    def stage_channels(self):
+    def stage_channels(self) -> List[StageChannel]:
         """List[:class:`StageChannel`]: A list of voice channels that belongs to this guild.
 
         .. versionadded:: 1.7
@@ -384,7 +763,7 @@ def stage_channels(self):
         return r
 
     @property
-    def me(self):
+    def me(self) -> Member:
         """:class:`Member`: Similar to :attr:`Client.user` except an instance of :class:`Member`.
         This is essentially used to get the member version of yourself.
         """
@@ -392,12 +771,12 @@ def me(self):
         return self.get_member(self_id)
 
     @property
-    def voice_client(self):
+    def voice_client(self) -> Optional[VoiceProtocol]:
         """Optional[:class:`VoiceProtocol`]: Returns the :class:`VoiceProtocol` associated with this guild, if any."""
         return self._state._get_voice_client(self.id)
 
     @property
-    def text_channels(self):
+    def text_channels(self) -> List[TextChannel]:
         """List[:class:`TextChannel`]: A list of text channels that belongs to this guild.
 
         This is sorted by the position and are in UI order from top to bottom.
@@ -407,7 +786,53 @@ def text_channels(self):
         return r
 
     @property
-    def categories(self):
+    def thread_channels(self) -> List[ThreadChannel]:
+        """List[:class:`ThreadChannel`]: A list of **cached** thread channels the guild has.
+
+        This is sorted by the position of the threads :attr:`~discord.ThreadChannel.parent`
+        and are in UI order from top to bottom.
+        """
+        r = list()
+        [r.extend(ch.threads) for ch in self._channels.values() if isinstance(ch, TextChannel)]
+        r.sort(key=lambda t: (t.parent_channel.position, t.id))
+        return r
+    
+    @property
+    def forum_channels(self) -> List[ForumChannel]:
+        """List[:class:`ForumChannel`]: A list of forum channels the guild has.
+
+        This is sorted by the position of the forums :attr:`~discord.ForumChannel.parent`
+        and are in UI order from top to bottom.
+        """
+        r = [ch for ch in self._channels.values() if isinstance(ch, ForumChannel)]
+        r.sort(key=lambda f: (f.parent_channel.position, f.id))
+        return r
+    
+    @property
+    def forum_posts(self) -> List[ForumPost]:
+        """List[:class:`ForumPost`]: A list of **cached** forum posts the guild has.
+
+        This is sorted by the position of the forums :attr:`~discord.ForumPost.parent`
+        and are in UI order from top to bottom.
+        """
+        r = [ch for ch in self._channels.values() if isinstance(ch, ForumPost)]
+        r.sort(key=lambda f: (f.parent_channel.position, f.id))
+        return r
+
+    @property
+    def guide_channels(self) -> GuildChannel:
+        """List[:class:`GuildChannel`]: A list of channels that are part of the server guide.
+
+            There is an alias for this called :attr:`~Guild.resource_channels`.
+        """
+        r: List[GuildChannel] = [ch for ch in self._channels.values() if ch.flags.is_resource_channel]
+        r.sort(key=lambda c: (c.position, c.id))
+        return r
+
+    resource_channels = guide_channels
+
+    @property
+    def categories(self) -> List[CategoryChannel]:
         """List[:class:`CategoryChannel`]: A list of categories that belongs to this guild.
 
         This is sorted by the position and are in UI order from top to bottom.
@@ -416,7 +841,7 @@ def categories(self):
         r.sort(key=lambda c: (c.position, c.id))
         return r
 
-    def by_category(self):
+    def by_category(self) -> List[Tuple[Optional[CategoryChannel], List[GuildChannel]]]:
         """Returns every :class:`CategoryChannel` and their associated channels.
 
         These channels and categories are sorted in the official Discord UI order.
@@ -434,7 +859,8 @@ def by_category(self):
             if isinstance(channel, CategoryChannel):
                 grouped.setdefault(channel.id, [])
                 continue
-
+            if isinstance(channel, ThreadChannel):
+                continue
             try:
                 grouped[channel.category_id].append(channel)
             except KeyError:
@@ -451,7 +877,9 @@ def key(t):
             channels.sort(key=lambda c: (c._sorting_bucket, c.position, c.id))
         return as_list
 
-    def get_channel(self, channel_id):
+    def get_channel(self, channel_id: int) -> Optional[
+        Union[CategoryChannel, TextChannel, StageChannel, VoiceChannel, ThreadChannel, ForumPost]
+    ]:
         """Returns a channel with the given ID.
 
         Parameters
@@ -461,13 +889,13 @@ def get_channel(self, channel_id):
 
         Returns
         --------
-        Optional[:class:`.abc.GuildChannel`]
-            The returned channel or ``None`` if not found.
+        Optional[Union[:class:`.abc.GuildChannel`, :class:`ThreadChannel`, :class:`ForumPost`]]
+            The channel or ``None`` if not found.
         """
         return self._channels.get(channel_id)
 
     @property
-    def system_channel(self):
+    def system_channel(self) -> Optional[TextChannel]:
         """Optional[:class:`TextChannel`]: Returns the guild's channel used for system messages.
 
         If no channel is set, then this returns ``None``.
@@ -476,12 +904,13 @@ def system_channel(self):
         return channel_id and self._channels.get(channel_id)
 
     @property
-    def system_channel_flags(self):
+    def system_channel_flags(self) -> SystemChannelFlags:
         """:class:`SystemChannelFlags`: Returns the guild's system channel settings."""
         return SystemChannelFlags._from_value(self._system_channel_flags)
 
+
     @property
-    def rules_channel(self):
+    def rules_channel(self) -> Optional[TextChannel]:
         """Optional[:class:`TextChannel`]: Return's the guild's channel used for the rules.
         The guild must be a Community guild.
 
@@ -493,41 +922,59 @@ def rules_channel(self):
         return channel_id and self._channels.get(channel_id)
 
     @property
-    def public_updates_channel(self):
+    def public_updates_channel(self) -> Optional[TextChannel]:
         """Optional[:class:`TextChannel`]: Return's the guild's channel where admins and
         moderators of the guilds receive notices from Discord. The guild must be a
         Community guild.
 
         If no channel is set, then this returns ``None``.
 
-        .. versionadded:: 1.4
+        .. versionadded:: 2.0
         """
         channel_id = self._public_updates_channel_id
         return channel_id and self._channels.get(channel_id)
 
     @property
-    def emoji_limit(self):
+    def safety_alerts_channel(self) -> Optional[TextChannel]:
+        """Optional[:class:`TextChannel`]: Return's the guild's channel where Discord
+        sends safety alerts in. The guild must be a Community guild.
+
+        If no channel is set, then this returns ``None``.
+
+        .. versionadded:: 2.0
+        """
+        channel_id = self._safety_alerts_channel_id
+        return channel_id and self._channels.get(channel_id)
+
+    @property
+    def emoji_limit(self) -> int:
         """:class:`int`: The maximum number of emoji slots this guild has."""
         more_emoji = 200 if 'MORE_EMOJI' in self.features else 50
         return max(more_emoji, self._PREMIUM_GUILD_LIMITS[self.premium_tier].emoji)
 
     @property
-    def bitrate_limit(self):
+    def sticker_limit(self) -> int:
+        """:class:`int`: The maximum number of sticker slots this guild has."""
+        more_sticker = 60 if 'MORE_STICKER' in self.features else 5
+        return max(more_sticker, self._PREMIUM_GUILD_LIMITS[self.premium_tier].sticker)
+
+    @property
+    def bitrate_limit(self) -> float:
         """:class:`float`: The maximum bitrate for voice channels this guild can have."""
         vip_guild = self._PREMIUM_GUILD_LIMITS[1].bitrate if 'VIP_REGIONS' in self.features else 96e3
         return max(vip_guild, self._PREMIUM_GUILD_LIMITS[self.premium_tier].bitrate)
 
     @property
-    def filesize_limit(self):
+    def filesize_limit(self) -> int:
         """:class:`int`: The maximum number of bytes files can have when uploaded to this guild."""
         return self._PREMIUM_GUILD_LIMITS[self.premium_tier].filesize
 
     @property
-    def members(self):
+    def members(self) -> List[Member]:
         """List[:class:`Member`]: A list of members that belong to this guild."""
         return list(self._members.values())
 
-    def get_member(self, user_id):
+    def get_member(self, user_id: int) -> Optional[Member]:
         """Returns a member with the given ID.
 
         Parameters
@@ -543,12 +990,12 @@ def get_member(self, user_id):
         return self._members.get(user_id)
 
     @property
-    def premium_subscribers(self):
+    def premium_subscribers(self) -> List[Member]:
         """List[:class:`Member`]: A list of members who have "boosted" this guild."""
         return [member for member in self.members if member.premium_since is not None]
 
     @property
-    def roles(self):
+    def roles(self) -> List[Role]:
         """List[:class:`Role`]: Returns a :class:`list` of the guild's roles in hierarchy order.
 
         The first element of this list will be the lowest role in the
@@ -556,7 +1003,7 @@ def roles(self):
         """
         return sorted(self._roles.values())
 
-    def get_role(self, role_id):
+    def get_role(self, role_id) -> Optional[Role]:
         """Returns a role with the given ID.
 
         Parameters
@@ -572,12 +1019,12 @@ def get_role(self, role_id):
         return self._roles.get(role_id)
 
     @property
-    def default_role(self):
+    def default_role(self) -> Role:
         """:class:`Role`: Gets the @everyone role that all members have by default."""
         return self.get_role(self.id)
 
     @property
-    def premium_subscriber_role(self):
+    def premium_subscriber_role(self) -> Optional[Role]:
         """Optional[:class:`Role`]: Gets the premium subscriber role, AKA "boost" role, in this guild.
 
         .. versionadded:: 1.6
@@ -588,7 +1035,7 @@ def premium_subscriber_role(self):
         return None
 
     @property
-    def self_role(self):
+    def self_role(self) -> Optional[Role]:
         """Optional[:class:`Role`]: Gets the role associated with this client's user, if any.
 
         .. versionadded:: 1.6
@@ -601,20 +1048,26 @@ def self_role(self):
         return None
 
     @property
-    def owner(self):
+    def owner(self) -> Optional[Member]:
         """Optional[:class:`Member`]: The member that owns the guild."""
         return self.get_member(self.owner_id)
 
     @property
-    def icon_url(self):
+    def icon_url(self) -> Asset:
         """:class:`Asset`: Returns the guild's icon asset."""
         return self.icon_url_as()
 
-    def is_icon_animated(self):
+    def is_icon_animated(self) -> bool:
         """:class:`bool`: Returns True if the guild has an animated icon."""
         return bool(self.icon and self.icon.startswith('a_'))
 
-    def icon_url_as(self, *, format=None, static_format='webp', size=1024):
+    def icon_url_as(
+            self,
+            *,
+            format: Literal['webp', 'jpeg', 'jpg', 'png', 'gif'] = None,
+            static_format: Literal['webp', 'jpeg', 'jpg', 'png'] = 'webp',
+            size: int = 1024
+    ) -> Asset:
         """Returns an :class:`Asset` for the guild's icon.
 
         The format must be one of 'webp', 'jpeg', 'jpg', 'png' or 'gif', and
@@ -646,11 +1099,16 @@ def icon_url_as(self, *, format=None, static_format='webp', size=1024):
         return Asset._from_guild_icon(self._state, self, format=format, static_format=static_format, size=size)
 
     @property
-    def banner_url(self):
+    def banner_url(self) -> Asset:
         """:class:`Asset`: Returns the guild's banner asset."""
         return self.banner_url_as()
 
-    def banner_url_as(self, *, format='webp', size=2048):
+    def banner_url_as(
+            self,
+            *,
+            format: Literal['webp', 'jpeg', 'jpg', 'png'] = 'webp',
+            size: int = 2048
+    ) -> Asset:
         """Returns an :class:`Asset` for the guild's banner.
 
         The format must be one of 'webp', 'jpeg', or 'png'. The
@@ -676,11 +1134,16 @@ def banner_url_as(self, *, format='webp', size=2048):
         return Asset._from_guild_image(self._state, self.id, self.banner, 'banners', format=format, size=size)
 
     @property
-    def splash_url(self):
+    def splash_url(self) -> Asset:
         """:class:`Asset`: Returns the guild's invite splash asset."""
         return self.splash_url_as()
 
-    def splash_url_as(self, *, format='webp', size=2048):
+    def splash_url_as(
+            self,
+            *,
+            format: Literal['webp', 'jpeg', 'jpg', 'png'] = 'webp',
+            size: int = 2048
+    ) -> Asset:
         """Returns an :class:`Asset` for the guild's invite splash.
 
         The format must be one of 'webp', 'jpeg', 'jpg', or 'png'. The
@@ -706,14 +1169,19 @@ def splash_url_as(self, *, format='webp', size=2048):
         return Asset._from_guild_image(self._state, self.id, self.splash, 'splashes', format=format, size=size)
 
     @property
-    def discovery_splash_url(self):
+    def discovery_splash_url(self) -> Asset:
         """:class:`Asset`: Returns the guild's discovery splash asset.
 
         .. versionadded:: 1.3
         """
         return self.discovery_splash_url_as()
 
-    def discovery_splash_url_as(self, *, format='webp', size=2048):
+    def discovery_splash_url_as(
+            self,
+            *,
+            format: Literal['webp', 'jpeg', 'jpg', 'png'] = 'webp',
+            size: int = 2048
+    ) -> Asset:
         """Returns an :class:`Asset` for the guild's discovery splash.
 
         The format must be one of 'webp', 'jpeg', 'jpg', or 'png'. The
@@ -738,10 +1206,17 @@ def discovery_splash_url_as(self, *, format='webp', size=2048):
         :class:`Asset`
             The resulting CDN asset.
         """
-        return Asset._from_guild_image(self._state, self.id, self.discovery_splash, 'discovery-splashes', format=format, size=size)
+        return Asset._from_guild_image(
+            self._state,
+            self.id,
+            self.discovery_splash,
+            'discovery-splashes',
+            format=format,
+            size=size
+        )
 
     @property
-    def member_count(self):
+    def member_count(self) -> int:
         """:class:`int`: Returns the true member count regardless of it being loaded fully or not.
 
         .. warning::
@@ -753,7 +1228,7 @@ def member_count(self):
         return self._member_count
 
     @property
-    def chunked(self):
+    def chunked(self) -> bool:
         """:class:`bool`: Returns a boolean indicating if the guild is "chunked".
 
         A chunked guild means that :attr:`member_count` is equal to the
@@ -768,23 +1243,23 @@ def chunked(self):
         return count == len(self._members)
 
     @property
-    def shard_id(self):
-        """:class:`int`: Returns the shard ID for this guild if applicable."""
+    def shard_id(self) -> Optional[int]:
+        """Optional[:class:`int`]: Returns the shard ID for this guild if applicable."""
         count = self._state.shard_count
         if count is None:
             return None
         return (self.id >> 22) % count
 
     @property
-    def created_at(self):
+    def created_at(self) -> datetime:
         """:class:`datetime.datetime`: Returns the guild's creation time in UTC."""
         return utils.snowflake_time(self.id)
 
-    def get_member_named(self, name):
+    def get_member_named(self, name: str) -> Optional[Member]:
         """Returns the first member found that matches the name provided.
 
         The name can have an optional discriminator argument, e.g. "Jake#0001"
-        or "Jake" will both do the lookup. However the former will give a more
+        or "Jake" will both do the lookup. However, the former will give a more
         precise result. Note that the discriminator must have all 4 digits
         for this to work.
 
@@ -821,12 +1296,20 @@ def get_member_named(self, name):
             if result is not None:
                 return result
 
-        def pred(m):
-            return m.nick == name or m.name == name
+        def pred(m: Member):
+            return m.nick == name or m.global_name == name or m.name == name
 
         return utils.find(pred, members)
 
-    def _create_channel(self, name, overwrites, channel_type, category=None, **options):
+    def _create_channel(
+            self,
+            name: str,
+            overwrites: Dict[Union[Role, Member], PermissionOverwrite],
+            channel_type: ChannelType,
+            category: Optional[CategoryChannel] = None,
+            reason: Optional[str] = None,
+            **options: Any
+    ):
         if overwrites is None:
             overwrites = {}
         elif not isinstance(overwrites, dict):
@@ -834,6 +1317,8 @@ def _create_channel(self, name, overwrites, channel_type, category=None, **optio
 
         perms = []
         for target, perm in overwrites.items():
+            if not isinstance(target, (Role, Member)):
+                raise InvalidArgument('Expected Member or Role received {0.__name__}'.format(type(target)))
             if not isinstance(perm, PermissionOverwrite):
                 raise InvalidArgument('Expected PermissionOverwrite received {0.__name__}'.format(type(perm)))
 
@@ -863,11 +1348,40 @@ def _create_channel(self, name, overwrites, channel_type, category=None, **optio
         else:
             options['rtc_region'] = None if rtc_region is None else str(rtc_region)
 
+        if channel_type.text or channel_type.forum_channel:
+            try:
+                default_auto_archive_duration: AutoArchiveDuration = options.pop('default_auto_archive_duration')
+            except KeyError:
+                pass
+            else:
+                default_auto_archive_duration = try_enum(AutoArchiveDuration, default_auto_archive_duration)
+                if not isinstance(default_auto_archive_duration, AutoArchiveDuration):
+                    raise InvalidArgument(
+                        f'{default_auto_archive_duration} is not a valid default_auto_archive_duration'
+                    )
+                else:
+                    options['default_auto_archive_duration'] = default_auto_archive_duration.value
+
+            try:
+                options['default_thread_rate_limit_per_user']: int = options.pop('default_thread_slowmode_delay')
+            except KeyError:
+                pass
+
         parent_id = category.id if category else None
-        return self._state.http.create_channel(self.id, channel_type.value, name=name, parent_id=parent_id,
-                                               permission_overwrites=perms, **options)
+        return self._state.http.create_channel(
+            self.id, channel_type.value, name=name, parent_id=parent_id,
+            permission_overwrites=perms, reason=reason, **options
+        )
 
-    async def create_text_channel(self, name, *, overwrites=None, category=None, reason=None, **options):
+    async def create_text_channel(
+        self,
+        name: str,
+        *,
+        overwrites: Optional[Dict[Snowflake, PermissionOverwrite]] = None,
+        category: Optional[CategoryChannel] = None,
+        reason: Optional[str] = None,
+        **options
+    ) -> TextChannel:
         """|coro|
 
         Creates a :class:`TextChannel` for the guild.
@@ -926,6 +1440,9 @@ async def create_text_channel(self, name, *, overwrites=None, category=None, rea
         slowmode_delay: :class:`int`
             Specifies the slowmode rate limit for user in this channel, in seconds.
             The maximum value possible is `21600`.
+        default_thread_slowmode_delay: :class:`int`
+            The initial ``slowmode_delay`` to set on newly created threads in the channel.
+            This field is copied to the thread at creation time and does not live update.
         nsfw: :class:`bool`
             To mark the channel as NSFW or not.
         reason: Optional[:class:`str`]
@@ -952,7 +1469,15 @@ async def create_text_channel(self, name, *, overwrites=None, category=None, rea
         self._channels[channel.id] = channel
         return channel
 
-    async def create_voice_channel(self, name, *, overwrites=None, category=None, reason=None, **options):
+    async def create_voice_channel(
+        self,
+        name: str,
+        *,
+        overwrites: Optional[Dict[Snowflake, PermissionOverwrite]] = None,
+        category: Optional[CategoryChannel] = None,
+        reason: Optional[str] = None,
+        **options
+    ) -> VoiceChannel:
         """|coro|
 
         This is similar to :meth:`create_text_channel` except makes a :class:`VoiceChannel` instead, in addition
@@ -991,10 +1516,25 @@ async def create_voice_channel(self, name, *, overwrites=None, category=None, re
         self._channels[channel.id] = channel
         return channel
 
-    async def create_stage_channel(self, name, *, topic=None, category=None, overwrites=None, reason=None, position=None):
+    async def create_stage_channel(
+        self,
+        name: str,
+        *,
+        topic: Optional[str] = None,
+        category: Optional[CategoryChannel] = None,
+        overwrites: Optional[Dict[Snowflake, PermissionOverwrite]] = None,
+        reason: Optional[str] = None,
+        position: Optional[int] = None
+    ) -> StageChannel:
         """|coro|
 
-        This is similar to :meth:`create_text_channel` except makes a :class:`StageChannel` instead.
+        This is similar to :meth:`create_text_channel` except makes a :class:`StageChannel` instead, in addition
+        to having the following new parameters.
+
+        Parameters
+        ----------
+        topic: Optional[:class:`str`]
+            The topic of the Stage instance (1-120 characters)
 
         .. note::
 
@@ -1016,14 +1556,106 @@ async def create_stage_channel(self, name, *, topic=None, category=None, overwri
         :class:`StageChannel`
             The channel that was just created.
         """
-        data = await self._create_channel(name, overwrites, ChannelType.stage_voice, category, reason=reason, position=position, topic=topic)
+        data = await self._create_channel(
+            name, overwrites, ChannelType.stage_voice, category, reason=reason, position=position, topic=topic
+        )
         channel = StageChannel(state=self._state, guild=self, data=data)
 
         # temporarily add to the cache
         self._channels[channel.id] = channel
         return channel
 
-    async def create_category(self, name, *, overwrites=None, reason=None, position=None):
+    async def create_forum_channel(
+            self,
+            name: str,
+            *,
+            topic: Optional[str] = None,
+            slowmode_delay: Optional[int] = None,
+            default_post_slowmode_delay: Optional[int] = None,
+            default_auto_archive_duration: Optional[AutoArchiveDuration] = None,
+            overwrites: Optional[Dict[Snowflake, PermissionOverwrite]] = None,
+            nsfw: Optional[bool] = None,
+            category: Optional[CategoryChannel] = None,
+            position: Optional[int] = None,
+            reason: Optional[str] = None
+    ) -> ForumChannel:
+        """|coro|
+
+        Same as :meth:`create_text_channel` excepts that it creates a forum channel instead
+
+        Parameters
+        ----------
+        name: :class:`str`
+            The name of the channel
+        overwrites
+            A :class:`dict` of target (either a role or a member) to
+            :class:`PermissionOverwrite` to apply upon creation of a channel.
+            Useful for creating secret channels.
+        category: Optional[:class:`CategoryChannel`]
+            The category to place the newly created channel under.
+            The permissions will be automatically synced to category if no
+            overwrites are provided.
+        position: :class:`int`
+            The position in the channel list. This is a number that starts
+            at 0. e.g. the top channel is position 0.
+        topic: Optional[:class:`str`]
+            The new channel's topic.
+        slowmode_delay: :class:`int`
+            Specifies the slowmode rate limit for user in this channel, in seconds.
+            The maximum value possible is `21600`.
+        default_post_slowmode_delay: :class:`int`
+            The initial ``slowmode_delay`` to set on newly created threads in the channel.
+            This field is copied to the thread at creation time and does not live update.
+        default_auto_archive_duration: :class:`AutoArchiveDuration`
+            The default duration that the clients use (not the API) for newly created threads in the channel,
+            in minutes, to automatically archive the thread after recent activity
+        nsfw: :class:`bool`
+            To mark the channel as NSFW or not.
+        reason: Optional[:class:`str`]
+            The reason for creating this channel. Shows up on the audit log.
+
+        Raises
+        -------
+        Forbidden
+            You do not have the proper permissions to create this channel.
+        HTTPException
+            Creating the channel failed.
+        InvalidArgument
+            The permission overwrite information is not in proper form,
+            or the ``default_auto_archive_duration`` is not a valid member of :class:`AutoArchiveDuration`
+
+        Returns
+        -------
+        :class:`ForumChannel`
+            The channel that was just created
+        """
+        data = await self._create_channel(
+            name,
+            overwrites,
+            ChannelType.forum_channel,
+            category,
+            topic=topic,
+            slowmode_delay=slowmode_delay,
+            default_thread_slowmode_delay=default_post_slowmode_delay,
+            default_auto_archive_duration=default_auto_archive_duration,
+            nsfw=nsfw,
+            position=position,
+            reason=reason
+        )
+        channel = ForumChannel(state=self._state, guild=self, data=data)
+
+        # temporarily add to the cache
+        self._channels[channel.id] = channel
+        return channel
+
+    async def create_category(
+            self,
+            name: str,
+            *,
+            overwrites: Optional[Dict[Snowflake, PermissionOverwrite]] = None,
+            reason: Optional[str] = None,
+            position: Optional[int] = None
+    ) -> CategoryChannel:
         """|coro|
 
         Same as :meth:`create_text_channel` except makes a :class:`CategoryChannel` instead.
@@ -1089,7 +1721,31 @@ async def delete(self):
 
         await self._state.http.delete_guild(self.id)
 
-    async def edit(self, *, reason=None, **fields):
+    async def edit(
+            self,
+            name: str = MISSING,
+            description: str = MISSING,
+            features: GuildFeatures = MISSING,
+            icon: Optional[bytes] = MISSING,
+            banner: Optional[bytes] = MISSING,
+            splash: Optional[bytes] = MISSING,
+            discovery_splash: Optional[bytes] = MISSING,
+            region: Optional[VoiceRegion] = MISSING,
+            afk_channel: Optional[VoiceChannel] = MISSING,
+            afk_timeout: Optional[int] = MISSING,
+            system_channel: Optional[TextChannel] = MISSING,
+            system_channel_flags: Optional[SystemChannelFlags] = MISSING,
+            rules_channel: Optional[TextChannel] = MISSING,
+            public_updates_channel: Optional[TextChannel] = MISSING,
+            preferred_locale: Optional[Union[str, Locale]] = MISSING,
+            verification_level: Optional[VerificationLevel] = MISSING,
+            default_notifications: Optional[NotificationLevel] = MISSING,
+            explicit_content_filter: Optional[ContentFilter] = MISSING,
+            vanity_code: Optional[str] = MISSING,
+            owner: Optional[Union[Member, User]] = MISSING,
+            *,
+            reason: Optional[str] = None,
+    ) -> None:
         """|coro|
 
         Edits the guild.
@@ -1107,6 +1763,10 @@ async def edit(self, *, reason=None, **fields):
         description: :class:`str`
             The new description of the guild. This is only available to guilds that
             contain ``PUBLIC`` in :attr:`Guild.features`.
+        features: :class:`GuildFeatures`
+            Features to enable/disable will be merged in to the current features.
+            See the `discord api documentation <https://discord.com/developers/docs/resources/guild#guild-object-mutable-guild-features>`_
+            for a list of currently mutable features and the required permissions.
         icon: :class:`bytes`
             A :term:`py:bytes-like object` representing the icon. Only PNG/JPEG is supported.
             GIF is only available to guilds that contain ``ANIMATED_ICON`` in :attr:`Guild.features`.
@@ -1119,8 +1779,12 @@ async def edit(self, *, reason=None, **fields):
             Only PNG/JPEG supported. Could be ``None`` to denote removing the
             splash. This is only available to guilds that contain ``INVITE_SPLASH``
             in :attr:`Guild.features`.
+        discovery_splash: :class:`bytes`
+            A :term:`py:bytes-like object` representing the discovery splash.
+            Only PNG/JPEG supported. Could be ``None`` to denote removing the splash.
+            This is only available to guilds that contain ``DISCOVERABLE`` in :attr:`Guild.features`.
         region: :class:`VoiceRegion`
-            The new region for the guild's voice communication.
+            Deprecated: The new region for the guild's voice communication.
         afk_channel: Optional[:class:`VoiceChannel`]
             The new channel that is the AFK channel. Could be ``None`` for no AFK channel.
         afk_timeout: :class:`int`
@@ -1167,121 +1831,85 @@ async def edit(self, *, reason=None, **fields):
         """
 
         http = self._state.http
-        try:
-            icon_bytes = fields['icon']
-        except KeyError:
-            icon = self.icon
-        else:
-            if icon_bytes is not None:
-                icon = utils._bytes_to_base64_data(icon_bytes)
-            else:
-                icon = None
-
-        try:
-            banner_bytes = fields['banner']
-        except KeyError:
-            banner = self.banner
-        else:
-            if banner_bytes is not None:
-                banner = utils._bytes_to_base64_data(banner_bytes)
-            else:
-                banner = None
-
-        try:
-            vanity_code = fields['vanity_code']
-        except KeyError:
-            pass
-        else:
-            await http.change_vanity_code(self.id, vanity_code, reason=reason)
-
-        try:
-            splash_bytes = fields['splash']
-        except KeyError:
-            splash = self.splash
-        else:
-            if splash_bytes is not None:
-                splash = utils._bytes_to_base64_data(splash_bytes)
-            else:
-                splash = None
-
-        fields['icon'] = icon
-        fields['banner'] = banner
-        fields['splash'] = splash
-
-        default_message_notifications = fields.get('default_notifications', self.default_notifications)
-        if not isinstance(default_message_notifications, NotificationLevel):
-            raise InvalidArgument('default_notifications field must be of type NotificationLevel')
-        fields['default_message_notifications'] = default_message_notifications.value
-
-        try:
-            afk_channel = fields.pop('afk_channel')
-        except KeyError:
-            pass
-        else:
-            if afk_channel is None:
-                fields['afk_channel_id'] = afk_channel
-            else:
-                fields['afk_channel_id'] = afk_channel.id
-
-        try:
-            system_channel = fields.pop('system_channel')
-        except KeyError:
-            pass
-        else:
-            if system_channel is None:
-                fields['system_channel_id'] = system_channel
-            else:
-                fields['system_channel_id'] = system_channel.id
-
-        if 'owner' in fields:
-            if self.owner_id != self._state.self_id:
-                raise InvalidArgument('To transfer ownership you must be the owner of the guild.')
-
-            fields['owner_id'] = fields['owner'].id
-
-        if 'region' in fields:
-            fields['region'] = str(fields['region'])
-
-        level = fields.get('verification_level', self.verification_level)
-        if not isinstance(level, VerificationLevel):
-            raise InvalidArgument('verification_level field must be of type VerificationLevel')
-
-        fields['verification_level'] = level.value
-
-        explicit_content_filter = fields.get('explicit_content_filter', self.explicit_content_filter)
-        if not isinstance(explicit_content_filter, ContentFilter):
-            raise InvalidArgument('explicit_content_filter field must be of type ContentFilter')
-
-        fields['explicit_content_filter'] = explicit_content_filter.value
-
-        system_channel_flags = fields.get('system_channel_flags', self.system_channel_flags)
-        if not isinstance(system_channel_flags, SystemChannelFlags):
-            raise InvalidArgument('system_channel_flags field must be of type SystemChannelFlags')
-
-        fields['system_channel_flags'] = system_channel_flags.value
-
-        try:
-            rules_channel = fields.pop('rules_channel')
-        except KeyError:
-            pass
-        else:
-            if rules_channel is None:
-                fields['rules_channel_id'] = rules_channel
-            else:
-                fields['rules_channel_id'] = rules_channel.id
-
-        try:
-            public_updates_channel = fields.pop('public_updates_channel')
-        except KeyError:
-            pass
-        else:
-            if public_updates_channel is None:
-                fields['public_updates_channel_id'] = public_updates_channel
-            else:
-                fields['public_updates_channel_id'] = public_updates_channel.id
+        
+        fields = {}
+        
+        if name is not MISSING:
+            fields['name'] = name
+        
+        if description is not MISSING:
+            fields['description'] = description
+        
+        if icon is not MISSING:
+            fields['icon'] = utils._bytes_to_base64_data(icon)
+        
+        if banner is not MISSING:
+            fields['banner'] = utils._bytes_to_base64_data(banner)
+        
+        if splash is not MISSING:
+            fields['splash'] = utils._bytes_to_base64_data(splash)
+        
+        if features is not MISSING:
+            current_features = GuildFeatures(self.features)
+            fields['features'] = current_features.merge(features).parsed()
+        
+        if discovery_splash is not MISSING:
+            fields['discovery_splash'] = utils._bytes_to_base64_data(discovery_splash)
+        
+        if region is not MISSING:
+            import warnings
+            warnings.warn('The region parameter is deprecated and will be removed in a future version.', DeprecationWarning)
+            if not isinstance(region, VoiceRegion):
+                raise InvalidArgument('region field must be of type VoiceRegion')
+            fields['region'] = region.value
+        
+        if afk_channel is not MISSING:
+            fields['afk_channel_id'] = afk_channel.id if afk_channel else None
+        
+        if afk_timeout is not MISSING:
+            fields['afk_timeout'] = afk_timeout
+        
+        if owner is not MISSING:
+            fields['owner_id'] = owner.id
+        
+        if verification_level is not MISSING:
+            if not isinstance(verification_level, VerificationLevel):
+                raise InvalidArgument('verification_level field must be of type VerificationLevel')
+            fields['verification_level'] = verification_level.value
+        
+        if default_notifications is not MISSING:
+            if not isinstance(default_notifications, NotificationLevel):
+                raise InvalidArgument('default_notifications field must be of type NotificationLevel')
+            fields['default_message_notifications'] = default_notifications.value
+        
+        if explicit_content_filter is not MISSING:
+            if not isinstance(explicit_content_filter, ContentFilter):
+                raise InvalidArgument('explicit_content_filter field must be of type ContentFilter')
+            fields['explicit_content_filter'] = explicit_content_filter.value
+        
+        if vanity_code is not MISSING:
+            fields['vanity_url_code'] = vanity_code
+        
+        if system_channel is not MISSING:
+            fields['system_channel_id'] = system_channel.id if system_channel else None
+        
+        if system_channel_flags is not MISSING:
+            if not isinstance(system_channel_flags, SystemChannelFlags):
+                raise InvalidArgument('system_channel_flags field must be of type SystemChannelFlags')
+            fields['system_channel_flags'] = system_channel_flags.value
+        
+        if preferred_locale is not MISSING:
+            fields['preferred_locale'] = str(preferred_locale)
+        
+        if rules_channel is not MISSING:
+            fields['rules_channel_id'] = rules_channel.id if rules_channel else None
+        
+        if public_updates_channel is not MISSING:
+            fields['public_updates_channel_id'] = public_updates_channel.id if public_updates_channel else None
+        
         await http.edit_guild(self.id, reason=reason, **fields)
 
-    async def fetch_channels(self):
+    async def fetch_channels(self) -> List[GuildChannel]:
         """|coro|
 
         Retrieves all :class:`abc.GuildChannel` that the guild has.
@@ -1310,13 +1938,47 @@ def convert(d):
             factory, ch_type = _channel_factory(d['type'])
             if factory is None:
                 raise InvalidData('Unknown channel type {type} for channel ID {id}.'.format_map(d))
-
             channel = factory(guild=self, state=self._state, data=d)
             return channel
 
         return [convert(d) for d in data]
 
-    def fetch_members(self, *, limit=1000, after=None):
+    async def fetch_active_threads(self) -> List[Union[ThreadChannel, ForumPost]]:
+        """|coro|
+
+        Returns all active threads and forum posts in the guild.
+        This includes all public and private threads as long as the current user has permissions to access them.
+        Threads are ordered by their id, in descending order.
+
+        .. note::
+
+            This method is an API call.
+
+        .. versionadded:: 2.0
+
+        Returns
+        -------
+        List[Union[:class:`ThreadChannel`, :class:`ForumPost`]]
+            The active threads and forum posts in the guild.
+        """
+        state = self._state
+        data = await state.http.list_active_threads(self.id)
+        thread_members = data['thread_members']
+
+        def convert(d):
+            thread_member = thread_members.get(int(d['id']))
+            if thread_member:
+                d['member'] = thread_member
+            return _thread_factory(guild=self, state=state, data=d)
+
+        return [convert(d) for d in data['threads']]
+
+    def fetch_members(
+            self,
+            *,
+            limit: int = 1000,
+            after: Optional[Union[Snowflake, datetime]] = None
+    ) -> MemberIterator:
         """Retrieves an :class:`.AsyncIterator` that enables receiving the guild's members. In order to use this,
         :meth:`Intents.members` must be enabled.
 
@@ -1368,7 +2030,7 @@ def fetch_members(self, *, limit=1000, after=None):
 
         return MemberIterator(self, limit=limit, after=after)
 
-    async def fetch_member(self, member_id):
+    async def fetch_member(self, member_id: id) -> Member:
         """|coro|
 
         Retrieves a :class:`Member` from a guild ID, and a member ID.
@@ -1397,7 +2059,7 @@ async def fetch_member(self, member_id):
         data = await self._state.http.get_member(self.id, member_id)
         return Member(data=data, state=self._state, guild=self)
 
-    async def fetch_ban(self, user):
+    async def fetch_ban(self, user: Snowflake) -> BanEntry:
         """|coro|
 
         Retrieves the :class:`BanEntry` for a user.
@@ -1424,45 +2086,114 @@ async def fetch_ban(self, user):
         :class:`BanEntry`
             The :class:`BanEntry` object for the specified user.
         """
-        data = await self._state.http.get_ban(user.id, self.id)
+        data = await self._state.http.get_ban(user.id, self.id)  # type: ignore
         return BanEntry(
             user=User(state=self._state, data=data['user']),
             reason=data['reason']
         )
 
-    async def bans(self):
-        """|coro|
-
-        Retrieves all the users that are banned from the guild as a :class:`list` of :class:`BanEntry`.
+    def bans(
+            self,
+            limit: Optional[int] = None,
+            before: Optional[Union['Snowflake', datetime]] = None,
+            after: Optional[Union['Snowflake', datetime]] = None
+    ) -> BanIterator:
+        """Retrieves an :class:`.AsyncIterator` that enables receiving the guild's bans.
 
         You must have the :attr:`~Permissions.ban_members` permission
         to get this information.
 
+        .. note::
+
+            This method is an API call. Use it careful.
+
+        All parameters are optional.
+
+        Parameters
+        ----------
+        limit: Optional[:class:`int`]
+            The number of bans to retrieve. Defaults to all.
+            Note that this is potentially slow.
+        before: Optional[Union[:class:`.abc.Snowflake`, :class:`datetime.datetime`]]
+            Retrieve members before this date or object.
+            If a date is provided it must be a timezone-naive datetime representing UTC time.
+        after: Optional[Union[:class:`.abc.Snowflake`, :class:`datetime.datetime`]]
+            Retrieve members after this date or object.
+            If a date is provided it must be a timezone-naive datetime representing UTC time.
+
         Raises
-        -------
+        ------
         Forbidden
             You do not have proper permissions to get the information.
         HTTPException
-            An error occurred while fetching the information.
+            Getting the bans failed.
 
-        Returns
+        Yields
+        ------
+        :class:`.BanEntry`
+            The ban entry containing the user and an optional reason.
+
+        Examples
         --------
-        List[:class:`BanEntry`]
-            A list of :class:`BanEntry` objects.
-        """
 
-        data = await self._state.http.get_bans(self.id)
-        return [BanEntry(user=User(state=self._state, data=e['user']),
-                         reason=e['reason'])
-                for e in data]
+        Usage ::
+
+            async for ban_entry in guild.bans(limit=150):
+                print(ban_entry.user)
 
-    async def prune_members(self, *, days, compute_prune_count=True, roles=None, reason=None):
+        Flattening into a list ::
+
+            ban_entries = await guild.bans(limit=150).flatten()
+            # ban_entries is now a list of BanEntry...
+        """
+        return BanIterator(self, limit=limit, before=before, after=after)
+    
+    @overload
+    async def prune_members(
+            self,
+            *,
+            days: int,
+            roles: Optional[List[Snowflake]],
+            reason: Optional[str]
+    ) -> int:
+        ...
+    
+    @overload
+    async def prune_members(
+            self,
+            *,
+            days: int,
+            compute_prune_count: Literal[True],
+            roles: Optional[List[Snowflake]],
+            reason: Optional[str]
+    ) -> int:
+        ...
+    
+    @overload
+    async def prune_members(
+        self,
+        *,
+        days: int,
+        compute_prune_count: Literal[False],
+        roles: Optional[List[Snowflake]],
+        reason: Optional[str]
+    ) -> None:
+        ...
+    
+    async def prune_members(
+            self,
+            *,
+            days: int,
+            compute_prune_count: bool = True,
+            roles: List[Snowflake] = None,
+            reason: Optional[str] = None
+    ) -> Optional[int]:
         r"""|coro|
 
         Prunes the guild from its inactive members.
 
         The inactive members are denoted if they have not logged on in
-        ``days`` number of days and they have no roles.
+        ``days`` number of days, and they have no roles.
 
         You must have the :attr:`~Permissions.kick_members` permission
         to use this.
@@ -1510,12 +2241,18 @@ async def prune_members(self, *, days, compute_prune_count=True, roles=None, rea
             raise InvalidArgument('Expected int for ``days``, received {0.__class__.__name__} instead.'.format(days))
 
         if roles:
-            roles = [str(role.id) for role in roles]
-
-        data = await self._state.http.prune_members(self.id, days, compute_prune_count=compute_prune_count, roles=roles, reason=reason)
+            roles = [str(role.id) for role in roles]  # type: ignore
+
+        data = await self._state.http.prune_members(
+            self.id,
+            days,
+            compute_prune_count=compute_prune_count,
+            roles=roles,
+            reason=reason
+        )
         return data['pruned']
 
-    async def templates(self):
+    async def templates(self) -> List[Template]:
         """|coro|
 
         Gets the list of templates from this guild.
@@ -1538,7 +2275,7 @@ async def templates(self):
         data = await self._state.http.guild_templates(self.id)
         return [Template(data=d, state=self._state) for d in data]
 
-    async def webhooks(self):
+    async def webhooks(self) -> List[Webhook]:
         """|coro|
 
         Gets the list of webhooks from this guild.
@@ -1560,7 +2297,7 @@ async def webhooks(self):
         data = await self._state.http.guild_webhooks(self.id)
         return [Webhook.from_state(d, state=self._state) for d in data]
 
-    async def estimate_pruned_members(self, *, days, roles=None):
+    async def estimate_pruned_members(self, *, days: int, roles: Optional[List[Snowflake]] = None) -> int:
         """|coro|
 
         Similar to :meth:`prune_members` except instead of actually
@@ -1596,12 +2333,12 @@ async def estimate_pruned_members(self, *, days, roles=None):
             raise InvalidArgument('Expected int for ``days``, received {0.__class__.__name__} instead.'.format(days))
 
         if roles:
-            roles = [str(role.id) for role in roles]
+            roles = [str(role.id) for role in roles]  # type: ignore
 
         data = await self._state.http.estimate_pruned_members(self.id, days, roles)
         return data['pruned']
 
-    async def invites(self):
+    async def invites(self) -> List[Invite]:
         """|coro|
 
         Returns a list of all active instant invites from the guild.
@@ -1632,7 +2369,7 @@ async def invites(self):
 
         return result
 
-    async def create_template(self, *, name, description=None):
+    async def create_template(self, *, name: str, description: Optional[str] = None) -> Template:
         """|coro|
 
         Creates a template for the guild.
@@ -1662,7 +2399,7 @@ async def create_template(self, *, name, description=None):
 
         return Template(state=self._state, data=data)
 
-    async def create_integration(self, *, type, id):
+    async def create_integration(self, *, type: IntegrationType, id: int):
         """|coro|
 
         Attaches an integration to the guild.
@@ -1688,8 +2425,9 @@ async def create_integration(self, *, type, id):
         """
         await self._state.http.create_integration(self.id, type, id)
 
-    async def integrations(self):
+    async def integrations(self) -> List[Integration]:
         """|coro|
+        
         Returns a list of all integrations attached to the guild.
         You must have the :attr:`~Permissions.manage_guild` permission to
         do this.
@@ -1706,6 +2444,7 @@ async def integrations(self):
             The list of integrations that are attached to the guild.
         """
         data = await self._state.http.get_all_integrations(self.id)
+
         def convert(d):
             factory, itype = _integration_factory(d['type'])
             if factory is None:
@@ -1714,7 +2453,7 @@ def convert(d):
 
         return [convert(d) for d in data]
 
-    async def fetch_emojis(self):
+    async def fetch_emojis(self) -> List[Emoji]:
         r"""|coro|
 
         Retrieves all custom :class:`Emoji`\s from the guild.
@@ -1736,7 +2475,7 @@ async def fetch_emojis(self):
         data = await self._state.http.get_all_custom_emojis(self.id)
         return [Emoji(guild=self, state=self._state, data=d) for d in data]
 
-    async def fetch_emoji(self, emoji_id):
+    async def fetch_emoji(self, emoji_id: int) -> Emoji:
         """|coro|
 
         Retrieves a custom :class:`Emoji` from the guild.
@@ -1766,7 +2505,14 @@ async def fetch_emoji(self, emoji_id):
         data = await self._state.http.get_custom_emoji(self.id, emoji_id)
         return Emoji(guild=self, state=self._state, data=data)
 
-    async def create_custom_emoji(self, *, name, image, roles=None, reason=None):
+    async def create_custom_emoji(
+            self,
+            *,
+            name: str,
+            image: bytes,
+            roles: Optional[List[Snowflake]] = None,
+            reason: Optional[str] = None
+    ) -> Emoji:
         r"""|coro|
 
         Creates a custom :class:`Emoji` for the guild.
@@ -1804,11 +2550,11 @@ async def create_custom_emoji(self, *, name, image, roles=None, reason=None):
 
         img = utils._bytes_to_base64_data(image)
         if roles:
-            roles = [role.id for role in roles]
+            roles = [role.id for role in roles]  # type: ignore
         data = await self._state.http.create_custom_emoji(self.id, name, img, roles=roles, reason=reason)
         return self._state.store_emoji(self, data)
 
-    async def fetch_roles(self):
+    async def fetch_roles(self) -> List[Role]:
         """|coro|
 
         Retrieves all :class:`Role` that the guild has.
@@ -1832,7 +2578,63 @@ async def fetch_roles(self):
         data = await self._state.http.get_roles(self.id)
         return [Role(guild=self, state=self._state, data=d) for d in data]
 
-    async def create_role(self, *, reason=None, **fields):
+    @overload
+    async def create_role(
+            self,
+            *,
+            name: str = MISSING,
+            permissions: Permissions = MISSING,
+            color: Union[Colour, int] = MISSING,
+            colour: Union[Colour, int] = MISSING,
+            hoist: bool = False,
+            mentionable: bool = False,
+            reason: Optional[str] = None
+    ) -> Role:
+        ...
+    
+    @overload
+    async def create_role(
+            self,
+            *,
+            icon: bytes,
+            name: str = MISSING,
+            permissions: Permissions = MISSING,
+            color: Union[Colour, int] = MISSING,
+            colour: Union[Colour, int] = MISSING,
+            hoist: bool = False,
+            mentionable: bool = False,
+            reason: Optional[str] = None
+    ) -> Role:
+        ...
+    
+    @overload
+    async def create_role(
+            self,
+            *,
+            unicode_emoji: str,
+            name: str = MISSING,
+            permissions: Permissions = MISSING,
+            color: Union[Colour, int] = MISSING,
+            colour: Union[Colour, int] = MISSING,
+            hoist: bool = False,
+            mentionable: bool = False,
+            reason: Optional[str] = None
+    ) -> Role:
+        ...
+    
+    async def create_role(
+            self,
+            *,
+            name: str = MISSING,
+            permissions: Permissions = MISSING,
+            color: Union[Colour, int] = MISSING,
+            colour: Union[Colour, int] = MISSING,
+            hoist: bool = False,
+            mentionable: bool = False,
+            icon: Optional[bytes] = None,
+            unicode_emoji: Optional[str] = None,
+            reason: Optional[str] = None
+    ) -> Role:
         """|coro|
 
         Creates a :class:`Role` for the guild.
@@ -1844,13 +2646,22 @@ async def create_role(self, *, reason=None, **fields):
 
         .. versionchanged:: 1.6
             Can now pass ``int`` to ``colour`` keyword-only parameter.
-
+        
+        .. versionadded:: 2.0
+            Added the ``icon`` and ``unicode_emoji`` keyword-only parameters.
+        
+        .. note::
+            The ``icon`` and ``unicode_emoji`` can't be used together.
+            Both of them can only be used when ``ROLE_ICONS`` is in the guild :meth:`~Guild.features`.
+            
         Parameters
         -----------
         name: :class:`str`
             The role name. Defaults to 'new role'.
         permissions: :class:`Permissions`
             The permissions to have. Defaults to no permissions.
+        color: Union[:class:`Colour`, :class:`int`]
+            The colour for the role. Defaults to :meth:`Colour.default`.
         colour: Union[:class:`Colour`, :class:`int`]
             The colour for the role. Defaults to :meth:`Colour.default`.
             This is aliased to ``color`` as well.
@@ -1860,9 +2671,13 @@ async def create_role(self, *, reason=None, **fields):
         mentionable: :class:`bool`
             Indicates if the role should be mentionable by others.
             Defaults to ``False``.
+        icon: Optional[:class:`bytes`]
+            The :term:`py:bytes-like object` representing the image data to use as the role :attr:`~Role.icon`.
+        unicode_emoji: Optional[:class:`str`]
+            The unicode emoji to use as the role :attr:`~Role.unicode_emoji`.
         reason: Optional[:class:`str`]
             The reason for creating this role. Shows up on the audit log.
-
+        
         Raises
         -------
         Forbidden
@@ -1870,42 +2685,50 @@ async def create_role(self, *, reason=None, **fields):
         HTTPException
             Creating the role failed.
         InvalidArgument
-            An invalid keyword argument was given.
-
+            Both ``icon`` and ``unicode_emoji`` were passed.
+        
         Returns
         --------
         :class:`Role`
             The newly created role.
         """
 
-        try:
-            perms = fields.pop('permissions')
-        except KeyError:
-            fields['permissions'] = 0
-        else:
-            fields['permissions'] = perms.value
-
-        try:
-            colour = fields.pop('colour')
-        except KeyError:
-            colour = fields.get('color', Colour.default())
-        finally:
-            if isinstance(colour, int):
-                colour = Colour(value=colour)
-            fields['color'] = colour.value
-
-        valid_keys = ('name', 'permissions', 'color', 'hoist', 'mentionable')
-        for key in fields:
-            if key not in valid_keys:
-                raise InvalidArgument('%r is not a valid field.' % key)
-
-        data = await self._state.http.create_role(self.id, reason=reason, **fields)
+        fields = {}
+        
+        if name is not MISSING:
+            fields['name'] = name
+        
+        if permissions is not MISSING:
+            fields['permissions'] = permissions.value
+        
+        color = color if color is not MISSING else colour
+        
+        if color is not MISSING:
+            if isinstance(color, Colour):
+                color = color.value
+            fields['color'] = color
+        
+        if hoist is not MISSING:
+            fields['hoist'] = hoist
+        
+        if mentionable is not MISSING:
+            fields['mentionable'] = mentionable
+        
+        if icon is not None:
+            if unicode_emoji is not None:
+                raise InvalidArgument('icon and unicode_emoji cannot be used together.')
+            fields['icon'] = utils._bytes_to_base64_data(icon)
+        
+        elif unicode_emoji is not None:
+            fields['unicode_emoji'] = str(unicode_emoji)
+
+        data = await self._state.http.create_role(self.id, reason=reason, fields=fields)
         role = Role(guild=self, data=data, state=self._state)
-
+        self._add_role(role)
         # TODO: add to cache
         return role
 
-    async def edit_role_positions(self, positions, *, reason=None):
+    async def edit_role_positions(self, positions: Dict[Role, int], *, reason: Optional[str] = None) -> List[Role]:
         """|coro|
 
         Bulk edits a list of :class:`Role` in the guild.
@@ -1971,7 +2794,7 @@ async def edit_role_positions(self, positions, *, reason=None):
 
         return roles
 
-    async def kick(self, user, *, reason=None):
+    async def kick(self, user: Snowflake, *, reason: Optional[str] = None):
         """|coro|
 
         Kicks a user from the guild.
@@ -1995,9 +2818,16 @@ async def kick(self, user, *, reason=None):
         HTTPException
             Kicking failed.
         """
-        await self._state.http.kick(user.id, self.id, reason=reason)
-
-    async def ban(self, user, *, reason=None, delete_message_days=1):
+        await self._state.http.kick(user.id, self.id, reason=reason)  # type: ignore
+
+    async def ban(
+            self,
+            user: Snowflake,
+            *,
+            delete_message_days: Optional[int] = None,
+            delete_message_seconds: Optional[int] = 0,
+            reason: Optional[str] = None
+    ) -> None:
         """|coro|
 
         Bans a user from the guild.
@@ -2014,6 +2844,13 @@ async def ban(self, user, *, reason=None, delete_message_days=1):
         delete_message_days: :class:`int`
             The number of days worth of messages to delete from the user
             in the guild. The minimum is 0 and the maximum is 7.
+
+            .. deprecated:: 2.0
+        delete_message_seconds: :class:`int`
+            The number of days worth of messages to delete from the user
+            in the guild. The minimum is 0 and the maximum is 604800 (7 days).
+
+            .. versionadded:: 2.0
         reason: Optional[:class:`str`]
             The reason the user got banned.
 
@@ -2024,9 +2861,17 @@ async def ban(self, user, *, reason=None, delete_message_days=1):
         HTTPException
             Banning failed.
         """
-        await self._state.http.ban(user.id, self.id, delete_message_days, reason=reason)
-
-    async def unban(self, user, *, reason=None):
+        if delete_message_days is not None:
+            import warnings
+            warnings.warn(
+                'delete_message_days is deprecated, use delete_message_seconds instead.',
+                DeprecationWarning,
+                stacklevel=2
+            )
+            delete_message_seconds = delete_message_days * 86400
+        await self._state.http.ban(user.id, self.id, delete_message_seconds, reason=reason)  # type: ignore
+
+    async def unban(self, user: Snowflake, *, reason: Optional[str] = None):
         """|coro|
 
         Unbans a user from the guild.
@@ -2050,9 +2895,9 @@ async def unban(self, user, *, reason=None):
         HTTPException
             Unbanning failed.
         """
-        await self._state.http.unban(user.id, self.id, reason=reason)
+        await self._state.http.unban(user.id, self.id, reason=reason)  # type: ignore
 
-    async def vanity_invite(self):
+    async def vanity_invite(self) -> Invite:
         """|coro|
 
         Returns the guild's special vanity invite.
@@ -2090,30 +2935,16 @@ async def vanity_invite(self):
         payload['max_age'] = 0
         return Invite(state=self._state, data=payload)
 
-    @utils.deprecated()
-    def ack(self):
-        """|coro|
-
-        Marks every message in this guild as read.
-
-        The user must not be a bot user.
-
-        .. deprecated:: 1.7
-
-        Raises
-        -------
-        HTTPException
-            Acking failed.
-        ClientException
-            You must not be a bot user.
-        """
-
-        state = self._state
-        if state.is_bot:
-            raise ClientException('Must not be a bot account to ack messages.')
-        return state.http.ack_guild(self.id)
-
-    def audit_logs(self, *, limit=100, before=None, after=None, oldest_first=None, user=None, action=None):
+    def audit_logs(
+            self,
+            *,
+            limit: int = 100,
+            before: Optional[Union[Snowflake, datetime]] = None,
+            after: Optional[Union[Snowflake, datetime]] = None,
+            oldest_first: Optional[bool] = None,
+            user: Optional[Snowflake] = None,
+            action: Optional[AuditLogAction] = None
+    ):
         """Returns an :class:`AsyncIterator` that enables receiving the guild's audit logs.
 
         You must have the :attr:`~Permissions.view_audit_log` permission to use this.
@@ -2167,15 +2998,22 @@ def audit_logs(self, *, limit=100, before=None, after=None, oldest_first=None, u
             The audit log entry.
         """
         if user:
-            user = user.id
+            user = user.id  # type: ignore
 
         if action:
             action = action.value
 
-        return AuditLogIterator(self, before=before, after=after, limit=limit,
-                                oldest_first=oldest_first, user_id=user, action_type=action)
+        return AuditLogIterator(
+            self,
+            before=before,
+            after=after,
+            limit=limit,
+            oldest_first=oldest_first,
+            user_id=user,
+            action_type=action
+        )
 
-    async def widget(self):
+    async def widget(self) -> Widget:
         """|coro|
 
         Returns the widget of the guild.
@@ -2200,7 +3038,7 @@ async def widget(self):
 
         return Widget(state=self._state, data=data)
 
-    async def chunk(self, *, cache=True):
+    async def chunk(self, *, cache: bool = True):
         """|coro|
 
         Requests all members that belong to this guild. In order to use this,
@@ -2227,7 +3065,15 @@ async def chunk(self, *, cache=True):
         if not self._state.is_guild_evicted(self):
             return await self._state.chunk_guild(self, cache=cache)
 
-    async def query_members(self, query=None, *, limit=5, user_ids=None, presences=False, cache=True):
+    async def query_members(
+            self,
+            query: Optional[str] = None,
+            *,
+            limit: int = 5,
+            user_ids: Optional[List[int]] = None,
+            presences: bool = False,
+            cache: bool = True
+    ) -> List[Member]:
         """|coro|
 
         Request members that belong to this guild whose username starts with
@@ -2291,9 +3137,22 @@ async def query_members(self, query=None, *, limit=5, user_ids=None, presences=F
             raise ValueError('user_ids must contain at least 1 value')
 
         limit = min(100, limit or 5)
-        return await self._state.query_members(self, query=query, limit=limit, user_ids=user_ids, presences=presences, cache=cache)
+        return await self._state.query_members(
+            self,
+            query=query,
+            limit=limit,
+            user_ids=user_ids,
+            presences=presences,
+            cache=cache
+        )
 
-    async def change_voice_state(self, *, channel, self_mute=False, self_deaf=False):
+    async def change_voice_state(
+            self,
+            *,
+            channel: Optional[Union[VoiceChannel, StageChannel]],
+            self_mute: bool = False,
+            self_deaf: bool = False
+    ):
         """|coro|
 
         Changes client's voice state in the guild.
@@ -2312,3 +3171,602 @@ async def change_voice_state(self, *, channel, self_mute=False, self_deaf=False)
         ws = self._state._get_websocket(self.id)
         channel_id = channel.id if channel else None
         await ws.voice_state(self.id, channel_id, self_mute, self_deaf)
+
+    async def create_sticker(
+            self,
+            name: str,
+            file: Union[UploadFile, PathLike[str], PathLike[bytes]],
+            tags: Union[str, List[str]],
+            description: Optional[str] = None,
+            *,
+            reason: Optional[str] = None
+    ) -> GuildSticker:
+        """|coro|
+
+        Create a new sticker for the guild.
+
+        Requires the ``MANAGE_EMOJIS_AND_STICKERS`` permission.
+
+
+        Parameters
+        ----------
+        name: :class:`str`
+            The name of the sticker (2-30 characters).
+        tags: Union[:class:`str`, List[:class:`str`]]
+            Autocomplete/suggestion tags for the sticker separated by ``,`` or in a list. (max 200 characters).
+        description: Optional[:class:`str`]
+            The description of the sticker (None or 2-100 characters).
+        file: Union[:class:`UploadFile`, :class:`str`]
+            The sticker file to upload or the path to it, must be a PNG, APNG, GIF or Lottie JSON file, max 500 KB
+        reason: Optional[:class:`str`]
+            The reason for creating the sticker., shows up in the audit-log.
+
+        Raises
+        ------
+        discord.Forbidden:
+            You don't have the permissions to upload stickers in this guild.
+        discord.HTTPException:
+            Creating the sticker failed.
+        ValueError
+            Any of name, description or tags is too short/long.
+
+        Return
+        ------
+        :class:`GuildSticker`
+            The new GuildSticker created on success.
+        """
+        if 2 > len(name) > 30:
+            raise ValueError(f'The name must be between 2 and 30 characters in length; got {len(name)}.')
+        if not isinstance(file, UploadFile):
+            file = UploadFile(file)
+        if description is not None and 2 > len(description) > 100:
+            raise ValueError(f'The description must be between 2 and 100 characters in length; got {len(description)}.')
+        if isinstance(tags, list):
+            tags = ','.join(tags)
+        if len(tags) > 200:
+            raise ValueError(f'The tags could be max. 200 characters in length; {len(tags)}.')
+        try:
+            data = await self._state.http.create_guild_sticker(
+                guild_id=self.id,
+                name=name,
+                description=description,
+                tags=tags,
+                file=file,
+                reason=reason
+            )
+        finally:
+            file.close()
+        return self._state.store_sticker(data)
+
+    async def fetch_events(
+            self,
+            with_user_count: bool = True
+    ) -> Optional[List[GuildScheduledEvent]]:
+        """|coro|
+
+        Retrieves a :class:`list` of scheduled events the guild has.
+
+        .. note::
+
+            This method is an API call.
+            For general usage, consider iterating over :attr:`events` instead.
+
+        Parameters
+        ----------
+        with_user_count: :class:`bool`
+            Whether to include the number of interested users the event has, default ``True``.
+
+        Returns
+        -------
+        Optional[List[:class:`GuildScheduledEvent`]]
+            A list of scheduled events the guild has.
+        """
+        data = self._state.http.get_guild_events(guild_id=self.id, with_user_count=with_user_count)
+        [self._add_event(GuildScheduledEvent(state=self._state, guild=self, data=d)) for d in data]
+        return self.events
+
+    async def fetch_event(
+            self,
+            id: int,
+            with_user_count: bool = True
+    ) -> Optional[GuildScheduledEvent]:
+        """|coro|
+
+        Fetches the :class:`GuildScheduledEvent` with the given id.
+
+        Parameters
+        ----------
+        id: :class:`int`
+            The id of the event to fetch.
+        with_user_count: :class:`bool`
+            Whether to include the number of interested users the event has, default ``True``.
+
+        Returns
+        -------
+        Optional[:class:`GuildScheduledEvent`]
+            The event on success.
+        """
+        data = await self._state.http.get_guild_event(guild_id=self.id, event_id=id, with_user_count=with_user_count)
+        if data:
+            event = GuildScheduledEvent(state=self._state, guild=self, data=data)
+            self._add_event(event)
+            return event
+
+    async def create_scheduled_event(
+            self,
+            name: str,
+            entity_type: EventEntityType,
+            start_time: datetime,
+            end_time: Optional[datetime] = None,
+            channel: Optional[Union[StageChannel, VoiceChannel]] = None,
+            description: Optional[str] = None,
+            location: Optional[str] = None,
+            cover_image: Optional[bytes] = None,
+            *,
+            reason: Optional[str] = None
+    ) -> GuildScheduledEvent:
+        """|coro|
+
+        Schedules a new Event in this guild. Requires ``MANAGE_EVENTS`` at least in the :attr:`channel`
+        or in the entire guild if :attr:`~GuildScheduledEvent.type` is :attr:`~EventType.external`.
+
+        Parameters
+        ----------
+        name: :class:`str`
+            The name of the scheduled event. 1-100 characters long.
+        entity_type: :class:`EventEntityType`
+            The entity_type of the scheduled event.
+
+            .. important::
+                :attr:`end_time` and :attr:`location` must be provided if entity_type is :class:`~EventEntityType.external`, otherwise :attr:`channel`
+
+        start_time: :class:`datetime.datetime`
+            The time when the event will start. Must be a valid date in the future.
+        end_time: Optional[:class:`datetime.datetime`]
+            The time when the event will end. Must be a valid date in the future.
+
+            .. important::
+                If :attr:`entity_type` is :class:`~EventEntityType.external` this must be provided.
+        channel: Optional[Union[:class:`StageChannel`, :class:`VoiceChannel`]]
+            The channel in which the event takes place.
+            Must be provided if :attr:`entity_type` is :class:`~EventEntityType.stage` or :class:`~EventEntityType.voice`.
+        description: Optional[:class:`str`]
+            The description of the scheduled event. 1-1000 characters long.
+        location: Optional[:class:`str`]
+            The location where the event will take place. 1-100 characters long.
+
+            .. important::
+                This must be provided if :attr:`~GuildScheduledEvent.entity_type` is :attr:`~EventEntityType.external`
+
+        cover_image: Optional[:class:`bytes`]
+            The cover image of the scheduled event.
+        reason: Optional[:class:`str`]
+            The reason for scheduling the event, shows up in the audit-log.
+
+        Returns
+        -------
+        :class:`~discord.GuildScheduledEvent`
+            The scheduled event on success.
+
+        Raises
+        ------
+        TypeError:
+            Any parameter is of wrong type.
+        errors.InvalidArgument:
+            entity_type is :attr:`~EventEntityType.stage` or :attr:`~EventEntityType.voice` but ``channel`` is not provided
+            or :attr:`~EventEntityType.external` but no ``location`` and/or ``end_time`` provided.
+        ValueError:
+            The value of any parameter is invalid. (e.g. to long/short)
+        errors.Forbidden:
+            You don't have permissions to schedule the event.
+        discord.HTTPException:
+            Scheduling the event failed.
+        """
+
+        fields: Dict[str, Any] = {}
+
+        if not isinstance(entity_type, EventEntityType):
+            entity_type = try_enum(EventEntityType, entity_type)
+            if not isinstance(entity_type, EventEntityType):
+                raise ValueError('entity_type must be a valid EventEntityType.')
+
+        if 1 > len(name) > 100:
+            raise ValueError(f'The length of the name must be between 1 and 100 characters long; got {len(name)}.')
+        fields['name'] = str(name)
+
+        if int(entity_type) == 3 and not location:
+            raise InvalidArgument('location must be provided if type is EventEntityType.external')
+        elif int(entity_type) != 3 and not channel:
+            raise InvalidArgument('channel must be provided if type is EventEntityType.stage or EventEntityType.voice.')
+
+        fields['entity_type'] = int(entity_type)
+
+        if channel is not None and not entity_type.external:
+            if not isinstance(channel, (VoiceChannel, StageChannel)):
+                raise TypeError(
+                    f'The channel must be a StageChannel or VoiceChannel object, not {channel.__class__.__name__}.'
+                    )
+            if int(entity_type) not in (1, 2):
+                entity_type = {StageChannel: EventEntityType.stage, VoiceChannel: EventEntityType.voice}.get(type(channel))
+                fields['entity_type'] = entity_type.value
+            fields['channel_id'] = str(channel.id)
+            fields['entity_metadata'] = None
+
+        if description is not None:
+            if 1 > len(description) > 1000:
+                raise ValueError(
+                    f'The length of the description must be between 1 and 1000 characters long; got {len(description)}.'
+                )
+            fields['description'] = description
+
+        if location is not None:
+            if 1 > len(location) > 100:
+                raise ValueError(
+                    f'The length of the location must be between 1 and 100 characters long; got {len(location)}.'
+                )
+            if not entity_type.external:
+                entity_type = EventEntityType.external
+                fields['entity_type'] = entity_type.value
+            fields['channel_id'] = None
+            fields['entity_metadata'] = {'location': location}
+
+        if entity_type.external and not end_time:
+            raise ValueError('end_time is required for external events.')
+
+        if not isinstance(start_time, datetime):
+            raise TypeError(f'The start_time must be a datetime.datetime object, not {start_time.__class__.__name__}.')
+        elif start_time < datetime.utcnow():
+            raise ValueError(f'The start_time could not be in the past.')
+
+        fields['scheduled_start_time'] = start_time.isoformat()
+
+        if end_time:
+            if not isinstance(end_time, datetime):
+                raise TypeError(f'The end_time must be a datetime.datetime object, not {end_time.__class__.__name__}.')
+            elif end_time < datetime.utcnow():
+                raise ValueError(f'The end_time could not be in the past.')
+
+            fields['scheduled_end_time'] = end_time.isoformat()
+
+        fields['privacy_level'] = 2
+
+        if cover_image:
+            if not isinstance(cover_image, bytes):
+                raise ValueError(f'cover_image must be of type bytes, not {cover_image.__class__.__name__}')
+            as_base64 = utils._bytes_to_base64_data(cover_image)
+            fields['image'] = as_base64
+
+        data = await self._state.http.create_guild_event(guild_id=self.id, fields=fields, reason=reason)
+        event = GuildScheduledEvent(state=self._state, guild=self, data=data)
+        self._add_event(event)
+        return event
+
+    async def _register_application_command(self, command):
+        client = self._state._get_client()
+        try:
+            client._guild_specific_application_commands[self.id]
+        except KeyError:
+            client._guild_specific_application_commands[self.id] = {
+                'chat_input': {},
+                'message': {},
+                'user': {}
+            }
+        client._guild_specific_application_commands[self.id][command.type.name][command.name] = command
+        data = command.to_dict()
+        command_data = await self._state.http.create_application_command(self._state._get_client().app.id, data=data,
+                                                                         guild_id=self.id
+                                                                         )
+        command._fill_data(command_data)
+        client._application_commands[command.id] = self._application_commands[command.id] = command
+        return command
+
+    async def add_slash_command(
+            self,
+            name: str,
+            name_localizations: Optional[Localizations] = Localizations(),
+            description: str = 'No description',
+            description_localizations: Optional[Localizations] = Localizations(),
+            is_nsfw: bool = False,
+            default_required_permissions: Optional['Permissions'] = None,
+            options: Optional[List[Union['SubCommandGroup', 'SubCommand', 'SlashCommandOption']]] = [],
+            connector: Optional[Dict[str, str]] = {},
+            func: Awaitable = default_callback,
+            cog: Optional[Cog] = None
+    ) -> SlashCommand:
+        command = SlashCommand(
+            name=name,
+            name_localizations=name_localizations,
+            description=description,
+            description_localizations=description_localizations,
+            is_nsfw=is_nsfw,
+            default_member_permissions=default_required_permissions,
+            options=options,
+            connector=connector,
+            func=func,
+            guild_id=self.id,
+            state=self._state,
+            cog=cog
+        )
+        return await self._register_application_command(command)
+
+    async def add_message_command(
+            self,
+            name: str,
+            name_localizations: Optional[Localizations] = Localizations(),
+            description: str = 'No description',
+            description_localizations: Optional[Localizations] = Localizations(),
+            is_nsfw: bool = False,
+            default_required_permissions: Optional[Permissions] = None,
+            func: Awaitable = default_callback,
+            cog: Optional[Cog] = None
+            ) -> MessageCommand:
+        command = MessageCommand(
+            name=name,
+            name_localizations=name_localizations,
+            description=description,
+            description_localizations=description_localizations,
+            is_nsfw=is_nsfw,
+            default_member_permissions=default_required_permissions,
+            func=func,
+            guild_id=self.id,
+            state=self._state,
+            cog=cog
+        )
+        return await self._register_application_command(command)
+
+    async def add_user_command(
+            self,
+            name: str,
+            name_localizations: Optional[Localizations] = Localizations(),
+            description: str = 'No description',
+            description_localizations: Optional[Localizations] = Localizations(),
+            is_nsfw: bool = False,
+            default_required_permissions: Optional[Permissions] = None,
+            func: Awaitable = default_callback,
+            cog: Optional[Cog] = None
+            ) -> UserCommand:
+        command = UserCommand(
+            name=name,
+            name_localizations=name_localizations,
+            description=description,
+            description_localizations=description_localizations,
+            is_nsfw=is_nsfw,
+            default_member_permissions=default_required_permissions,
+            func=func,
+            guild_id=self.id,
+            state=self._state,
+            cog=cog
+        )
+        return await self._register_application_command(command)
+
+    async def welcome_screen(self) -> Optional[WelcomeScreen]:
+        """|coro|
+
+        Fetches the welcome screen from the guild if any.
+
+        .. versionadded:: 2.0
+
+        Returns
+        --------
+        Optional[:class:`~discord.WelcomeScreen`]
+            The welcome screen of the guild if any.
+        """
+        data = await self._state.http.get_welcome_screen(self.id)
+        if data:
+            return WelcomeScreen(state=self._state, guild=self, data=data)
+
+    async def onboarding(self) -> Optional[Onboarding]:
+        """|coro|
+
+        Fetches the
+        `onboarding <https://support.discord.com/hc/en-us/articles/11074987197975-Community-Onboarding-FAQ>`_
+        configuration for the guild.
+
+        .. versionadded:: 2.0
+
+        Returns
+        --------
+        :class:`Onboarding`
+            The onboarding configuration fetched.
+        """
+        data = await self._state.http.get_guild_onboarding(self.id)
+        return Onboarding(data=data, state=self._state, guild=self)
+
+    async def edit_onboarding(
+        self,
+        *,
+        prompts: List[PartialOnboardingPrompt] = MISSING,
+        default_channels: List[Snowflake] = MISSING,
+        enabled: bool = MISSING,
+        mode: OnboardingMode = MISSING,
+        reason: Optional[str] = None
+    ) -> Onboarding:
+        """|coro|
+
+        Edits the onboarding configuration for the guild.
+
+        .. versionadded:: 2.0
+
+        Parameters
+        ----------
+        prompts: List[:class:`PartialOnboardingPrompt`]
+            The prompts that will be shown to new members
+            (if :attr:`~PartialOnboardingPrompt.is_onboarding` is ``True``, otherwise only in customise community).
+        default_channels: List[:class:`.Snowflake`]
+            The channels that will be added to new members' channel list by default.
+        enabled: :class:`bool`
+            Whether the onboarding configuration is enabled.
+        mode: :class:`OnboardingMode`
+            The mode that will be used for the onboarding configuration.
+        reason: Optional[:class:`str`]
+            The reason for editing the onboarding configuration. Shows up in the audit log.
+
+        Raises
+        -------
+        Forbidden
+            You do not have permissions to edit the onboarding configuration.
+        HTTPException
+            Editing the onboarding configuration failed.
+
+        Returns
+        --------
+        :class:`Onboarding`
+            The new onboarding configuration.
+        """
+        data = await self._state.http.edit_guild_onboarding(
+            self.id,
+            prompts=[p._to_dict() for p in prompts] if prompts is not MISSING else None,
+            default_channel_ids=[c.id for c in default_channels] if default_channels is not MISSING else None,
+            enabled=enabled if enabled is not MISSING else None,
+            mode=mode.value if mode is not MISSING else None,
+            reason=reason
+        )
+
+    async def automod_rules(self) -> List[AutoModRule]:
+        """|coro|
+
+        Fetches the Auto Moderation rules for this guild
+
+        .. warning::
+            This is an API-call, use it carefully.
+
+        Returns
+        --------
+        List[:class:`~discord.AutoModRule`]
+            A list of AutoMod rules the guild has
+        """
+        data = await self._state.http.get_automod_rules(guild_id=self.id)
+        for rule in data:
+            self._add_automod_rule(AutoModRule(state=self._state, guild=self, **rule))  # TODO: Advanced caching
+        return self.cached_automod_rules
+    
+    async def fetch_automod_rule(self, rule_id: int) -> AutoModRule:
+        """|coro|
+
+        Fetches a Auto Moderation rule for this guild by their ID
+
+        Raises
+        -------
+        Forbidden
+            You do not have permissions to fetch the rule.
+        HTTPException
+            Fetching the rule failed.
+
+        Returns
+        --------
+        :class:`~discord.AutoModRule`
+            The AutoMod rule
+        """
+        data = await self._state.http.get_automod_rule(self.id, rule_id)
+        rule = AutoModRule(state=self._state, guild=self, **data)
+        self._add_automod_rule(rule)
+        return rule
+
+    async def create_automod_rule(
+            self,
+            name: str,
+            event_type: AutoModEventType,
+            trigger_type: AutoModTriggerType,
+            trigger_metadata: AutoModTriggerMetadata,
+            actions: List[AutoModAction],
+            enabled: bool = True,
+            exempt_roles: List[Snowflake] = [],
+            exempt_channels: List[Snowflake] = [],
+            *,
+            reason: Optional[str] = None
+    ) -> AutoModRule:
+        """|coro|
+
+        Creates a new AutoMod rule for this guild
+
+        Parameters
+        -----------
+        name: :class:`str`
+            The name, the rule should have. Only valid if it's not a preset rule.
+        event_type: :class:`~discord.AutoModEventType`
+            Indicates in what event context a rule should be checked.
+        trigger_type: :class:`~discord.AutoModTriggerType`
+            Characterizes the type of content which can trigger the rule.
+        trigger_metadata: :class:`~discord.AutoModTriggerMetadata`
+            Additional data used to determine whether a rule should be triggered.
+            Different fields are relevant based on the value of :attr:`~AutoModRule.trigger_type`.
+        actions: List[:class:`~discord.AutoModAction`]
+            The actions which will execute when the rule is triggered.
+        enabled: :class:`bool`
+            Whether the rule is enabled, default :obj:`True`.
+        exempt_roles: List[:class:`.Snowflake`]
+            Up to 20 :class:`~discord.Role`'s, that should not be affected by the rule.
+        exempt_channels: List[:class:`.Snowflake`]
+            Up to 50 :class:`~discord.TextChannel`/:class:`~discord.VoiceChannel`'s, that should not be affected by the rule.
+        reason: Optional[:class:`str`]
+            The reason for creating the rule. Shows up in the audit log.
+
+        Raises
+        ------
+        :exc:`discord.Forbidden`
+            The bot is missing permissions to create AutoMod rules
+        :exc:`~discord.HTTPException`
+            Creating the rule failed
+
+        Returns
+        --------
+        :class:`~discord.AutoModRule`
+            The AutoMod rule created
+        """
+        data = {
+            'name': name,
+            'event_type': event_type if isinstance(event_type, int) else event_type.value,
+            'trigger_type': trigger_type if isinstance(trigger_type, int) else trigger_type.value,
+            'trigger_metadata': trigger_metadata.to_dict(),
+            'actions': [a.to_dict() for a in actions],
+            'enabled': enabled,
+            'exempt_roles': [str(r.id) for r in exempt_roles],  # type: ignore
+        }
+        for action in actions:  # Add the channels where messages should be logged to, to the exempted channels
+            if action.type.send_alert_message and action.channel_id not in exempt_channels:
+                exempt_channels.append(action.channel_id)
+        data['exempt_channels'] = [str(r.id) for r in exempt_channels]
+        rule_data = await self._state.http.create_automod_rule(guild_id=self.id, data=data, reason=reason)
+        rule = AutoModRule(state=self._state, guild=self, **rule_data)
+        self._add_automod_rule(rule)
+        return rule
+
+    async def edit_incidents_actions(
+            self,
+            *,
+            invites_disabled_until: Optional[datetime],
+            dms_disabled_until: Optional[datetime],
+            reason: Optional[str] = None
+    ) -> None:
+        """|coro|
+
+        Edits the incident actions of the guild.
+        This requires the :attr:`~Permissions.manage_guild` permission.
+
+        Parameters
+        ----------
+        invites_disabled_until: Optional[:class:`datetime.datetime`]
+            When invites should be possible again (up to 24h in the future).
+            Set to ``None`` to enable invites again.
+        dms_disabled_until: Optional[:class:`datetime.datetime`]
+            When direct messages should be enabled again (up to 24h in the future).
+            Set to ``None`` to enable direct messages again.
+        reason: Optional[:class:`str`]
+            The reason for editing the incident actions. Shows up in the audit log.
+
+        Raises
+        ------
+        Forbidden
+            You don't have permissions to edit the incident actions.
+        HTTPException
+            Editing the incident actions failed.
+        """
+
+        data = await self._state.http.edit_guild_incident_actions(
+            guild_id=self.id,
+            invites_disabled_until=invites_disabled_until.isoformat() if invites_disabled_until else None,
+            dms_disabled_until=dms_disabled_until.isoformat() if dms_disabled_until else None,
+            reason=reason
+        )
+
+
diff --git a/discord/http.py b/discord/http.py
index 531d79a7..ee23847a 100644
--- a/discord/http.py
+++ b/discord/http.py
@@ -3,9 +3,7 @@
 """
 The MIT License (MIT)
 
-Copyright (c) 2015-present Rapptz
-
-Implementing of the Discord-Message-components made by mccoderpy (Discord-User mccuber04#2960)
+Copyright (c) 2015-2021 Rapptz & (c) 2021-present mccoderpy
 
 Permission is hereby granted, free of charge, to any person obtaining a
 copy of this software and associated documentation files (the "Software"),
@@ -25,6 +23,20 @@
 FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 DEALINGS IN THE SOFTWARE.
 """
+from __future__ import annotations
+
+from typing import (
+    Any,
+    Coroutine,
+    Dict,
+    List,
+    Optional,
+    Sequence,
+    TYPE_CHECKING,
+    TypeVar,
+    Union,
+)
+from typing_extensions import Literal
 
 import asyncio
 import json
@@ -35,17 +47,41 @@
 
 import aiohttp
 
-from .errors import HTTPException, Forbidden, NotFound, LoginFailure, DiscordServerError, GatewayNotFound
+from .errors import HTTPException, Forbidden, NotFound, LoginFailure, DiscordServerError, GatewayNotFound, InvalidArgument
+from .file import File
+from .enums import Locale
 from .gateway import DiscordClientWebSocketResponse
+from .mentions import AllowedMentions
+from .components import ActionRow, Button, BaseSelect
 from . import __version__, utils
 
+
+if TYPE_CHECKING:
+    from .flags import MessageFlags
+    from enums import InteractionCallbackType
+    from .embeds import Embed
+    from .message import Attachment, MessageReference
+    from .types import (
+        guild,
+        monetization,
+    )
+    from .types.snowflake import SnowflakeID
+    from .utils import SnowflakeList
+
+    T = TypeVar('T')
+    Response = Coroutine[Any, Any, T]
+
+
+MISSING = utils.MISSING
+
+
 log = logging.getLogger(__name__)
 
 
 async def json_or_text(response):
     text = await response.text(encoding='utf-8')
     try:
-        if response.headers['content-type'] == 'application/json':
+        if 'application/json' in response.headers['content-type']:
             return json.loads(text)
     except KeyError:
         # Thanks Cloudflare
@@ -54,8 +90,299 @@ async def json_or_text(response):
     return text
 
 
+class MultipartParameters:
+    def __init__(
+            self,
+            payload: Optional[Dict[str, Any]] = None,
+            multipart: Optional[List[Dict[str, Any]]] = None,
+            files: Optional[Sequence[File]] = None
+    ):
+        self.payload: Optional[Dict[str, Any]] = payload
+        self.multipart: Optional[List[Dict[str, Any]]] = multipart
+        self.files: Optional[Sequence[File]] = files
+
+    def __enter__(self):
+        return self
+
+    def __exit__(self, exc_type, exc_val, exc_tb):
+        if self.files:
+            for file in self.files:
+                file.close()
+
+
+def handle_message_parameters(
+        content: Optional[str] = MISSING,
+        *,
+        username: str = MISSING,
+        avatar_url: Any = MISSING,
+        tts: bool = False,
+        nonce: Optional[Union[int, str]] = None,
+        flags: MessageFlags = MISSING,
+        file: Optional[File] = MISSING,
+        files: Sequence[File] = MISSING,
+        embed: Optional[Embed] = MISSING,
+        embeds: Sequence[Embed] = MISSING,
+        attachments: Sequence[Union[Attachment, File]] = MISSING,
+        components: List[Union[ActionRow, List[Union[Button, BaseSelect]]]] = MISSING,
+        allowed_mentions: Optional[AllowedMentions] = MISSING,
+        message_reference: Optional[MessageReference] = MISSING,
+        stickers: Optional[SnowflakeList] = MISSING,
+        previous_allowed_mentions: Optional[AllowedMentions] = None,
+        mention_author: Optional[bool] = None,
+        thread_name: str = MISSING,
+        channel_payload: Dict[str, Any] = MISSING
+) -> MultipartParameters:
+    """
+    Helper function to handle message parameters.
+    """
+    payload: Dict[str, Any] = {}
+
+    if embed is not MISSING or embeds is not MISSING:
+        _embeds = []
+        if embed not in {MISSING, None}:
+            _embeds.append(embed.to_dict())
+        if embeds is not MISSING and embeds is not None:
+            _embeds.extend([e.to_dict() for e in embeds])
+        if len(_embeds) > 10:
+            raise TypeError(f"Only can send up to 10 embeds per message; got {len(embeds)}")
+        payload['embeds'] = _embeds
+
+    if content is not MISSING:
+        if content is None:
+            payload['content'] = None
+        else:
+            payload['content'] = str(content)
+
+    if components is not MISSING:
+        if components is None:
+            payload['components'] = []
+        else:
+            _components = []
+            for component in (list(components) if not isinstance(components, list) else components):
+                if isinstance(component, (Button, BaseSelect)):
+                    _components.extend(ActionRow(component).to_dict())
+                elif isinstance(component, ActionRow):
+                    _components.extend(component.to_dict())
+                elif isinstance(component, list):
+                    _components.extend(
+                        ActionRow(*[obj for obj in component]).to_dict()
+                    )
+            if len(_components) > 5:
+                raise TypeError(f"Only can send up to 5 ActionRows per message; got {len(_components)}")
+            payload['components'] = _components
+
+    if nonce is not None:
+        payload['nonce'] = str(nonce)
+
+    if message_reference is not MISSING:
+        payload['message_reference'] = message_reference
+
+    if stickers is not MISSING:
+        if stickers is None:
+            payload['sticker_ids'] = []
+        else:
+            payload['sticker_ids'] = stickers
+
+    payload['tts'] = tts
+    if avatar_url:
+        payload['avatar_url'] = str(avatar_url)
+    if username:
+        payload['username'] = username
+
+    if flags is not MISSING:
+        payload['flags'] = flags.value
+
+    if thread_name is not MISSING:
+        payload['thread_name'] = thread_name
+
+    if allowed_mentions:
+        if previous_allowed_mentions is not None:
+            payload['allowed_mentions'] = previous_allowed_mentions.merge(allowed_mentions).to_dict()
+        else:
+            payload['allowed_mentions'] = allowed_mentions.to_dict()
+    elif previous_allowed_mentions is not None:
+        payload['allowed_mentions'] = previous_allowed_mentions.to_dict()
+
+    if mention_author is not None:
+        if 'allowed_mentions' not in payload:
+            payload['allowed_mentions'] = AllowedMentions().to_dict()
+        payload['allowed_mentions']['replied_user'] = mention_author
+
+    if file is not MISSING:
+        if files is not MISSING and files is not None:
+            files = [file, *files]
+        else:
+            files = [file]
+
+    if attachments is MISSING:
+        attachments = files
+    else:
+        files = [a for a in attachments if isinstance(a, File)]
+
+    if attachments is not MISSING:
+        file_index = 0
+        attachments_payload = []
+        for attachment in attachments:
+            if isinstance(attachment, File):
+                attachments_payload.append(attachment.to_dict(file_index))
+                file_index += 1
+            else:
+                attachments_payload.append(attachment.to_dict())  # type: ignore
+        payload['attachments'] = attachments_payload
+
+    if channel_payload is not MISSING:
+        payload = {
+            'message': payload,
+        }
+        payload.update(channel_payload)
+
+    multipart = []
+    if files:
+        multipart.append({'name': 'payload_json', 'value': utils.to_json(payload)})
+        payload = None
+        for index, file in enumerate(files):
+            multipart.append(
+                {
+                    'name': f'files[{index}]',
+                    'value': file.fp,
+                    'filename': file.filename,
+                    'content_type': 'application/octet-stream'
+                }
+            )
+
+    return MultipartParameters(payload=payload, multipart=multipart, files=files)
+
+
+def handle_interaction_message_parameters(
+        *,
+        type: InteractionCallbackType,
+        content: Optional[str] = MISSING,
+        tts: bool = False,
+        nonce: Optional[Union[int, str]] = None,
+        flags: MessageFlags = MISSING,
+        file: Optional[File] = MISSING,
+        files: Sequence[File] = MISSING,
+        embed: Optional[Embed] = MISSING,
+        embeds: Sequence[Embed] = MISSING,
+        attachments: Sequence[Union[Attachment, File]] = MISSING,
+        components: List[Union[ActionRow, List[Union[Button, BaseSelect]]]] = MISSING,
+        allowed_mentions: Optional[AllowedMentions] = MISSING,
+        message_reference: Optional[MessageReference] = MISSING,
+        stickers: Optional[SnowflakeList] = MISSING,
+        previous_allowed_mentions: Optional[AllowedMentions] = None,
+        mention_author: Optional[bool] = None
+) -> MultipartParameters:
+    """
+    Helper function to handle message parameters for interaction responses.
+    """
+    payload: Dict[str, Any] = {}
+
+    if embed is not MISSING or embeds is not MISSING:
+        _embeds = []
+        if embed not in {MISSING, None}:
+            _embeds.append(embed.to_dict())
+        if embeds is not MISSING and embeds is not None:
+            _embeds.extend([e.to_dict() for e in embeds])
+        if len(_embeds) > 10:
+            raise TypeError(f"Only can send up to 10 embeds per message; got {len(embeds)}")
+        payload['embeds'] = _embeds
+
+    if content is not MISSING:
+        if content is None:
+            payload['content'] = None
+        else:
+            payload['content'] = str(content)
+
+    if components is not MISSING:
+        if components is None:
+            payload['components'] = []
+        else:
+            _components = []
+            for component in ([components] if not isinstance(components, list) else components):
+                if isinstance(component, (Button, BaseSelect)):
+                    _components.extend(ActionRow(component).to_dict())
+                elif isinstance(component, ActionRow):
+                    _components.extend(component.to_dict())
+                elif isinstance(component, list):
+                    _components.extend(
+                        ActionRow(*[obj for obj in component]).to_dict()
+                    )
+            if len(_components) > 5:
+                raise TypeError(f"Only can send up to 5 ActionRows per message; got {len(_components)}")
+            payload['components'] = _components
+
+    if nonce is not None:
+        payload['nonce'] = str(nonce)
+
+    if message_reference is not MISSING:
+        payload['message_reference'] = message_reference.to_message_reference_dict()
+
+    if stickers is not MISSING:
+        if stickers is None:
+            payload['sticker_ids'] = []
+        else:
+            payload['sticker_ids'] = stickers
+
+    payload['tts'] = tts
+
+    if flags is not MISSING:
+        payload['flags'] = flags.value
+
+    if allowed_mentions:
+        if previous_allowed_mentions is not None:
+            payload['allowed_mentions'] = previous_allowed_mentions.merge(allowed_mentions).to_dict()
+        else:
+            payload['allowed_mentions'] = allowed_mentions.to_dict()
+    elif previous_allowed_mentions is not None:
+        payload['allowed_mentions'] = previous_allowed_mentions.to_dict()
+
+    if mention_author is not None:
+        if 'allowed_mentions' not in payload:
+            payload['allowed_mentions'] = AllowedMentions().to_dict()
+        payload['allowed_mentions']['replied_user'] = mention_author
+
+    if file is not MISSING:
+        if files is not MISSING and files is not None:
+            files = [file, *files]
+        else:
+            files = [file]
+
+    if attachments is MISSING:
+        attachments = files
+    else:
+        files = [a for a in attachments if isinstance(a, File)]
+
+    if attachments is not MISSING:
+        file_index = 0
+        attachments_payload = []
+        for attachment in attachments:
+            if isinstance(attachment, File):
+                attachments_payload.append(attachment.to_dict(file_index))
+                file_index += 1
+            else:
+                attachments_payload.append(attachment.to_dict())  # type: ignore
+        payload['attachments'] = attachments_payload
+
+    multipart = []
+    payload = {'type': int(type), 'data': payload}
+    if files:
+        multipart.append({'name': 'payload_json', 'value': utils.to_json(payload)})
+        payload = None
+        for index, file in enumerate(files):
+            multipart.append(
+                {
+                    'name': f'files[{index}]',
+                    'value': file.fp,
+                    'filename': file.filename,
+                    'content_type': 'application/octet-stream'
+                }
+            )
+
+    return MultipartParameters(payload=payload, multipart=multipart, files=files)
+
+
 class Route:
-    BASE = 'https://discord.com/api/v9'
+    BASE = 'https://discord.com/api/v10'
 
     def __init__(self, method, path, **parameters):
         self.path = path
@@ -91,10 +418,10 @@ def __exit__(self, type, value, traceback):
         if self._unlock:
             self.lock.release()
 
+
 # For some reason, the Discord voice websocket expects this header to be
 # completely lowercase while aiohttp respects spec and does it as case-insensitive
 
-
 aiohttp.hdrs.WEBSOCKET = 'websocket'
 
 
@@ -104,25 +431,40 @@ class HTTPClient:
     SUCCESS_LOG = '{method} {url} has received {text}'
     REQUEST_LOG = '{method} {url} with {json} has returned {status}'
 
-    def __init__(self, connector=None, *, proxy=None, proxy_auth=None, loop=None, unsync_clock=True):
+    def __init__(
+            self,
+            connector=None,
+            *,
+            proxy: Optional[str] = None,
+            proxy_auth: Optional[aiohttp.BasicAuth] = None,
+            loop: Optional[asyncio.AbstractEventLoop] = None,
+            unsync_clock: bool = True,
+            api_version: int = 10,
+            api_error_locale: Optional[Locale] = 'en-US'
+    ):
         self.loop = asyncio.get_event_loop() if loop is None else loop
         self.connector = connector
-        self.__session = None  # filled in static_login
+        self.__session: aiohttp.ClientSession = None  # filled in static_login
         self._locks = weakref.WeakValueDictionary()
         self._global_over = asyncio.Event()
         self._global_over.set()
         self.token = None
-        self.bot_token = False
         self.proxy = proxy
         self.proxy_auth = proxy_auth
         self.use_clock = not unsync_clock
+        self.api_version = api_version
+        self.api_error_locale = str(api_error_locale)
+        Route.BASE = f'https://discord.com/api/v{api_version}'
 
-        user_agent = 'DiscordBot (https://github.com/Rapptz/discord.py {0}) Python/{1[0]}.{1[1]} aiohttp/{2}'
+        user_agent = 'DiscordBot (https://github.com/mccoderpy/discord.py-message-components {0}) Python/{1[0]}.{1[1]} aiohttp/{2}'
         self.user_agent = user_agent.format(__version__, sys.version_info, aiohttp.__version__)
 
     def recreate(self):
         if self.__session.closed:
-            self.__session = aiohttp.ClientSession(connector=self.connector, ws_response_class=DiscordClientWebSocketResponse)
+            self.__session = aiohttp.ClientSession(
+                connector=self.connector,
+                ws_response_class=DiscordClientWebSocketResponse
+            )
 
     async def ws_connect(self, url, *, compress=0):
         kwargs = {
@@ -133,10 +475,10 @@ async def ws_connect(self, url, *, compress=0):
             'autoclose': False,
             'headers': {
                 'User-Agent': self.user_agent,
+                'X-Discord-Locale': self.api_error_locale
             },
             'compress': compress
         }
-
         return await self.__session.ws_connect(url, **kwargs)
 
     async def request(self, route, *, files=None, form=None, **kwargs):
@@ -151,18 +493,22 @@ async def request(self, route, *, files=None, form=None, **kwargs):
                 self._locks[bucket] = lock
 
         # header creation
-        headers = {
+        headers = kwargs.get('headers', {})
+        headers.update({
             'User-Agent': self.user_agent,
-            'X-Ratelimit-Precision': 'millisecond',
-        }
+            'X-Discord-Locale': self.api_error_locale
+        })
 
         if self.token is not None:
-            headers['Authorization'] = 'Bot ' + self.token if self.bot_token else self.token
+            headers['Authorization'] = 'Bot ' + self.token
         # some checking if it's a JSON request
         if 'json' in kwargs:
             headers['Content-Type'] = 'application/json'
             kwargs['data'] = utils.to_json(kwargs.pop('json'))
 
+        if 'content_type' in kwargs:
+            headers['Content-Type'] = kwargs.pop('content_type')
+
         try:
             reason = kwargs.pop('reason')
         except KeyError:
@@ -191,7 +537,7 @@ async def request(self, route, *, files=None, form=None, **kwargs):
                         f.reset(seek=tries)
 
                 if form:
-                    form_data = aiohttp.FormData()
+                    form_data = aiohttp.FormData(quote_fields=False)
                     for params in form:
                         form_data.add_field(**params)
                     kwargs['data'] = form_data
@@ -226,7 +572,7 @@ async def request(self, route, *, files=None, form=None, **kwargs):
                             fmt = 'We are being rate limited. Retrying in %.2f seconds. Handled under the bucket "%s"'
 
                             # sleep a bit
-                            retry_after = data['retry_after'] / 1000.0
+                            retry_after = data['retry_after']
                             log.warning(fmt, retry_after, bucket)
 
                             # check if it's a global rate limit
@@ -290,24 +636,24 @@ async def get_from_cdn(self, url):
     async def close(self):
         if self.__session:
             await self.__session.close()
+            await asyncio.sleep(0.025)  # wait for the connection to be released
 
-    def _token(self, token, *, bot=True):
+    def _token(self, token):
         self.token = token
-        self.bot_token = bot
         self._ack_token = None
 
     # login management
 
-    async def static_login(self, token, *, bot):
-        # Necessary to get aiohttp to stop complaining about session creation
+    async def static_login(self, token):
+        # Necessary to get aiohttp to stop complaining about _session creation
         self.__session = aiohttp.ClientSession(connector=self.connector, ws_response_class=DiscordClientWebSocketResponse)
-        old_token, old_bot = self.token, self.bot_token
-        self._token(token, bot=bot)
+        old_token = self.token
+        self._token(token)
 
         try:
             data = await self.request(Route('GET', '/users/@me'))
         except HTTPException as exc:
-            self._token(old_token, bot=old_bot)
+            self._token(old_token)
             if exc.response.status == 401:
                 raise LoginFailure('Improper token has been passed.') from exc
             raise
@@ -357,84 +703,27 @@ def start_private_message(self, user_id):
 
         return self.request(Route('POST', '/users/@me/channels'), json=payload)
 
-    def send_message(self, channel_id, content, *, tts=False, embeds=None, components=None, nonce=None, allowed_mentions=None, message_reference=None):
+    def send_message(self, channel_id, *, params: MultipartParameters):
         r = Route('POST', '/channels/{channel_id}/messages', channel_id=channel_id)
-        payload = {}
-
-        if content:
-            payload['content'] = content
-
-        if tts:
-            payload['tts'] = True
-
-        if embeds:
-            payload['embeds'] = embeds
-
-        if components:
-            payload['components'] = components
-
-        if nonce:
-            payload['nonce'] = nonce
-
-        if allowed_mentions:
-            payload['allowed_mentions'] = allowed_mentions
-
-        if message_reference:
-            payload['message_reference'] = message_reference
-
-        return self.request(r, json=payload)
-
+        if params.files:
+            return self.request(r, files=params.files, form=params.multipart)
+        else:
+            return self.request(r, json=params.payload)
+    
+    def send_voice_message(self, channel_id, *, params: MultipartParameters, x_super_properties: str):
+        r = Route('POST', '/channels/{channel_id}/messages', channel_id=channel_id)
+        return self.request(r, files=params.files, form=params.multipart, headers={'x-super-properties': x_super_properties})
+    
     def send_typing(self, channel_id):
         return self.request(Route('POST', '/channels/{channel_id}/typing', channel_id=channel_id))
 
-    def send_files(self, channel_id, *, files, content=None, tts=False, embeds=None, components=None, nonce=None, allowed_mentions=None, message_reference=None):
-        r = Route('POST', '/channels/{channel_id}/messages', channel_id=channel_id)
-        form = []
-
-        payload = {'tts': tts}
-        if content:
-            payload['content'] = content
-        if embeds:
-            payload['embeds'] = embeds
-        if components:
-            payload['components'] = components
-        if nonce:
-            payload['nonce'] = nonce
-        if allowed_mentions:
-            payload['allowed_mentions'] = allowed_mentions
-        if message_reference:
-            payload['message_reference'] = message_reference
-
-        form.append({'name': 'payload_json', 'value': utils.to_json(payload)})
-        if len(files) == 1:
-            file = files[0]
-            form.append({
-                'name': 'file',
-                'value': file.fp,
-                'filename': file.filename,
-                'content_type': 'application/octet-stream'
-            })
-        else:
-            for index, file in enumerate(files):
-                form.append({
-                    'name': 'file%s' % index,
-                    'value': file.fp,
-                    'filename': file.filename,
-                    'content_type': 'application/octet-stream'
-                })
-
-        return self.request(r, form=form, files=files)
-
-    async def ack_message(self, channel_id, message_id):
-        r = Route('POST', '/channels/{channel_id}/messages/{message_id}/ack', channel_id=channel_id, message_id=message_id)
-        data = await self.request(r, json={'token': self._ack_token})
-        self._ack_token = data['token']
-
-    def ack_guild(self, guild_id):
-        return self.request(Route('POST', '/guilds/{guild_id}/ack', guild_id=guild_id))
-
     def delete_message(self, channel_id, message_id, *, reason=None):
-        r = Route('DELETE', '/channels/{channel_id}/messages/{message_id}', channel_id=channel_id, message_id=message_id)
+        r = Route(
+            'DELETE',
+            '/channels/{channel_id}/messages/{message_id}',
+            channel_id=channel_id,
+             message_id=message_id
+        )
         return self.request(r, reason=reason)
 
     def delete_messages(self, channel_id, message_ids, *, reason=None):
@@ -444,129 +733,78 @@ def delete_messages(self, channel_id, message_ids, *, reason=None):
         }
         return self.request(r, json=payload, reason=reason)
 
-    def edit_message(self, channel_id, message_id, **fields):
+    def edit_message(self, channel_id, message_id, *, params: MultipartParameters):
         r = Route('PATCH', '/channels/{channel_id}/messages/{message_id}', channel_id=channel_id, message_id=message_id)
-        return self.request(r, json=fields)
-
-    def post_initial_response(self, use_webhook, _resp, interaction_id, token, application_id):
-        r_url = f"/webhooks/{application_id}/{token}/callback" if use_webhook is True else f"/interactions/{interaction_id}/{token}/callback"
-        r = Route("POST", r_url)
-        return self.request(r, json=_resp)
-
-    def edit_interaction_response(self, use_webhook, interaction_id, token, application_id, deferred, files=None, **fields):
-        if not deferred:
-            fields = {'data': fields, 'type': 7}
-            r = Route('POST', f'/webhooks/{application_id}/{token}/callback' if use_webhook is True else f"/interactions/{interaction_id}/{token}/callback")
-        else:
-            r = Route('PATCH', f'/webhooks/{application_id}/{token}/messages/@original')
-        form = []
-        if files is not None:
-            form.append({'name': 'payload_json', 'value': utils.to_json(fields)})
-            if len(files) == 1:
-                file = files[0]
-                form.append({
-                    'name': 'file',
-                    'value': file.fp,
-                    'filename': file.filename,
-                    'content_type': 'application/octet-stream'
-                })
-            else:
-                for index, file in enumerate(files):
-                    form.append({
-                        'name': 'file%s' % index,
-                        'value': file.fp,
-                        'filename': file.filename,
-                        'content_type': 'application/octet-stream'
-                    })
-
-            return self.request(r, form=form, files=files)
+        if params.files:
+            return self.request(r, files=params.files, form=params.multipart)
         else:
-            return self.request(r, json=fields)
-
-    def send_interaction_response(self, use_webhook, interaction_id, token, application_id, deferred, followup,
-                                  *, content=None, tts=False, embeds=None, components=None, files=None, nonce=None,
-                                  allowed_mentions=None, message_reference=None, flags=None):
-        form = []
-        payload = {'tts': tts}
-        if content:
-            payload['content'] = content
-        if embeds:
-            payload['embeds'] = embeds
-        if components:
-            payload['components'] = components
-        if nonce:
-            payload['nonce'] = nonce
-        if allowed_mentions:
-            payload['allowed_mentions'] = allowed_mentions
-        if message_reference:
-            payload['message_reference'] = message_reference
-        if flags:
-            payload['flags'] = flags
-        if not deferred and not followup:
-            payload = {'type': 4, 'data': payload}
-            r = Route('POST', f'/webhooks/{application_id}/{token}/callback' if use_webhook is True else f"/interactions/{interaction_id}/{token}/callback")
-        else:
-            r = Route('POST', f'/webhooks/{application_id}/{token}')
-        if files is not None:
-            form.append({'name': 'payload_json', 'value': utils.to_json(payload)})
-            if len(files) == 1:
-                file = files[0]
-                form.append({
-                    'name': 'file',
-                    'value': file.fp,
-                    'filename': file.filename,
-                    'content_type': 'application/octet-stream'
-                })
-            else:
-                for index, file in enumerate(files):
-                    form.append({
-                        'name': 'file%s' % index,
-                        'value': file.fp,
-                        'filename': file.filename,
-                        'content_type': 'application/octet-stream'
-                    })
-
-            return self.request(r, form=form, files=files)
-        else:
-            return self.request(r, json=payload)
+            return self.request(r, json=params.payload)
 
-    def get_original_interaction_response(self, interaction_token, application_id):
-        r = Route('GET', f'/webhooks/{application_id}/{interaction_token}/messages/@original')
-        return self.request(r)
-        
     def add_reaction(self, channel_id, message_id, emoji):
-        r = Route('PUT', '/channels/{channel_id}/messages/{message_id}/reactions/{emoji}/@me',
-                  channel_id=channel_id, message_id=message_id, emoji=emoji)
+        r = Route(
+            'PUT',
+            '/channels/{channel_id}/messages/{message_id}/reactions/{emoji}/@me',
+            channel_id=channel_id,
+            message_id=message_id,
+            emoji=emoji
+        )
         return self.request(r)
 
     def remove_reaction(self, channel_id, message_id, emoji, member_id):
-        r = Route('DELETE', '/channels/{channel_id}/messages/{message_id}/reactions/{emoji}/{member_id}',
-                  channel_id=channel_id, message_id=message_id, member_id=member_id, emoji=emoji)
+        r = Route(
+            'DELETE',
+            '/channels/{channel_id}/messages/{message_id}/reactions/{emoji}/{member_id}',
+            channel_id=channel_id,
+            message_id=message_id,
+            member_id=member_id,
+            emoji=emoji
+        )
         return self.request(r)
 
     def remove_own_reaction(self, channel_id, message_id, emoji):
-        r = Route('DELETE', '/channels/{channel_id}/messages/{message_id}/reactions/{emoji}/@me',
-                  channel_id=channel_id, message_id=message_id, emoji=emoji)
+        r = Route(
+            'DELETE',
+            '/channels/{channel_id}/messages/{message_id}/reactions/{emoji}/@me',
+            channel_id=channel_id,
+            message_id=message_id,
+            emoji=emoji
+        )
         return self.request(r)
 
-    def get_reaction_users(self, channel_id, message_id, emoji, limit, after=None):
-        r = Route('GET', '/channels/{channel_id}/messages/{message_id}/reactions/{emoji}',
-                  channel_id=channel_id, message_id=message_id, emoji=emoji)
+    def get_reaction_users(self, channel_id, message_id, emoji, limit, reaction_type, after=None):
+        r = Route(
+            'GET',
+            '/channels/{channel_id}/messages/{message_id}/reactions/{emoji}',
+            channel_id=channel_id,
+            message_id=message_id,
+            emoji=emoji
+        )
 
         params = {'limit': limit}
         if after:
             params['after'] = after
+        if reaction_type != 0:
+            params['type'] = type
         return self.request(r, params=params)
 
     def clear_reactions(self, channel_id, message_id):
-        r = Route('DELETE', '/channels/{channel_id}/messages/{message_id}/reactions',
-                  channel_id=channel_id, message_id=message_id)
+        r = Route(
+            'DELETE',
+            '/channels/{channel_id}/messages/{message_id}/reactions',
+            channel_id=channel_id,
+            message_id=message_id
+        )
 
         return self.request(r)
 
     def clear_single_reaction(self, channel_id, message_id, emoji):
-        r = Route('DELETE', '/channels/{channel_id}/messages/{message_id}/reactions/{emoji}',
-                  channel_id=channel_id, message_id=message_id, emoji=emoji)
+        r = Route(
+            'DELETE',
+            '/channels/{channel_id}/messages/{message_id}/reactions/{emoji}',
+            channel_id=channel_id,
+            message_id=message_id,
+            emoji=emoji
+        )
         return self.request(r)
 
     def get_message(self, channel_id, message_id):
@@ -588,46 +826,158 @@ def logs_from(self, channel_id, limit, before=None, after=None, around=None):
             params['after'] = after
         if around is not None:
             params['around'] = around
-
         return self.request(Route('GET', '/channels/{channel_id}/messages', channel_id=channel_id), params=params)
 
     def publish_message(self, channel_id, message_id):
-        return self.request(Route('POST', '/channels/{channel_id}/messages/{message_id}/crosspost',
-                                  channel_id=channel_id, message_id=message_id))
+        return self.request(
+            Route(
+                'POST',
+                '/channels/{channel_id}/messages/{message_id}/crosspost',
+                channel_id=channel_id,
+                message_id=message_id
+            )
+        )
 
     def pin_message(self, channel_id, message_id, reason=None):
-        return self.request(Route('PUT', '/channels/{channel_id}/pins/{message_id}',
-                                  channel_id=channel_id, message_id=message_id), reason=reason)
+        return self.request(
+            Route(
+                'PUT',
+                '/channels/{channel_id}/pins/{message_id}',
+                channel_id=channel_id,
+                message_id=message_id
+            ),
+            reason=reason
+        )
 
     def unpin_message(self, channel_id, message_id, reason=None):
-        return self.request(Route('DELETE', '/channels/{channel_id}/pins/{message_id}',
-                                  channel_id=channel_id, message_id=message_id), reason=reason)
+        return self.request(
+            Route(
+                'DELETE',
+                '/channels/{channel_id}/pins/{message_id}',
+                channel_id=channel_id,
+                message_id=message_id
+            ),
+            reason=reason
+        )
 
     def pins_from(self, channel_id):
         return self.request(Route('GET', '/channels/{channel_id}/pins', channel_id=channel_id))
 
-    # Member management
+    # Thread management
+    def create_thread(
+            self,
+            channel_id: int,
+            *,
+            payload: Dict[str, Any],
+            message_id: Optional[int] = None,
+            reason=None
+        ):
+        if message_id:
+            r = Route(
+                'POST',
+                '/channels/{channel_id}/messages/{message_id}/threads',
+                channel_id=channel_id,
+                message_id=message_id
+            )
+        else:
+            r = Route('POST', '/channels/{channel_id}/threads', channel_id=channel_id)
+        return self.request(r, json=payload, reason=reason)
 
-    def kick(self, user_id, guild_id, reason=None):
-        r = Route('DELETE', '/guilds/{guild_id}/members/{user_id}', guild_id=guild_id, user_id=user_id)
-        if reason:
-            # thanks aiohttp
-            r.url = '{0.url}?reason={1}'.format(r, _uriquote(reason))
+    def create_forum_post(self, channel_id, *, params: MultipartParameters, reason: Optional[str] = None):
+        r = Route('POST', '/channels/{channel_id}/threads', channel_id=channel_id)
+        query_params = {'use_nested_fields': True}
+        if params.files:
+            return self.request(r, files=params.files, form=params.multipart, params=query_params, reason=reason)
+        else:
+            return self.request(r, json=params.payload, params=query_params, reason=reason)
+
+    def add_thread_member(self, channel_id, member_id='@me'):
+        r = Route(
+            'PUT',
+            '/channels/{channel_id}/thread-members/{member_id}',
+            channel_id=channel_id,
+            member_id=member_id
+        )
+        return self.request(r)
 
+    def remove_thread_member(self, channel_id, member_id='@me'):
+        r = Route(
+            'DELETE',
+            '/channels/{channel_id}/thread-members/{member_id}',
+            channel_id=channel_id,
+            member_id=member_id
+        )
         return self.request(r)
 
-    def ban(self, user_id, guild_id, delete_message_days=1, reason=None):
-        r = Route('PUT', '/guilds/{guild_id}/bans/{user_id}', guild_id=guild_id, user_id=user_id)
-        params = {
-            'delete_message_days': delete_message_days,
+    def list_thread_members(
+            self,
+            channel_id: int,
+            with_member: bool = False,
+            *,
+            limit: int = 100,
+            after: Optional[int] = None
+    ):
+        query_params = {
+            'with_member': with_member,
+            'limit': limit
         }
+        if after:
+            query_params['after'] = after
+        return self.request(
+            Route('GET', '/channels/{channel_id}/thread-members', channel_id=channel_id),
+            params=query_params
+        )
 
-        if reason:
-            # thanks aiohttp
-            r.url = '{0.url}?reason={1}'.format(r, _uriquote(reason))
+    def list_active_threads(self, guild_id: int):
+        return self.request(
+            Route('GET', '/guilds/{guild_id}/threads/active', guild_id=guild_id),
+        )
 
+    def list_archived_threads(
+            self,
+            channel_id: int,
+            type: Literal['private', 'public'],
+            joined_private: bool = False,
+            *,
+            before: Optional[int] = None,
+            limit: int = 100
+    ):
+        if type not in ('public', 'private'):
+            raise ValueError('type must be public or private, not %s' % type)
+        if joined_private:
+            r = Route(
+                'GET',
+                '/channels/{channel_id}/users/@me/threads/archived/private', channel_id=channel_id
+            )
+        else:
+            r = Route(
+                'GET',
+                '/channels/{channel_id}/threads/archived/{type}', channel_id=channel_id, type=type
+            )
+        params = {'limit': limit}
+        if before:
+            params['before'] = before
         return self.request(r, params=params)
 
+    def create_post(self, channel_id: int, params: MultipartParameters, reason: Optional[str] = None):
+        r = Route('POST', '/channels/{channel_id}/threads', channel_id=channel_id)
+        if params.files:
+            return self.request(r, files=params.files, form=params.multipart)
+        else:
+            return self.request(r, json=params.payload, reason=reason)
+
+    # Member management
+    def kick(self, user_id, guild_id, reason=None):
+        r = Route('DELETE', '/guilds/{guild_id}/members/{user_id}', guild_id=guild_id, user_id=user_id)
+        return self.request(r, reason=reason)
+
+    def ban(self, user_id, guild_id, delete_message_seconds, *, reason=None):
+        r = Route('PUT', '/guilds/{guild_id}/bans/{user_id}', guild_id=guild_id, user_id=user_id)
+        params = {
+            'delete_message_seconds': delete_message_seconds
+        }
+        return self.request(r, params=params, reason=reason)
+
     def unban(self, user_id, guild_id, *, reason=None):
         r = Route('DELETE', '/guilds/{guild_id}/bans/{user_id}', guild_id=guild_id, user_id=user_id)
         return self.request(r, reason=reason)
@@ -643,19 +993,7 @@ def guild_voice_state(self, user_id, guild_id, *, mute=None, deafen=None, reason
 
         return self.request(r, json=payload, reason=reason)
 
-    def edit_profile(self, password, username, avatar, **fields):
-        payload = {
-            'password': password,
-            'username': username,
-            'avatar': avatar
-        }
-
-        if 'email' in fields:
-            payload['email'] = fields['email']
-
-        if 'new_password' in fields:
-            payload['new_password'] = fields['new_password']
-
+    def edit_profile(self, payload):
         return self.request(Route('PATCH', '/users/@me'), json=payload)
 
     def change_my_nickname(self, guild_id, nickname, *, reason=None):
@@ -688,9 +1026,32 @@ def edit_member(self, guild_id, user_id, *, reason=None, **fields):
 
     def edit_channel(self, channel_id, *, reason=None, **options):
         r = Route('PATCH', '/channels/{channel_id}', channel_id=channel_id)
-        valid_keys = ('name', 'parent_id', 'topic', 'bitrate', 'nsfw',
-                      'user_limit', 'position', 'permission_overwrites', 'rate_limit_per_user',
-                      'type', 'rtc_region')
+        valid_keys = (
+            'name',
+            'parent_id',
+            'topic',
+            'template',
+            'icon_emoji',
+            'bitrate',
+            'nsfw',
+            'flags',
+            'auto_archive_duration',
+            'default_auto_archive_duration',
+            'user_limit',
+            'position',
+            'permission_overwrites',
+            'rate_limit_per_user',
+            'default_reaction_emoji',
+            'default_thread_rate_limit_per_user',
+            'default_forum_layout',
+            'default_sort_order',
+            'available_tags',
+            'applied_tags',
+            'locked',
+            'archived',
+            'type',
+            'rtc_region',
+        )
         payload = {
             k: v for k, v in options.items() if k in valid_keys
         }
@@ -704,19 +1065,94 @@ def create_channel(self, guild_id, channel_type, *, reason=None, **options):
         payload = {
             'type': channel_type
         }
+        valid_keys = (
+            'name',
+            'parent_id',
+            'topic',
+            'template',
+            'icon_emoji',
+            'bitrate',
+            'nsfw',
+            'flags',
+            'default_auto_archive_duration',
+            'user_limit',
+            'position',
+            'permission_overwrites',
+            'rate_limit_per_user',
+            'default_reaction_emoji',
+            'default_thread_rate_limit_per_user',
+            'default_forum_layout',
+            'default_sort_order',
+            'available_tags',
+            'rtc_region',
+        )
+        payload.update(
+            {
+                k: v for k, v in options.items() if k in valid_keys and v is not None
+            }
+        )
 
-        valid_keys = ('name', 'parent_id', 'topic', 'bitrate', 'nsfw',
-                      'user_limit', 'position', 'permission_overwrites', 'rate_limit_per_user',
-                      'rtc_region')
-        payload.update({
-            k: v for k, v in options.items() if k in valid_keys and v is not None
-        })
-
-        return self.request(Route('POST', '/guilds/{guild_id}/channels', guild_id=guild_id), json=payload, reason=reason)
+        return self.request(
+            Route(
+                'POST',
+                '/guilds/{guild_id}/channels',
+                guild_id=guild_id
+            ),
+            json=payload,
+            reason=reason
+        )
 
     def delete_channel(self, channel_id, *, reason=None):
         return self.request(Route('DELETE', '/channels/{channel_id}', channel_id=channel_id), reason=reason)
 
+    # Stage instance management
+
+    def create_stage_instance(
+            self,
+            channel_id,
+            topic,
+            privacy_level,
+            send_start_notification,
+            *,
+            reason: Optional[str] = None
+    ):
+        payload = {
+            'channel_id': channel_id,
+            'topic': topic,
+            'privacy_level': privacy_level.value,
+            'send_start_notification': send_start_notification,
+
+        }
+        return self.request(Route('POST', '/stage-instances'), json=payload, reason=reason)
+
+    def get_stage_instance(self, channel_id):
+        return self.request(Route('GET', '/stage-instances/{channel_id}', channel_id=channel_id))
+
+    def edit_stage_instance(self, channel_id, topic, privacy_level=None, *, reason=None):
+        r = Route('PATCH', '/stage-instances/{channel_id}', channel_id=channel_id)
+        payload = {
+            'topic': topic
+        }
+        if privacy_level is not None:
+            payload['privacy_level'] = privacy_level.value
+        return self.request(r, json=payload, reason=reason)
+
+    def delete_stage_instance(self, channel_id, *, reason=None):
+        return self.request(Route('DELETE', '/stage-instances/{channel_id}', channel_id=channel_id), reason=reason)
+
+    # TODO: Add/remove this when we got a statement from Discord why bots can't set the channel status
+    # def set_voice_channel_status(
+    #         self,
+    #         channel_id: int,
+    #         status: Optional[str],
+    #         reason: Optional[str] = None
+    # ):
+    #     return self.request(
+    #         Route('PUT', '/channels/{channel_id}/voice-status', channel_id=channel_id),
+    #         json={'status': status},
+    #         reason=reason
+    #     )
+
     # Webhook management
 
     def create_webhook(self, channel_id, *, name, avatar=None, reason=None):
@@ -742,7 +1178,15 @@ def follow_webhook(self, channel_id, webhook_channel_id, reason=None):
         payload = {
             'webhook_channel_id': str(webhook_channel_id)
         }
-        return self.request(Route('POST', '/channels/{channel_id}/followers', channel_id=channel_id), json=payload, reason=reason)
+        return self.request(
+            Route(
+                'POST',
+                '/channels/{channel_id}/followers',
+                channel_id=channel_id
+            ),
+            json=payload,
+            reason=reason
+        )
 
     # Guild management
 
@@ -777,18 +1221,18 @@ def create_guild(self, name, region, icon):
         return self.request(Route('POST', '/guilds'), json=payload)
 
     def edit_guild(self, guild_id, *, reason=None, **fields):
-        valid_keys = ('name', 'region', 'icon', 'afk_timeout', 'owner_id',
-                      'afk_channel_id', 'splash', 'verification_level',
-                      'system_channel_id', 'default_message_notifications',
-                      'description', 'explicit_content_filter', 'banner',
-                      'system_channel_flags', 'rules_channel_id',
-                      'public_updates_channel_id', 'preferred_locale',)
+        return self.request(Route('PATCH', '/guilds/{guild_id}', guild_id=guild_id), json=fields, reason=reason)
 
-        payload = {
-            k: v for k, v in fields.items() if k in valid_keys
-        }
+    def edit_guild_incident_actions(self, guild_id, *, reason=None, **fields):
+        r = Route('PUT', '/guilds/{guild_id}/incident-actions', guild_id=guild_id)
+        return self.request(r, json=fields, reason=reason)
+
+    def get_welcome_screen(self, guild_id):
+        return self.request(Route('GET', '/guilds/{guild_id}/welcome-screen', guild_id=guild_id))
 
-        return self.request(Route('PATCH', '/guilds/{guild_id}', guild_id=guild_id), json=payload, reason=reason)
+    def edit_welcome_screen(self, guild_id, reason, **fields):
+        r = Route('PATCH', '/guilds/{guild_id}/welcome-screen', guild_id=guild_id)
+        return self.request(r, json=fields, reason=reason)
 
     def get_template(self, code):
         return self.request(Route('GET', '/guilds/templates/{code}', code=code))
@@ -810,7 +1254,15 @@ def edit_template(self, guild_id, code, payload):
         payload = {
             k: v for k, v in payload.items() if k in valid_keys
         }
-        return self.request(Route('PATCH', '/guilds/{guild_id}/templates/{code}', guild_id=guild_id, code=code), json=payload)
+        return self.request(
+            Route(
+                'PATCH',
+                '/guilds/{guild_id}/templates/{code}',
+                guild_id=guild_id,
+                code=code
+            ),
+            json=payload
+        )
 
     def delete_template(self, guild_id, code):
         return self.request(Route('DELETE', '/guilds/{guild_id}/templates/{code}', guild_id=guild_id, code=code))
@@ -823,8 +1275,15 @@ def create_from_template(self, code, name, region, icon):
         }
         return self.request(Route('POST', '/guilds/templates/{code}', code=code), json=payload)
 
-    def get_bans(self, guild_id):
-        return self.request(Route('GET', '/guilds/{guild_id}/bans', guild_id=guild_id))
+    def get_bans(self, guild_id, limit: int, after: int = None, before: int = None):
+        params = {
+            'limit': limit
+        }
+        if after:
+            params['after'] = after
+        if before:
+            params['before'] = before
+        return self.request(Route('GET', '/guilds/{guild_id}/bans', guild_id=guild_id), params=params)
 
     def get_ban(self, user_id, guild_id):
         return self.request(Route('GET', '/guilds/{guild_id}/bans/{user_id}', guild_id=guild_id, user_id=user_id))
@@ -834,7 +1293,15 @@ def get_vanity_code(self, guild_id):
 
     def change_vanity_code(self, guild_id, code, *, reason=None):
         payload = {'code': code}
-        return self.request(Route('PATCH', '/guilds/{guild_id}/vanity-url', guild_id=guild_id), json=payload, reason=reason)
+        return self.request(
+            Route(
+                'PATCH',
+                '/guilds/{guild_id}/vanity-url',
+                guild_id=guild_id
+            ),
+            json=payload,
+            reason=reason
+        )
 
     def get_all_guild_channels(self, guild_id):
         return self.request(Route('GET', '/guilds/{guild_id}/channels', guild_id=guild_id))
@@ -850,7 +1317,9 @@ def get_members(self, guild_id, limit, after):
         return self.request(r, params=params)
 
     def get_member(self, guild_id, member_id):
-        return self.request(Route('GET', '/guilds/{guild_id}/members/{member_id}', guild_id=guild_id, member_id=member_id))
+        return self.request(
+            Route('GET', '/guilds/{guild_id}/members/{member_id}', guild_id=guild_id, member_id=member_id)
+            )
 
     def prune_members(self, guild_id, days, compute_prune_count, roles, *, reason=None):
         payload = {
@@ -899,6 +1368,47 @@ def edit_custom_emoji(self, guild_id, emoji_id, *, name, roles=None, reason=None
         r = Route('PATCH', '/guilds/{guild_id}/emojis/{emoji_id}', guild_id=guild_id, emoji_id=emoji_id)
         return self.request(r, json=payload, reason=reason)
 
+    def create_guild_sticker(self, guild_id, file, reason=None, **fields):
+        r = Route('POST', '/guilds/{guild_id}/stickers', guild_id=guild_id)
+        initial_bytes = file.fp.read(16)
+
+        try:
+            mime_type = utils._get_mime_type_for_image(initial_bytes)
+        except InvalidArgument:
+            if initial_bytes.startswith(b'{'):
+                mime_type = 'application/json'
+            else:
+                mime_type = 'application/octet-stream'
+        finally:
+            file.reset()
+
+        form = [
+            {
+                'name': 'file',
+                'value': file.fp,
+                'filename': file.filename,
+                'content_type': mime_type
+            }
+        ]
+        for k, v in fields.items():
+            if v is not None:
+                form.append(
+                    {
+                        'name': k,
+                        'value': str(v)
+                    }
+                )
+
+        return self.request(r, form=form, files=[file], reason=reason)
+
+    def edit_guild_sticker(self, guild_id, sticker_id, data, reason=None):
+        r = Route('PATCH', '/guilds/{guild_id}/stickers/{sticker_id}', guild_id=guild_id, sticker_id=sticker_id)
+        return self.request(r, json=data, reason=reason)
+
+    def delete_guild_sticker(self, guild_id, sticker_id, reason=None):
+        r = Route('DELETE', '/guilds/{guild_id}/stickers/{sticker_id}', guild_id=guild_id, sticker_id=sticker_id)
+        return self.request(r, reason=reason)
+
     def get_all_integrations(self, guild_id):
         r = Route('GET', '/guilds/{guild_id}/integrations', guild_id=guild_id)
 
@@ -914,20 +1424,32 @@ def create_integration(self, guild_id, type, id):
         return self.request(r, json=payload)
 
     def edit_integration(self, guild_id, integration_id, **payload):
-        r = Route('PATCH', '/guilds/{guild_id}/integrations/{integration_id}', guild_id=guild_id,
-                  integration_id=integration_id)
+        r = Route(
+            'PATCH',
+            '/guilds/{guild_id}/integrations/{integration_id}',
+            guild_id=guild_id,
+            integration_id=integration_id
+        )
 
         return self.request(r, json=payload)
 
     def sync_integration(self, guild_id, integration_id):
-        r = Route('POST', '/guilds/{guild_id}/integrations/{integration_id}/sync', guild_id=guild_id,
-                  integration_id=integration_id)
+        r = Route(
+            'POST',
+            '/guilds/{guild_id}/integrations/{integration_id}/sync',
+            guild_id=guild_id,
+            integration_id=integration_id
+        )
 
         return self.request(r)
 
     def delete_integration(self, guild_id, integration_id):
-        r = Route('DELETE', '/guilds/{guild_id}/integrations/{integration_id}', guild_id=guild_id,
-                  integration_id=integration_id)
+        r = Route(
+            'DELETE',
+            '/guilds/{guild_id}/integrations/{integration_id}',
+            guild_id=guild_id,
+            integration_id=integration_id
+        )
 
         return self.request(r)
 
@@ -953,22 +1475,24 @@ def get_widget(self, guild_id):
     def create_invite(self, channel_id, *, reason=None, **options):
         r = Route('POST', '/channels/{channel_id}/invites', channel_id=channel_id)
         payload = {
-            'max_age': options.get('max_age', 84000),
+            'max_age': options.get('max_age', 86400),
             'max_uses': options.get('max_uses', 0),
             'temporary': options.get('temporary', False),
             'unique': options.get('unique', False),
             'target_type': options.get('target_type', None),
             'target_user_id': options.get('target_user_id', None),
-            'target_application_id': options.get('target_application_id', None),
-            'validate': options.get('validate', )
+            'target_application_id': options.get('target_application_id', None)
         }
 
         return self.request(r, reason=reason, json=payload)
 
-    def get_invite(self, invite_id, *, with_counts=True):
+    def get_invite(self, invite_id, *, with_counts=True, with_expiration=True, event_id=None):
         params = {
-            'with_counts': int(with_counts)
+            'with_counts': int(with_counts),
+            'with_expiration': int(with_expiration),
         }
+        if event_id:
+            params['guild_scheduled_event_id'] = str(event_id)
         return self.request(Route('GET', '/invites/{invite_id}', invite_id=invite_id), params=params)
 
     def invites_from(self, guild_id):
@@ -980,6 +1504,60 @@ def invites_from_channel(self, channel_id):
     def delete_invite(self, invite_id, *, reason=None):
         return self.request(Route('DELETE', '/invites/{invite_id}', invite_id=invite_id), reason=reason)
 
+    # Event management
+
+    def get_guild_event(self, guild_id, event_id, with_user_count=True):
+        with_user_count = str(with_user_count).lower()
+        r = Route(
+            'GET', '/guilds/{guild_id}/scheduled-events/{event_id}?with_user_count={with_user_count}',
+            guild_id=guild_id, event_id=event_id, with_user_count=with_user_count
+        )
+        return self.request(r)
+
+    def get_guild_events(self, guild_id, with_user_count=True):
+        r = Route(
+            'GET', '/guilds/{guild_id}/scheduled-events/{event_id}?with_user_count={with_user_count}',
+            guild_id=guild_id, with_user_count=with_user_count
+        )
+        return self.request(r)
+
+    def get_guild_event_users(self, guild_id, event_id, limit=100, before=None, after=None, with_member=False):
+        url = '/guilds/{guild_id}/scheduled-events/{event_id}/users?limit={limit}'
+        if before:
+            url += f'&before={before}'
+        elif after:
+            url += f'&after={after}'
+        if with_member:
+            url += '&with_member=true'
+        return self.request(Route('GET', url, guild_id=guild_id, event_id=event_id, limit=limit))
+
+    def create_guild_event(self, guild_id, fields, *, reason=None):
+        r = Route('POST', '/guilds/{guild_id}/scheduled-events', guild_id=guild_id)
+        return self.request(r, json=fields, reason=reason)
+
+    def edit_guild_event(self, guild_id, event_id, *, reason=None, **fields):
+        valid_keys = (
+            'name',
+            'description',
+            'entity_type',
+            'privacy_level',
+            'entity_metadata',
+            'channel_id',
+            'scheduled_start_time',
+            'scheduled_end_time',
+            'status',
+            'image'
+        )
+        payload = {
+            k: v for k, v in fields.items() if k in valid_keys
+        }
+        r = Route('PATCH', '/guilds/{guild_id}/scheduled-events/{event_id}', guild_id=guild_id, event_id=event_id)
+        return self.request(r, json=payload, reason=reason)
+
+    def delete_guild_event(self, guild_id, event_id, *, reason=None):
+        r = Route('DELETE', '/guilds/{guild_id}/scheduled-events/{event_id}', guild_id=guild_id, event_id=event_id)
+        return self.request(r, reason=reason)
+
     # Role management
 
     def get_roles(self, guild_id):
@@ -987,7 +1565,7 @@ def get_roles(self, guild_id):
 
     def edit_role(self, guild_id, role_id, *, reason=None, **fields):
         r = Route('PATCH', '/guilds/{guild_id}/roles/{role_id}', guild_id=guild_id, role_id=role_id)
-        valid_keys = ('name', 'permissions', 'color', 'hoist', 'mentionable')
+        valid_keys = ('name', 'permissions', 'color', 'hoist', 'mentionable', 'icon')
         payload = {
             k: v for k, v in fields.items() if k in valid_keys
         }
@@ -1000,7 +1578,7 @@ def delete_role(self, guild_id, role_id, *, reason=None):
     def replace_roles(self, user_id, guild_id, role_ids, *, reason=None):
         return self.edit_member(guild_id=guild_id, user_id=user_id, roles=role_ids, reason=reason)
 
-    def create_role(self, guild_id, *, reason=None, **fields):
+    def create_role(self, guild_id, *, reason=None, fields):
         r = Route('POST', '/guilds/{guild_id}/roles', guild_id=guild_id)
         return self.request(r, json=fields, reason=reason)
 
@@ -1009,13 +1587,23 @@ def move_role_position(self, guild_id, positions, *, reason=None):
         return self.request(r, json=positions, reason=reason)
 
     def add_role(self, guild_id, user_id, role_id, *, reason=None):
-        r = Route('PUT', '/guilds/{guild_id}/members/{user_id}/roles/{role_id}',
-                  guild_id=guild_id, user_id=user_id, role_id=role_id)
+        r = Route(
+            'PUT',
+            '/guilds/{guild_id}/members/{user_id}/roles/{role_id}',
+            guild_id=guild_id,
+            user_id=user_id,
+            role_id=role_id
+        )
         return self.request(r, reason=reason)
 
     def remove_role(self, guild_id, user_id, role_id, *, reason=None):
-        r = Route('DELETE', '/guilds/{guild_id}/members/{user_id}/roles/{role_id}',
-                  guild_id=guild_id, user_id=user_id, role_id=role_id)
+        r = Route(
+            'DELETE',
+            '/guilds/{guild_id}/members/{user_id}/roles/{role_id}',
+            guild_id=guild_id,
+            user_id=user_id,
+            role_id=role_id
+        )
         return self.request(r, reason=reason)
 
     def edit_channel_permissions(self, channel_id, target, allow, deny, type, *, reason=None):
@@ -1037,34 +1625,288 @@ def delete_channel_permissions(self, channel_id, target, *, reason=None):
     def move_member(self, user_id, guild_id, channel_id, *, reason=None):
         return self.edit_member(guild_id=guild_id, user_id=user_id, channel_id=channel_id, reason=reason)
 
-    # Relationship related
+    # application-command's management
+    def get_application_commands(self, application_id, command_id=None, guild_id=None):
+        if guild_id:
+            url = '/applications/{application_id}/guilds/{guild_id}/commands'
+            if command_id:
+                url += f'/{command_id}'
+                r = Route(
+                    'GET',
+                    f'{url}?with_localizations=true',
+                    application_id=application_id,
+                    guild_id=guild_id,
+                    command_id=command_id
+                )
+            else:
+                r = Route('GET', f'{url}?with_localizations=true', application_id=application_id, guild_id=guild_id)
+        else:
+            url = '/applications/{application_id}/commands'
+            if command_id:
+                url += f'/{command_id}'
+                r = Route('GET', f'{url}?with_localizations=true', application_id=application_id, command_id=command_id)
+            else:
+                r = Route('GET', f'{url}?with_localizations=true', application_id=application_id)
+        return self.request(r)
+
+    def create_application_command(self, application_id, data, guild_id=None):
+        if guild_id:
+            r = Route(
+                'POST',
+                '/applications/{application_id}/guilds/{guild_id}/commands',
+                application_id=application_id,
+                guild_id=guild_id
+            )
+        else:
+            r = Route('POST', '/applications/{application_id}/commands', application_id=application_id)
+        return self.request(r, json=data)
+
+    def edit_application_command(self, application_id, command_id, data, guild_id=None):
+        if guild_id:
+            r = Route('PATCH', '/applications/{application_id}/guilds/{guild_id}/commands/{command_id}',
+                      application_id=application_id, guild_id=guild_id, command_id=command_id
+                      )
+        else:
+            r = Route('PATCH', '/applications/{application_id}/commands/{command_id}',
+                      application_id=application_id, command_id=command_id
+                      )
+        return self.request(r, json=data)
+
+    def delete_application_command(self, application_id, command_id, guild_id=None):
+        if guild_id:
+            r = Route('DELETE', '/applications/{application_id}/guilds/{guild_id}/commands/{command_id}',
+                      application_id=application_id, guild_id=guild_id, command_id=command_id
+                      )
+        else:
+            r = Route('DELETE', '/applications/{application_id}/commands/{command_id}',
+                      application_id=application_id, command_id=command_id
+                      )
+        return self.request(r)
+
+    def bulk_overwrite_application_commands(self, application_id, data, guild_id=None):
+        if guild_id:
+            r = Route('PUT', '/applications/{application_id}/guilds/{guild_id}/commands',
+                      application_id=application_id, guild_id=guild_id
+                      )
+        else:
+            r = Route('PUT', '/applications/{application_id}/commands', application_id=application_id)
+        return self.request(r, json=data)
+
+    def get_guild_application_command_permissions(self, application_id, guild_id, command_id=None):
+        if command_id:
+            r = Route('GET', '/applications/{application_id}/guilds/{guild_id}/commands/{command_id}/permissions',
+                      application_id=application_id, guild_id=guild_id, command_id=command_id
+                      )
+        else:
+            r = Route('GET', '/applications/{application_id}/guilds/{guild_id}/commands/permissions',
+                      application_id=application_id, guild_id=guild_id
+                      )
+        return self.request(r)
+
+    def edit_application_command_permissions(self, application_id, guild_id, command_id, data):
+        r = Route(
+            'PUT',
+            '/applications/{application_id}/guilds/{guild_id}/commands/{command_id}/permissions',
+            application_id=application_id,
+            guild_id=guild_id,
+            command_id=command_id
+        )
+        return self.request(r, json=data)
+
+    # Interaction management
+    def post_initial_response(self, interaction_id: int, token: str, data: Dict[str, Any]):
+        return self.request(Route("POST", f'/interactions/{interaction_id}/{token}/callback'), json=data)
+
+    def send_interaction_response(
+            self,
+            interaction_id: int,
+            token: str,
+            params: MultipartParameters,
+    ):
+        r = Route('POST', f"/interactions/{interaction_id}/{token}/callback")
+        if params.files:
+            return self.request(r, files=params.files, form=params.multipart)
+        else:
+            return self.request(r, json=params.payload)
+
+    def edit_original_interaction_response(
+            self,
+            token: str,
+            application_id: int,
+            params: MultipartParameters
+    ):
+        r = Route('PATCH', f'/webhooks/{application_id}/{token}/messages/@original')
+        if params.files:
+            return self.request(r, files=params.files, form=params.multipart)
+        else:
+            return self.request(r, json=params.payload)
+
+    def send_followup(
+            self,
+            token: str,
+            application_id: int,
+            params: MultipartParameters,
+    ):
+        r = Route('POST', f'/webhooks/{application_id}/{token}')
+        if params.files:
+            return self.request(r, files=params.files, form=params.multipart)
+        else:
+            return self.request(r, json=params.payload)
+
+    def edit_followup(
+            self,
+            application_id: int,
+            token: str,
+            message_id: int,
+            params: MultipartParameters
+    ):
+        r = Route('PATCH', f'/webhooks/{application_id}/{token}/messages/{message_id}')
+        if params.files:
+            return self.request(r, files=params.files, form=params.multipart)
+        else:
+            return self.request(r, json=params.payload)
+
+    def get_original_interaction_response(self, token: str, application_id: int):
+        r = Route('GET', f'/webhooks/{application_id}/{token}/messages/@original')
+        return self.request(r)
+
+    def get_followup_message(self, token: str, application_id: int, message_id: int):
+        r = Route('GET', f'/webhooks/{application_id}/{token}/messages/{message_id}')
+        return self.request(r)
 
-    def remove_relationship(self, user_id):
-        r = Route('DELETE', '/users/@me/relationships/{user_id}', user_id=user_id)
+    def delete_interaction_response(self, token: str, application_id: int, message_id: int = '@original'):
+        r = Route('DELETE', f'/webhooks/{application_id}/{token}/messages/{message_id}')
         return self.request(r)
 
-    def add_relationship(self, user_id, type=None):
-        r = Route('PUT', '/users/@me/relationships/{user_id}', user_id=user_id)
+    def send_autocomplete_callback(self, token: str, interaction_id: int, choices: list):
+        r = Route('POST', f'/interactions/{interaction_id}/{token}/callback')
+        data = {'data': {'choices': choices}, 'type': 8}
+        return self.request(r, json=data)
+
+    # AutoMod management
+    def get_automod_rules(self, guild_id: int):
+        return self.request(Route('GET', '/guilds/{guild_id}/auto-moderation/rules', guild_id=guild_id))
+
+    def get_automod_rule(self, guild_id: int, rule_id: int):
+        return self.request(
+            Route('GET', '/guilds/{guild_id}/auto-moderation/rules/{rule_id}', guild_id=guild_id, rule_id=rule_id)
+            )
+
+    def create_automod_rule(self, guild_id: int, data: dict, reason: str = None):
+        r = Route('POST', '/guilds/{guild_id}/auto-moderation/rules', guild_id=guild_id)
+        return self.request(r, json=data, reason=reason)
+
+    def edit_automod_rule(self, guild_id: int, rule_id: int, fields: Dict[str, Any], reason: Optional[str] = None):
+        r = Route('PATCH', '/guilds/{guild_id}/auto-moderation/rules/{rule_id}', guild_id=guild_id, rule_id=rule_id)
+        return self.request(r, json=fields, reason=reason)
+
+    def delete_automod_rule(self, guild_id: int, rule_id: int, reason: str = None):
+        r = Route('DELETE', '/guilds/{guild_id}/auto-moderation/rules/{rule_id}', guild_id=guild_id, rule_id=rule_id)
+        return self.request(r, reason=reason)
+
+    # Onboarding management
+    def get_guild_onboarding(self, guild_id: int) -> Response[guild.Onboarding]:
+        return self.request(Route('GET', '/guilds/{guild_id}/onboarding', guild_id=guild_id))
+
+    def edit_guild_onboarding(
+            self,
+            guild_id: int,
+            *,
+            prompts: Optional[List[guild.OnboardingPrompt]] = None,
+            default_channel_ids: Optional[SnowflakeID] = None,
+            enabled: Optional[bool] = None,
+            mode: Optional[guild.OnboardingMode] = None,
+            reason: Optional[str] = None
+    ) -> Response[guild.Onboarding]:
         payload = {}
-        if type is not None:
-            payload['type'] = type
 
-        return self.request(r, json=payload)
+        if prompts is not None:
+            payload['prompts'] = prompts
+
+        if default_channel_ids is not None:
+            payload['default_channel_ids'] = default_channel_ids
+
+        if enabled is not None:
+            payload['enabled'] = enabled
+
+        if mode is not None:
+            payload['mode'] = mode
+
+        return self.request(
+            Route('PUT', '/guilds/{guild_id}/onboarding', guild_id=guild_id),
+            json=payload,
+            reason=reason
+        )
+
+    # Misc
+    def application_info(self):
+        return self.request(Route('GET', '/oauth2/applications/@me'))
+
+    def list_entitlements(
+            self,
+            application_id: int,
+            *,
+            limit: int = 100,
+            user_id: int = MISSING,
+            guild_id: int = MISSING,
+            sku_ids: List[int] = MISSING,
+            after: int = MISSING,
+            before: int = MISSING,
+            exclude_ended: int = False
+    ) -> Response[List[monetization.Entitlement]]:
+        params = {'limit': limit}
 
-    def send_friend_request(self, username, discriminator):
-        r = Route('POST', '/users/@me/relationships')
+        if user_id is not MISSING:
+            params['user_id'] = str(user_id)
+        if guild_id is not MISSING:  # FIXME: Can both be passed at the same time? Consider using elif instead
+            params['guild_id'] = str(guild_id)
+        if sku_ids is not MISSING:
+            params['sku_ids'] = [str(s) for s in sku_ids]
+        if after is not MISSING:
+            params['after'] = str(after)
+        if before is not MISSING:  # FIXME: Can both be passed at the same time? Consider using elif instead
+            params['before'] = str(before)
+        if exclude_ended is not False:  # TODO: what is the api default value?
+            params['exclude_ended'] = str(exclude_ended)
+
+        r = Route('GET', '/applications/{application_id}/entitlements', application_id=application_id)
+        return self.request(r, json=params)
+
+    def create_test_entitlement(
+            self,
+            application_id: int,
+            *,
+            sku_id: int,
+            owner_id: int,
+            owner_type: int
+    ) -> Response[monetization.TestEntitlement]:
         payload = {
-            'username': username,
-            'discriminator': int(discriminator)
+            'sku_id': sku_id,
+            'owner_id': owner_id,
+            'owner_type': owner_type
         }
+        r = Route('POST', '/applications/{application_id}/entitlements', application_id=application_id)
         return self.request(r, json=payload)
 
-    # Misc
+    def delete_test_entitlement(self, application_id: int, entitlement_id: int) -> Response[None]:
+        r = Route(
+            'DELETE',
+            '/applications/{application_id}/entitlements/{entitlement_id}',
+            application_id=application_id,
+            entitlement_id=entitlement_id
+        )
+        return self.request(r)
 
-    def application_info(self):
-        return self.request(Route('GET', '/oauth2/applications/@me'))
+    def consume_entitlement(self, application_id: int, entitlement_id: int) -> Response[None]:
+        r = Route(
+            'POST',
+            '/applications/{application_id}/entitlements/{entitlement_id}/consume',
+            application_id=application_id,
+            entitlement_id=entitlement_id
+        )
+        return self.request(r)
 
-    async def get_gateway(self, *, encoding='json', v=9, zlib=True):
+    async def get_gateway(self, *, encoding='json', v=10, zlib=True):
         try:
             data = await self.request(Route('GET', '/gateway'))
         except HTTPException as exc:
@@ -1075,7 +1917,7 @@ async def get_gateway(self, *, encoding='json', v=9, zlib=True):
             value = '{0}?encoding={1}&v={2}'
         return value.format(data['url'], encoding, v)
 
-    async def get_bot_gateway(self, *, encoding='json', v=9, zlib=True):
+    async def get_bot_gateway(self, *, encoding='json', v=10, zlib=True):
         try:
             data = await self.request(Route('GET', '/gateway/bot'))
         except HTTPException as exc:
@@ -1087,21 +1929,15 @@ async def get_bot_gateway(self, *, encoding='json', v=9, zlib=True):
             value = '{0}?encoding={1}&v={2}'
         return data['shards'], value.format(data['url'], encoding, v)
 
-    def get_user(self, user_id):
+    def get_voice_regions(self):
+        return self.request(Route('GET', '/voice/regions'))
+
+    def get_user(self, user_id: int):
         return self.request(Route('GET', '/users/{user_id}', user_id=user_id))
 
-    def get_user_profile(self, user_id):
+    def get_user_profile(self, user_id: int):
         return self.request(Route('GET', '/users/{user_id}/profile', user_id=user_id))
 
-    def get_mutual_friends(self, user_id):
-        return self.request(Route('GET', '/users/{user_id}/relationships', user_id=user_id))
-
-    def change_hypesquad_house(self, house_id):
-        payload = {'house_id': house_id}
-        return self.request(Route('POST', '/hypesquad/online'), json=payload)
-
-    def leave_hypesquad_house(self):
-        return self.request(Route('DELETE', '/hypesquad/online'))
-
-    def edit_settings(self, **payload):
-        return self.request(Route('PATCH', '/users/@me/settings'), json=payload)
+    def get_all_nitro_stickers(self):
+        return self.request(Route('GET', '/sticker-packs'))
+    
\ No newline at end of file
diff --git a/discord/integrations.py b/discord/integrations.py
index 4a5ecc41..6bf192ab 100644
--- a/discord/integrations.py
+++ b/discord/integrations.py
@@ -1,6 +1,8 @@
 """
 The MIT License (MIT)
-Copyright (c) 2015-present Rapptz
+
+Copyright (c) 2015-2021 Rapptz & (c) 2021-present mccoderpy
+
 Permission is hereby granted, free of charge, to any person obtaining a
 copy of this software and associated documentation files (the "Software"),
 to deal in the Software without restriction, including without limitation
@@ -17,38 +19,51 @@
 FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 DEALINGS IN THE SOFTWARE.
 """
-
 from __future__ import annotations
 
 import datetime
-from typing import Optional, TYPE_CHECKING, overload
-from .utils import _get_as_snowflake, get, parse_time
+from typing import (
+    Optional,
+    TYPE_CHECKING,
+    overload
+)
+from typing_extensions import Literal
+
+from .asset import Asset
+from .utils import _get_as_snowflake, parse_time
 from .role import Role
 from .user import User
 from .errors import InvalidArgument
 from .enums import try_enum, ExpireBehaviour
 
+if TYPE_CHECKING:
+    from .guild import Guild
+    from .state import ConnectionState
+    from .types.integration import (
+        Integration as IntegrationPayload,
+        IntegrationAccount as IntegrationAccountPayload,
+        IntegrationApplication as IntegrationApplicationPayload,
+        StreamIntegration as StreamIntegrationPayload,
+        BotIntegration as BotIntegrationPayload,
+        IntegrationType
+    )
+
 __all__ = (
     'IntegrationAccount',
     'IntegrationApplication',
+    'PartialIntegration',
     'Integration',
     'StreamIntegration',
     'BotIntegration',
+    '_integration_factory'
 )
 
-if TYPE_CHECKING:
-    from .types.integration import (
-        IntegrationAccount as IntegrationAccountPayload,
-        Integration as IntegrationPayload,
-        IntegrationType,
-        IntegrationApplication as IntegrationApplicationPayload,
-    )
-    from .guild import Guild
-
 
 class IntegrationAccount:
     """Represents an integration account.
+    
     .. versionadded:: 1.4
+    
     Attributes
     -----------
     id: :class:`int`
@@ -61,15 +76,57 @@ class IntegrationAccount:
 
     def __init__(self, data: IntegrationAccountPayload) -> None:
         self.id: Optional[int] = _get_as_snowflake(data, 'id')
-        self.name: str = data.pop('name')
+        self.name: str = data['name']
 
     def __repr__(self) -> str:
         return f'<IntegrationAccount id={self.id} name={self.name!r}>'
 
 
+class PartialIntegration:
+    """Represents a partial integration.
+
+    .. versionadded:: 2.0
+
+    Attributes
+    -----------
+    id: :class:`int`
+        The integration ID.
+    name: :class:`str`
+        The integration name.
+    type: :class:`str`
+        The integration type (i.e. discord).
+    application_id: Optional[:class:`int`]
+        The ID of the application for this integration.
+    account: :class:`IntegrationAccount`
+        The account linked to this integration.
+    """
+
+    __slots__ = (
+        'id',
+        'name',
+        'type',
+        'application_id',
+        'account',
+        'guild',
+    )
+
+    def __init__(self, *, data: IntegrationPayload, guild: Guild) -> None:
+        self.guild: Guild = guild
+        self.id: int = int(data['id'])
+        self.name: str = data['name']
+        self.type: str = data['type']
+        self.application_id: Optional[int] = _get_as_snowflake(data, 'application_id')
+        self.account: IntegrationAccount = IntegrationAccount(data['account'])
+
+    def __repr__(self) -> str:
+        return f'<PartialIntegration id={self.id} name={self.name!r} type={self.type!r}>'
+
+
 class Integration:
     """Represents a guild integration.
+    
     .. versionadded:: 1.4
+    
     Attributes
     -----------
     id: :class:`int`
@@ -100,16 +157,16 @@ class Integration:
     )
 
     def __init__(self, *, data: IntegrationPayload, guild: Guild) -> None:
-        self.guild = guild
-        self._state = guild._state
+        self.guild: Guild = guild
+        self._state: ConnectionState = guild._state
         self._from_data(data)
 
     def __repr__(self):
         return f"<{self.__class__.__name__} id={self.id} name={self.name!r}>"
 
-    def _from_data(self, data: IntegrationPayload) -> None:
+    def _from_data(self, data) -> None:
         self.id: int = int(data['id'])
-        self.type: IntegrationType = data['type']
+        self.type = data['type']
         self.name: str = data['name']
         self.account: IntegrationAccount = IntegrationAccount(data['account'])
 
@@ -122,6 +179,7 @@ async def delete(self) -> None:
         Deletes the integration.
         You must have the :attr:`~Permissions.manage_guild` permission to
         do this.
+        
         Raises
         -------
         Forbidden
@@ -134,7 +192,9 @@ async def delete(self) -> None:
 
 class StreamIntegration(Integration):
     """Represents a stream integration for Twitch or YouTube.
+    
     .. versionadded:: 2.0
+    
     Attributes
     ----------
     id: :class:`int`
@@ -178,7 +238,7 @@ class StreamIntegration(Integration):
         'subscriber_count'
     )
 
-    def _from_data(self, data: IntegrationPayload) -> None:
+    def _from_data(self, data: StreamIntegrationPayload) -> None:
         super()._from_data(data)
         self.revoked: bool = data['revoked']
         self.expire_behaviour: ExpireBehaviour = try_enum(ExpireBehaviour, data['expire_behavior'])
@@ -209,6 +269,7 @@ async def edit(self, **fields) -> None:
         Edits the integration.
         You must have the :attr:`~Permissions.manage_guild` permission to
         do this.
+        
         Parameters
         -----------
         expire_behaviour: :class:`ExpireBehaviour`
@@ -217,6 +278,7 @@ async def edit(self, **fields) -> None:
             The period (in days) where the integration will ignore lapsed subscriptions.
         enable_emoticons: :class:`bool`
             Where emoticons should be synced for this integration (currently twitch only).
+        
         Raises
         -------
         Forbidden
@@ -258,6 +320,7 @@ async def sync(self) -> None:
         Syncs the integration.
         You must have the :attr:`~Permissions.manage_guild` permission to
         do this.
+        
         Raises
         -------
         Forbidden
@@ -271,7 +334,9 @@ async def sync(self) -> None:
 
 class IntegrationApplication:
     """Represents an application for a bot integration.
+    
     .. versionadded:: 2.0
+    
     Attributes
     ----------
     id: :class:`int`
@@ -282,8 +347,6 @@ class IntegrationApplication:
         The application's icon hash.
     description: :class:`str`
         The application's description. Can be an empty string.
-    summary: :class:`str`
-        The summary of the application. Can be an empty string.
     user: Optional[:class:`User`]
         The bot user on this application.
     """
@@ -293,24 +356,52 @@ class IntegrationApplication:
         'name',
         'icon',
         'description',
-        'summary',
         'user',
+        '_state',
     )
 
-    def __init__(self, *, data: IntegrationApplicationPayload, state):
+    def __init__(self, *, data: IntegrationApplicationPayload, state: ConnectionState):
+        self._state: ConnectionState = state
         self.id: int = int(data['id'])
         self.name: str = data['name']
         self.icon: Optional[str] = data['icon']
         self.description: str = data['description']
-        self.summary: str = data['summary']
         user = data.get('bot')
         self.user: Optional[User] = User(state=state, data=user) if user else None
+    
+    def icon_url(self) -> Asset:
+        """Returns an :class:`Asset` for the application's icon."""
+        return self.icon_url_as()
+    
+    def icon_url_as(
+            self,
+            *,
+            format: Literal['png', 'jpg', 'jpeg', 'webp'] = 'webp',
+            size: int = 1024
+    ) -> Asset:
+        """
+        Returns an :class:`Asset` for the application's icon.
+        
+        Parameters
+        -----------
+        format: Optional[:class:`str`]
+            The format to attempt to convert the image to. Defaults to ``webp``.
+        size: :class:`int`
+            The size of the image to return. Defaults to 1024.
+        
+        Returns
+        -------
+        :class:`Asset`
+            The resulting CDN asset.
+        """
+        return Asset._from_icon(self._state, self, 'app', format=format, size=size)
 
 
 class BotIntegration(Integration):
     """Represents a bot integration on discord.
 
     .. versionadded:: 2.0
+    
     Attributes
     ----------
     id: :class:`int`
@@ -333,15 +424,16 @@ class BotIntegration(Integration):
 
     __slots__ = Integration.__slots__ + ('application',)
 
-    def _from_data(self, data: IntegrationPayload) -> None:
+    def _from_data(self, data: BotIntegrationPayload) -> None:
         super()._from_data(data)
         self.application = IntegrationApplication(data=data['application'], state=self._state)
 
 
-def _integration_factory(value):
+def _integration_factory(value: IntegrationType):
     if value == 'discord':
         return BotIntegration, value
     elif value in ('twitch', 'youtube'):
         return StreamIntegration, value
     else:
-        return Integration, value
\ No newline at end of file
+        return Integration, value
+    # TODO: Add guild_integration type
diff --git a/discord/interactions.py b/discord/interactions.py
index 31a98c9f..0b4d9a37 100644
--- a/discord/interactions.py
+++ b/discord/interactions.py
@@ -1,251 +1,1924 @@
-import typing
-import logging
-from . import utils
-from .user import User
-from .member import Member
-from .http import HTTPClient
-from .message import Message
-from .errors import NotFound
-from .channel import DMChannel
-from typing_extensions import Literal
-from typing import Union, List, Optional
-from .components import Button, SelectMenu
-from .enums import ComponentType, InteractionCallbackType
-
-log = logging.getLogger(__name__)
-
-__all__ = ('EphemeralMessage',
-           'Interaction',
-           'ButtonClick',
-           'SelectionSelect')
-
-
-class EphemeralMessage:
-
-    """
-    Since Discord doesn't return anything when we send a ephemeral message,
-    this class has no attributes and you can't do anything with it.
-    """
-
-
-class ButtonClick:
-    """Represents a :class:`discord.Button` that was pressed in an ephemeral Message(contains its custom_id and its hash)."""
-    def __init__(self, data):
-        self.component_type: int = data.get('component_type')
-        custom_id = data.get('custom_id')
-        self.custom_id: typing.Union[str, int] = int(custom_id) if custom_id.isdigit() else custom_id
-        self.__hash__: str = data.get('hash', None)
-
-    def __hash__(self):
-        return self.__hash__
-
-    def __repr__(self):
-        return f"<ButtonClick custom_id={self.custom_id}{', hash='+self.__hash__ if self.__hash__ else ''}>"
-
-
-class SelectionSelect:
-    """Represents a :class:`discord.SelectMenu` in an ephemeral Message from which options have been selected (contains its custom_id and the selected options)."""
-    def __init__(self, data):
-        self.component_type: int = data.get('component_type')
-        custom_id = data.get('custom_id')
-        self.custom_id: typing.Union[str, int] = int(custom_id) if custom_id.isdigit() else custom_id
-        self.values: typing.List[typing.Union[str, int]] = [int(value) if value.isdigit() else value for value in data.get('values', [])]
-
-    def __repr__(self):
-        return f'<SelectionSelect custom_id={self.custom_id}, values={self.values}>'
-
-
-class Interaction:
-
-    """
-    The Class for an discord-interaction like klick an :class:`Button` or select an option of :class:`SelectMenu` in discord
-
-    For more general information's about Interactions visit the Documentation of the
-    `Discord-API <https://discord.com/developers/docs/interactions/slash-commands#interaction-object>`_
-    """
-
-    def __init__(self, state, data):
-        self._state = state
-        self._http: HTTPClient = state.http
-        self._interaction_type = data.get('type', None)
-        self.__token = data.get('token', None)
-        self._message = data.get('message')
-        self.message_id = int(self._message.get('id'))
-        self.message_flags = self._message.get('flags', 0)
-        self._data = data.get('data', None)
-        self._member = data.get('member', None)
-        self._user = data.get('user', self._member.get('user', None) if self._member else None)
-        self.user_id = int(self._user['id'])
-        self.__interaction_id = int(data.get('id'))
-        self.guild_id = int(data.get('guild_id', 0))
-        self._guild = None
-        self._channel = None
-        self.channel_id = int(data.get('channel_id', 0))
-        self.__application_id = int(data.get('application_id'))
-        self.member: typing.Optional[Member] = None
-        self.user: typing.Optional[User] = None
-        self.deferred = False
-        self.deferred_hidden = False
-        self.callback_message = None
-        self._component = None
-        self.component_type: typing.Optional[int] = self._data.get('component_type', None)
-        self.message = EphemeralMessage() if self.message_is_hidden else None #Message(state=self._state, channel=self.channel, data=self._message)
-        # maybe ``later`` this library will also supports Slash-Commands
-        # self.command = None
-
-    def __repr__(self):
-        """Represents a :class:`discord.Interaction`-object."""
-        return f'<Interaction {", ".join(["%s=%s" % (a, getattr(self, a)) for a in self.__slots__ if a[0] != "_"])}>'
-
-    async def defer(self, response_type: Literal[5, 6] = InteractionCallbackType.deferred_update_msg, hidden: bool = False) -> None:
-        """
-        |coro|
-
-        'Defers' the response.
-
-        If :attr:`response_type` is `InteractionCallbackType.deferred_msg_with_source` it shows a loading state to the user.
-
-        :param response_type: Optional[Literal[5, 6]]
-            The type to response with, aiter :class:`InteractionCallbackType.deferred_msg_with_source` or :class:`InteractionCallbackType.deferred_update_msg` (e.g. 5 or 6)
-
-        :param hidden: Optional[bool]
-            Whether to defer ephemerally(only the :attr:`author` of the interaction can see the message)
-
-            .. note::
-                Only for :class:`InteractionCallbackType.deferred_msg_with_source`.
-
-        .. important::
-            If you doesn't respond with an message using :meth:`respond`
-            or edit the original message using :meth:`edit` within less than 3 seconds,
-            discord will indicates that the interaction failed and the interaction-token will be invalidated.
-            To provide this us this method
-
-        .. note::
-            A Token will be Valid for 15 Minutes so you could edit the original :attr:`message` with :meth:`edit`, :meth:`respond` or doing anything other with this interaction for 15 minutes.
-            after that time you have to edit the original message with the Methode :meth:`edit` of the :attr:`message` and sending new messages with the :meth:`send` Methode of :attr:`channel`
-            (you could not do this hidden as it isn't an respond anymore).
-        """
-
-        if isinstance(response_type, int):
-            response_type = InteractionCallbackType.from_value(response_type)
-        if response_type not in (InteractionCallbackType.deferred_msg_with_source, InteractionCallbackType.deferred_update_msg):
-            raise ValueError('response_type has to bee discord.InteractionCallbackType.deferred_msg_with_source or discord.InteractionCallbackType.deferred_update_msg (e.g. 5 or 6), not %s.__class__.__name__' % response_type)
-        if self.deferred:
-            return log.warning("\033[91You have already responded to this Interaction!\033[0m")
-        base = {"type": response_type.value, "data": {'flags': 64 if hidden else None}}
-        try:
-            data = await self._http.post_initial_response(_resp=base, use_webhook=False, interaction_id=self.__interaction_id,
-                                                          token=self.__token, application_id=self.__application_id)
-        except NotFound:
-            log.warning(f'Unknown Interaction {self.__interaction_id}')
-        else:
-            self.deferred = True
-            if hidden is True and response_type is InteractionCallbackType.deferred_msg_with_source:
-                self.deferred_hidden = True
-            return data
-
-    async def edit(self, **fields) -> Message:
-        """|coro|
-
-        'Defers' if it isn't yet and edit the message
-        """
-        if not self.channel:
-            self._channel = self._state.add_dm_channel(data=await self._http.get_channel(self.channel_id))
-        await self.message.edit(__is_interaction_response=True, __deferred=False if (not self.deferred or self.callback_message) else True, __use_webhook=False,
-                                __interaction_id=self.__interaction_id, __interaction_token=self.__token,
-                                __application_id=self.__application_id, **fields)
-        self.deferred = True
-        return self.message
-
-    async def respond(self, content=None, *, tts=False, embed=None, embeds=None, components=None, file=None,
-                      files=None, delete_after=None, nonce=None,
-                      allowed_mentions=None, reference=None,
-                      mention_author=None, hidden=False) -> typing.Union[Message, EphemeralMessage]:
-        """|coro|
-
-        Responds to an interaction by sending a message that can be made visible only to the person who performed the
-         interaction by setting the `hidden` parameter to :bool:`True`.
-        """
-        if not self.channel:
-            self._channel = self._state.add_dm_channel(data=await self._http.get_channel(self.channel_id))
-        msg = await self.channel.send(content, tts=tts, embed=embed, embeds=embeds, components=components, file=file,
-                                      files=files, delete_after=delete_after, nonce=nonce,
-                                      allowed_mentions=allowed_mentions, reference=reference,
-                                      mention_author=mention_author, hidden=hidden, __is_interaction_response=True,
-                                      __deferred=self.deferred, __use_webhook=False, __interaction_id=self.__interaction_id,
-                                      __interaction_token=self.__token, __application_id=self.__application_id,
-                                      followup=True if self.callback_message else False)
-
-        if hidden is True:
-            self.deferred_hidden = True
-        if not self.callback_message and not self.deferred:
-            self.callback_message = msg if msg else EphemeralMessage()
-        self.deferred = True
-        return msg
-
-    async def get_original_callback(self):
-        """|coro|
-
-        Fetch the Original Callback-Message of the Interaction
-
-        .. warning::
-            This is a API-Call and should use carefully"""
-        return await self._state.http.get_original_interaction_response(self.__token, self.__application_id)
-
-    @property
-    def created_at(self):
-        """
-        Returns the Interaction’s creation time in UTC.
-
-        :return: datetime.datetime
-        """
-        return utils.snowflake_time(self.__interaction_id)
-
-    @property
-    def author(self) -> typing.Union[Member, User]:
-        return self.member if self.member is not None else self.user
-
-    @property
-    def channel(self):
-        return self._channel if self._channel else self.message.channel
-
-    @property
-    def guild(self):
-        return self._guild
-
-    @property
-    def message_is_dm(self) -> bool:
-        return not self.guild_id
-
-    #@property
-    #def message(self) -> typing.Union[Message, EphemeralMessage]:
-    #    message = self._state._get_message(self.message_id)
-    #    if not message:
-    #        message = EphemeralMessage() if self.message_is_hidden else Message(state=self._state, channel=self.channel, data=self._message)
-    #    return message
-
-    @property
-    def message_is_hidden(self) -> bool:
-        return self.message_flags == 64
-
-    @property
-    def component(self) -> Union[Button, SelectMenu, ButtonClick, SelectionSelect, None]:
-        if self._component is None:
-            custom_id = self._data.get('custom_id')
-            if custom_id is not None:
-                if custom_id.isdigit():
-                    custom_id = int(custom_id)
-                if self._data.get('component_type') == 2:
-                    self._component = utils.get(self.message.all_buttons, custom_id=custom_id)
-                elif self._data.get('component_type') == 3:
-                    select_menu = utils.get(self.message.all_select_menus, custom_id=custom_id)
-                    if select_menu is not None:
-                        setattr(select_menu, '_values', self._data['values'])
-                    self._component = select_menu
-        return self._component
-
-
-class InteractionType:
-    PingAck = 1
-    SlashCommand = 2
-    Component = 3
+# -*- coding: utf-8 -*-
+
+"""
+The MIT License (MIT)
+
+Copyright (c) 2021-present mccoderpy
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+"""
+from __future__ import annotations
+
+import re
+import asyncio
+import logging
+from typing import (
+    Any,
+    Dict,
+    List,
+    Match,
+    Optional,
+    overload,
+    Sequence,
+    Set,
+    Tuple,
+    TYPE_CHECKING,
+    Union
+)
+
+from typing_extensions import Literal
+
+from . import abc, utils
+from .monetization import Entitlement
+from .object import Object
+from .channel import _channel_factory, DMChannel, TextChannel, ThreadChannel, VoiceChannel, ForumPost, PartialMessageable
+from .components import *
+from .embeds import Embed
+from .enums import (
+    ApplicationCommandType,
+    ComponentType,
+    Locale,
+    ChannelType,
+    InteractionCallbackType,
+    InteractionType,
+    MessageType,
+    OptionType,
+    InteractionContextType,
+    AppIntegrationType,
+    try_enum
+)
+from .errors import AlreadyResponded, HTTPException, NotFound, UnknownInteraction
+from .file import File
+from .flags import MessageFlags
+from .guild import Guild
+from .http import handle_interaction_message_parameters, handle_message_parameters, HTTPClient
+from .member import Member
+from .mentions import AllowedMentions
+from .message import Attachment, Message
+from .permissions import Permissions
+from .reaction import Reaction
+from .role import Role
+from .user import User
+from .utils import cached_slot_property, MISSING
+
+if TYPE_CHECKING:
+    import datetime
+    from .types.interaction import (
+        Interaction as InteractionPayload,
+        InteractionData as InteractionDataPayload,
+        ApplicationCommandInteractionDataOption as ApplicationCommandInteractionDataOptionPayload,
+        ResolvedData as ResolvedDataPayload,
+        AuthorizingIntegrationOwners as AuthorizingIntegrationOwnersPayload
+    )
+    from .types.message import Message as MessagePayload
+    from .state import ConnectionState
+    from .components import BaseSelect
+    from .application_commands import SlashCommandOptionChoice, SlashCommand, MessageCommand, UserCommand
+
+
+log = logging.getLogger(__name__)
+
+__all__ = (
+    'EphemeralMessage',
+    'BaseInteraction',
+    'ApplicationCommandInteraction',
+    'ComponentInteraction',
+    'AutocompleteInteraction',
+    'ModalSubmitInteraction',
+    'option_str',
+    'option_float',
+    'option_int',
+)
+
+
+class EphemeralMessage:
+    """
+    Like a normal :class:`~discord.Message` but with a modified :meth:`edit` method and without
+    :meth:`~discord.Message.delete` method.
+    """
+    # This class will be removed in the future when we switched to use the WebhookMessage model instead
+    def __init__(self, *, state, channel, data, interaction):
+        self._state: ConnectionState = state
+        self.__interaction__: BaseInteraction = interaction
+        self.id = int(data.get('id', 0))
+        self.webhook_id = utils._get_as_snowflake(data, 'webhook_id')
+        self.channel_id = utils._get_as_snowflake(data, 'channel_id')
+        self.channel = channel
+        self._update(data)
+
+    def _update(self, data):
+        self.application = data.get('application')
+        self.activity = data.get('activity')
+        self._edited_timestamp = utils.parse_time(data['edited_timestamp'])
+        self.type = try_enum(MessageType, data['type'])
+        self._thread = data.get('thread', None)
+        self.pinned = data['pinned']
+        self.mention_everyone = data['mention_everyone']
+
+        for handler in (
+                'tts',
+                'content',
+                'embeds',
+                'author',
+                'member',
+                'mentions',
+                'mention_roles',
+                'flags',
+                'components',
+                'interaction',
+                'attachments',
+                'reactions'
+        ):
+            try:
+                getattr(self, '_handle_%s' % handler)(data[handler])
+            except KeyError:
+                if not hasattr(self, handler):
+                    setattr(
+                        self,
+                        handler,
+                        None if handler not in {
+                            'embeds',
+                            'mentions',
+                            'mentioned_roles',
+                            'attachments',
+                            'reactions',
+                            'components'
+                        } else []
+                    )  # bad solution for now but works, will be removed anyway when rewrite the existing webhook system
+        return self
+
+    def _handle_flags(self, value):
+        self.flags = MessageFlags._from_value(value)
+
+    def _handle_application(self, value):
+        self.application = value
+
+    def _handle_activity(self, value):
+        self.activity = value
+
+    def _handle_mention_everyone(self, value):
+        self.mention_everyone = value
+
+    def _handle_tts(self, value):
+        self.tts = value
+
+    def _handle_type(self, value):
+        self.type = try_enum(MessageType, value)
+
+    def _handle_content(self, value):
+        self.content = value
+
+    def _handle_attachments(self, value):
+        self.attachments = [Attachment(data=a, state=self._state) for a in value]
+
+    def _handle_embeds(self, value):
+        self.embeds = [Embed.from_dict(data) for data in value]
+
+    def _handle_interaction(self, value):
+        self.interaction = value
+
+    def _handle_components(self, value):
+        self.components = [ActionRow.from_dict(data) for data in value]
+
+    def _handle_reactions(self, value):
+        self.reactions = [Reaction(message=self, data=d) for d in value]
+
+    def _handle_nonce(self, value):
+        self.nonce = value
+
+    def _handle_author(self, author):
+        self.author = self._state.store_user(author)
+        if isinstance(self.guild, Guild):
+            found = self.guild.get_member(self.author.id)
+            if found is not None:
+                self.author = found
+
+    def _handle_member(self, member):
+        # The gateway now gives us full Member objects sometimes with the following keys
+        # deaf, mute, joined_at, roles
+        # For the sake of performance I'm going to assume that the only
+        # field that needs *updating* would be the joined_at field.
+        # If there is no Member object (for some strange reason), then we can upgrade
+        # ourselves to a more "partial" member object.
+        author = self.author
+        try:
+            # Update member reference
+            author._update_from_message(member)
+        except AttributeError:
+            # It's a user here
+            # TODO: consider adding to cache here
+            self.author = Member._from_message(message=self, data=member)
+
+    def _handle_mentions(self, mentions):
+        self.mentions = r = []
+        guild = self.guild
+        state = self._state
+        if not isinstance(guild, Guild):
+            self.mentions = [state.store_user(m) for m in mentions]
+            return
+
+        for mention in filter(None, mentions):
+            id_search = int(mention['id'])
+            member = guild.get_member(id_search)
+            if member is not None:
+                r.append(member)
+            else:
+                r.append(Member._try_upgrade(data=mention, guild=guild, state=state))
+
+    def _handle_mention_roles(self, role_mentions):
+        self.role_mentions = []
+        if isinstance(self.guild, Guild):
+            for role_id in map(int, role_mentions):
+                role = self.guild.get_role(role_id)
+                if role is not None:
+                    self.role_mentions.append(role)
+
+    @utils.cached_slot_property('_cs_guild')
+    def guild(self):
+        """Optional[:class:`Guild`]: The guild that the message belongs to, if applicable."""
+        return getattr(self.channel, 'guild', None)
+
+    def __repr__(self):
+        return '<EphemeralMessage id={0.id} channel={0.channel!r} type={0.type!r} author={0.author!r} flags={0.flags!r}>'.format(
+            self)
+
+    def __eq__(self, other):
+        return isinstance(other, self.__class__) and self.id == other.id
+
+    @property
+    def all_components(self):
+        """Union[:class:`Button`, :ref:`Select <select-like-objects>`]:
+        Yields all buttons and selects that are contained in the message"""
+        for action_row in self.components:
+            yield from action_row
+
+    @property
+    def all_buttons(self):
+        """Returns all :class:`Button`'s that are contained in the message"""
+        for action_row in self.components:
+            for component in action_row:
+                yield component
+
+    @property
+    def all_select_menus(self):
+        """Returns all :ref:`Select <select-like-objects>`'s that are contained in the message"""
+        for action_row in self.components:
+            for component in action_row:
+                if int(component.type) in {3, 5, 6, 7, 8}:
+                    yield component
+
+    async def edit(
+            self,
+            *,
+            content: Any = MISSING,
+            embed: Optional[Embed] = MISSING,
+            embeds: Sequence[Embed] = MISSING,
+            components: List[Union[ActionRow, List[Union[Button, BaseSelect]]]] = MISSING,
+            attachments: Sequence[Union[Attachment, File]] = MISSING,
+            keep_existing_attachments: bool = False,
+            allowed_mentions: Optional[AllowedMentions] = MISSING,
+            suppress_embeds: bool = False,
+            delete_after: Optional[float] = None
+    ) -> Union[Message, EphemeralMessage]:
+        """|coro|
+
+        Edits the message.
+
+        Parameters
+        -----------
+        content: Optional[:class:`str`]
+            The new content to replace the message with.
+            Could be ``None`` to remove the content.
+        embed: Optional[:class:`Embed`]
+            The new embed to replace the original with.
+            Could be ``None`` to remove all embeds.
+        embeds: Optional[List[:class:`Embed`]]
+            A list containing up to 10 embeds to send.
+            If ``None`` or empty, all embeds will be removed.
+            
+            If passed, ``embed`` does also count towards the limit of 10 embeds.
+        components: List[Union[:class:`~discord.ActionRow`, List[Union[:class:`~discord.Button`, :ref:`Select <select-like-objects>`]]]]
+            A list of up to five :class:`~discord.ActionRow`s or :class:`list`,
+            each containing up to five :class:`~discord.Button` or one :ref:`Select <select-like-objects>` like object.
+        attachments: List[Union[:class:`Attachment`, :class:`File`]]
+            A list containing previous attachments to keep as well as new files to upload.
+            You can use ``keep_existing_attachments`` to auto-add the existing attachments to the list.
+            If  an empty list (``[]``) is passed, all attachment will be removed.
+
+            .. note::
+
+                New files will always appear under existing ones.
+
+        keep_existing_attachments: :class:`bool`
+            Whether to auto-add existing attachments to ``attachments``, default :obj:`False`.
+
+            .. note::
+
+                Only needed when ``attachments`` are passed, otherwise will be ignored.
+
+        suppress_embeds: :class:`bool`
+            Whether to suppress embeds for the message. If ``True`` this will remove all embeds from the message.
+            If `´False`` it adds them back.
+        delete_after: :class:`float`
+            If provided, the number of seconds to wait in the background
+            before deleting the response we just edited. If the deletion fails,
+            then it is silently ignored.
+        allowed_mentions: Optional[:class:`~discord.AllowedMentions`]
+            Controls the mentions being processed in this message. If this is
+            passed, then the object is merged with :attr:`~discord.Client.allowed_mentions`.
+            The merging behaviour only overrides attributes that have been explicitly passed
+            to the object, otherwise it uses the attributes set in :attr:`~discord.Client.allowed_mentions`.
+            If no object is passed at all then the defaults given by :attr:`~discord.Client.allowed_mentions`
+            are used instead.
+
+
+        """
+
+        if suppress_embeds:
+            flags = MessageFlags._from_value(self.flags.value)
+            flags.suppress_embeds = True
+        else:
+            flags = MISSING
+
+        if keep_existing_attachments:
+            if attachments is not MISSING:
+                attachments = [*self.attachments, *attachments]
+
+        state = self._state
+        interaction = self.__interaction__
+
+        if not self.channel:
+            self.channel = self._state.add_dm_channel(data=await state.http.get_channel(self.channel_id))
+
+        is_original_response = interaction.callback_message and self.id == interaction.callback_message.id
+
+        params = handle_message_parameters(
+            content=content,
+            flags=flags,
+            embed=embed,
+            embeds=embeds,
+            attachments=attachments,
+            components=components,
+            allowed_mentions=allowed_mentions,
+            previous_allowed_mentions=state.allowed_mentions
+        )
+
+        if is_original_response:
+            method = state.http.edit_original_interaction_response(
+                token=interaction._token,
+                application_id=interaction._application_id,
+                params=params
+            )
+        else:
+            method = state.http.edit_followup(
+                token=interaction._token,
+                application_id=interaction._application_id,
+                message_id=self.id,
+                params=params
+            )
+
+        with params:
+            data = await method
+
+        if not isinstance(data, dict):
+            if is_original_response:
+                return await interaction.get_original_callback()
+            else:
+                data = await state.http.get_followup_message(
+                    token=interaction._token,
+                    application_id=interaction._application_id,
+                    message_id=self.id,
+                )
+        self._update(data)
+        if delete_after:
+            import warnings
+            warnings.warn("You can\'t delete a ephemeral message manual.")
+        return self
+
+    async def delete(self, *, delay: Optional[float] = None) -> None:
+        """|coro|
+
+        Deletes the message.
+
+        .. note::
+            This can only be used while the interaction token is valid. So within 15 minutes after the interaction.
+
+        Parameters
+        -----------
+        delay: Optional[:class:`float`]
+            If provided, the number of seconds to wait in the background
+            before deleting the message. If the deletion fails then it is silently ignored.
+
+        Raises
+        ------
+        NotFound
+            The message was deleted already or the interaction token expired
+        HTTPException
+            Deleting the message failed.
+        """
+        interaction = self.__interaction__
+        is_original_response = interaction.callback_message and self.id == interaction.callback_message.id
+        if delay is not None:
+            async def delete():
+                await asyncio.sleep(delay)
+                try:
+                    await self._state.http.delete_interaction_response(
+                        interaction._token,
+                        interaction._application_id,
+                        message_id=self.id if not is_original_response else '@original'
+                    )
+                except HTTPException:
+                    pass
+
+            asyncio.ensure_future(delete(), loop=self._state.loop)
+        else:
+            await self._state.http.delete_interaction_response(
+                interaction._token,
+                interaction._application_id,
+                message_id=self.id if not is_original_response else '@original'
+            )
+
+
+class AuthorizingIntegrationOwners:
+    """
+    Includes details about the authorizing user or server (guild) for the installation(s) relevant to the interaction.
+    For apps installed to a user, it can be used to tell the difference between the authorizing user and the user
+    that triggered an interaction (like a message component).
+
+    An attribute will only be present if the following are true:
+
+    - The app has been authorized to the installation context (see :class:`~discord.AppIntegrationType`)
+    - The interaction is supported in the source :class:`~discord.InteractionContextType` for the installation context
+      corresponding to the key
+    - And for command invocations, the command must be supported in the installation context (using `integration_types`)
+
+    The values depend on the source of the interaction:
+
+    If the key is :attr:`~discord.AppIntegrationType.guild_install`, the value depends on the source of the interaction:
+        The value will be the guild ID if the interaction is triggered from a server
+        The value will be "0" if the interaction is triggered from a DM with the app's bot user
+    If the key is :attr:`~discord.AppIntegrationType.user_install`, the value will be the ID of the authorizing user
+    """
+    def __init__(self, data: AuthorizingIntegrationOwnersPayload, state: ConnectionState):
+        self._data = data
+
+    def __repr__(self):
+        return f'<AuthorizingIntegrationOwners {self._data!r}>'
+
+
+class BaseInteraction:
+    """
+    The Base-Class for a discord-interaction like clicking a :class:`~discord.Button`,
+    select (an) option(s) of :class:`~discord.SelectMenu` or using an application-command in discord
+    For more general information's about Interactions visit the Documentation of the
+    `Discord-API <https://discord.com/developers/docs/interactions/receiving-and-responding#interaction-object>`_
+
+    The following attributes are always available:
+
+    Attributes
+    ------------
+    id: :class:`int`
+        The id of the interaction.
+    type: :class:`~discord.InteractionType`
+        The type of the interaction.
+    user_id: :class:`int`
+        The id of the user who triggered the interaction.
+    channel_id: :class:`int`
+        The id of the channel where the interaction was triggered.
+    entitlements: Optional[List[:class:`~discord.Entitlement`]]
+        For :ddocs:`monetized apps <monetization/overview>` entitlements of the user who triggered the interaction
+        and optionally, if any.
+
+        This is available for all interaction types.
+    context: Optional[:class:`~discord.InteractionContextType`]
+        The context of the interaction, if any.
+    authorizing_guild_id: Optional[:class:`int`]
+        Depending on the context of the interaction, the guild ID where the app integration was authorized to:
+            - The value will be the guild ID if the interaction is triggered from a server
+            - The value will be `0` if the interaction is triggered from a DM with the app's bot user
+
+        .. seealso::
+            :attr:`.authorizing_guild`
+    authorizing_user_id: Optional[:class:`int`]
+        The ID of the user the app integration is authorized to, if any.
+
+        .. seealso::
+            :attr:`.authorizing_user`
+    data: :class:`~discord.InteractionData`
+        Some internal needed metadata for the interaction, depending on the type.
+    author_locale: Optional[:class:`~discord.Locale`]
+        The locale of the user who triggered the interaction.
+    guild_locale: Optional[:class:`~discord.Locale`]
+        The locale of the guild where the interaction was triggered.
+    guild_id: Optional[:class:`int`]
+        The id of the guild where the interaction was triggered, if any.
+    app_permissions: Optional[:class:`~discord.Permissions`]
+        The permissions of the bot in the channel where the interaction was triggered, if it was in a guild.
+
+        This is similar to `interaction.channel.permissions_for(interaction.guild.me)` but calculated on discord side.
+    author_permissions: Optional[:class:`~discord.Permissions`]
+        The author's permissions in the channel where the interaction was triggered, if it was in a guild.
+
+        This is similar to `interaction.channel.permissions_for(interaction.author)`, but calculated on discord side.
+    """
+    if TYPE_CHECKING:
+        type: InteractionType
+        id: int
+        context: Optional[InteractionContextType]  # Why is this optional?
+        authorizing_guild_id: Optional[int]
+        authorizing_user_id: Optional[int]
+        guild_id: Optional[int]
+        channel_id: int
+        user_id: int
+        user: User
+        author_locale: Locale
+        entitlements: Set[Entitlement]
+        app_permissions: Optional[Permissions]
+        author_permissions: Optional[Permissions]
+        member: Optional[Member]
+        guild_locale: Optional[Locale]
+        data: Optional[InteractionData]
+        message: Optional[Union[Message, EphemeralMessage]]
+        cached_message: Optional[Union[Message, EphemeralMessage]]
+        message_id: Optional[int]
+
+    def __init__(self, state: ConnectionState, data: InteractionPayload) -> None:
+        self._state: ConnectionState = state
+        self._http: HTTPClient = state.http
+        self._application_id = int(data.get('application_id'))
+        self._token = data['token']
+        self.type = InteractionType.try_value(data['type'])
+        self.id = int(data['id'])
+        self.context = try_enum(data.get('context'), InteractionContextType)
+        authorizing_integration_owners = data.get('authorizing_integration_owners')
+        self.authorizing_guild_id = utils._get_as_snowflake(authorizing_integration_owners, '0')
+        self.authorizing_user_id = utils._get_as_snowflake(authorizing_integration_owners, '1')
+        self.guild_id = guild_id = utils._get_as_snowflake(data, 'guild_id')
+        self.entitlements = {Entitlement(data=e, state=state) for e in data.get('entitlements', [])}
+        channel_data = data.get('channel', {})
+        self.channel_id = channel_id = int(data.get('channel_id', channel_data.get('id', 0)))
+
+        guild = self.guild or Object(id=guild_id) if guild_id else None  # I'm not sure if we need the Object thing here
+        channel, member = (None, None)
+
+        if guild:
+            member_data = data.get('member')
+            user_data = member_data.get('user')
+            self.user_id = user_id = int(user_data['id'])
+
+            if isinstance(guild, Guild):
+                channel = guild.get_channel(self.channel_id)
+                member = guild.get_member(user_id)
+
+            self.member = member or Member(state=state, data=member_data, guild=guild)
+            # consider updating the member here
+            self.author_permissions = Permissions(int(member_data.get('permissions', 0)))
+            self.guild_locale = try_enum(Locale, data.get('guild_locale'))
+        else:
+            channel = state._get_private_channel(channel_id)
+            user_data = data.get('user')
+            self.app_permissions = None
+            self.author_permissions = None
+            self.member = None
+            self.guild_locale = None
+            self.user_id = int(user_data['id'])
+
+        self.user = state.store_user(user_data)
+
+        if not channel:
+            factory, ch_type = _channel_factory(channel_data['type'])
+            if ch_type in (ChannelType.group, ChannelType.private):
+                # In my tests the required fields for those channels where always present
+                channel = factory(me=state.user, data=channel_data, state=state)
+            else:
+                channel = PartialMessageable(
+                    state=state,
+                    id=self.channel_id,
+                    guild_id=self.guild_id,
+                    type=ch_type,
+                    partial_data=channel_data
+                )
+
+        self._channel = channel
+
+        message_data: MessagePayload = data.get('message')
+        if message_data is not None:
+            if MessageFlags._from_value(message_data['flags']).ephemeral:
+                self.message = EphemeralMessage(state=state, channel=channel, data=message_data, interaction=self)
+            else:
+                self.message = Message(state=state, channel=channel, data=message_data)
+            # Remove this on release, it's unnecessary as we always get the full message (except reactions for components)
+            self.cached_message = self.message and state._get_message(self.message.id)
+            self.message_id = int(message_data['id'])
+        else:
+            self.message = None
+            self.cached_message = None
+            self.message_id = None
+
+        interaction_data: InteractionDataPayload = data.get('data')
+        if interaction_data is not None:
+            self.data = InteractionData(data=interaction_data, state=state, guild=self.guild, channel_id=self.channel_id)
+        else:
+            self.data = None
+
+        self.author_locale = try_enum(Locale, data['locale'])
+        self.deferred: bool = False
+        self.deferred_hidden: bool = False
+        self.deferred_modal: bool = False
+        self._command = None
+        self._callback_message: Optional[Union[Message, EphemeralMessage]] = None
+        self.messages: Dict[Union[str, int], Union[Message, EphemeralMessage]] = {}
+
+    def __repr__(self) -> str:
+        """Represents a :class:`~discord.BaseInteraction` object."""
+        return f'<{self.__class__.__name__} {", ".join([f"{k}={v}" for k, v in self.__dict__.items() if k[0] != "_"])}>'
+
+    @property
+    def authorizing_guild(self) -> Optional[Union[Guild, Object]]:
+        """Optional[Union[:class:`~discord.Guild`, :class:`~discord.Object`]]: The guild where the app integration was
+            authorized to. If not cached this will return an :class:`~discord.Object` with the ID set to the guild ID.
+
+
+        .. note::
+            This is only available for interactions that were triggered in a guild, in a DM this will be ``None``.
+        """
+        if self.authorizing_guild_id:
+            return self._state._get_guild(self.authorizing_guild_id) or Object(id=self.authorizing_guild_id)
+        return None
+
+    @property
+    def authorizing_user(self) -> Optional[User]:
+        """Optional[Union[:class:`~discord.User`, :class:`~discord.Object`]]: The user the app integration is
+            authorized to, if any.
+            If not cached this will return an :class:`~discord.Object` with the ID set to the user ID.
+        """
+        if self.authorizing_user_id:
+            return self._state.get_user(self.authorizing_user_id) or Object(id=self.authorizing_user_id)
+        return None
+
+    @property
+    def callback_message(self) -> Optional[Union[Message, EphemeralMessage]]:
+        """
+        Optional[Union[:class:`Message`, :class:`EphemeralMessage`]: The initial interaction response message, if any.
+        """
+        return self._callback_message
+    
+    @callback_message.setter
+    def callback_message(self, value: Optional[Union[Message, EphemeralMessage]]) -> None:
+        self._callback_message = value
+        if value:
+            self.messages['@original'] = value
+
+    async def _defer(
+            self,
+            response_type: Optional[InteractionCallbackType] = InteractionCallbackType.deferred_update_msg,
+            hidden: Optional[bool] = False
+    ) -> Optional[Union[Message, EphemeralMessage]]:
+        """
+        |coro|
+
+        'Defers' the response.
+
+        If :attr:`response_type` is `InteractionCallbackType.deferred_msg_with_source` it shows a loading state to the user.
+
+        response_type: Optional[:class:`InteractionCallbackType`]
+            The type to response with, aiter :class:`InteractionCallbackType.deferred_msg_with_source` or :class:`InteractionCallbackType.deferred_update_msg` (e.g. 5 or 6)
+
+        hidden: Optional[:class:`bool`]
+            Whether to defer ephemerally(only the :attr:`author` of the interaction can see the message)
+
+            .. note::
+                Only for :class:`InteractionCallbackType.deferred_msg_with_source`.
+
+        .. important::
+            If you don't respond with a message using :meth:`respond`
+            or edit the original message using :meth:`edit` within less than 3 seconds,
+            discord will indicate that the interaction failed and the interaction-token will be invalidated.
+            To provide this us this method
+
+        .. note::
+            A Token will be Valid for 15 Minutes, so you could edit the original :attr:`message` with :meth:`edit`,
+             :meth:`respond` or doing anything other with this interaction for 15 minutes.
+            After that time you have to edit the original message with the Methode :meth:`edit` of the :attr:`message`
+             and send new messages with the :meth:`send` Methode of :attr:`channel`
+            (you could not do this hidden as it isn't a response anymore).
+        """
+        if isinstance(response_type, int):
+            response_type = InteractionCallbackType.from_value(response_type)
+        if self.deferred:
+            raise AlreadyResponded(self.id)
+        base = {"type": int(response_type), "data": {'flags': 64 if hidden else None}}
+        try:
+            data = await self._http.post_initial_response(
+                data=base,
+                token=self._token,
+                interaction_id=self.id
+            )
+        except NotFound:
+            raise UnknownInteraction(self.id)
+        else:
+            self.deferred = True
+            if hidden is True:
+                self.deferred_hidden = True
+            if not data and response_type.msg_with_source or response_type.deferred_msg_with_source:
+                msg = self.callback_message = await self.get_original_callback()
+                return msg
+
+    @utils.deprecated("Respond normal using ButtonType.premium instead")
+    async def _premium_required(self) -> None:
+        """|coro|
+        Respond with an upgrade button, only available for apps
+        with :ddocs:`monetized apps <monetization/overview>` enabled.
+        """
+        await self._state.http.post_initial_response(
+            self.id,
+            self._token,
+            data={'type': InteractionCallbackType.premium_required.value}
+        )
+
+    async def _respond_with_launch_activity(self) -> None:
+        """|coro|
+        Respond by launching the activity associated with the application.
+        Only available for apps with :ddocs:`Activities <activities/overview>` enabled.
+        """
+        await self._state.http.post_initial_response(
+            self.id,
+            self._token,
+            data={'type': InteractionCallbackType.launch_activity.value}
+        )
+
+    async def edit(
+            self,
+            *,
+            content: Any = MISSING,
+            embed: Optional[Embed] = MISSING,
+            embeds: Sequence[Embed] = MISSING,
+            components: List[Union[ActionRow, List[Union[Button, BaseSelect]]]] = MISSING,
+            attachments: Sequence[Union[Attachment, File]] = MISSING,
+            keep_existing_attachments: bool = False,
+            delete_after: Optional[float] = None,
+            allowed_mentions: Optional[AllowedMentions] = MISSING,
+            suppress_embeds: Optional[bool] = False
+    ) -> Union[Message, EphemeralMessage]:
+        """|coro|
+
+        Responds to the interaction by editing the original (:attr:`~ComponentInteraction.message`)
+        or :attr:`callback_message`, depending on the :attr:`~BaseInteraction.type`.
+
+        Parameters
+        -----------
+        content: Optional[:class:`str`]
+            The new content to replace the message with.
+            Could be ``None`` to remove the content.
+        embed: Optional[:class:`Embed`]
+            The new embed to replace the original with.
+            Could be ``None`` to remove all embeds.
+        embeds: Optional[List[:class:`Embed`]]
+            A list containing up to 10 embeds to send.
+            If ``None`` or empty, all embeds will be removed.
+            
+            If passed, ``embed`` does also count towards the limit of 10 embeds.
+        components: List[Union[:class:`~discord.ActionRow`, List[Union[:class:`~discord.Button`, :ref:`Select <select-like-objects>`]]]]
+            A list of up to five :class:`~discord.ActionRow` or :class:`list`,
+            each containing up to five :class:`~discord.Button` or one :ref:`Select <select-like-objects>` like object.
+        attachments: List[Union[:class:`Attachment`, :class:`File`]]
+            A list containing previous attachments to keep as well as new files to upload.
+            You can use ``keep_existing_attachments`` to auto-add the existing attachments to the list.
+            If ``None`` or empty, all attachments will be removed.
+
+            .. note::
+
+                New files will always appear under existing ones.
+
+        keep_existing_attachments: :class:`bool`
+            Whether to auto-add existing attachments to ``attachments``, default :obj:`False`.
+            
+            .. note::
+
+                Only needed when ``attachments`` are passed, otherwise will be ignored.
+
+        suppress_embeds: :class:`bool`
+            Whether to suppress embeds for the message. This removes
+            all the embeds if set to ``True``. If set to ``False``
+            this brings the embeds back if they were suppressed.
+        delete_after: Optional[:class:`float`]
+            If provided, the number of seconds to wait in the background
+            before deleting the response we just edited. If the deletion fails,
+            then it is silently ignored.
+        allowed_mentions: Optional[:class:`~discord.AllowedMentions`]
+            Controls the mentions being processed in this message. If this is
+            passed, then the object is merged with :attr:`~discord.Client.allowed_mentions`.
+            The merging behaviour only overrides attributes that have been explicitly passed
+            to the object, otherwise it uses the attributes set in :attr:`~discord.Client.allowed_mentions`.
+            If no object is passed at all then the defaults given by :attr:`~discord.Client.allowed_mentions`
+            are used instead.
+        
+        Raises
+        -------
+        TypeError
+            The interaction was already responded to with a modal,
+            or it is an application-command that was not responded to.
+        NotFound:
+            The interaction is expired.
+        HTTPException
+            Editing the message failed.
+        
+        Returns
+        --------
+        Union[:class:`~discord.Message`, :class:`~discord.EphemeralMessage`]
+            The edited message.
+        """
+        if self.deferred_modal:
+            if self.type.Component:
+                return await self.message.edit(
+                    content=content,
+                    embed=embed,
+                    embeds=embeds,
+                    components=components,
+                    attachments=attachments,
+                    keep_existing_attachments=keep_existing_attachments,
+                    allowed_mentions=allowed_mentions,
+                    delete_after=delete_after,
+                    suppress_embeds=suppress_embeds
+                )
+            else:
+                raise TypeError('You can\'t edit the message as it does not exist when using `respond_with_modal`.')
+
+        response_type = MISSING
+
+        if not self.deferred:
+            if self.type.ApplicationCommand:
+                raise TypeError('You need to send a response first before you can edit it')
+            else:
+                response_type = InteractionCallbackType.update_msg
+
+        m = self.callback_message if self.type.ApplicationCommand else self.message
+        
+        if suppress_embeds is not MISSING:
+            flags = MessageFlags._from_value(m.flags.value) if m else MessageFlags._from_value(0)
+            flags.suppress_embeds = suppress_embeds
+        else:
+            flags = MISSING
+
+        state = self._state
+        if not self.channel:
+            ch = await self._http.get_channel(self.channel_id)
+            self.channel = _channel_factory(ch['type'])[0](state=state, data=ch)
+
+        if response_type is MISSING:
+            params = handle_message_parameters(
+                content=content,
+                flags=flags,
+                embed=embed,
+                embeds=embeds,
+                attachments=attachments,
+                components=components,
+                allowed_mentions=allowed_mentions,
+                previous_allowed_mentions=state.allowed_mentions
+            )
+            method = state.http.edit_original_interaction_response(
+                token=self._token,
+                application_id=self._application_id,
+                params=params
+            )
+        else:
+            params = handle_interaction_message_parameters(
+                type=response_type,
+                content=content,
+                flags=flags,
+                embed=embed,
+                attachments=attachments,
+                components=components,
+                allowed_mentions=allowed_mentions,
+                previous_allowed_mentions=state.allowed_mentions
+            )
+            method = state.http.send_interaction_response(
+                interaction_id=self.id,
+                token=self._token,
+                params=params
+            )
+
+        with params:
+            data = await method
+
+        if not isinstance(data, dict):
+            msg = await self.get_original_callback()
+        else:
+            if m is not None:
+                msg = m._update(data)
+            else:
+                if MessageFlags._from_value(data['flags']).ephemeral:
+                    msg = EphemeralMessage(state=self._state, data=data, channel=self.channel, interaction=self)
+                else:
+                    msg = Message(state=self._state, channel=self.channel, data=data)
+        if not self.deferred:
+            self.callback_message = msg
+        is_hidden = msg.flags.ephemeral
+
+        if is_hidden:
+            self.deferred_hidden = True
+        self.deferred = True
+        
+        if delete_after is not None:
+            await msg.delete(delay=delete_after)
+        
+        return msg
+
+    async def respond(
+            self,
+            content: str = None, *,
+            tts: bool = False,
+            embed: Optional[Embed] = None,
+            embeds: Optional[List[Embed]] = None,
+            components: Optional[List[Union[ActionRow, List[Union[Button, BaseSelect]]]]] = None,
+            file: Optional[File] = None,
+            files: Optional[List[File]] = None,
+            delete_after: Optional[float] = None,
+            allowed_mentions: Optional[AllowedMentions] = None,
+            suppress_embeds: bool = False,
+            suppress_notifications: bool = False,
+            hidden: bool = False
+    ) -> Union[Message, EphemeralMessage]:
+        """|coro|
+
+        Responds to an interaction by sending a message.
+
+        Parameters
+        ------------
+        content: :class:`str`
+            The content of the message to send.
+        tts: :class:`bool`
+            Indicates if the message should be sent using text-to-speech.
+        embed: :class:`~discord.Embed`
+            The rich embed for the content.
+        embeds: List[:class:`~discord.Embed`]
+            A list containing up to 10 embeds.
+            
+            If passed, ``embed`` also counts towards the limit of 10.
+        components: List[Union[:class:`~discord.ActionRow`, List[Union[:class:`~discord.Button`, :ref:`Select <select-like-objects>`]]]]
+            A list of up to five :class:`~discord.ActionRow`s/:class:`list`s.
+            Each containing up to five :class:`~discord.Button` or one :ref:`Select <select-like-objects>` like object.
+        file: :class:`~discord.File`
+            The file to upload.
+        files: List[:class:`~discord.File`]
+            A :class:`list` of files to upload. Must be a maximum of 10.
+        suppress_embeds: :class:`bool`
+            Whether to suppress embeds for the message.
+        suppress_notifications: :class:`bool`
+            Whether to suppress desktop- & push-notifications for the post starter-message.
+        delete_after: :class:`float`
+            If provided, the number of seconds to wait in the background
+            before deleting the response we just sent. If the deletion fails,
+            then it is silently ignored.
+        allowed_mentions: :class:`~discord.AllowedMentions`
+            Controls the mentions being processed in this message. If this is
+            passed, then the object is merged with :attr:`~discord.Client.allowed_mentions`.
+            The merging behaviour only overrides attributes that have been explicitly passed
+            to the object, otherwise it uses the attributes set in :attr:`~discord.Client.allowed_mentions`.
+            If no object is passed at all then the defaults given by :attr:`~discord.Client.allowed_mentions`
+            are used instead.
+        hidden: Optional[:class:`bool`]
+            If :obj:`True` the message will be only visible for the performer of the interaction (e.g. :attr:`.author`).
+        
+        Raises
+        -------
+        TypeError
+            This interaction was already responded to with a modal.
+        NotFound
+            The interaction has expired.
+        HTTPException
+            Responding to the interaction failed.
+        """
+
+        if self.deferred_modal:
+            raise TypeError('After responding to the interaction with a modal, you can\'t respond.')
+        state = self._state
+
+        flags = MessageFlags._from_value(0)
+        flags.ephemeral = hidden
+        flags.suppress_embeds = suppress_embeds
+        flags.suppress_notifications = suppress_notifications
+
+        is_initial = False
+        response_type = MISSING
+
+        if not self.deferred:
+            response_type = InteractionCallbackType.msg_with_source
+        else:
+            if self.callback_message and (self.callback_message.flags.loading if self.type.ApplicationCommand else False):
+                is_initial = True
+
+        if response_type is MISSING:
+            params = handle_message_parameters(
+                content=content,
+                tts=tts,
+                flags=flags,
+                embed=embed or MISSING,
+                embeds=embeds or MISSING,
+                file=file or MISSING,
+                files=files or MISSING,
+                components=components or MISSING,
+                allowed_mentions=allowed_mentions,
+                previous_allowed_mentions=state.allowed_mentions
+            )
+            if is_initial:
+                method = state.http.edit_original_interaction_response(
+                    token=self._token,
+                    application_id=self._application_id,
+                    params=params
+                )
+            else:
+                method = state.http.send_followup(
+                    token=self._token,
+                    application_id=self._application_id,
+                    params=params
+                )
+        else:
+            params = handle_interaction_message_parameters(
+                type=response_type,
+                content=content,
+                tts=tts,
+                flags=flags,
+                embed=embed or MISSING,
+                embeds=embeds or MISSING,
+                file=file or MISSING,
+                files=files or MISSING,
+                components=components or MISSING,
+                allowed_mentions=allowed_mentions,
+                previous_allowed_mentions=state.allowed_mentions
+            )
+            method = state.http.send_interaction_response(
+                token=self._token,
+                interaction_id=self.id,
+                params=params
+            )
+
+        with params:
+            data = await method
+
+        if not isinstance(data, dict):
+            data = await self.get_original_callback(raw=True)
+
+        # We can't use the value from the params here because the message might be an edit/followup of the initial (hidden or not) response.
+        # Anyway, this will be removed in the future when we switched to use the webhook message modell for interactions.
+        is_hidden = MessageFlags._from_value(data['flags']).ephemeral
+        if is_hidden:
+            msg = EphemeralMessage(state=self._state, channel=self.channel, data=data, interaction=self)
+        else:
+            msg = Message(state=self._state, channel=self.channel, data=data)
+
+        
+        if not self.callback_message or is_initial:
+            self.callback_message = msg
+        else:
+            self.messages[msg.id] = msg
+        if response_type is not MISSING or is_initial:
+            self.deferred = True
+            if is_hidden:
+                self.deferred_hidden = True
+        if delete_after is not None:
+            await msg.delete(delay=delete_after)
+        return msg
+
+    async def respond_with_modal(self, modal: Modal) -> Dict:
+        """|coro|
+        Respond to an interaction with a popup modal.
+
+        Parameters
+        ----------
+        modal: :class:`~discord.Modal`
+            The modal to send.
+        
+        Raises
+        -------
+        AlreadyResponded
+            This interaction was already responded to.
+        HTTPException
+            Responding to the interaction failed.
+        """
+        if not self.deferred:
+            data = await self._state.http.post_initial_response(
+                token=self._token,
+                interaction_id=self.id,
+                data={'type': 9, 'data': modal.to_dict()}
+            )
+        else:
+            raise AlreadyResponded(self.id)
+        self.deferred = True
+        self.deferred_modal = True
+        return data
+
+    async def get_original_callback(self, raw: bool = False) -> Union[Message, EphemeralMessage, dict]:
+        """|coro|
+        Fetch the original callback-message of the interaction.
+
+        .. warning::
+
+            This is an API-Call and should be used carefully
+
+        Parameters
+        ----------
+        raw: Optional[:class:`bool`]
+            Whether to return the raw data from the api instead of a :class:`~discord.Message`/:class:`EphemeralMessage`.
+        
+        Returns
+        -------
+        Union[:class:`~discord.Message`,:class:`EphemeralMessage`], :class:`dict`]
+            The original callback-message of the interaction.
+        """
+        data = await self._state.http.get_original_interaction_response(self._token, self._application_id)
+        if raw:
+            return data
+        if MessageFlags._from_value(data['flags']).ephemeral:
+            msg = EphemeralMessage(state=self._state, data=data, channel=self.channel, interaction=self)
+        else:
+            msg = Message(state=self._state, channel=self.channel, data=data)
+        self.callback_message = msg
+        return msg
+
+    def get_followup(self, id: int) -> Optional[Union[Message, EphemeralMessage]]:
+        """
+        Gets a followup message of this interaction with the given :attr:`~discord.BaseInteraction.id`.
+
+        Parameters
+        -----------
+        id: :class:`int`
+            The id of the followup message.
+
+        Returns
+        -------
+        Optional[Union[:class:`~discord.Message`, :class:`~discord.EphemeralMessage`]]
+            The followup or ``None`` if there is none.
+        """
+        return self.messages.get(id, None)
+
+    @property
+    def created_at(self) -> datetime.datetime:
+        """
+        Returns the Interaction’s creation time in UTC.
+
+        :return: :class:`datetime.datetime`
+        """
+        return utils.snowflake_time(self.id)
+
+    @property
+    def author(self) -> Union[Member, User]:
+        """
+        Union[:class:`~discord.Member`, :class:`~discord.User`]: The :class:`~discord.Member` that invoked the interaction.
+        If :attr:`.channel` is of type :class:`~discords.ChannelType.private` or the user has left the guild,
+        then it is a :class:`~discord.User` instead.
+        """
+        return self.member if self.member is not None else self.user
+
+    @property
+    def channel(self) -> Union[DMChannel, TextChannel, ThreadChannel, ForumPost, VoiceChannel, PartialMessageable]:
+        """
+        Union[
+            :class:`~discord.TextChannel`,
+            :class:`~discord.ThreadChannel`,
+            :class:`~discord.DMChannel`,
+            :class:`~discord.VoiceChannel`,
+            :class:`~discord.ForumPost`,
+            :class:`~discord.PartialMessageable`
+        ]: The channel where the interaction was invoked in.
+        """
+        # TODO: I think we can remove this now
+        return getattr(
+            self,
+            '_channel',
+            self.guild.get_channel(self.channel_id) if isinstance(self.guild, Guild) else self._state.get_channel(self.channel_id)
+        ) or PartialMessageable(state=self._state, id=self.channel_id, guild_id=self.guild_id)
+
+    @channel.setter
+    def channel(self, channel):
+        self._channel = channel
+
+    @property
+    def guild(self) -> Optional[Guild]:
+        """Optional[:class:`~discord.Guild`]: The guild the interaction was invoked in, if there is one."""
+        return self._state._get_guild(self.guild_id)
+
+    @property
+    @utils.deprecated('is_dm')
+    def message_is_dm(self) -> bool:
+        """:class:`bool`: An deprecated alias to :attr:`is_dm`."""
+        return not self.guild_id
+
+    @property
+    def is_dm(self) -> bool:
+        """:class:`bool`: Whether the interaction was invoked in a :class:`~discord.DMChannel`."""
+        return not self.guild_id
+
+    @property
+    def bot(self):
+        """Union[:class:`~discord.Client`, :class:`~discord.ext.commands.Bot`]:
+        The :class:`~discord.Client`/:class:`~discord.ext.commands.Bot` instance of the bot."""
+        return self._state._get_client()
+
+    @classmethod
+    def from_type(cls, state: ConnectionState, data: InteractionPayload) -> Union[ApplicationCommandInteraction, ComponentInteraction, AutocompleteInteraction, ModalSubmitInteraction]:
+        type = try_enum(InteractionType, data['type'])
+        if type == InteractionType.ApplicationCommand:
+            return ApplicationCommandInteraction(state=state, data=data)
+        elif type == InteractionType.Component:
+            return ComponentInteraction(state=state, data=data)
+        elif type == InteractionType.ApplicationCommandAutocomplete:
+            return AutocompleteInteraction(state=state, data=data)
+        elif type == InteractionType.ModalSubmit:
+            return ModalSubmitInteraction(state=state, data=data)
+
+
+class ApplicationCommandInteraction(BaseInteraction):
+    """
+    Holds the data of an interaction when a `~discord.SlashCommand`,
+    :class:`~discord.UserCommand` or :class:`~discord.MessageCommand` is used and allows responding to it.
+
+    Attributes
+    ------------
+    id: :class:`int`
+        The id of the interaction.
+    type: :class:`~discord.InteractionType`
+        The type of the interaction.
+    user_id: :class:`int`
+        The id of the user who triggered the interaction.
+    channel_id: :class:`int`
+        The id of the channel where the interaction was triggered.
+    messages: Dict[:class:`int`, Union[:class:`~discord.Message`, :class:`~discord.EphemeralMessage`]]
+        A mapping of message id's to the message objects that were sent using :attr:`respond`.
+    author_locale: Optional[:class:`~discord.Locale`]
+        The locale of the user who triggered the interaction.
+    guild_locale: Optional[:class:`~discord.Locale`]
+        The locale of the guild where the interaction was triggered.
+    guild_id: Optional[:class:`int`]
+        The id of the guild where the interaction was triggered, if any.
+    app_permissions: Optional[:class:`~discord.Permissions`]
+        The permissions of the bot in the channel where the interaction was triggered, if it was in a guild.
+    target: Optional[Union[:class:`~discord.Member`, :class:`~discord.Message`]]
+        The resolved target of the interaction, if it is a user or message command.
+    """
+    if TYPE_CHECKING:
+        target: Optional[Union[Member, User, Message]]
+
+    def __init__(self, *args, **kwargs):
+        super().__init__(*args, **kwargs)
+        target_id = self.data.target_id
+        if target_id:
+            target_type = self.data.type
+            resolved = self.data.resolved
+            if target_type == ApplicationCommandType.user:
+                self.target = resolved.members.get(target_id) or resolved.users.get(target_id)
+            elif target_type == ApplicationCommandType.message:
+                self.target = resolved.messages[target_id]
+        else:
+            self.target = None
+
+    @property
+    def command(self) -> Optional[Union[SlashCommand, MessageCommand, UserCommand]]:
+        """Union[:class:`~discord.SlashCommand`, :class:`~discord.UserCommand`, :class:`~discord.MessageCommand`]:
+        The application-command that was invoked."""
+        if getattr(self, '_command', None) is not None:
+            return self._command
+        return self._state._get_client()._get_application_command(self.data.id) \
+            if (self.type.ApplicationCommand or self.type.ApplicationCommandAutocomplete) else None
+
+    async def defer(self, hidden: bool = False) -> Union[Message, EphemeralMessage]:
+        """
+        Defers the interaction, the user sees a loading state
+
+        Parameters
+        ----------
+        hidden: Optional[:class:`bool`]
+            Weather only the author of the command should see this
+        
+        Raises
+        ------
+        AlreadyResponded
+            The interaction has already been responded to.
+        UnknownInteraction
+            The interaction has expired.
+        
+        Returns
+        -------
+        Union[:class:`~discord.Message, :class:`~discord.EphemeralMessage`]:
+            The Message containing the loading state
+        """
+        data = await super()._defer(InteractionCallbackType.deferred_msg_with_source, hidden)
+        return data
+
+    async def respond_with_premium_required(self) -> None:
+        """|coro|
+        **Deprecated** Respond normal using :attr:`~discord.ButtonType.premium` instead.
+
+
+        Respond with an upgrade button, only available for apps
+        with :ddocs:`monetized apps <monetization/overview>` enabled.
+
+        .. note::
+            You must respond with this one directly, without using any of
+            :meth:`~discord.ApplicationCommandInteraction.defer` or
+            :meth:`~discord.ApplicationCommandInteraction.respond`.
+        """
+        return await super()._premium_required()
+
+    async def respond_with_launch_activity(self) -> None:
+        """|coro|
+        Respond by launching the activity associated with the application.
+        Only available for apps with :ddocs:`Activities <activities/overview>` enabled.
+
+        .. note::
+            You must respond with this one directly, without using any of
+            :meth:`~discord.ApplicationCommandInteraction.defer` or
+            :meth:`~discord.ApplicationCommandInteraction.respond`.
+        """
+        return await super()._respond_with_launch_activity()
+
+
+class ComponentInteraction(BaseInteraction):
+    """
+    Holds the data of an interaction with a button or select and allows responding to it.
+
+    Attributes
+    ------------
+    id: :class:`int`
+        The id of the interaction.
+    type: :class:`~discord.InteractionType`
+        The type of the interaction.
+    user_id: :class:`int`
+        The id of the user who triggered the interaction.
+    channel_id: :class:`int`
+        The id of the channel where the interaction was triggered.
+    messages: Dict[:class:`int`, Union[:class:`~discord.Message`, :class:`~discord.EphemeralMessage`]]
+        A mapping of message id's to the message objects that were sent using :attr:`respond`.
+    author_locale: Optional[:class:`~discord.Locale`]
+        The locale of the user who triggered the interaction.
+    guild_locale: Optional[:class:`~discord.Locale`]
+        The locale of the guild where the interaction was triggered.
+    message: Optional[Union[:class:`~discord.Message`, :class:`~discord.EphemeralMessage`]
+        The message the component is attached to.
+    cached_message: Optional[Union[:class:`~discord.Message`, :class:`~discord.EphemeralMessage`]
+        The cached version of :attr:`message`, if any.
+    guild_id: Optional[:class:`int`]
+        The id of the guild where the interaction was triggered, if any.
+    app_permissions: Optional[:class:`~discord.Permissions`]
+        The permissions of the bot in the channel where the interaction was triggered, if it was in a guild.
+    match: Optional[:class:`~re.Match`]
+        The RegEx |match_object| result of the custom_id of
+        the component, if an ``on_click`` or ``on_select`` decorator was used.
+    """
+    if TYPE_CHECKING:
+        match: Optional[Match]
+
+    @property
+    def message_is_hidden(self) -> bool:
+        """:class:`bool`: Whether the :attr:`message` has the :func:`~discord.MessageFlags.ephemeral` flag."""
+        return self.message and self.message.flags.ephemeral
+
+    @cached_slot_property('_cs_component')
+    def component(self) -> Union[Button, SelectMenu, UserSelect, RoleSelect, MentionableSelect, ChannelSelect]:
+        """
+        Union[:class:`~discord.Button`, :ref:`Select <select-like-objects>` like objects]: The component that was used
+        """
+        custom_id = self.data.custom_id
+        component_type = self.data.component_type
+        if custom_id.isdigit():
+            custom_id = int(custom_id)
+
+        if component_type == ComponentType.Button:
+            return utils.get(self.message.all_buttons, custom_id=custom_id)
+        elif component_type.value in {3, 5, 6, 7, 8}:
+            select_menu = utils.get(self.message.all_select_menus, custom_id=custom_id)
+            setattr(select_menu, '_values', self.data.values)
+            setattr(select_menu, '_interaction', self)
+            return select_menu
+        else:
+            raise ValueError(f'Unknown component type {self.data.component_type}')
+
+    async def defer(
+            self,
+            type: Union[Literal[7], InteractionCallbackType] = InteractionCallbackType.deferred_update_msg,
+            hidden: bool = False
+    ) -> Message:
+        """
+        Defers the interaction.
+
+        Parameters
+        ----------
+        type: Union[Literal[5, 6]]
+            Use ``5`` to edit the original message later and ``6`` to let the user sees a loading state and edit it later.
+        hidden: Optional[:class:`bool`]
+            Weather only the author of the command should see this, default :obj:`True`
+
+             .. note::
+                Only for :attr:`~discord.InteractionCallbackType.deferred_msg_with_source` (``5``).
+        
+        Raises
+        ------
+        AlreadyResponded
+            The interaction has already been responded to.
+        UnknownInteraction
+            The interaction has expired.
+        
+        Returns
+        -------
+        Optional[Union[:class:`~discord.Message, :class:`~discord.EphemeralMessage`]]:
+            The message containing the loading-state if :class:`~discord.InteractionCallbackType.deferred_msg_with_source` (``5``) is used, else :obj:`None`.
+        """
+        return await super()._defer(type, hidden)
+
+    async def respond_with_premium_required(self) -> None:
+        """|coro|
+        Respond with an upgrade button, only available for apps
+        with :ddocs:`monetized apps <monetization/overview>` enabled.
+
+        .. note::
+            You must respond with this one directly, without using any of
+            :meth:`~discord.ComponentInteraction.defer` or
+            :meth:`~discord.ComponentInteraction.respond`.
+        """
+        return await super()._premium_required()
+
+    async def respond_with_launch_activity(self) -> None:
+        """|coro|
+        Respond by launching the activity associated with the application.
+        Only available for apps with :ddocs:`Activities <activities/overview>` enabled.
+
+        .. note::
+            You must respond with this one directly, without using any of
+            :meth:`~discord.ComponentInteraction.defer` or
+            :meth:`~discord.ComponentInteraction.respond`.
+        """
+        return await super()._respond_with_launch_activity()
+
+
+class AutocompleteInteraction(BaseInteraction):
+    """
+    Holds the data of an application command autocomplete interaction that will be received when autocomplete for a
+    :class:`~discord.SlashCommandOption` with :attr:`~discord.SlashCommandOption.autocomplete` is set to :obj:`True`.
+
+    To respond with the autocomplete choices, use :meth:`send_choices`.
+
+    Attributes
+    ------------
+    id: :class:`int`
+        The id of the interaction.
+    type: :class:`~discord.InteractionType`
+        The type of the interaction.
+    user_id: :class:`int`
+        The id of the user who triggered the interaction.
+    channel_id: :class:`int`
+        The id of the channel where the interaction was triggered.
+    author_locale: Optional[:class:`~discord.Locale`]
+        The locale of the user who triggered the interaction.
+    guild_locale: Optional[:class:`~discord.Locale`]
+        The locale of the guild where the interaction was triggered.
+    guild_id: Optional[:class:`int`]
+        The id of the guild where the interaction was triggered, if any.
+    app_permissions: Optional[:class:`~discord.Permissions`]
+        The permissions of the bot in the channel where the interaction was triggered, if it was in a guild.
+    """
+
+    @property
+    def command(self) -> Optional[Union[SlashCommand, MessageCommand, UserCommand]]:
+        """Optional[:class:`~discord.SlashCommand`]: The slash-command for which autocomplete was triggered."""
+        if getattr(self, '_command', None) is not None:
+            return self._command
+        return self._state._get_client()._get_application_command(self.data.id) \
+            if (self.type.ApplicationCommand or self.type.ApplicationCommandAutocomplete) else None
+
+    @property
+    def focused_option(self) -> 'InteractionDataOption':
+        """:class:`~discord.interactions.InteractionDataOption`: Returns the currently focused option."""
+        return self.focused  # type: ignore
+
+    @property
+    def focused_option_name(self) -> str:
+        """:class:`str`: Returns the name of the currently focused option."""
+        return self.focused_option.name
+
+    async def send_choices(self, choices: List[SlashCommandOptionChoice]) -> None:
+        """
+        Respond to the interaction with the choices the user should have.
+
+        Parameters
+        ----------
+        choices: List[:class:`~discord.SlashCommandOptionChoice`]
+            A list of maximum 25 options the user could choose from.
+
+        Raises
+        ------
+        ValueError
+            When more than 25 choices are passed.
+        NotFound
+            You have been waited to long with responding to the interaction.
+        """
+        if len(choices) > 25:
+            raise ValueError(f'The maximum of choices is 25. Got {len(choices)}.')
+        else:
+            await self._http.send_autocomplete_callback(
+                token=self._token,
+                interaction_id=self.id,
+                choices=[choice.to_dict() for choice in choices]
+            )
+
+    @utils.copy_doc(send_choices)
+    @utils.deprecated('send_choices')
+    async def suggest(self, choices: List[SlashCommandOptionChoice]) -> None:
+        """An aliase for :meth:`.send_choices`"""
+        return await self.send_choices(choices)
+
+    async def respond(self, *args, **kwargs):
+        raise NotImplementedError
+
+    async def defer(self, *args, **kwargs):
+        raise NotImplementedError('You must directly respond to an autocomplete interaction.')
+
+    async def respond_with_premium_required(self) -> None:
+        raise NotImplementedError('You must directly respond to an autocomplete interaction.')
+
+    async def respond_with_launch_activity(self) -> None:
+        raise NotImplementedError('You must directly respond to an autocomplete interaction.')
+
+
+class ModalSubmitInteraction(BaseInteraction):
+    """Holds the data of an interaction that will be received when the ``Submit`` button of a :class:`~discord.Modal`
+    is pressed and allows responding to it.
+
+    .. note::
+        You **can't** respond to a modal submit interaction with another modal.
+
+    Attributes
+    -----------
+    id: :class:`int`
+        The id of the interaction.
+    type: :class:`~discord.InteractionType`
+        The type of the interaction.
+    user_id: :class:`int`
+        The id of the user who triggered the interaction.
+    channel_id: :class:`int`
+        The id of the channel where the interaction was triggered.
+    messages: Dict[:class:`int`, Union[:class:`~discord.Message`, :class:`~discord.EphemeralMessage`]]
+        A mapping of message id's to the message objects that were sent using :attr:`respond`.
+    author_locale: Optional[:class:`~discord.Locale`]
+        The locale of the user who triggered the interaction.
+    guild_locale: Optional[:class:`~discord.Locale`]
+        The locale of the guild where the interaction was triggered.
+    cached_message: Optional[Union[:class:`~discord.Message`, :class:`~discord.EphemeralMessage`]
+        The cached version of :attr:`message`, if any.
+    guild_id: Optional[:class:`int`]
+        The id of the guild where the interaction was triggered, if any.
+    app_permissions: Optional[:class:`~discord.Permissions`]
+        The permissions of the bot in the channel where the interaction was triggered, if it was in a guild.
+    match: Optional[|match_object|]
+        The RegEx |match_object| result of the custom_id of
+        the modal, if an ``on_submit`` decorator was used.
+    """
+
+    if TYPE_CHECKING:
+        match: Optional[Match]
+
+    @overload
+    def get_field(self, custom_id: str) -> Optional[TextInput]: ...
+
+    @overload
+    def get_field(self, custom_id: re.Pattern) -> Optional[Tuple[TextInput, Match]]: ...
+
+    def get_field(self, custom_id: Union[str, re.Pattern]) -> Optional[Union[TextInput, Tuple[TextInput, Match]]]:
+        """
+        Gets the field which :attr:`~discord.TextInput.custom_id` match, if any.
+
+        Parameters
+        ----------
+        custom_id: Union[:class:`str`, |pattern_object|]
+            The custom_id of the field to get.
+
+            .. note::
+                You can also pass a |pattern_object| when you want to use dynamic custom_id's.
+                Only the first matching field will be returned.
+
+        Returns
+        -------
+        Optional[Union[:class:`~discord.TextInput`, Tuple[:class:`~discord.TextInput`, |match_object|]]]:
+            - If ``custom_id`` is a :class:`str`, the found :class:`TextInput` is returned, if any.
+            - if ``custom_id`` is a |pattern_object| a :class:`tuple` is returned containing the field
+                which :attr:`~discord.TextInput.custom_id` matches and the corresponding |match_object|, if any.
+        """
+        if isinstance(custom_id, re.Pattern):
+            def _check(_c: TextInput):
+                match = custom_id.match(_c.custom_id)
+                if match:
+                    return _c, match
+        else:
+            def _check(_c: TextInput):
+                if _c.custom_id == custom_id:
+                    return _c
+        for ar in self.data.components:
+            for c in ar:
+                result = _check(c)
+                if result:
+                    return result
+        return None
+
+    @property
+    def fields(self) -> List[TextInput]:
+        """
+        List[:class:`~discord.TextInput`]: Returns a :class:`list` containing the fields of the :class:`~discord.Modal`.
+        """
+        field_list = []
+        for ar in self.data.components:
+            for c in ar:
+                field_list.append(c)
+        return field_list
+
+    @property
+    def custom_id(self) -> str:
+        """
+        The Custom ID of the :class:`~discord.Modal`
+
+        Returns
+        -------
+        :class:`str`
+            The :attr:`~discord.Modal.custom_id` of the :class:`~discord.Modal`.
+        """
+        return self.data.custom_id
+
+    async def defer(self, hidden: Optional[bool] = False) -> Optional[Union[Message, EphemeralMessage]]:
+        """
+        Defers the interaction, the user sees a loading state
+
+        Parameters
+        ----------
+        hidden: Optional[:class:`bool`]
+            Weather only the author of the modal should see this
+        
+        Raises
+        ------
+        AlreadyResponded
+            The interaction has already been responded to.
+        UnknownInteraction
+            The interaction has expired.
+        
+        Returns
+        -------
+        Union[:class:`~discord.Message, :class:`~discord.EphemeralMessage`]:
+            The Message containing the loading-state.
+        """
+        return await super()._defer(InteractionCallbackType.deferred_msg_with_source, hidden)
+
+    async def respond_with_modal(self, modal: Modal) -> NotImplementedError:
+        raise NotImplementedError('You can\'t respond to a modal submit with another modal.')
+
+    async def respond_with_premium_required(self) -> None:
+        """|coro|
+        Respond with an upgrade button, only available for apps
+        with :ddocs:`monetized apps <monetization/overview>` enabled.
+
+        .. note::
+            You must respond with this one directly, without using any of
+            :meth:`~discord.ModalSubmitInteraction.defer` or
+            :meth:`~discord.ModalSubmitInteraction.respond`.
+        """
+        await super()._premium_required()
+
+    async def respond_with_launch_activity(self) -> None:
+        """|coro|
+        Respond by launching the activity associated with the application.
+        Only available for apps with :ddocs:`Activities <activities/overview>` enabled.
+
+        .. note::
+            You must respond with this one directly, without using any of
+            :meth:`~discord.ModalSubmitInteraction.defer` or
+            :meth:`~discord.ModalSubmitInteraction.respond`.
+        """
+        return await super()._respond_with_launch_activity()
+
+
+class InteractionData:
+    def __init__(self, *, state: ConnectionState, data: InteractionDataPayload, guild: Optional[Guild] = None, **kwargs) -> None:
+        self._data = data
+        self._state: ConnectionState = state
+        self._guild: Optional[Guild] = guild
+        self._channel_id = kwargs.pop('channel_id', None)
+        if resolved := data.get('resolved'):
+            self.resolved: ResolvedData = ResolvedData(state=state, data=resolved, guild=guild, channel_id=self._channel_id)
+        else:
+            self.resolved = None  # just to be sure, but shouldn't be necessary unless discord misses to send them
+        options = self._data.get('options', [])
+        self.options: List[InteractionDataOption] = [
+            InteractionDataOption(state=state, data=option, guild=guild) for option in options
+        ]
+
+    def __getitem__(self, item):
+        return getattr(self, item, NotImplemented)
+
+    @property
+    def name(self) -> Optional[str]:
+        return self._data.get('name', None)
+
+    @property
+    def id(self) -> int:
+        return int(self._data.get('id', 0))
+
+    @property
+    def type(self) -> Optional[ApplicationCommandType]:
+        return try_enum(ApplicationCommandType, self._data.get('type', None))
+
+    @property
+    def component_type(self) -> Optional[ComponentType]:
+        return ComponentType.try_value(self._data.get('component_type', None))
+
+    @property
+    def custom_id(self) -> Optional[str]:
+        return self._data.get('custom_id', None)
+
+    @property
+    def target_id(self) -> Optional[int]:
+        return utils._get_as_snowflake(self._data, 'target_id')
+
+    @property
+    def values(self) -> List[Union[str, int, float]]:
+        return self._data.get('values', [])
+
+    @property
+    def components(self) -> Optional[List[ActionRow]]:
+        c = self._data.get('components', None)
+        if c:
+            return [ActionRow.from_dict(a) for a in c]
+
+
+class option_str(str):
+    def __new__(cls, *args, **kwargs):
+        focused = kwargs.pop('focused', False)
+        __self = super().__new__(cls, *args, **kwargs)
+        __self.focused = focused
+        return __self
+
+
+class option_int(int):
+    def __new__(cls, *args, **kwargs):
+        focused = kwargs.pop('focused', False)
+        __self = super().__new__(cls, *args, **kwargs)
+        __self.focused = focused
+        return __self
+
+
+class option_float(float):
+    def __new__(cls, *args, **kwargs):
+        focused = kwargs.pop('focused', False)
+        __self = super().__new__(cls, *args, **kwargs)
+        __self.focused = focused
+        return __self
+
+
+class InteractionDataOption:
+    """
+    Represents a slash-command option passed via a command.
+    By default, you only get in contact with this using :attr:`~discord.AutocompleteInteraction.focused_option`.
+
+    Attributes
+    -----------
+    name: :class:`str`
+        The name of the option
+    type: :class:`~discord.OptionType`
+        The type of the option
+
+    """
+
+    def __init__(
+            self,
+            *,
+            state: ConnectionState,
+            data: ApplicationCommandInteractionDataOptionPayload,
+            guild: Optional[Guild] = None,
+            **kwargs
+    ) -> None:
+        self._state: ConnectionState = state
+        self._data = data
+        self._guild: Optional[Guild] = guild
+        self._channel_id = kwargs.pop('channel_id', None)
+        self.name: str = data['name']
+        self.type: OptionType = OptionType.try_value(data['type'])
+
+    @property
+    def value(self) -> Optional[Union[str, int, float]]:
+        """Union[:class:`str`, :class:`int`, :class:`float`]: Returns the value of the option (what the user passed)"""
+        value = self._data.get('value', MISSING)
+        if value is not MISSING:
+            if isinstance(value, bool):  # because booleans are integers too
+                return value
+            if isinstance(value, int):
+                return option_int(value, focused=self.focused)
+            elif isinstance(value, str):
+                return option_str(value, focused=self.focused)
+            elif isinstance(value, float):
+                return option_float(value, focused=self.focused)
+            return value
+
+    @property
+    def focused(self) -> bool:
+        """:class:`bool`: Whether this option is currently focused (for autocomplete)"""
+        return self._data.get('focused', False)
+
+    @property
+    def options(self) -> Optional[List[InteractionDataOption]]:
+        """Optional[List[:class:`InteractionDataOption`]]: For sub-command (groups) the sub-command or the actual options"""
+        options = self._data.get('options', [])
+        return [InteractionDataOption(state=self._state, data=option, guild=self._guild) for option in options]
+
+
+class ResolvedData:
+    def __init__(self, *, state: ConnectionState, data: ResolvedDataPayload, guild: Optional[Guild] = None, **kwargs) -> None:
+        self._state: ConnectionState = state
+        self._data = data
+        self._guild: Optional[Guild] = guild
+        self._channel_id: Optional[int] = kwargs.pop('channel_id', None)
+        for attr in ('users', 'members', 'channels', 'roles', 'messages', 'attachments'):
+            value = data.get(attr, None)
+            if value is not None:
+                setattr(self, f'_{attr}', {})
+                getattr(self, f'_{self.__class__.__name__}__handle_{attr}')(value)
+        del self._data  # No longer needed
+
+    @property
+    def users(self) -> Optional[Dict[int, User]]:
+        return getattr(self, '_users', {})
+
+    def __handle_users(self, value: dict):
+        _users = getattr(self, '_users', {})
+        for _id, u in value.items():
+            _users[int(_id)] = User(state=self._state, data=u)
+
+    @property
+    def members(self) -> Optional[Dict[int, Member]]:
+        return getattr(self, '_members', {})
+
+    def __handle_members(self, value: dict):
+        _members = getattr(self, '_members', {})
+        for _id, m in value.items():
+            m['user'] = self._data['users'][_id]
+            _members[int(_id)] = Member(state=self._state, data=m, guild=self._guild)
+        return _members
+
+    @property
+    def channels(self) -> Optional[Dict[int, Union[abc.GuildChannel]]]:  # add DMChannel/GroupChannel
+        return getattr(self, '_channels', {})
+
+    def __handle_channels(self, value: dict):
+        _channels = getattr(self, '_channels', {})
+        for _id, c in value.items():
+            _id = int(_id)
+            if self._guild and isinstance(self._guild, Guild):
+                channel = self._guild.get_channel(_id)
+            else:
+                channel = self._state.get_channel(_id)
+            if not channel:
+                channel = PartialMessageable(
+                    state=self._state,
+                    id=_id,
+                    type=try_enum(ChannelType, c['type']),
+                    guild_id=self._guild.id if self._guild else None,
+                    partial_data=c
+                )
+            _channels[_id] = channel
+
+    @property
+    def roles(self) -> Optional[Dict[int, Role]]:
+        return getattr(self, '_roles', {})
+
+    def __handle_roles(self, value: dict):
+        _roles: dict = getattr(self, '_roles', {})
+        for _id, r in value.items():
+            _roles[int(_id)] = Role(guild=self._guild, data=r, state=self._state)
+
+    @property
+    def messages(self) -> Optional[Dict[int, Message]]:
+        return getattr(self, '_messages', {})
+
+    def __handle_messages(self, value: dict):
+        _messages: dict = getattr(self, '_messages', {})
+        for _id, m in value.items():
+            _messages[int(_id)] = Message(state=self._state, channel=self._state.get_channel(self._channel_id), data=m)
+
+    @property
+    def attachments(self) -> Optional[Dict[int, Attachment]]:
+        return getattr(self, '_attachments', {})
+
+    def __handle_attachments(self, value: dict):
+        _attachments: dict = getattr(self, '_attachments', {})
+        for _id, a in value.items():
+            _attachments[int(_id)] = Attachment(state=self._state, data=a)
diff --git a/discord/invite.py b/discord/invite.py
index a1d794b0..fed6887d 100644
--- a/discord/invite.py
+++ b/discord/invite.py
@@ -23,13 +23,32 @@
 FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 DEALINGS IN THE SOFTWARE.
 """
+from __future__ import annotations
+
+
+from typing import (
+    Optional,
+    List,
+    Tuple,
+    TYPE_CHECKING
+)
+from typing_extensions import Literal
 
 from .asset import Asset
+from .welcome_screen import WelcomeScreen
+from .sticker import GuildSticker
 from .utils import parse_time, snowflake_time, _get_as_snowflake
 from .object import Object
 from .mixins import Hashable
 from .enums import ChannelType, VerificationLevel, try_enum
 
+if TYPE_CHECKING:
+    from datetime import datetime
+
+    from .state import ConnectionState
+    from .scheduled_event import GuildScheduledEvent
+
+
 class PartialInviteChannel:
     """Represents a "partial" invite channel.
 
@@ -80,7 +99,7 @@ def __repr__(self):
     @property
     def mention(self):
         """:class:`str`: The string that allows you to mention the channel."""
-        return '<#%s>' % self.id
+        return f'<#{self.id}>'
 
     @property
     def created_at(self):
@@ -129,47 +148,58 @@ class PartialInviteGuild:
         The partial guild's invite splash.
     description: Optional[:class:`str`]
         The partial guild's description.
+    premium_subscription_count: :class:`int`
+        The partial guild's "boost" count.
     """
 
     __slots__ = ('_state', 'features', 'icon', 'banner', 'id', 'name', 'splash',
-                 'verification_level', 'description')
-
-    def __init__(self, state, data, id):
-        self._state = state
-        self.id = id
-        self.name = data['name']
-        self.features = data.get('features', [])
-        self.icon = data.get('icon')
-        self.banner = data.get('banner')
-        self.splash = data.get('splash')
-        self.verification_level = try_enum(VerificationLevel, data.get('verification_level'))
-        self.description = data.get('description')
-
-    def __str__(self):
+                 'verification_level', 'description', 'premium_subscription_count',
+                 'stickers')
+
+    def __init__(self, state: ConnectionState, data, id):
+        self._state: ConnectionState = state
+        self.id: int = id
+        self.name: str = data['name']
+        self.features: List[str] = data.get('features', [])
+        self.icon: Optional[str] = data.get('icon')
+        self.banner: Optional[str] = data.get('banner')
+        self.splash: Optional[str] = data.get('splash')
+        self.verification_level: VerificationLevel = try_enum(VerificationLevel, data.get('verification_level'))
+        self.description: Optional[str] = data.get('description')
+        self.premium_subscription_count: int = data.get('premium_subscription_count', 0)
+        self.stickers: Tuple[GuildSticker] = tuple(GuildSticker(state=state, data=d) for d in data.get('stickers', []))
+
+    def __str__(self) -> str:
         return self.name
 
-    def __repr__(self):
+    def __repr__(self) -> str:
         return '<{0.__class__.__name__} id={0.id} name={0.name!r} features={0.features} ' \
                'description={0.description!r}>'.format(self)
 
     @property
-    def created_at(self):
+    def created_at(self) -> datetime:
         """:class:`datetime.datetime`: Returns the guild's creation time in UTC."""
         return snowflake_time(self.id)
 
     @property
-    def icon_url(self):
+    def icon_url(self) -> Asset:
         """:class:`Asset`: Returns the guild's icon asset."""
         return self.icon_url_as()
 
-    def is_icon_animated(self):
+    def is_icon_animated(self) -> bool:
         """:class:`bool`: Returns ``True`` if the guild has an animated icon.
 
         .. versionadded:: 1.4
         """
         return bool(self.icon and self.icon.startswith('a_'))
 
-    def icon_url_as(self, *, format=None, static_format='webp', size=1024):
+    def icon_url_as(
+            self,
+            *,
+            format: Literal['webp', 'jpeg', 'jpg', 'png', 'gif'] = None,
+            static_format: Literal['webp', 'jpeg', 'jpg', 'png'] = 'webp',
+            size: int =1024
+    ) -> Asset:
         """The same operation as :meth:`Guild.icon_url_as`.
 
         Returns
@@ -180,11 +210,16 @@ def icon_url_as(self, *, format=None, static_format='webp', size=1024):
         return Asset._from_guild_icon(self._state, self, format=format, static_format=static_format, size=size)
 
     @property
-    def banner_url(self):
+    def banner_url(self) -> Asset:
         """:class:`Asset`: Returns the guild's banner asset."""
         return self.banner_url_as()
 
-    def banner_url_as(self, *, format='webp', size=2048):
+    def banner_url_as(
+            self,
+            *,
+            format: Literal['webp', 'jpeg', 'jpg', 'png'] = 'webp',
+            size: int = 2048
+    ) -> Asset:
         """The same operation as :meth:`Guild.banner_url_as`.
 
         Returns
@@ -195,11 +230,16 @@ def banner_url_as(self, *, format='webp', size=2048):
         return Asset._from_guild_image(self._state, self.id, self.banner, 'banners', format=format, size=size)
 
     @property
-    def splash_url(self):
+    def splash_url(self) -> Asset:
         """:class:`Asset`: Returns the guild's invite splash asset."""
         return self.splash_url_as()
 
-    def splash_url_as(self, *, format='webp', size=2048):
+    def splash_url_as(
+            self,
+            *,
+            format: Literal['webp', 'jpeg', 'jpg', 'png'] = 'webp',
+            size: int = 2048
+    ) -> Asset:
         """The same operation as :meth:`Guild.splash_url_as`.
 
         Returns
@@ -209,6 +249,7 @@ def splash_url_as(self, *, format='webp', size=2048):
         """
         return Asset._from_guild_image(self._state, self.id, self.splash, 'splashes', format=format, size=size)
 
+
 class Invite(Hashable):
     r"""Represents a Discord :class:`Guild` or :class:`abc.GuildChannel` invite.
 
@@ -252,6 +293,8 @@ class Invite(Hashable):
     +------------------------------------+----------------------------------------------------------+
     | :attr:`approximate_presence_count` | :meth:`Client.fetch_invite`                              |
     +------------------------------------+----------------------------------------------------------+
+    | :attr:`scheduled_event`            | :meth:`Client.fetch_invite`                              |
+    +------------------------------------+----------------------------------------------------------+
 
     If it's not in the table above then it is available by all methods.
 
@@ -283,35 +326,44 @@ class Invite(Hashable):
     approximate_presence_count: Optional[:class:`int`]
         The approximate number of members currently active in the guild.
         This includes idle, dnd, online, and invisible members. Offline members are excluded.
+    scheduled_event: Optional[:class:`GuildScheduledEvent`]
+        The scheduled event attached to this invite link, if any.
     channel: Union[:class:`abc.GuildChannel`, :class:`Object`, :class:`PartialInviteChannel`]
         The channel the invite is for.
     """
 
     __slots__ = ('max_age', 'code', 'guild', 'revoked', 'created_at', 'uses',
                  'temporary', 'max_uses', 'inviter', 'channel', '_state',
-                 'approximate_member_count', 'approximate_presence_count' )
+                 'approximate_member_count', 'approximate_presence_count',
+                 'scheduled_event')
 
     BASE = 'https://discord.gg'
 
-    def __init__(self, *, state, data):
+    def __init__(self, *, state: ConnectionState, data) -> None:
         self._state = state
         self.max_age = data.get('max_age')
         self.code = data.get('code')
         self.guild = data.get('guild')
-        self.revoked = data.get('revoked')
-        self.created_at = parse_time(data.get('created_at'))
-        self.temporary = data.get('temporary')
-        self.uses = data.get('uses')
-        self.max_uses = data.get('max_uses')
-        self.approximate_presence_count = data.get('approximate_presence_count')
-        self.approximate_member_count = data.get('approximate_member_count')
+        self.revoked: Optional[bool] = data.get('revoked')
+        self.created_at: datetime = parse_time(data.get('created_at'))
+        self.temporary: Optional[bool] = data.get('temporary')
+        self.uses: Optional[int] = data.get('uses')
+        self.max_uses: Optional[int] = data.get('max_uses')
+        self.approximate_presence_count: Optional[int] = data.get('approximate_presence_count')
+        self.approximate_member_count: Optional[int] = data.get('approximate_member_count')
 
         inviter_data = data.get('inviter')
         self.inviter = None if inviter_data is None else self._state.store_user(inviter_data)
         self.channel = data.get('channel')
+        self.scheduled_event: Optional[GuildScheduledEvent]
+        guild_scheduled_event = data.get('guild_scheduled_event', None)
+        if guild_scheduled_event is not None:
+            self.scheduled_event = state.store_event(guild=self.guild, data=guild_scheduled_event)
+        else:
+            self.scheduled_event = None
 
     @classmethod
-    def from_incomplete(cls, *, state, data):
+    def from_incomplete(cls, *, state: ConnectionState, data) -> Invite:
         try:
             guild_id = int(data['guild']['id'])
         except KeyError:
@@ -339,7 +391,7 @@ def from_incomplete(cls, *, state, data):
         return cls(state=state, data=data)
 
     @classmethod
-    def from_gateway(cls, *, state, data):
+    def from_gateway(cls, *, state: ConnectionState, data) -> Invite:
         guild_id = _get_as_snowflake(data, 'guild_id')
         guild = state._get_guild(guild_id)
         channel_id = _get_as_snowflake(data, 'channel_id')
@@ -353,28 +405,29 @@ def from_gateway(cls, *, state, data):
         data['channel'] = channel
         return cls(state=state, data=data)
 
-    def __str__(self):
+    def __str__(self) -> str:
         return self.url
 
-    def __repr__(self):
-        return '<Invite code={0.code!r} guild={0.guild!r} ' \
-                'online={0.approximate_presence_count} ' \
-                'members={0.approximate_member_count}>'.format(self)
+    def __repr__(self) -> str:
+        return f'<Invite code={self.code!r} guild={self.guild!r} ' \
+               f'online={self.approximate_presence_count} ' \
+               f'members={self.approximate_member_count} ' \
+               f'scheduled_event={self.scheduled_event}>'
 
-    def __hash__(self):
+    def __hash__(self) -> int:
         return hash(self.code)
 
     @property
-    def id(self):
+    def id(self) -> str:
         """:class:`str`: Returns the proper code portion of the invite."""
         return self.code
 
     @property
     def url(self):
         """:class:`str`: A property that retrieves the invite URL."""
-        return self.BASE + '/' + self.code
+        return f"{self.BASE}/{self.code}{f'?event={self.scheduled_event.id}' if self.scheduled_event else ''}"
 
-    async def delete(self, *, reason=None):
+    async def delete(self, *, reason: Optional[str] = None) -> None:
         """|coro|
 
         Revokes the instant invite.
@@ -397,3 +450,22 @@ async def delete(self, *, reason=None):
         """
 
         await self._state.http.delete_invite(self.code, reason=reason)
+
+    def set_scheduled_event(self, event: GuildScheduledEvent) -> None:
+        """Links the given scheduled event to this invite.
+
+        .. note::
+
+            Scheduled events aren't actually associated with invites on the API.
+            Any guild channel invite can have an event attached to it. Using
+            :meth:`abc.GuildChannel.create_invite`, :meth:`Client.fetch_invite`,
+            or this method, you can link scheduled events.
+
+        .. versionadded:: 2.0
+
+        Parameters
+        ----------
+        event: :class:`ScheduledEvent`
+            The scheduled event object to link.
+        """
+        self.scheduled_event = event
diff --git a/discord/iterators.py b/discord/iterators.py
index d18437ca..7b5825f7 100644
--- a/discord/iterators.py
+++ b/discord/iterators.py
@@ -3,7 +3,7 @@
 """
 The MIT License (MIT)
 
-Copyright (c) 2015-present Rapptz
+Copyright (c) 2015-2021 Rapptz & (c) 2021-present mccoderpy
 
 Permission is hereby granted, free of charge, to any person obtaining a
 copy of this software and associated documentation files (the "Software"),
@@ -24,15 +24,53 @@
 DEALINGS IN THE SOFTWARE.
 """
 
+from __future__ import annotations
+
 import asyncio
 import datetime
-
+from collections import namedtuple
+
+from typing import (
+    TYPE_CHECKING,
+    Optional,
+    Union,
+    List,
+)
+from typing_extensions import Literal
+
+if TYPE_CHECKING:
+    from .types import (
+        monetization,
+    )
+    from .state import ConnectionState
+    from .guild import Guild
+    from .abc import Snowflake, Messageable
+    from .scheduled_event import GuildScheduledEvent
+    from .channel import ThreadChannel, ForumPost, TextChannel, ForumChannel
+    from .monetization import Entitlement
+
+from .utils import MISSING
 from .errors import NoMoreItems
 from .utils import time_snowflake, maybe_coroutine
 from .object import Object
-from .audit_logs import AuditLogEntry
 
 OLDEST_OBJECT = Object(id=0)
+BanEntry = namedtuple('BanEntry', 'reason user')
+
+
+__all__ = (
+    'BanEntry',
+    'AuditLogIterator',
+    'BanIterator',
+    'EventUsersIterator',
+    'GuildIterator',
+    'HistoryIterator',
+    'MemberIterator',
+    'ReactionIterator',
+    'ThreadMemberIterator',
+    'EntitlementIterator',
+)
+
 
 class _AsyncIterator:
     __slots__ = ()
@@ -94,9 +132,11 @@ async def __anext__(self):
         else:
             return msg
 
+
 def _identity(x):
     return x
 
+
 class _ChunkedAsyncIterator(_AsyncIterator):
     def __init__(self, iterator, max_size):
         self.iterator = iterator
@@ -117,6 +157,7 @@ async def next(self):
                 n += 1
         return ret
 
+
 class _MappedAsyncIterator(_AsyncIterator):
     def __init__(self, iterator, func):
         self.iterator = iterator
@@ -127,6 +168,7 @@ async def next(self):
         item = await self.iterator.next()
         return await maybe_coroutine(self.func, item)
 
+
 class _FilteredAsyncIterator(_AsyncIterator):
     def __init__(self, iterator, predicate):
         self.iterator = iterator
@@ -146,14 +188,16 @@ async def next(self):
             if ret:
                 return item
 
+
 class ReactionIterator(_AsyncIterator):
-    def __init__(self, message, emoji, limit=100, after=None):
+    def __init__(self, message, emoji, reaction_type: int, limit: int = 100, after: Optional[Snowflake] = None):
         self.message = message
         self.limit = limit
         self.after = after
         state = message._state
         self.getter = state.http.get_reaction_users
         self.state = state
+        self.reaction_type = reaction_type
         self.emoji = emoji
         self.guild = message.guild
         self.channel_id = message.channel.id
@@ -176,7 +220,9 @@ async def fill_users(self):
             retrieve = self.limit if self.limit <= 100 else 100
 
             after = self.after.id if self.after else None
-            data = await self.getter(self.channel_id, self.message.id, self.emoji, retrieve, after=after)
+            data = await self.getter(
+                self.channel_id, self.message.id, self.emoji, retrieve, reaction_type=self.reaction_type, after=after
+            )
 
             if data:
                 self.limit -= retrieve
@@ -194,6 +240,7 @@ async def fill_users(self):
                     else:
                         await self.users.put(User(state=self.state, data=element))
 
+
 class HistoryIterator(_AsyncIterator):
     """Iterator for receiving a channel's message history.
 
@@ -228,8 +275,13 @@ class HistoryIterator(_AsyncIterator):
         ``True`` if `after` is specified, otherwise ``False``.
     """
 
-    def __init__(self, messageable, limit,
-                 before=None, after=None, around=None, oldest_first=None):
+    def __init__(self,
+                 messageable: 'Messageable',
+                 limit: int,
+                 before: Optional[Union['Snowflake', datetime.datetime]] = None,
+                 after: Optional[Union['Snowflake', datetime.datetime]] = None,
+                 around: Optional[Union['Snowflake', datetime.datetime]] = None,
+                 oldest_first: Optional[bool] = None):
 
         if isinstance(before, datetime.datetime):
             before = Object(id=time_snowflake(before, high=False))
@@ -244,10 +296,10 @@ def __init__(self, messageable, limit,
             self.reverse = oldest_first
 
         self.messageable = messageable
-        self.limit = limit
-        self.before = before
-        self.after = after or OLDEST_OBJECT
-        self.around = around
+        self.limit: int = limit
+        self.before: Optional[Object] = before
+        self.after: Optional[Object] = after or OLDEST_OBJECT
+        self.around: Optional[Object] = around
 
         self._filter = None  # message dict -> bool
 
@@ -307,7 +359,7 @@ async def flatten(self):
         while self._get_retrieve():
             data = await self._retrieve_messages(self.retrieve)
             if len(data) < 100:
-                self.limit = 0 # terminate the infinite loop
+                self.limit = 0  # terminate the infinite loop
 
             if self.reverse:
                 data = reversed(data)
@@ -327,7 +379,7 @@ async def fill_messages(self):
         if self._get_retrieve():
             data = await self._retrieve_messages(self.retrieve)
             if len(data) < 100:
-                self.limit = 0 # terminate the infinite loop
+                self.limit = 0  # terminate the infinite loop
 
             if self.reverse:
                 data = reversed(data)
@@ -371,14 +423,21 @@ async def _retrieve_messages_around_strategy(self, retrieve):
             return data
         return []
 
+
 class AuditLogIterator(_AsyncIterator):
-    def __init__(self, guild, limit=None, before=None, after=None, oldest_first=None, user_id=None, action_type=None):
+    def __init__(self,
+                 guild,
+                 limit=None,
+                 before=None,
+                 after=None,
+                 oldest_first=None,
+                 user_id=None,
+                 action_type=None):
         if isinstance(before, datetime.datetime):
             before = Object(id=time_snowflake(before, high=False))
         if isinstance(after, datetime.datetime):
             after = Object(id=time_snowflake(after, high=True))
 
-
         if oldest_first is None:
             self.reverse = after is not None
         else:
@@ -393,14 +452,18 @@ def __init__(self, guild, limit=None, before=None, after=None, oldest_first=None
         self.action_type = action_type
         self.after = OLDEST_OBJECT
         self._users = {}
+        self._integrations = {}
+        self._webhooks = {}
+        self._scheduled_events = {}
+        self._threads = {}
+        self._application_commands = {}
+        self._auto_moderation_rules = {}
         self._state = guild._state
 
-
         self._filter = None  # entry dict -> bool
 
         self.entries = asyncio.Queue()
 
-
         if self.reverse:
             self._strategy = self._after_strategy
             if self.before:
@@ -414,13 +477,12 @@ async def _before_strategy(self, retrieve):
         before = self.before.id if self.before else None
         data = await self.request(self.guild.id, limit=retrieve, user_id=self.user_id,
                                   action_type=self.action_type, before=before)
-
         entries = data.get('audit_log_entries', [])
         if len(data) and entries:
             if self.limit is not None:
                 self.limit -= retrieve
             self.before = Object(id=int(entries[-1]['id']))
-        return data.get('users', []), entries
+        return data, entries
 
     async def _after_strategy(self, retrieve):
         after = self.after.id if self.after else None
@@ -431,7 +493,7 @@ async def _after_strategy(self, retrieve):
             if self.limit is not None:
                 self.limit -= retrieve
             self.after = Object(id=int(entries[0]['id']))
-        return data.get('users', []), entries
+        return data, entries
 
     async def next(self):
         if self.entries.empty():
@@ -453,27 +515,73 @@ def _get_retrieve(self):
 
     async def _fill(self):
         from .user import User
+        from .integrations import _integration_factory, PartialIntegration
+        from .webhook import Webhook
+        from .scheduled_event import GuildScheduledEvent
+        from .channel import ForumChannel, ForumPost, ThreadChannel
+        from .application_commands import ApplicationCommand
+        from .automod import AutoModRule
+        from .audit_logs import AuditLogEntry
 
         if self._get_retrieve():
-            users, data = await self._strategy(self.retrieve)
-            if len(data) < 100:
-                self.limit = 0 # terminate the infinite loop
+            data, entries = await self._strategy(self.retrieve)
+            if len(entries) < 100:
+                self.limit = 0  # terminate the infinite loop
 
             if self.reverse:
-                data = reversed(data)
+                entries = reversed(entries)
             if self._filter:
                 data = filter(self._filter, data)
 
-            for user in users:
-                u = User(data=user, state=self._state)
+            _state = self._state
+            _guild = self.guild
+
+            for user in data.get('users', []):
+                u = User(data=user, state=_state)
                 self._users[u.id] = u
 
-            for element in data:
+            for integration in data.get('integrations', []):
+                i = PartialIntegration(data=integration, guild=_guild)
+                self._integrations[i.id] = i
+
+            for webhook in data.get('webhooks', []):
+                w = Webhook.from_state(data=webhook, state=_state)
+                self._webhooks[w.id] = w
+
+            for scheduled_event in data.get('guild_scheduled_events', []):
+                e = GuildScheduledEvent(state=_state, guild=_guild, data=scheduled_event)
+                self._scheduled_events[e.id] = e
+
+            for thread in data.get('threads', []):
+                parent_id = int(thread.get('parent_id'))
+                parent_channel = _guild.get_channel(parent_id)
+                if isinstance(parent_channel, ForumChannel):
+                    t = ForumPost(state=_state, guild=_guild, data=thread)
+                else:
+                    t = ThreadChannel(state=_state, guild=_guild, data=thread)
+                self._threads[t.id] = t
+
+            for application_command in data.get('application_commands', []):
+                c = ApplicationCommand._from_type(state=_state, data=application_command)
+                self._application_commands[c.id] = c
+
+            for automod_rule in data.get('auto_moderation_rules', []):
+                r = AutoModRule(state=_state, guild=_guild, **automod_rule)
+                self._auto_moderation_rules[r.id] = r
+
+            for entry in entries:
                 # TODO: remove this if statement later
-                if element['action_type'] is None:
+                if entry['action_type'] is None:
                     continue
 
-                await self.entries.put(AuditLogEntry(data=element, users=self._users, guild=self.guild))
+                await self.entries.put(
+                    AuditLogEntry(
+                        data=entry,
+                        guild=self.guild,
+                        users=self._users,
+
+                    )
+                )
 
 
 class GuildIterator(_AsyncIterator):
@@ -504,7 +612,11 @@ class GuildIterator(_AsyncIterator):
     after: Optional[Union[:class:`abc.Snowflake`, :class:`datetime.datetime`]]
         Object after which all guilds must be.
     """
-    def __init__(self, bot, limit, before=None, after=None):
+    def __init__(self,
+                 bot,
+                 limit: int,
+                 before: Optional[Union['Snowflake', datetime.datetime]] = None,
+                 after: Optional[Union['Snowflake', datetime.datetime]] = None):
 
         if isinstance(before, datetime.datetime):
             before = Object(id=time_snowflake(before, high=False))
@@ -512,9 +624,9 @@ def __init__(self, bot, limit, before=None, after=None):
             after = Object(id=time_snowflake(after, high=True))
 
         self.bot = bot
-        self.limit = limit
-        self.before = before
-        self.after = after
+        self.limit: int = limit
+        self.before: Optional[Object] = before
+        self.after: Optional[Object] = after
 
         self._filter = None
 
@@ -560,7 +672,7 @@ async def flatten(self):
                 self.limit = 0
 
             if self._filter:
-                data = filter(self._filter, data)
+                entries = filter(self._filter, entries)
 
             for element in data:
                 result.append(self.create_guild(element))
@@ -602,6 +714,7 @@ async def _retrieve_guilds_after_strategy(self, retrieve):
             self.after = Object(id=int(data[0]['id']))
         return data
 
+
 class MemberIterator(_AsyncIterator):
     def __init__(self, guild, limit=1000, after=None):
 
@@ -653,3 +766,480 @@ async def fill_members(self):
     def create_member(self, data):
         from .member import Member
         return Member(data=data, guild=self.guild, state=self.state)
+
+
+class ThreadMemberIterator(_AsyncIterator):
+    def __init__(
+            self,
+            thread: ThreadChannel,
+            limit: int = 100,
+            after: Optional[Union[Snowflake, datetime.datetime]] = None,
+            with_member: bool = False
+    ):
+        self.state = state = thread._state
+        self.guild = thread.guild
+        self.thread = thread
+        self.channel_id = thread.id
+        self.limit = limit
+
+        if isinstance(after, datetime.datetime):
+            after = Object(id=time_snowflake(after, high=True))
+
+        self.after: Optional[Object] = after
+
+        self.with_member = with_member
+        self.members = asyncio.Queue()
+        self.getter = state.http.list_thread_members
+
+        self._retrieve_members = self._retrieve_members_after_strategy
+
+    async def next(self):
+        if self.members.empty():
+            await self.fill_members()
+
+        try:
+            return self.members.get_nowait()
+        except asyncio.QueueEmpty:
+            raise NoMoreItems()
+
+    def _get_retrieve(self):
+        l = self.limit
+        if l is None or l > 100:
+            r = 100
+        else:
+            r = l
+        self.retrieve = r
+        return r > 0
+
+    async def fill_members(self):
+        # this is a hack because >circular imports<
+        from .member import Member
+        from .channel import ThreadMember
+
+        guild = self.guild
+        state = self.state
+        thread = self.thread
+        with_member = self.with_member
+        cache_joined = state.member_cache_flags.joined
+        cache_online = state.member_cache_flags.online
+
+        if self._get_retrieve():
+
+            data = await self._retrieve_members(self.retrieve)
+            if self.limit is None or len(data) < 100:
+                self.limit = 0
+
+            if not with_member or guild is None or isinstance(guild, Object):
+                for element in data:
+                    thread_member = ThreadMember(state=state, guild=guild, data=element)
+                    thread._add_member(thread_member)
+                    await self.members.put(thread_member)
+                    
+            else:
+                for element in data:
+                    member = Member(data=element.pop('member'), guild=guild, state=state)
+                    if cache_joined or (cache_online and 'online' in member.raw_status):
+                        guild._add_member(member)
+                    thread_member = ThreadMember(state=state, guild=guild, data=element)
+                    thread._add_member(thread_member)
+                    await self.members.put(thread_member)
+
+    async def _retrieve_members_after_strategy(self, retrieve: int):
+        """Retrieve thread members using after parameter."""
+        after = self.after.id if self.after else None
+        data = await self.getter(self.channel_id, limit=retrieve, after=after, with_member=self.with_member)
+        if len(data):
+            if self.limit is not None:
+                self.limit -= retrieve
+            self.after = Object(id=int(data[0]['user_id']))
+            data = reversed(data)
+        return data
+
+
+class ArchivedThreadIterator(_AsyncIterator):
+    def __init__(
+        self,
+        channel: Union[TextChannel, ForumChannel],
+        limit: int = 100,
+        before: Optional[Union[Snowflake, datetime.datetime]] = None,
+        private: bool = False,
+        joined_private: bool = True
+    ) -> None:
+        self.state = state = channel._state
+        self.guild = channel.guild
+        self.channel_id = channel.id
+        self.limit = limit
+        self._retrieve_type = 0 if channel.__class__.__name__ == 'TextChannel' else 1
+
+        if isinstance(before, datetime.datetime):
+            before = Object(id=time_snowflake(before, high=False))
+
+        self.before: Optional[Object] = before
+
+        self.threads = asyncio.Queue()
+        self.getter = state.http.list_archived_threads
+        self.type: Literal['private', 'public'] = 'private' if private else 'public'
+        self.joined_private = joined_private
+        self.getter = state.http.list_archived_threads
+
+    async def next(self):
+        if self.threads.empty():
+            await self.fill_threads()
+
+        try:
+            return self.threads.get_nowait()
+        except asyncio.QueueEmpty:
+            raise NoMoreItems()
+
+    def _get_retrieve(self):
+        l = self.limit
+        r = 100 if l is None or l > 100 else l
+        self.retrieve = r
+        return r > 0
+
+    async def fill_threads(self):
+        # this is a hack because >circular imports<
+        if self._retrieve_type == 0:
+            from .channel import ThreadChannel as Factory
+        else:
+            from .channel import ForumPost as Factory
+
+        if self._get_retrieve():
+            guild = self.guild
+            data = await self.getter(
+                self.channel_id,
+                type=self.type,
+                joined_private=self.joined_private,
+                limit=self.retrieve
+            )
+            if self.limit is None or len(data) < 100 and not data.get('has_more'):
+                self.limit = 0
+
+            members_dict = {int(member['id']): member for member in data['members']}
+
+            for element in data['threads']:
+                thread_member = members_dict.get(int(element['id']))
+                if thread_member is not None:
+                    element['member'] = thread_member
+                await self.threads.put(Factory(guild=guild, state=self.state, data=element))
+
+
+class EventUsersIterator(_AsyncIterator):
+    def __init__(self,
+                 event: 'GuildScheduledEvent',
+                 limit: int = 100,
+                 before: Optional[Union['Snowflake', datetime.datetime]] = None,
+                 after: Optional[Union['Snowflake', datetime.datetime]] = None,
+                 with_member: bool = False):
+        self.guild = event.guild
+        self.guild_id = event.guild_id
+        self.state = event._state
+        self.event = event
+        self.limit = limit
+
+        if isinstance(before, datetime.datetime):
+            before = Object(id=time_snowflake(before, high=True))
+        if isinstance(after, datetime.datetime):
+            after = Object(id=time_snowflake(after, high=True))
+
+        self.before: Optional[Object] = before
+        self.after: Optional[Object] = after
+
+        self.with_member = with_member
+        self.users = asyncio.Queue()
+        self.getter = event._state.http.get_guild_event_users
+
+        self._filter = None
+
+        if self.before and self.after:
+            self._retrieve_users = self._retrieve_users_before_strategy
+            self._filter = lambda m: int(m['user']['id']) > self.after.id
+        elif self.before:
+            self._retrieve_users = self._retrieve_users_before_strategy
+        else:
+            self._retrieve_users = self._retrieve_users_after_strategy
+
+    async def next(self):
+        if self.users.empty():
+            await self.fill_users()
+
+        try:
+            return self.users.get_nowait()
+        except asyncio.QueueEmpty:
+            raise NoMoreItems()
+
+    def _get_retrieve(self):
+        l = self.limit
+        if l is None or l > 100:
+            r = 100
+        else:
+            r = l
+        self.retrieve = r
+        return r > 0
+
+    async def fill_users(self):
+        # this is a hack because >circular imports<
+        from .user import User
+        from .member import Member
+
+        guild = self.guild
+        state = self.state
+        cache_joined = state.member_cache_flags.joined
+        cache_online = state.member_cache_flags.online
+
+        if self._get_retrieve():
+
+            data = await self._retrieve_users(self.retrieve)
+            if self.limit is None or len(data) < 100:
+                self.limit = 0
+
+            if self._filter:
+                data = filter(self._filter, data)
+
+            if guild is None or isinstance(guild, Object):
+                for element in data:
+                    await self.users.put(User(state=state, data=element['user']))
+            else:
+                for element in data:
+                    member_id = int(element['user']['id'])
+                    member = self.guild.get_member(member_id)
+                    if member is not None:
+                        await self.users.put(member)
+                    else:
+                        if self.with_member:
+                            element['member']['user'] = element['user']
+                            member = Member(data=element['member'], guild=guild, state=state)
+                            if cache_joined or (cache_online and 'online' in member.raw_status):
+                                self.guild._add_member(member)
+                            await self.users.put(member)
+                        else:
+                            await self.users.put(User(state=self.state, data=element))
+
+    async def _retrieve_users_before_strategy(self, retrieve):
+        """Retrieve users using before parameter."""
+        before = self.before.id if self.before else None
+        data = await self.getter(self.guild_id, self.event.id, limit=retrieve, before=before, with_member=self.with_member)
+        if len(data):
+            if self.limit is not None:
+                self.limit -= retrieve
+            self.before = Object(id=int(data[-1]['user']['id']))
+        return data
+
+    async def _retrieve_users_after_strategy(self, retrieve):
+        """Retrieve users using after parameter."""
+        after = self.after.id if self.after else None
+        data = await self.getter(self.guild_id, self.event.id, limit=retrieve, after=after, with_member=self.with_member)
+        if len(data):
+            if self.limit is not None:
+                self.limit -= retrieve
+            self.after = Object(id=int(data[0]['user']['id']))
+            data = reversed(data)
+        return data
+
+
+class BanIterator(_AsyncIterator):
+    def __init__(
+            self,
+            guild: Guild,
+            limit: int = 1000,
+            before: Optional[Union[Snowflake, datetime.datetime]] = None,
+            after: Optional[Union[Snowflake, datetime.datetime]] = None
+    ):
+        self.guild = guild
+        self.guild_id = guild.id
+        self.state = guild._state
+        self.limit = limit
+
+        if isinstance(before, datetime.datetime):
+            before = Object(id=time_snowflake(before, high=True))
+        if isinstance(after, datetime.datetime):
+            after = Object(id=time_snowflake(after, high=True))
+
+        self.before: Optional[Object] = before
+        self.after: Optional[Object] = after
+        
+        self.ban_entries = asyncio.Queue()
+        self.getter = guild._state.http.get_bans
+
+        self._filter = None
+
+        if self.before and self.after:
+            self._retrieve_bans = self._retrieve_bans_before_strategy
+            self._filter = lambda be: int(be['user']['id']) > self.after.id
+        elif self.before:
+            self._retrieve_bans = self._retrieve_bans_before_strategy
+        else:
+            self._retrieve_bans = self._retrieve_bans_after_strategy
+
+    async def next(self):
+        if self.ban_entries.empty():
+            await self.fill_ban_entries()
+
+        try:
+            return self.ban_entries.get_nowait()
+        except asyncio.QueueEmpty:
+            raise NoMoreItems()
+
+    def _get_retrieve(self):
+        l = self.limit
+        if l is None or l > 1000:
+            r = 1000
+        else:
+            r = l
+        self.retrieve = r
+        return r > 0
+
+    async def fill_ban_entries(self):
+        # this is a hack because >circular imports<
+        from .user import User
+
+        state = self.state
+
+        if self._get_retrieve():
+
+            data = await self._retrieve_bans(self.retrieve)
+            if self.limit is None or len(data) < 100:
+                self.limit = 0
+
+            if self._filter:
+                data = filter(self._filter, data)
+
+            for element in data:
+                await self.ban_entries.put(
+                    BanEntry(user=User(state=state, data=element['user']), reason=element['reason'])
+                )
+
+    async def _retrieve_bans_before_strategy(self, retrieve):
+        """Retrieve bans using before parameter."""
+        before = self.before.id if self.before else None
+        data = await self.getter(self.guild_id, limit=retrieve, before=before)
+        if len(data):
+            if self.limit is not None:
+                self.limit -= retrieve
+            self.before = Object(id=int(data[-1]['user']['id']))
+        return data
+
+    async def _retrieve_bans_after_strategy(self, retrieve):
+        """Retrieve bans using after parameter."""
+        after = self.after.id if self.after else None
+        data = await self.getter(self.guild_id, limit=retrieve, after=after)
+        if len(data):
+            if self.limit is not None:
+                self.limit -= retrieve
+            self.after = Object(id=int(data[0]['user']['id']))
+            data = reversed(data)
+        return data
+
+
+class EntitlementIterator(_AsyncIterator):
+    def __init__(
+            self,
+            state: ConnectionState,
+            limit: int = 100,
+            user_id: int = MISSING,
+            guild_id: int = MISSING,
+            sku_ids: List[int] = MISSING,
+            before: Optional[Union[datetime.datetime, Snowflake]] = None,
+            after: Optional[Union[datetime.datetime, Snowflake]] = None,
+            exclude_ended: bool = False
+    ):
+        self.application_id = state.application_id
+        self.guild_id = guild_id
+        self.user_id = user_id
+        self.sku_ids = sku_ids
+        self.state: ConnectionState = state
+        self.limit: int = limit
+        self.exclude_ended: bool = exclude_ended
+
+        if isinstance(before, datetime.datetime):
+            before = Object(id=time_snowflake(before, high=True))
+        if isinstance(after, datetime.datetime):
+            after = Object(id=time_snowflake(after, high=True))
+
+        self.before: Optional[Object] = before
+        self.after: Optional[Object] = after
+
+        self.entitlements = asyncio.Queue()
+        self.getter = state.http.list_entitlements
+
+        self._filter = None
+
+        if self.before and self.after:
+            self._retrieve_entitlements = self._retrieve_entitlements_before_strategy
+            self._filter = lambda e: int(e['id']) > self.after.id
+        elif self.before:
+            self._retrieve_entitlements = self._retrieve_entitlements_before_strategy
+        else:
+            self._retrieve_entitlements = self._retrieve_entitlements_after_strategy
+
+    async def next(self):
+        if self.entitlements.empty():
+            await self.fill_entitlements()
+
+        try:
+            return self.entitlements.get_nowait()
+        except asyncio.QueueEmpty:
+            raise NoMoreItems()
+
+    def _get_retrieve(self):
+        l = self.limit
+        r = 100 if l is None or l > 100 else l
+        self.retrieve = r
+        return r > 0
+
+    async def fill_entitlements(self):
+        # this is a hack because >circular imports<
+        from .monetization import Entitlement
+
+        state = self.state
+
+        if self._get_retrieve():
+
+            data = await self._retrieve_entitlements(self.retrieve)
+            if self.limit is None or len(data) < 100:
+                self.limit = 0
+
+            if self._filter:
+                data = filter(self._filter, data)
+
+            for element in data:
+                await self.entitlements.put(
+                    Entitlement(data=element, state=state)
+                )
+
+    async def _retrieve_entitlements_before_strategy(self, retrieve) -> List[monetization.Entitlement]:
+        """Retrieve bans using before parameter."""
+        before = self.before.id if self.before else MISSING
+        data = await self.getter(
+            self.application_id,
+            limit=retrieve,
+            before=before,
+            user_id=self.user_id,
+            guild_id=self.guild_id,
+            sku_ids=self.sku_ids,
+            exclude_ended=self.exclude_ended
+        )
+        if len(data):
+            if self.limit is not None:
+                self.limit -= retrieve
+            self.before = Object(id=int(data[-1]['id']))
+        return data
+
+    async def _retrieve_entitlements_after_strategy(self, retrieve) -> List[monetization.Entitlement]:
+        """Retrieve bans using after parameter."""
+        after = self.after.id if self.after else MISSING
+        data = await self.getter(
+            self.application_id,
+            limit=retrieve,
+            after=after,
+            user_id=self.user_id,
+            guild_id=self.guild_id,
+            sku_ids=self.sku_ids,
+            exclude_ended=self.exclude_ended,
+        )
+        if len(data):
+            if self.limit is not None:
+                self.limit -= retrieve
+            self.after = Object(id=int(data[0]['id']))
+            data = reversed(data)
+        return data
diff --git a/discord/member.py b/discord/member.py
index 102586f3..947fc3ad 100644
--- a/discord/member.py
+++ b/discord/member.py
@@ -3,7 +3,7 @@
 """
 The MIT License (MIT)
 
-Copyright (c) 2015-present Rapptz
+Copyright (c) 2015-2021 Rapptz & (c) 2021-present mccoderpy
 
 Permission is hereby granted, free of charge, to any person obtaining a
 copy of this software and associated documentation files (the "Software"),
@@ -23,6 +23,7 @@
 FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 DEALINGS IN THE SOFTWARE.
 """
+from __future__ import annotations
 
 import datetime
 import inspect
@@ -30,19 +31,71 @@
 import sys
 from operator import attrgetter
 
-import discord.abc
-
-from . import utils
-from .user import BaseUser, User
-from .activity import create_activity
+from typing import (
+    Optional,
+    Union,
+    List,
+    Dict,
+    Coroutine,
+    Tuple,
+    TYPE_CHECKING,
+    Any,
+    Iterable,
+    Callable,
+    Type,
+    TypeVar,
+)
+
+from typing_extensions import Literal
+
+from . import utils, abc
+from .asset import Asset
+from .user import BaseUser, User, _BaseUser
+from .activity import ActivityTypes, create_activity
 from .permissions import Permissions
+from .voice_client import VoiceProtocol, VoiceClient
 from .enums import Status, try_enum
+from .flags import GuildMemberFlags, PublicUserFlags
 from .colour import Colour
 from .object import Object
+from .errors import NotInVoiceChannel
+
+if TYPE_CHECKING:
+    from .types.user import (
+        User as UserData,
+        MemberWithUser,
+        UserWithMember,
+        PartialMember
+    )
+    from .role import Role
+    from .state import ConnectionState
+    from .guild import Guild
+    from .activity import BaseActivity, Spotify
+    from .message import Message
+    from .channel import ThreadChannel, VoiceChannel, StageChannel, DMChannel
+
+    VocalGuildChannel = Union[VoiceChannel, StageChannel]
+
+
+MISSING = utils.MISSING
+T = TypeVar('T')
+VP = TypeVar('VP', bound=VoiceProtocol)
+
+__all__ = (
+    'VoiceState',
+    'Member',
+)
+
 
 class VoiceState:
     """Represents a Discord user's voice state.
+    
+    .. container:: operations
 
+        .. describe:: await voice(...)
+            Acts as a shortcut to :meth:`VoiceProtocol.connect`.
+            Raises :exc:`NotInVoiceChannel` if :attr:`channel` is ``None``.
+    
     Attributes
     ------------
     deaf: :class:`bool`
@@ -87,11 +140,23 @@ class VoiceState:
                  'self_stream', 'self_video', 'self_deaf', 'afk', 'channel',
                  'requested_to_speak_at', 'suppress')
 
-    def __init__(self, *, data, channel=None):
+    if TYPE_CHECKING:
+        session_id: Optional[str]
+        self_mute: bool
+        self_deaf: bool
+        self_stream: bool
+        self_video: bool
+        afk: bool
+        mute: bool
+        deaf: bool
+        suppress: bool
+        requested_to_speak_at: Optional[datetime.datetime]
+
+    def __init__(self, *, data, channel: Optional[VocalGuildChannel] = None) -> None:
         self.session_id = data.get('session_id')
         self._update(data, channel)
 
-    def _update(self, data, channel):
+    def _update(self, data, channel: Optional[VocalGuildChannel]) -> None:
         self.self_mute = data.get('self_mute', False)
         self.self_deaf = data.get('self_deaf', False)
         self.self_stream = data.get('self_stream', False)
@@ -112,50 +177,64 @@ def __repr__(self):
             ('requested_to_speak_at', self.requested_to_speak_at),
             ('channel', self.channel)
         ]
-        return '<%s %s>' % (self.__class__.__name__, ' '.join('%s=%r' % t for t in attrs))
-
-def flatten_user(cls):
-    for attr, value in itertools.chain(BaseUser.__dict__.items(), User.__dict__.items()):
-        # ignore private/special methods
-        if attr.startswith('_'):
-            continue
-
-        # don't override what we already have
-        if attr in cls.__dict__:
-            continue
-
-        # if it's a slotted attribute or a property, redirect it
-        # slotted members are implemented as member_descriptors in Type.__dict__
-        if not hasattr(value, '__annotations__'):
-            getter = attrgetter('_user.' + attr)
-            setattr(cls, attr, property(getter, doc='Equivalent to :attr:`User.%s`' % attr))
-        else:
-            # Technically, this can also use attrgetter
-            # However I'm not sure how I feel about "functions" returning properties
-            # It probably breaks something in Sphinx.
-            # probably a member function by now
-            def generate_function(x):
-                # We want sphinx to properly show coroutine functions as coroutines
-                if inspect.iscoroutinefunction(value):
-                    async def general(self, *args, **kwargs):
-                        return await getattr(self._user, x)(*args, **kwargs)
-                else:
-                    def general(self, *args, **kwargs):
-                        return getattr(self._user, x)(*args, **kwargs)
-
-                general.__name__ = x
-                return general
-
-            func = generate_function(attr)
-            func = utils.copy_doc(value)(func)
-            setattr(cls, attr, func)
-
-    return cls
-
-_BaseUser = discord.abc.User
-
-@flatten_user
-class Member(discord.abc.Messageable, _BaseUser):
+        return f"<{self.__class__.__name__} {' '.join('%s=%r' % t for t in attrs)}>"
+
+    def __call__(
+            self,
+            *,
+            timeout: Optional[float] = 60.0,
+            reconnect: bool = True,
+            cls: VP = VoiceClient
+    ) -> Coroutine[None, None, VP]:
+        channel = self.channel
+        if not channel:
+            raise NotInVoiceChannel()
+        return channel.connect(timeout=timeout, reconnect=reconnect, cls=cls)
+
+
+def flatten_user(*types):
+    def decorator(cls):
+        for attr, value in itertools.chain(*(t.__dict__.items() for t in types)):
+            # ignore private/special methods
+            if attr.startswith('_'):
+                continue
+
+            # don't override what we already have
+            if attr in cls.__dict__:
+                continue
+
+            # if it's a slotted attribute or a property, redirect it
+            # slotted members are implemented as member_descriptors in Type.__dict__
+            if not hasattr(value, '__annotations__'):
+                getter = attrgetter(f'_user.{attr}')
+                setattr(cls, attr, property(getter, doc=f'Equivalent to :attr:`User.{attr}`'))
+            else:
+                # Technically, this can also use attrgetter
+                # However I'm not sure how I feel about "functions" returning properties
+                # It probably breaks something in Sphinx.
+                # probably a member function by now
+                def generate_function(x):
+                    # We want sphinx to properly show coroutine functions as coroutines
+                    if inspect.iscoroutinefunction(value):
+                        async def general(self, *args, **kwargs):
+                            return await getattr(self._user, x)(*args, **kwargs)
+                    else:
+                        def general(self, *args, **kwargs):
+                            return getattr(self._user, x)(*args, **kwargs)
+
+                    general.__name__ = x
+                    return general
+
+                func = generate_function(attr)
+                func = utils.copy_doc(value)(func)
+                setattr(cls, attr, func)
+
+        return cls
+    return decorator
+
+
+@flatten_user(BaseUser, User)
+class Member(abc.Messageable, _BaseUser):
     """Represents a Discord member to a :class:`Guild`.
 
     This implements a lot of the functionality of :class:`User`.
@@ -178,7 +257,11 @@ class Member(discord.abc.Messageable, _BaseUser):
 
         .. describe:: str(x)
 
-            Returns the member's name with the discriminator.
+            Returns the members :attr:`username` if :attr:`is_migrated` is true, else the member's name with discriminator.
+
+            .. note::
+
+                When the migration is complete, this will always return the :attr:`username`.
 
     Attributes
     ----------
@@ -192,7 +275,7 @@ class Member(discord.abc.Messageable, _BaseUser):
 
             Due to a Discord API limitation, a user's Spotify activity may not appear
             if they are listening to a song with a title longer
-            than 128 characters. See :issue:`1738` for more information.
+            than 128 characters. See :old-issue:`1738` for more information.
 
     guild: :class:`Guild`
         The guild that the member belongs to.
@@ -208,40 +291,73 @@ class Member(discord.abc.Messageable, _BaseUser):
     """
 
     __slots__ = ('_roles', 'joined_at', 'premium_since', '_client_status',
-                 'activities', 'guild', 'pending', 'nick', '_user', '_state')
-
-    def __init__(self, *, data, guild, state):
-        self._state = state
-        self._user = state.store_user(data['user'])
-        self.guild = guild
-        self.joined_at = utils.parse_time(data.get('joined_at'))
-        self.premium_since = utils.parse_time(data.get('premium_since'))
+                 'activities', 'guild', '_flags', 'pending', 'nick', 'guild_avatar', 'guild_banner',
+                 '_user', '_state', '_communication_disabled_until')
+
+    if TYPE_CHECKING:
+        name: str
+        username: str
+        global_name: str
+        id: int
+        discriminator: str
+        bot: bool
+        system: bool
+        created_at: datetime.datetime
+        default_avatar: str
+        avatar: Optional[str]
+        dm_channel: Optional[DMChannel]
+        create_dm = User.create_dm
+        mutual_guilds: List[Guild]
+        public_flags: PublicUserFlags
+        banner: Optional[str]
+        accent_color: Optional[Colour]
+        accent_colour: Optional[Colour]
+        communication_disabled_until: Optional[datetime.datetime]
+
+
+    def __init__(self, *, data: MemberWithUser, guild: Guild, state: ConnectionState):
+        self._state: ConnectionState = state
+        self._user: User = state.store_user(data['user'])
+        self.guild: Guild = guild
+        self.joined_at: Optional[datetime.datetime] = utils.parse_time(data.get('joined_at'))
+        self.premium_since: Optional[datetime.datetime] = utils.parse_time(data.get('premium_since'))
         self._update_roles(data)
-        self._client_status = {
-            None: 'offline'
-        }
-        self.activities = tuple(map(create_activity, data.get('activities', [])))
-        self.nick = data.get('nick', None)
-        self.pending = data.get('pending', False)
-
-    def __str__(self):
+        self._client_status: Dict[Optional[str], str] = {None: 'offline'}
+        self.activities: Tuple[ActivityTypes, ...] = tuple(map(create_activity, data.get('activities', [])))
+        self.nick: Optional[str] = data.get('nick')
+        self._flags: int = data.get('flags', 0)
+        self.pending: bool = data.get('pending', False)
+        self.guild_avatar = data.get('avatar')
+        self.guild_banner = data.get('banner')
+        self._communication_disabled_until = data.get('communication_disabled_until', None)
+
+    def __str__(self) -> str:
         return str(self._user)
 
-    def __repr__(self):
-        return '<Member id={1.id} name={1.name!r} discriminator={1.discriminator!r}' \
-               ' bot={1.bot} nick={0.nick!r} guild={0.guild!r}>'.format(self, self._user)
+    def __repr__(self) -> str:
+        user = self._user
+        if not user.is_migrated:
+            return f'<Member id={user.id} username={user.username!r} global_name={user.global_name} ' \
+                   f'discriminator={user.discriminator!r} bot={user.bot} nick={self.nick!r} guild={self.guild!r}>'
+        return f'<Member id={user.id} username={user.username!r} global_name={user.global_name} ' \
+               f'bot={user.bot} nick={self.nick!r} guild={self.guild!r}>'
 
-    def __eq__(self, other):
+    def __eq__(self, other: Any) -> bool:
         return isinstance(other, _BaseUser) and other.id == self.id
 
-    def __ne__(self, other):
+    def __ne__(self, other: Any) -> bool:
         return not self.__eq__(other)
 
-    def __hash__(self):
+    def __hash__(self) -> int:
         return hash(self._user)
 
+    @property
+    def flags(self) -> GuildMemberFlags:
+        """:class:`GuildMemberFlags`: Guild specific flags for the member."""
+        return GuildMemberFlags._from_value(self._flags)
+
     @classmethod
-    def _from_message(cls, *, message, data):
+    def _from_message(cls, *, message: Message, data: MemberWithUser):
         author = message.author
         data['user'] = author._to_minimal_user_json()
         return cls(data=data, guild=message.guild, state=message._state)
@@ -251,13 +367,14 @@ def _update_from_message(self, data):
         self.premium_since = utils.parse_time(data.get('premium_since'))
         self._update_roles(data)
         self.nick = data.get('nick', None)
+        self._flags = data.get('flags', 0)
         self.pending = data.get('pending', False)
 
     @classmethod
-    def _try_upgrade(cls, *,  data, guild, state):
+    def _try_upgrade(cls, *,  data: UserWithMember, guild: Guild, state: ConnectionState) -> Union[Member, User]:
         # A User object with a 'member' key
         try:
-            member_data = data.pop('member')
+            member_data: MemberWithUser = data.pop('member')  # type: ignore
         except KeyError:
             return state.store_user(data)
         else:
@@ -265,7 +382,7 @@ def _try_upgrade(cls, *,  data, guild, state):
             return cls(data=member_data, guild=guild, state=state)
 
     @classmethod
-    def _from_presence_update(cls, *, data, guild, state):
+    def _from_presence_update(cls, *, data, guild: Guild, state: ConnectionState) -> Tuple[Member, Member]:
         clone = cls(data=data, guild=guild, state=state)
         to_return = cls(data=data, guild=guild, state=state)
         to_return._client_status = {
@@ -276,16 +393,20 @@ def _from_presence_update(cls, *, data, guild, state):
         return to_return, clone
 
     @classmethod
-    def _copy(cls, member):
-        self = cls.__new__(cls) # to bypass __init__
+    def _copy(cls, member: Member) -> Member:
+        self = cls.__new__(cls)  # to bypass __init__
 
         self._roles = utils.SnowflakeList(member._roles, is_sorted=True)
         self.joined_at = member.joined_at
         self.premium_since = member.premium_since
         self._client_status = member._client_status.copy()
+        self._communication_disabled_until = member._communication_disabled_until
         self.guild = member.guild
         self.nick = member.nick
+        self.guild_avatar = member.guild_avatar
+        self.guild_banner = member.guild_banner
         self.pending = member.pending
+        self._flags = member._flags
         self.activities = member.activities
         self._state = member._state
 
@@ -294,14 +415,13 @@ def _copy(cls, member):
         self._user = member._user
         return self
 
-    async def _get_channel(self):
-        ch = await self.create_dm()
-        return ch
+    async def _get_channel(self) -> DMChannel:
+        return await self.create_dm()
 
-    def _update_roles(self, data):
-        self._roles = utils.SnowflakeList(map(int, data['roles']))
+    def _update_roles(self, data: PartialMember) -> None:
+        self._roles = utils.SnowflakeList(map(int, data.get('roles', [])))
 
-    def _update(self, data):
+    def _update(self, data: MemberWithUser) -> None:
         # the nickname change is optional,
         # if it isn't in the payload then it didn't change
         try:
@@ -313,11 +433,22 @@ def _update(self, data):
             self.pending = data['pending']
         except KeyError:
             pass
+        
+        try:
+            self._flags = data['flags']
+        except KeyError:
+            pass
+        
+
+        try:
+            self._communication_disabled_until = data['communication_disabled_until']
+        except KeyError:
+            self._communication_disabled_until = None
 
         self.premium_since = utils.parse_time(data.get('premium_since'))
         self._update_roles(data)
 
-    def _presence_update(self, data, user):
+    def _presence_update(self, data, user: Optional[UserData] = None) -> Optional[Tuple[User, User]]:
         self.activities = tuple(map(create_activity, data.get('activities', [])))
         self._client_status = {
             sys.intern(key): sys.intern(value)
@@ -325,28 +456,45 @@ def _presence_update(self, data, user):
         }
         self._client_status[None] = sys.intern(data['status'])
 
-        if len(user) > 1:
+        if user:
             return self._update_inner_user(user)
-        return False
 
-    def _update_inner_user(self, user):
+    def _update_inner_user(self, user: UserData) -> Tuple[User, User]:
         u = self._user
-        original = (u.name, u.avatar, u.discriminator, u._public_flags)
+        original = (
+            u.username,
+            u.global_name,
+            u.avatar,
+            u.avatar_decoration,
+            u.discriminator,
+            u._public_flags
+        )
+        if len(user) == 1 and 'id' in user:
+            # The user wasn't updated, so we can just ignore this
+            return
         # These keys seem to always be available
-        modified = (user['username'], user['avatar'], user['discriminator'], user.get('public_flags', 0))
+        modified = (
+            user.get('username'),
+            user.get('global_name'),
+            user.get('avatar'),
+            user.get('avatar_decoration'),
+            user.get('discriminator', '0'),
+            user.get('public_flags', 0)
+        )
+
         if original != modified:
             to_return = User._copy(self._user)
-            u.name, u.avatar, u.discriminator, u._public_flags = modified
+            u.username, u.global_name, u.avatar, u.avatar_decoration, u.discriminator, u._public_flags = modified
             # Signal to dispatch on_user_update
             return to_return, u
 
     @property
-    def status(self):
+    def status(self) -> Status:
         """:class:`Status`: The member's overall status. If the value is unknown, then it will be a :class:`str` instead."""
         return try_enum(Status, self._client_status[None])
 
     @property
-    def raw_status(self):
+    def raw_status(self) -> str:
         """:class:`str`: The member's overall status as a string value.
 
         .. versionadded:: 1.5
@@ -359,26 +507,26 @@ def status(self, value):
         self._client_status[None] = str(value)
 
     @property
-    def mobile_status(self):
+    def mobile_status(self) ->  Status:
         """:class:`Status`: The member's status on a mobile device, if applicable."""
         return try_enum(Status, self._client_status.get('mobile', 'offline'))
 
     @property
-    def desktop_status(self):
+    def desktop_status(self) -> Status:
         """:class:`Status`: The member's status on the desktop client, if applicable."""
         return try_enum(Status, self._client_status.get('desktop', 'offline'))
 
     @property
-    def web_status(self):
+    def web_status(self) -> Status:
         """:class:`Status`: The member's status on the web client, if applicable."""
         return try_enum(Status, self._client_status.get('web', 'offline'))
 
-    def is_on_mobile(self):
+    def is_on_mobile(self) -> bool:
         """:class:`bool`: A helper function that determines if a member is active on a mobile device."""
         return 'mobile' in self._client_status
 
     @property
-    def colour(self):
+    def colour(self) -> Colour:
         """:class:`Colour`: A property that returns a colour denoting the rendered colour
         for the member. If the default colour is the one rendered then an instance
         of :meth:`Colour.default` is returned.
@@ -397,7 +545,7 @@ def colour(self):
         return Colour.default()
 
     @property
-    def color(self):
+    def color(self) -> Colour:
         """:class:`Colour`: A property that returns a color denoting the rendered color for
         the member. If the default color is the one rendered then an instance of :meth:`Colour.default`
         is returned.
@@ -407,7 +555,13 @@ def color(self):
         return self.colour
 
     @property
-    def roles(self):
+    def role_ids(self) -> utils.SnowflakeList:
+        """:class:`utils.SnowflakeList`: An iterable of :class:`int` contain the ID's of the roles the member has.
+        You can use this to check on an efficient way whether a member has a role or not"""
+        return self._roles
+
+    @property
+    def roles(self) -> List[Role]:
         """List[:class:`Role`]: A :class:`list` of :class:`Role` that the member belongs to. Note
         that the first element of this list is always the default '@everyone'
         role.
@@ -425,32 +579,157 @@ def roles(self):
         return result
 
     @property
-    def mention(self):
+    def mention(self) -> str:
         """:class:`str`: Returns a string that allows you to mention the member."""
-        if self.nick:
-            return '<@!%s>' % self.id
-        return '<@%s>' % self.id
+        return f'<@!{self.id}>' if self.nick else f'<@{self.id}>'
 
     @property
-    def display_name(self):
+    def display_name(self) -> str:
         """:class:`str`: Returns the user's display name.
 
-        For regular users this is just their username, but
-        if they have a guild specific nickname then that
-        is returned instead.
+        This is either the guild :attr:`nick`, the :attr:`global_name` or the :attr:`username` of the user.
+        """
+        return self.nick or self.global_name or self.username
+
+    @property
+    def guild_avatar_url(self) -> Optional[Asset]:
+        """Optional[:class:`Asset`]: Returns the guild-specific banner asset for the member if any."""
+        return self.guild_avatar_url_as()
+
+    def guild_avatar_url_as(
+            self,
+            *,
+            format: Optional[Literal['jpeg', 'jpg', 'webp', 'png', 'gif']] = None,
+            static_format: Literal['jpeg', 'jpg', 'webp', 'png'] = 'webp',
+            size: int = 1024
+    ) -> Optional[Asset]:
+        """Returns an :class:`Asset` for the guild-specific avatar of the member if any, else :obj:`None`.
+
+        The format must be one of 'webp', 'jpeg', or 'png'. The
+        size must be a power of 2 between 16 and 4096.
+
+        Parameters
+        -----------
+        format: :class:`str`
+            The format to attempt to convert the avatar to.
+        static_format: :class:`str`
+            The format to attempt to convert the avatar to if the avatar is animated.
+        size: :class:`int`
+            The size of the image to display.
+
+        Raises
+        ------
+        InvalidArgument
+            Bad image format passed to ``format`` or invalid ``size``.
+
+        Returns
+        --------
+        Optional[:class:`Asset`]
+            The resulting CDN asset if any.
+        """
+        if self.guild_avatar:
+            return Asset._from_guild_avatar(self._state, self, static_format=static_format, format=format, size=size)
+
+    def is_guild_avatar_animated(self) -> bool:
+        """:class:`bool`: Indicates if the member has an animated guild-avatar."""
+        return bool(self.guild_avatar and self.guild_avatar.startswith('a_'))
+
+    @property
+    def display_avatar_url(self) -> Asset:
+        """:class:`Asset`:
+        Returns the displayed avatar of the member.
+
+        This is in the following order:
+        - Guild-specific avatar if available
+        - User avatar if available
+        - Default avatar
+         """
+        return self.guild_avatar_url or self.avatar_url
+
+    @property
+    def display_avatar(self) -> Asset:
+        """:class:`Asset`: An alias for :attr:`display_avatar_url`."""
+        return self.display_avatar_url
+
+    def display_avatar_url_as(
+            self,
+            format: Optional[Literal['jpeg', 'jpg', 'webp', 'png', 'gif']] = None,
+            static_format: Literal['jpeg', 'jpg', 'webp', 'png'] = 'webp',
+            size: int = 1024
+    ) -> Asset:
+        """:class:`Asset`: Same behaviour as :meth:`User.avatar_url_as` and :meth:`.guild_avatar_url_as` but it prefers the guild-specific avatar"""
+        if self.guild_avatar:
+            return self.guild_avatar_url_as(format=format, static_format=static_format, size=size)
+        return self.avatar_url_as(format=format, static_format=static_format, size=size)
+
+    @property
+    def guild_banner_url(self) -> Optional[Asset]:
+        """Optional[:class:`Asset`]: Returns the guild-specific banner asset for the member if any."""
+        return self.guild_banner_url_as()
+
+    def guild_banner_url_as(
+            self,
+            *,
+            format: Optional[Literal['jpeg', 'jpg', 'webp', 'png', 'gif']] = None,
+            static_format: Literal['jpeg', 'jpg', 'webp', 'png'] = 'webp',
+            size: int = 1024
+    ) -> Optional[Asset]:
+        """Returns an :class:`Asset` for the guild-specific banner of the member if any, else :obj:`None`.
+
+        The format must be one of 'webp', 'jpeg', 'gif' or 'png'. The
+        size must be a power of 2 between 16 and 4096.
+
+        Parameters
+        -----------
+        format: :class:`str`
+            The format to attempt to convert the banner to.
+        static_format: :class:`str`
+            The format to attempt to convert the banner to if the banner is animated.
+        size: :class:`int`
+            The size of the image to display.
+
+        Raises
+        ------
+        InvalidArgument
+            Bad image format passed to ``format`` or invalid ``size``.
+
+        Returns
+        --------
+        Optional[:class:`Asset`}
+            The resulting CDN asset if any.
         """
-        return self.nick or self.name
+        return Asset._from_guild_banner(self._state, self, static_format=static_format, format=format, size=size)
+
+    def is_guild_banner_animated(self) -> bool:
+        """:class:`bool`: Indicates if the member has an animated guild-banner."""
+        return bool(self.guild_banner and self.guild_banner.startswith('a_'))
+
+    @property
+    def display_banner_url(self) -> Optional[Asset]:
+        """Optional[:class:`Asset`]: Returns the guild-specific banner asset for the member if he has one, else the default banner asset if any."""
+        return self.guild_banner_url or self.banner_url
+
+    def display_banner_url_as(
+            self,
+            format: Optional[Literal['jpeg', 'jpg', 'webp', 'png', 'gif']] = None,
+            static_format: Literal['jpeg', 'jpg', 'webp', 'png'] = 'webp',
+            size: int = 1024
+    ) -> Optional[Asset]:
+        """Optional[:class:`Asset`]: Same behaviour as :meth:`User.banner_url_as` and :meth:`~Member.guild_banner_url_as` but it prefers the guild-specific banner"""
+        if self.guild_banner:
+            return self.guild_banner_url_as(format=format, static_format=static_format, size=size)
+        return self.banner_url_as(format=format, static_format=static_format, size=size)
 
     @property
-    def activity(self):
+    def activity(self) -> Optional[Union[BaseActivity, Spotify]]:
         """Union[:class:`BaseActivity`, :class:`Spotify`]: Returns the primary
         activity the user is currently doing. Could be ``None`` if no activity is being done.
 
         .. note::
 
-            Due to a Discord API limitation, this may be ``None`` if 
+            Due to a Discord API limitation, this may be ``None`` if
             the user is listening to a song on Spotify with a title longer
-            than 128 characters. See :issue:`1738` for more information.
+            than 128 characters. See :old-issue:`1738` for more information.
 
         .. note::
 
@@ -459,7 +738,7 @@ def activity(self):
         if self.activities:
             return self.activities[0]
 
-    def mentioned_in(self, message):
+    def mentioned_in(self, message: Message) -> bool:
         """Checks if the member is mentioned in the specified message.
 
         Parameters
@@ -480,7 +759,7 @@ def mentioned_in(self, message):
 
         return any(self._roles.has(role.id) for role in message.role_mentions)
 
-    def permissions_in(self, channel):
+    def permissions_in(self, channel: Union[abc.GuildChannel, ThreadChannel]) -> Permissions:
         """An alias for :meth:`abc.GuildChannel.permissions_for`.
 
         Basically equivalent to:
@@ -502,7 +781,7 @@ def permissions_in(self, channel):
         return channel.permissions_for(self)
 
     @property
-    def top_role(self):
+    def top_role(self) -> Role:
         """:class:`Role`: Returns the member's highest role.
 
         This is useful for figuring where a member stands in the role
@@ -515,7 +794,7 @@ def top_role(self):
         return max(guild.get_role(rid) or guild.default_role for rid in self._roles)
 
     @property
-    def guild_permissions(self):
+    def guild_permissions(self) -> Permissions:
         """:class:`Permissions`: Returns the member's guild permissions.
 
         This only takes into consideration the guild permissions
@@ -541,51 +820,162 @@ def guild_permissions(self):
         return base
 
     @property
-    def voice(self):
+    def voice(self) -> Optional[VoiceState]:
         """Optional[:class:`VoiceState`]: Returns the member's current voice state."""
         return self.guild._voice_state_for(self._user.id)
 
-    async def ban(self, **kwargs):
+    @property
+    def communication_disabled_until(self) -> Optional[datetime.datetime]:
+        """Optional[:class:`datetime.datetime`]: The time until the member is timeouted, if any"""
+        return datetime.datetime.fromisoformat(self._communication_disabled_until) if self._communication_disabled_until else None
+
+    @property
+    def timed_out(self) -> bool:
+        """:class.`bool`: Returns True when the member is timed out.
+
+        .. versionadded:: 2.0
+        """
+        return (
+            self.communication_disabled_until is not None
+            and self.communication_disabled_until
+            > utils.utcnow()
+        )
+
+    @utils.deprecated('Member.timeout')
+    async def mute(self, until: datetime.datetime, *, reason: Optional[str] = None) -> Member:
+        return await self.edit(communication_disabled_until=until, reason=reason)
+
+    async def timeout(
+            self,
+            until: Union[datetime.datetime, datetime.timedelta],
+            *,
+            reason: Optional[str] = None
+    ) -> Member:
         """|coro|
 
-        Bans this member. Equivalent to :meth:`Guild.ban`.
+        A shortcut method to timeout a member.
+        This just calls :meth:`~Member.edit` with the `communication_disabled_until` field set.
+
+        The :attr:`~Permissions.moderate_members` permission is needed to do this.
+
+        Parameters
+        -----------
+        until: Union[:class:`~datetime.datetime`, :class:`~datetime.timedelta`]
+            Until when the member should be timeouted.
+            This can be a timezone aware datetime object or a timedelta that will be added to the current time.
+            
+            .. note::
+
+                This can be max 28 days from current time!
+
+        reason: Optional[:class:`str`]
+            The reason for sending the member to timeout - Shows up in the audit-log
+        
+        Raises
+        -------
+        TypeError
+            The passed :class:`~datetime.datetime` object is not timezone aware
+        Forbidden
+            The bot missing access to time out this member
+        HTTPException
+            Sending the member to timeout failed
         """
-        await self.guild.ban(self, **kwargs)
+        if isinstance(until, datetime.timedelta):
+            until = utils.utcnow() + until
+        return await self.edit(communication_disabled_until=until, reason=reason)
 
-    async def unban(self, *, reason=None):
+    async def remove_timeout(self, *, reason: Optional[str] = None) -> Member:
+        """|coro|
+
+        A shortcut method to remove a member from timeout.
+
+        The :attr:`~Permissions.moderate_members` permission is needed to do this.
+
+        Parameters
+        -----------
+        reason: Optional[:class:`str`]
+            The reason for removing the member from timeout - Shows up in the audit-log
+
+        Raises
+        -------
+        Forbidden
+            The bot missing access to remove this member from timeout
+        HTTPException
+            Removing the member from timeout failed
+        """
+        return await self.edit(communication_disabled_until=None, reason=reason)
+
+    async def ban(
+            self,
+            delete_message_days: Optional[int] = None,
+            delete_message_seconds: Optional[int] = 0,
+            reason: Optional[str] = None
+    ):
+        """|coro|
+
+        Bans this member. Equivalent to :meth:`Guild.ban`.
+        """
+        await self.guild.ban(
+            self,
+            delete_message_days=delete_message_days,
+            delete_message_seconds=delete_message_seconds,
+            reason=reason
+        )
+
+    async def unban(self, *, reason: Optional[str] = None):
         """|coro|
 
         Unbans this member. Equivalent to :meth:`Guild.unban`.
         """
         await self.guild.unban(self, reason=reason)
 
-    async def kick(self, *, reason=None):
+    async def kick(self, *, reason: Optional[str] = None):
         """|coro|
 
         Kicks this member. Equivalent to :meth:`Guild.kick`.
         """
         await self.guild.kick(self, reason=reason)
 
-    async def edit(self, *, reason=None, **fields):
+    async def edit(
+            self,
+            *,
+            nick: Optional[str] = MISSING,
+            mute: bool = MISSING,
+            deafen: bool = MISSING,
+            suppress: bool = MISSING,
+            roles: Iterable[abc.Snowflake] = MISSING,
+            voice_channel: Optional[VoiceChannel] = MISSING,
+            flags: GuildMemberFlags = MISSING,
+            communication_disabled_until: Optional[datetime.datetime] = MISSING,
+            reason: Optional[str] = None
+    ) -> Member:
         """|coro|
 
         Edits the member's data.
 
         Depending on the parameter passed, this requires different permissions listed below:
 
-        +---------------+--------------------------------------+
-        |   Parameter   |              Permission              |
-        +---------------+--------------------------------------+
-        | nick          | :attr:`Permissions.manage_nicknames` |
-        +---------------+--------------------------------------+
-        | mute          | :attr:`Permissions.mute_members`     |
-        +---------------+--------------------------------------+
-        | deafen        | :attr:`Permissions.deafen_members`   |
-        +---------------+--------------------------------------+
-        | roles         | :attr:`Permissions.manage_roles`     |
-        +---------------+--------------------------------------+
-        | voice_channel | :attr:`Permissions.move_members`     |
-        +---------------+--------------------------------------+
+        +------------------------------+--------------------------------------------+
+        |          Parameter           |              Permission                    |
+        +------------------------------+--------------------------------------------+
+        | nick                         | :attr:`Permissions.manage_nicknames`       |
+        +------------------------------+--------------------------------------------+
+        | mute                         | :attr:`Permissions.mute_members`           |
+        +------------------------------+--------------------------------------------+
+        | deafen                       | :attr:`Permissions.deafen_members`         |
+        +------------------------------+--------------------------------------------+
+        | roles                        | :attr:`Permissions.manage_roles`           |
+        +------------------------------+--------------------------------------------+
+        | voice_channel                | :attr:`Permissions.move_members`           |
+        +------------------------------+--------------------------------------------+
+        | flags                        | - :attr:`Permissions.manage_guild` OR      |
+        |                              | - :attr:`Permissions.manage_roles` OR      |
+        |                              | - :attr:`Permissions.moderate_members` AND |
+        |                              |   :attr:`Permissions.kick_members` AND     |
+        |                              |   :attr:`Permissions.ban_members`          |
+        +------------------------------+--------------------------------------------+
+        | communication_disabled_until | :attr:`Permissions.moderate_members`       |
+        +------------------------------+--------------------------------------------+
 
         All parameters are optional.
 
@@ -610,11 +1000,25 @@ async def edit(self, *, reason=None, **fields):
         voice_channel: Optional[:class:`VoiceChannel`]
             The voice channel to move the member to.
             Pass ``None`` to kick them from voice.
+        flags: Optional[:class:`GuildMemberFlags`]
+            The new flags for this member.
+            Note that you are currently only able to update the
+            :attr:`~discord.GuildMemberFlags.bypasses_verification` flag.
+        communication_disabled_until: Optional[:class:`datetime.datetime`]
+            Temporarily puts the member in timeout until this time.
+            If :obj:`None`, then the member  is removed from timeout.
+
+            .. note::
+
+                The :class:`~datetime.datetime` object must be timezone aware.
+
         reason: Optional[:class:`str`]
             The reason for editing this member. Shows up on the audit log.
 
         Raises
         -------
+        TypeError
+            The :class:`~datetime.datetime` object passed to ``communication_disabled_until`` is not timezone aware
         Forbidden
             You do not have the proper permissions to the action requested.
         HTTPException
@@ -623,31 +1027,23 @@ async def edit(self, *, reason=None, **fields):
         http = self._state.http
         guild_id = self.guild.id
         me = self._state.self_id == self.id
-        payload = {}
+        payload: Dict[str, Any] = {}
 
-        try:
-            nick = fields['nick']
-        except KeyError:
-            # nick not present so...
-            pass
-        else:
+        if nick is not MISSING:
             nick = nick or ''
             if me:
                 await http.change_my_nickname(guild_id, nick, reason=reason)
             else:
                 payload['nick'] = nick
 
-        deafen = fields.get('deafen')
-        if deafen is not None:
-            payload['deaf'] = deafen
-
-        mute = fields.get('mute')
-        if mute is not None:
+        if mute is not MISSING:
             payload['mute'] = mute
 
-        suppress = fields.get('suppress')
-        if suppress is not None:
-            voice_state_payload = {
+        if deafen is not MISSING:
+            payload['deaf'] = deafen
+
+        if suppress is not MISSING:
+            voice_state_payload: Dict[str, Any] = {
                 'channel_id': self.voice.channel.id,
                 'suppress': suppress,
             }
@@ -659,29 +1055,40 @@ async def edit(self, *, reason=None, **fields):
                 await http.edit_my_voice_state(guild_id, voice_state_payload)
             else:
                 if not suppress:
-                    voice_state_payload['request_to_speak_timestamp'] = datetime.datetime.utcnow().isoformat()
+                    voice_state_payload[
+                        'request_to_speak_timestamp'
+                    ] = datetime.datetime.now(datetime.timezone.utc).isoformat()
                 await http.edit_voice_state(guild_id, self.id, voice_state_payload)
 
-        try:
-            vc = fields['voice_channel']
-        except KeyError:
-            pass
-        else:
-            payload['channel_id'] = vc and vc.id
+        if voice_channel is not MISSING:
+            payload['channel_id'] = voice_channel and voice_channel.id
 
-        try:
-            roles = fields['roles']
-        except KeyError:
-            pass
-        else:
+        if roles is not MISSING:
             payload['roles'] = tuple(r.id for r in roles)
 
+        if flags is not MISSING:
+            payload['flags'] = flags.value
+
+        if communication_disabled_until is not MISSING:
+            if communication_disabled_until:
+                if not communication_disabled_until.tzinfo:
+                    raise TypeError(
+                        'communication_disabled_until must be an aware datetime.'
+                        'Consider using discord.utils.utcnow() '
+                        'or datetime.datetime.now().astimezone() for local time.'
+                    )
+                payload['communication_disabled_until'] = communication_disabled_until.isoformat()
+            else:
+                payload['communication_disabled_until'] = None
+
         if payload:
-            await http.edit_member(guild_id, self.id, reason=reason, **payload)
+            data = await http.edit_member(guild_id, self.id, reason=reason, **payload)
+            self._update(data)
+            return self
 
         # TODO: wait for WS event for modify-in-place behaviour
 
-    async def request_to_speak(self):
+    async def request_to_speak(self) -> None:
         """|coro|
 
         Request to speak in the connected channel.
@@ -704,7 +1111,7 @@ async def request_to_speak(self):
         """
         payload = {
             'channel_id': self.voice.channel.id,
-            'request_to_speak_timestamp': datetime.datetime.utcnow().isoformat(),
+            'request_to_speak_timestamp': datetime.datetime.now(datetime.timezone.utc).isoformat(),
         }
 
         if self._state.self_id != self.id:
@@ -713,7 +1120,7 @@ async def request_to_speak(self):
         else:
             await self._state.http.edit_my_voice_state(self.guild.id, payload)
 
-    async def move_to(self, channel, *, reason=None):
+    async def move_to(self, channel: Optional[VocalGuildChannel], *, reason: Optional[str] = None) -> None:
         """|coro|
 
         Moves a member to a new voice channel (they must be connected first).
@@ -728,7 +1135,7 @@ async def move_to(self, channel, *, reason=None):
 
         Parameters
         -----------
-        channel: Optional[:class:`VoiceChannel`]
+        channel: Optional[Union[:class:`VoiceChannel`, :class:`StageChannel`]
             The new voice channel to move the member to.
             Pass ``None`` to kick them from voice.
         reason: Optional[:class:`str`]
@@ -736,7 +1143,7 @@ async def move_to(self, channel, *, reason=None):
         """
         await self.edit(voice_channel=channel, reason=reason)
 
-    async def add_roles(self, *roles, reason=None, atomic=True):
+    async def add_roles(self, *roles: abc.Snowflake, reason: Optional[str] = None, atomic: bool = True) -> None:
         r"""|coro|
 
         Gives the member a number of :class:`Role`\s.
@@ -766,8 +1173,11 @@ async def add_roles(self, *roles, reason=None, atomic=True):
         """
 
         if not atomic:
-            new_roles = utils._unique(Object(id=r.id) for s in (self.roles[1:], roles) for r in s)
-            await self.edit(roles=new_roles, reason=reason)
+            new_roles = utils._unique(
+                (Object(id=r.id) for s in (self.roles[1:], roles) for r in s),
+                tuple
+            )
+            await self.edit(roles=new_roles, reason=reason) # type: ignore
         else:
             req = self._state.http.add_role
             guild_id = self.guild.id
@@ -775,7 +1185,7 @@ async def add_roles(self, *roles, reason=None, atomic=True):
             for role in roles:
                 await req(guild_id, user_id, role.id, reason=reason)
 
-    async def remove_roles(self, *roles, reason=None, atomic=True):
+    async def remove_roles(self, *roles: Role, reason: Optional[str] = None, atomic: bool = True):
         r"""|coro|
 
         Removes :class:`Role`\s from this member.
@@ -805,7 +1215,7 @@ async def remove_roles(self, *roles, reason=None, atomic=True):
         """
 
         if not atomic:
-            new_roles = [Object(id=r.id) for r in self.roles[1:]] # remove @everyone
+            new_roles = [Object(id=r.id) for r in self.roles[1:]]  # remove @everyone
             for role in roles:
                 try:
                     new_roles.remove(Object(id=role.id))
diff --git a/discord/mentions.py b/discord/mentions.py
index 2cabc4c6..a54af27a 100644
--- a/discord/mentions.py
+++ b/discord/mentions.py
@@ -3,7 +3,7 @@
 """
 The MIT License (MIT)
 
-Copyright (c) 2015-present Rapptz
+Copyright (c) 2015-2021 Rapptz & (c) 2021-present mccoderpy
 
 Permission is hereby granted, free of charge, to any person obtaining a
 copy of this software and associated documentation files (the "Software"),
diff --git a/discord/message.py b/discord/message.py
index 8f31878b..9106fd84 100644
--- a/discord/message.py
+++ b/discord/message.py
@@ -3,9 +3,7 @@
 """
 The MIT License (MIT)
 
-Copyright (c) 2015-present Rapptz
-
-Implementing of the Discord-Message-components made by mccoderpy (Discord-User mccuber04#2960)
+Copyright (c) 2015-2021 Rapptz & (c) 2021-present mccoderpy
 
 Permission is hereby granted, free of charge, to any person obtaining a
 copy of this software and associated documentation files (the "Software"),
@@ -25,39 +23,104 @@
 FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 DEALINGS IN THE SOFTWARE.
 """
+from __future__ import annotations
 
 import asyncio
-import datetime
+from datetime import datetime
+from base64 import b64decode
 import re
 import io
 
+from typing import (
+    TYPE_CHECKING,
+    Generic,
+    Union,
+    Optional,
+    Callable,
+    Sequence,
+    Iterator,
+    List,
+    Any,
+    TypeVar,
+)
+
+from typing_extensions import Self
+
 from . import utils
 from .reaction import Reaction
 from .emoji import Emoji
 from .partial_emoji import PartialEmoji
-from .calls import CallMessage
-from .enums import MessageType, ChannelType, try_enum
-from .errors import InvalidArgument, ClientException, HTTPException, NotFound
+from .enums import try_enum, MessageType, ChannelType, AutoArchiveDuration, InteractionType
+from .errors import InvalidArgument, HTTPException
+from .components import ActionRow, Button, SelectMenu
 from .embeds import Embed
-from .components import Button, SelectMenu, ActionRow
 from .member import Member
 from .flags import MessageFlags
 from .file import File
-from .utils import escape_mentions
+from .utils import escape_mentions, MISSING
 from .guild import Guild
 from .mixins import Hashable
 from .sticker import Sticker
+from .http import handle_message_parameters
+from .channel import (
+    PartialMessageable,
+    ThreadChannel,
+    TextChannel,
+    VoiceChannel,
+    StageChannel,
+    ForumChannel,
+    ForumPost,
+    DMChannel,
+)
+
+if TYPE_CHECKING:
+    from os import PathLike
+    from .types.user import PartialMember as PartialMemberPayload
+    from .types.message import (
+        Attachment as AttachmentPayload,
+        Message as MessagePayload,
+        RoleSubscriptionData,
+        MessageReference as MessageReferenceData,
+        MessageInteraction as MessageInteractionData
+    )
+    from .user import User
+    from .state import ConnectionState
+    from .http import HTTPClient
+    from .mentions import AllowedMentions
+    from .abc import Messageable, Snowflake
+    from .sticker import GuildSticker
+    from .role import Role
+    from .components import (
+        UserSelect,
+        RoleSelect,
+        MentionableSelect,
+        ChannelSelect
+    )
+    MentionableChannel = Union[
+        TextChannel,
+        VoiceChannel,
+        StageChannel,
+        ThreadChannel,
+        TextChannel,
+        ForumChannel,
+        ForumPost
+    ]
+    Select = Union[SelectMenu, UserSelect, RoleSelect, MentionableSelect, ChannelSelect]
+
+_MCH = TypeVar('_MCH', TextChannel, VoiceChannel, StageChannel, ThreadChannel, ForumPost, DMChannel, PartialMessageable)
 
 __all__ = (
     'Attachment',
+    'MessageInteraction',
     'Message',
     'PartialMessage',
     'MessageReference',
     'DeletedReferencedMessage',
+    'RoleSubscriptionInfo',
 )
 
 
-def convert_emoji_reaction(emoji):
+def convert_emoji_reaction(emoji: Union[Reaction, Emoji, PartialEmoji, str]) -> str:
     if isinstance(emoji, Reaction):
         emoji = emoji.emoji
 
@@ -96,7 +159,9 @@ class Attachment(Hashable):
             Returns the hash of the attachment.
 
     .. versionchanged:: 1.7
-        Attachment can now be casted to :class:`str` and is hashable.
+        Attachment can now be cast to :class:`str` and is hashable.
+    .. versionchanged:: 2.0
+        The :attr:`ephemeral`, :attr:`description`, :attr:`duration` and :attr:`waveform` attributes were added.
 
     Attributes
     ------------
@@ -119,34 +184,60 @@ class Attachment(Hashable):
         minutes or not valid at all.
     content_type: Optional[:class:`str`]
         The attachment's `media type <https://en.wikipedia.org/wiki/Media_type>`_
-
-        .. versionadded:: 1.7
+    ephemeral: :class:`bool`
+        Whether the attachment is ephemeral (part of an ephemeral message or was provided in a slash-command option).
+    description: Optional[:class:`str`]
+        The description for the file.
+    duration: Optional[:class:`float`]
+        The duration of the audio file (currently only for voice messages).
     """
 
-    __slots__ = ('id', 'size', 'height', 'width', 'filename', 'url', 'proxy_url', '_http', 'content_type')
-
-    def __init__(self, *, data, state):
-        self.id = int(data['id'])
-        self.size = data['size']
-        self.height = data.get('height')
-        self.width = data.get('width')
-        self.filename = data['filename']
-        self.url = data.get('url')
+    __slots__ = ('id', 'size', 'height', 'width', 'ephemeral', 'description',
+                 'filename', 'url', 'proxy_url', '_http', 'content_type', 'duration', '_waveform')
+
+    def __init__(self, *, data: AttachmentPayload, state: ConnectionState):
+        self.id: int = int(data['id'])
+        self.size: int = data['size']
+        self.height: Optional[int] = data.get('height')
+        self.width: Optional[int] = data.get('width')
+        self.ephemeral: bool = data.get('ephemeral', False)
+        self.description: Optional[str] = data.get('description')
+        self.filename: str = data['filename']
+        self.url: str = data.get('url')
         self.proxy_url = data.get('proxy_url')
-        self._http = state.http
-        self.content_type = data.get('content_type')
+        self._http: HTTPClient = state.http
+        self.content_type: str = data.get('content_type')
+        self.duration: Optional[float] = data.get('duration_secs')
+        self._waveform: Optional[List[int]] = data.get('waveform')
 
-    def is_spoiler(self):
+    def is_spoiler(self) -> bool:
         """:class:`bool`: Whether this attachment contains a spoiler."""
         return self.filename.startswith('SPOILER_')
+    
+    @property
+    def waveform(self) -> Optional[bytearray]:
+        """:class:`Optional[List[:class:`int`]]`: The waveform of the audio file (currently only for voice messages)."""
+        return b64decode(self._waveform) if self._waveform else None
 
-    def __repr__(self):
+    def __repr__(self) -> str:
         return '<Attachment id={0.id} filename={0.filename!r} url={0.url!r}>'.format(self)
 
-    def __str__(self):
+    def __str__(self) -> str:
         return self.url or ''
 
-    async def save(self, fp, *, seek_begin=True, use_cached=False):
+    def _to_minimal_dict(self):
+        """:class:`dict`: A minimal dictionary containing the filename and description of the attachment."""
+        return {'filename': self.filename, 'description': self.description}
+
+    to_dict = _to_minimal_dict
+
+    async def save(
+            self,
+            fp: Union[io.BufferedIOBase, PathLike[str], PathLike[bytes]],
+            *,
+            seek_begin: bool = True,
+            use_cached: bool = False
+    ) -> int:
         """|coro|
 
         Saves this attachment into a file-like object.
@@ -190,7 +281,7 @@ async def save(self, fp, *, seek_begin=True, use_cached=False):
             with open(fp, 'wb') as f:
                 return f.write(data)
 
-    async def read(self, *, use_cached=False):
+    async def read(self, *, use_cached: bool = False) -> bytes:
         """|coro|
 
         Retrieves the content of this attachment as a :class:`bytes` object.
@@ -225,7 +316,13 @@ async def read(self, *, use_cached=False):
         data = await self._http.get_from_cdn(url)
         return data
 
-    async def to_file(self, *, use_cached=False, spoiler=False):
+    async def to_file(
+            self,
+            *,
+            use_cached: bool = False,
+            spoiler: bool = False,
+            description: Optional[str] = MISSING
+    ) -> File:
         """|coro|
 
         Converts the attachment into a :class:`File` suitable for sending via
@@ -248,6 +345,12 @@ async def to_file(self, *, use_cached=False, spoiler=False):
             Whether the file is a spoiler.
 
             .. versionadded:: 1.4
+        description: :class:`bool`
+            The description (*alt text*) for the file.
+
+            This will be default to the :attr:`~discord.Attachment.description`.
+            Set the value to :obj:`None` to supress this.
+            .. versionadded:: 2.0
 
         Raises
         ------
@@ -265,7 +368,87 @@ async def to_file(self, *, use_cached=False, spoiler=False):
         """
 
         data = await self.read(use_cached=use_cached)
-        return File(io.BytesIO(data), filename=self.filename, spoiler=spoiler)
+        return File(
+            io.BytesIO(data),
+            filename=self.filename,
+            spoiler=spoiler,
+            description=self.description if description is MISSING else description
+        )
+
+
+class MessageInteraction:
+    """
+    Represents the :attr:`~Message.interaction` object of a message that is a response to an interaction without an existing message.
+
+    .. note::
+        This means responses to :class:`ComponentInteraction` does not include this,
+        instead including a :attr:`~Message.reference` as components *always* exist on preexisting messages.
+
+    .. versionadded:: 2.0
+
+    Attributes
+    ----------
+    id: :class:`int`
+        The interaction's ID.
+    type: :class:`InteractionType`
+        The type of the interaction.
+    name: :class:`str`
+        The name of the :class:`ApplicationCommand`, **including subcommands and subcommand groups**.
+    user: :class:`User`
+        The user who invoked the interaction.
+    """
+    def __init__(self, state: ConnectionState, data: MessageInteractionData, guild: Optional[Guild] = None) -> None:
+        self._state: ConnectionState = state
+        self.id: int = int(data['id'])
+        self.type: InteractionType = try_enum(InteractionType, data['type'])
+        self.name: Optional[str] = data['name']
+        self.user: User = state.store_user(data['user'])
+        try:
+            member = data['member']
+        except KeyError:
+            self.member: Optional[Member] = None
+        else:
+            member['user'] = data['user']
+            if guild:  # can be None when cache is not filled yet 
+                self.member: Optional[Member] = guild.get_member(self.user.id) or Member(data=member, state=state, guild=guild)
+            else:
+                self.member: Optional[Member] = None
+    
+    def __repr__(self) -> str:
+        return f'<MessageInteraction command={self.name} user={self.user} interaction_id={self.id}>'
+
+
+class RoleSubscriptionInfo:
+    """Represents a message's role subscription information.
+
+    This is currently only attached to messages of type :attr:`MessageType.role_subscription_purchase`.
+
+    .. versionadded:: 2.0
+
+    Attributes
+    -----------
+    role_subscription_listing_id: :class:`int`
+        The ID of the SKU and listing that the user is subscribed to.
+    tier_name: :class:`str`
+        The name of the tier that the user is subscribed to.
+    total_months_subscribed: :class:`int`
+        The cumulative number of months that the user has been subscribed for.
+    is_renewal: :class:`bool`
+        Whether this notification is for a renewal rather than a new purchase.
+    """
+
+    __slots__ = (
+        'role_subscription_listing_id',
+        'tier_name',
+        'total_months_subscribed',
+        'is_renewal',
+    )
+
+    def __init__(self, data: RoleSubscriptionData) -> None:
+        self.role_subscription_listing_id: int = int(data['role_subscription_listing_id'])
+        self.tier_name: str = data['tier_name']
+        self.total_months_subscribed: int = data['total_months_subscribed']
+        self.is_renewal: bool = data['is_renewal']
 
 
 class DeletedReferencedMessage:
@@ -280,21 +463,21 @@ class DeletedReferencedMessage:
 
     __slots__ = ('_parent')
 
-    def __init__(self, parent):
+    def __init__(self, parent: MessageReference) -> None:
         self._parent = parent
 
     @property
-    def id(self):
+    def id(self) -> int:
         """:class:`int`: The message ID of the deleted referenced message."""
         return self._parent.message_id
 
     @property
-    def channel_id(self):
+    def channel_id(self) -> int:
         """:class:`int`: The channel ID of the deleted referenced message."""
         return self._parent.channel_id
 
     @property
-    def guild_id(self):
+    def guild_id(self) -> int:
         """Optional[:class:`int`]: The guild ID of the deleted referenced message."""
         return self._parent.guild_id
 
@@ -336,16 +519,16 @@ class MessageReference:
 
     __slots__ = ('message_id', 'channel_id', 'guild_id', 'fail_if_not_exists', 'resolved', '_state')
 
-    def __init__(self, *, message_id, channel_id, guild_id=None, fail_if_not_exists=True):
-        self._state = None
-        self.resolved = None
+    def __init__(self, *, message_id: int, channel_id: int, guild_id: Optional[int] = None, fail_if_not_exists: bool = True) -> None:
+        self._state: Optional[ConnectionState] = None
+        self.resolved: Optional[Union[Message, DeletedReferencedMessage]] = None
         self.message_id = message_id
         self.channel_id = channel_id
         self.guild_id = guild_id
         self.fail_if_not_exists = fail_if_not_exists
 
     @classmethod
-    def with_state(cls, state, data):
+    def with_state(cls, state: ConnectionState, data: MessageReferenceData) -> MessageReference:
         self = cls.__new__(cls)
         self.message_id = utils._get_as_snowflake(data, 'message_id')
         self.channel_id = int(data.pop('channel_id'))
@@ -356,7 +539,7 @@ def with_state(cls, state, data):
         return self
 
     @classmethod
-    def from_message(cls, message, *, fail_if_not_exists=True):
+    def from_message(cls, message: Message, *, fail_if_not_exists: bool = True) -> MessageReference:
         """Creates a :class:`MessageReference` from an existing :class:`~discord.Message`.
 
         .. versionadded:: 1.6
@@ -381,12 +564,12 @@ def from_message(cls, message, *, fail_if_not_exists=True):
         return self
 
     @property
-    def cached_message(self):
+    def cached_message(self) -> Optional[Message]:
         """Optional[:class:`~discord.Message`]: The cached message, if found in the internal message cache."""
         return self._state._get_message(self.message_id)
 
     @property
-    def jump_url(self):
+    def jump_url(self) -> str:
         """:class:`str`: Returns a URL that allows the client to jump to the referenced message.
 
         .. versionadded:: 1.7
@@ -394,10 +577,10 @@ def jump_url(self):
         guild_id = self.guild_id if self.guild_id is not None else '@me'
         return 'https://discord.com/channels/{0}/{1.channel_id}/{1.message_id}'.format(guild_id, self)
 
-    def __repr__(self):
+    def __repr__(self) -> str:
         return '<MessageReference message_id={0.message_id!r} channel_id={0.channel_id!r} guild_id={0.guild_id!r}>'.format(self)
 
-    def to_dict(self):
+    def to_dict(self) -> MessageReferenceData:
         result = {'message_id': self.message_id} if self.message_id is not None else {}
         result['channel_id'] = self.channel_id
         if self.guild_id is not None:
@@ -427,7 +610,7 @@ def flatten_handlers(cls):
 
 
 @flatten_handlers
-class Message(Hashable):
+class Message(Hashable, Generic[_MCH]):
     r"""Represents a message from Discord.
 
     .. container:: operations
@@ -463,15 +646,11 @@ class Message(Hashable):
         This is not stored long term within Discord's servers and is only used ephemerally.
     embeds: List[:class:`Embed`]
         A list of embeds the message has.
-    channel: Union[:class:`abc.Messageable`]
-        The :class:`TextChannel` that the message was sent from.
+    components: List[:class:`~discord.ActionRow`]:
+        A list of components the message has.
+    channel: Union[:class:`abc.Messageable`, :class:`~discord.ThreadChannel`]
+        The :class:`TextChannel`, :class:`~discord.ThreadChannel` or :class:`VoiceChannel` that the message was sent from.
         Could be a :class:`DMChannel` or :class:`GroupChannel` if it's a private message.
-    call: Optional[:class:`CallMessage`]
-        The call that the message refers to. This is only applicable to messages of type
-        :attr:`MessageType.call`.
-
-        .. deprecated:: 1.7
-
     reference: Optional[:class:`~discord.MessageReference`]
         The message that this message references. This is only applicable to messages of
         type :attr:`MessageType.pins_add`, crossposted messages created by a
@@ -516,7 +695,6 @@ class Message(Hashable):
         Extra features of the message.
 
         .. versionadded:: 1.3
-
     reactions : List[:class:`Reaction`]
         Reactions to a message. Reactions can be either custom emoji or standard unicode emoji.
     activity: Optional[:class:`dict`]
@@ -541,42 +719,81 @@ class Message(Hashable):
         A list of stickers given to the message.
 
         .. versionadded:: 1.6
+    interaction: Optional[:class:`MessageInteraction`]
+        The interaction this message is a response to, if any.
+
+        .. versionadded:: 2.0
+    role_subscription: Optional[:class:`RoleSubscriptionInfo`]
+        The data of the role subscription purchase or renewal that prompted this
+        :attr:`MessageType.role_subscription_purchase` message.
+
+        .. versionadded:: 2.0
+    position: Optional[:class:`int`]
+        A generally increasing integer with potentially gaps or duplicates that represents
+        the approximate position of the message in a thread.
+
+        .. versionadded:: 2.0
+    guild: Optional[:class:`Guild`]
+        The guild that the message belongs to if any.
     """
 
     __slots__ = ('_edited_timestamp', 'tts', 'content', 'channel', 'webhook_id',
                  'mention_everyone', 'embeds', 'components', 'id', 'mentions', 'author',
                  '_cs_channel_mentions', '_cs_raw_mentions', 'attachments',
                  '_cs_clean_content', '_cs_raw_channel_mentions', 'nonce', 'pinned',
-                 'role_mentions', '_cs_raw_role_mentions', 'type', 'call', 'flags',
-                 '_cs_system_content', '_cs_guild', '_state', 'reactions', 'reference',
-                 'application', 'activity', 'stickers')
-
-    def __init__(self, *, state, channel, data):
-        self._state = state
-        self.id = utils._get_as_snowflake(data, 'id')
-        self.webhook_id = utils._get_as_snowflake(data, 'webhook_id')
-        self.reactions = [Reaction(message=self, data=d) for d in data.get('reactions', [])]
-        self.attachments = [Attachment(data=a, state=self._state) for a in data.get('attachments', [])]
-        self.embeds = [Embed.from_dict(a) for a in data.get('embeds', [])]
-        self.components = [ActionRow.from_dict(d) for d in data.get('components', [])]
-        self.application = data.get('application')
-        self.activity = data.get('activity')
-        self.channel = channel
-        self.call = None
-        self._edited_timestamp = utils.parse_time(data['edited_timestamp'])
-        self.type = try_enum(MessageType, data['type'])
-        self.pinned = data['pinned']
-        self.flags = MessageFlags._from_value(data.get('flags', 0))
-        self.mention_everyone = data['mention_everyone']
-        self.tts = data['tts']
-        self.content = data['content']
-        self.nonce = data.get('nonce')
-        self.stickers = [Sticker(data=data, state=state) for data in data.get('stickers', [])]
+                 'role_mentions', '_cs_raw_role_mentions', 'type', 'flags',
+                 '_cs_system_content', '_state', 'reactions', 'reference',
+                 'application', 'activity', 'stickers', '_thread', 'interaction', 'guild',
+                 'role_subscription', 'position',)
+
+    if TYPE_CHECKING:
+        _state: ConnectionState
+        channel: _MCH
+        author: Union[User, Member]
+        mentions: List[Union[User, Member]]
+        role_mentions: List[Role]
+        reactions: List[Reaction]
+
+
+    def __init__(self, *, state: ConnectionState, channel: _MCH, data: MessagePayload):
+        self._state: ConnectionState = state
+        self.id: int = utils._get_as_snowflake(data, 'id')
+        self.webhook_id: Optional[int] = utils._get_as_snowflake(data, 'webhook_id')
+        self.reactions: List[Reaction] = [Reaction(message=self, data=d) for d in data.get('reactions', [])]
+        self.attachments: List[Attachment] = [Attachment(data=a, state=self._state) for a in data.get('attachments', [])]
+        self.embeds: List[Embed] = [Embed.from_dict(a) for a in data.get('embeds', [])]
+        self.components: List[ActionRow] = [ActionRow.from_dict(d) for d in data.get('components', [])]
+        self.application = data.get('application')  # TODO: make this a class
+        self.activity = data.get('activity')  # TODO: make this a class
+        self.channel: _MCH = channel
+        self._edited_timestamp: datetime = utils.parse_time(data['edited_timestamp'])
+        self.type: MessageType = try_enum(MessageType, data['type'])
+        self.pinned: bool = data['pinned']
+        self.mention_everyone: bool = data['mention_everyone']
+        self.tts: bool = data['tts']
+        self.content: Optional[str] = data['content']
+        self.nonce: Optional[str] = data.get('nonce')
+        self.position: Optional[int] = data.get('position')
+        self.stickers: List[Union[Sticker, GuildSticker]] = [
+            Sticker(data=data, state=state) for data in data.get('sticker_items', [])
+        ]
 
+        try:
+            self.guild: Optional[Guild] = channel.guild
+        except AttributeError:
+            self.guild: Optional[Guild] = state._get_guild(utils._get_as_snowflake(data, 'guild_id'))
+        
+        interaction = data.get('interaction')
+        self.interaction: Optional[MessageInteraction] = MessageInteraction(
+            state=state,
+            data=interaction,
+            guild=self.guild
+        ) if interaction else None
+        
         try:
             ref = data['message_reference']
         except KeyError:
-            self.reference = None
+            self.reference: Optional[Union[MessageReference, DeletedReferencedMessage]] = None
         else:
             self.reference = ref = MessageReference.with_state(state, ref)
             try:
@@ -588,23 +805,40 @@ def __init__(self, *, state, channel, data):
                     ref.resolved = DeletedReferencedMessage(ref)
                 else:
                     # Right now the channel IDs match but maybe in the future they won't.
-                    if ref.channel_id == channel.id:
+                    if (
+                            ref.channel_id == channel.id or
+                            isinstance(channel, ThreadChannel) and channel.parent_id == ref.channel_id
+                    ):
                         chan = channel
                     else:
                         chan, _ = state._get_guild_channel(resolved)
 
                     ref.resolved = self.__class__(channel=chan, data=resolved, state=state)
 
-        for handler in ('author', 'member', 'mentions', 'mention_roles', 'call', 'flags'):
+        self.role_subscription: Optional[RoleSubscriptionInfo] = None
+        try:
+            role_subscription = data['role_subscription_data']
+        except KeyError:
+            pass
+        else:
+            self.role_subscription = RoleSubscriptionInfo(role_subscription)
+
+        for handler in ('author', 'member', 'mentions', 'mention_roles', 'flags', 'thread'):
             try:
                 getattr(self, '_handle_%s' % handler)(data[handler])
             except KeyError:
                 continue
 
-    def __repr__(self):
-        return '<Message id={0.id} channel={0.channel!r} type={0.type!r} author={0.author!r} flags={0.flags!r}>'.format(self)
+    def __repr__(self) -> str:
+        return (
+            '<Message id={0.id} channel={0.channel!r} type={0.type!r} '
+            'author={0.author!r} flags={0.flags!r}>'.format(self)
+        )
+
+    def __remove_from_cache__(self, _):
+        self._state._messages.remove(self)
 
-    def _try_patch(self, data, key, transform=None):
+    def _try_patch(self, data: MessagePayload, key: str, transform: Optional[Callable[..., Any]] = None) -> None:
         try:
             value = data[key]
         except KeyError:
@@ -648,7 +882,7 @@ def _remove_reaction(self, data, emoji, user_id):
 
         return reaction
 
-    def _clear_emoji(self, emoji):
+    def _clear_emoji(self, emoji: Union[Emoji, PartialEmoji, str]):
         to_check = str(emoji)
         for index, reaction in enumerate(self.reactions):
             if str(reaction.emoji) == to_check:
@@ -660,7 +894,7 @@ def _clear_emoji(self, emoji):
         del self.reactions[index]
         return reaction
 
-    def _update(self, data):
+    def _update(self: Self, data: MessagePayload) -> Self:
         # In an update scheme, 'author' key has to be handled before 'member'
         # otherwise they overwrite each other which is undesirable.
         # Since there's no good way to do this we have to iterate over every
@@ -679,6 +913,7 @@ def _update(self, data):
                 delattr(self, attr)
             except AttributeError:
                 pass
+        return self
 
     def _handle_edited_timestamp(self, value):
         self._edited_timestamp = utils.parse_time(value)
@@ -687,7 +922,7 @@ def _handle_pinned(self, value):
         self.pinned = value
 
     def _handle_flags(self, value):
-        self.flags = MessageFlags._from_value(value)
+        self.flags: MessageFlags = MessageFlags._from_value(value)
 
     def _handle_application(self, value):
         self.application = value
@@ -696,7 +931,7 @@ def _handle_activity(self, value):
         self.activity = value
 
     def _handle_mention_everyone(self, value):
-        self.mention_everyone = value
+        self.mention_everyone: bool = value
 
     def _handle_tts(self, value):
         self.tts = value
@@ -705,13 +940,23 @@ def _handle_type(self, value):
         self.type = try_enum(MessageType, value)
 
     def _handle_content(self, value):
-        self.content = value
+        self.content: str = value
 
     def _handle_attachments(self, value):
-        self.attachments = [Attachment(data=a, state=self._state) for a in value]
+        self.attachments: List[Attachment] = [Attachment(data=a, state=self._state) for a in value]
 
     def _handle_embeds(self, value):
-        self.embeds = [Embed.from_dict(data) for data in value]
+        self.embeds: List[Embed] = [Embed.from_dict(data) for data in value]
+
+    def _handle_interaction(self, value):
+        self.interaction = MessageInteraction(state=self._state, data=value)
+
+    def _handle_thread(self, value):
+        thread = self.guild.get_channel(self.id)
+        if thread:
+            self._thread = thread._update(self.guild, value)
+        else:
+            self._thread = ThreadChannel(state=self._state, guild=self.guild, data=value)
 
     def _handle_components(self, value):
         self.components = [ActionRow.from_dict(data) for data in value]
@@ -766,26 +1011,6 @@ def _handle_mention_roles(self, role_mentions):
                 if role is not None:
                     self.role_mentions.append(role)
 
-    def _handle_call(self, call):
-        if call is None or self.type is not MessageType.call:
-            self.call = None
-            return
-
-        # we get the participant source from the mentions array or
-        # the author
-
-        participants = []
-        for uid in map(int, call.get('participants', [])):
-            if uid == self.author.id:
-                participants.append(self.author)
-            else:
-                user = utils.find(lambda u: u.id == uid, self.mentions)
-                if user is not None:
-                    participants.append(user)
-
-        call['participants'] = participants
-        self.call = CallMessage(message=self, **call)
-
     def _rebind_channel_reference(self, new_channel):
         self.channel = new_channel
 
@@ -793,14 +1018,9 @@ def _rebind_channel_reference(self, new_channel):
             del self._cs_guild
         except AttributeError:
             pass
-
-    @utils.cached_slot_property('_cs_guild')
-    def guild(self):
-        """Optional[:class:`Guild`]: The guild that the message belongs to, if applicable."""
-        return getattr(self.channel, 'guild', None)
-
+    
     @utils.cached_slot_property('_cs_raw_mentions')
-    def raw_mentions(self):
+    def raw_mentions(self) -> List[int]:
         """List[:class:`int`]: A property that returns an array of user IDs matched with
         the syntax of ``<@user_id>`` in the message content.
 
@@ -810,28 +1030,28 @@ def raw_mentions(self):
         return [int(x) for x in re.findall(r'<@!?([0-9]+)>', self.content)]
 
     @utils.cached_slot_property('_cs_raw_channel_mentions')
-    def raw_channel_mentions(self):
+    def raw_channel_mentions(self) -> List[int]:
         """List[:class:`int`]: A property that returns an array of channel IDs matched with
         the syntax of ``<#channel_id>`` in the message content.
         """
         return [int(x) for x in re.findall(r'<#([0-9]+)>', self.content)]
 
     @utils.cached_slot_property('_cs_raw_role_mentions')
-    def raw_role_mentions(self):
+    def raw_role_mentions(self) -> List[int]:
         """List[:class:`int`]: A property that returns an array of role IDs matched with
         the syntax of ``<@&role_id>`` in the message content.
         """
         return [int(x) for x in re.findall(r'<@&([0-9]+)>', self.content)]
 
     @utils.cached_slot_property('_cs_channel_mentions')
-    def channel_mentions(self):
+    def channel_mentions(self) -> List[MentionableChannel]:
         if self.guild is None:
             return []
         it = filter(None, map(self.guild.get_channel, self.raw_channel_mentions))
         return utils._unique(it)
 
     @utils.cached_slot_property('_cs_clean_content')
-    def clean_content(self):
+    def clean_content(self) -> str:
         """:class:`str`: A property that returns the content in a "cleaned up"
         manner. This basically means that mentions are transformed
         into the way the client shows it. e.g. ``<#id>`` will transform
@@ -881,22 +1101,22 @@ def repl(obj):
         return escape_mentions(result)
 
     @property
-    def created_at(self):
+    def created_at(self) -> datetime:
         """:class:`datetime.datetime`: The message's creation time in UTC."""
         return utils.snowflake_time(self.id)
 
     @property
-    def edited_at(self):
+    def edited_at(self) -> Optional[datetime]:
         """Optional[:class:`datetime.datetime`]: A naive UTC datetime object containing the edited time of the message."""
         return self._edited_timestamp
 
     @property
-    def jump_url(self):
+    def jump_url(self) -> str:
         """:class:`str`: Returns a URL that allows the client to jump to this message."""
         guild_id = getattr(self.guild, 'id', '@me')
         return 'https://discord.com/channels/{0}/{1.channel.id}/{1.id}'.format(guild_id, self)
 
-    def is_system(self):
+    def is_system(self) -> bool:
         """:class:`bool`: Whether the message is a system message.
 
         .. versionadded:: 1.3
@@ -904,32 +1124,40 @@ def is_system(self):
         return self.type is not MessageType.default
 
     @utils.cached_slot_property('_cs_system_content')
-    def system_content(self):
+    def system_content(self) -> str:
         r""":class:`str`: A property that returns the content that is rendered
         regardless of the :attr:`Message.type`.
 
         In the case of :attr:`MessageType.default`\, this just returns the
-        regular :attr:`Message.content`. Otherwise this returns an English
-        message denoting the contents of the system message.
+        regular :attr:`Message.content`.
+        Otherwise, this returns an English message denoting the contents of the system message.
         """
 
         if self.type is MessageType.default:
             return self.content
 
         if self.type is MessageType.pins_add:
-            return '{0.name} pinned a message to this channel.'.format(self.author)
+            return f'{self.author.display_name} pinned a message to this channel.'
 
         if self.type is MessageType.recipient_add:
-            return '{0.name} added {1.name} to the group.'.format(self.author, self.mentions[0])
+            return (
+                f'{self.author.display_name} added {self.mentions[0].display_name} to the '
+                f'{"thread" if self.guild else "group"}.'
+            )
 
         if self.type is MessageType.recipient_remove:
-            return '{0.name} removed {1.name} from the group.'.format(self.author, self.mentions[0])
+            return (
+                f'{self.author.display_name} removed {self.mentions[0].display_name} from the '
+                f'{"thread" if self.guild else "group"}.'
+            )
 
         if self.type is MessageType.channel_name_change:
-            return '{0.author.name} changed the channel name: {0.content}'.format(self)
+            if getattr(self.channel, "parent_channel", self.channel).type is ChannelType.forum_channel:
+                return f'{self.author.display_name} changed the post title: **{self.content}**'
+            return f'{self.author.display_name} changed the channel name: **{self.content}**'
 
         if self.type is MessageType.channel_icon_change:
-            return '{0.author.name} changed the channel icon.'.format(self)
+            return f'{self.author.display_name} changed the channel icon.'
 
         if self.type is MessageType.new_member:
             formats = [
@@ -951,7 +1179,7 @@ def system_content(self):
             # manually reconstruct the epoch with millisecond precision, because
             # datetime.datetime.timestamp() doesn't return the exact posix
             # timestamp with the precision that we need
-            created_at_ms = int((self.created_at - datetime.datetime(1970, 1, 1)).total_seconds() * 1000)
+            created_at_ms = int((self.created_at - datetime(1970, 1, 1)).total_seconds() * 1000)
             return formats[created_at_ms % len(formats)].format(self.author.name)
 
         if self.type is MessageType.call:
@@ -961,51 +1189,124 @@ def system_content(self):
             call_ended = self.call.ended_timestamp is not None
 
             if self.channel.me in self.call.participants:
-                return '{0.author.name} started a call.'.format(self)
+                return f'{self.author.display_name} started a call.'
             elif call_ended:
-                return 'You missed a call from {0.author.name}'.format(self)
+                return f'You missed a call from {self.author.display_name}'
             else:
-                return '{0.author.name} started a call \N{EM DASH} Join the call.'.format(self)
+                return f'{self.author.display_name} started a call \N{EM DASH} Join the call.'
 
         if self.type is MessageType.premium_guild_subscription:
-            return '{0.author.name} just boosted the server!'.format(self)
+            return f'{self.author.display_name} just boosted the server!'
 
         if self.type is MessageType.premium_guild_tier_1:
-            return '{0.author.name} just boosted the server! {0.guild} has achieved **Level 1!**'.format(self)
+            if self.content:
+                return (
+                    f'{self.author.display_name} just boosted the server **{self.content}** times! '
+                    f'{self.guild.name} has achieved **Level 1!**'
+                )
+            return f'{self.author.display_name} just boosted the server! {self.guild.name} has achieved **Level 1!**'
 
         if self.type is MessageType.premium_guild_tier_2:
-            return '{0.author.name} just boosted the server! {0.guild} has achieved **Level 2!**'.format(self)
+            if self.content:
+                return (
+                    f'{self.author.display_name} just boosted the server **{self.content}** times! '
+                    f'{self.guild.name} has achieved **Level 2!**'
+                )
+            return f'{self.author.display_name} just boosted the server! {self.guild.name} has achieved **Level 2!**'
 
         if self.type is MessageType.premium_guild_tier_3:
-            return '{0.author.name} just boosted the server! {0.guild} has achieved **Level 3!**'.format(self)
+            if self.content:
+                return (
+                    f'{self.author.display_name} just boosted the server **{self.content}** times! '
+                    f'{self.guild.name} has achieved **Level 3!**'
+                )
+            return f'{self.author.display_name} just boosted the server! {self.guild.name} has achieved **Level 3!**'
 
         if self.type is MessageType.channel_follow_add:
-            return '{0.author.name} has added {0.content} to this channel'.format(self)
+            return f'{self.author.display_name} has added {self.content} to this channel'
 
         if self.type is MessageType.guild_stream:
-            return '{0.author.name} is live! Now streaming {0.author.activity.name}'.format(self)
+            return f'{self.author.display_name} is live! Now streaming {self.author.activity.name}'
 
         if self.type is MessageType.guild_discovery_disqualified:
-            return 'This server has been removed from Server Discovery because it no longer passes all the requirements. Check Server Settings for more details.'
+            return (
+                'This server has been removed from Server Discovery because it no longer passes all the requirements. '
+                'Check Server Settings for more details.'
+            )
 
         if self.type is MessageType.guild_discovery_requalified:
             return 'This server is eligible for Server Discovery again and has been automatically relisted!'
 
         if self.type is MessageType.guild_discovery_grace_period_initial_warning:
-            return 'This server has failed Discovery activity requirements for 1 week. If this server fails for 4 weeks in a row, it will be automatically removed from Discovery.'
+            return (
+                'This server has failed Discovery activity requirements for 1 week. '
+                'If this server fails for 4 weeks in a row, it will be automatically removed from Discovery.'
+            )
 
         if self.type is MessageType.guild_discovery_grace_period_final_warning:
-            return 'This server has failed Discovery activity requirements for 3 weeks in a row. If this server fails for 1 more week, it will be removed from Discovery.'
+            return (
+                'This server has failed Discovery activity requirements for 3 weeks in a row. '
+                'If this server fails for 1 more week, it will be removed from Discovery.'
+            )
+
+        if self.type is MessageType.thread_created:
+            return f'{self.author.display_name} started a thread: **{self.content}**. See all **threads**.'
+
+        if self.type is MessageType.reply:
+            return self.content
+
+        if self.type is MessageType.thread_starter_message:
+            if self.reference is None or self.reference.resolved is None:
+                return 'Sorry, we couldn\'t load the first message in this thread'
+
+            return self.reference.resolved.content
+
+        if self.type is MessageType.guild_invite_reminder:
+            return 'Wondering who to invite?\nStart by inviting anyone who can help you build the server!'
+
+        if self.type is MessageType.premium_guild_subscription and self.role_subscription is not None:
+            role_subscription = self.role_subscription
+            total_months = role_subscription.total_months_subscribed
+            months = '1 month' if total_months == 1 else f'{total_months} months'
+            if role_subscription.is_renewal:
+                return (
+                    f'{self.author.display_name} renewed **{role_subscription.tier_name}** '
+                    f'and has been a subscriber of {self.guild.name} for {months}!'
+                )
+            return (
+                f'{self.author.display_name} joined **{role_subscription.tier_name}** '
+                f'and has been a subscriber of {self.guild.name}  for {months}!'
+            )
+
+        if self.type is MessageType.stage_start:
+            return f'{self.author.display_name} started **{self.content}**.'
+
+        if self.type is MessageType.stage_end:
+            return f'{self.author.display_name} ended **{self.content}**.'
+
+        if self.type is MessageType.stage_speaker_change:
+            return f'{self.author.display_name} is now a speaker.'
+
+        if self.type is MessageType.stage_raise_hand:
+            return f'{self.author.display_name} requested to speak.'
+
+        if self.type is MessageType.stage_topic_change:
+            return f'{self.author.display_name} changed Stage topic: **{self.content}**.'
+
+        return ''
+
+        # TODO: Add missing system message types
 
     @property
-    def all_components(self):
-        """Returns all :class:`Button`'s and :class:`SelectMenu`'s that are contained in the message"""
+    def all_components(self) -> Iterator[Union[Button, Select]]:
+        """Returns all :class:`Button`'s and :ref:`Select <select-like-objects>` like objects
+        that are contained in the message"""
         for action_row in self.components:
             for component in action_row:
                 yield component
 
     @property
-    def all_buttons(self):
+    def all_buttons(self) -> Iterator[Button]:
         """Returns all :class:`Button`'s that are contained in the message"""
         for action_row in self.components:
             for component in action_row:
@@ -1013,19 +1314,24 @@ def all_buttons(self):
                     yield component
 
     @property
-    def all_select_menus(self):
-        """Returns all :class:`SelectMenu`'s that are contained in the message"""
+    def all_select_menus(self) -> Iterator[Select]:
+        """Returns all :ref:`Select <select-like-objects>` like objects that are contained in the message"""
         for action_row in self.components:
             for component in action_row:
-                if isinstance(component, SelectMenu):
+                if int(component.type) in {3, 5, 6, 7, 8}:
                     yield component
 
-    async def delete(self, *, delay=None):
+    @property
+    def thread(self) -> Optional[ThreadChannel]:
+        """Optional[:class:`ThreadChannel`]: The thread that belongs to this message, if there is one"""
+        return getattr(self, '_thread', None)
+
+    async def delete(self, *, delay: Optional[float] = None, reason: Optional[str] = None):
         """|coro|
 
         Deletes the message.
 
-        Your own messages could be deleted without any proper permissions. However to
+        Your own messages could be deleted without any proper permissions. However, to
         delete other people's messages, you need the :attr:`~Permissions.manage_messages`
         permission.
 
@@ -1037,6 +1343,8 @@ async def delete(self, *, delay=None):
         delay: Optional[:class:`float`]
             If provided, the number of seconds to wait in the background
             before deleting the message. If the deletion fails then it is silently ignored.
+        reason: Optional[:class:`str`]
+            The reason for deleting this message. Shows up on the audit log.
 
         Raises
         ------
@@ -1051,7 +1359,7 @@ async def delete(self, *, delay=None):
             async def delete():
                 await asyncio.sleep(delay)
                 try:
-                    await self._state.http.delete_message(self.channel.id, self.id)
+                    await self._state.http.delete_message(self.channel.id, self.id, reason=reason)
                 except HTTPException:
                     pass
 
@@ -1059,15 +1367,35 @@ async def delete():
         else:
             await self._state.http.delete_message(self.channel.id, self.id)
 
-    async def edit(self, **fields):
+    async def edit(
+            self,
+            *,
+            content: Any = MISSING,
+            embed: Optional[Embed] = MISSING,
+            embeds: Sequence[Embed] = MISSING,
+            components: List[Union[ActionRow, List[Union[Button, Select]]]] = MISSING,
+            attachments: Sequence[Union[Attachment, File]] = MISSING,
+            keep_existing_attachments: bool = False,
+            delete_after: Optional[float] = None,
+            allowed_mentions: Optional[AllowedMentions] = MISSING,
+            suppress_embeds: Optional[bool] = MISSING
+    ) -> Message:
         """|coro|
 
         Edits the message.
 
         The content must be able to be transformed into a string via ``str(content)``.
-
+        
+        .. warning::
+            Since API v10, the ``attachments`` **must contain all attachments** that should be present after edit,
+            **including retained** and new attachments.
+        
         .. versionchanged:: 1.3
             The ``suppress`` keyword-only parameter was added.
+        .. versionchanged:: 2.0
+            The ``suppress`` keyword-only parameter was renamed to ``suppress_embeds``.
+        .. versionchanged:: 2.0
+            The ``components`, ``attachments`` and ``keep_existing_attachments`` keyword-only parameters were added.
 
         Parameters
         -----------
@@ -1076,16 +1404,34 @@ async def edit(self, **fields):
             Could be ``None`` to remove the content.
         embed: Optional[:class:`Embed`]
             The new embed to replace the original with.
-            Could be ``None`` to remove the embed.
+            Could be ``None`` to remove all embeds.
         embeds: Optional[List[:class:`Embed`]]
-            A list containing up to 10 embeds
-        components: List[Union[:class:`discord.ActionRow`, List]]
-            A list of :class:`discord.ActionRow`'s or a Lists with :class:`Button`'s or :class:`SelectMenu`.
-        suppress: :class:`bool`
+            A list containing up to 10 embeds to send.
+            If ``None`` or empty, all embeds will be removed.
+            
+            If passed, ``embed`` does also count towards the limit of 10 embeds.
+        components: List[Union[:class:`~discord.ActionRow`, List[Union[:class:`~discord.Button`, :ref:`Select <select-like-objects>`]]]]
+            A list of up to five :class:`~discord.ActionRow`s or :class:`list`,
+            each containing up to five :class:`~discord.Button` or one :ref:`Select <select-like-objects>` like object.
+        attachments: List[Union[:class:`Attachment`, :class:`File`]]
+            A list containing previous attachments to keep as well as new files to upload.
+            You can use ``keep_existing_attachments`` to auto-add the existing attachments to the list.
+            If ``None`` or empty, all attachments will be removed.
+            
+            .. note::
+                
+                New files will always appear under existing ones.
+        keep_existing_attachments: :class:`bool`
+            Whether to auto-add existing attachments to ``attachments``, defaults to :obj:`False`.
+
+            .. note::
+
+                Only needed when ``attachments`` are passed, otherwise will be ignored.
+        suppress_embeds: :class:`bool`
             Whether to suppress embeds for the message. This removes
             all the embeds if set to ``True``. If set to ``False``
             this brings the embeds back if they were suppressed.
-            Using this parameter requires :attr:`~.Permissions.manage_messages`.
+            Requires :attr:`~.Permissions.manage_messages` permissions for messages that aren't from the bot.
         delete_after: Optional[:class:`float`]
             If provided, the number of seconds to wait in the background
             before deleting the message we just edited. If the deletion fails,
@@ -1109,110 +1455,42 @@ async def edit(self, **fields):
             edited a message's content or embed that isn't yours.
         """
 
-        try:
-            content = fields['content']
-        except KeyError:
-            pass
-        else:
-            if content is not None:
-                fields['content'] = str(content)
-        raw_embeds = []
-
-        try:
-            embed = fields.pop('embed')
-        except KeyError:
-            pass
-        else:
-            if embed is not None:
-                raw_embeds.append(embed.to_dict())
-
-        try:
-            embeds = fields.pop('embeds')
-        except KeyError:
-            pass
+        if content is not MISSING:
+            previous_allowed_mentions = self._state.allowed_mentions
         else:
-            if embeds is not None:
-                raw_embeds.extend([e.to_dict() for e in embeds])
-        
-        if raw_embeds:
-            fields['embeds'] = raw_embeds
+            previous_allowed_mentions = None
 
-        try:
-            components = fields['components']
-        except KeyError:
-            pass
-        else:
-            if components is not None:
-                _components = []
-                for component in (list(components) if not isinstance(components, list) else components):
-                    if isinstance(component, (Button, SelectMenu)):
-                        _components.extend(ActionRow(component).to_dict())
-                    elif isinstance(component, ActionRow):
-                        _components.extend(component.to_dict())
-                    elif isinstance(component, list):
-                        _components.extend(ActionRow(*[obj for obj in component if isinstance(obj, (Button, SelectMenu))]).to_dict())
-                fields['components'] = _components
+        if keep_existing_attachments and attachments is not MISSING:
+            attachments = [*self.attachments, *attachments]
 
-        try:
-            suppress = fields.pop('suppress')
-        except KeyError:
-            pass
-        else:
+        if suppress_embeds is not MISSING:
             flags = MessageFlags._from_value(self.flags.value)
-            flags.suppress_embeds = suppress
-            fields['flags'] = flags.value
-
-        delete_after = fields.pop('delete_after', None)
-
-        try:
-            allowed_mentions = fields.pop('allowed_mentions')
-        except KeyError:
-            pass
+            flags.suppress_embeds = suppress_embeds
         else:
-            if allowed_mentions is not None:
-                if self._state.allowed_mentions is not None:
-                    allowed_mentions = self._state.allowed_mentions.merge(allowed_mentions).to_dict()
-                else:
-                    allowed_mentions = allowed_mentions.to_dict()
-                fields['allowed_mentions'] = allowed_mentions
-
-        is_interaction_response = fields.pop('__is_interaction_response', None)
-        if is_interaction_response is True:
-            deferred = fields.pop('__deferred', False)
-            use_webhook = fields.pop('__use_webhook', False)
-            interaction_id = fields.pop('__interaction_id', None)
-            interaction_token = fields.pop('__interaction_token', None)
-            application_id = fields.pop('__application_id', None)
-            files = fields.pop('files', fields.pop('file', None))
-            if files and not isinstance(files, list):
-                files = [files]
-            if fields:
-                try:
-                    payload = await self._state.http.edit_interaction_response(use_webhook=use_webhook,
-                                                                            interaction_id=interaction_id,
-                                                                            token=interaction_token,
-                                                                            application_id=application_id,
-                                                                            deferred=deferred, files=files, **fields)
-                except NotFound:
-                    is_interaction_response = None
-                else:
-                    if payload:
-                        self._update(payload)
-                    else:
-                        [self.__setattr__(k, v) for k, v in fields.items()]
-
-        if is_interaction_response is None:
-            payload = await self._state.http.edit_message(self.channel.id, self.id, **fields)
-            self._update(payload)
+            flags = MISSING
+
+        with handle_message_parameters(
+                content=content,
+                flags=flags,
+                embed=embed if embed is not None else MISSING,
+                embeds=embeds if embeds is not None else MISSING,
+                attachments=attachments,
+                components=components,
+                allowed_mentions=allowed_mentions,
+                previous_allowed_mentions=previous_allowed_mentions
+        ) as params:
+            data = await self._state.http.edit_message(self.channel.id, self.id, params=params)
+        self._update(data)
 
         if delete_after is not None:
             await self.delete(delay=delete_after)
+        return self
 
     @property
     def dict(self):
         return {s: self.__getattribute__(s) for s in self.__slots__ if not s.startswith('_')}
 
-    async def publish(self):
+    async def publish(self) -> None:
         """|coro|
 
         Publishes this message to your announcement channel.
@@ -1230,7 +1508,7 @@ async def publish(self):
 
         await self._state.http.publish_message(self.channel.id, self.id)
 
-    async def pin(self, *, reason=None):
+    async def pin(self, *, suppress_system_message: bool = False, reason: Optional[str] = None) -> None:
         """|coro|
 
         Pins the message.
@@ -1240,6 +1518,10 @@ async def pin(self, *, reason=None):
 
         Parameters
         -----------
+        suppress_system_message: :class:`bool`
+            When set to ``True``, the function will wait 5 seconds for the system message and delete it. Defaults to ``False``.
+
+            .. versionadded:: 2.0
         reason: Optional[:class:`str`]
             The reason for pinning the message. Shows up on the audit log.
 
@@ -1254,12 +1536,27 @@ async def pin(self, *, reason=None):
         HTTPException
             Pinning the message failed, probably due to the channel
             having more than 50 pinned messages.
+        :exc:`~asyncio.TimeoutError`
+            Waiting for the system message timed out.
         """
 
         await self._state.http.pin_message(self.channel.id, self.id, reason=reason)
         self.pinned = True
 
-    async def unpin(self, *, reason=None):
+        # TODO: we don't get a message create for this...
+        if suppress_system_message:
+            try:
+                msg = await self._state._get_client().wait_for(
+                    'message',
+                    check=lambda m: m.type is MessageType.pins_add and m.channel == self.channel,
+                    timeout=5.0
+                )
+            except asyncio.TimeoutError as exc:
+                raise asyncio.TimeoutError('Timed out waiting for the system message to suppress.') from exc
+            else:
+                await msg.delete(reason='Suppressing system message for pinned message')
+
+    async def unpin(self, *, reason: Optional[str] = None) -> None:
         """|coro|
 
         Unpins the message.
@@ -1287,7 +1584,7 @@ async def unpin(self, *, reason=None):
         await self._state.http.unpin_message(self.channel.id, self.id, reason=reason)
         self.pinned = False
 
-    async def add_reaction(self, emoji):
+    async def add_reaction(self, emoji: Union[Emoji, Reaction, PartialEmoji, str]) -> None:
         """|coro|
 
         Add a reaction to the message.
@@ -1318,7 +1615,7 @@ async def add_reaction(self, emoji):
         emoji = convert_emoji_reaction(emoji)
         await self._state.http.add_reaction(self.channel.id, self.id, emoji)
 
-    async def remove_reaction(self, emoji, member):
+    async def remove_reaction(self, emoji: Union[Emoji, Reaction, PartialEmoji, str], member: Snowflake) -> None:
         """|coro|
 
         Remove a reaction by the member from the message.
@@ -1357,7 +1654,7 @@ async def remove_reaction(self, emoji, member):
         else:
             await self._state.http.remove_reaction(self.channel.id, self.id, emoji, member.id)
 
-    async def clear_reaction(self, emoji):
+    async def clear_reaction(self, emoji: Union[Emoji, Reaction, PartialEmoji, str]) -> None:
         """|coro|
 
         Clears a specific reaction from the message.
@@ -1388,7 +1685,7 @@ async def clear_reaction(self, emoji):
         emoji = convert_emoji_reaction(emoji)
         await self._state.http.clear_single_reaction(self.channel.id, self.id, emoji)
 
-    async def clear_reactions(self):
+    async def clear_reactions(self) -> None:
         """|coro|
 
         Removes all the reactions from the message.
@@ -1404,30 +1701,23 @@ async def clear_reactions(self):
         """
         await self._state.http.clear_reactions(self.channel.id, self.id)
 
-    @utils.deprecated()
-    async def ack(self):
-        """|coro|
-
-        Marks this message as read.
-
-        The user must not be a bot user.
-
-        .. deprecated:: 1.7
-
-        Raises
-        -------
-        HTTPException
-            Acking failed.
-        ClientException
-            You must not be a bot user.
-        """
-
-        state = self._state
-        if state.is_bot:
-            raise ClientException('Must not be a bot account to ack messages.')
-        return await state.http.ack_message(self.channel.id, self.id)
-
-    async def reply(self, content=None, **kwargs):
+    async def reply(
+            self,
+            content: utils.SupportsStr = None,
+            tts: bool = False,
+            embed: Optional[Embed] = None,
+            embeds: Optional[List[Embed]] = None,
+            components: Optional[List[Union[ActionRow, List[Union[Button, Select]]]]] = None,
+            file: Optional[File] = None,
+            files: Optional[List[File]] = None,
+            stickers: Optional[List[GuildSticker]] = None,
+            delete_after: Optional[float] = None,
+            nonce: Optional[int] = None,
+            allowed_mentions: Optional[AllowedMentions] = None,
+            mention_author: Optional[bool] = None,
+            suppress_embeds: bool = False,
+            suppress_notifications: bool = False
+    ) -> Message:
         """|coro|
 
         A shortcut method to :meth:`.abc.Messageable.send` to reply to the
@@ -1451,9 +1741,95 @@ async def reply(self, content=None, **kwargs):
             The message that was sent.
         """
 
-        return await self.channel.send(content, reference=self, **kwargs)
+        return await self.channel.send(
+            content,
+            reference=self,
+            tts=tts,
+            embed=embed,
+            embeds=embeds,
+            components=components,
+            file=file,
+            files=files,
+            stickers=stickers,
+            delete_after=delete_after,
+            nonce=nonce,
+            allowed_mentions=allowed_mentions,
+            mention_author=mention_author,
+            suppress_embeds=suppress_embeds,
+            suppress_notifications=suppress_notifications
+        )
+
+    async def create_thread(
+            self,
+            name: str,
+            auto_archive_duration: Optional[AutoArchiveDuration] = None,
+            slowmode_delay: int = 0,
+            reason: Optional[str] = None
+    ) -> ThreadChannel:
+        """|coro|
+
+        Creates a new thread in the channel of the message with this message as the :attr:`~ThreadChannel.starter_message`.
+
+        Parameters
+        ----------
+        name: :class:`str`
+            The name of the thread.
+        auto_archive_duration: Optional[:class:`AutoArchiveDuration`]
+            Amount of time after that the thread will auto-hide from the channel list
+        slowmode_delay: :class:`int`
+            Amount of seconds a user has to wait before sending another message (0-21600)
+        reason: Optional[:class:`str`]
+            The reason for creating the thread. Shows up in the audit log.
+
+        Raises
+        ------
+        :exc:`TypeError`
+            The channel of the message is not a text or news channel,
+            or the message has already a thread,
+            or ``auto_archive_duration`` is not a valid member of :class:`AutoArchiveDuration`
+        :exc:`ValueError`
+            The ``name`` is of invalid length
+        :exc:`Forbidden`
+            The bot is missing permissions to create threads in this channel
+        :exc:`HTTPException`
+            Creating the thread failed
+
+        Returns
+        -------
+        :class:`ThreadChannel`
+            The created thread on success
+        """
+        if self.channel.type not in (ChannelType.text, ChannelType.news):
+            raise TypeError('You could not create a thread inside a %s.' % self.channel.__class__.__name__)
+        if self.thread:
+            raise TypeError('There is already a thread associated with this message')
+
+        if len(name) > 100 or len(name) < 1:
+            raise ValueError('The name of the thread must bee between 1-100 characters; got %s' % len(name))
+
+        payload = {
+            'name': name
+        }
 
-    def to_reference(self, *, fail_if_not_exists=True):
+        if auto_archive_duration:
+            auto_archive_duration = try_enum(
+                AutoArchiveDuration, auto_archive_duration
+            )  # for the case someone pass a number
+            if not isinstance(auto_archive_duration, AutoArchiveDuration):
+                raise TypeError(
+                    f'auto_archive_duration must be a member of discord.AutoArchiveDuration, not {auto_archive_duration.__class__.__name__!r}'
+                )
+            payload['auto_archive_duration'] = auto_archive_duration.value
+
+        if slowmode_delay:
+            payload['rate_limit_per_user'] = slowmode_delay
+
+        data = await self._state.http.create_thread(self.channel.id, message_id=self.id, payload=payload, reason=reason)
+        thread = ThreadChannel(state=self._state, guild=self.guild, data=data)
+        self.guild._add_channel(thread)
+        return thread
+
+    def to_reference(self, *, fail_if_not_exists: bool = True):
         """Creates a :class:`~discord.MessageReference` from the current message.
 
         .. versionadded:: 1.6
@@ -1474,7 +1850,7 @@ def to_reference(self, *, fail_if_not_exists=True):
 
         return MessageReference.from_message(self, fail_if_not_exists=fail_if_not_exists)
 
-    def to_message_reference_dict(self):
+    def to_message_reference_dict(self) -> MessageReferenceData:
         data = {
             'message_id': self.id,
             'channel_id': self.channel.id,
@@ -1495,7 +1871,7 @@ def implement_partial_methods(cls):
 
 
 @implement_partial_methods
-class PartialMessage(Hashable):
+class PartialMessage(Hashable, Generic[_MCH]):
 
     """Represents a partial message to aid with working messages when only
     a message and channel ID are present.
@@ -1524,13 +1900,15 @@ class PartialMessage(Hashable):
 
     Attributes
     -----------
-    channel: Union[:class:`TextChannel`, :class:`DMChannel`]
+    channel: Union[:class:`TextChannel`, :class:`~discord.ThreadChannel`, :class:`DMChannel`]
         The channel associated with this partial message.
     id: :class:`int`
         The message ID.
+    guild: Optional[:class:`Guild`]
+        The guild associated with this partial message, if applicable.
     """
 
-    __slots__ = ('channel', 'id', '_cs_guild', '_state')
+    __slots__ = ('channel', 'id', 'guild', '_state')
 
     _exported_names = (
         'jump_url',
@@ -1543,17 +1921,59 @@ class PartialMessage(Hashable):
         'clear_reaction',
         'clear_reactions',
         'reply',
+        'create_thread',
         'to_reference',
         'to_message_reference_dict',
     )
 
-    def __init__(self, *, channel, id):
-        if channel.type not in (ChannelType.text, ChannelType.news, ChannelType.private):
-            raise TypeError('Expected TextChannel or DMChannel not %r' % type(channel))
-
-        self.channel = channel
-        self._state = channel._state
-        self.id = id
+    if TYPE_CHECKING:
+        # Take over the methods from Message that are in _exported_names, so we got the correct type hints.
+
+        def jump_url(self) -> str: ...
+        async def delete(self, *, delay: Optional[float] = None, reason: Optional[str] = None) -> None: ...
+        async def publish(self) -> None: ...
+        async def pin(self, *, reason: Optional[str] = None) -> None: ...
+        async def unpin(self, *, reason: Optional[str] = None) -> None: ...
+        async def add_reaction(self, emoji: Union[Emoji, Reaction, str]) -> None: ...
+        async def remove_reaction(self, emoji: Union[Emoji, Reaction, str], member: Optional[Member] = None) -> None: ...
+        async def clear_reaction(self, emoji: Union[Emoji, Reaction, str]) -> None: ...
+        async def clear_reactions(self) -> None: ...
+        async def reply(
+                self,
+                content: utils.SupportsStr = None,
+                tts: bool = False,
+                embed: Optional[Embed] = None,
+                embeds: Optional[List[Embed]] = None,
+                components: Optional[List[Union[ActionRow, List[Union[Button, Select]]]]] = None,
+                file: Optional[File] = None,
+                files: Optional[List[File]] = None,
+                stickers: Optional[List[GuildSticker]] = None,
+                delete_after: Optional[float] = None,
+                nonce: Optional[int] = None,
+                allowed_mentions: Optional[AllowedMentions] = None,
+                mention_author: Optional[bool] = None,
+                suppress_embeds: bool = False,
+                suppress_notifications: bool = False
+        ) -> Message: ...
+        async def create_thread(
+                self,
+                name: str,
+                *,
+                auto_archive_duration: Optional[Union[AutoArchiveDuration, int]] = None,
+                slowmode_delay: Optional[int] = None,
+                reason: Optional[str] = None
+        ) -> ThreadChannel: ...
+        def to_reference(self, *, fail_if_not_exists: bool = True) -> MessageReference: ...
+        def to_message_reference_dict(self) -> MessageReference: ...
+
+    def __init__(self, *, channel: _MCH, id: int) -> None:
+        if not isinstance(channel, PartialMessageable) and int(channel.type) not in {0, 1, 2, 3, 5, 10, 11, 12, 15}:
+            raise TypeError('Expected TextChannel, VoiceChannel, ThreadChannel or DMChannel not %r' % type(channel))
+
+        self.channel: _MCH = channel
+        self._state: ConnectionState = channel._state
+        self.id: int = id
+        self.guild: Optional[Guild] = getattr(channel, 'guild', None)
 
     def _update(self, data):
         # This is used for duck typing purposes.
@@ -1564,20 +1984,15 @@ def _update(self, data):
     # n.b. not exposed
     pinned = property(None, lambda x, y: ...)
 
-    def __repr__(self):
+    def __repr__(self) -> str:
         return '<PartialMessage id={0.id} channel={0.channel!r}>'.format(self)
 
     @property
-    def created_at(self):
+    def created_at(self) -> datetime:
         """:class:`datetime.datetime`: The partial message's creation time in UTC."""
         return utils.snowflake_time(self.id)
-
-    @utils.cached_slot_property('_cs_guild')
-    def guild(self):
-        """Optional[:class:`Guild`]: The guild that the partial message belongs to, if applicable."""
-        return getattr(self.channel, 'guild', None)
-
-    async def fetch(self):
+    
+    async def fetch(self) -> Message:
         """|coro|
 
         Fetches the partial message to a full :class:`Message`.
@@ -1600,39 +2015,38 @@ async def fetch(self):
         data = await self._state.http.get_message(self.channel.id, self.id)
         return self._state.create_message(channel=self.channel, data=data)
 
-    @property
-    def all_components(self):
-        """Returns all :class:`Button`'s and :class:`SelectMenu`'s that are contained in the message"""
-        for action_row in self.components:
-            for component in action_row:
-                yield component
-
-    @property
-    def all_buttons(self):
-        """Returns all :class:`Button`'s that are contained in the message"""
-        for action_row in self.components:
-            for component in action_row:
-                if isinstance(component, Button):
-                    yield component
-
-    @property
-    def all_select_menus(self):
-        """Returns all :class:`SelectMenu`'s that are contained in the message"""
-        for action_row in self.components:
-            for component in action_row:
-                if isinstance(component, SelectMenu):
-                    yield component
-
-    async def edit(self, **fields):
+    async def edit(
+            self,
+            *,
+            content: Any = MISSING,
+            embed: Optional[Embed] = MISSING,
+            embeds: Sequence[Embed] = MISSING,
+            components: List[Union[ActionRow, List[Union[Button, Select]]]] = MISSING,
+            attachments: Sequence[Union[Attachment, File]] = MISSING,
+            delete_after: Optional[float] = None,
+            allowed_mentions: Optional[AllowedMentions] = MISSING,
+            suppress_embeds: bool = MISSING
+    ) -> Optional[Message]:
         """|coro|
 
         Edits the message.
 
         The content must be able to be transformed into a string via ``str(content)``.
 
-        .. versionchanged:: 1.7
-            :class:`discord.Message` is returned instead of ``None`` if an edit took place.
-
+        .. versionchanged:: 1.3
+            The ``suppress`` keyword-only parameter was added.
+        .. versionchanged:: 2.0
+            The ``components`` and ``attachments`` parameters were added.
+        .. versionchanged:: 2.0
+            The ``suppress`` keyword-only parameter was renamed to ``suppress_embeds``.
+        
+        .. warning::
+            Since API v10, the ``attachments`` (when passed) **must contain all attachments** that should be present after edit,
+            **including retained** and new attachments.
+            
+            As this requires to know the current attachments consider either storing the attachments that were sent with a message or
+            using a fetched version of the message to edit it.
+        
         Parameters
         -----------
         content: Optional[:class:`str`]
@@ -1640,16 +2054,28 @@ async def edit(self, **fields):
             Could be ``None`` to remove the content.
         embed: Optional[:class:`Embed`]
             The new embed to replace the original with.
-            Could be ``None`` to remove the embed.
+            Could be ``None`` to remove all embeds.
         embeds: Optional[List[:class:`Embed`]]
-            A list containing up to 10 embeds
-        components: List[Union[:class:`discord.ActionRow`, List]]
-            A list of :class:`discord.ActionRow`'s or a Lists with :class:`Button`'s or :class:`SelectMenu`.
-        suppress: :class:`bool`
+            A list containing up to 10 embeds to send.
+            If ``None`` or empty, all embeds will be removed.
+            
+            If passed, ``embed`` does also count towards the limit of 10 embeds.
+        components: List[Union[:class:`~discord.ActionRow`, List[Union[:class:`~discord.Button`, :ref:`Select <select-like-objects>`]]]]
+            A list of up to five :class:`~discord.ActionRow`s or :class:`list`,
+            each containing up to five :class:`~discord.Button` or one :ref:`Select <select-like-objects>` like object.
+        attachments: List[Union[:class:`Attachment`, :class:`File`]]
+            A list containing previous attachments to keep as well as new files to upload.
+            
+            When  ``None`` or empty, all attachment will be removed.
+
+            .. note::
+
+                New files will always appear under existing ones.
+        suppress_embeds: :class:`bool`
             Whether to suppress embeds for the message. This removes
             all the embeds if set to ``True``. If set to ``False``
             this brings the embeds back if they were suppressed.
-            Using this parameter requires :attr:`~.Permissions.manage_messages`.
+            Requires :attr:`~.Permissions.manage_messages` for messages that aren't from the bot.
         delete_after: Optional[:class:`float`]
             If provided, the number of seconds to wait in the background
             before deleting the message we just edited. If the deletion fails,
@@ -1669,7 +2095,7 @@ async def edit(self, **fields):
         HTTPException
             Editing the message failed.
         Forbidden
-            Tried to suppress a message without permissions or
+            Tried to suppress the embeds a message without permissions or
             edited a message's content or embed that isn't yours.
 
         Returns
@@ -1678,104 +2104,31 @@ async def edit(self, **fields):
             The message that was edited.
         """
 
-        try:
-            content = fields['content']
-        except KeyError:
-            pass
-        else:
-            if content is not None:
-                fields['content'] = str(content)
-
-        raw_embeds = []
-
-        try:
-            embed = fields.pop('embed')
-        except KeyError:
-            pass
-        else:
-            if embed is not None:
-                raw_embeds.append(embed.to_dict())
-
-        try:
-            embeds = fields.pop('embeds')
-        except KeyError:
-            pass
-        else:
-            if embeds is not None:
-                raw_embeds.extend([e.to_dict() for e in embeds])
-        
-        if raw_embeds:
-            fields['embeds'] = raw_embeds
-            
-        try:
-            components = fields['components']
-        except KeyError:
-            pass
+        if content is not MISSING:
+            previous_allowed_mentions = self._state.allowed_mentions
         else:
-            if components is not None:
-                _components = []
-                for component in (list(components) if not isinstance(components, list) else components):
-                    if isinstance(component, (Button, SelectMenu)):
-                        _components.extend(ActionRow(component).to_dict())
-                    elif isinstance(component, ActionRow):
-                        _components.extend(component.to_dict())
-                    elif isinstance(component, list):
-                        _components.extend(ActionRow(*[obj for obj in component if isinstance(obj, (Button, SelectMenu))]).to_dict())
-                fields['components'] = _components
+            previous_allowed_mentions = None
 
-        try:
-            suppress = fields.pop('suppress')
-        except KeyError:
-            pass
-        else:
+        if suppress_embeds is not MISSING:
             flags = MessageFlags._from_value(0)
-            flags.suppress_embeds = suppress
-            fields['flags'] = flags.value
-
-        delete_after = fields.pop('delete_after', None)
-
-        try:
-            allowed_mentions = fields.pop('allowed_mentions')
-        except KeyError:
-            pass
+            flags.suppress_embeds = suppress_embeds
         else:
-            if allowed_mentions is not None:
-                if self._state.allowed_mentions is not None:
-                    allowed_mentions = self._state.allowed_mentions.merge(allowed_mentions).to_dict()
-                else:
-                    allowed_mentions = allowed_mentions.to_dict()
-                fields['allowed_mentions'] = allowed_mentions
-
-        is_interaction_response = fields.pop('__is_interaction_response', None)
-        if is_interaction_response is True:
-            deferred = fields.pop('__deferred', False)
-            use_webhook = fields.pop('__use_webhook', False)
-            interaction_id = fields.pop('__interaction_id', None)
-            interaction_token = fields.pop('__interaction_token', None)
-            application_id = fields.pop('__application_id', None)
-            files = fields.pop('files', fields.pop('file', None))
-            if files and not isinstance(files, list):
-                files = [files]
-            if fields:
-                try:
-                    payload = await self._state.http.edit_interaction_response(use_webhook=use_webhook,
-                                                                               interaction_id=interaction_id,
-                                                                               token=interaction_token,
-                                                                               application_id=application_id,
-                                                                               deferred=deferred, files=files, **fields)
-                except NotFound:
-                    is_interaction_response = None
-                else:
-                    if payload:
-                        self._update(payload)
-                    else:
-                        [self.__setattr__(k, v) for k, v in fields.items()]
-
-        if is_interaction_response is None:
-            payload = await self._state.http.edit_message(self.channel.id, self.id, **fields)
-            self._update(payload)
+            flags = MISSING
+
+        with handle_message_parameters(
+                content=content,
+                flags=flags,
+                embed=embed if embed is not None else MISSING,
+                embeds=embeds if embeds is not None else MISSING,
+                attachments=attachments,
+                components=components,
+                allowed_mentions=allowed_mentions,
+                previous_allowed_mentions=previous_allowed_mentions
+        ) as params:
+            data = await self._state.http.edit_message(self.channel.id, self.id, params=params)
 
         if delete_after is not None:
             await self.delete(delay=delete_after)
 
-        return self._state.create_message(channel=self.channel, data=payload)
+        if data is not None:
+            return self._state.create_message(channel=self.channel, data=data)
diff --git a/discord/mixins.py b/discord/mixins.py
index afdbc1d0..26842e3b 100644
--- a/discord/mixins.py
+++ b/discord/mixins.py
@@ -24,6 +24,7 @@
 DEALINGS IN THE SOFTWARE.
 """
 
+
 class EqualityComparable:
     __slots__ = ()
 
@@ -35,6 +36,7 @@ def __ne__(self, other):
             return other.id != self.id
         return True
 
+
 class Hashable(EqualityComparable):
     __slots__ = ()
 
diff --git a/discord/monetization.py b/discord/monetization.py
new file mode 100644
index 00000000..d6e04b59
--- /dev/null
+++ b/discord/monetization.py
@@ -0,0 +1,231 @@
+#  The MIT License (MIT)
+#
+#  Copyright (c) 2021-present mccoderpy
+#
+#  Permission is hereby granted, free of charge, to any person obtaining a
+#  copy of this software and associated documentation files (the "Software"),
+#  to deal in the Software without restriction, including without limitation
+#  the rights to use, copy, modify, merge, publish, distribute, sublicense,
+#  and/or sell copies of the Software, and to permit persons to whom the
+#  Software is furnished to do so, subject to the following conditions:
+#
+#  The above copyright notice and this permission notice shall be included in
+#  all copies or substantial portions of the Software.
+#
+#  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+#  OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+#  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+#  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+#  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+#  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+#  DEALINGS IN THE SOFTWARE.
+
+#  The MIT License (MIT)
+#
+#
+#  Permission is hereby granted, free of charge, to any person obtaining a
+#  copy of this software and associated documentation files (the "Software"),
+#  to deal in the Software without restriction, including without limitation
+#  the rights to use, copy, modify, merge, publish, distribute, sublicense,
+#  and/or sell copies of the Software, and to permit persons to whom the
+#  Software is furnished to do so, subject to the following conditions:
+#
+#
+from __future__ import annotations
+
+from typing import Optional, Union, TYPE_CHECKING, List
+from datetime import datetime
+
+from .types import monetization as m
+
+from . import utils
+from .enums import SKUType, EntitlementType, try_enum, SubscriptionStatus
+from .flags import SKUFlags
+
+if TYPE_CHECKING:
+    from .user import User
+    from .guild import Guild
+    from .state import ConnectionState
+
+__all__ = (
+    'SKU',
+    'Entitlement',
+    'Subscription',
+)
+
+
+# App Subscriptions
+class SKU:
+    """
+    SKUs (stock-keeping units) in Discord represent premium offerings
+    that can be made available to your application's users or guilds.
+
+    .. versionadded:: 2.0
+
+    Attributes
+    ----------
+    id: :class:`int`
+        The ID of the SKU
+    type: :class:`SKUType`
+        The type of the SKU
+    application_id: :class:`int`
+        The ID of the application this SKU belongs to
+    name: :class:`str`
+        Customer-facing name of the SKU
+    slug: :class:`str`
+        Discord-generated URL slug based on the :attr:`~discord.SKU.name`
+    flags: :class:`SKUFlags`
+        Flags of the SKU, see :class:`~discord.SKUFlags` for more info.
+
+        .. note::
+            This can be used to differentiate between a user and a server subscription.
+    """
+    __slots__ = ('id', 'type', 'application_id', 'name', 'slug', 'flags',)
+
+    def __init__(self, data: m.SKU) -> None:
+        self.id: int = int(data['id'])
+        self.type: SKUType = try_enum(SKUType, data['type'])
+        self.application_id: int = int(data['application_id'])
+        self.name: str = data['name']
+        self.slug: str = data['slug']
+        self.flags: SKUFlags = SKUFlags._from_value(data['flags'])
+
+
+class Entitlement:
+    """
+    Entitlements represent that a user or guild has access to a premium offering in your application.
+
+    .. versionadded:: 2.0
+
+    Attributes
+    ----------
+    id: :class:`int`
+        The ID of the entitlement
+    sku_id: :class:`int`
+        The ID of the :class:`SKU` this entitlement is for
+    application_id: :class:`int`
+        The ID of the application this entitlement belongs to
+    user_id: Optional[:class:`int`]
+        :attr:`~discord.SKUFlags.app_user_subscription` only: The ID of the user that is granted access to the
+        entitlement's sku
+    guild_id: Optional[:class:`int`]
+        :attr:`~discord.SKUFlags.app_guild_subscription` only: The ID of the guild that is granted access to the
+        entitlement's sku
+    deleted: :class:`bool`
+        Whether this entitlement was deleted
+    starts_at: Optional[:class:`~datetime.datetime`]
+        Start date at which the entitlement is valid. ``None`` for test entitlements.
+    ends_at: Optional[:class:`~datetime.datetime`]
+        Time at which the entitlement is no longer valid. ``None`` for test entitlements.
+    consumed: Optional[:class:`bool`]
+            :attr:`~discord.SKUType.consumable` entitlements only: Indicates whether the entitlement has been consumed
+
+            .. seealso:: To consume an entitlement you can use either of those
+
+                - :meth:`~discord.Entitlement.consume` from the Entitlement object directly
+                - :meth:`discord.Client.consume_entitlement` by using only the ID
+    """
+    __slots__ = (
+        '_state', '_type', 'id', 'sku_id', 'application_id', 'user_id', 'guild_id', 'deleted', 'starts_at', 'ends_at',
+        'consumed',
+    )
+
+    def __init__(self, data: m.EntitlementData, state: ConnectionState) -> None:
+        self._state: ConnectionState = state
+        self.id: int = int(data['id'])
+        self.sku_id: int = int(data['sku_id'])
+        self.application_id: int = int(data['application_id'])
+        self.user_id: Optional[int] = utils._get_as_snowflake(data, 'user_id')
+        self.guild_id: Optional[int] = utils._get_as_snowflake(data, 'guild_id')
+        self.deleted: bool = data['deleted']
+        self.starts_at: datetime = utils.parse_time(data.get('starts_at'))
+        self.ends_at: datetime = utils.parse_time(data.get('ends_at'))
+        self.consumed: Optional[bool] = data.get('consumed')
+        self._type: int = data['type']
+
+    @property
+    def type(self) -> EntitlementType:
+        """:class:`~discord.EntitlementType`: The type of the entitlement"""
+        return try_enum(EntitlementType, self._type)
+
+    @property
+    def target(self) -> Union[User, Guild]:
+        """
+        Returns the target of the entitlement.
+
+        .. note::
+            This can be either a :class:`~discord.User` or a :class:`~discord.Guild` depending on the
+            :attr:`~discord.SKUFlags` of the :class:`~discord.SKU` this entitlement belongs to.
+        """
+        if self.user_id is not None:
+            return self._state.get_user(self.user_id)
+        elif self.guild_id is not None:
+            return self._state._get_guild(self.guild_id)
+
+    async def consume(self) -> None:
+        """|coro|
+
+        For one-time purchase :attr:`~discord.SKUType.consumable` SKUs,
+        marks a given entitlement for the user as consumed.
+        :attr:`.consumed` will be ``False`` for this entitlement when using :meth:`~discord.Client.fetch_entitlements`.
+
+        .. note::
+            This can can also be done with just the ID using :meth:`~discord.Client.consume_entitlement`
+        """
+        await self._state.http.consume_entitlement(self.application_id, self.id)
+
+    # TODO: Add additional attributes used for gift entitlements
+    # TODO: Finish documentation
+
+
+class Subscription:
+    """
+    Subscriptions in Discord represent a user making recurring payments for at least one SKU over an ongoing period.
+    Successful payments grant the user access to entitlements associated with the SKU.
+
+    .. versionadded:: 2.0
+
+    Attributes
+    ----------
+    id: :class:`int`
+        The ID of the subscription
+    user_id: :class:`int`
+        The ID of the user that is subscribed to the SKU(s)
+    sku_ids: List[:class:`int`]
+        List of SKU IDs the user is subscribed to
+    entitlement_ids: List[:class:`int`]
+        List of entitlements granted for this subscription
+    current_period_start: :class:`~datetime.datetime`
+        Start date of the current subscription period
+    current_period_end: :class:`~datetime.datetime`
+        End date of the current subscription period
+    status: :class:`~discord.SubscriptionStatus`
+        The status of the subscription
+    canceled_at: Optional[:class:`~datetime.datetime`]
+        Time at which the subscription was canceled
+    country_code: Optional[:class:`str`]
+        The country code of the user.
+
+        ISO3166-1 alpha-2 country code of the payment source used to purchase the subscription.
+        Missing unless queried with a private OAuth scope.
+    """
+
+    def __init__(self, data: m.Subscription, state: ConnectionState):
+        self.id: int = int(data['id'])
+        self.user_id: int = int(data['user_id'])
+        self.sku_ids: List[int] = [int(sku_id) for sku_id in data['sku_ids']]
+        self.entitlement_ids: List[int] = [int(entitlement_id) for entitlement_id in data['entitlement_ids']]
+        self.current_period_start: datetime = utils.parse_time(data['starts_at'])
+        self.current_period_end: datetime = utils.parse_time(data['ends_at'])
+        self.status: SubscriptionStatus = try_enum(SubscriptionStatus, data['status'])
+        self.canceled_at: Optional[datetime] = utils.parse_time(data.get('canceled_at'))
+        self.country_code: Optional[str] = data.get('country')
+        self._state: ConnectionState = state
+
+    def __repr__(self) -> str:
+        return f'<Subscription id={self.id} user_id={self.user_id} status={self.status.name}>'
+
+    @property
+    def user(self) -> User:
+        """The user that is subscribed to the SKU(s)"""
+        return self._state.get_user(self.user_id)
diff --git a/discord/oauth2/__init__.py b/discord/oauth2/__init__.py
new file mode 100644
index 00000000..c15bc031
--- /dev/null
+++ b/discord/oauth2/__init__.py
@@ -0,0 +1,19 @@
+# -*- coding: utf-8 -*-
+
+"""
+Discord Oauth2 implementation
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+An implementation of the discord oauth2 features
+https://discord.com/developers/docs/topics/oauth2
+
+:author: mccoderpy
+:copyright: (c) 2021-present mccoderpy
+:license: MIT, see LICENSE for more details.
+"""
+
+from .client import *
+from .enums import *
+from .errors import *
+from .models import *
+from .server import *
diff --git a/discord/oauth2/client.py b/discord/oauth2/client.py
new file mode 100644
index 00000000..b26dcc15
--- /dev/null
+++ b/discord/oauth2/client.py
@@ -0,0 +1,1233 @@
+# -*- coding: utf-8 -*-
+
+"""
+The MIT License (MIT)
+
+Copyright (c) 2023-present mccoderpy
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+"""
+from __future__ import annotations
+
+import asyncio
+from aiosignal import Signal
+from copy import copy
+import logging
+from functools import wraps
+
+from typing import (
+    Any,
+    Callable,
+    Dict,
+    List,
+    Optional,
+    overload,
+    TYPE_CHECKING,
+    TypeVar,
+    Union
+)
+
+from typing_extensions import (
+    Literal,
+    Self
+)
+
+from .errors import *
+from .http import OAuth2HTTPClient
+from .models import *
+from ..errors import HTTPException, Unauthorized
+from ..application_commands import (
+    AppCommandPermission,
+    GuildAppCommandPermissions
+)
+from ..utils import (
+    MISSING,
+    setup_logging as _setup_logging,
+    SupportsStr
+)
+
+if TYPE_CHECKING:
+    from . import types
+    from ..types import (
+        app_command,
+        guild,
+        user
+    )
+    from ..types.snowflake import SnowflakeID
+    
+    from typing_extensions import (
+        ParamSpec
+    )
+    
+    T = TypeVar('T')
+    P = ParamSpec('P')
+    
+
+__all__ = (
+    'AccessTokenStore',
+    'OAuth2Client',
+)
+
+
+_log = logging.getLogger(__name__)
+
+
+def handle_auto_refresh(func: Callable[P, T]) -> T:
+    @wraps(func)
+    async def wrapper(*args: P.args, **kwargs: P.kwargs) -> T:
+        try:
+            return await func(*args, **kwargs)
+        except AccessTokenExpired as exc:
+            self: OAuth2Client
+            access_token: AccessToken
+            if exc.refreshable:
+                self, access_token = args[:2]
+                if self.auto_refresh:
+                    _log.debug('Access token expired or invalid, auto-refreshing...')
+                    access_token = await self.refresh_access_token(access_token)
+                    return await func(self, access_token, *args[2:], **kwargs)
+                raise
+            raise
+    
+    return wrapper
+
+
+class AccessTokenStore:
+    """
+    Base class for an access token store.
+    
+    Attributes
+    ----------
+    oauth2_client: :class:`OAuth2Client`
+        The client that this store is associated with.
+    """
+    oauth2_client: OAuth2Client
+    
+    async def on_startup(self) -> None:
+        """|coro|
+        
+        This is called by the :class:`OAuth2Client` when it is starting up.
+        
+        This can be used to initialise a database connection or similar.
+        
+        By default, this calls :meth:`load_access_tokens`.
+        """
+        await self.load_access_tokens()
+    
+    async def on_close(self) -> None:
+        """|coro|
+        
+        This is called by the :class:`OAuth2Client` when it is closing.
+        
+        This can be used to close a database connection or similar.
+        
+        By default, this calls :meth:`store_access_tokens`.
+        """
+        await self.store_access_tokens()
+    
+    async def store_access_token(self, access_token: AccessToken) -> None:
+        """|coro|
+        
+        This is called by the :class:`OAuth2Client` when a new access token is created using :meth:`OAuth2Client.authorize`.
+        
+        It can be used to store the access token to a database or similar.
+        
+        Parameters
+        ----------
+        access_token: :class:`AccessToken`
+            The access token that was created.
+        """
+        pass
+    
+    async def store_refreshed_access_token(self, old_access_token: AccessToken, new_access_token: AccessToken) -> None:
+        """|coro|
+        
+        This is called by the :class:`OAuth2Client` when an access token is refreshed using :meth:`OAuth2Client.refresh_access_token`.
+        
+        It can be used to update the database entry for the access token with the new data.
+        
+        Parameters
+        ----------
+        old_access_token: :class:`AccessToken`
+            The old access token that was refreshed.
+        new_access_token: :class:`AccessToken`
+            The new access token that was refreshed.
+        """
+        pass
+    
+    async def store_access_tokens(self) -> None:
+        """|coro|
+        
+        This can be used to store access tokens to a database or similar.
+        
+        .. note::
+            By default this is called by :meth:`on_close`.
+        """
+        pass
+    
+    async def load_access_token(self, *args, **kwargs) -> AccessToken:
+        """|coro|
+        
+        This can be used to load an access token from a database or similar.
+        """
+        raise NotImplementedError('load_access_token must be implemented by a subclass of discord.oauth2.AccessTokenStore')
+    
+    async def load_access_tokens(self) -> Any:
+        """|coro|
+        
+        This can be used to load access tokens from a database or similar.
+        
+        .. note::
+            By default this is called by :meth:`on_startup`.
+        """
+        pass
+    
+    async def remove_revoked_access_token(self, access_token: AccessToken) -> None:
+        """|coro|
+        
+        This is called by the :class:`OAuth2Client` when an access token is revoked using :meth:`OAuth2Client.revoke_access_token`.
+        
+        It can be used to remove the access token from the database or similar.
+        
+        Parameters
+        ----------
+        access_token: :class:`AccessToken`
+            The access token that was revoked.
+        """
+        pass
+
+
+class OAuth2Client:
+    def __init__(
+        self,
+        client_id: int,
+        client_secret: str,
+        access_token_store: Optional[AccessTokenStore] = AccessTokenStore(),
+        *,
+        auto_refresh: bool = True,
+        log_level: Optional[int] = logging.INFO,
+        loop: Optional[asyncio.AbstractEventLoop] = None
+    ):
+        """
+        A class for interacting with the Discord OAuth2 API.
+        
+        Parameters
+        ----------
+        client_id: :class:`int`
+            The client ID of your application.
+        client_secret: :class:`str`
+            The client secret of your application.
+        access_token_store: :class:`AccessTokenStore`
+            The access token store to use to store and update and load the access_tokens.
+            Must be a subclass of :class:`AccessTokenStore`
+        auto_refresh: :class:`bool`
+            Whether to automatically refresh access tokens when :exc:`AccessTokenExpired` is raised.
+        log_level: Optional[:class:`int`]
+            The log level to use for the internal logger.
+        loop: Optional[:class:`asyncio.AbstractEventLoop`]
+            The event loop to use for the internal HTTP client.
+            Only required if you are using a custom event loop.
+        
+        Attributes
+        ----------
+        client_id: :class:`int`
+            The client ID of your application.
+        access_token_store: :class:`AccessTokenStore`
+            The access token store to use to store and update and load the access_tokens.
+            Must be a subclass of :class:`AccessTokenStore`
+        auto_refresh: :class:`bool`
+            Whether to automatically refresh access tokens when :exc:`AccessTokenExpired` is raised.
+        loop: :class:`asyncio.AbstractEventLoop`
+            The event loop that the client is running on.
+        """
+        self.loop: asyncio.AbstractEventLoop = loop
+        self.client_id: int = client_id
+        if not issubclass(access_token_store.__class__, AccessTokenStore):
+            raise TypeError(f'access_token_store must be a subclass of discord.oauth2.AccessTokenStore')
+        self.access_token_store: AccessTokenStore = access_token_store
+        access_token_store.oauth2_client = self
+        self._closed: bool = False
+        self._on_startup = Signal(self)
+        self._on_close = Signal(self)
+        self.on_startup.append(access_token_store.on_startup)
+        self.on_close.append(access_token_store.on_close)
+        self.__client_secret: str = client_secret
+        self.auto_refresh: bool = auto_refresh
+        self.http: OAuth2HTTPClient = OAuth2HTTPClient(client_id=client_id, client_secret=client_secret, loop=loop)
+        self.__log_level: Optional[int] = log_level
+        self.__logging_setup_done: bool = False
+    
+    def __aenter__(self):
+        return self.start()
+    
+    def __aexit__(self, exc_type, exc_val, exc_tb):
+        return self.close()
+    
+    def is_closed(self) -> bool:
+        return self._closed
+    
+    @property
+    def on_startup(self):
+        return self._on_startup
+    
+    @property
+    def on_close(self):
+        return self._on_close
+    
+    def setup_logging(
+            self,
+            *,
+            log_handler: Optional[logging.Handler] = MISSING,
+            log_formatter: logging.Formatter = MISSING,
+            log_level: int = MISSING,
+            root_logger: bool = False
+    ) -> Optional[logging.Logger]:
+        """
+        Sets up the `:mod:`logging` library to make it easier for beginners to know what is going on with the library.
+        For more advanced users, this can be disabled by passing :obj:`None` to the ``log_handler`` parameter.
+        
+        .. note::
+        
+            This will only return the logger when called the first time on this instance.
+            Subsequent calls will return :obj:`None`.
+            
+            So if you want to get the logger, you should call this method yourself before starting the client.
+            
+            
+        Parameters
+        ----------
+        log_handler: Optional[:class:`logging.Handler`]
+            The log handler to use for the library's logger. If this is :obj:`None`
+            then the library will not set up anything logging related. Logging
+            will still work if :obj:`None` is passed, though it is your responsibility
+            to set it up.
+            The default log handler if not provided is :class:`logging.StreamHandler`.
+        log_formatter: :class:`logging.Formatter`
+            The formatter to use with the given log handler. If not provided then it
+            defaults to a colour based logging formatter (if available).
+        log_level: :class:`int`
+            The default log level for the library's logger. This is only applied if the
+            ``log_handler`` parameter is not :obj:`None`.
+            Defaults to the value of ``log_level`` in the init or :attr:`logging.INFO`.
+        root_logger: :class:`bool`
+            Whether to set up the root logger rather than the library logger.
+            By default, only the library logger (``'discord'``) is set up. If this
+            is set to :obj:`True` then the root logger is set up as well.
+            Defaults to :obj:`False`.
+        
+        Returns
+        -------
+        Optional[:class:`logging.Logger`]
+            The logger that was set up. This is the library logger if ``root_logger``
+        """
+        if not self.__logging_setup_done:
+            self.__logging_setup_done = True
+            if log_handler is not None:
+                if log_level is MISSING:
+                    log_level = self.__log_level
+                if log_level is not None:
+                    return _setup_logging(
+                        handler=log_handler,
+                        formatter=log_formatter,
+                        level=log_level,
+                        root=root_logger
+                    )
+    
+    async def start(self) -> Self:
+        """|coro|
+        
+        Starts the client. This will start the internal HTTP client and call the :attr:`on_startup` event.
+        
+        .. important::
+            This must be called before any other requests are made.
+        """
+        self.setup_logging()
+        
+        if not self.loop:
+            self.loop = self.http.loop = asyncio.get_running_loop()
+        
+        self.on_startup.freeze()
+        self.on_close.freeze()
+        
+        self.http.start()
+        self._closed = False
+        await self.on_startup.send()
+        return self
+    
+    async def close(self) -> None:
+        await self.http.close()
+        await self.on_close.send()
+        self._closed = True
+    
+    async def authorize(self, code: str, redirect_uri: str) -> AccessToken:
+        """|coro|
+        
+        Retrieves a users access token by doing a post-request with the authorization code to ``https://discord.com/api/oauth2/token``
+        
+        Parameters
+        ----------
+        code: :class:`str`
+            The access code from ``https://discord.com/oauth2/authorize``
+        redirect_uri: :class:`str`
+            The redirect_uri associated with this authorization, usually from your authorization URL
+        
+        Raises
+        ------
+        :exc:`InvalidAuthorizationCode`
+            The authorization code is invalid or has expired
+        :exc:`HTTPException`
+            Requesting the access token failed
+        
+        Returns
+        -------
+        :class:`AccessToken`
+            The access token for the user
+        """
+        try:
+            data = await self.http.exchange_authorization_token(code, redirect_uri)
+        except HTTPException as e:
+            if e.status == 400:
+                raise InvalidAuthorizationCode()
+            raise
+        
+        access_token = AccessToken.from_raw_data(self, data)
+        await self.access_token_store.store_access_token(access_token)
+        return access_token
+    
+    async def refresh_access_token(self, access_token: AccessToken, /) -> AccessToken:
+        """|coro|
+        
+        Refreshes an access token using its :attr:`~.AccessToken.refresh_token` and returns the updated instance.
+        
+        Parameters
+        ----------
+        access_token: :class:`.AccessToken`
+            The access_token to refresh
+        
+        Raises
+        ------
+        :exc:`InvalidRefreshToken`
+            The refresh token is invalid or has expired
+        
+        Returns
+        -------
+        :class:`.AccessToken`
+            The refreshed token
+        """
+        try:
+            data = await self.http.exchange_refresh_token(access_token.refresh_token)
+        except HTTPException as e:
+            if e.status == 400:
+                raise InvalidRefreshToken() from e
+            raise
+        
+        old_access_token = copy(access_token)
+        access_token._update(data)
+
+        await self.access_token_store.store_refreshed_access_token(old_access_token, access_token)
+
+        return access_token
+    
+    async def revoke_access_token(self, access_token: AccessToken, /) -> None:
+        """|coro|
+        
+        Revokes an access token. It will no longer be usable.
+        
+        Parameters
+        ----------
+        access_token: :class:`AccessToken`
+            The access token to revoke
+        
+        Raises
+        ------
+        :exc:`HTTPException`
+            Revoking the access token failed
+        """
+        await self.http.revoke_access_token(access_token.access_token)
+        await self.access_token_store.remove_revoked_access_token(access_token)
+    
+    @overload
+    async def fetch_access_token_info(self, access_token: AccessToken, /) -> AccessTokenInfo: ...
+    
+    @overload
+    async def fetch_access_token_info(self, access_token: AccessToken, /, *, raw: Literal[True]) -> types.CurrentAuthorizationInfo: ...
+    
+    @handle_auto_refresh
+    async def fetch_access_token_info(
+            self,
+            access_token: AccessToken,
+            /, *,
+            raw: bool = False
+    ) -> Union[AccessTokenInfo, types.CurrentAuthorizationInfo]:
+        """|coro|
+        
+        Fetches info about the current authorization.
+        
+        Parameters
+        ----------
+        access_token: :class:`.AccessToken`
+            The access token to fetch info for
+        raw: :class:`bool`
+            Whether to return the raw data or not
+        
+        Raises
+        ------
+        :exc:`AccessTokenExpired`
+            The access token is expired (this might be handled automatically when :attr:`auto_refresh` is ``True``)
+        
+        Returns
+        -------
+        :class:`~discord.oauth2.AccessTokenInfo`
+            The info about the current authorization
+        :class:`dict`
+            The raw data if ``raw`` is ``True``
+        """
+        try:
+            data = await self.http.get_current_auth_info(access_token.access_token)
+        except Unauthorized:
+            raise AccessTokenExpired(access_token.refreshable)
+        
+        if raw:
+            return data
+        
+        return AccessTokenInfo(data=data, client=self)
+    
+    @overload
+    async def fetch_user(self, access_token: AccessToken, /) -> User: ...
+    
+    @overload
+    async def fetch_user(self, access_token: AccessToken, /, *, raw: Literal[False]) -> User: ...
+
+    @overload
+    async def fetch_user(self, access_token: AccessToken, /, *, raw: Literal[True]) -> types.User: ...
+
+    @handle_auto_refresh
+    async def fetch_user(self, access_token: AccessToken, /, *, raw: bool = False) -> Union[User, types.User]:
+        """|coro|
+        
+        Fetches the user associated with the access token. Requires the :attr:`~OAuth2Scope.IDENTIFY` scope.
+        
+        Parameters
+        ----------
+        access_token: :class:`.AccessToken`
+            The access token to fetch the user for
+        raw: :class:`bool`
+            Whether to return the raw data, defaults to ``False``
+        
+        Returns
+        -------
+        :class:`~discord.oauth2.User`
+            The user associated with the access token
+        :class:`dict`
+            The raw data if ``raw`` is ``True``
+        """
+        try:
+            data = await self.http.get_user(access_token.access_token)
+        except Unauthorized:
+            raise AccessTokenExpired(access_token.refreshable)
+        
+        if raw:
+            return data
+        
+        return User(client=self, data=data)
+    
+    @overload
+    async def fetch_guilds(self, access_token: AccessToken, /) -> List[PartialGuild]: ...
+    @overload
+    async def fetch_guilds(self, access_token: AccessToken, /, *, raw: Literal[True]) -> List[guild.PartialGuild]: ...
+    
+    @handle_auto_refresh
+    async def fetch_guilds(self, access_token: AccessToken, /, *, raw: bool = False) -> Union[List[PartialGuild], List[guild.PartialGuild]]:
+        """|coro|
+        
+        Fetches the guilds the current user is a member of. Requires the :attr:`~OAuth2Scope.GUILDS` scope.
+        
+        Parameters
+        ----------
+        access_token: :class:`.AccessToken`
+            The access token to fetch the guilds for
+        raw: :class:`bool`
+            Whether to return the raw data, defaults to ``False``
+        
+        Returns
+        -------
+        List[:class:`PartialGuild`]
+            The guilds the current user is a member of
+        List[:class:`dict`]
+            The raw data if ``raw`` is ``True``
+        """
+        try:
+            data = await self.http.get_user_guilds(access_token.access_token)
+        except Unauthorized:
+            raise AccessTokenExpired(access_token.refreshable)
+        
+        if raw:
+            return data
+        
+        return [PartialGuild(client=self, data=d) for d in data]
+    
+    @overload
+    async def fetch_guild_member(self, access_token: AccessToken, guild_id: SupportsStr, /) -> GuildMember: ...
+    
+    @overload
+    async def fetch_guild_member(self, access_token: AccessToken, guild_id: SupportsStr, /, *, raw: Literal[True]) -> user.Member: ...
+    
+    @handle_auto_refresh
+    async def fetch_guild_member(self, access_token, guild_id: SupportsStr, *, raw: bool = False) -> Union[GuildMember, user.Member]:
+        """|coro|
+        
+        Fetches the guild member of the current user in the guild. Requires the :attr:`~OAuth2Scope.READ_GUILD_MEMBERS` scope.
+        
+        Parameters
+        ----------
+        access_token: :class:`.AccessToken`
+            The access token to fetch the guild member for
+        guild_id: :class:`SupportsStr`
+            The ID of the guild to fetch the guild member for
+        raw: :class:`bool`
+            Whether to return the raw data, defaults to ``False``
+        
+        Raises
+        ------
+        :exc:`AccessTokenExpired`
+            The access token is expired (this might be handled automatically when :attr:`auto_refresh` is ``True``)
+        
+        Returns
+        -------
+        :class:`GuildMember`
+            The guild member of the current user in the guild
+        :class:`dict`
+            The raw data if ``raw`` is ``True``
+        """
+        try:
+            data = await self.http.get_user_guild_member(access_token.access_token, guild_id)
+        except Unauthorized:
+            raise AccessTokenExpired(access_token.refreshable)
+        
+        if raw:
+            return data
+        
+        return GuildMember(client=self, data=data)
+    
+    @overload
+    async def add_guild_member(
+            self,
+            access_token: AccessToken,
+            /, *,
+            bot_token: SupportsStr,
+            guild_id: SupportsStr,
+            user_id: SupportsStr,
+            nick: str = MISSING,
+            roles: List[SupportsStr] = MISSING,
+            mute: bool = MISSING,
+            deaf: bool = MISSING,
+    ) -> GuildMember: ...
+    
+    @overload
+    async def add_guild_member(
+            self,
+            access_token: AccessToken,
+            /, *,
+            bot_token: SupportsStr,
+            guild_id: SupportsStr,
+            user_id: SupportsStr,
+            nick: str = MISSING,
+            roles: List[SupportsStr] = MISSING,
+            mute: bool = MISSING,
+            deaf: bool = MISSING,
+            raw: Literal[True],
+    ) -> user.Member: ...
+    
+    @handle_auto_refresh
+    async def add_guild_member(
+            self,
+            access_token: AccessToken,
+            /, *,
+            bot_token: SupportsStr,
+            guild_id: SupportsStr,
+            user_id: SupportsStr,
+            nick: str = MISSING,
+            roles: List[SupportsStr] = MISSING,
+            mute: bool = MISSING,
+            deaf: bool = MISSING,
+            raw: bool = False,
+    ) -> Union[user.Member, GuildMember]:
+        """
+        Adds a user to a guild using their access token.
+        
+        .. note::
+            This requires the ``access_token`` to be authorized with the :attr:`~OAuth2Scope.JOIN_GUILDS` scope.
+            Furthermore, the bot must be a member of the guild with the :attr:`~Permissions.create_instant_invite` permissions.
+        
+        .. warning::
+            You should always ask for the user's consent before adding them to a guild.
+        
+        The ``nick``, ``roles``, ``mute`` and ``deaf`` parameters are optional and requires different permission for the bot.
+        
+        +-----------------+-------------------------------------------------------+
+        | Parameter       | Required Permissions                                  |
+        +=================+=======================================================+
+        | ``nick``        | :attr:`~discord.Permissions.manage_nicknames`         |
+        +-----------------+-------------------------------------------------------+
+        | ``roles``       | :attr:`~discord.Permissions.manage_roles`             |
+        +-----------------+-------------------------------------------------------+
+        | ``mute``        | :attr:`~discord.Permissions.mute_members`             |
+        +-----------------+-------------------------------------------------------+
+        | ``deaf``        | :attr:`~discord.Permissions.deafen_members`           |
+        +-----------------+-------------------------------------------------------+
+        
+        Parameters
+        ----------
+        access_token: :class:`AccessToken`
+            The access token for the user to add to the guild.
+        bot_token: :class:`SupportsStr`
+            The bot token for the bot. This is required for authorization.
+        guild_id: :class:`SupportsStr`
+            The ID of the guild to add the user to.
+        user_id: :class:`SupportsStr`
+            The ID of the user to add to the guild. If you don\'t store the user ID already you can get it using :meth:`fetch_user`.
+        nick: :class:`str`
+            The nickname to give the user. Defaults to ``None``.
+        roles: List[:class:`SupportsStr`]
+            A list of role IDs for roles to give the member on join. Defaults to ``None``.
+            
+            .. important::
+            
+                For guilds with `membership screening <https://support.discord.com/hc/en-us/articles/1500000466882-Membership-Screening-FAQ>`_ enabled,
+                assigning a role using the roles parameter will add the user to the guild as a full member
+                (:attr:`~discord.oauth2.GuildMember.pending` will be ``False``).
+                
+                **A member with a role will bypass membership screening, onboarding and the guild's verification level, and get immediate access to chat.**
+                Therefore, instead of assigning a role when the member joins, it is recommended to grant roles only after the user completes screening.
+            
+        mute: :class:`bool`
+            Whether to mute the user on join. Defaults to ``False``.
+        deaf: :class:`bool`
+            Whether to deafen the user on join. Defaults to ``False``.
+        raw: :class:`bool`
+            Whether to return the raw data. Defaults to ``False``.
+        
+        Raises
+        ------
+        :exc:`AccessTokenExpired`
+            The access token is expired (this might be handled automatically when :attr:`auto_refresh` is ``True``)
+        :exc:`Forbidden`
+            The bot does not have the :attr:`~Permissions.create_instant_invite` permission.
+        :exc:`UserIsAtGuildLimit`
+            The user cannot be added to the guild because they reached the guild limit of 100 (200 with nitro).
+        :exc:`HTTPException`
+            Adding the user to the guild failed.
+        
+        Returns
+        -------
+        :class:`~discord.oauth2.GuildMember`
+            The guild member of the current user in the guild.
+        :class:`dict`
+            The raw data if ``raw`` is ``True``.
+        """
+        try:
+            data = await self.http.add_guild_member(
+                access_token.access_token,
+                bot_token,
+                guild_id=guild_id,
+                user_id=user_id,
+                nick=nick,
+                roles=roles,
+                mute=mute,
+                deaf=deaf,
+            )
+        except Unauthorized:
+            raise AccessTokenExpired(access_token.refreshable)
+        except HTTPException as exc:
+            if exc.status == 400 and exc.code == 30001:
+                raise UserIsAtGuildLimit()
+            raise
+        
+        if raw:
+            return data
+        
+        return GuildMember(client=self, data=data) if data else None
+    
+    @overload
+    async def fetch_connections(self, access_token: AccessToken, /) -> List[Connection]: ...
+    
+    @overload
+    async def fetch_connections(self, access_token: AccessToken, /, *, raw: Literal[True]) -> List[types.Connection]: ...
+    
+    @handle_auto_refresh
+    async def fetch_connections(self, access_token: AccessToken, /, *, raw: bool = False) -> Union[List[Connection], List[types.Connection]]:
+        """|coro|
+        
+        Fetches the connections of the current user. Requires the :attr:`~OAuth2Scope.CONNECTIONS` scope.
+        
+        Parameters
+        ----------
+        access_token: :class:`.AccessToken`
+            The access token to fetch the connections for
+        raw: :class:`bool`
+            Whether to return the raw data, defaults to ``False``
+        
+        Raises
+        ------
+        :exc:`AccessTokenExpired`
+            The access token is expired (this might be handled automatically when :attr:`auto_refresh` is ``True``)
+        
+        Returns
+        -------
+        List[:class:`.Connection`]
+            The connections of the current user
+        :class:`dict`
+            The raw data if ``raw`` is ``True``
+        """
+        try:
+            data = await self.http.get_user_connections(access_token.access_token)
+        except Unauthorized:
+            raise AccessTokenExpired(access_token.refreshable)
+        
+        if raw:
+            return data
+        
+        return [Connection(client=self, data=d) for d in data]
+    
+    @overload
+    async def fetch_user_app_role_connection(self, access_token: AccessToken, /) -> RoleConnection: ...
+    
+    @overload
+    async def fetch_user_app_role_connection(self, access_token: AccessToken, /, *, raw: Literal[True]) -> types.RoleConnection: ...
+    
+    @handle_auto_refresh
+    async def fetch_user_app_role_connection(
+            self,
+            access_token: AccessToken,
+            /, *,
+            raw: bool = False
+    ) -> Union[RoleConnection, types.RoleConnection]:
+        """|coro|
+        
+        Fetches the role connection of the current user if any. Requires the :attr:`~OAuth2Scope.WRITE_ROLE_CONNECTIONS` scope.
+        
+        Parameters
+        ----------
+        access_token: :class:`AccessToken`
+            The access token to fetch the role connection for
+        raw: :class:`bool`
+            Whether to return the raw data, defaults to ``False``
+        
+        Raises
+        ------
+        :exc:`AccessTokenExpired`
+            The access token is expired (this might be handled automatically when :attr:`auto_refresh` is ``True``)
+        
+        Returns
+        -------
+        :class:`.RoleConnection`
+            The role connection of the current user
+        :class:`dict`
+            The raw data if ``raw`` is ``True``
+        """
+        try:
+            data = await self.http.get_user_application_role_connection(access_token.access_token)
+        except Unauthorized:
+            raise AccessTokenExpired(access_token.refreshable)
+        
+        if raw:
+            return data
+        
+        return RoleConnection(data=data)
+    
+    @overload
+    async def update_user_app_role_connection(
+            self,
+            access_token: AccessToken,
+            /, *,
+            platform_name: str = MISSING,
+            platform_username: str = MISSING,
+            metadata: Dict[str, str] = MISSING,
+            application_id: int = None
+    ) -> RoleConnection: ...
+    
+    @overload
+    async def update_user_app_role_connection(
+            self,
+            access_token: AccessToken,
+            /, *,
+            platform_name: str = MISSING,
+            platform_username: str = MISSING,
+            metadata: Dict[str, str] = MISSING,
+            application_id: int = None,
+            raw: Literal[True]
+    ) -> types.RoleConnection: ...
+    
+    @handle_auto_refresh
+    async def update_user_app_role_connection(
+            self,
+            access_token: AccessToken,
+            /, *,
+            platform_name: str = MISSING,
+            platform_username: str = MISSING,
+            metadata: Dict[str, str] = MISSING,
+            application_id: int = None,
+            raw: bool = False
+    ) -> Union[RoleConnection, types.RoleConnection]:
+        """|coro|
+        
+        Updates the role connection of the current user. Requires the :attr:`~OAuth2Scope.WRITE_ROLE_CONNECTIONS` scope.
+        
+        All parameters are optional and will only be updated if provided.
+        
+        Parameters
+        ----------
+        access_token: :class:`.AccessToken`
+            The access token to update the role connection for
+        platform_name: :class:`str`
+            The vanity name of the platform a bot has connected (max 50 characters)
+        platform_username: :class:`str`
+            The username on the platform a bot has connected (max 100 characters)
+        metadata: Dict[:class:`str`, :class:`str`]
+            The metadata of the role connection.
+            
+            Mapping of :attr:`AppRoleConnectionMetadata.key` s to their string-ified value (max 100 characters)
+        application_id: :class:`int`
+            The ID of the application to update the role connection for.
+            
+            Only required if the application id is not the same as the client id (e.g. for some older applications)
+
+        raw: :class:`bool`
+            Whether to return the raw data, defaults to ``False``
+        
+        Returns
+        -------
+        :class:`.RoleConnection`
+            The updated role connection of the current user
+        :class:`dict`
+            The raw data if ``raw`` is ``True``
+        """
+        payload = {}
+        if platform_name is not MISSING:
+            payload['platform_name'] = platform_name
+        if platform_username is not MISSING:
+            payload['platform_username'] = platform_username
+        if metadata is not MISSING:
+            payload['metadata'] = metadata
+        
+        data = await self.http.update_user_application_role_connection(access_token.access_token, data=payload, application_id=application_id)
+        
+        if raw:
+            return data
+        
+        return RoleConnection(data=data)
+    
+    @overload
+    async def fetch_all_application_command_permissions(
+            self,
+            access_token: AccessToken, /, *,
+            guild_id: SnowflakeID,
+            application_id: Optional[SnowflakeID] = None
+    ) -> List[GuildAppCommandPermissions]: ...
+    
+    @overload
+    async def fetch_all_application_command_permissions(
+            self,
+            access_token: AccessToken, /, *,
+            guild_id: SnowflakeID,
+            application_id: Optional[SnowflakeID] = None,
+            raw: Literal[True]
+    ) -> List[app_command.GuildApplicationCommandPermissions]: ...
+    
+    @handle_auto_refresh
+    async def fetch_all_application_command_permissions(
+            self,
+            access_token: AccessToken, /, *,
+            guild_id: SnowflakeID,
+            application_id: Optional[SnowflakeID] = None,
+            raw: bool = False
+    ) -> Union[List[GuildAppCommandPermissions], List[app_command.GuildApplicationCommandPermissions]]:
+        """|coro|
+        
+        Fetches all application command permissions for the given guild.
+        
+        Parameters
+        ----------
+        access_token: :class:`.AccessToken`
+            An access token of a user that is a member of the guild to fetch the application-command permissions for.
+        guild_id: Union[:class:`int`, :class:`str`]
+            The ID of the guild to fetch the application-command permissions for.
+        application_id: Optional[Union[:class:`int`, :class:`str`]]
+            The ID of the application to fetch the permissions for.
+            If not provided, defaults to the client's application ID.
+            
+            .. note::
+                
+                This is only required if the application ID is not the same as the client ID (e.g. for some older applications).
+        raw: :class:`bool`
+            Whether to return the raw data, defaults to ``False``
+        
+        Raises
+        ------
+        :exc:`AccessTokenExpired`
+            The access token is expired (this might be handled automatically when :attr:`auto_refresh` is ``True``)
+        :exc:`HTTPException`
+            Fetching the application-command permissions failed.
+        
+        Returns
+        -------
+        List[:class:`.GuildApplicationCommandPermissions`]
+            A list of all application command permissions for the given guild.
+        List[:class:`dict`]
+            The raw data if ``raw`` is ``True``.
+        """
+        data = await self.http.get_all_application_command_permissions(
+            access_token.access_token, guild_id=guild_id, application_id=application_id
+        )
+        
+        if raw:
+            return data
+        
+        return [GuildAppCommandPermissions.from_dict(data=entry) for entry in data]
+    
+    @overload
+    async def fetch_application_command_permissions(
+            self,
+            access_token: AccessToken, /, *,
+            guild_id: SnowflakeID,
+            command_id: SnowflakeID,
+            application_id: Optional[SnowflakeID] = None
+    ) -> GuildAppCommandPermissions: ...
+    
+    @overload
+    async def fetch_application_command_permissions(
+            self,
+            access_token: AccessToken, /, *,
+            guild_id: SnowflakeID,
+            command_id: SnowflakeID,
+            application_id: Optional[SnowflakeID] = None,
+            raw: Literal[True]
+    ) -> app_command.GuildApplicationCommandPermissions: ...
+    
+    @handle_auto_refresh
+    async def fetch_application_command_permissions(
+            self,
+            access_token: AccessToken, /, *,
+            guild_id: SnowflakeID,
+            command_id: SnowflakeID,
+            application_id: Optional[SnowflakeID] = None,
+            raw: bool = False
+    ) -> Union[GuildAppCommandPermissions, app_command.GuildApplicationCommandPermissions]:
+        """|coro|
+        
+        Fetches the permission overwrites for an application-command in a guild.
+        
+        Parameters
+        ----------
+        access_token: :class:`.AccessToken`
+            An access token of a user that is a member of the guild to fetch the application-commands permissions for.
+        guild_id: Union[:class:`int`, :class:`str`]
+            The ID of the guild to fetch the application-command permissions for.
+        command_id: Union[:class:`int`, :class:`str`]
+            The ID of the application-command to fetch the permissions for.
+        application_id: Optional[Union[:class:`int`, :class:`str`]]
+            The ID of the application to fetch the permissions for.
+            If not provided, defaults to the client's application ID.
+            
+            .. note::
+                
+                This is only required if the application ID is not the same as the client ID (e.g. for some older applications).
+        raw: :class:`bool`
+            Whether to return the raw data, defaults to ``False``
+        
+        Raises
+        ------
+        :exc:`AccessTokenExpired`
+            The access token is expired (this might be handled automatically when :attr:`auto_refresh` is ``True``)
+        :exc:`Forbidden`
+            The application does not have the permission to fetch the permissions.
+        :exc:`NotFound`
+            The application-command or the guild was not found.
+        
+        Returns
+        -------
+        :class:`.GuildApplicationCommandPermissions`
+            The permission overwrites for the application-command in the guild.
+        :class:`dict`
+            The raw data if ``raw`` is ``True
+        """
+        data = await self.http.get_application_command_permissions(
+            access_token.access_token, guild_id=guild_id, command_id=command_id, application_id=application_id
+        )
+        
+        if raw:
+            return data
+        
+        return GuildAppCommandPermissions.from_dict(data=data)
+    
+    @overload
+    async def edit_application_command_permissions(
+            self,
+            access_token: AccessToken, /, *,
+            guild_id: SnowflakeID,
+            command_id: SnowflakeID,
+            permissions: List[AppCommandPermission],
+            application_id: Optional[SnowflakeID] = None
+    ) -> GuildAppCommandPermissions: ...
+    
+    @overload
+    async def edit_application_command_permissions(
+            self,
+            access_token: AccessToken, /, *,
+            guild_id: SnowflakeID,
+            command_id: SnowflakeID,
+            permissions: List[AppCommandPermission],
+            application_id: Optional[SnowflakeID] = None,
+            raw: Literal[True]
+    ) -> app_command.GuildApplicationCommandPermissions: ...
+    
+    @handle_auto_refresh
+    async def edit_application_command_permissions(
+            self,
+            access_token: AccessToken, /, *,
+            guild_id: SnowflakeID,
+            command_id: SnowflakeID,
+            permissions: List[AppCommandPermission],
+            application_id: Optional[SnowflakeID] = None,
+            raw: bool = False
+    ) -> Union[GuildAppCommandPermissions, app_command.GuildApplicationCommandPermissions]:
+        """|coro|
+        
+        Edits the permission overwrites for an application-command in a guild.
+        Requires the :attr:`~OAuth2Scope.UPDATE_APPLICATIONS_COMMANDS_PERMISSIONS` scope.
+        
+        .. warning::
+            
+            This method will overwrite all existing permissions for the application-command.
+            So if you want to keep the existing permissions, you need to include the existing ones in ``permissions``.
+        
+        .. note::
+            
+            The ``access_token`` must be of a user that is a member of the guild and the following permissions are required:
+            
+            - :attr:`.Permissions.manage_guild`
+            - :attr:`.Permissions.manage_roles`
+            - Has the ability to run the application-command
+            - Has the permissions to manage the resources that will be affected (roles, users, and/or channels depending on the :attr:`.ApplicationCommandPermissions.type`)
+        
+        Parameters
+        ----------
+        access_token: :class:`.AccessToken`
+            An access token of a user that is a member of the guild to edit the application-command permissions for.
+        guild_id: Union[:class:`int`, :class:`str`]
+            The ID of the guild to edit the application-command permissions for.
+        command_id: Union[:class:`int`, :class:`str`]
+            The ID of the application-command to edit the permissions for.
+        permissions: List[:class:`.ApplicationCommandPermissions`]
+            The new permissions for the application-command.
+        application_id: Optional[Union[:class:`int`, :class:`str`]]
+            The ID of the application to edit the permissions for.
+            If not provided, defaults to the client's application ID.
+            
+            .. note::
+                
+                This is only required if the application ID is not the same as the client ID (e.g. for some older applications).
+        raw: :class:`bool`
+            Whether to return the raw data, defaults to ``False``
+        
+        Raises
+        ------
+        :exc:`AccessTokenExpired`
+            The access token is expired (this might be handled automatically when :attr:`auto_refresh` is ``True``)
+        :exc:`.Forbidden`
+            The application does not have the permission to edit the permissions.
+        :exc:`NotFound`
+            The application-command or the guild was not found.
+        
+        Returns
+        -------
+        :class:`.GuildApplicationCommandPermissions`
+            The permission overwrites for the application-command in the guild.
+        :class:`dict`
+            The raw data if ``raw`` is ``True
+        
+        Examples
+        --------
+        Editing the permissions for an application-command in a guild:
+        
+            There is a command called "test" and now you want to ensure the following for the guild with the ID 852871920411475968:
+            
+            - ``@everyone`` should not be able to use the command
+            - Every member with the role "Member" (ID: 852937257903456256) can use the command
+            - The command should only be usable in the channel "commands" (ID: 853000092156035083)
+            
+        .. code-block:: python3
+            
+            import discord.oauth2 as oauth2
+            
+            from discord import (
+                AppCommandPermission
+                AppCommandPermissionType
+            )
+            
+            # Assuming you have a OAuth2Client instance and a command called "test" with the ID 919316347165495356
+            
+            GUILD_ID = 852871920411475968
+            MEMBER_ROLE_ID = 852937257903456256
+            COMMAND_CHANNEL_ID = 853000092156035083
+            COMMAND_ID = 919316347165495356
+            
+            permissions = [
+                AppCommandPermission(
+                    type=AppCommandPermissionType.ROLE,
+                    id=GUILD_ID,  # Special constant for all members in the guild
+                    permission=False
+                ),  # Deny permission for @everyone
+                AppCommandPermission(
+                    type=AppCommandPermissionType.ROLE,
+                    id=MEMBER_ROLE_ID,
+                    permission=True
+                ), # Allow permission for members with the "Member" role
+                AppCommandPermission(
+                    type=AppCommandPermissionType.CHANNEL,
+                    id=GUILD_ID - 1,  # Special constant for "all channels"
+                    permission=False
+                )  # Deny permission for all channels
+                AppCommandPermission(
+                    type=AppCommandPermissionType.CHANNEL,
+                    id=COMMAND_CHANNEL_ID,
+                    permission=True
+                )  # Allow permission for the "commands" channel
+            ]
+            
+            await client.edit_application_command_permissions(
+                access_token,
+                guild_id=guild_id,
+                command_id=COMMAND_ID,
+                permissions=permissions
+            )
+            
+        """
+        data = await self.http.update_application_command_permissions(
+            access_token.access_token,
+            guild_id=guild_id,
+            command_id=command_id,
+            application_id=application_id,
+            permissions=[permission.to_dict() for permission in permissions]
+        )
+        
+        if raw:
+            return data
+        
+        return GuildAppCommandPermissions.from_dict(data=data)
diff --git a/discord/oauth2/enums.py b/discord/oauth2/enums.py
new file mode 100644
index 00000000..db9bf56b
--- /dev/null
+++ b/discord/oauth2/enums.py
@@ -0,0 +1,233 @@
+# -*- coding: utf-8 -*-
+
+"""
+The MIT License (MIT)
+
+Copyright (c) 2023-present mccoderpy
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+"""
+
+from ..enums import Enum
+
+__all__ = (
+    'OAuth2Scope',
+    'GrantType',
+    'ConnectionService',
+)
+
+
+class OAuth2Scope(Enum):
+    """
+    These are all the OAuth2 scopes that Discord supports.
+    Some scopes require approval from Discord to use.
+    Requesting them from a user without approval from Discord may cause errors or undocumented behavior in the OAuth2 flow.
+    
+    +---------------------------------------------------------+------------------------------------------+--------------------------------------------------------------------------------------------------------------------+
+    | Attribute                                               | Name                                     | Description                                                                                                        |
+    +=========================================================+==========================================+====================================================================================================================+
+    | .. attribute:: READ_ACTIVITIES                          | activities.read                          | allows your app to fetch data from a user's "Now Playing/Recently Played" list                                     |
+    |                                                         |                                          | - **not currently available for apps**                                                                             |
+    +---------------------------------------------------------+------------------------------------------+--------------------------------------------------------------------------------------------------------------------+
+    | .. attribute:: WRITE_ACTIVITIES                         | activities.write                         | allows your app to update a user's activity                                                                        |
+    |                                                         |                                          | - **requires Discord approval** (NOT REQUIRED FOR GAMESDK ACTIVITY MANAGER)                                        |
+    +---------------------------------------------------------+------------------------------------------+--------------------------------------------------------------------------------------------------------------------+
+    | .. attribute:: READ_APPLICATIONS_BUILDS                 | applications.builds.read                 | allows your app to read build data for a user's applications                                                       |
+    +---------------------------------------------------------+------------------------------------------+--------------------------------------------------------------------------------------------------------------------+
+    | .. attribute:: UPLOAD_APPLICATIONS_BUILDS               | applications.builds.upload               | allows your app to upload/update builds for a user's applications                                                  |
+    |                                                         |                                          | - **requires Discord approval**                                                                                    |
+    +---------------------------------------------------------+------------------------------------------+--------------------------------------------------------------------------------------------------------------------+
+    | .. attribute:: APPLICATIONS_COMMANDS                    | applications.commands                    | allows your app to use application-commands in a guild                                                             |
+    +---------------------------------------------------------+------------------------------------------+--------------------------------------------------------------------------------------------------------------------+
+    | .. attribute:: UPDATE_APPLICATIONS_COMMANDS             | applications.commands.update             | allows your app to update its application-commands using a Bearer token - client credentials grant only            |
+    +---------------------------------------------------------+------------------------------------------+--------------------------------------------------------------------------------------------------------------------+
+    | .. attribute:: UPDATE_APPLICATIONS_COMMANDS_PERMISSIONS | applications.commands.permissions.update | allows your app to update permissions for its commands in a guild a user has permissions to                        |
+    +---------------------------------------------------------+------------------------------------------+--------------------------------------------------------------------------------------------------------------------+
+    | .. attribute:: APPLICATIONS_ENTITLEMENTS                | applications.entitlements                | allows your app to read entitlements for a user's applications                                                     |
+    +---------------------------------------------------------+------------------------------------------+--------------------------------------------------------------------------------------------------------------------+
+    | .. attribute:: UPDATE_APPLICATIONS_STORE                | applications.store.update                | allows your app to read and update store data (SKUs, store listings, achievements, etc.) for a user's applications |
+    +---------------------------------------------------------+------------------------------------------+--------------------------------------------------------------------------------------------------------------------+
+    | .. attribute:: BOT                                      | bot                                      | for oauth2 bots, this puts the bot in the user's selected guild by default                                         |
+    +---------------------------------------------------------+------------------------------------------+--------------------------------------------------------------------------------------------------------------------+
+    | .. attribute:: CONNECTIONS                              | connections                              | allows ``/users/@me/connections`` to return linked third-party accounts                                            |
+    +---------------------------------------------------------+------------------------------------------+--------------------------------------------------------------------------------------------------------------------+
+    | .. attribute:: READ_DM_CHANNELS                         | dm_channels.read                         | allows your app to see information about the user's DMs and group DMs                                              |
+    |                                                         |                                          | - **requires Discord approval**                                                                                    |
+    +---------------------------------------------------------+------------------------------------------+--------------------------------------------------------------------------------------------------------------------+
+    | .. attribute:: ACCESS_EMAIL                             | email                                    | enables ``/users/@me`` to return an ``email``                                                                      |
+    +---------------------------------------------------------+------------------------------------------+--------------------------------------------------------------------------------------------------------------------+
+    | .. attribute:: JOIN_GROUPS                              | gdm.join                                 | allows your app to join users to a group dm                                                                        |
+    +---------------------------------------------------------+------------------------------------------+--------------------------------------------------------------------------------------------------------------------+
+    | .. attribute:: ACCESS_GUILDS                            | guilds                                   | allows ``/users/@me/guilds`` to return basic information about all of a user's guilds                              |
+    +---------------------------------------------------------+------------------------------------------+--------------------------------------------------------------------------------------------------------------------+
+    | .. attribute:: JOIN_GUILDS                              | guilds.join                              | allows ``/guilds/{guild.id}/members/{user.id}`` to be used for joining users to a guild                            |
+    +---------------------------------------------------------+------------------------------------------+--------------------------------------------------------------------------------------------------------------------+
+    | .. attribute:: READ_GUILDS_MEMBERS                      | guilds.members.read                      | allows ``/users/@me/guilds/{guild.id}/member`` to return a user's member information in a guild                    |
+    +---------------------------------------------------------+------------------------------------------+--------------------------------------------------------------------------------------------------------------------+
+    | .. attribute:: IDENTIFY                                 | identify                                 | allows ``/users/@me`` without ``email``                                                                            |
+    +---------------------------------------------------------+------------------------------------------+--------------------------------------------------------------------------------------------------------------------+
+    | .. attribute:: READ_MESSAGES                            | messages.read                            | for local rpc server api access, this allows you to read messages from all client channels                         |
+    |                                                         |                                          | (otherwise restricted to channels/guilds your app creates)                                                         |
+    +---------------------------------------------------------+------------------------------------------+--------------------------------------------------------------------------------------------------------------------+
+    | .. attribute:: READ_RELATIONSHIPS                       | relationships.read                       | allows your app to know a user's friends and implicit relationships                                                |
+    |                                                         |                                          | - **requires Discord approval**                                                                                    |
+    +---------------------------------------------------------+------------------------------------------+--------------------------------------------------------------------------------------------------------------------+
+    | .. attribute:: WRITE_ROLE_CONNECTIONS                   | role_connections.write                   | allows your app to update a user's connection and metadata for the app                                             |
+    +---------------------------------------------------------+------------------------------------------+--------------------------------------------------------------------------------------------------------------------+
+    | .. attribute:: ACCESS_RPC                               | rpc                                      | for local rpc server access, this allows you to control a user's local Discord client                              |
+    |                                                         |                                          | - **requires Discord approval**                                                                                    |
+    +---------------------------------------------------------+------------------------------------------+--------------------------------------------------------------------------------------------------------------------+
+    | .. attribute:: RPC_WRITE_ACTIVITIES                     | rpc.activities.write                     | for local rpc server access, this allows you to update a user's activity                                           |
+    |                                                         |                                          | - **requires Discord approval**                                                                                    |
+    +---------------------------------------------------------+------------------------------------------+--------------------------------------------------------------------------------------------------------------------+
+    | .. attribute:: RPC_READ_NOTIFICATIONS                   | rpc.notifications.read                   | for local rpc server access, this allows you to receive notifications pushed out to the user                       |
+    |                                                         |                                          | - **requires Discord approval**                                                                                    |
+    +---------------------------------------------------------+------------------------------------------+--------------------------------------------------------------------------------------------------------------------+
+    | .. attribute:: RPC_READ_VOICE                           | rpc.voice.read                           | for local rpc server access, this allows you to read a user's voice settings and listen for voice events           |
+    |                                                         |                                          | - **requires Discord approval**                                                                                    |
+    +---------------------------------------------------------+------------------------------------------+--------------------------------------------------------------------------------------------------------------------+
+    | .. attribute:: RPC_WRITE_VOICE                          | rpc.voice.write                          | for local rpc server access, this allows you to update a user's voice settings                                     |
+    |                                                         |                                          | - **requires Discord approval**                                                                                    |
+    +---------------------------------------------------------+------------------------------------------+--------------------------------------------------------------------------------------------------------------------+
+    | .. attribute:: VOICE                                    | voice                                    | allows your app to connect to voice on user's behalf and see all the voice members                                 |
+    |                                                         |                                          | - **requires Discord approval**                                                                                    |
+    +---------------------------------------------------------+------------------------------------------+--------------------------------------------------------------------------------------------------------------------+
+    | .. attribute:: CREATE_WEBHOOK                           | webhook.incoming                         | this generates a webhook that is returned in the oauth token response for authorization code grants                |
+    +---------------------------------------------------------+------------------------------------------+--------------------------------------------------------------------------------------------------------------------+
+    
+    .. important::
+    
+        :attr:`JOIN_GUILDS` and :attr:`BOT` require you to have a bot account linked to your application.
+        Also, in order to add a user to a guild, your bot has to already belong to that guild.
+    """
+    READ_ACTIVITIES                          = 'activities.read'
+    WRITE_ACTIVITIES                         = 'activities.write'
+    READ_APPLICATIONS_BUILDS                 = 'applications.builds.read'
+    UPLOAD_APPLICATIONS_BUILDS               = 'applications.builds.upload'
+    APPLICATIONS_COMMANDS                    = 'applications.commands'
+    UPDATE_APPLICATIONS_COMMANDS             = 'applications.commands.update'
+    UPDATE_APPLICATIONS_COMMANDS_PERMISSIONS = 'applications.commands.permissions.update'
+    APPLICATIONS_ENTITLEMENTS                = 'applications.entitlements'
+    UPDATE_APPLICATIONS_STORE                = 'applications.store.update'
+    BOT                                      = 'bot'
+    CONNECTIONS                              = 'connections'
+    READ_DM_CHANNELS                         = 'dm_channels.read'
+    ACCESS_EMAIL                             = 'email'
+    JOIN_GROUPS                              = 'gdm.join'
+    ACCESS_GUILDS                            = 'guilds'
+    JOIN_GUILDS                              = 'guilds.join'
+    READ_GUILDS_MEMBERS                      = 'guilds.members.read'
+    IDENTIFY                                 = 'identify'
+    READ_MESSAGES                            = 'messages.read'
+    READ_RELATIONSHIPS                       = 'relationships.read'
+    WRITE_ROLE_CONNECTIONS                   = 'role_connections.write'
+    ACCESS_RPC                               = 'rpc'
+    RPC_WRITE_ACTIVITIES                     = 'rpc.activities.write'
+    RPC_READ_NOTIFICATIONS                   = 'rpc.notifications.read'
+    RPC_READ_VOICE                           = 'rpc.voice.read'
+    RPC_WRITE_VOICE                          = 'rpc.voice.write'
+    VOICE                                    = 'voice'
+    CREATE_WEBHOOK                           = 'webhook.incoming'
+    
+    def __str__(self) -> str:
+        return self.value
+
+
+class GrantType(Enum):
+    AUTHORIZATION_CODE = 'authorization_code'
+    CLIENT_CREDENTIALS = 'client_credentials'
+    REFRESH_TOKEN      = 'refresh_token'
+
+
+class ConnectionService(Enum):
+    """Represents the service of a :class:`Connection`.
+    
+    .. container:: operations
+    
+        .. describe:: str(x)
+    
+            Returns the connection type's name.
+    
+    +----------------------------------+----------------------+
+    | Name                             | Value                |
+    +==================================+======================+
+    | .. attribute:: Battlenet         | battlenet            |
+    +----------------------------------+----------------------+
+    | .. attribute:: Crunchyroll       | crunchyroll          |
+    +----------------------------------+----------------------+
+    | .. attribute:: eBay              | ebay                 |
+    +----------------------------------+----------------------+
+    | .. attribute:: Epic_Games        | epicgames            |
+    +----------------------------------+----------------------+
+    | .. attribute:: Facebook          | facebook             |
+    +----------------------------------+----------------------+
+    | .. attribute:: GitHub            | github               |
+    +----------------------------------+----------------------+
+    | .. attribute:: Instagram         | instagram            |
+    +----------------------------------+----------------------+
+    | .. attribute:: League_of_Legends | leagueoflegends      |
+    +----------------------------------+----------------------+
+    | .. attribute:: PayPal            | paypal               |
+    +----------------------------------+----------------------+
+    | .. attribute:: Playstation       | playstation          |
+    +----------------------------------+----------------------+
+    | .. attribute:: Reddit            | reddit               |
+    +----------------------------------+----------------------+
+    | .. attribute:: Riotgames         | riotgames            |
+    +----------------------------------+----------------------+
+    | .. attribute:: Skype             | skype                |
+    +----------------------------------+----------------------+
+    | .. attribute:: Spotify           | spotify              |
+    +----------------------------------+----------------------+
+    | .. attribute:: Steam             | steam                |
+    +----------------------------------+----------------------+
+    | .. attribute:: TikTok            | tiktok               |
+    +----------------------------------+----------------------+
+    | .. attribute:: Twitch            | twitch               |
+    +----------------------------------+----------------------+
+    | .. attribute:: Twitter           | twitter              |
+    +----------------------------------+----------------------+
+    | .. attribute:: xBox              | xbox                 |
+    +----------------------------------+----------------------+
+    | .. attribute:: YouTube           | youtube              |
+    +----------------------------------+----------------------+
+    """
+    Battlenet   = 'battlenet'
+    Crunchyroll = 'crunchyroll'
+    eBay        = 'ebay'
+    Epic_Games   = 'epicgames'
+    Facebook    = 'facebook'
+    GitHub      = 'github'
+    Instagram   = 'instagram'
+    League_of_Legends = 'leagueoflegends'
+    PayPal      = 'paypal'
+    Playstation = 'playstation'
+    Reddit      = 'reddit'
+    Riotgames   = 'riotgames'
+    Skype       = 'skype'
+    Spotify     = 'spotify'
+    Steam       = 'steam'
+    TikTok      = 'tiktok'
+    Twitch      = 'twitch'
+    Twitter     = 'twitter'
+    xBox        = 'xbox'
+    YouTube     = 'youtube'
+    
+    def __str__(self) -> str:
+        return self.value
diff --git a/discord/oauth2/errors.py b/discord/oauth2/errors.py
new file mode 100644
index 00000000..e8ba7f95
--- /dev/null
+++ b/discord/oauth2/errors.py
@@ -0,0 +1,82 @@
+# -*- coding: utf-8 -*-
+
+"""
+The MIT License (MIT)
+
+Copyright (c) 2023-present mccoderpy
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+"""
+from ..errors import DiscordException
+
+__all__ = (
+    'OAuth2Exception',
+    'AccessTokenExpired',
+    'AccessTokenNotRefreshable',
+    'InvalidAccessToken',
+    'InvalidRefreshToken',
+    'InvalidAuthorizationCode',
+    'UserIsAtGuildLimit'
+)
+
+
+class OAuth2Exception(DiscordException):
+    """Base class for all OAuth2 errors."""
+    pass
+
+
+class AccessTokenExpired(OAuth2Exception):
+    """Exception raised when an access token has expired."""
+    def __init__(self, refreshable: bool = True):
+        if refreshable:
+            msg = 'This access token has expired and needs to be refreshed first.'
+        else:
+            msg = 'This access token has expired and the user must re-authorize the application.'
+        self.refreshable = refreshable
+        super().__init__(msg)
+
+
+class AccessTokenNotRefreshable(OAuth2Exception):
+    """Exception raised when a token is not refreshable."""
+    def __init__(self):
+        super().__init__('This token is not refreshable as it is missing a refresh_token')
+
+
+class InvalidAccessToken(OAuth2Exception):
+    """Exception raised when an invalid access token is used."""
+    def __init__(self):
+        super().__init__('The access token is invalid or has expired.')
+
+
+class InvalidRefreshToken(OAuth2Exception):
+    """Exception raised when an invalid refresh token is used."""
+    def __init__(self):
+        super().__init__('The refresh token is invalid or has expired.')
+
+
+class InvalidAuthorizationCode(OAuth2Exception):
+    """Exception raised when an invalid authorization code is used."""
+    def __init__(self):
+        super().__init__('The authorization code is invalid or has expired.')
+
+
+class UserIsAtGuildLimit(OAuth2Exception):
+    """Exception raised when the user is at the guild limit."""
+    def __init__(self):
+        super().__init__('This user can\'t be added to the guild as they are at the 100 (200 with nitro) server limit.')
diff --git a/discord/oauth2/http.py b/discord/oauth2/http.py
new file mode 100644
index 00000000..6bdd533c
--- /dev/null
+++ b/discord/oauth2/http.py
@@ -0,0 +1,464 @@
+# -*- coding: utf-8 -*-
+
+"""
+The MIT License (MIT)
+
+Copyright (c) 2021-present mccoderpy
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+"""
+from __future__ import annotations
+
+import asyncio
+import logging
+import sys
+import weakref
+from typing import (
+    Any,
+    Coroutine,
+    List,
+    Optional,
+    TYPE_CHECKING,
+    TypeVar,
+    Union
+)
+
+import aiohttp
+from typing_extensions import NoReturn
+
+from .. import __version__
+from ..errors import (
+    DiscordServerError,
+    Forbidden,
+    Unauthorized,
+    HTTPException,
+    NotFound
+)
+from ..http import (
+    json_or_text,
+    MaybeUnlock,
+    Route
+)
+from ..utils import (
+    _parse_ratelimit_header,
+    MISSING,
+    to_json
+)
+
+if TYPE_CHECKING:
+    from . import types
+    from ..types import (
+        app_command,
+        guild,
+        user
+    )
+    from ..enums import Locale
+    from ..utils import SupportsStr
+    
+    T = TypeVar('T')
+    Response = Coroutine[None, None, T]
+    
+
+__all__ = ('OAuth2HTTPClient',)
+
+_log = logging.getLogger(__name__)
+
+
+class OAuth2HTTPClient:
+    """
+    This class manages the async requests to the Discords OAuth2 API and manages ratelimiting automatically.
+    
+    """
+    SUCCESS_LOG = '{method} {url} has received {text}'
+    REQUEST_LOG = '{method} {url} with {json} has returned {status}'
+    
+    __session: aiohttp.ClientSession
+    
+    def __init__(
+            self,
+            client_id: int,
+            client_secret: str,
+            *,
+            connector=None,
+            proxy: Optional[str] = None,
+            proxy_auth: Optional[aiohttp.BasicAuth] = None,
+            loop: Optional[asyncio.AbstractEventLoop] = None,
+            unsync_clock: bool = True,
+            api_version: int = 10,
+            api_error_locale: Optional[Locale] = 'en-US'
+    ):
+        self.client_id: str = str(client_id)
+        self.__client_secret: str = client_secret
+        self.loop = loop
+        self.connector = connector
+        self._locks = weakref.WeakValueDictionary()
+        self._global_over = asyncio.Event()
+        self._global_over.set()
+        self.proxy = proxy
+        self.proxy_auth = proxy_auth
+        self.use_clock = not unsync_clock
+        self.api_version = api_version
+        self.api_error_locale = str(api_error_locale)
+        Route.BASE = f'https://discord.com/api/v{api_version}'
+    
+        user_agent = 'DiscordBot (https://github.com/mccoderpy/discord.py-message-components {0}) Python/{1[0]}.{1[1]} aiohttp/{2}'
+        self.user_agent = user_agent.format(__version__, sys.version_info, aiohttp.__version__)
+    
+    def start(self):
+        self.__session = aiohttp.ClientSession(connector=self.connector)
+    
+    def recreate(self):
+        if self.__session.closed:
+            self.__session = aiohttp.ClientSession(connector=self.connector)
+
+    async def request(
+            self,
+            route: Route,
+            *,
+            content_type: Optional[str] = None,
+            authorization: Optional[str] = None,
+            **kwargs
+    ) -> Any:
+        bucket = route.bucket
+        method = route.method
+        url = route.url
+    
+        lock = self._locks.get(bucket)
+        if lock is None:
+            lock = asyncio.Lock()
+            if bucket is not None:
+                self._locks[bucket] = lock
+    
+        # header creation
+        headers = {
+            'User-Agent': self.user_agent,
+            'X-Discord-Locale': self.api_error_locale
+        }
+        
+        if content_type:
+            headers['Content-Type'] = content_type
+        if authorization:
+            headers['Authorization'] = authorization
+        
+        # some checking if it's a JSON request
+        if 'json' in kwargs:
+            headers['Content-Type'] = 'application/json'
+            kwargs['data'] = to_json(kwargs.pop('json'))
+    
+        kwargs['headers'] = headers
+    
+        # Proxy support
+        if self.proxy is not None:
+            kwargs['proxy'] = self.proxy
+        if self.proxy_auth is not None:
+            kwargs['proxy_auth'] = self.proxy_auth
+    
+        if not self._global_over.is_set():
+            # wait until the global lock is complete
+            await self._global_over.wait()
+    
+        await lock.acquire()
+        with MaybeUnlock(lock) as maybe_lock:
+            for tries in range(5):
+                try:
+                    async with self.__session.request(method, url, **kwargs) as r:
+                        _log.debug('%s %s with %s has returned %s', method, url, kwargs.get('data'), r.status)
+                    
+                        # even errors have text involved in them so this is safe to call
+                        data = await json_or_text(r)
+                    
+                        # check if we have rate limit header information
+                        remaining = r.headers.get('X-Ratelimit-Remaining')
+                        if remaining == '0' and r.status != 429:
+                            # we've depleted our current bucket
+                            delta = _parse_ratelimit_header(r, use_clock=self.use_clock)
+                            _log.debug('A rate limit bucket has been exhausted (bucket: %s, retry: %s).', bucket, delta)
+                            maybe_lock.defer()
+                            self.loop.call_later(delta, lock.release)
+                    
+                        # the request was successful so just return the text/json
+                        if 300 > r.status >= 200:
+                            _log.debug('%s %s has received %s', method, url, data)
+                            return data
+                    
+                        # we are being rate limited
+                        if r.status == 429:
+                            if not r.headers.get('Via'):
+                                # Banned by Cloudflare more than likely.
+                                raise HTTPException(r, data)
+                        
+                            fmt = 'We are being rate limited. Retrying in %.2f seconds. Handled under the bucket "%s"'
+                        
+                            # sleep a bit
+                            retry_after = data['retry_after']
+                            _log.warning(fmt, retry_after, bucket)
+                        
+                            # check if it's a global rate limit
+                            is_global = data.get('global', False)
+                            if is_global:
+                                _log.warning('Global rate limit has been hit. Retrying in %.2f seconds.', retry_after)
+                                self._global_over.clear()
+                        
+                            await asyncio.sleep(retry_after)
+                            _log.debug('Done sleeping for the rate limit. Retrying...')
+                        
+                            # release the global lock now that the
+                            # global rate limit has passed
+                            if is_global:
+                                self._global_over.set()
+                                _log.debug('Global rate limit is now over.')
+                        
+                            continue
+                    
+                        # we've received a 500 or 502, unconditional retry
+                        if r.status in {500, 502}:
+                            await asyncio.sleep(1 + tries * 2)
+                            continue
+                    
+                        # the usual error cases
+                        if r.status == 401:
+                            raise Unauthorized(r, data)
+                        elif r.status == 403:
+                            raise Forbidden(r, data)
+                        elif r.status == 404:
+                            raise NotFound(r, data)
+                        elif r.status == 503:
+                            raise DiscordServerError(r, data)
+                        else:
+                            raise HTTPException(r, data)
+            
+                # This is handling exceptions from the request
+                except OSError as e:
+                    # Connection reset by peer
+                    if tries < 4 and e.errno in (54, 10054):
+                        continue
+                    raise
+        
+            # We've run out of retries, raise.
+            if r.status >= 500:
+                raise DiscordServerError(r, data)
+        
+            raise HTTPException(r, data)
+
+    # state management
+    async def close(self):
+        if self.__session:
+            await self.__session.close()
+            await asyncio.sleep(0.025)  # wait for the connection to be released
+    
+    async def get_from_cdn(self, url: str) -> bytes:
+        async with self.__session.get(url) as resp:
+            if resp.status == 200:
+                return await resp.read()
+            elif resp.status == 404:
+                raise NotFound(resp, 'asset not found')
+            elif resp.status == 403:
+                raise Forbidden(resp, 'cannot retrieve asset')
+            else:
+                raise HTTPException(resp, 'failed to get asset')
+    
+    def exchange_authorization_token(
+            self,
+            code: str,
+            redirect_uri: str
+    ) -> Response[types.AccessToken]:
+        r = Route('POST', '/oauth2/token')
+        data = {
+            'client_id': self.client_id,
+            'client_secret': self.__client_secret,
+            'grant_type': 'authorization_code',
+            'code': code,
+            'redirect_uri': redirect_uri
+        }
+        return self.request(
+            r,
+            data=data,
+            content_type='application/x-www-form-urlencoded'
+        )
+    
+    def exchange_client_credentials(self, scopes: List[SupportsStr]) -> Response[types.ClientCredentialsAccessToken]:
+        r = Route('POST', '/oauth2/token')
+        data = {
+            'grant_type': 'client_credentials',
+            'scope': ' '.join(str(s) for s in scopes)
+        }
+        return self.request(
+            r,
+            data=data,
+            content_type='application/x-www-form-urlencoded',
+            auth=aiohttp.BasicAuth(self.client_id, self.__client_secret)
+        )
+    
+    def exchange_refresh_token(self, refresh_token: str) -> Response[types.AccessToken]:
+        r = Route('POST', '/oauth2/token')
+        data = {
+            'client_id': self.client_id,
+            'client_secret': self.__client_secret,
+            'grant_type': 'refresh_token',
+            'refresh_token': refresh_token
+        }
+        return self.request(
+            r,
+            data=data,
+            content_type='application/x-www-form-urlencoded'
+        )
+    
+    def revoke_access_token(self, access_token: SupportsStr) -> Response[NoReturn]:
+        r = Route('POST', '/oauth2/token/revoke')
+        params = {
+            'token': str(access_token),
+            'token_type_hint': 'access_token'
+        }
+        return self.request(
+            r,
+            params=params,
+            authorization=f'Basic {self.__client_secret}',
+            content_type='application/x-www-form-urlencoded'
+        )
+    
+    def get_current_auth_info(self, access_token: SupportsStr) -> Coroutine[types.CurrentAuthorizationInfo]:
+        r = Route('GET', '/oauth2/@me')
+        return self.request(r, authorization=f'Bearer {access_token}')
+    
+    def get_user(self, access_token: SupportsStr) -> Response[types.User]:
+        r = Route('GET', '/users/@me')
+        return self.request(r, authorization=f'Bearer {access_token}')
+        
+    def get_user_guilds(
+            self,
+            access_token: SupportsStr,
+            *,
+            before: Optional[SupportsStr] = MISSING,
+            after: Optional[SupportsStr] = MISSING,
+            limit: Optional[int] = MISSING
+    ) -> Response[List[guild.PartialGuild]]:
+        r = Route('GET', '/users/@me/guilds')
+        
+        params = {}
+        if before is not MISSING:
+            params['before'] = str(before)
+        if after is not MISSING:
+            params['after'] = str(after)
+        if limit is not MISSING:
+            params['limit'] = limit
+        
+        return self.request(r, authorization=f'Bearer {access_token}', params=params)
+    
+    def get_user_guild_member(self, access_token: SupportsStr, guild_id: SupportsStr) -> Response[user.Member]:
+        r = Route('GET', '/users/@me/guilds/{guild_id}/member', guild_id=guild_id)
+        return self.request(r, authorization=f'Bearer {access_token}')
+    
+    def add_guild_member(
+            self,
+            access_token: SupportsStr,
+            bot_token: SupportsStr,
+            *,
+            guild_id: SupportsStr,
+            user_id: SupportsStr,
+            nick: Optional[SupportsStr] = MISSING,
+            roles: Optional[List[SupportsStr]] = MISSING,
+            mute: Optional[bool] = MISSING,
+            deaf: Optional[bool] = MISSING
+    ) -> Response[Union[user.Member, NoReturn]]:
+        r = Route('PUT', '/guilds/{guild_id}/members/{user_id}', guild_id=guild_id, user_id=user_id)
+        data = {
+            'access_token': str(access_token),
+        }
+        if nick is not MISSING:
+            data['nick'] = str(nick)
+        if roles is not MISSING:
+            data['roles'] = [str(r) for r in roles]
+        if mute is not MISSING:
+            data['mute'] = mute
+        if deaf is not MISSING:
+            data['deaf'] = deaf
+        
+        return self.request(r, authorization=f'Bot {bot_token}', json=data)
+    
+    def get_user_connections(self, access_token: SupportsStr) -> Response[List[types.Connection]]:
+        r = Route('GET', '/users/@me/connections')
+        return self.request(r, authorization=f'Bearer {access_token}')
+    
+    def get_user_application_role_connection(
+            self,
+            access_token: SupportsStr,
+            *,
+            application_id: Optional[SupportsStr] = None
+    ) -> Response[types.RoleConnection]:
+        r = Route('GET', '/users/@me/applications/{application_id}/role-connection', application_id=application_id or self.client_id)
+        return self.request(r, authorization=f'Bearer {access_token}')
+    
+    def update_user_application_role_connection(
+            self,
+            access_token: SupportsStr, *,
+            data: types.RoleConnection,
+            application_id: Optional[SupportsStr] = None
+    ) -> Response[types.RoleConnection]:
+        r = Route('PUT', '/users/@me/applications/{application_id}/role-connection', application_id=application_id or self.client_id)
+        return self.request(r, authorization=f'Bearer {access_token}', json=data)
+    
+    def get_all_application_command_permissions(
+            self,
+            access_token: SupportsStr, *,
+            guild_id: SupportsStr,
+            application_id: Optional[SupportsStr] = None
+    ) -> Response[List[app_command.GuildApplicationCommandPermissions]]:
+        r = Route(
+            'GET',
+            '/applications/{application_id}/guilds/{guild_id}/commands/permissions',
+            application_id=application_id or self.client_id,
+            guild_id=guild_id
+        )
+        return self.request(r, authorization=f'Bearer {access_token}')
+    
+    def get_application_command_permissions(
+            self,
+            access_token: SupportsStr, *,
+            guild_id: SupportsStr,
+            command_id: SupportsStr,
+            application_id: Optional[SupportsStr] = None
+    ) -> Response[app_command.GuildApplicationCommandPermissions]:
+        r = Route(
+            'GET',
+            '/applications/{application_id}/guilds/{guild_id}/commands/{command_id}/permissions',
+            application_id=application_id or self.client_id,
+            guild_id=guild_id,
+            command_id=command_id
+        )
+        return self.request(r, authorization=f'Bearer {access_token}')
+    
+    def update_application_command_permissions(
+            self,
+            access_token: SupportsStr, *,
+            application_id: SupportsStr,
+            guild_id: SupportsStr,
+            command_id: SupportsStr,
+            permissions: List[app_command.ApplicationCommandPermission]
+    ) -> Response[app_command.GuildApplicationCommandPermissions]:
+        r = Route(
+            'PUT',
+            '/applications/{application_id}/guilds/{guild_id}/commands/{command_id}/permissions',
+            application_id=application_id or self.client_id,
+            guild_id=guild_id,
+            command_id=command_id
+        )
+        data = {
+            'permissions': permissions
+        }
+        return self.request(r, authorization=f'Bearer {access_token}', json=data)
diff --git a/discord/oauth2/models.py b/discord/oauth2/models.py
new file mode 100644
index 00000000..6d2a04f3
--- /dev/null
+++ b/discord/oauth2/models.py
@@ -0,0 +1,1458 @@
+# -*- coding: utf-8 -*-
+
+"""
+The MIT License (MIT)
+
+Copyright (c) 2023-present mccoderpy
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+"""
+from __future__ import annotations
+
+from typing import (
+    Any,
+    Dict,
+    Iterable,
+    Optional,
+    overload,
+    Set,
+    Union,
+    List,
+    Type,
+    TYPE_CHECKING,
+    TypeVar
+)
+from typing_extensions import (
+    Self,
+    Literal
+)
+
+from datetime import (
+    datetime,
+    timedelta,
+    timezone
+)
+
+from ..mixins import Hashable
+from ..asset import Asset
+from ..enums import Locale, DefaultAvatar, PremiumType, IntegrationType, try_enum
+from ..flags import ApplicationFlags, PublicUserFlags, GuildMemberFlags
+from ..utils import (
+    cached_property,
+    utcnow,
+    snowflake_time,
+    SnowflakeList,
+    SupportsStr,
+    MISSING
+)
+from ..user import BaseUser, _BaseUser
+from ..member import flatten_user
+from ..permissions import Permissions
+from ..webhook import Webhook
+
+from .enums import OAuth2Scope, ConnectionService
+from .errors import (
+    AccessTokenNotRefreshable
+)
+
+if TYPE_CHECKING:
+    from ..types import (
+        user,
+        guild,
+        appinfo
+    )
+    from ..types.snowflake import SnowflakeID
+    from .client import OAuth2Client
+    from . import types
+
+
+T = TypeVar('T')
+DatetimeLike = Union[int, str, datetime]
+
+
+__all__ = (
+    'AccessToken',
+    'AccessTokenInfo',
+    'PartialAppInfo',
+    'User',
+    'PartialGuild',
+    'PartialGuildIntegration',
+    'PartialUser',
+    'GuildMember',
+    'Connection',
+    'RoleConnection'
+)
+
+
+def convert_to_datetime(value: DatetimeLike, /, from_delta: bool = False) -> datetime:
+    """
+    Converts the given value to an utc-aware :class:`~datetime.datetime` object:
+    
+    - If the value already is a :class:`~datetime.datetime` object it is returned instant
+    
+    - If the value is a :class:`int` / :class:`float` it is usually interpreted as an utc-aware POSIX timestamp -
+     if :attr:`from_delta` is :obj:`True` it will return :func:`~discord.utils.utcnow()` + :func:`~datetime.timedelta(seconds=value)`
+    
+    - If is a :class:`str` it will be interpreted as a ISO 8601 compatible timestamp
+    """
+    if isinstance(value, datetime):
+        return value
+    elif isinstance(value, (float, int)):
+        if from_delta:
+            return utcnow() + timedelta(seconds=value)
+        else:
+            return datetime.fromtimestamp(value, timezone.utc)
+    elif isinstance(value, str):
+        return datetime.fromisoformat(value)
+    
+
+class AccessToken:
+    """
+    A representation of a
+    `access token response <https://discord.com/developers/docs/topics/oauth2#authorization-code-grant-access-token-response>`_
+    from discord.
+    
+    This can be also used to store additional data that can be accessed through getitem.
+    
+    Attributes
+    -----------
+    additional_data: :class:`dict`
+        Additional data that was stored in the access token.
+    
+    
+    .. container:: operations
+        
+        .. describe:: x == y
+            
+            Checks if two access tokens are equal.
+        
+        .. describe:: x != y
+            
+            Checks if two access tokens are not equal.
+        
+        .. describe:: str(x)
+            
+            Returns the :attr:`~AccessToken.access_token` **Be careful where you use this!**
+        
+        .. describe:: x[key]
+            
+            Returns the additional data stored in the access token.
+        
+        .. describe:: x[key] = value
+            
+            Sets the additional data stored in the access token.
+        
+        .. describe:: del x[key]
+            
+            Deletes the additional data stored in the access token.
+        
+        .. describe:: key in x
+            
+            Checks if the given key is stored in the additional data.
+        
+        .. describe:: iter(x)
+            
+            Returns an iterator over the additional data.
+        
+        .. describe:: len(x)
+            
+            Returns the amount of additional data stored in the access token.
+    """
+    def __init__(
+            self,
+            client: OAuth2Client,
+            /,
+            access_token: str,
+            expires_at: DatetimeLike,
+            refresh_token: Optional[str] = None,
+            scopes: Iterable[str] = None,
+            **additional_data: Any,
+    ):
+        """
+        A representation of a
+        `access token response <https://discord.com/developers/docs/topics/oauth2#authorization-code-grant-access-token-response>`_
+        from discord.
+        
+        This can be also used to store additional data that can be accessed through get item.
+        
+        Parameters
+        -----------
+        client: :class:`OAuth2Client`
+            The client that created this access token
+        access_token: :class:`str`
+            The actual access token - this will also be returned when calling ``str(some_access_token)``
+        expires_at: Union[:class:`int`, :class:`str`, :class:`~datetime.datetime`]
+            When the access token will expire and needs to be refreshed.
+            In order to make it compatible with most of the database drivers it allows the following types
+            
+                - integers/floats (POSIX timestamp)
+                - strings (timestamps in any ISO 8601 format)
+                - :class:`~datetime.datetime` objects for the drivers that already convert it to a datetime object
+        refresh_token: Optional[:class:`str`]
+            The token that is required to request a new access token when the previous one expires.
+            This might be :obj:`None` depending on the grant type used
+        scopes: Iterable[:class:`str`]
+            A list of scopes the access token is authorized to
+        **additional_data
+            Additional data that should be stored as key=value pairs
+        """
+        self._client: OAuth2Client = client
+        self._access_token: str = access_token
+        self._expires_at: datetime = convert_to_datetime(expires_at)
+        self._refresh_token: Optional[str] = refresh_token
+        self._scopes: Set[str] = set(scopes)
+        self.additional_data: Dict[str, Any] = additional_data
+    
+    def __str__(self) -> str:
+        return self._access_token
+    
+    def __repr__(self) -> str:
+        return f'<{self.__class__.__name__} expires_at={self.expires_at.isoformat()} scopes={", ".join(str(s) for s in self.scopes)}>'
+    
+    def __getitem__(self, item: str) -> Any:
+        return self.additional_data.get(item)
+    
+    def __setitem__(self, key: str, value: Any):
+        self.additional_data[key] = value
+    
+    @property
+    def client(self) -> Optional[OAuth2Client]:
+        """
+        The :class:`~discord.oauth2.OAuth2Client` that manages this access token.
+        """
+        return self._client
+    
+    @client.setter
+    def client(self, value: OAuth2Client):
+        from .client import OAuth2Client  # avoid circular import
+        if not isinstance(value, OAuth2Client):
+            raise ValueError('Attribute client must be an instance of discord.oauth2.OAuth2Client')
+        self._client = value
+    
+    @property
+    def access_token(self) -> str:
+        """
+        The actual bearer access token.
+        
+        .. note::
+            Note that this might be expired, and you need to refresh the token first.
+            Use :meth:`is_expired` to check if it is expired.
+        """
+        return self._access_token
+    
+    @property
+    def expires_at(self) -> datetime:
+        """:class:`~datetime.datetime`: Wen the access token will expire"""
+        return self._expires_at
+    
+    @property
+    def refresh_token(self) -> Optional[str]:
+        """:class:`str`: The refresh token that is required to refresh the access token when it is expired"""
+        return self._refresh_token
+
+    @cached_property
+    def scopes(self) -> Set[OAuth2Scope]:
+        """
+        A set of :class:`~discord.oauth2.OAuth2Scope` that the access token is authorized to.
+        """
+        return {try_enum(OAuth2Scope, scope) for scope in self._scopes}
+    
+    @cached_property
+    def webhook(self) -> Optional[Webhook]:
+        """:class:`~discord.Webhook`: The webhook that was created with the webhook when the access token was authorized
+        with the :attr:`~OAuth2Scope.CREATE_WEBHOOK` scope. Only available on the original access token instance"""
+        return getattr(self, '_webhook', None)
+    
+    @property
+    def refreshable(self) -> bool:
+        """:class:`bool`: Whether the access token is refreshable. This checks if the :attr:`.refresh_token` is set"""
+        return self.refresh_token is not None
+    
+    def is_expired(self) -> bool:
+        """:class:`bool`: Whether the access token is expired. This just checks if the :attr:`~AccessToken.expires_at` is in the past"""
+        return utcnow() > self.expires_at
+    
+    @classmethod
+    def from_raw_data(cls, client: OAuth2Client, data: types.AccessToken) -> AccessToken:
+        """
+        Creates an :class:`~discord.oauth2.AccessToken` from raw data returned by discord.
+        
+        Parameters
+        -----------
+        client: :class:`~discord.oauth2.OAuth2Client`
+            The client that created this access token
+        data: :class:`AccessToken`
+            The raw data returned by discord
+        
+        Returns
+        --------
+        :class:`AccessToken`
+            The access token object
+        """
+        expires_at = convert_to_datetime(data.pop('expires_in'), from_delta=True)  # type: ignore
+        scopes = data.pop('scope', '').split(' ')  # type: ignore
+        base = cls(client, expires_at=expires_at, scopes=scopes, **data)
+        
+        try:
+            webhook = data.pop('webhook')
+        except KeyError:
+            pass
+        else:
+            base._webhook = Webhook.from_oauth2(webhook, client)
+        
+        return base
+    
+    def _update(self, data: types.AccessToken) -> Self:
+        self._access_token = data['access_token']
+        self._expires_at = convert_to_datetime(data['expires_in'], from_delta=True)
+        self._refresh_token = data['refresh_token']
+        return self
+    
+    def to_dict(self) -> Union[types.AccessTokenWithAbsoluteTime, types.ClientCredentialsAccessTokenWithAbsoluteTime]:
+        """
+        Converts the access token data to a dictionary.
+        
+        Structure of the dictionary:
+        
+        .. code-block:: python3
+        
+            {
+                'access_token': str,
+                'token_type': 'Bearer',
+                'expires_at': str,
+                'scopes': List[str],
+                'refresh_token': NotRequired[str]
+                'webhook_url': NotRequired[str]
+            }
+            
+        Example
+        -------
+        
+        .. code-block:: python3
+        
+            {
+                "access_token": "6qrZcUqja7812RVdnEKjpzOL4CvHBFG",
+                "token_type": "Bearer",
+                "expires_at": "2018-06-10T21:20:00+00:00",
+                "scopes": ["identify", "guilds"],
+                "refresh_token": "D43f5y0ahjqew82jZ4NViEr2YafMKhue"  # only available when refresh_token is set
+                "webhook_url": "https://discord.com/api/v10/webhooks/12345678910/T0kEn0fw3Bh00K"  # only available when webhook is set
+            }
+        
+        Returns
+        --------
+        Dict[:class:`str`, Any]
+            The access token data as a dictionary
+        """
+        base = {
+            'access_token': self.access_token,
+            'token_type': 'Bearer',
+            'expires_at': self.expires_at.isoformat(),
+            'scopes': list(self._scopes)
+        }
+        refresh_token = self.refresh_token
+        webhook = self.webhook
+        if refresh_token:
+            base['refresh_token'] = refresh_token
+        if webhook:
+            base['webhook_url'] = webhook.url
+        
+        return base
+        
+    async def refresh(self, *, force: bool = False) -> Self:
+        """|coro|
+        
+        Refreshes the access token when possible and returns the new one.
+        If the token is still valid it will instantly return it unless ``force`` is set.
+        This also updates the :attr:`expires_at` and :attr:`refresh_token`.
+        
+        .. note::
+            This is only available when :attr:`.client` and :attr:`refresh_token` is set
+        
+        Parameters
+        ----------
+        force: :class:`bool`
+            Whether to force-refresh the access token, even when :meth:`.is_expired` returns :obj:`False`
+        
+        Raises
+        ------
+        AttributeError
+            The client attribute is not set
+        :exc:`AccessTokenNotRefreshable`:
+            The access token is not refreshable
+        :exc:`InvalidRefreshToken`
+            The refresh token is invalid or has expired
+        
+        Returns
+        -------
+        :class:`str`:
+            The new access token
+        """
+        if not self.is_expired() and not force:
+            return self.access_token
+        
+        if not self.refresh_token:
+            raise AccessTokenNotRefreshable()
+        
+        client = self.client
+        if not client:
+            raise AttributeError('client attribute is not set so you can\'t call this from the access token directly')
+
+        return await self._client.refresh_access_token(self)
+    
+    async def revoke(self) -> None:
+        """|coro|
+        
+        Revokes the access token.
+        
+        For more details, see :meth:`.OAuth2Client.revoke_access_token`.
+        """
+        
+        client = self.client
+        if not client:
+            raise AttributeError('client attribute is not set so you can\'t call this from the access token directly')
+        
+        await self._client.revoke_access_token(self)
+
+    @overload
+    async def fetch_info(self) -> AccessTokenInfo: ...
+
+    @overload
+    async def fetch_info(self, *, raw: Literal[False]) -> AccessTokenInfo: ...
+
+    @overload
+    async def fetch_info(self, *, raw: Literal[True]) -> types.CurrentAuthorizationInfo: ...
+
+    async def fetch_info(
+            self,
+            *,
+            raw: Literal[True, False] = False
+    ) -> Union[AccessTokenInfo, types.CurrentAuthorizationInfo]:
+        """|coro|
+        
+        Fetches the authorization information for the access token.
+        
+        Fpr details, see :meth:`.OAuth2Client.fetch_access_token_info`.
+        """
+        return await self._client.fetch_access_token_info(self)
+    
+    @overload
+    async def fetch_user(self) -> User: ...
+    
+    @overload
+    async def fetch_user(self, *, raw: Literal[False]) -> User: ...
+
+    @overload
+    async def fetch_user(self, *, raw: Literal[True]) -> types.User: ...
+    
+    async def fetch_user(self, *, raw: Literal[True, False] = False) -> Union[User, types.User]:
+        """|coro|
+        
+        Fetches the user associated with the access token.
+        
+        For details, see :meth:`.OAuth2Client.fetch_user`.
+        """
+        return await self._client.fetch_user(self, raw=raw)
+    
+    @overload
+    async def fetch_guilds(self) -> List[PartialGuild]: ...
+    
+    @overload
+    async def fetch_guilds(self, *, raw: Literal[False]) -> List[PartialGuild]: ...
+    
+    @overload
+    async def fetch_guilds(self, *, raw: Literal[True]) -> List[guild.PartialGuild]: ...
+    
+    async def fetch_guilds(self, *, raw: Literal[True, False] = False) -> Union[List[PartialGuild], List[guild.PartialGuild]]:
+        """|coro|
+        
+        Fetches the guilds associated with the access token.
+        
+        For details, see :meth:`.OAuth2Client.fetch_guilds`.
+        """
+        return await self._client.fetch_guilds(self, raw=raw)
+    
+    @overload
+    async def fetch_guild_member(self, guild_id: SnowflakeID, /) -> GuildMember: ...
+    
+    @overload
+    async def fetch_guild_member(self, guild_id: SnowflakeID, /, *, raw: Literal[False]) -> GuildMember: ...
+    
+    @overload
+    async def fetch_guild_member(self, guild_id: SnowflakeID, /, *, raw: Literal[True]) -> user.Member: ...
+    
+    async def fetch_guild_member(self, guild_id: SnowflakeID, /, *, raw: Literal[True, False] = False) -> Union[GuildMember, user.Member]:
+        """|coro|
+        
+        Fetches the guild member of the current user in the guild. Requires the :attr:`OAuth2Scope.READ_GUILD_MEMBERS` scope.
+        
+        For details, see :meth:`.OAuth2Client.fetch_guild_member`.
+        """
+        return await self._client.fetch_guild_member(self, guild_id, raw=raw)
+    
+    @overload
+    async def add_guild_member(
+        self,
+        /, *,
+        bot_token: SupportsStr,
+        guild_id: SupportsStr,
+        user_id: SupportsStr,
+        nick: str = MISSING,
+        roles: List[SupportsStr] = MISSING,
+        mute: bool = MISSING,
+        deaf: bool = MISSING
+    ) -> GuildMember: ...
+    
+    @overload
+    async def add_guild_member(
+        self,
+        /, *,
+        bot_token: SupportsStr,
+        guild_id: SupportsStr,
+        user_id: SupportsStr,
+        nick: str = MISSING,
+        roles: List[SupportsStr] = MISSING,
+        mute: bool = MISSING,
+        deaf: bool = MISSING,
+        raw: Literal[False]
+    ) -> GuildMember: ...
+    
+    @overload
+    async def add_guild_member(
+        self,
+        /, *,
+        bot_token: SupportsStr,
+        guild_id: SupportsStr,
+        user_id: SupportsStr,
+        nick: str = MISSING,
+        roles: List[SupportsStr] = MISSING,
+        mute: bool = MISSING,
+        deaf: bool = MISSING,
+        raw: Literal[True]
+    ) -> user.Member: ...
+    
+    async def add_guild_member(
+        self,
+        /, *,
+        bot_token: SupportsStr,
+        guild_id: SupportsStr,
+        user_id: SupportsStr,
+        nick: str = MISSING,
+        roles: List[SupportsStr] = MISSING,
+        mute: bool = MISSING,
+        deaf: bool = MISSING,
+        raw: Literal[True, False] = False
+    ):
+        """|coro|
+        
+        Adds a user to a guild using their access token.
+        
+        For details, see :meth:`.OAuth2Client.add_guild_member`.
+        """
+        return await self._client.add_guild_member(
+            self,
+            bot_token=bot_token,
+            guild_id=guild_id,
+            user_id=user_id,
+            nick=nick,
+            roles=roles,
+            mute=mute,
+            deaf=deaf,
+            raw=raw
+        )
+    
+    @overload
+    async def fetch_connections(self, /) -> List[Connection]: ...
+    
+    @overload
+    async def fetch_connections(self, /, *, raw: Literal[False]) -> List[Connection]: ...
+    
+    @overload
+    async def fetch_connections(self, /, *, raw: Literal[True]) -> List[types.Connection]: ...
+    
+    async def fetch_connections(self, /, *, raw: Literal[True, False] = False) -> Union[List[Connection], List[types.Connection]]:
+        """|coro|
+        
+        Fetches the connections associated with the access token.
+        
+        For details, see :meth:`.OAuth2Client.fetch_connections`.
+        """
+        return await self._client.fetch_connections(self, raw=raw)
+    
+    @overload
+    async def fetch_user_app_role_connection(self, /) -> RoleConnection: ...
+    
+    @overload
+    async def fetch_user_app_role_connection(self, /, *, raw: Literal[False]) -> RoleConnection: ...
+    
+    @overload
+    async def fetch_user_app_role_connection(self, /, *, raw: Literal[True]) -> types.RoleConnection: ...
+    
+    async def fetch_user_app_role_connection(self, /, *, raw: Literal[True, False] = False) -> Union[RoleConnection, types.RoleConnection]:
+        """|coro|
+        
+        Fetches the application role connection associated with the access token.
+        
+        For details, see :meth:`.OAuth2Client.fetch_user_app_role_connection`.
+        """
+        return await self._client.fetch_user_app_role_connection(self, raw=raw)
+
+    @overload
+    async def update_user_app_role_connection(
+            self,
+            /, *,
+            platform_name: str = MISSING,
+            platform_username: str = MISSING,
+            metadata: Dict[str, str] = MISSING,
+            application_id: int = None
+    ) -> RoleConnection: ...
+    
+    @overload
+    async def update_user_app_role_connection(
+            self,
+            /, *,
+            platform_name: str = MISSING,
+            platform_username: str = MISSING,
+            metadata: Dict[str, str] = MISSING,
+            application_id: int = None,
+            raw: Literal[False]
+    ) -> RoleConnection: ...
+    
+    @overload
+    async def update_user_app_role_connection(
+            self,
+            /, *,
+            platform_name: str = MISSING,
+            platform_username: str = MISSING,
+            metadata: Dict[str, str] = MISSING,
+            application_id: int = None,
+            raw: Literal[True]
+    ) -> types.RoleConnection: ...
+    
+    async def update_user_app_role_connection(
+            self,
+            /, *,
+            platform_name: str = MISSING,
+            platform_username: str = MISSING,
+            metadata: Dict[str, str] = MISSING,
+            application_id: int = None,
+            raw: Literal[True, False] = False
+    ) -> Union[RoleConnection, types.RoleConnection]:
+        """|coro|
+        
+        Updates the application role connection associated with the access token.
+        
+        For details, see :meth:`.OAuth2Client.update_user_app_role_connection`.
+        """
+        return await self._client.update_user_app_role_connection(
+            self,
+            platform_name=platform_name,
+            platform_username=platform_username,
+            metadata=metadata,
+            application_id=application_id,
+            raw=raw
+        )
+
+
+class PartialAppInfo:
+    """Represents the application info for the bot provided by Discord.
+
+
+    Attributes
+    -------------
+    id: :class:`int`
+        The application ID.
+    name: :class:`str`
+        The application name.
+    icon: Optional[:class:`str`]
+        The icon hash, if it exists.
+    description: Optional[:class:`str`]
+        The application description.
+    bot_public: :class:`bool`
+        Whether the bot can be invited by anyone or if it is locked
+        to the application owner.
+    bot_require_code_grant: :class:`bool`
+        Whether the bot requires the completion of the full oauth2 code
+        grant flow to join.
+    verify_key: :class:`str`
+        The hex encoded key for verification in interactions and the
+        GameSDK's `GetTicket <https://discord.com/developers/docs/game-sdk/applications#getticket>`_.
+    """
+    
+    __slots__ = ('_client', 'description', 'id', 'name', 'bot_public', 'bot_require_code_grant', 'icon',
+                 'verify_key', 'custom_install_url', 'tags', '_flags', 'interactions_endpoint_url')
+    
+    def __init__(self, *, client: OAuth2Client, data: appinfo.PartialAppInfo) -> None:
+        self._client: OAuth2Client = client
+        self.id = int(data['id'])
+        self.name = data['name']
+        self.description = data['description']
+        self.icon = data['icon']
+        self.bot_public: bool = data['bot_public']
+        self.bot_require_code_grant: bool = data['bot_require_code_grant']
+        self.tags: List[str] = data.get('tags', [])
+        self._flags = data.get('flags', 0)
+        self.verify_key = data['verify_key']
+
+    def __repr__(self) -> str:
+        return f'<{self.__class__.__name__} id={self.id} name={self.name!r} description={self.description!r} ' \
+               f'public={self.bot_public}>'
+    
+    @property
+    def icon_url(self) -> Asset:
+        """:class:`~discord.Asset`: Retrieves the application's icon asset.
+
+        This is equivalent to calling :meth:`icon_url_as` with
+        the default parameters ('webp' format and a size of 1024).
+        """
+        return self.icon_url_as()
+    
+    def icon_url_as(
+            self,
+            *,
+            format: Literal['png', 'jpeg', 'jpg', 'webp'] = 'webp',
+            size=1024
+    ) -> Asset:
+        """Returns an :class:`~discord.Asset` for the icon the application has.
+
+        The format must be one of 'webp', 'jpeg', 'jpg' or 'png'.
+        The size must be a power of 2 between 16 and 4096.
+
+        Parameters
+        -----------
+        format: :class:`str`
+            The format to attempt to convert the icon to. Defaults to 'webp'.
+        size: :class:`int`
+            The size of the image to display.
+
+        Raises
+        ------
+        InvalidArgument
+            Bad image format passed to ``format`` or invalid ``size``.
+
+        Returns
+        --------
+        :class:`~discord.Asset`
+            The resulting CDN asset.
+        """
+        return Asset._from_icon(self._client, self, 'app', format=format, size=size)
+    
+    @property
+    def flags(self):
+        return ApplicationFlags._from_value(self._flags)
+
+
+class AccessTokenInfo:
+    """Represents the authorization information for an access token."""
+    __slots__ = ('_client', '_application', '_scopes', '_expires_at', '_user')
+    
+    def __init__(self, *, client: OAuth2Client, data: types.CurrentAuthorizationInfo):
+        self._client: OAuth2Client = client
+        self._application = data['application']
+        self._scopes = data['scopes']
+        self._expires_at = data['expires']
+        self._user = data['user']
+    
+    def __repr__(self) -> str:
+        return '<AccessTokenInfo app={0.application!r} scopes={0.scopes!r} expires_at={0.expires_at!r} user={0.user!r}>'.format(self)
+    
+    @property
+    def application(self) -> PartialAppInfo:
+        """:class:`~discord.oauth2.PartialAppInfo`: The application the access token is authorized for."""
+        return PartialAppInfo(client=self._client, data=self._application)
+    
+    @property
+    def scopes(self) -> Set[OAuth2Scope]:
+        """Set[:class:`~discord.oauth2.OAuth2Scope`]: A list of scopes the access token is authorized to."""
+        return {try_enum(OAuth2Scope, scope) for scope in self._scopes}
+    
+    @property
+    def expires_at(self) -> datetime:
+        """:class:`~datetime.datetime`: The time when the access token expires."""
+        return datetime.fromisoformat(self._expires_at)
+    
+    @property
+    def user(self) -> PartialUser:
+        """:class:`PartialUser`: The user associated with the access token."""
+        return PartialUser(client=self._client, data=self._user)
+    
+    def to_dict(self) -> types.CurrentAuthorizationInfo:
+        return {
+            'application': self._application,
+            'scopes': self._scopes,
+            'expires': self._expires_at,
+            'user': self._user,
+        }
+
+
+class PartialUser(_BaseUser):
+    """Represents a partial Discord User retrieved via an OAuth2 :class:`AccessToken`.
+
+    This
+
+    .. container:: operations
+        
+        .. describe:: x == y
+            Checks if two partial users are equal.
+        
+        .. describe:: x != y
+            Checks if two partial users are not equal.
+        
+        .. describe:: hash(x)
+            Returns the partial user's hash.
+        
+        .. describe:: str(x)
+            Returns the :attr:`username` if :attr:`is_migrated` is true, else the user's name with discriminator.
+
+            .. note::
+
+                When the migration is complete, this will always return the :attr:`username` .
+
+    .. versionadded:: 2.0
+
+    Attributes
+    -----------
+    id: :class:`int`
+        The user's ID.
+    username: :class:`str`
+        The user's username.
+    global_name: Optional[:class:`str`]
+        The users global name if set.
+        In the client UI this referred to as "Display Name".
+    discriminator: :class:`str`
+        The user's discriminator.
+
+        .. deprecated:: 2.0
+
+        .. important::
+            This will be removed in the future.
+            Read more about it :dis-gd:`here <usernames>`.
+    avatar: Optional[:class:`str`]
+        The user's avatar hash.
+    avatar_decoration: Optional[:class:`str`]
+        The user's avatar decoration hash.
+    """
+    def __init__(self, *, client: OAuth2Client, data: types.User):
+        self._client = client
+        self.id: int = int(data['id'])
+        self.username: str = data['username']
+        self.global_name: Optional[str] = data.get('global_name')
+        self.discriminator: str = data.get('discriminator')
+        self.avatar: str = data.get('avatar')
+        self.avatar_decoration: str = data.get('avatar_decoration')
+        self._public_flags: int = data.get('public_flags', 0)
+
+    def __str__(self) -> str:
+        return f'{self.username}' if self.is_migrated else f'{self.name}#{self.discriminator}'
+    
+    def __repr__(self) -> str:
+        return self.__str__()
+    
+    def __eq__(self, other: Any) -> bool:
+        return isinstance(other, _BaseUser) and other.id == self.id
+
+    def __ne__(self, other: Any) -> bool:
+        return not self.__eq__(other)
+
+    def __hash__(self) -> int:
+        return self.id >> 22
+
+    @property
+    def name(self) -> str:
+        """:class:`str`: This is an alias of :attr:`username` which replaces the previous `name` attribute.
+
+        .. note::
+            It is recommended to use :attr:`username` instead as this might be removed in the future.
+        """
+        return self.username
+
+    @property
+    def is_migrated(self) -> bool:
+        """:class:`bool`: Indicates if the user has migrated to the :dis-gd:`new username system <usernames>`."""
+        return self.discriminator == '0'
+
+    @property
+    def public_flags(self) -> PublicUserFlags:
+        """:class:`PublicUserFlags`: The available public flags the user has."""
+        return PublicUserFlags._from_value(self._public_flags)
+
+    @property
+    def mention(self) -> str:
+        """:class:`str`: Returns a string that allows you to mention the given user in discord."""
+        return f'<@{self.id}>'
+
+    @property
+    def display_name(self) -> str:
+        """:class:`str`: Returns the user's display name.
+
+        For regular users this is just their :attr:`global_name` if set else their :attr:`username`, but
+        if they have a guild specific nickname then that
+        is returned instead.
+        """
+        return self.global_name or self.username
+
+    @property
+    def created_at(self) -> datetime:
+        """:class:`~datetime.datetime`: Returns the user's creation time in UTC.
+
+        This is when the user's Discord account was created."""
+        return snowflake_time(self.id)
+    
+    @property
+    def avatar_url(self) -> Asset:
+        """:class:`~discord.Asset`: Returns an :class:`~discord.Asset` for the avatar the user has.
+
+        If the user does not have a traditional avatar, an asset for
+        the default avatar is returned instead.
+
+        This is equivalent to calling :meth:`avatar_url_as` with
+        the default parameters (i.e. webp/gif detection and a size of 1024).
+        """
+        return self.avatar_url_as(format=None, size=1024)
+
+    def is_avatar_animated(self) -> bool:
+        """:class:`bool`: Indicates if the user has an animated avatar."""
+        return bool(self.avatar and self.avatar.startswith('a_'))
+    
+    def avatar_url_as(
+            self,
+            *,
+            format: Optional[Literal['jpeg', 'jpg', 'webp', 'png', 'gif']] = None,
+            static_format: Literal['jpeg', 'jpg', 'webp', 'png'] = 'webp',
+            size=1024
+    ) -> Asset:
+        """Returns an :class:`~discord.Asset` for the avatar the user has.
+
+        If the user does not have a traditional avatar, an asset for
+        the default avatar is returned instead.
+
+        The format must be one of 'webp', 'jpeg', 'jpg', 'png' or 'gif', and
+        'gif' is only valid for animated avatars. The size must be a power of 2
+        between 16 and 4096.
+
+        Parameters
+        -----------
+        format: Optional[:class:`str`]
+            The format to attempt to convert the avatar to.
+            If the format is ``None``, then it is automatically
+            detected into either 'gif' or static_format depending on the
+            avatar being animated or not.
+        static_format: Optional[:class:`str`]
+            Format to attempt to convert only non-animated avatars to.
+            Defaults to 'webp'
+        size: :class:`int`
+            The size of the image to display.
+
+        Raises
+        ------
+        InvalidArgument
+            Bad image format passed to ``format`` or ``static_format``, or
+            invalid ``size``.
+
+        Returns
+        --------
+        :class:`~discord.Asset`
+            The resulting CDN asset.
+        """
+        return Asset._from_avatar(self._client, self, format=format, static_format=static_format, size=size)
+
+    @property
+    def default_avatar(self) -> DefaultAvatar:
+        """:class:`DefaultAvatar`: Returns the default avatar for a given user.
+        For non-migrated users this is calculated by the user's discriminator.
+        For :dis-gd:`migrated <usernames>` users this is calculated by the user's ID.
+        """
+        if self.is_migrated:
+            value = (self.id >> 22) % len(DefaultAvatar)
+        else:
+            value = int(self.discriminator) % len(DefaultAvatar)
+        return try_enum(DefaultAvatar, value)
+
+    @property
+    def default_avatar_url(self) -> Asset:
+        """:class:`~discord.Asset`: Returns a URL for a user's default avatar."""
+        return Asset(self._client, f'/embed/avatars/{self.default_avatar.value}.png')
+
+
+class User(BaseUser):
+    """Represents a full Discord user retrieved via an OAuth2 :class:`AccessToken`.
+    
+    .. note::
+        :attr:`~discord.oauth2.User.email` and :attr:`discord.oauth2.User.verified` are only present
+        if authorized with the :attr:`~OAuth2Scope.email`. Otherwise they are :obj:`MISSING`
+    
+    Attributes
+    -----------
+    id: :class:`int`
+        The user's ID.
+    username: :class:`str`
+        The user's username.
+    global_name: Optional[:class:`str`]
+        The users global name if set.
+        In the client UI this referred to as "Display Name".
+    discriminator: :class:`str`
+        The user's discriminator.
+
+        .. deprecated:: 2.0
+
+        .. important::
+            This will be removed in the future.
+            Read more about it :dis-gd:`here <usernames>`.
+    avatar: Optional[:class:`str`]
+        The user's avatar hash.
+    bot: :class:`bool`
+        Indicates if the user is a bot account. Should always be :obj:`False` as bots can't use OAuth2.
+    system: :class:`bool`
+        Indicates if the user is a system account.
+    mfa_enabled: :class:`bool`
+        Indicates if the user has MFA enabled on their account.
+    banner: Optional[:class:`str`]
+        The user's banner hash.
+    locale: Optional[:class:`~discord.Locale`]
+        The user's chosen language option.
+    verified: Optional[:class:`bool`]
+        Indicates if the email on this account has been verified.
+    email: Optional[:class:`str`]
+        The user's email.
+    premium_type: :class:`PremiumType`
+        The user's premium subscription type.
+    """
+    __slots__ = BaseUser.__slots__ + (
+        '_client', 'mfa_enabled', 'locale', 'verified', 'email', '_flags', 'premium_type',
+    )
+    
+    def __init__(self, *, client: OAuth2Client, data: types.User):
+        super().__init__(state=client, data=data)
+        self._client: OAuth2Client = client
+        self.mfa_enabled: bool = data.get('mfa_enabled', False)
+        self.locale: Locale = try_enum(Locale, data.get('locale', None))
+        email = data.get('email', MISSING)
+        self.email: str = email
+        self.verified: bool = data.get('verified', MISSING if email is MISSING else False)
+        self.premium_type: Optional[PremiumType] = try_enum(PremiumType, data.get('premium_type', None))
+        self._flags: int = data.get('flags', 0)
+
+
+    @property
+    def flags(self) -> PublicUserFlags:
+        """:class:`PublicUserFlags`: The available flags the user has. This might be the same as :attr:`public_flags`."""
+        return PublicUserFlags._from_value(self._flags)
+
+    @classmethod
+    def _copy(cls: Type[User], user: User) -> User:
+        return super()._copy(user)
+
+
+class PartialGuild(Hashable):
+    """
+    Represents a partial guild returned by the OAuth2 API.
+    
+    .. container:: operations
+        
+        .. describe:: x == y
+            
+            Checks if two partial guilds are equal.
+        
+        .. describe:: x != y
+            
+            Checks if two partial guilds are not equal.
+            
+        .. describe:: hash(x)
+            
+            Returns the partial guild's hash.
+        
+        .. describe:: str(x)
+            Returns the partial guild's name.
+            
+    Attributes
+    -----------
+    id: :class:`int`
+        The guild's ID.
+    name: :class:`str`
+        The guild's name.
+    features: List[:class:`str`]
+        The guild's features.
+    icon: Optional[:class:`str`]
+        The guild's icon hash.
+    owner: Optional[:class:`bool`]
+        Indicates if the user is the owner of the guild.
+    permissions: Optional[:class:`Permissions`]
+        The permissions the user has in the guild.
+    """
+    def __init__(self, *, client: OAuth2Client, data: guild.PartialGuild):
+        self._client: OAuth2Client = client
+        self.id: SnowflakeID = int(data['id'])
+        self.name: str = data['name']
+        self.features: List[str] = data.get('features', [])
+        self.icon: Optional[str] = data.get('icon', None)
+        self.owner: Optional[bool] = data.get('owner', False)
+        self.permissions: Optional[Permissions] = Permissions(int(data.get('permissions', 0)))
+    
+    def __str__(self) -> str:
+        return self.name
+    
+    def __repr__(self) -> str:
+        return '<PartialGuild id={0.id} name={0.name!r} features={0.features!r}>'.format(self)
+    
+    @property
+    def icon_url(self):
+        """:class:`~discord.Asset`: Returns the guild's icon asset."""
+        return self.icon_url_as()
+
+    def is_icon_animated(self):
+        """:class:`bool`: Returns True if the guild has an animated icon."""
+        return bool(self.icon and self.icon.startswith('a_'))
+
+    def icon_url_as(
+            self,
+            *,
+            format: Literal['webp', 'jpeg', 'jpg', 'png', 'gif'] = None,
+            static_format: Literal['jpeg', 'jpg', 'webp', 'png'] = 'webp',
+            size=1024
+    ):
+        """Returns an :class:`~discord.Asset` for the guild's icon.
+
+        The format must be one of 'webp', 'jpeg', 'jpg', 'png' or 'gif', and
+        'gif' is only valid for animated avatars. The size must be a power of 2
+        between 16 and 4096.
+
+        Parameters
+        -----------
+        format: Optional[:class:`str`]
+            The format to attempt to convert the icon to.
+            If the format is ``None``, then it is automatically
+            detected into either 'gif' or static_format depending on the
+            icon being animated or not.
+        static_format: Optional[:class:`str`]
+            Format to attempt to convert only non-animated icons to.
+        size: :class:`int`
+            The size of the image to display.
+
+        Raises
+        ------
+        InvalidArgument
+            Bad image format passed to ``format`` or invalid ``size``.
+
+        Returns
+        --------
+        :class:`~discord.Asset`
+            The resulting CDN asset.
+        """
+        return Asset._from_guild_icon(self._client, self, format=format, static_format=static_format, size=size)
+
+@flatten_user(PartialUser)
+class GuildMember(_BaseUser):
+    """Represents a member of a guild.
+
+    .. container:: operations
+
+        .. describe:: x == y
+
+            Checks if two members are equal.
+
+        .. describe:: x != y
+
+            Checks if two members are not equal.
+
+        .. describe:: hash(x)
+
+            Returns the member's hash.
+
+        .. describe:: str(x)
+
+            Returns the member's name with discriminator.
+
+    Attributes
+    -----------
+    id: :class:`int`
+        The member's ID.
+    joined_at: :class:`datetime.datetime`
+        When the member joined the guild.
+    deaf: :class:`bool`
+        Indicates if the member is deafened.
+    mute: :class:`bool`
+        Indicates if the member is muted.
+    pending: :class:`bool`
+        Indicates if the member is pending verification.
+    nick: Optional[:class:`str`]
+        The member's nickname. Could be ``None``.
+    guild_avatar: Optional[:class:`str`]
+        The member's guild-specific avatar hash. Could be ``None``.
+    premium_since: Optional[:class:`datetime.datetime`]
+        When the member started boosting the guild.
+    role_ids: :class:`~discord.utils.SnowflakeList`
+        A list of role ids for roles the member has.
+    """
+    __slots__ = (
+        '_client', 'id', 'guild', 'joined_at', 'deaf', 'mute', 'pending', 'nick', 'guild_avatar', 'premium_since',
+        '_user', 'role_ids', '_flags', '_communication_disabled_until'
+    )
+
+    if TYPE_CHECKING:
+        name: str
+        username: str
+        global_name: str
+        id: int
+        discriminator: str
+        bot: bool
+        system: bool
+        created_at: datetime
+        default_avatar: str
+        avatar: Optional[str]
+        public_flags: PublicUserFlags
+        banner: Optional[str]
+
+    def __init__(self, *, client: OAuth2Client, data: user.Member):
+        self._client: OAuth2Client = client
+        self.id: SnowflakeID = int(data['user']['id'])
+        self.joined_at: datetime = datetime.fromisoformat(data['joined_at'])
+        self.deaf: bool = data['deaf']
+        self.mute: bool = data['mute']
+        self.pending: bool = data.get('pending', False)
+        self.nick: Optional[str] = data.get('nick', None)
+        self.guild_avatar: Optional[str] = data.get('avatar', None)
+        self.premium_since: Optional[datetime] = datetime.fromisoformat(data['premium_since']) if data.get('premium_since') else None
+        self._user: PartialUser = PartialUser(client=client, data=data['user'])
+        self.role_ids: SnowflakeList = SnowflakeList(map(int, data.get('roles', [])))
+        self._flags = data.get('flags', 0)
+        self._communication_disabled_until: Optional[str] = data.get('communication_disabled_until', None)
+
+    def __str__(self):
+        return str(self._user)
+    
+    def __repr__(self) -> str:
+        user = self._user
+        if not user.is_migrated:
+            return f'<GuildMember id={user.id} username={user.username!r} global_name={user.global_name} ' \
+                   f'discriminator={user.discriminator!r} nick={self.nick!r} guild={self.guild!r}>'
+        return f'<GuildMember id={user.id} username={user.username!r} global_name={user.global_name} ' \
+               f'nick={self.nick!r} guild={self.guild!r}>'
+
+    def __eq__(self, other: Any) -> bool:
+        return isinstance(other, _BaseUser) and other.id == self.id
+
+    def __ne__(self, other: Any) -> bool:
+        return not self.__eq__(other)
+
+    def __hash__(self) -> int:
+        return hash(self._user)
+
+    @property
+    def flags(self) -> GuildMemberFlags:
+        """:class:`GuildMemberFlags`: Guild specific flags for the member."""
+        return GuildMemberFlags._from_value(self._flags)
+    
+    @property
+    def mention(self) -> str:
+        """:class:`str`: Returns a string that allows you to mention the member in discord."""
+        return f'<@{self.id}>'
+    
+    @property
+    def display_name(self) -> str:
+        """:class:`str`: Returns the user's display name.
+
+        For regular users this is just their username, but
+        if they have a guild specific nickname then that
+        is returned instead.
+        """
+        return self.nick or self._user.display_name
+    
+    @property
+    def communication_disabled_until(self) -> Optional[datetime]:
+        """Optional[:class:`datetime.datetime`]: The time until the member is timeouted, if any"""
+        return datetime.fromisoformat(self._communication_disabled_until) if self._communication_disabled_until else None
+
+    @property
+    def guild_avatar_url(self) -> Optional[Asset]:
+        """Optional[:class:`~discord.Asset`]: Returns the guild-specific banner asset for the member if any."""
+        return self.guild_avatar_url_as()
+
+    def guild_avatar_url_as(
+        self,
+        *,
+        format: Optional[Literal['jpeg', 'jpg', 'webp', 'png', 'gif']] = None,
+        static_format: Literal['jpeg', 'jpg', 'webp', 'png'] = 'webp',
+        size: int = 1024
+    ) -> Optional[Asset]:
+        """Returns an :class:`~discord.Asset` for the guild-specific avatar of the member if any, else :obj:`None`.
+    
+        The format must be one of 'webp', 'jpeg', or 'png'. The
+        size must be a power of 2 between 16 and 4096.
+    
+        Parameters
+        -----------
+        format: :class:`str`
+            The format to attempt to convert the avatar to.
+        static_format: Optional[:class:`str`]
+            Format to attempt to convert only non-animated avatars to.
+        size: :class:`int`
+            The size of the image to display.
+    
+        Raises
+        ------
+        InvalidArgument
+            Bad image format passed to ``format`` or invalid ``size``.
+    
+        Returns
+        --------
+        Optional[:class:`~discord.Asset`]
+            The resulting CDN asset if any.
+        """
+        if self.guild_avatar:
+            return Asset._from_guild_avatar(self._client, self, static_format=static_format, format=format, size=size)
+
+    def is_guild_avatar_animated(self):
+        """:class:`bool`: Indicates if the member has an animated guild-avatar."""
+        return bool(self.guild_avatar and self.guild_avatar.startswith('a_'))
+
+    @property
+    def display_avatar_url(self) -> Asset:
+        """:class:`~discord.Asset`: Returns the guild-specific avatar asset for the member if he has one, else the default avatar asset"""
+        return self.guild_avatar_url or self._user.avatar_url
+
+    def display_avatar_url_as(
+        self,
+        format: Optional[Literal['jpeg', 'jpg', 'webp', 'png', 'gif']] = None,
+        static_format: Literal['jpeg', 'jpg', 'webp', 'png'] = 'webp',
+        size: int = 1024
+    ) -> Optional[Asset]:
+        """
+        Same behaviour as :meth:`~discord.oauth2.User.avatar_url_as` and :meth:`~discord.oauth2.GuildMember.guild_avatar_url_as`
+        but it prefers the guild-specific avatar
+        
+        Returns
+        --------
+        :class:`~discord.Asset`:
+            The resulting CDN asset for the avatar
+        """
+        if self.guild_avatar:
+            return self.guild_avatar_url_as(format=format, static_format=static_format, size=size)
+        return self._user.avatar_url_as(format=format, static_format=static_format, size=size)
+
+
+class PartialGuildIntegration:
+    """Represents a partial integration in a guild."""
+    def __init__(self, *, data):
+        self.id: int = int(data['id'])
+        self.name: str = data['name']
+        self.type: IntegrationType = try_enum(IntegrationType, data['type'])
+        self.enabled: bool = data['enabled']
+        self.syncing: bool = data['syncing']
+        self.role_id: Optional[int] = int(data['role_id']) if data['role_id'] else None
+        self.expire_behavior = data['expire_behavior']
+        self.expire_grace_period = data['expire_grace_period']
+        self.account = data['account']
+        self.synced_at: datetime = datetime.fromisoformat(data['synced_at'])
+
+
+class Connection:
+    """Represents a connection of a user to a service.
+
+    .. container:: operations
+
+        .. describe:: str(x)
+
+            Returns the connection's name.
+
+    Attributes
+    -----------
+    id: :class:`str`
+        The connection id.
+    name: :class:`str`
+        The connection's name.
+    type: :class:`str`
+        The connection's type.
+    revoked: :class:`bool`
+        Indicates if the connection is revoked.
+    verified: :class:`bool`
+        Indicates if the connection is verified.
+    friend_sync: :class:`bool`
+        Indicates if the connection is syncing friends.
+    show_activity: :class:`bool`
+        Indicates if the connection is showing activity.
+    visibility: :class:`int`
+        The visibility of the connection.
+    """
+
+    __slots__ = (
+        '_client', 'id', 'name', 'type', 'revoked', '_integrations', 'verified', 'friend_sync', 'show_activity', 'visibility'
+    )
+
+    def __init__(self, *, client: OAuth2Client, data: types.Connection):
+        self._client: OAuth2Client = client
+        self.id: str = data['id']
+        self.name: str = data['name']
+        self.type: ConnectionService = try_enum(ConnectionService, data['type'])
+        self.revoked: bool = data.get('revoked', False)
+        self._integrations: List[types.PartialGuildIntegration] = data.get('integrations', [])
+        self.verified: bool = data['verified']
+        self.friend_sync: bool = data['friend_sync']
+        self.show_activity: bool = data['show_activity']
+        self.visibility: int = data['visibility']
+
+    def __repr__(self):
+        return '<Connection type={0.type!r} name={0.name!r} id={0.id}>'.format(self)
+    
+    @property
+    def integrations(self) -> List[PartialGuildIntegration]:
+        """List[:class:`Integration`]: A list of partial guild integrations for the connection."""
+        return [PartialGuildIntegration(data=i) for i in self._integrations]
+    
+    def get_platform_user_url(self) -> Optional[str]:
+        """Optional[:class:`str`]: Returns the platform user url for the connection if available."""
+        
+        connection_type = str(self.type)
+        
+        if connection_type == 'twitch':
+            return f'https://www.twitch.tv/{self.name}'
+        elif connection_type == 'youtube':
+            return f'https://www.youtube.com/channel/{self.id}'
+        elif connection_type == 'github':
+            return f'https://github.com/{self.name}'
+        elif connection_type == 'instagram':
+            return f'https://www.instagram.com/{self.name}/'
+        elif connection_type == 'skype':
+            return f'https://www.skype.com/{self.name}'
+        elif connection_type == 'tiktok':
+            return f'https://www.tiktok.com/{self.name}'
+        elif connection_type == 'twitter':
+            return f'https://twitter.com/{self.name}'
+        elif connection_type == 'reddit':
+            return f'https://www.reddit.com/user/{self.name}'
+        elif connection_type == 'steam':
+            return f'https://steamcommunity.com/profiles/{self.id}'
+        elif connection_type == 'xbox':
+            return f'https://account.xbox.com/en-US/Profile?Gamertag={self.name}'
+        elif connection_type == 'spotify':
+            return f'https://open.spotify.com/user/{self.id}'
+        elif connection_type == 'ebay':
+            return f'https://www.ebay.com/usr/{self.name}'
+        return None
+
+
+class RoleConnection:
+    def __init__(self, *, data: types.RoleConnection):
+        self.platform_name: Optional[str] = data['platform_name']
+        self.platform_username: Optional[str] = data['platform_username']
+        self.metadata: Dict[str, str] = data['metadata']
+    
+    def __repr__(self):
+        return '<RoleConnection platform={0.platform_name!r} username={0.platform_username!r}>'.format(self)
+
+
diff --git a/discord/oauth2/server.py b/discord/oauth2/server.py
new file mode 100644
index 00000000..bff5a1a0
--- /dev/null
+++ b/discord/oauth2/server.py
@@ -0,0 +1,447 @@
+# -*- coding: utf-8 -*-
+
+"""
+The MIT License (MIT)
+
+Copyright (c) 2023-present mccoderpy
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+"""
+from __future__ import annotations
+
+import asyncio
+import logging
+import signal
+import sys
+from typing import (
+    Iterable,
+    List,
+    Optional,
+    TYPE_CHECKING,
+    Union
+)
+from urllib.parse import quote as _uriquote
+from uuid import uuid4
+
+import aiohttp.web as web
+
+from .client import AccessTokenStore, OAuth2Client
+
+if TYPE_CHECKING:
+    from .enums import OAuth2Scope
+    from .models import (
+        AccessToken,
+    )
+
+__all__ = (
+    'BasicOAuth2Server',
+)
+
+_log = logging.getLogger(__name__)
+
+
+def _cancel_tasks(loop):
+    try:
+        task_retriever = asyncio.Task.all_tasks
+    except AttributeError:
+        # future proofing for 3.9 I guess
+        task_retriever = asyncio.all_tasks
+
+    tasks = {t for t in task_retriever(loop=loop) if not t.done()}
+
+    if not tasks:
+        return
+
+    _log.info('Cleaning up after %d tasks.', len(tasks))
+    for task in tasks:
+        task.cancel()
+
+    loop.run_until_complete(asyncio.gather(*tasks, return_exceptions=True))
+    _log.info('All tasks finished cancelling.')
+
+    for task in tasks:
+        if task.cancelled():
+            continue
+        if task.exception() is not None:
+            loop.call_exception_handler({
+                'message': 'Unhandled exception during OAuth2Client.run shutdown.',
+                'exception': task.exception(),
+                'task': task
+            })
+
+
+def _cleanup_loop(loop):
+    try:
+        _cancel_tasks(loop)
+        if sys.version_info >= (3, 6):
+            loop.run_until_complete(loop.shutdown_asyncgens())
+    finally:
+        _log.info('Closing the event loop.')
+        loop.close()
+
+
+class BasicOAuth2Server(web.Application):
+    """
+    A basic server for handling OAuth2 authorization.
+    
+    This has the following endpoints by default:
+    
+    - ``/authorize`` - The authorization endpoint. Will redirect to the Discord OAuth2 page with the given scopes.
+    - ``/callback`` - The callback endpoint  (redirect_uri). Will exchange the code returned by discord for an access token.
+    
+    You can add your own endpoints by using the :meth:`~aiohttp.web.Application.add_routes` method.
+    
+    .. note::
+        
+        You don't need to use this, you can use any web framework you want.
+    
+    Example
+    -------
+    
+    .. code-block:: python3
+    
+        import json
+        import aiofiles
+        import discord.oauth2 as oauth2
+        
+        
+        class MyAccessTokenStore(oauth2.AccessTokenStore):
+            ...
+        
+        
+        server = MyOAuth2Server(
+            CLIENT_ID,
+            CLIENT_SECRET,
+            access_token_store=MyAccessTokenStore(),
+            scopes=[
+                OAuth2Scope.IDENTIFY,
+                OAuth2Scope.ACCESS_EMAIL,
+                OAuth2Scope.ACCESS_GUILDS,
+                OAuth2Scope.CONNECTIONS,
+                OAuth2Scope.READ_GUILDS_MEMBERS,
+                OAuth2Scope.WRITE_ROLE_CONNECTIONS
+            ],
+            redirect_uri="https://auth.example.com/discord-oauth2/callback",
+            base_path='/discord-oauth2'
+        )
+        
+        ssl_context = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH)
+        ssl_context.load_cert_chain('cert.pem', 'key.pem')
+        
+        server.run(host='auth.example.com', port=443, ssl_context=ssl_context, ...)
+        
+    
+    """
+    def __init__(
+        self,
+        client_id: int,
+        client_secret: str,
+        access_token_store: Optional[AccessTokenStore] = AccessTokenStore(),
+        *,
+        scopes: List[OAuth2Scope] = ['identify'],
+        redirect_uri: str,
+        state_required: bool = True,
+        base_path: str = '',
+        **kwargs
+    ):
+        """
+        A basic server for handling OAuth2 authorization.
+        
+
+        Parameters
+        ----------
+        client_id: :class:`int`
+            The client ID of your application.
+        client_secret: :class:`str`
+            The client secret of your application.
+        access_token_store: :class:`AccessTokenStore`
+            The access token store to use.
+        scopes: List[:class:`OAuth2Scope`]
+            The scopes to request.
+        redirect_uri: :class:`str`
+            The redirect URI to use.
+        state_required: :class:`bool`
+            Whether the state parameter is required.
+        base_path: :class:`str`
+            The base path to use for the routes.
+        **kwargs
+            Keyword arguments to pass to :class:`~aiohttp.web.Application`.
+        """
+        super().__init__(**kwargs)
+        self.client_id: int = client_id
+        self.oauth2_client = OAuth2Client(
+            client_id,
+            client_secret,
+            access_token_store
+        )
+        self.scopes: List[str] = [str(scope) for scope in scopes]
+        self.redirect_uri = redirect_uri
+        self.auth_url = f'https://discord.com/oauth2/authorize?response_type=code&client_id={client_id}&redirect_uri={_uriquote(redirect_uri)}&scope={"%20".join(self.scopes)}'
+        self.state_required = state_required
+        self.router.add_get(f'{base_path}/authorize', self.authorize)
+        self.router.add_get(f'{base_path}/callback', self.callback)
+        
+        self._states: List[str] = []
+    
+    async def store_state(self, request: web.Request, state: str) -> None:
+        """
+        Stores the ``state`` created in :meth:`~BasicOAuth2Server.create_state`.
+        
+        By default, this will store the state in a list.
+        
+        Parameters
+        ----------
+        request: :class:`aiohttp.web.Request`
+            The request that is being handled.
+        state: :class:`str`
+            The ``state`` to store.
+        """
+        self._states.append(state)
+    
+    async def create_state(self, request: web.Request) -> str:
+        """
+        Creates a ``state`` to use for the authorization endpoint and stores it using :meth:`~BasicOAuth2Server.store_state`.
+        
+        By default, this will return a random UUID4.
+        
+        Parameters
+        ----------
+        request: :class:`aiohttp.web.Request`
+            The request that is being handled.
+        
+        Returns
+        -------
+        :class:`str`
+            The ``state`` to use.
+        """
+        state = uuid4().hex
+        await self.store_state(request, state)
+        return state
+    
+    async def check_state(self, request: web.Request, state: str) -> bool:
+        """
+        Checks if the ``state`` is valid.
+        
+        By default, this will trys to remove the ``state`` from the list of stored states - if it succeeds, it is valid.
+        
+        Parameters
+        ----------
+        request: :class:`aiohttp.web.Request`
+            The request that is being handled.
+        state: :class:`str`
+            The ``state`` to check.
+        
+        Returns
+        -------
+        :class:`bool`
+            Whether the ``state`` is valid.
+        """
+        try:
+            self._states.remove(state)
+        except ValueError:
+            return False
+        else:
+            return True
+    
+    async def authorize(self, request: web.Request) -> Union[web.HTTPFound, web.HTTPBadRequest]:
+        """
+        The authorization endpoint.
+        
+        By default, this will redirect to the Discord OAuth2 page with the :attr:`~BasicOAuth2Server.scopes` given.
+        
+        .. note::
+            The ``state`` this redirects to Discord with is generated by :meth:`~BasicOAuth2Server.create_state`.
+            However, you can override this method to change how the state is generated. By default, it is a random UUID4.
+        
+        Parameters
+        ----------
+        request: :class:`~aiohttp.web.Request`
+            The request to the authorization endpoint.
+        
+        Returns
+        -------
+        Union[:class:`~aiohttp.web.HTTPFound`, :class:`~aiohttp.web.HTTPBadRequest`]
+            The redirect to Discord, or a bad request if the ``state`` is invalid.
+        """
+        if self.state_required:
+            state = await self.create_state(request)
+            return web.HTTPFound(self.auth_url + f'&state={state}')
+        else:
+            return web.HTTPFound(self.auth_url)
+        
+    async def callback(self, request: web.Request) -> web.Response:
+        """
+        The callback endpoint.
+        
+        By default, this will exchange the code returned by Discord for an access token.
+        
+        .. note::
+            The ``state`` this checks using :meth:`~BasicOAuth2Server.check_state` is generated by :meth:`~BasicOAuth2Server.create_state`.
+        
+        When the user has successfully authorized,
+        :meth:`~BasicOAuth2Server.successfully_authorized_response` is called, and it's return value is returned.
+        
+        Parameters
+        ----------
+        request: :class:`~aiohttp.web.Request`
+            The request from discords redirect containing the code and if set the ``state``.
+        
+        Returns
+        -------
+        :class:`~aiohttp.web.Response`
+            The response to send to the user.
+        """
+        try:
+            code = request.query.get('code')
+        except KeyError:
+            return web.HTTPBadRequest()
+        else:
+            if self.state_required:
+                try:
+                    state = request.query.get('state')
+                except KeyError:
+                    return web.HTTPBadRequest(text='Missing state')
+                else:
+                    state_ok = await self.check_state(request, state)
+                    if not state_ok:
+                        return web.HTTPBadRequest(text='State mismatch')
+            access_token = await self.oauth2_client.authorize(code, self.redirect_uri)
+            return await self.successfully_authorized_response(request, access_token)
+    
+    async def successfully_authorized_response(self, request: web.Request, access_token: AccessToken) -> web.Response:
+        """|coro|
+        The response to send when the user has successfully authorized.
+        
+        Parameters
+        ----------
+        request: :class:`~aiohttp.web.Request`
+            The request to the callback endpoint.
+        access_token: :class:`AccessToken`
+            The access token.
+        
+        Returns
+        -------
+        :class:`~aiohttp.web.Response`
+            The response to send to the user.
+        """
+        if 'identify' in access_token.scopes:
+            user = await access_token.fetch_user()
+        else:
+            user = None
+        template = """
+        <!DOCTYPE html>
+        <html lang="en">
+    <head>
+        <meta charset="UTF-8">
+        <meta name="color-scheme" content="light dark">
+        <title>Successfully authorized!</title>
+        <style>
+            .dark-mode {
+                background-color: #36393f;
+                color: white;
+            }
+
+            .light-mode {
+                background-color: white;
+                color: black;
+            }
+
+            @media (prefers-color-scheme: dark) {
+                body {
+                    background-color: #36393f;
+                    color: white;
+                }
+            }
+        </style>
+    </head>
+    <body style="background-color: #36393f; font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; color: white; text-align: center;">
+        <h1>Successfully authorized{{ user }}!</h1>
+        <p>You can now close this page</p>
+    </body>
+</html>
+"""
+        return web.HTTPOk(text=template.replace('{{ user }}', f' as {str(user)}' if user else ''), content_type='text/html')
+    
+    def run(
+        self,
+        *,
+        host: Union[str, Iterable[str]],
+        port: Optional[int] = None,
+        loop: Optional[asyncio.AbstractEventLoop] = None,
+        **kwargs
+    ):
+        """
+        Runs the server.
+        
+        .. important::
+        
+            This method is blocking. If you want to run it in a non-blocking way - for example from a bot - use :meth:`run_async` instead.
+        
+        Parameters
+        ----------
+        host: Union[:class:`str`, Iterable[:class:`str`]]
+            The host to run the server on.
+        port: Optional[:class:`int`]
+            The port to run the server on.
+        loop: Optional[:class:`~asyncio.AbstractEventLoop`]
+            The event loop to use.
+        **kwargs
+            Keyword arguments to pass to :meth:`aiohttp.web.run_app`.
+        """
+        if not loop:
+            try:
+                loop = asyncio.get_running_loop()
+            except RuntimeError:
+                loop = asyncio.new_event_loop()
+                asyncio.set_event_loop(loop)
+    
+        try:
+            loop.add_signal_handler(signal.SIGINT, lambda: loop.stop())
+            loop.add_signal_handler(signal.SIGTERM, lambda: loop.stop())
+        except NotImplementedError:
+            pass
+    
+        async def runner():
+            try:
+                await self.oauth2_client.start()
+                await web._run_app(self, host=host, port=port, **kwargs)
+            finally:
+                await self.oauth2_client.close()
+    
+        def stop_loop_on_completion(_):
+            loop.stop()
+    
+        future = asyncio.ensure_future(runner(), loop=loop)
+        future.add_done_callback(stop_loop_on_completion)
+        try:
+            loop.run_forever()
+        except KeyboardInterrupt:
+            _log.info('Received signal to close the event loop.')
+        finally:
+            future.remove_done_callback(stop_loop_on_completion)
+            _log.info('Cleaning up tasks.')
+            _cleanup_loop(loop)
+    
+        if not future.cancelled():
+            try:
+                return future.result()
+            except KeyboardInterrupt:
+                # I am unsure why this gets raised here but suppress it anyway
+                return None
+        
\ No newline at end of file
diff --git a/discord/oauth2/types.py b/discord/oauth2/types.py
new file mode 100644
index 00000000..61549e35
--- /dev/null
+++ b/discord/oauth2/types.py
@@ -0,0 +1,169 @@
+# -*- coding: utf-8 -*-
+
+"""
+The MIT License (MIT)
+
+Copyright (c) 2021-present mccoderpy
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+"""
+from __future__ import annotations
+
+from typing import (
+    Dict,
+    List,
+    Optional
+)
+
+from typing_extensions import (
+    Literal,
+    NotRequired,
+    TypedDict
+)
+
+from discord.types import (
+    appinfo,
+    integration,
+    user,
+    webhook
+)
+
+
+__all__ = (
+    'AccessToken',
+    'AccessTokenWithAbsoluteTime',
+    'ClientCredentialsAccessToken',
+    'ClientCredentialsAccessTokenWithAbsoluteTime',
+    'Connection',
+    'ConnectionService',
+    'CurrentAuthorizationInfo',
+    'IntegrationAccount',
+    'PartialUser',
+    'PartialGuildIntegration',
+    'RoleConnection',
+    'User'
+)
+
+
+VisibilityType = Literal[0, 1]
+ConnectionService = Literal[
+    'battlenet',
+    'crunchyroll',
+    'ebay',
+    'epicgames',
+    'facebook',
+    'github',
+    'instagram',
+    'leagueoflegends',
+    'paypal',
+    'playstation',
+    'reddit',
+    'riotgames',
+    'spotify',
+    'skype',
+    'steam',
+    'tiktok',
+    'twitch',
+    'twitter',
+    'xbox',
+    'youtube'
+]
+PremiumType = Literal[0, 1, 2, 3]
+RoleConnectionMetadataType = Literal[1, 2, 3, 4, 5, 6, 7, 8]
+
+
+class _AccessToken(TypedDict):
+    access_token: str
+    token_type: str
+
+
+class AccessToken(_AccessToken):
+    refresh_token: str
+    expires_in: int
+    scope: str
+    webhook: NotRequired[webhook.Webhook]
+
+
+class AccessTokenWithAbsoluteTime(_AccessToken):
+    refresh_token: str
+    expires_at: str
+    scopes: List[str]
+    webhook_url: NotRequired[str]
+
+
+class ClientCredentialsAccessToken(_AccessToken):
+    expires_in: int
+    scope: str
+    webhook: NotRequired[webhook.Webhook]
+
+
+class ClientCredentialsAccessTokenWithAbsoluteTime(_AccessToken):
+    expires_at: str
+    scopes: List[str]
+    webhook_url: NotRequired[str]
+
+
+class PartialUser(user.BaseUser):
+    avatar_decoration: Optional[str]
+    public_flags: NotRequired[int]
+
+
+class User(user.User):
+    mfa_enabled: NotRequired[bool]
+    locale: NotRequired[str]
+    verified: NotRequired[bool]
+    email: NotRequired[Optional[str]]
+    flags: NotRequired[int]
+    premium_type: PremiumType
+
+
+class CurrentAuthorizationInfo(TypedDict):
+    application: appinfo.PartialAppInfo
+    scopes: List[str]
+    expires: str
+    user: NotRequired[PartialUser]
+
+
+class IntegrationAccount(TypedDict):
+    id: str
+    name: str
+
+
+class PartialGuildIntegration(TypedDict):
+    pass
+    # TODO: Find out the structure of this
+
+
+class Connection(TypedDict):
+    id: str
+    name: str
+    type: ConnectionService
+    revoked: NotRequired[bool]
+    integrations: NotRequired[List[integration.PartialIntegration]]
+    verified: bool
+    friend_sync: bool
+    show_activity: bool
+    two_way_link: bool
+    visibility: int
+
+
+class RoleConnection(TypedDict):
+    platform_name: Optional[str]
+    platform_username: Optional[str]
+    metadata: Dict[str, str]
diff --git a/discord/object.py b/discord/object.py
index d349caa3..76b2faaf 100644
--- a/discord/object.py
+++ b/discord/object.py
@@ -3,7 +3,7 @@
 """
 The MIT License (MIT)
 
-Copyright (c) 2015-present Rapptz
+Copyright (c) 2015-2021 Rapptz & (c) 2021-present mccoderpy
 
 Permission is hereby granted, free of charge, to any person obtaining a
 copy of this software and associated documentation files (the "Software"),
@@ -24,9 +24,33 @@
 DEALINGS IN THE SOFTWARE.
 """
 
+from __future__ import annotations
+
+from typing import (
+    Any,
+    Type,
+    Optional,
+    TYPE_CHECKING
+)
+
+if TYPE_CHECKING:
+    from .abc import Snowflake
+    from datetime import datetime
+    from .state import ConnectionState
+
+
+from .types.snowflake import SnowflakeID
+
 from . import utils
 from .mixins import Hashable
 
+MISSING = utils.MISSING
+
+__all__ = (
+    'Object',
+)
+
+
 class Object(Hashable):
     """Represents a generic Discord object.
 
@@ -37,7 +61,7 @@ class Object(Hashable):
     objects (if any) actually inherit from this class.
 
     There are also some cases where some websocket events are received
-    in :issue:`strange order <21>` and when such events happened you would
+    in :old-issue:`strange order <21>` and when such events happened you would
     receive this class rather than the actual data class. These cases are
     extremely rare.
 
@@ -59,20 +83,40 @@ class Object(Hashable):
     -----------
     id: :class:`int`
         The ID of the object.
+    type: :class:`object`
+        The object this should represent if any.
     """
-
-    def __init__(self, id):
+    id: int
+
+    def __init__(
+            self,
+            id: SnowflakeID,
+            type: Type = MISSING,
+            *,
+            state: Optional[ConnectionState] = MISSING
+    ):
         try:
-            id = int(id)
-        except ValueError:
-            raise TypeError('id parameter must be convertable to int not {0.__class__!r}'.format(id)) from None
-        else:
-            self.id = id
-
-    def __repr__(self):
-        return '<Object id=%r>' % self.id
-
+            self.id: int = int(id)
+        except (ValueError, TypeError):
+            raise TypeError('id parameter must be convertible to int not {0.__class__!r}'.format(id)) from None
+
+        self.type: Type = type
+        self._state: Optional[ConnectionState] = state
+
+    def __repr__(self) -> str:
+        return f'<Object id={self.id!r} type={self.type!r}>'
+    
+    def __instancecheck__(self, other: Any) -> bool:
+        if self.type is not MISSING:
+            return self.type == type(other)  # This can make some problems, so the lib doesn't use it
+        return self.__class__ == type(other)
+    
     @property
-    def created_at(self):
+    def created_at(self) -> datetime:
         """:class:`datetime.datetime`: Returns the snowflake's creation time in UTC."""
         return utils.snowflake_time(self.id)
+
+
+if TYPE_CHECKING:
+    class Object(Snowflake, Object):
+        pass
\ No newline at end of file
diff --git a/discord/onboarding.py b/discord/onboarding.py
new file mode 100644
index 00000000..816fe5d5
--- /dev/null
+++ b/discord/onboarding.py
@@ -0,0 +1,351 @@
+#  The MIT License (MIT)
+#
+#  Copyright (c) 2021-present mccoderpy
+#
+#  Permission is hereby granted, free of charge, to any person obtaining a
+#  copy of this software and associated documentation files (the "Software"),
+#  to deal in the Software without restriction, including without limitation
+#  the rights to use, copy, modify, merge, publish, distribute, sublicense,
+#  and/or sell copies of the Software, and to permit persons to whom the
+#  Software is furnished to do so, subject to the following conditions:
+#
+#  The above copyright notice and this permission notice shall be included in
+#  all copies or substantial portions of the Software.
+#
+#  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+#  OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+#  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+#  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+#  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+#  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+#  DEALINGS IN THE SOFTWARE.
+
+from __future__ import annotations
+
+import os
+from typing import (
+    TYPE_CHECKING,
+    Iterable,
+    Optional,
+    Set,
+    List,
+    Union,
+)
+
+
+from . import utils
+from .mixins import Hashable
+from .enums import OnboardingMode, OnboardingPromptType, try_enum
+from .utils import cached_slot_property, MISSING
+
+__all__ = (
+    'Onboarding',
+    'OnboardingPrompt',
+    'PartialOnboardingPrompt',
+    'OnboardingPromptOption',
+    'PartialOnboardingPromptOption',
+)
+
+
+if TYPE_CHECKING:
+    from .abc import GuildChannel
+    from .channel import ThreadChannel
+    from .emoji import Emoji
+    from .guild import Guild
+    from .partial_emoji import PartialEmoji
+    from .role import Role
+    from .state import ConnectionState
+    from .types.guild import (
+        Onboarding as OnboardingData,
+        OnboardingPrompt as PromptData,
+        OnboardingPromptOption as PromptOptionData,
+    )
+
+
+class PartialOnboardingPromptOption(Hashable):
+    """Represents a partial onboarding prompt option.
+    These are used when creating a new :class:`OnboardingPrompt` via. :meth:`Guild.edit_onboarding`.
+
+    .. versionadded:: 2.0
+
+    Attributes
+    ----------
+    title: :class:`str`
+        The title of the option.
+    description: :class:`str`
+        The description of the option.
+    emoji: Optional[Union[:class:`Emoji`, :class:`PartialEmoji`, :class:`str`]]
+        The emoji to display next to the option. This can be a custom emoji of the same guild, or a unicode emoji.
+    channel_ids: Set[:class:`int`]
+        The IDs of the channels added to the users channel list, if the option is selected.
+    role_ids: Set[:class:`int`]
+        The IDs of the roles that the option will add the user to, if the option is selected.
+    """
+
+    __slots__ = (
+        'title',
+        'emoji',
+        'description',
+        'channel_ids',
+        'role_ids',
+    )
+
+    def __init__(
+        self,
+        title: str,
+        emoji: Optional[Union[Emoji, PartialEmoji, str]] = None,
+        description: Optional[str] = None,
+        channel_ids: Iterable[int] = MISSING,
+        role_ids: Iterable[int] = MISSING,
+    ) -> None:
+        self.title: str = title
+        self.emoji: Optional[Union[Emoji, PartialEmoji, str]] = emoji
+        self.description: Optional[str] = description
+        self.channel_ids: Set[int] = set(channel_ids or [])
+        self.role_ids: Set[int] = set(role_ids or [])
+
+    def _to_dict(self, *, id: int = MISSING) -> PromptOptionData:
+        from .state import ConnectionState
+
+        base = {
+            'title': self.title,
+            'emoji': ConnectionState.emoji_to_partial_payload(self.emoji) if self.emoji else None,
+            'description': self.description,
+            'channel_ids': list(self.channel_ids),
+            'role_ids': list(self.role_ids),
+        }
+        if id is not MISSING:
+            base['id'] = id
+        return base
+
+
+class OnboardingPromptOption(PartialOnboardingPromptOption, Hashable):
+    """Represents an onboarding prompt option.
+
+    .. versionadded:: 2.0
+
+    Attributes
+    ----------
+    id: :class:`int`
+        The ID of the option.
+    title: :class:`str`
+        The title of the option.
+    description: Optional[:class:`str`]
+        The description of the option.
+    emoji: Optional[Union[:class:`Emoji`, :class:`PartialEmoji`, :class:`str`]]
+        The emoji displayed next to the option.
+        This can be a custom emoji of the same guild, or a unicode emoji.
+    channel_ids: Set[:class:`int`]
+        The IDs of the channels added to the users channel list, if the option is selected.
+    role_ids: Set[:class:`int`]
+        The IDs of the roles added to the user, if the option is selected.
+    """
+
+    __slots__ = (
+        '_state',
+        '_cs_channels',
+        '_cs_roles',
+        'guild',
+        'id',
+    )
+
+    def __init__(self, *, data: PromptOptionData, state: ConnectionState, guild: Guild) -> None:
+        self._state: ConnectionState = state
+        self.guild: Guild = guild
+        self.id: int = int(data['id'])
+        super().__init__(
+            title=data['title'],
+            emoji=state.get_emoji_from_partial(data['emoji']),
+            description=data['description'],
+            channel_ids=[int(id) for id in data['channel_ids']],
+            role_ids=[int(id) for id in data['role_ids']],
+        )
+
+    def __repr__(self) -> str:
+        return f'<OnboardingPromptOption id={self.id} title={self.title!r}>'
+
+    @cached_slot_property('_cs_channels')
+    def channels(self) -> List[Union[GuildChannel, ThreadChannel]]:
+        """List[Union[:class:`abc.GuildChannel`, :class:`ThreadChannel`]]: The channels added to the users channel list,
+        if the option is selected.
+        """
+        return utils._unique(filter(None, map(self.guild.get_channel, self.channel_ids)))  # type: ignore
+
+    @cached_slot_property('_cs_roles')
+    def roles(self) -> List[Role]:
+        """List[:class:`Role`]: The roles added to the user, if the option is selected."""
+        return utils._unique(filter(None, map(self.guild.get_role, self.role_ids)))  # type: ignore
+
+    def _to_dict(self) -> PromptOptionData:
+        return super()._to_dict(id=self.id)
+
+
+class PartialOnboardingPrompt:
+    """Represents a partial onboarding prompt.
+    These are used when creating a new :class:`OnboardingPrompt` via. :meth:`Guild.edit_onboarding`.
+
+    .. versionadded:: 2.0
+
+    Attributes
+    ----------
+    type: :class:`OnboardingPromptType`
+        The type of the prompt.
+    title: :class:`str`
+        The title of the prompt.
+    options: List[:class:`PartialOnboardingPromptOption`]
+        The options of the prompt.
+    single_select: :class:`bool`
+        Whether users can only select one option in the prompt.
+    required: :class:`bool`
+        Whether the prompt is required, for completing the onboarding flow.
+    in_onboarding: :class:`bool`
+        Whether the prompt is in the onboarding flow.
+        If ``False``, the prompt will only appear in the Channels & Roles tab
+    """
+
+    __slots__ = (
+        'type',
+        'title',
+        'options',
+        'single_select',
+        'required',
+        'in_onboarding',
+    )
+
+    def __init__(
+        self,
+        *,
+        type: OnboardingPromptType,
+        title: str,
+        options: List[PartialOnboardingPromptOption],
+        single_select: bool = True,
+        required: bool = True,
+        in_onboarding: bool = True,
+    ) -> None:
+        self.type: OnboardingPromptType = try_enum(OnboardingPromptType, type)
+        self.title: str = title
+        self.options: List[PartialOnboardingPromptOption] = options
+        self.single_select: bool = single_select
+        self.required: bool = required
+        self.in_onboarding: bool = in_onboarding
+
+    def _to_dict(self, *, id: int = MISSING) -> PromptData:
+        base = {
+            'type': self.type.value,
+            'title': self.title,
+            'options': [option._to_dict() for option in self.options],
+            'single_select': self.single_select,
+            'required': self.required,
+            'in_onboarding': self.in_onboarding,
+        }
+        if id is not MISSING:
+            base['id'] = id
+        else:
+            base['id'] = 0
+        return base
+
+
+class OnboardingPrompt(PartialOnboardingPrompt, Hashable):
+    """Represents an onboarding prompt.
+
+    .. versionadded:: 2.0
+
+    Attributes
+    ----------
+    id: :class:`int`
+        The ID of the prompt.
+    guild: :class:`Guild`
+        The guild that the prompt belongs to.
+    type: :class:`OnboardingPromptType`
+        The type of the prompt.
+    title: :class:`str`
+        The title of the prompt.
+    options: List[:class:`OnboardingPromptOption`]
+        The options available to select from in the prompt.
+    single_select: :class:`bool`
+        Whether users can only select one option in the prompt.
+    in_onboarding: :class:`bool`
+        Whether the prompt is in the onboarding flow.
+    """
+
+    options: List[OnboardingPromptOption]
+
+    __slots__ = (
+        '_state',
+        'guild',
+        'id',
+        'type',
+        'title',
+        'options',
+        'single_select',
+        'required',
+        'in_onboarding',
+    )
+
+    def __init__(self, *, data: PromptData, state: ConnectionState, guild: Guild) -> None:
+        self._state: ConnectionState = state
+        self.guild: Guild = guild
+        self.id: int = int(data['id'])
+        super().__init__(
+            type=try_enum(OnboardingPromptType, data['type']),
+            title=data['title'],
+            options=[OnboardingPromptOption(data=option, state=state, guild=guild) for option in data['options']],
+            single_select=data['single_select'],
+            required=data['required'],
+            in_onboarding=data['in_onboarding'],
+        )
+
+    def __repr__(self) -> str:
+        return f'<OnboardingPrompt id={self.id} title={self.title!r}>'
+
+    def _to_dict(self) -> PromptData:
+        return super()._to_dict(id=self.id)
+
+
+class Onboarding:
+    """Represents a guilds onboarding configuration.
+
+    .. versionadded:: 2.0
+
+    Attributes
+    ----------
+    guild: :class:`Guild`
+        The guild that the onboarding configuration belongs to.
+    prompts: List[:class:`OnboardingPrompt`]
+        The list of prompts shown during onboarding flow and in the customize community (Channel & Roles) tab.
+    default_channel_ids: Set[:class:`int`]
+        The IDs of the channels that are added to the users channel list by default.
+    enabled: :class:`bool`
+        Whether onboarding is enabled for the guild.
+    mode: :class:`OnboardingMode`
+        The onboarding mode for the guild.
+    """
+
+    __slots__ = (
+        '_state',
+        '_cs_default_channels',
+        'guild',
+        'prompts',
+        'default_channel_ids',
+        'enabled',
+        'mode',
+    )
+
+    def __init__(self, *, data: OnboardingData, state: ConnectionState, guild: Guild) -> None:
+        self._state: ConnectionState = state
+        self.guild: Guild = guild
+        self.default_channel_ids: Set[int] = set(map(int, data['default_channel_ids']))
+        self.prompts: List[OnboardingPrompt] = [
+            OnboardingPrompt(data=prompt, state=state, guild=guild) for prompt in data['prompts']
+        ]
+        self.enabled: bool = data['enabled']
+        self.mode: OnboardingMode = try_enum(OnboardingMode, data['mode'])
+
+    def __repr__(self) -> str:
+        return f'<Onboarding guild={self.guild!r} enabled={self.enabled}>'
+
+    @cached_slot_property('_cs_default_channels')
+    def default_channels(self) -> List[Union[GuildChannel, ThreadChannel]]:
+        """List[Union[:class:`abc.GuildChannel`, :class:`ThreadChannel`]]: The list of channels
+        that are added to the users channel list by default."""
+        return utils._unique(filter(None, map(self.guild.get_channel, self.default_channel_ids)))  # type: ignore
diff --git a/discord/opus.py b/discord/opus.py
index 94adf338..7f127209 100644
--- a/discord/opus.py
+++ b/discord/opus.py
@@ -32,8 +32,19 @@
 import os.path
 import struct
 import sys
+import threading
+import time
 
 from .errors import DiscordException
+from .sink import RawData
+
+__all__ = (
+    'Encoder',
+    'Decoder',
+    'DecodeManager',
+    'OpusError',
+    'OpusNotLoaded',
+)
 
 log = logging.getLogger(__name__)
 
@@ -337,6 +348,7 @@ def encode(self, pcm, frame_size):
 
         return array.array('b', data[:ret]).tobytes()
 
+
 class Decoder(_OpusStruct):
     def __init__(self):
         _OpusStruct.get_opus_version()
@@ -405,13 +417,55 @@ def decode(self, data, *, fec=False):
             channel_count = self.CHANNELS
         else:
             frames = self.packet_get_nb_frames(data)
-            channel_count = self.packet_get_nb_channels(data)
+            channel_count = self.CHANNELS
             samples_per_frame = self.packet_get_samples_per_frame(data)
             frame_size = frames * samples_per_frame
 
-        pcm = (ctypes.c_int16 * (frame_size * channel_count))()
+        pcm = (ctypes.c_int16 * (frame_size * channel_count * ctypes.sizeof(ctypes.c_int16)))()
         pcm_ptr = ctypes.cast(pcm, c_int16_ptr)
 
         ret = _lib.opus_decode(self._state, data, len(data) if data else 0, pcm_ptr, frame_size, fec)
 
         return array.array('h', pcm[:ret * channel_count]).tobytes()
+
+
+class DecodeManager(threading.Thread, _OpusStruct):
+    def __init__(self, client):
+        super().__init__(daemon=True, name='DecodeManager')
+
+        self.client = client
+        self.decode_queue = []
+
+        self.decoder = Decoder()
+
+        self._end_thread = threading.Event()
+
+    def decode(self, opus_frame):
+        if not isinstance(opus_frame, RawData):
+            raise TypeError("opus_frame should be a RawData object.")
+        self.decode_queue.append(opus_frame)
+
+    def run(self):
+        while not self._end_thread.is_set():
+            try:
+                data = self.decode_queue.pop(0)
+            except IndexError:
+                continue
+
+            try:
+                data.decoded_data = self.decoder.decode(data.decrypted_data)
+            except OpusError:
+                print("Error occurred decoding opus frame.")
+                continue
+
+            self.client.recv_decoded_audio(data)
+
+    def stop(self):
+        while self.decoding:
+            time.sleep(0.1)
+        self._end_thread.set()
+
+    @property
+    def decoding(self):
+        return bool(self.decode_queue)
+    
\ No newline at end of file
diff --git a/discord/partial_emoji.py b/discord/partial_emoji.py
index 91f85532..674001ba 100644
--- a/discord/partial_emoji.py
+++ b/discord/partial_emoji.py
@@ -3,7 +3,7 @@
 """
 The MIT License (MIT)
 
-Copyright (c) 2015-present Rapptz
+Copyright (c) 2015-2021 Rapptz & (c) 2021-present mccoderpy
 
 Permission is hereby granted, free of charge, to any person obtaining a
 copy of this software and associated documentation files (the "Software"),
@@ -23,14 +23,28 @@
 FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 DEALINGS IN THE SOFTWARE.
 """
+from __future__ import annotations
+
+from typing import (
+    Optional,
+    TYPE_CHECKING
+)
+from typing_extensions import Literal
+
 import re
 from .asset import Asset
 from . import utils
 
+if TYPE_CHECKING:
+    from .state import ConnectionState
+    from datetime import datetime
+    from .types.emoji import PartialEmoji as PartialEmojiPayload
+
 
 class _EmojiTag:
     __slots__ = ()
 
+
 class PartialEmoji(_EmojiTag):
     """Represents a "partial" emoji.
 
@@ -71,36 +85,44 @@ class PartialEmoji(_EmojiTag):
 
     __slots__ = ('animated', 'name', 'id', '_state')
 
-    def __init__(self, *, name, animated=False, id=None):
-        self.animated = animated
-        self.name = name
-        self.id = id
-        self._state = None
+    def __init__(self, *, name: str, animated: bool = False, id: Optional[int] = None) -> None :
+        self.animated: bool = animated
+        self.name: str = name
+        self.id: Optional[int] = id
+        self._state: Optional[ConnectionState] = None
 
     @classmethod
-    def from_string(cls, string: str):
-        """Converts a custom emoji as they are in a message into a partial emoji object.
+    def from_string(cls, string: str) -> PartialEmoji:
+        """Converts a (custom) emoji as they are in a message into a partial emoji object.
 
         .. note::
             To get them, type a custom emoji into the chat, put an ``\`` in front of it and send it.
             You can then use what comes out when you add a reaction or similar.
+
+        .. warning::
+            This does **not** support the :emoji: format for (standard) emojis
+        
+        Returns
+        --------
+        :class:`PartialEmoji`
+            The emoji object if the string was valid.
         """
 
         match = re.match('^<(a?):([\-\w]+):(\d+)>$', string)
         if match:
             return cls(animated=bool(match.group(1)), name=match.group(2), id=int(match.group(3)))
-        raise ValueError('The Passed Emoji is not a discord custom-emoji.')
+        return cls(name=string)
 
     @classmethod
-    def from_dict(cls, data):
+    def from_dict(cls, data: PartialEmojiPayload) -> PartialEmoji:
         return cls(
             animated=data.get('animated', False),
             id=utils._get_as_snowflake(data, 'id'),
             name=data.get('name'),
         )
 
-    def to_dict(self):
-        o = { 'name': self.name }
+    def to_dict(self) -> PartialEmojiPayload:
+        o = {'name': self.name}
         if self.id:
             o['id'] = self.id
         if self.animated:
@@ -108,50 +130,60 @@ def to_dict(self):
         return o
 
     @classmethod
-    def with_state(cls, state, *, name, animated=False, id=None):
+    def with_state(
+            cls,
+            state: ConnectionState,
+            *,
+            name: str,
+            animated: bool = False,
+            id: Optional[int] = None
+    ) -> PartialEmoji:
         self = cls(name=name, animated=animated, id=id)
         self._state = state
         return self
 
-    def __str__(self):
+    def __str__(self) -> str:
         if self.id is None:
             return self.name
         if self.animated:
             return '<a:%s:%s>' % (self.name, self.id)
         return '<:%s:%s>' % (self.name, self.id)
 
-    def __repr__(self):
+    def __len__(self) -> int:
+        return len(str(self))
+
+    def __repr__(self) -> str:
         return '<{0.__class__.__name__} animated={0.animated} name={0.name!r} id={0.id}>'.format(self)
 
-    def __eq__(self, other):
+    def __eq__(self, other) -> bool:
         if self.is_unicode_emoji():
             return isinstance(other, PartialEmoji) and self.name == other.name
 
         if isinstance(other, _EmojiTag):
-            return self.id == other.id
+            return self.id == other.id  # type: ignore
         return False
-
-    def __ne__(self, other):
+    
+    def __ne__(self, other) -> bool:
         return not self.__eq__(other)
 
-    def __hash__(self):
+    def __hash__(self) -> int:
         return hash((self.id, self.name))
 
-    def is_custom_emoji(self):
+    def is_custom_emoji(self) -> bool:
         """:class:`bool`: Checks if this is a custom non-Unicode emoji."""
         return self.id is not None
 
-    def is_unicode_emoji(self):
+    def is_unicode_emoji(self) -> bool:
         """:class:`bool`: Checks if this is a Unicode emoji."""
         return self.id is None
 
-    def _as_reaction(self):
+    def _as_reaction(self) -> str:
         if self.id is None:
             return self.name
         return '%s:%s' % (self.name, self.id)
 
     @property
-    def created_at(self):
+    def created_at(self) -> Optional[datetime]:
         """Optional[:class:`datetime.datetime`]: Returns the emoji's creation time in UTC, or None if Unicode emoji.
 
         .. versionadded:: 1.6
@@ -162,7 +194,7 @@ def created_at(self):
         return utils.snowflake_time(self.id)
 
     @property
-    def url(self):
+    def url(self) -> Asset:
         """:class:`Asset`: Returns the asset of the emoji, if it is custom.
 
         This is equivalent to calling :meth:`url_as` with
@@ -170,7 +202,12 @@ def url(self):
         """
         return self.url_as(format=None)
 
-    def url_as(self, *, format=None, static_format="png"):
+    def url_as(
+            self,
+            *,
+            format: Optional[Literal['jpeg', 'jpg', 'webp', 'png', 'gif']] = None,
+            static_format: Literal['jpeg', 'jpg', 'webp', 'png', ] = 'png'
+    ) -> Asset:
         """Returns an :class:`Asset` for the emoji's url, if it is custom.
 
         The format must be one of 'webp', 'jpeg', 'jpg', 'png' or 'gif'.
diff --git a/discord/permissions.py b/discord/permissions.py
index 3fd0dacf..b6b1821c 100644
--- a/discord/permissions.py
+++ b/discord/permissions.py
@@ -3,7 +3,7 @@
 """
 The MIT License (MIT)
 
-Copyright (c) 2015-present Rapptz
+Copyright (c) 2015-2021 Rapptz & (c) 2021-present mccoderpy
 
 Permission is hereby granted, free of charge, to any person obtaining a
 copy of this software and associated documentation files (the "Software"),
@@ -23,8 +23,24 @@
 FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 DEALINGS IN THE SOFTWARE.
 """
+from __future__ import annotations
+
+from typing import (
+    ClassVar,
+    Dict,
+    Iterator,
+    Optional,
+    Set,
+    Tuple,
+    TYPE_CHECKING
+)
+from typing_extensions import Final
+
+from .flags import alias_flag_value, BaseFlags, fill_with_flags, flag_value
+
+if TYPE_CHECKING:
+    from .types.guild import PermissionFlag
 
-from .flags import BaseFlags, flag_value, fill_with_flags, alias_flag_value
 
 __all__ = (
     'Permissions',
@@ -47,7 +63,7 @@ def decorator(func):
 class Permissions(BaseFlags):
     """Wraps up the Discord permission value.
 
-    The properties provided are two way. You can set and retrieve individual
+    The properties provided are two-way. You can set and retrieve individual
     bits using the properties as if they were regular bools. This allows
     you to edit permissions.
 
@@ -93,36 +109,46 @@ class Permissions(BaseFlags):
     """
 
     __slots__ = ()
-
-    def __init__(self, permissions=0, **kwargs):
+    
+    if TYPE_CHECKING:
+        VALID_FLAGS: Final[ClassVar[Dict[PermissionFlag, int]]]
+        DEFAULT_VALUE: ClassVar[int]
+        
+    def __init__(self, permissions: int = 0, **kwargs: bool) -> None:
         if not isinstance(permissions, int):
-            raise TypeError('Expected int parameter, received %s instead.' % permissions.__class__.__name__)
+            raise TypeError(
+                f'Expected int parameter, received {permissions.__class__.__name__} instead.'
+            )
 
-        self.value = permissions
+        self.value: int = permissions
         for key, value in kwargs.items():
             if key not in self.VALID_FLAGS:
                 raise TypeError('%r is not a valid permission name.' % key)
             setattr(self, key, value)
 
-    def is_subset(self, other):
+    def is_subset(self, other: Permissions) -> bool:
         """Returns ``True`` if self has the same or fewer permissions as other."""
         if isinstance(other, Permissions):
             return (self.value & other.value) == self.value
         else:
-            raise TypeError("cannot compare {} with {}".format(self.__class__.__name__, other.__class__.__name__))
+            raise TypeError(
+                f"cannot compare {self.__class__.__name__} with {other.__class__.__name__}"
+            )
 
-    def is_superset(self, other):
+    def is_superset(self, other: Permissions) -> bool:
         """Returns ``True`` if self has the same or more permissions as other."""
         if isinstance(other, Permissions):
             return (self.value | other.value) == self.value
         else:
-            raise TypeError("cannot compare {} with {}".format(self.__class__.__name__, other.__class__.__name__))
+            raise TypeError(
+                f"cannot compare {self.__class__.__name__} with {other.__class__.__name__}"
+            )
 
-    def is_strict_subset(self, other):
+    def is_strict_subset(self, other: Permissions) -> bool:
         """Returns ``True`` if the permissions on other are a strict subset of those on self."""
         return self.is_subset(other) and self != other
 
-    def is_strict_superset(self, other):
+    def is_strict_superset(self, other: Permissions) -> bool:
         """Returns ``True`` if the permissions on other are a strict superset of those on self."""
         return self.is_superset(other) and self != other
 
@@ -142,7 +168,7 @@ def all(cls):
         """A factory method that creates a :class:`Permissions` with all
         permissions set to ``True``.
         """
-        return cls(0b111111111111111111111111111111111)
+        return cls(0b11111111111111111111111111111111111111111111111)
 
     @classmethod
     def all_channel(cls):
@@ -162,8 +188,12 @@ def all_channel(cls):
 
         .. versionchanged:: 1.7
            Added :attr:`stream`, :attr:`priority_speaker` and :attr:`use_slash_commands` permissions.
+
+        .. versionchanged:: 2.0
+            Added :attr:`start_embedded_activities`, :attr:`moderate_members`, :attr:`manage_events`, :attr:`create_private_threads`,
+            :attr:`create_puplic_threads`, :attr:`manage_threads`, :attr:`send_messages_in_threads`, :attr:`request_to_speak` and :attr:`use_external_stickers`
         """
-        return cls(0b10110011111101111111111101010001)
+        return cls(0b11111111110110011111101111111111101010001)
 
     @classmethod
     def general(cls):
@@ -175,8 +205,11 @@ def general(cls):
            permissions :attr:`administrator`, :attr:`create_instant_invite`, :attr:`kick_members`,
            :attr:`ban_members`, :attr:`change_nickname` and :attr:`manage_nicknames` are
            no longer part of the general permissions.
+
+        .. versionchanged:: 2.0
+            Added :attr:`moderate_members`, :attr:`manage_expressions` and :attr:`create_expressions` permission.
         """
-        return cls(0b01110000000010000000010010110000)
+        return cls(0b10010000000001110000000010000000010010110000)
 
     @classmethod
     def membership(cls):
@@ -184,8 +217,11 @@ def membership(cls):
         "Membership" permissions from the official Discord UI set to ``True``.
 
         .. versionadded:: 1.7
+
+        .. versionchanged:: 2.0
+            Added :attr:`moderate_members` permission.
         """
-        return cls(0b00001100000000000000000000000111)
+        return cls(0b10000000000001100000000000000000000000111)
 
     @classmethod
     def text(cls):
@@ -195,14 +231,23 @@ def text(cls):
         .. versionchanged:: 1.7
            Permission :attr:`read_messages` is no longer part of the text permissions.
            Added :attr:`use_slash_commands` permission.
+
+        .. versionchanged:: 2.0
+            Added :attr:`send_voice_messages`, :attr:`manage_threads`, :attr:`create_public_threads`,
+            :attr:`create_private_threads`, :attr:`send_messages_in_threads` and :attr:`use_external_stickers` permission.
         """
-        return cls(0b10000000000001111111100001000000)
+        return cls(0b10000000111110010000000000001111111100001000000)
 
     @classmethod
     def voice(cls):
         """A factory method that creates a :class:`Permissions` with all
-        "Voice" permissions from the official Discord UI set to ``True``."""
-        return cls(0b00000011111100000000001100000000)
+        "Voice" permissions from the official Discord UI set to ``True``.
+
+        .. versionchanged:: 2.0
+            Added :attr:`start_embedded_activities`, :attr:`use_soundboard` :attr:`use_external_sounds` and
+            :attr:`set_voice_channel_status` permission.
+        """
+        return cls(0b1001001001000000000000011111100000000001100000000)
 
     @classmethod
     def stage(cls):
@@ -222,6 +267,15 @@ def stage_moderator(cls):
         """
         return cls(0b100000001010000000000000000000000)
 
+    @classmethod
+    def events(cls):
+        """A factory method that creates a :class:`Permissions` with all
+        "Events" permissions from the official Discord UI set to ``True``.
+
+        .. versionadded:: 2.0
+        """
+        return cls(0b100000000001000000000000000000000000000000000)
+
     @classmethod
     def advanced(cls):
         """A factory method that creates a :class:`Permissions` with all
@@ -231,7 +285,7 @@ def advanced(cls):
         """
         return cls(1 << 3)
 
-    def update(self, **kwargs):
+    def update(self, **kwargs: bool) -> None:
         r"""Bulk updates this permission object.
 
         Allows you to set multiple attributes by using keyword
@@ -247,7 +301,7 @@ def update(self, **kwargs):
             if key in self.VALID_FLAGS:
                 setattr(self, key, value)
 
-    def handle_overwrite(self, allow, deny):
+    def handle_overwrite(self, allow: int, deny: int) -> None:
         # Basically this is what's happening here.
         # We have an original bit array, e.g. 1010
         # Then we have another bit array that is 'denied', e.g. 1111
@@ -332,7 +386,16 @@ def view_channel(self):
 
     @flag_value
     def send_messages(self):
-        """:class:`bool`: Returns ``True`` if a user can send messages from all or specific text channels."""
+        """:class:`bool`: Returns ``True`` if a user can send messages from all or specific text channels
+        and create posts in forum channels."""
+        return 1 << 11
+
+    @make_permission_alias('send_messages')
+    def create_posts(self):
+        """:class:`bool`: An alias for :attr:`send_messages`.
+
+        .. versionadded:: 2.0
+        """
         return 1 << 11
 
     @flag_value
@@ -451,20 +514,69 @@ def manage_permissions(self):
     def manage_webhooks(self):
         """:class:`bool`: Returns ``True`` if a user can create, edit, or delete webhooks."""
         return 1 << 29
-
+    
     @flag_value
+    def manage_expressions(self):
+        """:class:`bool`: Returns ``True`` if a user can create, edit, or delete emojis, stickers and sounds."""
+        return 1 << 30
+    
+    @make_permission_alias('manage_expressions')
     def manage_emojis(self):
-        """:class:`bool`: Returns ``True`` if a user can create, edit, or delete emojis."""
+        """:class:`bool`: An aliase for :attr:`manage_expressions`"""
         return 1 << 30
-
+    
+    @make_permission_alias('manage_expressions')
+    def manage_stickers(self):
+        """:class:`bool`: An aliase for :attr:`manage_expressions`"""
+        return 1 << 30
+    
+    @make_permission_alias('manage_expressions')
+    def manage_emojis_and_stickers(self):
+        """:class:`bool`: An aliase for :attr:`manage_expressions`"""
+        return 1 << 30
+    
+    @make_permission_alias('manage_expressions')
+    def manage_sounds(self):
+        """:class:`bool`: An aliase for :attr:`manage_expressions`"""
+        return 1 << 30
+    
     @flag_value
-    def use_slash_commands(self):
-        """:class:`bool`: Returns ``True`` if a user can use slash commands.
+    def create_expressions(self):
+        """:class:`bool`: Returns ``True`` if a user can create emojis, stickers or
+        `sounds <https://support.discord.com/hc/de/articles/12612888127767-Soundboard-FAQ>`_ in a server.
+        
+        .. versionadded:: 2.0
+        """
+        return 1 << 43
+    
+    @make_permission_alias('create_expressions')
+    def create_emojis(self):
+        """:class:`bool`: An aliase for :attr:`create_expressions`"""
+        return 1 << 43
+    
+    @make_permission_alias('create_expressions')
+    def create_stickers(self):
+        """:class:`bool`: An aliase for :attr:`create_expressions`"""
+        return 1 << 43
+    
+    @make_permission_alias('create_expressions')
+    def create_sounds(self):
+        """:class:`bool`: An aliase for :attr:`create_expressions`"""
+        return 1 << 43
+    
+    @flag_value
+    def use_application_commands(self):
+        """:class:`bool`: Returns ``True`` if a user can use application commands.
 
         .. versionadded:: 1.7
         """
         return 1 << 31
 
+    @make_permission_alias('use_application_commands')
+    def use_slash_commands(self):
+        """:class:`bool`: An aliase for :attr:`use_application_commands`"""
+        return 1 << 31
+
     @flag_value
     def request_to_speak(self):
         """:class:`bool`: Returns ``True`` if a user can request to speak in a stage channel.
@@ -473,6 +585,149 @@ def request_to_speak(self):
         """
         return 1 << 32
 
+    @flag_value
+    def manage_events(self):
+        """:class:`bool`: Returns ``True`` if a user can create and manage Guild-Scheduled-Events.
+        
+        .. versionadded:: 2.0
+        """
+        return 1 << 33
+    
+    @flag_value
+    def create_events(self):
+        """:class:`bool`: Returns ``True`` if a user can create Guild-Scheduled-Events.
+        
+        .. versionadded:: 2.0
+        """
+        return 1 << 44
+
+    @flag_value
+    def manage_threads(self):
+        """:class:`bool`: Returns ``True`` if a user can delete and archive threads and viewing all private threads.
+        
+        .. versionadded:: 2.0"""
+        return 1 << 34
+
+    @flag_value
+    def create_public_threads(self):
+        """:class:`bool`: Returns ``True`` if a user can create and participate in threads.
+        
+        .. versionadded:: 2.0"""
+        return 1 << 35
+
+    @flag_value
+    def create_private_threads(self):
+        """:class:`bool`: Returns ``True`` if a user can create and participate in private threads.
+        
+        .. versionadded:: 2.0"""
+        return 1 << 36
+
+    @flag_value
+    def use_external_stickers(self):
+        """:class:`bool`: Returns ``True`` if a user can use custom stickers from other servers.
+        
+        .. versionadded:: 2.0
+        """
+        return 1 << 37
+
+    @flag_value
+    def send_messages_in_threads(self):
+        """:class:`bool`: Returns ``True`` if a user can send messages in threads and forum posts.
+        
+        .. versionadded:: 2.0
+        """
+        return 1 << 38
+
+    @make_permission_alias('send_messages_in_threads')
+    def send_messages_in_posts(self):
+        """:class:`bool`: An alias for :attr:`send_messages_in_threads`."""
+        return 1 << 38
+
+    # TODO: Remove this alias in 2.0 release
+    @make_permission_alias('send_messages_in_threads')
+    def send_thread_messages(self):
+        """:class:`bool`: An alias for :attr:`send_messages_in_threads`."""
+        return 1 << 38
+
+    @flag_value
+    def start_embedded_activities(self):
+        """:class:`bool`: Returns ``True`` if a user can start embedded activities in a voice channel
+        (e.g. voice-activities).
+        
+        .. versionadded:: 2.0"""
+        return 1 << 39
+
+    @make_permission_alias('start_embedded_activities')
+    def start_voice_activities(self):
+        """:class:`bool`: An alias for :attr:`start_embedded_activities`."""
+        return 1 << 39
+
+    @flag_value
+    def moderate_members(self):
+        """:class:`bool`: Returns ``True`` if a user can moderate other members (like timeout or verify them).
+        
+        .. versionadded:: 2.0"""
+        return 1 << 40
+
+    @make_permission_alias('moderate_members')
+    def timeout_members(self):
+        """:class:`bool`: An alias for :attr:`moderate_members`."""
+        return 1 << 40
+    
+    @flag_value
+    def view_creator_monetization_analytics(self):
+        """:class:`bool`: Returns ``True`` if a user can view analytics for monetization of their content.
+        
+        .. versionadded:: 2.0"""
+        return 1 << 41
+    
+    @flag_value
+    def use_soundboard(self):
+        """:class:`bool`: Returns ``True`` if a user can use the soundboard in a voice channel.
+        
+        .. versionadded:: 2.0"""
+        return 1 << 42
+    
+    @flag_value
+    def use_external_sounds(self):
+        """:class:`bool`: Returns ``True`` if a user can use custom soundboard sounds from other servers.
+        
+        .. versionadded:: 2.0"""
+        return 1 << 45
+
+    @flag_value
+    def send_voice_messages(self):
+        """:class:`bool`: Returns ``True`` if a user can send voice messages.
+        
+        .. versionadded:: 2.0"""
+        return 1 << 46
+
+    @flag_value
+    def set_voice_channel_status(self):
+        """:class:`bool`: Returns ``True`` if a user can set the status of a voice channel.
+
+        .. versionadded:: 2.0"""
+        return 1 << 48
+
+    @flag_value
+    def send_polls(self):
+        """:class:`bool`: Returns ``True`` if a user can send polls in a channel.
+
+        .. versionadded:: 2.0"""
+        return 1 << 49
+
+    @flag_value
+    def use_external_apps(self):
+        """:class:`bool`: Returns ``True`` if user-installed apps are allowed to send public responses.
+
+        .. note::
+            - When ``False``, users will still be allowed to use their apps but the responses will be ephemeral.
+            - This only applies to apps not also installed to the server
+
+        .. versionadded:: 2.0"""
+        return 1 << 50
+
+
 def augment_from_permissions(cls):
     cls.VALID_NAMES = set(Permissions.VALID_FLAGS)
     aliases = set()
@@ -499,6 +754,7 @@ def setter(self, value, x=key):
     cls.PURE_FLAGS = cls.VALID_NAMES - aliases
     return cls
 
+
 @augment_from_permissions
 class PermissionOverwrite:
     r"""A type that is used to represent a channel specific permission.
@@ -511,30 +767,78 @@ class PermissionOverwrite:
 
     The values supported by this are the same as :class:`Permissions`
     with the added possibility of it being set to ``None``.
-
-    .. container:: operations
-
-        .. describe:: x == y
-
-            Checks if two overwrites are equal.
-        .. describe:: x != y
-
-            Checks if two overwrites are not equal.
-        .. describe:: iter(x)
-
-           Returns an iterator of ``(perm, value)`` pairs. This allows it
-           to be, for example, constructed as a dict or a list of pairs.
-           Note that aliases are not shown.
-
-    Parameters
-    -----------
-    \*\*kwargs
-        Set the value of permissions by their name.
     """
 
     __slots__ = ('_values',)
-
-    def __init__(self, **kwargs):
+    
+    if TYPE_CHECKING:
+        VALID_NAMES: ClassVar[Set[str]]
+        PURE_FLAGS: ClassVar[Set[str]]
+        
+        create_instant_invite: Optional[bool]
+        kick_members: Optional[bool]
+        ban_members: Optional[bool]
+        administrator: Optional[bool]
+        manage_channels: Optional[bool]
+        manage_guild: Optional[bool]
+        add_reactions: Optional[bool]
+        view_audit_log: Optional[bool]
+        priority_speaker: Optional[bool]
+        stream: Optional[bool]
+        read_messages: Optional[bool]
+        view_channel: Optional[bool]
+        send_messages: Optional[bool]
+        send_tts_messages: Optional[bool]
+        manage_messages: Optional[bool]
+        embed_links: Optional[bool]
+        attach_files: Optional[bool]
+        read_message_history: Optional[bool]
+        mention_everyone: Optional[bool]
+        external_emojis: Optional[bool]
+        use_external_emojis: Optional[bool]
+        view_guild_insights: Optional[bool]
+        connect: Optional[bool]
+        speak: Optional[bool]
+        mute_members: Optional[bool]
+        deafen_members: Optional[bool]
+        move_members: Optional[bool]
+        use_voice_activation: Optional[bool]
+        change_nickname: Optional[bool]
+        manage_nicknames: Optional[bool]
+        manage_roles: Optional[bool]
+        manage_permissions: Optional[bool]
+        manage_webhooks: Optional[bool]
+        manage_expressions: Optional[bool]
+        manage_emojis: Optional[bool]
+        manage_stickers: Optional[bool]
+        manage_emojis_and_stickers: Optional[bool]
+        manage_sounds: Optional[bool]
+        create_expressions: Optional[bool]
+        create_emojis: Optional[bool]
+        create_stickers: Optional[bool]
+        create_sounds: Optional[bool]
+        use_slash_commands: Optional[bool]
+        use_application_commands: Optional[bool]
+        request_to_speak: Optional[bool]
+        manage_events: Optional[bool]
+        create_events: Optional[bool]
+        manage_threads: Optional[bool]
+        create_public_threads: Optional[bool]
+        create_private_threads: Optional[bool]
+        use_external_stickers: Optional[bool]
+        send_messages_in_threads: Optional[bool]
+        send_thread_messages: Optional[bool]
+        start_embedded_activities: Optional[bool]
+        start_voice_activities: Optional[bool]
+        moderate_members: Optional[bool]
+        timeout_members: Optional[bool]
+        view_creator_monetization_analytics: Optional[bool]
+        use_soundboard: Optional[bool]
+        use_external_sounds: Optional[bool]
+        send_voice_messages: Optional[bool]
+        set_voice_channel_status: Optional[bool]
+    
+    def __init__(self, **kwargs: Optional[bool]) -> None:
         self._values = {}
 
         for key, value in kwargs.items():
@@ -543,10 +847,14 @@ def __init__(self, **kwargs):
 
             setattr(self, key, value)
 
-    def __eq__(self, other):
+    def __eq__(self, other) -> bool:
+        """Checks if two overwrites are equal."""
         return isinstance(other, PermissionOverwrite) and self._values == other._values
+    def __ne__(self, other) -> bool:
+        """Checks if two overwrites are not equal."""
+        return not self.__eq__(other)
 
-    def _set(self, key, value):
+    def _set(self, key: PermissionFlag, value: Optional[bool]) -> None:
         if value not in (True, None, False):
             raise TypeError('Expected bool or NoneType, received {0.__class__.__name__}'.format(value))
 
@@ -555,7 +863,7 @@ def _set(self, key, value):
         else:
             self._values[key] = value
 
-    def pair(self):
+    def pair(self) -> Tuple[Permissions, Permissions]:
         """Tuple[:class:`Permissions`, :class:`Permissions`]: Returns the (allow, deny) pair from this overwrite."""
 
         allow = Permissions.none()
@@ -570,7 +878,7 @@ def pair(self):
         return allow, deny
 
     @classmethod
-    def from_pair(cls, allow, deny):
+    def from_pair(cls, allow: Permissions, deny: Permissions) -> PermissionOverwrite:
         """Creates an overwrite from an allow/deny pair of :class:`Permissions`."""
         ret = cls()
         for key, value in allow:
@@ -583,7 +891,7 @@ def from_pair(cls, allow, deny):
 
         return ret
 
-    def is_empty(self):
+    def is_empty(self) -> bool:
         """Checks if the permission overwrite is currently empty.
 
         An empty permission overwrite is one that has no overwrites set
@@ -596,7 +904,7 @@ def is_empty(self):
         """
         return len(self._values) == 0
 
-    def update(self, **kwargs):
+    def update(self, **kwargs: Optional[bool]) -> None:
         r"""Bulk updates this permission overwrite object.
 
         Allows you to set multiple attributes by using keyword
@@ -614,6 +922,10 @@ def update(self, **kwargs):
 
             setattr(self, key, value)
 
-    def __iter__(self):
+    def __iter__(self) -> Iterator[Tuple[PermissionFlag, bool]]:
+        """Returns an iterator of ``(perm, value)`` pairs.
+        This allows it to be, for example, constructed as a dict or a list  of pairs.
+
+        Note that aliases are not shown."""
         for key in self.PURE_FLAGS:
             yield key, self._values.get(key)
diff --git a/discord/player.py b/discord/player.py
index 413e5de6..e14bb0b6 100644
--- a/discord/player.py
+++ b/discord/player.py
@@ -23,10 +23,26 @@
 FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 DEALINGS IN THE SOFTWARE.
 """
+from __future__ import annotations
+
+from typing import (
+    overload,
+    Union,
+    Optional,
+    TYPE_CHECKING
+)
+
+if TYPE_CHECKING:
+    from typing_extensions import (
+        Literal
+    )
+    from io import BufferedIOBase
+    from os import PathLike
 
 import threading
 import traceback
 import subprocess
+# TODO: find a replacement for audioop at is deprecated and slated for removal in 3.13
 import audioop
 import asyncio
 import logging
@@ -56,6 +72,7 @@
 else:
     CREATE_NO_WINDOW = 0x08000000
 
+
 class AudioSource:
     """Represents an audio stream.
 
@@ -102,6 +119,7 @@ def cleanup(self):
     def __del__(self):
         self.cleanup()
 
+
 class PCMAudio(AudioSource):
     """Represents raw 16-bit 48KHz stereo PCM audio source.
 
@@ -119,6 +137,7 @@ def read(self):
             return b''
         return ret
 
+
 class FFmpegAudio(AudioSource):
     """Represents an FFmpeg (or AVConv) based AudioSource.
 
@@ -171,6 +190,7 @@ def cleanup(self):
 
         self._process = self._stdout = None
 
+
 class FFmpegPCMAudio(FFmpegAudio):
     """An audio source from FFmpeg (or AVConv).
 
@@ -205,8 +225,41 @@ class FFmpegPCMAudio(FFmpegAudio):
     ClientException
         The subprocess failed to be created.
     """
-
-    def __init__(self, source, *, executable='ffmpeg', pipe=False, stderr=None, before_options=None, options=None):
+    
+    @overload
+    def __init__(
+            self,
+            source: Union[str, PathLike[str]],
+            *,
+            executable='ffmpeg',
+            pipe: Literal[False] = False,
+            stderr=None,
+            before_options: Optional[str] = None,
+            options: Optional[str] = None
+    ): ...
+
+    @overload
+    def __init__(
+            self,
+            source: BufferedIOBase,
+            *,
+            executable='ffmpeg',
+            pipe: Literal[True] = True,
+            stderr=None,
+            before_options: Optional[str] = None,
+            options: Optional[str] = None
+    ): ...
+
+    def __init__(
+            self,
+            source: Union[str, PathLike[str], BufferedIOBase],
+            *,
+            executable: str = 'ffmpeg',
+            pipe: bool = False,
+            stderr=None,
+            before_options: Optional[str] = None,
+            options: Optional[str] = None
+    ):
         args = []
         subprocess_kwargs = {'stdin': source if pipe else subprocess.DEVNULL, 'stderr': stderr}
 
@@ -233,6 +286,7 @@ def read(self):
     def is_opus(self):
         return False
 
+
 class FFmpegOpusAudio(FFmpegAudio):
     """An audio source from FFmpeg (or AVConv).
 
@@ -495,6 +549,7 @@ def read(self):
     def is_opus(self):
         return True
 
+
 class PCMVolumeTransformer(AudioSource):
     """Transforms a previous :class:`AudioSource` to have volume controls.
 
@@ -543,6 +598,7 @@ def read(self):
         ret = self.original.read()
         return audioop.mul(ret, 2, min(self._volume, 2.0))
 
+
 class AudioPlayer(threading.Thread):
     DELAY = OpusEncoder.FRAME_LENGTH / 1000.0
 
diff --git a/discord/raw_models.py b/discord/raw_models.py
index 7ea67c25..4f0ffde8 100644
--- a/discord/raw_models.py
+++ b/discord/raw_models.py
@@ -3,9 +3,7 @@
 """
 The MIT License (MIT)
 
-Copyright (c) 2015-present Rapptz
-
-Implementing of the Discord-Message-components made by mccoderpy (Discord-User mccuber04#2960)
+Copyright (c) 2015-2021 Rapptz & 2021-present mccoderpy
 
 Permission is hereby granted, free of charge, to any person obtaining a
 copy of this software and associated documentation files (the "Software"),
@@ -25,13 +23,20 @@
 FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 DEALINGS IN THE SOFTWARE.
 """
-import sys
-import typing
+
+from __future__ import annotations
+
+from typing import TYPE_CHECKING, Optional
+
+from .utils import _get_as_snowflake
 from .member import Member
 from .user import User
+from .partial_emoji import PartialEmoji
 from .message import Message
-from .errors import NotFound, UnknowInteraction
-from .channel import DMChannel
+from .enums import ReactionType, try_enum
+
+if TYPE_CHECKING:
+    from .state import ConnectionState
 
 
 class _RawReprMixin:
@@ -162,7 +167,7 @@ class RawReactionActionEvent(_RawReprMixin):
     """
 
     __slots__ = ('message_id', 'user_id', 'channel_id', 'guild_id', 'emoji',
-                 'event_type', 'member')
+                 'event_type', '_type', 'member')
 
     def __init__(self, data, emoji, event_type):
         self.message_id = int(data['message_id'])
@@ -171,12 +176,24 @@ def __init__(self, data, emoji, event_type):
         self.emoji = emoji
         self.event_type = event_type
         self.member = None
+        self._type = data.get('type', 0)
 
         try:
             self.guild_id = int(data['guild_id'])
         except KeyError:
             self.guild_id = None
 
+    @property
+    def type(self) -> ReactionType:
+        """
+        :class:`ReactionType`: The type of reaction; e.g. normal or burst.
+
+        .. versionadded:: 2.0
+        """
+        return try_enum(ReactionType, self._type)
+
+    # TODO: Add support for things like query reaction members and co. from here.
+
 
 class RawReactionClearEvent(_RawReprMixin):
     """Represents the payload for a :func:`on_raw_reaction_clear` event.
@@ -233,34 +250,52 @@ def __init__(self, data, emoji):
             self.guild_id = None
 
 
-class RawInteractionCreateEvent(_RawReprMixin):
-    def __init__(self, data, http=None):
-        self.http = http
-        self._type = data.get('t', data.get('type', None))
-        d = data.get('d', None)
-        if d:
-            self.__token = d.get('token', None)
-            self._version = d.get('version', None)
-            self._type = d.get(type, None)
-            if self._type != 'INTERACTION_CREATE':
-                return
-        else:
-            self._version = data.get('version', None)
-            self._type = data.get('type', None)
-            self.__token = data.get('token', None)
-        self._raw = data
-        self._message_id = data.get('message').get('id', None)
-        self._data = data.get('data', None)
-        self._member = data.get('member', None)
-        self._user = data.get('user', self._member.get('user'))
-        self.__interaction_id = data.get('id', 0)
-        self._guild_id = data.get('guild_id', 0)
-        self._channel_id = data.get('channel_id', 0)
-        self.__application_id = data.get('application_id', 0)
-        self.guild = None
-        self.channel = None
-        self.member: Member = None
-        self.user: User = None
-        self.button = (self._data)
-        self.message: Message = None
-        self._deferred = False
\ No newline at end of file
+class VoiceChannelEffectSendEvent(_RawReprMixin):
+    """
+    Represents the payload for an :func:`on_voice_channel_effect_send` event.
+
+    .. versionadded:: 2.0
+
+    Attributes
+    -----------
+    guild_id: :class:`int`
+        The guild ID where the effect is being sent.
+    channel_id: :class:`int`
+        The channel ID where the effect is being sent.
+    user_id: :class:`int`
+        The user ID who sent the effect.
+    emoji: Optional[:class:`PartialEmoji`]
+        The emoji used when this is an emoji effect or the emoji associated to the sound.
+    sound_id: Optional[:class:`int`]
+        The sound ID of the soundboard sound used, if any.
+    sound_volume: Optional[:class:`float`]
+        The volume of the soundboard sound used, if any.
+    """
+
+    __slots__ = ('guild_id', 'channel_id', 'user_id', 'emoji', 'sound_id', 'sound_volume')
+
+    if TYPE_CHECKING:
+        _state: ConnectionState
+        guild_id: int
+        channel_id: int
+        user_id: int
+        emoji: Optional[PartialEmoji]
+        sound_id: Optional[int]
+        sound_volume: Optional[float]
+
+    def __init__(self, state, data):
+        self._state = state
+        self.guild_id = int(data['guild_id'])
+        self.channel_id = int(data['channel_id'])
+        self.user_id = int(data['user_id'])
+        emoji = data.get('emoji')
+        self.emoji = PartialEmoji.with_state(state, **emoji) if emoji else None
+        self.sound_id = _get_as_snowflake(data, 'sound_id')
+        self.sound_volume = data.get('sound_volume')
+
+    @property
+    def type(self) -> str:
+        """
+        :class:`str`: The type of effect being sent. Can be ``emoji`` or ``sound``.
+        """
+        return 'emoji' if self.sound_id is None else 'sound'
diff --git a/discord/reaction.py b/discord/reaction.py
index 437c0fe9..213e045b 100644
--- a/discord/reaction.py
+++ b/discord/reaction.py
@@ -3,7 +3,7 @@
 """
 The MIT License (MIT)
 
-Copyright (c) 2015-present Rapptz
+Copyright (c) 2015-2021 Rapptz & (c) 2021-present mccoderpy
 
 Permission is hereby granted, free of charge, to any person obtaining a
 copy of this software and associated documentation files (the "Software"),
@@ -23,14 +23,30 @@
 FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 DEALINGS IN THE SOFTWARE.
 """
+from __future__ import annotations
+
+from typing import (
+    Optional,
+    TYPE_CHECKING,
+    Union,
+)
+
+if TYPE_CHECKING:
+    from .types.message import Reaction as ReactionPayload
+    from .message import Message
+    from .emoji import Emoji
+    from .partial_emoji import PartialEmoji
+    from .abc import Snowflake
 
 from .iterators import ReactionIterator
+from .enums import try_enum, ReactionType
+
 
 class Reaction:
     """Represents a reaction to a message.
 
-    Depending on the way this object was created, some of the attributes can
-    have a value of ``None``.
+    Depending on the way this object was created, some attributes can
+    have a value of ``None``
 
     .. container:: operations
 
@@ -55,45 +71,61 @@ class Reaction:
     Attributes
     -----------
     emoji: Union[:class:`Emoji`, :class:`PartialEmoji`, :class:`str`]
-        The reaction emoji. May be a custom emoji, or a unicode emoji.
+        The reaction emoji. Might be a custom emoji, or a unicode emoji.
     count: :class:`int`
-        Number of times this reaction was made
+        Number of times this reaction was made.
     me: :class:`bool`
         If the user sent this reaction.
     message: :class:`Message`
         Message this reaction is for.
     """
-    __slots__ = ('message', 'count', 'emoji', 'me')
+    __slots__ = ('message', 'count', 'emoji', 'me', '_type')
 
-    def __init__(self, *, message, data, emoji=None):
-        self.message = message
-        self.emoji = emoji or message._state.get_reaction_emoji(data['emoji'])
-        self.count = data.get('count', 1)
-        self.me = data.get('me')
+    def __init__(self, *, message: Message, data: ReactionPayload, emoji: Optional[Union[Emoji, PartialEmoji, str]] = None):
+        self.message: Message = message
+        self.emoji: Union[Emoji, PartialEmoji, str] = emoji or message._state.get_emoji_from_partial(data['emoji'])
+        count_details = data.get('count_details', {})
 
-    @property
-    def custom_emoji(self):
-        """:class:`bool`: If this is a custom emoji."""
-        return not isinstance(self.emoji, str)
+        # The burst reactions api is still not stable yet, that's why the code looks like this for now
+        normal_count: int = data.get('count', count_details.get('normal', 0))
+        burst_count: int = data.get('burst_count', count_details.get('burst', 0))
+
+        self.count: int = (burst_count + normal_count) or 1  # this should be fine for now
+        self.me: bool = data.get('me')
+        self._type = data.get('type', 0)
 
-    def __eq__(self, other):
+    def __eq__(self, other) -> bool:
         return isinstance(other, self.__class__) and other.emoji == self.emoji
 
-    def __ne__(self, other):
+    def __ne__(self, other) -> bool:
         if isinstance(other, self.__class__):
             return other.emoji != self.emoji
         return True
 
-    def __hash__(self):
+    def __hash__(self) -> int:
         return hash(self.emoji)
 
-    def __str__(self):
+    def __str__(self) -> str:
         return str(self.emoji)
 
-    def __repr__(self):
-        return '<Reaction emoji={0.emoji!r} me={0.me} count={0.count}>'.format(self)
+    def __repr__(self) -> str:
+        return f'<Reaction emoji={self.emoji!r} me={self.me} count={self.count} type={self.type}'
+
+    @property
+    def custom_emoji(self) -> bool:
+        """:class:`bool`: If this is a custom emoji."""
+        return not isinstance(self.emoji, str)
+
+    @property
+    def type(self) -> ReactionType:
+        """:class:`ReactionType`: The type of this reaction; normal or burst."""
+        return try_enum(ReactionType, self._type)
+
+    def is_burst(self) -> bool:
+        """:class:`bool`: Whether this is a burst reaction or not."""
+        return self._type == 1
 
-    async def remove(self, user):
+    async def remove(self, user: Snowflake) -> None:
         """|coro|
 
         Remove the reaction by the provided :class:`User` from the message.
@@ -121,7 +153,7 @@ async def remove(self, user):
 
         await self.message.remove_reaction(self.emoji, user)
 
-    async def clear(self):
+    async def clear(self) -> None:
         """|coro|
 
         Clears this reaction from the message.
@@ -143,7 +175,7 @@ async def clear(self):
         """
         await self.message.clear_reaction(self.emoji)
 
-    def users(self, limit=None, after=None):
+    def users(self, limit: Optional[int] = None, after: Optional[Snowflake] = None) -> ReactionIterator:
         """Returns an :class:`AsyncIterator` representing the users that have reacted to the message.
 
         The ``after`` parameter must represent a member
@@ -196,4 +228,4 @@ def users(self, limit=None, after=None):
         if limit is None:
             limit = self.count
 
-        return ReactionIterator(self.message, emoji, limit, after)
+        return ReactionIterator(self.message, emoji, self._type, limit, after)
diff --git a/discord/relationship.py b/discord/relationship.py
deleted file mode 100644
index 0a9fffda..00000000
--- a/discord/relationship.py
+++ /dev/null
@@ -1,87 +0,0 @@
-# -*- coding: utf-8 -*-
-
-"""
-The MIT License (MIT)
-
-Copyright (c) 2015-present Rapptz
-
-Permission is hereby granted, free of charge, to any person obtaining a
-copy of this software and associated documentation files (the "Software"),
-to deal in the Software without restriction, including without limitation
-the rights to use, copy, modify, merge, publish, distribute, sublicense,
-and/or sell copies of the Software, and to permit persons to whom the
-Software is furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
-DEALINGS IN THE SOFTWARE.
-"""
-
-from .enums import RelationshipType, try_enum
-from . import utils
-
-class Relationship:
-    """Represents a relationship in Discord.
-
-    A relationship is like a friendship, a person who is blocked, etc.
-    Only non-bot accounts can have relationships.
-
-    .. deprecated:: 1.7
-
-    Attributes
-    -----------
-    user: :class:`User`
-        The user you have the relationship with.
-    type: :class:`RelationshipType`
-        The type of relationship you have.
-    """
-
-    __slots__ = ('type', 'user', '_state')
-
-    def __init__(self, *, state, data):
-        self._state = state
-        self.type = try_enum(RelationshipType, data['type'])
-        self.user = state.store_user(data['user'])
-
-    def __repr__(self):
-        return '<Relationship user={0.user!r} type={0.type!r}>'.format(self)
-
-    @utils.deprecated()
-    async def delete(self):
-        """|coro|
-
-        Deletes the relationship.
-
-        .. deprecated:: 1.7
-
-        Raises
-        ------
-        HTTPException
-            Deleting the relationship failed.
-        """
-
-        await self._state.http.remove_relationship(self.user.id)
-
-    @utils.deprecated()
-    async def accept(self):
-        """|coro|
-
-        Accepts the relationship request. e.g. accepting a
-        friend request.
-
-        .. deprecated:: 1.7
-
-        Raises
-        -------
-        HTTPException
-            Accepting the relationship failed.
-        """
-
-        await self._state.http.add_relationship(self.user.id)
diff --git a/discord/role.py b/discord/role.py
index 5fe20fcf..48c668c5 100644
--- a/discord/role.py
+++ b/discord/role.py
@@ -3,7 +3,7 @@
 """
 The MIT License (MIT)
 
-Copyright (c) 2015-present Rapptz
+Copyright (c) 2015-2021 Rapptz & (c) 2021-present mccoderpy
 
 Permission is hereby granted, free of charge, to any person obtaining a
 copy of this software and associated documentation files (the "Software"),
@@ -23,12 +23,16 @@
 FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 DEALINGS IN THE SOFTWARE.
 """
+from typing import Optional, Union
+from typing_extensions import Literal, Annotated
 
+from .asset import Asset
 from .permissions import Permissions
 from .errors import InvalidArgument
 from .colour import Colour
 from .mixins import Hashable
-from .utils import snowflake_time, _get_as_snowflake
+from .utils import snowflake_time, _get_as_snowflake, _bytes_to_base64_data
+
 
 class RoleTags:
     """Represents tags on a role.
@@ -76,6 +80,7 @@ def __repr__(self):
         return '<RoleTags bot_id={0.bot_id} integration_id={0.integration_id} ' \
                'premium_subscriber={1}>'.format(self, self.is_premium_subscriber())
 
+
 class Role(Hashable):
     """Represents a Discord role in a :class:`Guild`.
 
@@ -122,7 +127,11 @@ class Role(Hashable):
     guild: :class:`Guild`
         The guild the role belongs to.
     hoist: :class:`bool`
-         Indicates if the role will be displayed separately from other members.
+        Indicates if the role will be displayed separately from other members.
+    icon: Optional[:class:`str`]
+        The role-icon hash
+    unicode_emoji: Optional[:class:`str`]
+        The unicode emoji of the role (shows as role-icon)
     position: :class:`int`
         The position of the role. This number is usually positive. The bottom
         role has a position of 0.
@@ -135,8 +144,8 @@ class Role(Hashable):
         The role tags associated with this role.
     """
 
-    __slots__ = ('id', 'name', '_permissions', '_colour', 'position',
-                 'managed', 'mentionable', 'hoist', 'guild', 'tags', '_state')
+    __slots__ = ('id', 'name', '_permissions', '_colour', 'position', 'managed',
+                 'mentionable', 'hoist', 'guild', 'tags', '_state', 'icon', 'unicode_emoji')
 
     def __init__(self, *, guild, state, data):
         self.guild = guild
@@ -187,14 +196,15 @@ def __ge__(self, other):
         return not r
 
     def _update(self, data):
-        self.name = data['name']
-        self._permissions = int(data.get('permissions', 0))
-        self.position = data.get('position', 0)
-        self._colour = data.get('color', 0)
-        self.hoist = data.get('hoist', False)
-        self.managed = data.get('managed', False)
-        self.mentionable = data.get('mentionable', False)
-
+        self.name: str = data['name']
+        self._permissions: int = int(data.get('permissions', 0))
+        self.position: int = data.get('position', 0)
+        self._colour: int = data.get('color', 0)
+        self.hoist: bool = data.get('hoist', False)
+        self.managed: bool = data.get('managed', False)
+        self.mentionable: bool = data.get('mentionable', False)
+        self.icon: Optional[str] = data.get('icon', None)
+        self.unicode_emoji: Optional[str] = data.get('unicode_emoji', None)
         try:
             self.tags = RoleTags(data['tags'])
         except KeyError:
@@ -260,6 +270,36 @@ def members(self):
         role_id = self.id
         return [member for member in all_members if member._roles.has(role_id)]
 
+    @property
+    def icon_url(self):
+        """:class:`Asset`: Returns the role icon asset."""
+        return self.icon_url_as()
+
+    def icon_url_as(self, *, format: Literal['jpeg', 'jpg', 'webp', 'png'] = 'webp', size = 1024):
+        """Returns an :class:`Asset` for the role icon.
+
+        The format must be one of 'webp', 'jpeg', or 'png'. The
+        size must be a power of 2 between 16 and 4096.
+
+        Parameters
+        -----------
+        format: :class:`str`
+            The format to attempt to convert the icon to.
+        size: :class:`int`
+            The size of the image to display.
+
+        Raises
+        ------
+        InvalidArgument
+            Bad image format passed to ``format`` or invalid ``size``.
+
+        Returns
+        --------
+        :class:`Asset`
+            The resulting CDN asset.
+        """
+        return Asset._from_icon(self._state, self, 'role', format=format, size=size)
+
     async def _move(self, position, reason):
         if position <= 0:
             raise InvalidArgument("Cannot move role to position 0 or below")
@@ -283,7 +323,7 @@ async def _move(self, position, reason):
         payload = [{"id": z[0], "position": z[1]} for z in zip(roles, change_range)]
         await http.move_role_position(self.guild.id, payload, reason=reason)
 
-    async def edit(self, *, reason=None, **fields):
+    async def edit(self, *, reason: Optional[str] = None, **fields):
         """|coro|
 
         Edits the role.
@@ -311,6 +351,13 @@ async def edit(self, *, reason=None, **fields):
         position: :class:`int`
             The new role's position. This must be below your top role's
             position or it will fail.
+        unicode_emoji: :class:`str`
+            The new role-icon as a unicode-emoji
+            This is only available for guilds that contain ``ROLE_ICON`` in :attr:`Guild.features`.
+        icon: :class:`bytes`
+            A :term:`py:bytes-like object` representing the new role-icon. Only PNG/JPEG is supported.
+            This is only available for guilds that contain ``ROLE_ICON`` in :attr:`Guild.features`.
+            Could be ``None`` to denote removal of the icon.
         reason: Optional[:class:`str`]
             The reason for editing this role. Shows up on the audit log.
 
@@ -338,14 +385,37 @@ async def edit(self, *, reason=None, **fields):
         if isinstance(colour, int):
             colour = Colour(value=colour)
 
+        try:
+            icon_bytes: Optional[bytes] = fields['icon']
+        except KeyError:
+            icon = self.icon
+        else:
+            if icon_bytes is not None:
+                icon = _bytes_to_base64_data(icon_bytes)
+            else:
+                icon = None
+
+        try:
+            unicode_emoji: Optional[str] = fields['unicode_emoji']
+        except KeyError:
+            unicode_emoji = self.unicode_emoji
+        else:
+            if unicode_emoji is not None:
+                unicode_emoji = str(unicode_emoji)
+            else:
+                unicode_emoji = None
+
         payload = {
             'name': fields.get('name', self.name),
             'permissions': str(fields.get('permissions', self.permissions).value),
             'color': colour.value,
             'hoist': fields.get('hoist', self.hoist),
-            'mentionable': fields.get('mentionable', self.mentionable)
+            'icon': icon,
+            'unicode_emoji': unicode_emoji,
+            'mentionable': fields.get('mentionable', self.mentionable),
         }
 
+
         data = await self._state.http.edit_role(self.guild.id, self.id, reason=reason, **payload)
         self._update(data)
 
diff --git a/discord/scheduled_event.py b/discord/scheduled_event.py
new file mode 100644
index 00000000..190ee370
--- /dev/null
+++ b/discord/scheduled_event.py
@@ -0,0 +1,418 @@
+# -*- coding: utf-8 -*-
+
+"""
+The MIT License (MIT)
+
+Copyright (c) 2021-present mccoderpy
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+"""
+from __future__ import annotations
+
+from typing_extensions import Literal
+from typing import Any, Optional, Union, Dict, TYPE_CHECKING
+
+from datetime import datetime
+
+from .mixins import Hashable
+from .errors import InvalidArgument
+from .utils import _get_as_snowflake, cached_slot_property, _bytes_to_base64_data, utcnow, MISSING
+from .enums import PrivacyLevel, EventEntityType, EventStatus, try_enum
+from .iterators import EventUsersIterator
+
+
+if TYPE_CHECKING:
+    from .types.guild import (
+        ScheduledEventEntityMetadata as ScheduledEventEntityMetadataData,
+        ScheduledEvent as ScheduledEventData,
+    )
+    from .state import ConnectionState
+    from .asset import Asset
+    from .guild import Guild
+    from .user import User
+    from .channel import StageChannel, VoiceChannel
+
+__all__ = (
+    'GuildScheduledEvent',
+)
+
+
+class GuildScheduledEvent(Hashable):
+    """
+    Represents a scheduled event in a guild
+
+    .. warning::
+        Do not initialize this class manually. Use :meth:`~discord.Guild.fetch_event`/:meth:`~discord.Guild.fetch_events`
+        or to create one :meth:`~discord.Guild.create_scheduled_event` instead.
+
+    Attributes
+    -----------
+    id: :class:`int`
+        The id of the event
+    name: :class:`str`
+        The name of the event
+    description: :class:`str`
+        The description of the event
+    start_time: :class:`datetime.datetime`
+        When the event will start
+    end_time: Optional[:class:`datetime.datetime`]
+        Optional, when the event will end
+    creator: :class:`~discord.User`
+        The creator of the event
+    status: :class:`EventStatus`
+        The status of the event
+    entity_type: :class:`EventEntityType`
+        The type of the scheduled event
+    image: Optional[:class:`str`]
+        Optional, the image hash of the event
+    broadcast_to_directory_channels: :class:`bool`
+        Whether the event will be broadcasted to directory channels
+
+        .. note::
+            This is only possible when the guild the event belongs to is part of a student hub.
+    """
+    if TYPE_CHECKING:
+        name: str
+        guild_id: int
+        status: EventStatus
+        entity_type: EventEntityType
+        privacy_level: PrivacyLevel
+        channel_id: Optional[int]
+        creator_id: Optional[int]
+        description: Optional[str]
+        start_time: datetime
+        end_time: Optional[datetime]
+        entity_id: Optional[int]
+        image: Optional[str]
+        creator: Optional[User]
+        user_count: Optional[int]
+        broadcast_to_directory_channels: bool
+        _entity_meta: Optional[ScheduledEventEntityMetadataData]
+
+    def __init__(self, state: ConnectionState, guild: Guild, data: ScheduledEventData) -> None:
+        self._state: ConnectionState = state
+        self.id: int = int(data['id'])
+        self.guild: Guild = guild or self.guild
+        self._update(data)
+
+    def _update(self, data: ScheduledEventData) -> None:
+        state = self._state
+        self.name = data['name']
+        self.guild_id = int(data['guild_id'])
+        self.channel_id = _get_as_snowflake(data, 'channel_id')
+        self.creator_id = _get_as_snowflake(data, 'creator_id')
+        self.description = data.get('description')
+        self.start_time = datetime.fromisoformat(data['scheduled_start_time'])
+        self.end_time = datetime.fromisoformat(data['scheduled_end_time']) \
+            if data['scheduled_end_time'] is not None else None
+        self.privacy_level = try_enum(PrivacyLevel, data['privacy_level'])
+        self.status = try_enum(EventStatus, data['status'])
+        self.entity_type = try_enum(EventEntityType, data['entity_type'])
+        self.entity_id = _get_as_snowflake(data, 'entity_id')
+        self._entity_meta = data.get('entity_metadata')
+        self.image = data.get('image')
+        creator = data.pop('creator', None)
+        if creator:
+            self.creator = state.store_user(data=creator)
+        else:
+            self.creator = state.get_user(self.creator_id) or None
+        self.user_count = data.get('user_count')
+        self.broadcast_to_directory_channels = data.get('broadcast_to_directory_channels', False)
+
+    @cached_slot_property
+    def guild(self) -> Optional[Guild]:
+        """Optional[:class:`Guild`]: The guild the event is scheduled in, if cached."""
+        return self._state._get_guild(self.guild_id)
+
+    @property
+    def location(self) -> Optional[str]:
+        """Optional[:class:`str`]: The location of the event if :attr:`.entity_type` is ``external``."""
+        if self._entity_meta:
+            return self._entity_meta.get('location', None)
+
+    @property
+    def channel(self) -> Optional[Union[StageChannel, VoiceChannel]]:
+        """Optional[Union[:class:`StageChannel`, :class:`VoiceChannel`]]:
+        The channel the event is scheduled in if :attr:`.entity_type` is ``stage`` or ``voice``.
+        """
+        if self.creator_id:
+            return self.guild.get_channel(self.channel_id)
+
+    @property
+    def icon_url(self) -> Asset:
+        """:class:`Asset`: Returns the event image asset."""
+        return self.icon_url_as()
+
+    def icon_url_as(
+        self,
+        *,
+        format: Literal['jpeg', 'jpg', 'webp', 'png'] = 'webp',
+        size: int = 1024
+    ) -> Asset:
+        """Returns an :class:`Asset` for the event image.
+
+        The format must be one of 'webp', 'jpeg', or 'png'. The
+        size must be a power of 2 between 16 and 4096.
+
+        Parameters
+        -----------
+        format: :class:`str`
+            The format to attempt to convert the icon to.
+        size: :class:`int`
+            The size of the image to display.
+
+        Raises
+        ------
+        InvalidArgument
+            Bad image format passed to ``format`` or invalid ``size``.
+
+        Returns
+        --------
+        :class:`Asset`
+            The resulting CDN asset.
+        """
+        from discord import Asset
+        return Asset._from_guild_event(self._state, self, format=format, size=size)
+
+    async def edit(
+        self,
+        *,
+        name: str = MISSING,
+        description: str = MISSING,
+        start_time: datetime = MISSING,
+        end_time: Optional[datetime] = MISSING,
+        status: EventStatus = MISSING,
+        entity_type: EventEntityType = MISSING,
+        location: str = MISSING,
+        channel: Optional[Union[StageChannel, VoiceChannel]] = MISSING,
+        cover_image: Optional[bytes] = MISSING,
+        reason: Optional[str] = None
+    ) -> GuildScheduledEvent:
+        """|coro|
+
+        Modify the event. Requires :attr:`~Permissions.manage_events` permissions.
+        All parameters are optional.
+
+        Parameters
+        ----------
+        name: :class:`str`
+            The new name of the event
+        description: :class:`str`
+            The new description of the event
+        start_time: :class:`datetime.datetime`
+            The new start time of the event
+        end_time: Optional[:class:`datetime.datetime`]
+            The new end time of the event
+        status: :class:`EventStatus`
+            The new status of the event.
+        entity_type: :class:`EventEntityType`
+            The new type of the scheduled event
+        location: :class:`str`
+            The new location of the event. If ``entity_type`` is :attr:`~EventEntityType.external`
+        channel: Optional[Union[:class:`StageChannel, :class:`VoiceChannel`]]
+            The new channel the event is scheduled in if ``entity_type`` is :attr:`EventEntityType.stage` or
+            :attr:`EventEntityType.voice`.
+        cover_image: Optional[:class:`bytes`]
+            The new cover image of the event. Must be a :attr:`bytes` object representing a jpeg or png image.
+        reason: Optional[:class:`str`]
+            The reason for editing the event, shows up in the audit-log.
+
+        Returns
+        -------
+        :class:`GuildScheduledEvent`
+            The updatet event.
+        """
+
+        payload: Dict[str, Any] = {}
+
+        if entity_type is MISSING:
+            entity_type = self.entity_type
+        else:
+            payload['entity_type'] = int(entity_type)
+
+        if name is not MISSING:
+            if 1 > len(name) > 100:
+                raise ValueError(f'The length of the name must be between 1 and 100 characters long; got {len(name)}.')
+            payload['name'] = name
+
+        if description is not MISSING:
+            if 1 > len(description) > 1000:
+                raise ValueError(
+                    f'The length of the description must be between 1 and 1000 characters long; got {len(description)}.'
+                )
+
+            payload['description'] = description
+
+        if location is not MISSING:
+            if 1 > len(location) > 100:
+                raise ValueError(
+                    f'The length of the location must be between 1 and 100 characters long; got {len(location)}.'
+                )
+            if not entity_type.external:
+                entity_type = EventEntityType.external
+                payload['entity_type'] = int(entity_type)
+            payload['entity_metadata'] = {'location': location}
+            payload['channel_id'] = None
+
+        if channel is not MISSING:
+            if channel.__class__.__name__ not in ('StageChannel', 'VoiceChannel'):
+                raise TypeError(
+                    f'The new channel must be a StageChannel or VoiceChannel object, not {channel.__class__.__name__}.'
+                )
+            if entity_type.external:
+                entity_type = {13: EventEntityType.stage, 2: EventEntityType.voice}.get(int(channel.type))
+                payload['entity_type'] = entity_type.value
+            payload['channel_id'] = str(channel.id)
+            payload['entity_metadata'] = None
+
+        if not entity_type.external and not channel:
+            raise InvalidArgument(
+                'A channel must be provided if type is EventEntityType.stage or EventEntityType.voice.'
+            )
+
+        if end_time is MISSING:
+            end_time = self.end_time
+        elif end_time is not None:
+            if not isinstance(end_time, datetime):
+                raise TypeError(f'The end_time must be a datetime.datetime object, not {end_time.__class__.__name__}.')
+            elif end_time < utcnow():
+                raise ValueError('The end_time could not be in the past.')
+            payload['scheduled_end_time'] = end_time.isoformat()
+        else:
+            payload['scheduled_end_time'] = None
+
+
+        if entity_type.external and not end_time:
+            raise ValueError('end_time is required for external events.')
+
+        if start_time is MISSING:
+            start_time = self.start_time
+        elif start_time is not None:
+            if not isinstance(start_time, datetime):
+                raise TypeError(
+                    f'The start_time must be a datetime.datetime object, not {start_time.__class__.__name__}.'
+                )
+            elif start_time < utcnow():
+                raise ValueError('The start_time could not be in the past.')
+            payload['scheduled_start_time'] = start_time.isoformat()
+        else:
+            payload['scheduled_start_time'] = None
+
+        if end_time and start_time > end_time:
+            raise ValueError('The start_time could not be before the end_time.')
+
+        if status is not MISSING:
+            if not isinstance(status, EventStatus):
+                raise TypeError(f'The status must be of type discord.EventStatus, not {status.__class__.__name__}.')
+            current_status = self.status
+            if current_status.canceled or current_status.completed:
+                raise ValueError('The status of an completed or canceled event could not be changed.')
+            elif current_status.active and not status.completed:
+                raise ValueError('The status of an active event could only be changed to completed.')
+            elif current_status.scheduled and not status.active or status.canceled:
+                raise ValueError('The status of an scheduled event could only be changed to active or canceled.')
+            payload['status'] = status.value
+
+        if cover_image is not MISSING:
+            if cover_image is not None:
+                if not isinstance(cover_image, bytes):
+                    raise ValueError(f'cover_image must be of type bytes, not {cover_image.__class__.__name__}')
+                cover_image = _bytes_to_base64_data(cover_image)
+            payload['image'] = cover_image
+
+        data = await self._state.http.edit_guild_event(
+            guild_id=self.guild_id,
+            event_id=self.id,
+            reason=reason,
+            payload=payload
+        )
+        self._update(data)
+        return self
+
+    async def users(
+        self,
+        limit: int = 100,
+        before: Union[User, datetime] = None,
+        after: Union[User, datetime] = None,
+        with_member: bool = False
+    ) -> EventUsersIterator:
+        """Returns an :class:`~discord.AsyncIterator` that enables receiving the interest users of the event.
+
+        All parameters are optional.
+
+        Parameters
+        -----------
+        limit: Optional[:class:`int`]
+            The number of users to retrieve.
+            If ``None``, retrieves every user of the event.
+            Note, however, that this would make it a slow operation.
+        before: Optional[Union[:class:`~discord.abc.Snowflake`, :class:`datetime.datetime`]]
+            Retrieve users before this user.
+            If a date is provided it must be a timezone-naive datetime representing UTC time.
+        after: Optional[Union[:class:`~discord.abc.Snowflake`, :class:`datetime.datetime`]]
+            Retrieve users after this user.
+            If a date is provided it must be a timezone-naive datetime representing UTC time.
+        with_member: Optional[:class:`bool`]
+            If set to ``True``, return the :class:`~discord.Member` instead of the :class:`~discord.User` if it is part of the guild the event is in.
+
+
+        Examples
+        ---------
+
+        .. code-block:: python3
+
+            # Usage
+
+            counter = 0
+            async for user in event.users(limit=200):
+                if user.id > 264905529753600000:  # all accounts created before 2018
+                    counter += 1
+
+            # Flattening into a list
+
+            users = await event.users(limit=123).flatten()
+            # users is now a list of Member/User...
+
+        Raises
+        ------
+        ~discord.Forbidden
+            You do not have permissions to get the event users.
+        ~discord.HTTPException
+            The request to get event users failed.
+
+        Yields
+        -------
+        Union[:class:`~discord.Member`, :class:`~discord.User`]
+            The user or member.
+        """
+        return EventUsersIterator(event=self, limit=limit, before=before, after=after, with_member=with_member)
+
+    async def delete(self, *, reason: Optional[str] = None) -> None:
+        """
+        Deletes the event. Requires ``MANAGE_EVENTS`` permissions.
+
+        Parameters
+        ----------
+        reason: Optional[:class:`str`]
+            The reason for deleting the event, shows up in the audit-log.
+        Returns
+        -------
+        None
+        """
+        await self._state.http.delete_guild_event(guild_id=self.guild_id, event_id=self.id, reason=reason)
\ No newline at end of file
diff --git a/discord/shard.py b/discord/shard.py
index 1ef9e923..082d4c68 100644
--- a/discord/shard.py
+++ b/discord/shard.py
@@ -3,7 +3,7 @@
 """
 The MIT License (MIT)
 
-Copyright (c) 2015-present Rapptz
+Copyright (c) 2015-2021 Rapptz & (c) 2021-present mccoderpy
 
 Permission is hereby granted, free of charge, to any person obtaining a
 copy of this software and associated documentation files (the "Software"),
diff --git a/discord/sink.py b/discord/sink.py
new file mode 100644
index 00000000..ae7c2c3c
--- /dev/null
+++ b/discord/sink.py
@@ -0,0 +1,214 @@
+"""
+The MIT License (MIT)
+
+Copyright (c) 2021-present mccoderpy
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+"""
+
+from .errors import ClientException
+import wave
+import os
+import threading
+import time
+import subprocess
+import sys
+import struct
+
+
+__all__ = (
+    'Filters',
+    'Sink',
+    'AudioData',
+    'RawData',
+)
+
+
+if sys.platform != 'win32':
+    CREATE_NO_WINDOW = 0
+else:
+    CREATE_NO_WINDOW = 0x08000000
+
+default_filters = {
+    'time': 0,
+    'users': [],
+    'max_size': 0,
+}
+
+
+class Filters:
+    # TODO: Filter for max size per file; audio can be split into multiple files
+    def __init__(self, **kwargs):
+        self.filtered_users = kwargs.get('users', default_filters['users'])
+        self.seconds = kwargs.get('time', default_filters['time'])
+        self.max_size = kwargs.get('max_size', default_filters['max_size'])
+        self.finished = False
+
+    @staticmethod
+    def filter_decorator(func):  # Contains all filters
+        def _filter(self, data, user):
+            if not self.filtered_users or user in self.filtered_users:
+                return func(self, data, user)
+        return _filter
+
+    def init(self):
+        if self.seconds != 0:
+            thread = threading.Thread(target=self.wait_and_stop)
+            thread.start()
+
+    def wait_and_stop(self):
+        time.sleep(self.seconds)
+        if self.finished:
+            return
+        self.vc.stop_recording()
+
+
+class RawData:
+    """Handles raw data from Discord so that it can be decrypted and decoded to be used."""
+
+    def __init__(self, data, client):
+        self.data = bytearray(data)
+        self.client = client
+
+        self.header = data[:12]
+        self.data = self.data[12:]
+
+        unpacker = struct.Struct('>xxHII')
+        self.sequence, self.timestamp, self.ssrc = unpacker.unpack_from(self.header)
+        self.decrypted_data = getattr(self.client, '_decrypt_' + self.client.mode)(self.header, self.data)
+        self.decoded_data = None
+
+        self.user_id = None
+
+
+class AudioData:
+    """Handles data that's been completely decrypted and decoded and is ready to be saved to file."""
+
+    def __init__(self, file):
+        self.file = open(file, 'ab')
+        self.dir_path = os.path.split(file)[0]
+
+        self.finished = False
+
+    def write(self, data):
+        if self.finished:
+            raise ClientException("This AudioData is already finished writing.")
+        self.file.write(data)
+
+    def cleanup(self):
+        if self.finished:
+            raise ClientException("This AudioData is already finished writing.")
+        self.file.close()
+        self.file = os.path.join(self.dir_path, self.file.name)
+        self.finished = True
+
+    def on_format(self, encoding):
+        if not self.finished:
+            raise ClientException("This AudioData is still writing.")
+        name = os.path.split(self.file)[1]
+        name = name.split('.')[0] + f'.{encoding}'
+        self.file = os.path.join(self.dir_path, name)
+
+
+class Sink(Filters):
+    """A Sink "stores" all the audio data.
+        Parameters
+        ----------
+        encoding: :class:`string`
+            The encoding to use. Valid types include wav, mp3, and pcm (even though it's not an actual encoding).
+        output_path: :class:`string`
+            A path to where the audio files should be output.
+        Raises
+        ------
+        ClientException
+            An invalid encoding type was specified.
+    """
+
+    valid_encodings = ['wav', 'mp3', 'pcm']
+
+    def __init__(self, *, encoding='wav', output_path='', filters=None):
+        if filters is None:
+            filters = default_filters
+        self.filters = filters
+        Filters.__init__(self, **self.filters)
+
+        encoding = encoding.lower()
+
+        # Would also like to add opus but don't
+        # know how I would go about it.
+        if encoding not in self.valid_encodings:
+            raise ClientException("An invalid encoding type was specified.")
+
+        self.encoding = encoding
+        self.file_path = output_path
+        self.vc = None
+        self.audio_data = {}
+
+    def init(self, vc):  # called under start_recording
+        self.vc = vc
+        super().init()
+
+    @Filters.filter_decorator
+    def write(self, data, user):
+        if user not in self.audio_data:
+            ssrc = self.vc.get_ssrc(user)
+            file = os.path.join(self.file_path, f'{ssrc}.pcm')
+            self.audio_data.update({user: AudioData(file)})
+
+        file = self.audio_data[user]
+        file.write(data)
+
+    def cleanup(self):
+        self.finished = True
+        for file in self.audio_data.values():
+            file.cleanup()
+            self.format_audio(file)
+
+    def format_audio(self, audio):
+        if self.vc.recording:
+            raise ClientException("Audio may only be formatted after recording is finished.")
+        if self.encoding == 'pcm':
+            return
+        if self.encoding == 'mp3':
+            mp3_file = audio.file.split('.')[0] + '.mp3'
+            args = ['ffmpeg', '-f', 's16le', '-ar', '48000', '-ac', '2', '-i', audio.file, mp3_file]
+            process = None
+            if os.path.exists(mp3_file):
+                os.remove(
+                    mp3_file)  # process will get stuck asking whether or not to overwrite, if file already exists.
+            try:
+                process = subprocess.Popen(args, creationflags=CREATE_NO_WINDOW)
+            except FileNotFoundError:
+                raise ClientException('ffmpeg was not found.') from None
+            except subprocess.SubprocessError as exc:
+                raise ClientException('Popen failed: {0.__class__.__name__}: {0}'.format(exc)) from exc
+            process.wait()
+        elif self.encoding == 'wav':
+            with open(audio.file, 'rb') as pcm:
+                data = pcm.read()
+                pcm.close()
+
+            wav_file = audio.file.split('.')[0] + '.wav'
+            with wave.open(wav_file, 'wb') as f:
+                f.setnchannels(self.vc.decoder.CHANNELS)
+                f.setsampwidth(self.vc.decoder.SAMPLE_SIZE // self.vc.decoder.CHANNELS)
+                f.setframerate(self.vc.decoder.SAMPLING_RATE)
+                f.writeframes(data)
+                f.close()
+
+        os.remove(audio.file)
+        audio.on_format(self.encoding)
diff --git a/discord/state.py b/discord/state.py
index d45c043e..60d62b23 100644
--- a/discord/state.py
+++ b/discord/state.py
@@ -3,9 +3,7 @@
 """
 The MIT License (MIT)
 
-Copyright (c) 2015-present Rapptz
-
-Implementing of the Discord-Message-components made by mccoderpy (Discord-User mccuber04#2960)
+Copyright (c) 2015-2021 Rapptz & (c) 2021-present mccoderpy
 
 Permission is hereby granted, free of charge, to any person obtaining a
 copy of this software and associated documentation files (the "Software"),
@@ -25,9 +23,9 @@
 FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 DEALINGS IN THE SOFTWARE.
 """
+from __future__ import annotations
 
 import asyncio
-import typing
 from collections import deque, OrderedDict
 import copy
 import datetime
@@ -39,25 +37,39 @@
 import gc
 
 import os
+from typing import Union, Callable, TYPE_CHECKING
 
 from .guild import Guild
+from .application_commands import GuildAppCommandPermissions
 from .activity import BaseActivity
+from .audit_logs import AuditLogEntry
+from .scheduled_event import GuildScheduledEvent
 from .user import User, ClientUser
 from .emoji import Emoji
+from .sticker import Sticker, GuildSticker
 from .mentions import AllowedMentions
 from .partial_emoji import PartialEmoji
 from .message import Message
-from .relationship import Relationship
 from .channel import *
 from .raw_models import *
 from .member import Member
 from .role import Role
-from .enums import ChannelType, try_enum, Status
+from .enums import ChannelType, try_enum, Status, MessageType, ComponentType, InteractionType
 from . import utils
-from .flags import Intents, MemberCacheFlags
+from .flags import Intents, MemberCacheFlags, ApplicationFlags
 from .object import Object
 from .invite import Invite
-from .interactions import Interaction, InteractionType
+from .automod import AutoModRule, AutoModActionPayload
+from .interactions import BaseInteraction
+from .monetization import Entitlement, Subscription
+
+if TYPE_CHECKING:
+    from .http import HTTPClient
+    from .client import Client
+    from .shard import AutoShardedClient
+    from .gateway import DiscordWebSocket
+    from .types import gateway as gw
+    from .types.emoji import PartialEmoji as PartialEmojiPayload
 
 
 class ChunkRequest:
@@ -112,20 +124,23 @@ async def logging_coroutine(coroutine, *, info):
 
 
 class ConnectionState:
+    _get_client: Callable[[], Client]
+    _get_websocket: Callable[[int], DiscordWebSocket]
+    
     def __init__(self, *, dispatch, handlers, hooks, syncer, http, loop, **options):
         self.loop = loop
-        self.http = http
+        self.http: HTTPClient = http
         self.max_messages = options.get('max_messages', 1000)
         if self.max_messages is not None and self.max_messages <= 0:
             self.max_messages = 1000
-
+        self.sync_commands_on_ready: bool = options.get('sync_commands', False)
         self.dispatch = dispatch
         self.syncer = syncer
-        self.is_bot = None
         self.handlers = handlers
         self.hooks = hooks
         self.shard_count = None
         self._ready_task = None
+        self.application_id = None
         self.heartbeat_timeout = options.get('heartbeat_timeout', 60.0)
         self.guild_ready_timeout = options.get('guild_ready_timeout', 2.0)
         if self.guild_ready_timeout < 0:
@@ -154,7 +169,7 @@ def __init__(self, *, dispatch, handlers, hooks, syncer, http, loop, **options):
             else:
                 status = str(status)
 
-        intents = options.get('intents', None)
+        intents: Intents = options.get('intents', None)
         if intents is not None:
             if not isinstance(intents, Intents):
                 raise TypeError('intents parameter must be Intent not %r' % type(intents))
@@ -206,7 +221,8 @@ def clear(self):
         self.user = None
         self._users = weakref.WeakValueDictionary()
         self._emojis = {}
-        self._calls = {}
+        self._stickers = {}
+        self._events = {}
         self._guilds = {}
         self._voice_clients = {}
 
@@ -277,7 +293,7 @@ def _update_references(self, ws):
         for vc in self.voice_clients:
             vc.main_ws = ws
 
-    def store_user(self, data):
+    def store_user(self, data) -> User:
         # this way is 300% faster than `dict.setdefault`.
         user_id = int(data['id'])
         try:
@@ -291,19 +307,40 @@ def store_user(self, data):
     def store_user_no_intents(self, data):
         return User(state=self, data=data)
 
-    def get_user(self, id):
+    def get_user(self, id) -> User:
         return self._users.get(id)
 
-    def store_emoji(self, guild, data):
+    def store_emoji(self, guild, data) -> Emoji:
         emoji_id = int(data['id'])
         self._emojis[emoji_id] = emoji = Emoji(guild=guild, state=self, data=data)
         return emoji
 
+    def store_sticker(self, data, pack=None) -> Union[Sticker, GuildSticker]:
+        sticker_id = int(data['id'])
+        guild_id = data.get('guild_id', None)
+        if guild_id:
+            self._stickers[sticker_id] = sticker = GuildSticker(state=self, data=data)
+        else:
+            self._stickers[sticker_id] = sticker = Sticker(state=self, data=data, pack=pack)
+        return sticker
+
+    def store_event(self, guild, data) -> GuildScheduledEvent:
+        event_id = int(data['id'])
+        try:
+            event = self._events[event_id]
+        except KeyError:
+            self._events[event_id] = event = GuildScheduledEvent(state=self, guild=guild, data=data)
+        try:
+            guild._add_event(event)
+        except AttributeError:  # If it is a PartialInviteGuild
+            pass
+        return event
+
     @property
     def guilds(self):
         return list(self._guilds.values())
 
-    def _get_guild(self, guild_id):
+    def _get_guild(self, guild_id) -> Guild:
         return self._guilds.get(guild_id)
 
     def _add_guild(self, guild):
@@ -315,6 +352,9 @@ def _remove_guild(self, guild):
         for emoji in guild.emojis:
             self._emojis.pop(emoji.id, None)
 
+        for event in guild.scheduled_events:
+            self._events.pop(event.id, None)
+
         del guild
 
         # Much like clear(), if we have a massive deallocation
@@ -328,6 +368,13 @@ def emojis(self):
     def get_emoji(self, emoji_id):
         return self._emojis.get(emoji_id)
 
+    @property
+    def stickers(self):
+        return list(self._stickers.values())
+
+    def get_sticker(self, sticker_id):
+        return self._stickers.get(sticker_id)
+
     @property
     def private_channels(self):
         return list(self._private_channels.values())
@@ -348,7 +395,7 @@ def _add_private_channel(self, channel):
         channel_id = channel.id
         self._private_channels[channel_id] = channel
 
-        if self.is_bot and len(self._private_channels) > 128:
+        if len(self._private_channels) > 128:
             _, to_remove = self._private_channels.popitem(last=False)
             if isinstance(to_remove, DMChannel):
                 self._private_channels_by_user.pop(to_remove.recipient.id, None)
@@ -366,7 +413,7 @@ def _remove_private_channel(self, channel):
         if isinstance(channel, DMChannel):
             self._private_channels_by_user.pop(channel.recipient.id, None)
 
-    def _get_message(self, msg_id):
+    def _get_message(self, msg_id) -> Message:
         return utils.find(lambda m: m.id == msg_id, reversed(self._messages)) if self._messages else None
 
     def _add_guild_from_data(self, guild):
@@ -383,12 +430,12 @@ def _get_guild_channel(self, data):
         try:
             guild = self._get_guild(int(data['guild_id']))
         except KeyError:
-            channel = DMChannel._from_message(self, channel_id)
+            channel = self.get_channel(channel_id)
             guild = None
         else:
             channel = guild and guild.get_channel(channel_id)
 
-        return channel or PartialMessageable(state=self, id=channel_id), guild
+        return channel or PartialMessageable(self, channel_id, guild_id=guild.id if guild else None), guild
 
     async def chunker(self, guild_id, query='', limit=0, presences=False, *, nonce=None):
         ws = self._get_websocket(guild_id) # This is ignored upstream
@@ -413,36 +460,34 @@ async def query_members(self, guild, query, limit, user_ids, cache, presences):
 
     async def _delay_ready(self):
         try:
-            # only real bots wait for GUILD_CREATE streaming
-            if self.is_bot:
-                states = []
-                while True:
-                    # this snippet of code is basically waiting N seconds
-                    # until the last GUILD_CREATE was sent
-                    try:
-                        guild = await asyncio.wait_for(self._ready_state.get(), timeout=self.guild_ready_timeout)
-                    except asyncio.TimeoutError:
-                        break
+            states = []
+            while True:
+                # this snippet of code is basically waiting N seconds
+                # until the last GUILD_CREATE was sent
+                try:
+                    guild = await asyncio.wait_for(self._ready_state.get(), timeout=self.guild_ready_timeout)
+                except asyncio.TimeoutError:
+                    break
+                else:
+                    if self._guild_needs_chunking(guild):
+                        future = await self.chunk_guild(guild, wait=False)
+                        states.append((guild, future))
                     else:
-                        if self._guild_needs_chunking(guild):
-                            future = await self.chunk_guild(guild, wait=False)
-                            states.append((guild, future))
+                        if guild.unavailable is False:
+                            self.dispatch('guild_available', guild)
                         else:
-                            if guild.unavailable is False:
-                                self.dispatch('guild_available', guild)
-                            else:
-                                self.dispatch('guild_join', guild)
-
-                for guild, future in states:
-                    try:
-                        await asyncio.wait_for(future, timeout=5.0)
-                    except asyncio.TimeoutError:
-                        log.warning('Shard ID %s timed out waiting for chunks for guild_id %s.', guild.shard_id, guild.id)
-
-                    if guild.unavailable is False:
-                        self.dispatch('guild_available', guild)
-                    else:
-                        self.dispatch('guild_join', guild)
+                            self.dispatch('guild_join', guild)
+
+            for guild, future in states:
+                try:
+                    await asyncio.wait_for(future, timeout=5.0)
+                except asyncio.TimeoutError:
+                    log.warning('Shard ID %s timed out waiting for chunks for guild_id %s.', guild.shard_id, guild.id)
+
+                if guild.unavailable is False:
+                    self.dispatch('guild_available', guild)
+                else:
+                    self.dispatch('guild_join', guild)
 
             # remove the state
             try:
@@ -450,20 +495,19 @@ async def _delay_ready(self):
             except AttributeError:
                 pass # already been deleted somehow
 
-            # call GUILD_SYNC after we're done chunking
-            if not self.is_bot:
-                log.info('Requesting GUILD_SYNC for %s guilds', len(self.guilds))
-                await self.syncer([s.id for s in self.guilds])
         except asyncio.CancelledError:
             pass
         else:
-            # dispatch the event
+
             self.call_handlers('ready')
             self.dispatch('ready')
+            # sync the application-commands
+            await self._get_client()._request_sync_commands()
+
         finally:
             self._ready_task = None
 
-    def parse_ready(self, data):
+    def parse_ready(self, data: gw.ReadyEvent):
         if self._ready_task is not None:
             self._ready_task.cancel()
 
@@ -475,31 +519,61 @@ def parse_ready(self, data):
         for guild_data in data['guilds']:
             self._add_guild_from_data(guild_data)
 
-        for relationship in data.get('relationships', []):
-            try:
-                r_id = int(relationship['id'])
-            except KeyError:
-                continue
-            else:
-                user._relationships[r_id] = Relationship(state=self, data=relationship)
-
         for pm in data.get('private_channels', []):
             factory, _ = _channel_factory(pm['type'])
             self._add_private_channel(factory(me=user, data=pm, state=self))
 
+        if self.application_id is None:
+            try:
+                application = data['application']
+            except KeyError:
+                pass
+            else:
+                # flags will always be present here
+                self.application_flags = ApplicationFlags._from_value(application['flags'])
+                self.application_id = utils._get_as_snowflake(application, 'id')
+
+        self.call_handlers('connect')
         self.dispatch('connect')
         self._ready_task = asyncio.ensure_future(self._delay_ready(), loop=self.loop)
 
     def parse_resumed(self, data):
+        self.call_handlers('resumed')
         self.dispatch('resumed')
 
+    def parse_entitlement_create(self, data):
+        entitlement = Entitlement(data, self)
+        self.dispatch('entitlement_create', entitlement)
+
+    def parse_entitlement_update(self, data):
+        entitlement = Entitlement(data, self)
+        # TODO: Add this to advanced cache
+        self.dispatch('entitlement_update', entitlement)
+
+    def parse_entitlement_delete(self, data):
+        entitlement = Entitlement(data, self)
+        self.dispatch('entitlement_delete', entitlement)
+
+    def parse_subscription_create(self, data):
+        subscription = Subscription(data, self)
+        self.dispatch('subscription_create', subscription)
+
+    def parse_subscription_update(self, data):
+        subscription = Subscription(data, self)
+        self.dispatch('subscription_update', subscription)
+
+    def parse_subscription_delete(self, data):
+        subscription = Subscription(data, self)
+        self.dispatch('subscription_delete', subscription)
+
     def parse_message_create(self, data):
         channel, _ = self._get_guild_channel(data)
         message = Message(channel=channel, data=data, state=self)
         self.dispatch('message', message)
         if self._messages is not None:
             self._messages.append(message)
-        if channel and channel.__class__ is TextChannel:
+        # not sure if we get ephemeral message here, but we don't want them as last message so ignore them
+        if channel and isinstance(channel, (TextChannel, VoiceChannel, ThreadChannel)) and not message.flags.ephemeral:
             channel.last_message_id = message.id
 
     def parse_message_delete(self, data):
@@ -541,36 +615,267 @@ def parse_message_update(self, data):
 
     def parse_interaction_create(self, data):
         self.dispatch('interaction_create', data)
-        if data.get('type', data.get('t', 0)) < 3:
-            return
-        interaction = Interaction(state=self, data=data)
-
-        interaction.user = self.store_user(interaction._user)
-        if interaction.guild_id:
-            interaction._guild = self._get_guild(interaction.guild_id)
-            interaction._channel = interaction.guild.get_channel(interaction.channel_id)
-            interaction.member = interaction.guild.get_member(interaction.user_id)
-            if interaction.member is None:
-                # This can only be the case if member-intents are not activated. or the member is not in the guild-cache right now
-                interaction.member = Member(guild=interaction.guild, data=interaction._member, state=self)
-        else:
-            interaction._channel = self._get_private_channel(interaction.channel_id)
-        interaction.message = self._get_message(interaction.message_id) if interaction.message is None else interaction.message
-        if self._get_message(interaction.message_id) is not None:
-            if interaction._interaction_type == InteractionType.Component:
-                if interaction.component_type == 2:
+        interaction = BaseInteraction.from_type(state=self, data=data)
+
+        if interaction.type in (InteractionType.ApplicationCommand, InteractionType.ApplicationCommandAutocomplete):
+            cmd = self._get_client()._get_application_command(interaction.data.id)
+            if cmd and not cmd.disabled:
+                interaction._command = cmd
+                self._get_client()._schedule_event(cmd._parse_arguments, '_application_command_invoke', interaction)
+        elif interaction.type == InteractionType.Component:
+            if interaction.cached_message is not None:  # Remove this check and on_raw_x events on v2 release
+                if interaction.data.component_type == ComponentType.Button:
                     self.dispatch('button_click', interaction, interaction.component)
                     self.dispatch('raw_button_click', interaction, interaction.component)
-                elif interaction.component_type == 3:
+                elif interaction.data.component_type.value in {3, 5, 6, 7, 8}:
                     self.dispatch('selection_select', interaction, interaction.component)
                     self.dispatch('raw_selection_select', interaction, interaction.component)
-        else:
-            interaction.message = Message(state=self, channel=interaction.channel, data=interaction._message)
-            if interaction._interaction_type == InteractionType.Component:
-                if interaction.component_type == 2:
+            else:
+                if interaction.data.component_type == ComponentType.Button:
                     self.dispatch('raw_button_click', interaction, interaction.component)
-                elif interaction.component_type == 3:
+                elif interaction.data.component_type.value in {3, 5, 6, 7, 8}:
                     self.dispatch('raw_selection_select', interaction, interaction.component)
+        elif interaction.type == InteractionType.ModalSubmit:
+            self.dispatch('modal_submit', interaction)
+
+    def parse_application_command_permissions_update(self, data):
+        guild = self._get_guild(int(data['guild_id']))
+        if guild is not None:
+            command_id = int(data['id'])
+            command = self._get_client()._get_application_command(command_id) or Object(id=command_id)
+            new_permissions = GuildAppCommandPermissions.from_dict(data)  # We don't cache permissions for now
+            self.dispatch('application_command_permissions_update', guild, command, new_permissions)
+        else:
+            log.debug('APPLICATION_COMMAND_PERMISSIONS_UPDATE referencing an unknown guild ID %s', data['guild_id'])
+
+    def parse_thread_create(self, data):
+        guild = self._get_guild(int(data['guild_id']))
+        if guild is not None:
+            parent_channel = guild.get_channel(int(data['parent_id']))
+
+            if parent_channel is None:
+                log.debug(
+                    'THREAD_CREATE referencing an unknown channel ID: %s. Discarding.', data['parent_id']
+                )
+            elif isinstance(parent_channel, ForumChannel):
+                post = ForumPost(state=self, guild=guild, data=data)
+                guild._add_channel(post)
+                self.dispatch('post_create', post)
+            elif isinstance(parent_channel, TextChannel):
+                thread = ThreadChannel(state=self, guild=guild, data=data)
+                message = self._get_message(thread.id)
+                if message:
+                    message._thread = thread
+                guild._add_channel(thread)
+                self.dispatch('thread_create', thread)
+        else:
+            log.debug('THREAD_CREATE referencing an unknown guild ID: %s. Discarding.', data['guild_id'])
+
+    def parse_thread_update(self, data):
+        guild_id = int(data['guild_id'])
+        guild = self._get_guild(guild_id)
+        if guild is not None:
+            thread_id = int(data['id'])
+            thread = guild.get_channel(thread_id)
+            if thread is not None:
+                old_thread = copy.copy(thread)
+                thread._update(guild, data)
+                if isinstance(thread.parent_channel, ForumChannel):
+                    self.dispatch('post_update', old_thread, thread)
+                else:
+                    self.dispatch('thread_update', old_thread, thread)
+            else:
+                log.debug('THREAD_UPDATE referencing an unknown channel ID: %s. Discarding.', thread_id)
+        else:
+            log.debug('THREAD_UPDATE referencing an unknown guild ID: %s. Discarding.', guild_id)
+
+    def parse_thread_delete(self, data):
+        guild = self._get_guild(int(data['guild_id']))
+        if guild is not None:
+            thread = guild.get_channel(int(data['id']))
+            if not thread:
+                thread = ThreadChannel._from_partial(state=self, guild=guild, data=data)
+            elif isinstance(thread.parent_channel, ForumChannel):
+                guild._remove_channel(thread)
+                self.dispatch('post_delete', thread)
+            else:
+                guild._remove_channel(thread)
+                self.dispatch('thread_delete', thread)
+                if thread.starter_message:
+                    thread.starter_message._thread = None
+            self.dispatch('thread_delete', thread)
+        else:
+            log.debug('THREAD_DELETE referencing an unknown guild ID: %s. Discarding.', data['guild_id'])
+
+    def parse_thread_member_update(self, data):
+        guild = self._get_guild(int(data['guild_id']))
+        if guild is not None:
+            thread = guild.get_channel(int(data['id']))
+            if thread is not None:
+                old_thread = copy.copy(thread)
+                thread._add_self(data)
+                if isinstance(thread, ForumPost):
+                    self.dispatch('post_member_update', old_thread, thread)
+                else:
+                    self.dispatch('thread_member_update', old_thread, thread)
+            else:
+                log.debug('THREAD_MEMBER_UPDATE referencing an unknown channel ID: %s. Discarding.', data['id'])
+        else:
+            log.debug('THREAD_MEMBER_UPDATE referencing an unknown guild ID: %s. Discarding.', data['guild_id'])
+
+    def parse_thread_members_update(self, data):
+        guild = self._get_guild(int(data['guild_id']))
+        if guild is not None:
+            thread = guild.get_channel(int(data['id']))
+            if thread is not None:
+                old_thread = copy.copy(thread)
+                thread._sync_from_members_update(data)
+
+                if isinstance(thread, ForumPost):
+                    self.dispatch('post_members_update', old_thread, thread)
+                else:
+                    self.dispatch('thread_members_update', old_thread, thread)
+            else:
+                log.debug('THREAD_MEMBERS_UPDATE referencing an unknown channel ID: %s. Discarding.', data['id'])
+        else:
+            log.debug('THREAD_MEMBERS_UPDATE referencing an unknown guild ID: %s. Discarding.', data['guild_id'])
+
+    def parse_thread_list_sync(self, data):
+        guild = self._get_guild(int(data['guild_id']))
+        if guild is not None:
+            old_guild = copy.copy(guild)
+            channel_ids = [int(c) for c in data.get('channel_ids', [])]
+            for t in data['threads']:
+                factory, _ = _channel_factory(t['type'])
+                if factory is None:
+                    log.debug('THREAD_LIST_SYNC referencing an unknown channel type: %s. Discarding.', _)
+                    continue
+                thread = factory(state=self, guild=guild, data=t)
+                guild._add_channel(thread)
+                try:
+                    channel_ids.remove(thread.parent_id)
+                except ValueError:
+                    pass
+            for m in data['members']:
+                member = ThreadMember(state=self,  guild=guild, data=m)
+                thread = guild.get_channel(member.thread_id)
+                thread._add_member(member)
+
+            for c in channel_ids:
+                channel = guild.get_channel(c)
+                channel._threads = {}
+
+            self.dispatch('thread_list_sync', old_guild, guild)
+        else:
+            log.debug('THREAD_LIST_SYNC referencing an unknown guild ID: %s. Discarding.', data['guild_id'])
+
+    def parse_guild_scheduled_event_create(self, data):
+        guild = self._get_guild(int(data['guild_id']))
+        if guild is not None:
+            event = self.store_event(guild, data)
+            self.dispatch('scheduled_event_create', event)
+        else:
+            log.debug('GUILD_SCHEDULED_EVENT_CREATE referencing an unknown guild ID: %s. Discarding.', data['guild_id'])
+
+    def parse_guild_scheduled_event_update(self, data):
+        guild = self._get_guild(int(data['guild_id']))
+        if guild is not None:
+            event = guild.get_event(int(data['id']))
+            if event is not None:
+                before = copy.copy(event)
+                event._update(data)
+                self.dispatch('scheduled_event_update', before, event)
+            else:
+                log.debug('GUILD_SCHEDULED_EVENT_UPDATE referencing an unknown event ID: %s. Discarding.', data['id'])
+        else:
+            log.debug('GUILD_SCHEDULED_EVENT_UPDATE referencing an unknown guild ID: %s. Discarding.', data['guild_id'])
+
+    def parse_guild_scheduled_event_delete(self, data):
+        guild = self._get_guild(int(data['guild_id']))
+        if guild is not None:
+            event = guild.get_event(int(data['id']))
+            if event is not None:
+                event._update(data)
+                self.dispatch('scheduled_event_delete', event)
+            else:
+                # TODO: Consider adding a raw event here.
+                log.debug('GUILD_SCHEDULED_EVENT_DELETE referencing an unknown event ID: %s. Discarding.', data['id'])
+        else:
+            log.debug('GUILD_SCHEDULED_EVENT_DELETE referencing an unknown guild ID: %s. Discarding.', data['guild_id'])
+
+    def parse_stage_instance_create(self, data):
+        guild = self._get_guild(int(data['guild_id']))
+        if guild is not None:
+            channel = guild.get_channel(int(data['channel_id']))
+            if channel is not None:
+                stage_instance = StageInstance(state=self, channel=channel, data=data)
+                guild._add_stage_instance(stage_instance)
+                self.dispatch('stage_instance_create', stage_instance)
+            else:
+                log.debug(
+                    'STAGE_INSTANCE_CREATE referencing an unknown channel ID: %s. Discarding.', data['channel_id']
+                )
+        else:
+            log.debug('STAGE_INSTANCE_CREATE referencing an unknown guild ID: %s. Discarding.', data['guild_id'])
+
+    def parse_stage_instance_update(self, data):
+        guild = self._get_guild(int(data['guild_id']))
+        if guild is not None:
+            stage_instance = guild._stage_instances.get(int(data['channel_id']))
+            if stage_instance:
+                before = copy.copy(stage_instance)
+                stage_instance._update(data)
+                self.dispatch('stage_instance_update', before, stage_instance)
+            else:
+                # TODO: Consider adding a raw event here. (we get all data anyway)
+                log.debug('STAGE_INSTANCE_UPDATE referencing an unknown stage instance: %s. Discarding.', data['id'])
+        else:
+            log.debug('STAGE_INSTANCE_UPDATE referencing an unknown guild ID: %s. Discarding.', data['guild_id'])
+
+    def parse_stage_instance_delete(self, data):
+        guild = self._get_guild(int(data['guild_id']))
+        if guild is not None:
+            stage_instance = guild._stage_instances.pop(int(data['channel_id']), None)
+            if stage_instance is not None:
+                self.dispatch('stage_instance_delete', stage_instance)
+            else:
+                # TODO: Consider adding a raw event here. (we get all data anyway)
+                log.debug('STAGE_INSTANCE_DELETE referencing an unknown stage instance: %s. Discarding.', data['id'])
+        else:
+            log.debug('STAGE_INSTANCE_DELETE referencing an unknown guild ID: %s. Discarding.', data['guild_id'])
+
+    def parse_voice_channel_effect_send(self, data: gw.VoiceChannelEffectSendEvent):
+        guild = self._get_guild(int(data['guild_id']))
+        if guild is not None:
+            channel = guild.get_channel(int(data['channel_id']))
+            if channel is not None:
+                effect = VoiceChannelEffectSendEvent(state=self, data=data)
+                self.dispatch('voice_channel_effect_send', channel, effect)
+            else:
+                log.debug(
+                    'VOICE_CHANNEL_EFFECT_SEND referencing an unknown channel ID: %s. Discarding.', data['channel_id']
+                )
+        else:
+            log.debug('VOICE_CHANNEL_EFFECT_SEND referencing an unknown guild ID: %s. Discarding.', data['guild_id'])
+
+    def parse_voice_channel_status_update(self, data):
+        guild = self._get_guild(int(data['guild_id']))
+        if guild is not None:
+            channel = guild.get_channel(int(data['id']))
+            if channel is not None:
+                before = copy.copy(channel.status)
+                channel._status = status = data['status']
+                self.dispatch('voice_channel_status_update', channel, before, status)
+            else:
+                log.debug(
+                    'VOICE_CHANNEL_STATUS_UPDATE referencing an unknown channel ID: %s. Discarding.',
+                    data['id']
+                )
+        else:
+            log.debug(
+                'VOICE_CHANNEL_STATUS_UPDATE referencing an unknown guild ID: %s. Discarding.',
+                data['guild_id']
+            )
 
     def parse_message_reaction_add(self, data):
         emoji = data['emoji']
@@ -636,7 +941,7 @@ def parse_message_reaction_remove_emoji(self, data):
         if message is not None:
             try:
                 reaction = message._clear_emoji(emoji)
-            except (AttributeError, ValueError): # eventual consistency lol
+            except (AttributeError, ValueError):  # eventual consistency lol
                 pass
             else:
                 if reaction:
@@ -670,7 +975,7 @@ def parse_presence_update(self, data):
 
             if member.id != self.self_id and flags._online_only and member.raw_status == 'offline':
                 guild._remove_member(member)
-
+        self.dispatch('presence_update', old_member, member)
         self.dispatch('member_update', old_member, member)
 
     def parse_user_update(self, data):
@@ -692,6 +997,9 @@ def parse_channel_delete(self, data):
             if channel is not None:
                 guild._remove_channel(channel)
                 self.dispatch('guild_channel_delete', channel)
+                if isinstance(channel, (TextChannel, ForumChannel)):
+                    # Allow the threads/posts in this channel to be removed from cache when the object is about to be finalized
+                    setattr(channel, f'_{channel.__class__.__name__}__deleted', True)
         else:
             # the reason we're doing this is so it's also removed from the
             # private channel by user cache as well
@@ -855,6 +1163,18 @@ def parse_guild_emojis_update(self, data):
         guild.emojis = tuple(map(lambda d: self.store_emoji(guild, d), data['emojis']))
         self.dispatch('guild_emojis_update', guild, before_emojis, guild.emojis)
 
+    def parse_guild_stickers_update(self, data):
+        guild = self._get_guild(int(data['guild_id']))
+        if guild is None:
+            log.debug('GUILD_STICKERS_UPDATE referencing an unknown guild ID: %s. Discarding.', data['guild_id'])
+            return
+
+        before_stickers = copy.copy(guild.stickers)
+        for sticker in before_stickers:
+            self._stickers.pop(sticker.id, None)
+        guild.stickers = tuple(map(lambda d: self.store_sticker(d), data['stickers']))
+        self.dispatch('guild_stickers_update', guild, before_stickers, guild.stickers)
+
     def _get_create_guild(self, data):
         if data.get('unavailable') is False:
             # GUILD_CREATE with unavailable in the response
@@ -1108,40 +1428,77 @@ def parse_typing_start(self, data):
                 timestamp = datetime.datetime.utcfromtimestamp(data.get('timestamp'))
                 self.dispatch('typing', channel, member, timestamp)
 
-    def parse_relationship_add(self, data):
-        key = int(data['id'])
-        old = self.user.get_relationship(key)
-        new = Relationship(state=self, data=data)
-        self.user._relationships[key] = new
-        if old is not None:
-            self.dispatch('relationship_update', old, new)
+    def parse_auto_moderation_rule_create(self, data):
+        guild = self._get_guild(int(data['guild_id']))
+        if guild is not None:
+            rule = AutoModRule(state=self, guild=guild, **data)
+            guild._add_automod_rule(rule)
+            self.dispatch('automod_rule_create', rule)
         else:
-            self.dispatch('relationship_add', new)
+            log.debug('AUTO_MODERATION_RULE_CREATE referencing an unknown guild ID: %s. Discarding.', data['guild_id'])
 
-    def parse_relationship_remove(self, data):
-        key = int(data['id'])
-        try:
-            old = self.user._relationships.pop(key)
-        except KeyError:
-            pass
+    def parse_auto_moderation_rule_update(self, data):
+        guild = self._get_guild(int(data['guild_id']))
+        rule_id = int(data['id'])
+        if guild is not None:
+            rule = guild._automod_rules.get(rule_id)
+            if rule is not None:
+                old_rule = copy.copy(rule)
+                rule._update(data)
+                self.dispatch('automod_rule_update', old_rule, rule)
+        else:
+            log.debug('AUTO_MODERATION_RULE_UPDATE referencing an unknown guild ID: %s. Discarding.', data['guild_id'])
+
+    def parse_auto_moderation_rule_delete(self, data):
+        guild = self._get_guild(int(data['guild_id']))
+        if guild is not None:
+            rule = guild._automod_rules.pop(int(data['id']), None) or AutoModRule(state=self, guild=guild, **data)
+            self.dispatch('automod_rule_delete', rule)
         else:
-            self.dispatch('relationship_remove', old)
+            log.debug('AUTO_MODERATION_RULE_DELETE referencing an unknown guild ID: %s. Discarding.', data['guild_id'])
 
+    def parse_auto_moderation_action_execution(self, data):
+        guild = self._get_guild(int(data['guild_id']))
+        if guild is not None:
+            payload = AutoModActionPayload(state=self, data=data)
+            self.dispatch('automod_action', payload)
+        else:
+            log.debug('AUTO_MODERATION_ACTION_EXECUTION referencing an unknown guild ID: %s. Discarding.', data['guild_id'])
+    
+    def parse_guild_audit_log_entry_create(self, data):
+        guild = self._get_guild(int(data['guild_id']))
+        if guild is not None:
+            entry = AuditLogEntry(guild=guild, data=data, users=self._users)
+            self.dispatch('audit_log_entry_create', guild, entry)
+        else:
+            log.debug('GUILD_AUDIT_LOG_ENTRY_CREATE referencing an unknown guild ID: %s. Discarding.', data['guild_id'])
+    
     def _get_reaction_user(self, channel, user_id):
-        if isinstance(channel, TextChannel):
+        if isinstance(channel, (TextChannel, ThreadChannel, VoiceChannel, StageChannel)):
             return channel.guild.get_member(user_id)
         return self.get_user(user_id)
 
-    def get_reaction_emoji(self, data):
+    def get_emoji_from_partial(self, data):
         emoji_id = utils._get_as_snowflake(data, 'id')
 
         if not emoji_id:
-            return data['name']
+            # the name key will be a str
+            return data['name']  # type: ignore
 
         try:
             return self._emojis[emoji_id]
         except KeyError:
-            return PartialEmoji.with_state(self, animated=data.get('animated', False), id=emoji_id, name=data['name'])
+            return PartialEmoji.with_state(
+                self, animated=data.get('animated', False), id=emoji_id, name=data['name']  # type: ignore
+            )
+
+    @staticmethod
+    def emoji_to_partial_payload(emoji: Union[Emoji, PartialEmoji, str]) -> PartialEmojiPayload:
+        if isinstance(emoji, str):
+            return {'name': emoji}  # type: ignore
+        elif isinstance(emoji, Emoji):
+            emoji = emoji._as_partial()
+        return emoji.to_dict()
 
     def _upgrade_partial_emoji(self, emoji):
         emoji_id = emoji.id
@@ -1165,10 +1522,16 @@ def get_channel(self, id):
             if channel is not None:
                 return channel
 
+        # We assume it is an uncached privat channel here, this may be false
+
     def create_message(self, *, channel, data):
         return Message(state=self, channel=channel, data=data)
 
+
 class AutoShardedConnectionState(ConnectionState):
+    _get_client: Callable[[], AutoShardedClient]
+    _get_websocket: Callable[[int, int], DiscordWebSocket]
+    
     def __init__(self, *args, **kwargs):
         super().__init__(*args, **kwargs)
         self._ready_task = None
@@ -1176,15 +1539,24 @@ def __init__(self, *args, **kwargs):
         self.shards_launched = asyncio.Event()
 
     def _update_message_references(self):
+        removed = set()
         for msg in self._messages:
             if not msg.guild:
+                removed.add(msg)
                 continue
-
+            
             new_guild = self._get_guild(msg.guild.id)
             if new_guild is not None and new_guild is not msg.guild:
                 channel_id = msg.channel.id
-                channel = new_guild.get_channel(channel_id) or Object(id=channel_id)
-                msg._rebind_channel_reference(channel)
+                channel = new_guild.get_channel(channel_id)
+                if channel:
+                    msg._rebind_channel_reference(channel)
+                else:
+                    removed.add(msg)
+        if removed:
+            # Remove the messages from cache we no longer have access to
+            for msg in removed:
+                self._messages.remove(msg)
 
     async def chunker(self, guild_id, query='', limit=0, presences=False, *, shard_id=None, nonce=None):
         ws = self._get_websocket(guild_id, shard_id=shard_id)
@@ -1253,11 +1625,12 @@ async def _delay_ready(self):
         # clear the current task
         self._ready_task = None
 
-        # dispatch the event
         self.call_handlers('ready')
         self.dispatch('ready')
+        # sync the application-commands
+        await self._get_client()._request_sync_commands()
 
-    def parse_ready(self, data):
+    def parse_ready(self, data: gw.ReadyEvent):
         if not hasattr(self, '_ready_state'):
             self._ready_state = asyncio.Queue()
 
diff --git a/discord/sticker.py b/discord/sticker.py
index 401174cc..3b619062 100644
--- a/discord/sticker.py
+++ b/discord/sticker.py
@@ -3,7 +3,7 @@
 """
 The MIT License (MIT)
 
-Copyright (c) 2015-present Rapptz
+Copyright (c) 2015-2021 Rapptz & (c) 2021-present mccoderpy
 
 Permission is hereby granted, free of charge, to any person obtaining a
 copy of this software and associated documentation files (the "Software"),
@@ -23,11 +23,117 @@
 FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 DEALINGS IN THE SOFTWARE.
 """
+from __future__ import annotations
+
+from typing import (
+    List,
+    Optional,
+    Tuple,
+    TYPE_CHECKING,
+    Union
+)
 
-from .mixins import Hashable
 from .asset import Asset
-from .utils import snowflake_time
 from .enums import StickerType, try_enum
+from .mixins import Hashable
+from .utils import get as utils_get, snowflake_time
+
+if TYPE_CHECKING:
+    from datetime import datetime
+    
+    from .guild import Guild
+    from .user import User
+    from .state import ConnectionState
+
+
+__all__ = (
+    'StickerPack',
+    'Sticker',
+    'GuildSticker'
+)
+
+
+class StickerPack(Hashable):
+    """Represents a pack of build-in stickers
+
+    Attributes
+    ----------
+    name: :class:`str`
+        The name of the sticker pack.
+    id: :class:`int`
+        The id of the sticker pack.
+    description: :class:`str`
+        The description of the sticker pack.
+    sku_id: :class:`int`
+        The id of the pack's SKU.
+    banner_asset_id: :class:`int`
+        The id of the sticker pack's banner image.
+    cover_sticker_id: Optional[:class:`int`]
+        The id of a sticker in the pack which is shown in the client as the pack's icon.
+    """
+    def __init__(self, state: ConnectionState, data) -> None:
+        self._state = state
+        self.id = int(data['id'])
+        self.name: str = data['name']
+        self.sku_id: int = int(data['sku_id'])
+        self.cover_sticker_id: Optional[int] = int(data.get('cover_sticker_id', 0)) or None
+        self.description: str = data['description']
+        self.banner_asset_id = int(data['banner_asset_id'])
+        self.__stickers: Tuple[Sticker] = tuple(map(lambda d: state.store_sticker(d, self), data['stickers']))
+
+    @property
+    def stickers(self) -> Tuple[Sticker]:
+        """Tuple[:class:`Sticker`]: The stickers of the pack"""
+        return self.__stickers
+
+    @stickers.setter
+    def stickers(self, value):
+        raise TypeError('Sticker Packs are immutable.')
+
+    @property
+    def banner_url(self) -> Asset:
+        """Returns an :class:`Asset` for the sticker pack's banner.
+
+        Returns
+        -------
+        :class:`Asset`
+            The resulting CDN asset.
+        """
+        return self.banner_url_as()
+
+    def banner_url_as(self, format: str = 'png', size=1024) -> Asset:
+        """Returns an :class:`Asset` for the sticker pack's banner.
+
+        The size must be a power of 2 between 16 and 4096.
+
+        Returns
+        -------
+        :class:`Asset`
+            The resulting CDN asset.
+        """
+        return Asset._from_sticker_pack(self._state, self, format=format, size=size)
+
+    @property
+    def cover_sticker(self) -> Sticker:
+        """:class:`Sticker`: Returns the sticker in the pack which is shown in the client as the pack's icon."""
+        return self.get_sticker(self.cover_sticker_id)
+
+    def get_sticker(self, id: int) -> Optional[Sticker]:
+        """
+        Returns a sticker of the pack with the given id or :obj:`None` if not found.
+        
+        Parameters
+        -----------
+        id: :class:`int`
+            The id of the sticker to get 
+        
+        Returns
+        --------
+        Optional[:class:`Sticker`]
+            The sticker or ``None`` if not found.
+        """
+        return utils_get(self.stickers, id=id)
+
 
 class Sticker(Hashable):
     """Represents a sticker.
@@ -60,30 +166,28 @@ class Sticker(Hashable):
         The id of the sticker's pack.
     format: :class:`StickerType`
         The format for the sticker's image.
-    image: :class:`str`
-        The sticker's image.
     tags: List[:class:`str`]
         A list of tags for the sticker.
-    preview_image: Optional[:class:`str`]
-        The sticker's preview asset hash.
+    pack: Optional[:class:`StickerPack`]
+        The pack the sticker belongs to. Could be :obj:`None` even if :attr:`Sticker.pack_id` is present.
+    sort_value: :class:`int`
+        The sticker's sort order within its :attr:`Sticker.pack`.
     """
-    __slots__ = ('_state', 'id', 'name', 'description', 'pack_id', 'format', 'image', 'tags', 'preview_image')
+    __slots__ = ('_state', 'id', 'name', 'description', 'pack_id', 'format', 'tags', 'sort_value' , 'pack')
 
-    def __init__(self, *, state, data):
+    def __init__(self, *, state, data, pack: Optional[StickerPack] = None) -> None:
         self._state = state
         self.id = int(data['id'])
         self.name: str = data['name']
-        self.description: str = data['description']
+        self.description: str = data.get('description', None)
         self.pack_id: int = int(data.get('pack_id', 0))
         self.format: StickerType = try_enum(StickerType, data['format_type'])
-        self.image: str = data['asset']
-
+        self.sort_value = data.get('sort_value', 0)
         try:
             self.tags = [tag.strip() for tag in data['tags'].split(',')]
         except KeyError:
             self.tags = []
-
-        self.preview_image = data.get('preview_asset')
+        self.pack = pack
 
     def __repr__(self):
         return '<{0.__class__.__name__} id={0.id} name={0.name!r}>'.format(self)
@@ -92,12 +196,12 @@ def __str__(self):
         return self.name
 
     @property
-    def created_at(self):
+    def created_at(self) -> datetime:
         """:class:`datetime.datetime`: Returns the sticker's creation time in UTC as a naive datetime."""
         return snowflake_time(self.id)
 
     @property
-    def image_url(self):
+    def image_url(self) -> Asset:
         """Returns an :class:`Asset` for the sticker's image.
 
         .. note::
@@ -110,7 +214,7 @@ def image_url(self):
         """
         return self.image_url_as()
 
-    def image_url_as(self, *, size=1024):
+    def image_url_as(self) -> Asset:
         """Optionally returns an :class:`Asset` for the sticker's image.
 
         The size must be a power of 2 between 16 and 4096.
@@ -118,22 +222,150 @@ def image_url_as(self, *, size=1024):
         .. note::
             This will return ``None`` if the format is ``StickerType.lottie``.
 
+        Returns
+        -------
+        Optional[:class:`Asset`]
+            The resulting CDN asset or ``None``.
+        """
+        if self.format is StickerType.lottie:
+            return None
+
+        return Asset._from_sticker(self._state, self, format='png')
+
+
+class GuildSticker(Sticker):
+    """
+    Represents a "custom" sticker in a guild
+
+    Attributes
+    ----------
+    name: :class:`str`
+        The sticker's name.
+    id: :class:`int`
+        The id of the sticker.
+    description: :class:`str`
+        The description of the sticker.
+    format: :class:`StickerType`
+        The format for the sticker's image.
+    tags: List[:class:`str`]
+        A list of tags for the sticker.
+    guild_id: :class:`int`
+        The id of the guild which this sticker belongs to.
+    available: :class:`bool`
+        Whether this guild sticker can be used, may be :obj:`False` due to loss of Server Boosts
+    user: :class:`User`
+        The user that uploaded the guild sticker
+    """
+    __slots__ = ('_state', 'id', 'name', 'description', 'format', 'tags', 'available', 'guild_id', 'user')
+
+    def __init__(self, *, state: ConnectionState, data) -> None:
+        super().__init__(state=state, data=data)
+        self.guild_id: int = int(data['guild_id'])
+        self.available = data.get('available', True)
+        try:
+            user = data['user']
+        except KeyError:
+            self.user: Optional[User] = None
+        else:
+            self.user: Optional[User] = state.store_user(user)
+
+    @property
+    def guild(self) -> Guild:
+        """:class:`Guild`: The guild the sticker belongs to"""
+        return self._state._get_guild(self.guild_id)
+
+    def _update(self, data):
+        for k, v in data.items():
+            setattr(self, k, v)
+        return self
+
+    async def edit(self, *, reason: Optional[str] = None, **fields) -> GuildSticker:
+        """|coro|
+
+        Modify the sticker.
+
+        Requires the ``MANAGE_EMOJIS_AND_STICKERS`` permission.
+
+        Parameters
+        ----------
+        name: :class:`str`
+            The name of the sticker; 2-30 characters long.
+        description: Optional[:class:`str`]
+            The description of the sticker; ``None`` or 2-100 characters long.
+        tags: Union[:class:`str`, List[:class:`str`]]
+            The autocomplete/suggestion tags for the sticker.
+            A string in which the individual tags are separated by ``,`` or a list of tags; (max 200 characters).
+        reason: Optional[:class:`str`]
+            The reason for modifying the sticker, shows up in the audit-log.
+
+        Raises
+        ------
+        discord.Forbidden:
+            You don't have the required permission to edit the sticker.
+        discord.HTTPException:
+            Editing the sticker failed.
+        ValueError:
+            Any of name, description or tags is invalid.
+
+        Returns
+        -------
+        discord.GuildSticker:
+            The updated sticker on success.
+        """
+
+        try:
+            name: str = fields['name']
+        except KeyError:
+            pass
+        else:
+            if 2 > len(name) > 30:
+                raise ValueError(f'The length of sticker name must be between 2 and 30 characters long; got {len(name)}.')
+
+        try:
+            description: Optional[str] = fields['description']
+        except KeyError:
+            pass
+        else:
+            if description is not None and 2 > len(description) > 100:
+                raise ValueError(f'The length of sticker description must be between 2 and 30 characters long; got {len(description)}.')
+
+        try:
+            tags: Union[str, List[str]] = fields['tags']
+        except KeyError:
+            pass
+        else:
+            if isinstance(tags, list):
+                fields['tags'] = tags = ','.join(tags)
+            if len(tags) > 200:
+                raise ValueError(f'The length of the sticker tags must not exceed 200 characters; got {len(tags)}.')
+
+        data = await self._state.http.edit_guild_sticker(guild_id=self.guild_id, sticker_id=self.id, data=fields, reason=reason)
+        return self._update(data)
+
+    async def delete(self, *, reason: Optional[str]) -> GuildSticker:
+        """|coro|
+
+        Delete the sticker.
+
+        Requires the ``MANAGE_EMOJIS_AND_STICKERS`` permission.
+
         Parameters
         -----------
-        size: :class:`int`
-            The size of the image to display.
+        reason: Optional[:class:`str`]
+            The reason for deleting the sticker, shows up in the audit-log.
 
         Raises
         ------
-        InvalidArgument
-            Invalid ``size``.
+        discord.Forbidden:
+            You don't have the required permissions to delete the sticker.
+        discord.HTTPException:
+            Deleting the sticker failed.
 
         Returns
         -------
-        Optional[:class:`Asset`]
-            The resulting CDN asset or ``None``.
+        discord.GuildSticker:
+            The sticker that was deleted.
         """
-        if self.format is StickerType.lottie:
-            return None
 
-        return Asset._from_sticker_url(self._state, self, size=size)
+        await self._state.http.delete_guid_sticker(guild_id=self.guild_id, sticker_id=self.id, reason=reason)
+        return self
diff --git a/discord/team.py b/discord/team.py
index 63cd0c07..7adf9827 100644
--- a/discord/team.py
+++ b/discord/team.py
@@ -23,11 +23,26 @@
 FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 DEALINGS IN THE SOFTWARE.
 """
+from __future__ import annotations
+
+from typing import (
+    TYPE_CHECKING,
+    Optional,
+    List
+)
+from typing_extensions import Literal
+
+if TYPE_CHECKING:
+    from .state import ConnectionState
+    from .types.appinfo import (
+        Team as TeamData,
+        TeamMember as TeamMemberData,
+    )
 
 from . import utils
 from .user import BaseUser
 from .asset import Asset
-from .enums import TeamMembershipState, try_enum
+from .enums import TeamMembershipState, TeamRole, try_enum
 
 __all__ = (
     'Team',
@@ -54,20 +69,19 @@ class Team:
     """
     __slots__ = ('_state', 'id', 'name', 'icon', 'owner_id', 'members')
 
-    def __init__(self, state, data):
-        self._state = state
-
-        self.id = utils._get_as_snowflake(data, 'id')
-        self.name = data['name']
-        self.icon = data['icon']
-        self.owner_id = utils._get_as_snowflake(data, 'owner_user_id')
-        self.members = [TeamMember(self, self._state, member) for member in data['members']]
+    def __init__(self, state: ConnectionState, data: TeamData) -> None:
+        self._state: ConnectionState = state
+        self.id: int = utils._get_as_snowflake(data, 'id')
+        self.name: str = data['name']
+        self.icon: str = data['icon']
+        self.owner_id: int = utils._get_as_snowflake(data, 'owner_user_id')
+        self.members: List[TeamMember] = [TeamMember(self, self._state, member) for member in data['members']]
 
-    def __repr__(self):
-        return '<{0.__class__.__name__} id={0.id} name={0.name}>'.format(self)
+    def __repr__(self) -> str:
+        return f'<{self.__class__.__name__} id={self.id} name={self.name}>'
 
     @property
-    def icon_url(self):
+    def icon_url(self) -> Asset:
         """:class:`.Asset`: Retrieves the team's icon asset.
 
         This is equivalent to calling :meth:`icon_url_as` with
@@ -75,7 +89,7 @@ def icon_url(self):
         """
         return self.icon_url_as()
 
-    def icon_url_as(self, *, format='webp', size=1024):
+    def icon_url_as(self, *, format: Literal['webp', 'jpeg', 'jpg', 'png'] = 'webp', size: int = 1024) -> Asset:
         """Returns an :class:`Asset` for the icon the team has.
 
         The format must be one of 'webp', 'jpeg', 'jpg' or 'png'.
@@ -103,13 +117,18 @@ def icon_url_as(self, *, format='webp', size=1024):
         return Asset._from_icon(self._state, self, 'team', format=format, size=size)
 
     @property
-    def owner(self):
+    def owner(self) -> Optional[TeamMember]:
         """Optional[:class:`TeamMember`]: The team's owner."""
         return utils.get(self.members, id=self.owner_id)
 
+
 class TeamMember(BaseUser):
     """Represents a team member in a team.
 
+    .. versionchanged:: 2.0
+        The :attr:`name` attribute was renamed to :attr:`username` due to the (upcoming)
+        :dis-gd:`username changes <username>`.
+
     .. container:: operations
 
         .. describe:: x == y
@@ -126,18 +145,28 @@ class TeamMember(BaseUser):
 
         .. describe:: str(x)
 
-            Returns the team member's name with discriminator.
+            Returns the team member's :attr:`username` if :attr:`is_migrated` is true, else the user's name with discriminator.
+
+            .. note::
+
+                When the migration is complete, this will always return the :attr:`username`.
 
     .. versionadded:: 1.3
 
     Attributes
     -------------
-    name: :class:`str`
+    username: :class:`str`
         The team member's username.
+    global_name: Optional[:class:`str`]
+        The team members :attr:`~User.global_name` if any.
     id: :class:`int`
         The team member's unique ID.
     discriminator: :class:`str`
-        The team member's discriminator. This is given when the username has conflicts.
+        The team member's discriminator.
+
+        .. important::
+            This will be removed in a future API version.
+            Read more about it :dis-gd:`here <usernames>`.
     avatar: Optional[:class:`str`]
         The avatar hash the team member has. Could be None.
     bot: :class:`bool`
@@ -146,15 +175,29 @@ class TeamMember(BaseUser):
         The team that the member is from.
     membership_state: :class:`TeamMembershipState`
         The membership state of the member (e.g. invited or accepted)
+    role: :class:`TeamRole`
+        The role of the team member.
+
+        .. versionadded:: 2.0
     """
-    __slots__ = BaseUser.__slots__ + ('team', 'membership_state', 'permissions')
+    __slots__ = BaseUser.__slots__ + ('team', 'membership_state', 'permissions', 'role')
 
-    def __init__(self, team, state, data):
-        self.team = team
-        self.membership_state = try_enum(TeamMembershipState, data['membership_state'])
-        self.permissions = data['permissions']
+    def __init__(self, team: Team, state: ConnectionState, data: TeamMemberData):
+        self.team: Team = team
+        self.membership_state: TeamMembershipState = try_enum(TeamMembershipState, data['membership_state'])
+        self.permissions: List[str] = data['permissions']
+        self.role: TeamRole = try_enum(TeamRole, data['role'])
         super().__init__(state=state, data=data['user'])
 
-    def __repr__(self):
-        return '<{0.__class__.__name__} id={0.id} name={0.name!r} ' \
-               'discriminator={0.discriminator!r} membership_state={0.membership_state!r}>'.format(self)
+    def __repr__(self) -> str:
+        if not self.is_migrated:
+            return (
+                f'<{self.__class__.__name__} role={self.role!r} id={self.id} username={self.username!r} '
+                f'global_name={self.global_name} membership_state={self.membership_state!r}>'
+            )
+        return (
+            f'<{self.__class__.__name__} role={self.role!r} id={self.id} username={self.username!r} '
+            f'discriminator={self.discriminator!r} global_name={self.global_name} '
+            f'membership_state={self.membership_state!r}>'
+        )
+
diff --git a/discord/template.py b/discord/template.py
index 2e957346..920c7978 100644
--- a/discord/template.py
+++ b/discord/template.py
@@ -43,10 +43,6 @@ def __init__(self, *, state):
         self.__state = state
         self.http = _FriendlyHttpAttributeErrorHelper()
 
-    @property
-    def is_bot(self):
-        return self.__state.is_bot
-
     @property
     def shard_count(self):
         return self.__state.shard_count
diff --git a/discord/types/__init__.py b/discord/types/__init__.py
new file mode 100644
index 00000000..01ac333e
--- /dev/null
+++ b/discord/types/__init__.py
@@ -0,0 +1,10 @@
+# -*- coding: utf-8 -*-
+"""
+discord4py.types
+~~~~~~~~~~~~~~~~~~~
+
+Typings for the discord-api models
+
+:copyright: (c) 2021-present mccoderpy
+:license: MIT, see LICENSE for more details.
+"""
\ No newline at end of file
diff --git a/discord/types/activity.py b/discord/types/activity.py
new file mode 100644
index 00000000..fd602f00
--- /dev/null
+++ b/discord/types/activity.py
@@ -0,0 +1,102 @@
+# -*- coding: utf-8 -*-
+
+"""
+The MIT License (MIT)
+
+Copyright (c) 2021-present mccoderpy
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+"""
+from __future__ import annotations
+
+from typing import TypedDict, Optional, Union, List
+from typing_extensions import Literal, NotRequired
+
+
+from .emoji import PartialEmoji
+from .user import BaseUser
+from .snowflake import SnowflakeID
+
+ActivityType = Literal[0, 1, 2, 3, 4, 5]
+StatusType = Literal["idle", "dnd", "online", "offline"]
+
+class PartialPresenceUpdate(TypedDict):
+    user: BaseUser
+    guild_id: SnowflakeID
+    status: StatusType
+    activities: List[Activity]
+    client_status: ClientStatus
+
+
+class ClientStatus(TypedDict, total=False):
+    desktop: str
+    mobile: str
+    web: str
+
+
+class ActivityTimestamps(TypedDict, total=False):
+    start: int
+    end: int
+
+
+class ActivityAssets(TypedDict, total=False):
+    large_image: str
+    large_text: str
+    small_image: str
+    small_text: str
+
+
+class ActivitySecrets(TypedDict, total=False):
+    join: str
+    spectate: str
+    match: str
+
+
+class ActivityParty(TypedDict, total=False):
+    id: str
+    size: List[int]
+
+class ActivityButton(TypedDict):
+    label: str
+    url: str
+
+
+class SendableActivity(TypedDict, total=False):
+    url: NotRequired[str]
+    name: str
+    type: ActivityType
+
+
+class _BaseActivity(SendableActivity):
+    created_at: int
+
+
+class Activity(_BaseActivity, total=False):
+    state: Optional[str]
+    details: Optional[str]
+    timestamps: ActivityTimestamps
+    assets: ActivityAssets
+    party: ActivityParty
+    application_id: SnowflakeID
+    flags: int
+    emoji: Optional[PartialEmoji]
+    secrets: ActivitySecrets
+    session_id: Optional[str]
+    instance: bool
+    buttons: List[str]
\ No newline at end of file
diff --git a/discord/types/app_command.py b/discord/types/app_command.py
new file mode 100644
index 00000000..1426d7aa
--- /dev/null
+++ b/discord/types/app_command.py
@@ -0,0 +1,55 @@
+# -*- coding: utf-8 -*-
+
+"""
+The MIT License (MIT)
+
+Copyright (c) 2021-present mccoderpy
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+"""
+from __future__ import annotations
+
+from typing import (
+    List,
+    TypedDict,
+)
+
+from typing_extensions import (
+    Literal
+)
+
+__all__ = (
+    'ApplicationCommandPermission',
+    'GuildApplicationCommandPermissions'
+)
+
+ApplicationCommandPermissionType = Literal[1, 2, 3]
+
+
+class GuildApplicationCommandPermissions(TypedDict):
+    id: str
+    application_id: str
+    guild_id: str
+    permissions: List[ApplicationCommandPermission]
+
+
+class ApplicationCommandPermission(TypedDict):
+    id: str
+    type: ApplicationCommandPermissionType
+    permission: bool
diff --git a/discord/types/appinfo.py b/discord/types/appinfo.py
new file mode 100644
index 00000000..c9c2f811
--- /dev/null
+++ b/discord/types/appinfo.py
@@ -0,0 +1,104 @@
+# -*- coding: utf-8 -*-
+
+"""
+The MIT License (MIT)
+
+Copyright (c) 2021-present mccoderpy
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+"""
+
+from typing import (
+    List,
+    Optional
+)
+from typing_extensions import (
+    TypedDict,
+    NotRequired,
+    Literal
+)
+
+from .snowflake import SnowflakeID
+from .user import User
+
+__all__ = (
+    'TeamMember',
+    'Team',
+    'GatewayAppInfo',
+    'PartialAppInfo',
+    'AppInfo',
+)
+
+TeamMembershipState = Literal[1, 2]
+TeamRole = Literal['owner', 'admin', 'developer', 'read_only']
+
+class TeamMember(TypedDict):
+    membership_state: TeamMembershipState
+    permissions: List[str]
+    team_id: SnowflakeID
+    user: User
+    role: TeamRole
+
+
+class Team(TypedDict):
+    id: SnowflakeID
+    name: str
+    icon: Optional[str]
+    members: List[TeamMember]
+    owner_user_id: SnowflakeID
+
+
+class GatewayAppInfo(TypedDict):
+    id: SnowflakeID
+    flags: int
+
+
+class PartialAppInfo(TypedDict):
+    id: SnowflakeID
+    name: str
+    icon: NotRequired[str]
+    description: str
+    type: int
+    hook: bool
+    bot_public: bool
+    bot_require_code_grant: bool
+    verify_key: str
+    flags: NotRequired[int]
+    tags: List[str]
+
+
+class InstallParams(TypedDict):
+    scopes: List[str]
+    permissions: str
+
+
+class AppInfo(PartialAppInfo):
+    rpc_origins: NotRequired[List[str]]
+    terms_of_service_url: NotRequired[str]
+    privacy_policy_url: NotRequired[str]
+    owner: NotRequired[User]
+    team: Optional[Team]
+    guild_id: NotRequired[SnowflakeID]
+    primary_sku_id: NotRequired[SnowflakeID]
+    slug: NotRequired[str]
+    cover_image: NotRequired[str]
+    install_params: NotRequired[InstallParams]
+    custom_install_url: NotRequired[str]
+    role_connections_verification_url: NotRequired[str]
+    interactions_endpoint_url: NotRequired[str]
diff --git a/discord/types/channel.py b/discord/types/channel.py
new file mode 100644
index 00000000..55bb2181
--- /dev/null
+++ b/discord/types/channel.py
@@ -0,0 +1,159 @@
+# -*- coding: utf-8 -*-
+
+"""
+The MIT License (MIT)
+
+Copyright (c) 2021-present mccoderpy
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+"""
+from __future__ import annotations
+
+from typing import (
+    List,
+    Optional
+)
+
+from typing_extensions import (
+    Literal,
+    NotRequired,
+    TypedDict
+)
+
+from .snowflake import SnowflakeID
+from .user import BaseUser
+from .emoji import PartialEmoji
+
+__all__ = (
+    'ChannelType',
+    'OverwriteType',
+    'Overwrite',
+    'PartialChannel',
+    'GuildChannel',
+    'VoiceChannel',
+    'StageChannel',
+    'StageInstance',
+    'ForumTag',
+    'ForumChannel',
+    'DefaultReactionEmoji',
+    'ThreadMetadata',
+    'DMChannel',
+    'GroupChannel'
+)
+
+ChannelType = Literal[0, 1, 2, 3, 4, 5, 10, 11, 12, 13, 14, 15, 16]
+OverwriteType = Literal[0, 1]
+StagePrivacyLevel = Literal[1, 2]
+
+
+class Overwrite(TypedDict):
+    id: SnowflakeID
+    type: OverwriteType
+    allow: str
+    deny: str
+
+
+class GuildChannel(TypedDict):
+    id: SnowflakeID
+    type: ChannelType
+    name: NotRequired[Optional[str]]
+    flags: NotRequired[int]
+    position: NotRequired[int]
+    parent_id: NotRequired[SnowflakeID]
+    permission_overwrites: NotRequired[List[Overwrite]]
+
+
+class ThreadMetadata(TypedDict):
+    archived: bool
+    auto_archive_duration: int
+    archive_timestamp: str
+    locked: bool
+    invitable: NotRequired[bool]
+    create_timestamp: NotRequired[Optional[str]]
+
+
+class DefaultReactionEmoji(TypedDict):
+    emoji_id: NotRequired[SnowflakeID]
+    emoji_name: str
+
+
+class ForumTag(TypedDict):
+    id: SnowflakeID
+    name: str
+    emoji_name: NotRequired[str]
+    emoji_id: NotRequired[SnowflakeID]
+    moderated: NotRequired[bool]
+
+
+class PartialChannel(TypedDict):
+    id: SnowflakeID
+    type: ChannelType
+    name: NotRequired[Optional[str]]
+    # TODO: What fields are missing here?
+
+
+class DMChannel(PartialChannel):
+    recipients: NotRequired[List[BaseUser]]
+    last_message_id: NotRequired[Optional[SnowflakeID]]
+
+
+class GroupChannel(DMChannel, total=False):
+    owner_id: SnowflakeID
+    managed: NotRequired[bool]
+    icon: Optional[str]
+
+
+class VoiceChannel(GuildChannel, total=False):
+    bitrate: int
+    user_limit: int
+    video_quality_mode: int
+    rate_limit_per_user: int
+    nsfw: bool
+    icon_emoji: Optional[PartialEmoji]
+    rtc_region: Optional[str]
+    status: Optional[str]
+
+
+class StageChannel(VoiceChannel, total=False):
+    privacy_level: int
+    discoverable_disabled: bool
+
+
+class StageInstance(TypedDict):
+    id: SnowflakeID
+    guild_id: SnowflakeID
+    channel_id: SnowflakeID
+    topic: str
+    privacy_level: StagePrivacyLevel
+    discoverable_disabled: NotRequired[bool]
+    guild_scheduled_event_id: Optional[SnowflakeID]
+
+
+class ForumChannel(GuildChannel, total=False):
+    nsfw: bool
+    default_auto_archive_duration: int
+    default_rate_limit_per_user: int
+    rate_limit_per_user: int
+    default_thread_rate_limit_per_user: int
+    default_sort_order: int
+    default_forum_layout: int
+    default_reaction_emoji: DefaultReactionEmoji
+    icon_emoji: Optional[PartialEmoji]
+    topic: Optional[str]
+    template: Optional[bool]
diff --git a/discord/types/emoji.py b/discord/types/emoji.py
new file mode 100644
index 00000000..3c5e977c
--- /dev/null
+++ b/discord/types/emoji.py
@@ -0,0 +1,60 @@
+# -*- coding: utf-8 -*-
+
+"""
+The MIT License (MIT)
+
+Copyright (c) 2021-present mccoderpy
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+"""
+from typing import (
+    List,
+    Optional
+)
+
+from typing_extensions import (
+    Literal,
+    TypedDict,
+    NotRequired
+)
+
+from .snowflake import SnowflakeID, SnowflakeList
+from .user import BaseUser
+
+__all__ = (
+    'PartialEmoji',
+    'BaseEmoji',
+)
+
+
+class PartialEmoji(TypedDict):
+    id: Optional[SnowflakeID]  # The ID of the emoji
+    name: Optional[str]        # The emoji name
+    animated: NotRequired[bool]  # Whether this emoji is animated
+
+
+class BaseEmoji(TypedDict):
+    id: Optional[SnowflakeID]          # The ID of the emoji
+    name: Optional[str]                # The emoji name
+    roles: NotRequired[SnowflakeList]  # The roles allowed to use this emoji
+    user: NotRequired[BaseUser]        # The user that created this emoji
+    require_colons: NotRequired[bool]  # Whether this emoji must be wrapped in colons
+    managed: NotRequired[bool]         # Whether this emoji is managed
+    animated: NotRequired[bool]        # Whether this emoji is animated
+    available: NotRequired[bool]       # Whether this emoji can be used, may be false due to loss of Server Boosts
diff --git a/discord/types/gateway.py b/discord/types/gateway.py
new file mode 100644
index 00000000..94f9ddef
--- /dev/null
+++ b/discord/types/gateway.py
@@ -0,0 +1,89 @@
+# -*- coding: utf-8 -*-
+
+"""
+The MIT License (MIT)
+
+Copyright (c) 2021-present mccoderpy
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+"""
+
+from typing import (
+    Any,
+    Dict,
+    List,
+    Optional
+)
+
+from typing_extensions import (
+    Literal,
+    TypedDict,
+    NotRequired
+)
+
+from .appinfo import GatewayAppInfo
+from .emoji import PartialEmoji
+from .guild import UnavailableGuild
+from .snowflake import SnowflakeID
+from .user import ClientUser
+
+__all__ = (
+    'GatewayPayload',
+    'ReadyEvent',
+    'VoiceGatewayPayload',
+    'VoiceChannelEffectSendEvent',
+)
+
+
+class GatewayPayload(TypedDict):
+    op: Literal[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
+    d: Optional[Dict[str, Any]]
+    s: Optional[int]
+    t: Optional[str]
+
+
+class ReadyEvent(TypedDict):
+    v: int  # gateway version
+    user: ClientUser
+    shard: List[int]  # shard id, total shards
+    session_id: str
+    resume_gateway_url: str
+    application: GatewayAppInfo
+    guilds: List[UnavailableGuild]
+    _trace: List[str]
+
+
+# voice gateway
+class VoiceGatewayPayload(TypedDict):
+    op: Literal[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]
+    d: Optional[Dict[str, Any]]
+    s: Optional[int]
+    t: Optional[str]
+
+
+class VoiceChannelEffectSendEvent(TypedDict):
+    user_id: SnowflakeID
+    guild_id: SnowflakeID
+    channel_id: SnowflakeID
+    sound_id: NotRequired[SnowflakeID]  # This is actually an int for build-in sounds
+    sound_volume: NotRequired[float]
+    sound_override_path: NotRequired[Optional[str]]
+    animation_type: int
+    animation_id: int
+    emoji: NotRequired[Optional[PartialEmoji]]
diff --git a/discord/types/guild.py b/discord/types/guild.py
new file mode 100644
index 00000000..4ff147ca
--- /dev/null
+++ b/discord/types/guild.py
@@ -0,0 +1,358 @@
+# -*- coding: utf-8 -*-
+
+"""
+The MIT License (MIT)
+
+Copyright (c) 2021-present mccoderpy
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+"""
+from __future__ import annotations
+
+from typing import (
+    Type,
+    List,
+    Optional
+)
+
+from typing_extensions import (
+    Final,
+    Literal,
+    NotRequired,
+    TypedDict
+)
+
+from .channel import GuildChannel
+from .emoji import BaseEmoji, PartialEmoji
+from .snowflake import SnowflakeID, SnowflakeList
+from .sticker import GuildSticker
+from .user import User, Member
+
+__all__ = (
+    'PermissionFlag',
+    'UnavailableGuild',
+    'PartialGuild',
+    'Guild',
+    'GuildPreview',
+    'GuildWidget',
+    'GuildWidgetSettings',
+    'Role',
+    'RoleTag',
+    'OnboardingPrompt',
+    'OnboardingPromptOption',
+    'Onboarding',
+    'WelcomeScreen',
+    'WelcomeScreenChannel',
+    'ScheduledEventEntityMetadata',
+    'ScheduledEvent',
+)
+
+DefaultMessageNotificationLevel = Literal[0, 1]
+ExplicitContentFilterLevel = Literal[0, 1, 2]
+MFALevel = Literal[0, 1]
+AfkTimeout = Literal[60, 300, 900, 1800, 3600]
+VerificationLevel = Literal[0, 1, 2, 3, 4]
+GuildNSFWLevel = Literal[0, 1, 2, 3]
+PremiumTier = Literal[0, 1, 2, 3]
+OnlineStatus = Literal['online', 'idle', 'dnd', 'offline']
+GuildFeature: Final[Type[str]] = Literal[
+    'ANIMATED_BANNER',
+    'ANIMATED_ICON',
+    'APPLICATION_COMMAND_PERMISSIONS_V2',
+    'AUTO_MODERATION',
+    'BANNER',
+    'COMMERCE',
+    'COMMUNITY',
+    'DISCOVERABLE',
+    'ENABLED_DISCOVERABLE_BEFORE',
+    'FORCE_RELAY',
+    'RELAY_ENABLED',
+    'INVITE_SPLASH',
+    'MEMBER_VERIFICATION_GATE_ENABLED',
+    'MORE_EMOJI',
+    'NEWS',
+    'PARTNERED',
+    'VERIFIED',
+    'VANITY_URL',
+    'VIP_REGIONS',
+    'WELCOME_SCREEN_ENABLED',
+    'DISCOVERY_DISABLED',
+    'PREVIEW_ENABLED',
+    'MORE_STICKERS',
+    'MONETIZATION_ENABLED',
+    'TICKETING_ENABLED',
+    'HUB',
+    'LINKED_TO_HUB',
+    'HAS_DIRECTORY_ENTRY',
+    'THREE_DAY_THREAD_ARCHIVE',
+    'SEVEN_DAY_THREAD_ARCHIVE',
+    'PRIVATE_THREADS',
+    'THREADS_ENABLED',
+    'ROLE_ICONS',
+    'INTERNAL_EMPLOYEE_ONLY',
+    'PREMIUM_TIER_3_OVERRIDE',
+    'FEATUREABLE',
+    'MEMBER_PROFILES'
+    'APPEALABLE',
+    'ROLE_SUBSCRIPTIONS_ENABLED',
+    'ROLE_SUBSCRIPTIONS_ENABLED_FOR_PURCHASE',
+]
+PermissionFlag: Final[Type[str]] = Literal[
+    'create_instant_invite',
+    'kick_members',
+    'ban_members',
+    'administrator',
+    'manage_channels',
+    'manage_guild',
+    'add_reactions',
+    'view_audit_log',
+    'priority_speaker',
+    'stream',
+    'read_messages',
+    'send_messages',
+    'send_tts_messages',
+    'manage_messages',
+    'embed_links',
+    'attach_files',
+    'read_message_history',
+    'mention_everyone',
+    'external_emojis',
+    'view_guild_insights',
+    'connect',
+    'speak',
+    'mute_members',
+    'deafen_members',
+    'move_members',
+    'use_voice_activation',
+    'change_nickname',
+    'manage_nicknames',
+    'manage_roles',
+    'manage_webhooks',
+    'manage_expressions',
+    'create_expressions',
+    'use_slash_commands',
+    'request_to_speak',
+    'manage_events',
+    'create_events',
+    'manage_threads',
+    'create_public_threads',
+    'create_private_threads',
+    'use_external_stickers',
+    'send_messages_in_threads',
+    'start_embedded_activities',
+    'moderate_members',
+    'view_creator_monetization_analytics',
+    'use_soundboard',
+    'use_external_sounds',
+    'send_voice_messages',
+    'set_voice_channel_status',
+]
+ScheduledEventPrivacyLevel = Literal[2]
+ScheduledEventStatus = Literal[1, 2, 3, 4]
+ScheduledEntityType = Literal[1, 2, 3]
+OnboardingMode = Literal[0, 1]
+OnboardingPromptType = Literal[0, 1]
+
+class UnavailableGuild(TypedDict):
+    id: SnowflakeID
+    unavailable: bool
+
+
+class PartialGuild(TypedDict):
+    id: SnowflakeID
+    name: str
+    features: List[str]
+    icon: NotRequired[str]
+    owner: NotRequired[bool]
+    permissions: NotRequired[str]
+
+
+class RoleTag(TypedDict):
+    bot_id: NotRequired[SnowflakeID]
+    integration_id: NotRequired[SnowflakeID]
+    premium_subscriber: NotRequired[Literal[None]]
+    subscription_listing_id: NotRequired[SnowflakeID]
+    available_for_purchase: NotRequired[Literal[None]]
+    guild_connection: NotRequired[Literal[None]]
+
+
+class Role(TypedDict):
+    id: SnowflakeID
+    name: str
+    color: int
+    hoist: bool
+    icon: NotRequired[Optional[str]]
+    unicode_emoji: NotRequired[Optional[str]]
+    position: int
+    permissions: str
+    mentionable: bool
+    tags: NotRequired[RoleTag]
+
+
+class IncidentsData(TypedDict):
+    invites_disabled_until: Optional[str]
+    dms_disabled_until: Optional[str]
+
+
+class Guild(UnavailableGuild):
+    name: str
+    icon: str
+    splash: Optional[str]
+    discovery_splash: Optional[str]
+    owner: NotRequired[bool]
+    owner_id: SnowflakeID
+    permissions: NotRequired[str]
+    afk_channel_id: Optional[SnowflakeID]
+    afk_timeout: AfkTimeout
+    member_count: NotRequired[int]
+    widget_enabled: NotRequired[bool]
+    widget_channel_id: NotRequired[Optional[SnowflakeID]]
+    verification_level: VerificationLevel
+    default_message_notifications: DefaultMessageNotificationLevel
+    explicit_content_filter: ExplicitContentFilterLevel
+    roles: List[Role]
+    emojis: List[BaseEmoji]
+    features: List[GuildFeature]
+    mfa_level: MFALevel
+    application_id: Optional[SnowflakeID]
+    system_channel_id: Optional[SnowflakeID]
+    system_channel_flags: int
+    rules_channel_id: Optional[SnowflakeID]
+    max_presences: NotRequired[Optional[int]]
+    max_members: NotRequired[int]
+    vanity_url_code: Optional[str]
+    description: Optional[str]
+    banner: Optional[str]
+    premium_tier: PremiumTier
+    premium_subscription_count: NotRequired[int]
+    preferred_locale: str
+    public_updates_channel_id: Optional[SnowflakeID]
+    safety_alerts_channel_id: Optional[SnowflakeID]
+    max_video_channel_users: NotRequired[int]
+    approximate_member_count: NotRequired[int]
+    approximate_presence_count: NotRequired[int]
+    welcome_screen: NotRequired[WelcomeScreen]
+    nsfw_level: GuildNSFWLevel
+    stickers: NotRequired[List[GuildSticker]]
+    premium_progress_bar_enabled: bool
+    incidents_data: NotRequired[IncidentsData]
+    members: NotRequired[List[Member]]
+
+
+class WelcomeScreenChannel(TypedDict):
+    channel_id: SnowflakeID
+    description: str
+    emoji_id: Optional[SnowflakeID]
+    emoji_name: Optional[str]
+
+
+class WelcomeScreen(TypedDict):
+    description: str
+    welcome_channels: List[WelcomeScreenChannel]
+
+
+class GuildPreview(TypedDict):
+    id: SnowflakeID
+    name: str
+    icon: Optional[str]
+    splash: Optional[str]
+    discovery_splash: Optional[str]
+    emojis: List[BaseEmoji]
+    features: List[GuildFeature]
+    approximate_member_count: int
+    approximate_presence_count: int
+    description: Optional[str]
+    stickers: List[GuildSticker]
+
+
+class GuildWidgetSettings(TypedDict):
+    enabled: bool
+    channel_id: Optional[SnowflakeID]
+
+
+class GuildWidgetUser(TypedDict):
+    id: SnowflakeID
+    username: str
+    discriminator: Literal['0000']
+    avatar: Literal[None]
+    status: OnlineStatus
+    bot: bool
+    avatar_url: str
+
+
+class OnboardingPromptOption(TypedDict):
+    id: SnowflakeID
+    channel_ids: SnowflakeList
+    role_ids: SnowflakeList
+    emoji: PartialEmoji
+    title: str
+    description: Optional[str]
+
+
+class OnboardingPrompt(TypedDict):
+    id: SnowflakeID
+    type: OnboardingPromptType
+    options: List[OnboardingPromptOption]
+    title: str
+    single_select: bool
+    required: bool
+    in_onboarding: bool
+
+
+class Onboarding(TypedDict):
+    guild_id: SnowflakeID
+    prompts: List[OnboardingPrompt]
+    default_channel_ids: SnowflakeList
+    enabled: bool
+    mode: OnboardingMode
+    # There are some other fields for storing the seen prompts of the current user
+    # and their selected options, but as bots can't use onboarding itself, we don't them
+
+
+class GuildWidget(TypedDict):
+    id: SnowflakeID
+    name: str
+    instant_invite: Optional[str]
+    channels: List[GuildChannel]
+    members: List[GuildWidgetUser]
+    presence_count: int
+
+
+class ScheduledEventEntityMetadata(TypedDict, total=False):
+    location: str
+
+
+class ScheduledEvent(TypedDict):
+    id: SnowflakeID
+    guild_id: SnowflakeID
+    name: str
+    channel_id: Optional[SnowflakeID]
+    creator_id: NotRequired[Optional[SnowflakeID]]
+    description: NotRequired[Optional[str]]
+    scheduled_start_time: str
+    scheduled_end_time: Optional[str]
+    privacy_level: ScheduledEventPrivacyLevel
+    status: ScheduledEventStatus
+    entity_type: ScheduledEntityType
+    entity_id: Optional[SnowflakeID]
+    entity_metadata: Optional[ScheduledEventEntityMetadata]
+    creator: NotRequired[User]
+    user_count: NotRequired[int]
+    image: NotRequired[Optional[str]]
+    broadcast_to_directory_channels: NotRequired[bool]
\ No newline at end of file
diff --git a/discord/types/integration.py b/discord/types/integration.py
new file mode 100644
index 00000000..8b0cd1d1
--- /dev/null
+++ b/discord/types/integration.py
@@ -0,0 +1,100 @@
+# -*- coding: utf-8 -*-
+
+"""
+The MIT License (MIT)
+
+Copyright (c) 2021-present mccoderpy
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+"""
+
+from __future__ import annotations
+
+from typing import (
+    Optional,
+    Union
+)
+from typing_extensions import (
+    TypedDict,
+    NotRequired,
+    Literal
+)
+
+from .snowflake import SnowflakeID
+from .user import BaseUser
+
+__all__ = (
+    'IntegrationType',
+    'IntegrationExpireBehavior',
+    'IntegrationApplication',
+    'IntegrationAccount',
+    'PartialIntegration',
+    'BaseIntegration',
+    'StreamIntegration',
+    'BotIntegration',
+    'Integration'
+)
+
+IntegrationType = Literal['twitch', 'youtube', 'discord', 'guild_subscription']
+IntegrationExpireBehavior = Literal[0, 1]
+
+
+class IntegrationApplication(TypedDict):
+    id: SnowflakeID
+    name: str
+    icon: Optional[str]
+    description: str
+    summary: str
+    bot: NotRequired[BaseUser]
+
+
+class IntegrationAccount(TypedDict):
+    id: str
+    name: str
+
+
+class PartialIntegration(TypedDict):
+    id: SnowflakeID
+    name: str
+    type: IntegrationType
+    account: IntegrationAccount
+    application_id: SnowflakeID
+
+
+class BaseIntegration(PartialIntegration):
+    enabled: bool
+    syncing: bool
+    synced_at: str
+    user: BaseUser
+    expire_behavior: IntegrationExpireBehavior
+    expire_grace_period: int
+
+
+class StreamIntegration(BaseIntegration):
+    role_id: Optional[SnowflakeID]
+    enable_emoticons: bool
+    subscriber_count: int
+    revoked: bool
+
+
+class BotIntegration(BaseIntegration):
+    application: IntegrationApplication
+
+
+Integration = Union[BaseIntegration, StreamIntegration, BotIntegration]
diff --git a/discord/types/interaction.py b/discord/types/interaction.py
new file mode 100644
index 00000000..f60f0add
--- /dev/null
+++ b/discord/types/interaction.py
@@ -0,0 +1,164 @@
+# -*- coding: utf-8 -*-
+
+"""
+The MIT License (MIT)
+
+Copyright (c) 2021-present mccoderpy
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+"""
+from __future__ import annotations
+
+from typing import (
+    Dict,
+    List,
+    Union
+)
+
+from typing_extensions import (
+    Literal,
+    NotRequired,
+    TypedDict
+)
+
+from .channel import PartialChannel
+from .guild import Role
+from .message import (
+    ActionRow,
+    Attachment,
+    ComponentType,
+    Message,
+    PartialMessage
+)
+from .snowflake import SnowflakeID
+from .user import BaseUser, MemberWithUser, PartialMember
+
+__all__ = (
+    'AuthorizingIntegrationOwners',
+    'PingInteraction',
+    'ApplicationCommandInteraction',
+    'ComponentInteraction',
+    'ModalSubmitInteraction',
+    'ApplicationCommandData',
+    'ApplicationCommandInteractionDataOption',
+    'MessageComponentData',
+    'ModalSubmitData',
+    'ResolvedData',
+    'Interaction',
+    'InteractionData',
+)
+
+
+InteractionType = Literal[1, 2, 3, 4, 5]
+ApplicationCommandType = Literal[1, 2, 3]
+ContextType = Literal[1, 2, 3]
+AppIntegrationType = Literal[1, 2]
+
+
+class PartialInteractionGuild(TypedDict):
+    locale: str
+    id: SnowflakeID
+    features: List[str]
+
+
+class ResolvedData(TypedDict):
+    users: NotRequired[Dict[SnowflakeID, BaseUser]]
+    members: NotRequired[Dict[SnowflakeID, PartialMember]]
+    roles: NotRequired[Dict[SnowflakeID, Role]]
+    channels: NotRequired[Dict[SnowflakeID, PartialChannel]]
+    messages: NotRequired[Dict[SnowflakeID, PartialMessage]]
+    attachments: NotRequired[Dict[SnowflakeID, Attachment]]
+
+
+class ApplicationCommandInteractionDataOption(TypedDict):
+    name: str
+    type: ApplicationCommandType
+    value: NotRequired[Union[str, int, float, bool]]
+    options: NotRequired[List[ApplicationCommandInteractionDataOption]]
+    focused: NotRequired[Literal[True]]
+
+
+class ApplicationCommandData(TypedDict):
+    id: SnowflakeID
+    name: str
+    type: ApplicationCommandType
+    resolved: NotRequired[ResolvedData]
+    options: NotRequired[List[ApplicationCommandInteractionDataOption]]
+    guild_id: NotRequired[SnowflakeID]
+    target_id: NotRequired[SnowflakeID]
+
+
+class MessageComponentData(TypedDict):
+    custom_id: str
+    component_type: ComponentType
+    values: NotRequired[List[str]]
+
+
+class ModalSubmitData(TypedDict):
+    custom_id: str
+    values: List[ActionRow]
+
+
+class PingInteraction(TypedDict):
+    type: Literal[1]
+    id: SnowflakeID
+    application_id: SnowflakeID
+
+
+class AuthorizingIntegrationOwners(TypedDict):
+    Literal['0']: NotRequired[SnowflakeID]  # Guild ID or 0 in a DM with the Bot
+    Literal['1']: NotRequired[SnowflakeID]  # User ID
+
+
+class BaseInteraction(TypedDict):
+    id: SnowflakeID
+    application_id: SnowflakeID
+    token: str
+    version: int
+    locale: str
+    authorizing_integration_owners: AppIntegrationType
+    context: NotRequired[ContextType]
+    guild_id: NotRequired[SnowflakeID]
+    channel_id: NotRequired[SnowflakeID]
+    channel: NotRequired[PartialChannel]
+    guild: NotRequired[PartialInteractionGuild]
+    user: NotRequired[BaseUser]
+    member: NotRequired[MemberWithUser]
+    app_permissions: NotRequired[str]
+    guild_locale: NotRequired[str]
+
+
+class ApplicationCommandInteraction(BaseInteraction, final=False):
+    type: Literal[1, 3]
+    data: ApplicationCommandData
+
+    
+class ComponentInteraction(BaseInteraction, final=False):
+    type: Literal[2]
+    data: MessageComponentData
+    message: Message
+
+
+class ModalSubmitInteraction(BaseInteraction, final=False):
+    type: Literal[4]
+    data: ModalSubmitData
+
+
+Interaction = Union[ApplicationCommandInteraction, ComponentInteraction, ModalSubmitInteraction]
+InteractionData = Union[ApplicationCommandData, MessageComponentData, ModalSubmitData]
diff --git a/discord/types/message.py b/discord/types/message.py
new file mode 100644
index 00000000..679e29b1
--- /dev/null
+++ b/discord/types/message.py
@@ -0,0 +1,343 @@
+# -*- coding: utf-8 -*-
+
+"""
+The MIT License (MIT)
+
+Copyright (c) 2021-present mccoderpy
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+"""
+from __future__ import annotations
+
+from typing import (
+    Dict,
+    List,
+    Optional,
+    Union
+)
+from typing_extensions import (
+    TypedDict,
+    NotRequired,
+    Literal
+)
+
+from .snowflake import SnowflakeID
+from .emoji import PartialEmoji
+from .channel import ChannelType, ThreadChannel
+from .appinfo import PartialAppInfo
+from .user import BaseUser, User, WebhookUser, PartialMember
+
+
+__all__ = (
+    'ActionRow',
+    'Button',
+    'SelectMenu',
+    'SelectOption',
+    'DefaultValue',
+    'TextInput',
+    'MessageComponent',
+    'Attachment',
+    'PartialEmoji',
+    'Reaction',
+    'Embed',
+    'PartialMessage',
+    'RoleSubscriptionData',
+    'Message',
+    'MessageReference',
+    'MessageActivity',
+    'MessageInteraction',
+    'Modal'
+)
+
+
+ComponentType = Literal[1, 2, 3, 4, 5, 6, 7, 8]
+ButtonStyle = Literal[1, 2, 3, 4, 5, 6]
+TextInputStyle = Literal[1, 2]
+SelectDefaultValueType = Literal['user', 'role', 'channel']
+MessageType = Literal[
+    0,  # Default
+    1,  # Recipient Add
+    2,  # Recipient Remove
+    3,  # Call
+    4,  # Channel Name Change
+    5,  # Channel Icon Change
+    6,  # Channel Pin
+    7,  # Guild Member Join
+    8,  # User Premium Guild Subscription
+    9,  # User Premium Guild Subscription Tier 1
+    10,  # User Premium Guild Subscription Tier 2
+    11,  # User Premium Guild Subscription Tier 3
+    12,  # Channel Follow Add
+    14,  # Guild Discovery Disqualified
+    15,  # Guild Discovery Requalified
+    16,  # Guild Discovery Grace Period Initial Warning
+    17,  # Guild Discovery Grace Period Final Warning
+    18,  # Thread Created
+    19,  # Reply
+    20,  # Chatinput Command
+    21,  # Thread Starter Message
+    22,  # Guild Invite Reminder
+    23,  # Context Menu Command
+    24,  # Automod Action
+    25,  # Role Subscription Purchase
+    26,  # Interaction Premium Upsell
+    27,  # Stage start
+    28,  # Stage end
+    29,  # Stage speaker change
+    31,  # Stage topic change
+    32  # Guild application premium subscription
+]
+EmbedType = Literal['rich', 'image', 'video', 'gifv', 'article', 'link']
+MessageActivityType = Literal[1, 2, 3, 5]
+StickerFormatType = Literal[1, 2, 3, 4]
+ReactionType = Literal[1, 2]
+
+
+class ActionRow(TypedDict):
+    type: Literal[1]
+    components: List[MessageComponent]
+
+
+class Button(TypedDict):
+    type: Literal[2]
+    style: ButtonStyle
+    label: str
+    emoji: NotRequired[PartialEmoji]
+    custom_id: NotRequired[str]
+    url: NotRequired[str]
+    disabled: NotRequired[bool]
+    sku_id: NotRequired[int]
+
+
+class DefaultValue(TypedDict):
+    id: SnowflakeID
+    type: SelectDefaultValueType
+
+
+class SelectMenu(TypedDict):
+    type: Literal[3, 5, 6, 7, 8]
+    custom_id: str
+    options: NotRequired[List[SelectOption]]
+    channel_types: NotRequired[List[ChannelType]]
+    placeholder: NotRequired[str]
+    min_values: NotRequired[int]
+    max_values: NotRequired[int]
+    disabled: NotRequired[bool]
+    default_values: NotRequired[List[DefaultValue]]
+
+
+class SelectOption(TypedDict):
+    label: str
+    value: str
+    description: NotRequired[str]
+    emoji: NotRequired[PartialEmoji]
+    default: NotRequired[Literal[True]]
+
+
+class TextInput(TypedDict):
+    type: Literal[4]
+    custom_id: str
+    style: TextInputStyle
+    label: str
+    min_length: NotRequired[int]
+    max_length: NotRequired[int]
+    required: NotRequired[bool]
+    value: NotRequired[str]
+    placeholder: NotRequired[str]
+
+
+MessageComponent = Union[Button, SelectMenu, TextInput]
+
+
+class Attachment(TypedDict):
+    id: SnowflakeID
+    filename: str
+    description: NotRequired[str]
+    content_type: NotRequired[str]
+    size: int
+    url: str
+    proxy_url: str
+    height: NotRequired[Optional[int]]
+    width: NotRequired[Optional[int]]
+    ephemeral: NotRequired[Literal[True]]
+    duration_secs: NotRequired[float]
+    waveform: NotRequired[str]
+
+
+class PartialMessage(TypedDict):
+    id: SnowflakeID
+    channel_id: SnowflakeID
+    guild_id: NotRequired[SnowflakeID]
+
+
+class EmbedFooter(TypedDict):
+    text: str
+    icon_url: NotRequired[str]
+    proxy_icon_url: NotRequired[str]
+
+
+class EmbedImage(TypedDict):
+    url: str
+    proxy_url: NotRequired[str]
+    height: NotRequired[int]
+    width: NotRequired[int]
+
+
+class EmbedThumbnail(TypedDict):
+    url: str
+    proxy_url: NotRequired[str]
+    height: NotRequired[int]
+    width: NotRequired[int]
+
+
+class EmbedVideo(TypedDict):
+    url: NotRequired[str]
+    proxy_url: NotRequired[str]
+    height: NotRequired[int]
+    width: NotRequired[int]
+
+
+class EmbedProvider(TypedDict):
+    name: NotRequired[str]
+    url: NotRequired[str]
+
+
+class EmbedAuthor(TypedDict):
+    name: str
+    url: NotRequired[str]
+    icon_url: NotRequired[str]
+    proxy_icon_url: NotRequired[str]
+
+
+class EmbedField(TypedDict):
+    name: str
+    value: str
+    inline: NotRequired[bool]
+
+
+class Embed(TypedDict):
+    title: NotRequired[str]
+    type: EmbedType
+    description: NotRequired[str]
+    url: NotRequired[str]
+    timestamp: NotRequired[str]
+    color: NotRequired[int]
+    footer: NotRequired[EmbedFooter]
+    image: NotRequired[EmbedImage]
+    thumbnail: NotRequired[EmbedThumbnail]
+    video: NotRequired[EmbedVideo]
+    provider: NotRequired[EmbedProvider]
+    author: NotRequired[EmbedAuthor]
+    fields: NotRequired[List[EmbedField]]
+
+
+class ReactionCountDetails(TypedDict):
+    normal: int
+    burst: int
+
+
+class Reaction(TypedDict):
+    count: int
+    burst_count: NotRequired[int]
+    count_details: NotRequired[ReactionCountDetails]
+    me: bool
+    emoji: PartialEmoji
+    type: Literal[1, 2]
+    burst: NotRequired[bool]  # As burst reactions api is still subject to change this might be removed in the future
+    message_id: NotRequired[SnowflakeID]
+    channel_id: NotRequired[SnowflakeID]
+    user_id: NotRequired[SnowflakeID]
+
+
+
+class ChannelMention(TypedDict):
+    id: SnowflakeID
+    guild_id: SnowflakeID
+    type: ChannelType
+    name: str
+
+
+class MessageReference(TypedDict):
+    message_id: NotRequired[SnowflakeID]
+    channel_id: NotRequired[SnowflakeID]
+    guild_id: NotRequired[SnowflakeID]
+    fail_if_not_exists: NotRequired[bool]
+
+
+class MessageActivity(TypedDict):
+    type: MessageActivityType
+    party_id: NotRequired[str]
+
+
+class MessageInteraction(TypedDict):
+    id: SnowflakeID
+    type: Literal[1]
+    name: str
+    user: BaseUser
+    member: NotRequired[PartialMember]
+
+
+class StickerItem(TypedDict):
+    id: SnowflakeID
+    name: str
+    format_type: StickerFormatType
+
+
+class RoleSubscriptionData(TypedDict):
+    role_subscription_listing_id: SnowflakeID
+    tier_name: str
+    total_months_subscribed: int
+    is_renewal: bool
+
+
+class Message(PartialMessage):
+    author: Union[User, WebhookUser]
+    content: str
+    timestamp: str
+    edited_timestamp: Optional[str]
+    tts: bool
+    mention_everyone: bool
+    mentions: List[User]
+    mention_roles: List[SnowflakeID]
+    mention_channels: NotRequired[List[ChannelMention]]
+    attachments: List[Attachment]
+    embeds: List[Embed]
+    reactions: NotRequired[List[Reaction]]
+    nonce: NotRequired[Union[int, str]]
+    pinned: bool
+    webhook_id: NotRequired[SnowflakeID]
+    type: MessageType
+    activity: NotRequired[MessageActivity]
+    application: NotRequired[PartialAppInfo]
+    application_id: NotRequired[SnowflakeID]
+    message_reference: NotRequired[MessageReference]
+    flags: NotRequired[int]
+    referenced_message: NotRequired[Optional[Message]]
+    interaction: NotRequired[MessageInteraction]
+    thread: NotRequired[ThreadChannel]
+    components: NotRequired[List[ActionRow]]
+    sticker_items: NotRequired[List[StickerItem]]
+    position: NotRequired[int]
+    role_subscription_data: NotRequired[RoleSubscriptionData]
+
+
+class Modal(TypedDict):
+    title: str
+    custom_id: str
+    components: List[ActionRow]
diff --git a/discord/types/monetization.py b/discord/types/monetization.py
new file mode 100644
index 00000000..22b2bda1
--- /dev/null
+++ b/discord/types/monetization.py
@@ -0,0 +1,92 @@
+#  The MIT License (MIT)
+#
+#  Copyright (c) 2015-2021 Rapptz & (c) 2021-present mccoderpy
+#
+#  Permission is hereby granted, free of charge, to any person obtaining a
+#  copy of this software and associated documentation files (the "Software"),
+#  to deal in the Software without restriction, including without limitation
+#  the rights to use, copy, modify, merge, publish, distribute, sublicense,
+#  and/or sell copies of the Software, and to permit persons to whom the
+#  Software is furnished to do so, subject to the following conditions:
+#
+#  The above copyright notice and this permission notice shall be included in
+#  all copies or substantial portions of the Software.
+#
+#  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+#  OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+#  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+#  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+#  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+#  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+#  DEALINGS IN THE SOFTWARE.
+
+#  The MIT License (MIT)
+#
+#
+#  Permission is hereby granted, free of charge, to any person obtaining a
+#  copy of this software and associated documentation files (the "Software"),
+#  to deal in the Software without restriction, including without limitation
+#  the rights to use, copy, modify, merge, publish, distribute, sublicense,
+#  and/or sell copies of the Software, and to permit persons to whom the
+#  Software is furnished to do so, subject to the following conditions:
+#
+#
+from __future__ import annotations
+
+from typing import TypedDict, Union, Optional, List
+
+from typing_extensions import Literal, NotRequired
+
+from .snowflake import SnowflakeID
+
+__all__ = (
+    'SKU',
+    'TestEntitlement',
+    'Entitlement',
+    'Subscription',
+)
+
+SKUType = Literal[1, 2, 3, 4, 5, 6]
+EntitlementType = Literal[1, 2, 3, 4, 5, 6, 7, 8]
+SubscriptionStatus = Literal[0, 1, 2]
+
+
+class SKU(TypedDict):
+    id: SnowflakeID
+    type: SKUType
+    application_id: SnowflakeID
+    name: str
+    slug: str
+    flags: int
+
+
+class TestEntitlement(TypedDict):
+    id: SnowflakeID
+    application_id: SnowflakeID
+    sku_id: SnowflakeID
+    user_id: NotRequired[SnowflakeID]
+    guild_id: NotRequired[SnowflakeID]
+    type: EntitlementType
+    consumed: bool
+    deleted: bool
+
+
+class Entitlement(TestEntitlement):
+    subscription_id: SnowflakeID
+    starts_at: str
+    ends_at: str
+
+
+class Subscription(TypedDict):
+    id: SnowflakeID
+    user_id: SnowflakeID
+    sku_ids: List[SnowflakeID]
+    entitlement_ids: List[SnowflakeID]
+    starts_at: str
+    ends_at: str
+    status: SubscriptionStatus
+    canceled_at: Optional[str]
+    country: NotRequired[str]
+
+
+EntitlementData = Union[TestEntitlement, Entitlement]
diff --git a/discord/types/snowflake.py b/discord/types/snowflake.py
new file mode 100644
index 00000000..0f676be7
--- /dev/null
+++ b/discord/types/snowflake.py
@@ -0,0 +1,47 @@
+# -*- coding: utf-8 -*-
+
+"""
+The MIT License (MIT)
+
+Copyright (c) 2021-present mccoderpy
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+"""
+from typing import (
+    List,
+    Protocol,
+    runtime_checkable,
+    Union
+)
+
+__all__ = (
+    'SnowflakeID',
+    'SnowflakeObject',
+    'SnowflakeList',
+)
+
+SnowflakeID = Union[int, str]
+
+
+@runtime_checkable
+class SnowflakeObject(Protocol):
+    id: SnowflakeID
+
+
+SnowflakeList = List[SnowflakeID]
diff --git a/discord/types/sticker.py b/discord/types/sticker.py
new file mode 100644
index 00000000..ade0ab09
--- /dev/null
+++ b/discord/types/sticker.py
@@ -0,0 +1,81 @@
+# -*- coding: utf-8 -*-
+
+"""
+The MIT License (MIT)
+
+Copyright (c) 2021-present mccoderpy
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+"""
+from __future__ import annotations
+
+from typing import (
+    List,
+    Optional
+)
+
+from typing_extensions import (
+    Literal,
+    NotRequired,
+    TypedDict
+)
+
+from .snowflake import SnowflakeID
+from .user import BaseUser
+
+__all__ = (
+    'StickerPack',
+    'Sticker',
+    'GuildSticker'
+)
+
+StickerFormatType = Literal[1, 2, 3, 4]
+
+
+class StickerPack(TypedDict):
+    id: SnowflakeID
+    stickers: List[Sticker]
+    name: str
+    sku_id: SnowflakeID
+    cover_sticker_id: NotRequired[SnowflakeID]
+    description: str
+    banner_asset_id: NotRequired[SnowflakeID]
+
+
+class Sticker(TypedDict):
+    id: SnowflakeID
+    pack_id: NotRequired[SnowflakeID]
+    type: Literal[1]
+    name: str
+    description: Optional[str]
+    tags: str
+    format_type: StickerFormatType
+    sort_value: NotRequired[int]
+
+
+class GuildSticker(TypedDict):
+    id: SnowflakeID
+    type: Literal[2]
+    name: str
+    description: Optional[str]
+    tags: str
+    format_type: StickerFormatType
+    available: bool
+    guild_id: SnowflakeID
+    user: NotRequired[BaseUser]
diff --git a/discord/types/user.py b/discord/types/user.py
new file mode 100644
index 00000000..6eeefd09
--- /dev/null
+++ b/discord/types/user.py
@@ -0,0 +1,123 @@
+# -*- coding: utf-8 -*-
+
+"""
+The MIT License (MIT)
+
+Copyright (c) 2021-present mccoderpy
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+"""
+from __future__ import annotations
+
+from typing import (
+    List,
+    Optional,
+    TypedDict
+)
+
+from typing_extensions import (
+    NotRequired
+)
+
+from .snowflake import SnowflakeID, SnowflakeList
+
+__all__ = (
+    'BaseUser',
+    'User',
+    'ClientUser',
+    'WebhookUser',
+    'PartialMember',
+    'Member',
+    'MemberWithUser',
+    'UserWithMember'
+)
+
+
+class AvatarDecoration(TypedDict):
+    sku_id: SnowflakeID
+    asset: str
+
+class BaseUser(TypedDict):
+    id: SnowflakeID
+    username: str
+    global_name: Optional[str]
+    discriminator: str  # Deprecated :(
+    avatar: Optional[str]
+
+
+class User(BaseUser, total=False):
+    public_flags: NotRequired[int]
+    bot: NotRequired[bool]
+    system: NotRequired[bool]
+    avatar_decoration: NotRequired[str]
+    avatar_decoration_data: NotRequired[AvatarDecoration]
+    banner: NotRequired[Optional[str]]
+    accent_color: NotRequired[Optional[int]]
+
+
+class ClientUser(User, total=False):
+    verified: NotRequired[bool]
+    mfa_enabled: NotRequired[bool]
+    flags: NotRequired[int]
+    locale: NotRequired[str]
+    # There are some other fields, but they are not usable by bots so empty
+
+
+class WebhookUser(TypedDict):
+    id: SnowflakeID
+    username: str
+    avatar: Optional[str]
+    
+
+class PartialMember(TypedDict):
+    roles: SnowflakeList
+    deaf: bool
+    mute: bool
+    joined_at: str
+    flags: NotRequired[int]
+    
+
+class Member(PartialMember):
+    avatar: NotRequired[Optional[str]]
+    banner: NotRequired[Optional[str]]
+    user: User
+    nick: NotRequired[Optional[str]]
+    premium_since: NotRequired[Optional[str]]
+    pending: NotRequired[bool]
+    permissions: NotRequired[str]
+    communication_disabled_until: NotRequired[Optional[str]]
+    
+
+class _OptionalMemberWithUser(PartialMember):
+    avatar: NotRequired[Optional[str]]
+    banner: NotRequired[Optional[str]]
+    nick: NotRequired[Optional[str]]
+    premium_since: Optional[str]
+    pending: NotRequired[bool]
+    permissions: NotRequired[str]
+    communication_disabled_until: NotRequired[Optional[str]]
+
+
+class MemberWithUser(_OptionalMemberWithUser):
+    user: User
+
+
+class UserWithMember(User, total=False):
+    member: _OptionalMemberWithUser
+
diff --git a/discord/types/voice.py b/discord/types/voice.py
new file mode 100644
index 00000000..960fb9b4
--- /dev/null
+++ b/discord/types/voice.py
@@ -0,0 +1,36 @@
+"""
+The MIT License (MIT)
+
+Copyright (c) 2021-present mccoderpy
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+"""
+
+from __future__ import annotations
+
+from typing_extensions import TypedDict
+
+
+class VoiceRegion(TypedDict):
+    id: str
+    name: str
+    vip: bool
+    optimal: bool
+    deprecated: bool
+    custom: bool
diff --git a/discord/types/webhook.py b/discord/types/webhook.py
new file mode 100644
index 00000000..9c279384
--- /dev/null
+++ b/discord/types/webhook.py
@@ -0,0 +1,68 @@
+# -*- coding: utf-8 -*-
+
+"""
+The MIT License (MIT)
+
+Copyright (c) 2021-present mccoderpy
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+"""
+
+from __future__ import annotations
+
+from typing import (
+    Optional
+)
+
+from typing_extensions import (
+    Literal,
+    NotRequired,
+    TypedDict
+)
+from . import (
+    channel,
+    guild,
+    user
+)
+from .snowflake import SnowflakeID
+
+WebhookType = Literal[1, 2, 3]
+
+
+class PartialWebhook(TypedDict):
+    id: SnowflakeID
+    type: WebhookType
+    token: NotRequired[str]
+
+
+class Webhook(PartialWebhook, total=False):
+    guild_id: str
+    channel_id: str
+    user: user.User
+    name: str
+    avatar: str
+    application_id: str
+    source_guild: guild.PartialGuild
+    source_channel: channel.PartialChannel
+    url: str
+
+
+class FollowedChannel(TypedDict):
+    channel_id: SnowflakeID
+    webhook_id: SnowflakeID
diff --git a/discord/user.py b/discord/user.py
index 8b2d3a1c..5cd8b033 100644
--- a/discord/user.py
+++ b/discord/user.py
@@ -3,7 +3,7 @@
 """
 The MIT License (MIT)
 
-Copyright (c) 2015-present Rapptz
+Copyright (c) 2015-2021 Rapptz & (c) 2021-present mccoderpy
 
 Permission is hereby granted, free of charge, to any person obtaining a
 copy of this software and associated documentation files (the "Software"),
@@ -23,124 +23,178 @@
 FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 DEALINGS IN THE SOFTWARE.
 """
+from __future__ import annotations
 
-from collections import namedtuple
+from typing import (
+    Any,
+    Dict,
+    List,
+    Union,
+    Optional,
+    Type,
+    TYPE_CHECKING
+)
 
-import discord.abc
+from typing_extensions import Literal
+
+from . import abc, utils
 from .flags import PublicUserFlags
-from .utils import snowflake_time, _bytes_to_base64_data, parse_time
-from .enums import DefaultAvatar, RelationshipType, UserFlags, HypeSquadHouse, PremiumType, try_enum
-from .errors import ClientException
+from .utils import snowflake_time, _bytes_to_base64_data
+from .enums import DefaultAvatar, try_enum
 from .colour import Colour
 from .asset import Asset
-from .utils import deprecated
-
-class Profile(namedtuple('Profile', 'flags user mutual_guilds connected_accounts premium_since')):
-    __slots__ = ()
-
-    @property
-    def nitro(self):
-        return self.premium_since is not None
 
-    premium = nitro
+if TYPE_CHECKING:
+    from .types.user import (
+        User as UserData,
+        ClientUser as ClientUserData,
+    )
+    import datetime
+    from .abc import GuildChannel
+    from .channel import DMChannel, ThreadChannel
+    from .guild import Guild
+    from .message import Message
+    from .permissions import Permissions
+    from .state import ConnectionState
+    from .oauth2.client import OAuth2Client
 
-    def _has_flag(self, o):
-        v = o.value
-        return (self.flags & v) == v
+    HAS_HTTP_CONNECTION = Union[ConnectionState, OAuth2Client]
 
-    @property
-    def staff(self):
-        return self._has_flag(UserFlags.staff)
 
-    @property
-    def partner(self):
-        return self._has_flag(UserFlags.partner)
+MISSING = utils.MISSING
 
-    @property
-    def bug_hunter(self):
-        return self._has_flag(UserFlags.bug_hunter)
-
-    @property
-    def early_supporter(self):
-        return self._has_flag(UserFlags.early_supporter)
 
-    @property
-    def hypesquad(self):
-        return self._has_flag(UserFlags.hypesquad)
-
-    @property
-    def hypesquad_houses(self):
-        flags = (UserFlags.hypesquad_bravery, UserFlags.hypesquad_brilliance, UserFlags.hypesquad_balance)
-        return [house for house, flag in zip(HypeSquadHouse, flags) if self._has_flag(flag)]
-
-    @property
-    def team_user(self):
-        return self._has_flag(UserFlags.team_user)
-
-    @property
-    def system(self):
-        return self._has_flag(UserFlags.system)
+class _BaseUser:
+    __slots__ = ()
+    id: int
 
-_BaseUser = discord.abc.User
 
 class BaseUser(_BaseUser):
-    __slots__ = ('name', 'id', 'discriminator', 'avatar', 'bot', 'system', '_public_flags', '_state')
-
-    def __init__(self, *, state, data):
-        self._state = state
+    __slots__ = (
+        'username', 'id', 'global_name', 'discriminator', 'avatar', 'banner', 'avatar_decoration',
+        'bot', 'system', '_accent_color', '_public_flags', '_state'
+    )
+    
+    if TYPE_CHECKING:
+        username: str
+        id: int
+        discriminator: str
+        global_name: str | None
+        bot: bool
+        system: bool
+        _state: HAS_HTTP_CONNECTION
+        avatar: str | None
+        avatar_decoration: str | None
+        banner: str | None
+        _accent_color: int | None
+        _public_flags: int
+
+    def __init__(self, *, state: HAS_HTTP_CONNECTION, data: UserData) -> None:
+        self._state: HAS_HTTP_CONNECTION = state
         self._update(data)
 
-    def __str__(self):
-        return '{0.name}#{0.discriminator}'.format(self)
-
-    def __eq__(self, other):
+    def __str__(self) -> str:
+        return f'{self.username}' if self.is_migrated else f'{self.name}#{self.discriminator}'
+    
+    def __eq__(self, other: Any) -> bool:
         return isinstance(other, _BaseUser) and other.id == self.id
 
-    def __ne__(self, other):
+    def __ne__(self, other: Any) -> bool:
         return not self.__eq__(other)
 
-    def __hash__(self):
+    def __hash__(self) -> int:
         return self.id >> 22
 
-    def _update(self, data):
-        self.name = data['username']
+    def _update(self, data: UserData) -> None:
         self.id = int(data['id'])
-        self.discriminator = data['discriminator']
+        self.username = data['username']
+        self.global_name = data.get('global_name', None)
+        self.discriminator: str = data.get('discriminator', '0')  # Deprecated
         self.avatar = data['avatar']
+        self.banner = data.get('banner', None)
+        avatar_decoration_data = data.get('avatar_decoration_data') or {}
+        self.avatar_decoration = avatar_decoration_data.get('asset')
+        self._accent_color = data.get('accent_color', None)
         self._public_flags = data.get('public_flags', 0)
         self.bot = data.get('bot', False)
         self.system = data.get('system', False)
 
     @classmethod
-    def _copy(cls, user):
-        self = cls.__new__(cls) # bypass __init__
-
-        self.name = user.name
+    def _copy(cls: Type[User], user: User) -> User:
+        self = cls.__new__(cls)  # bypass __init__
         self.id = user.id
+        self.username = user.username
+        self.global_name = user.global_name
         self.discriminator = user.discriminator
         self.avatar = user.avatar
+        self.banner = user.banner
+        self._accent_color = user._accent_color
         self.bot = user.bot
         self._state = user._state
         self._public_flags = user._public_flags
 
         return self
 
-    def _to_minimal_user_json(self):
+    def _to_minimal_user_json(self) -> Dict[str, Any]:
         return {
-            'username': self.name,
+            'username': self.username,
+            'global_name': self.global_name,
             'id': self.id,
             'avatar': self.avatar,
+            'banner': self.banner,
+            'avatar_decoration': self.avatar_decoration,
+            'accent_color': self._accent_color,
             'discriminator': self.discriminator,
             'bot': self.bot,
         }
+    
+    @property
+    def name(self) -> str:
+        """:class:`str`: This is an alias of :attr:`username` which replaces the previous `name` attribute.
 
+        .. versionadded: 2.0
+
+        .. note::
+            It is recommended to use :attr:`username` instead as this might be removed in the future.
+        """
+        return self.username
+    
+    @property
+    def is_migrated(self) -> bool:
+        """:class:`bool`: Indicates if the user has migrated to the :dis-gd:`new username system <usernames>`."""
+        return self.discriminator == '0'
+    
     @property
-    def public_flags(self):
+    def public_flags(self) -> PublicUserFlags:
         """:class:`PublicUserFlags`: The publicly available flags the user has."""
         return PublicUserFlags._from_value(self._public_flags)
+    
+    @property
+    def accent_color(self) -> Optional[Colour]:
+        """Optional[:class:`Colour`]: A colour object that represents the user's banner colour.
+        
+        .. note::
 
+            This information is only available via :meth:`Client.fetch_user`.
+        """
+        return Colour(self._accent_color)
+    
+    @property
+    def accent_colour(self) -> Optional[Colour]:
+        """Optional[:class:`Colour`]: An alias for :attr:`accent_color`."""
+        return self.accent_color
+    
+    banner_color = accent_color
+    banner_colour = accent_color
+    
+    @property
+    def hex_banner_color(self) -> Optional[str]:
+        """Optional[:class:`str`]: Returns a hexadecimal representation of the user's banner colour, if available."""
+        if self._accent_color:
+            return f'#{self._accent_color:0>6x}'
+        
     @property
-    def avatar_url(self):
+    def avatar_url(self) -> Asset:
         """:class:`Asset`: Returns an :class:`Asset` for the avatar the user has.
 
         If the user does not have a traditional avatar, an asset for
@@ -151,11 +205,16 @@ def avatar_url(self):
         """
         return self.avatar_url_as(format=None, size=1024)
 
-    def is_avatar_animated(self):
+    def is_avatar_animated(self) -> bool:
         """:class:`bool`: Indicates if the user has an animated avatar."""
         return bool(self.avatar and self.avatar.startswith('a_'))
 
-    def avatar_url_as(self, *, format=None, static_format='webp', size=1024):
+    def avatar_url_as(
+            self, *,
+            format: Optional[Literal['png', 'jpg', 'jpeg', 'webp', 'gif']] = None,
+            static_format: Literal['png', 'jpg', 'jpeg', 'webp'] = 'webp',
+            size=1024
+    ) -> Asset:
         """Returns an :class:`Asset` for the avatar the user has.
 
         If the user does not have a traditional avatar, an asset for
@@ -192,17 +251,120 @@ def avatar_url_as(self, *, format=None, static_format='webp', size=1024):
         return Asset._from_avatar(self._state, self, format=format, static_format=static_format, size=size)
 
     @property
-    def default_avatar(self):
-        """:class:`DefaultAvatar`: Returns the default avatar for a given user. This is calculated by the user's discriminator."""
-        return try_enum(DefaultAvatar, int(self.discriminator) % len(DefaultAvatar))
+    def default_avatar(self) -> DefaultAvatar:
+        """:class:`DefaultAvatar`: Returns the default avatar for a given user.
+        For non-migrated users this is calculated by the user's discriminator.
+        For :dis-gd:`migrated <usernames>` users this is calculated by the user's ID.
+        """
+        if self.is_migrated:
+            value = (self.id >> 22) % len(DefaultAvatar)
+        else:
+            value = int(self.discriminator) % 5
+        return try_enum(DefaultAvatar, value)
 
     @property
-    def default_avatar_url(self):
+    def default_avatar_url(self) -> Asset:
         """:class:`Asset`: Returns a URL for a user's default avatar."""
-        return Asset(self._state, '/embed/avatars/{}.png'.format(self.default_avatar.value))
+        return Asset(self._state, f'/embed/avatars/{self.default_avatar.value}.png')
+
+    @property
+    def display_avatar(self) -> Asset:
+        """:class:`Asset`: Returns the users display avatar.
+
+        For regular users this is equal to :attr:`avatar_url`.
+        """
+        return self.avatar_url_as(format=None, size=1024)
+
+    @property
+    def banner_url(self) -> Optional[Asset]:
+        """
+        Optional[:class:`Asset`]: Returns an asset for the banner the user has, if any.
+        This is equal to calling :meth:`banner_url_as` with the default arguments.
+
+        Returns
+        --------
+        Optional[:class:`Asset`]
+            The resulting CDN asset if any.
+        """
+        return self.banner_url_as()
+
+    def is_banner_animated(self) -> bool:
+        """:class:`bool`: Indicates if the user has an animated banner."""
+        return bool(self.banner and self.banner.startswith('a_'))
+
+    def banner_url_as(
+            self,
+            *,
+            format: Optional[Literal['png', 'jpg', 'jpeg', 'webp', 'gif']] = None,
+            static_format: Literal['png', 'jpg', 'jpeg', 'webp'] = 'webp',
+            size: int = 1024
+    ) -> Optional[Asset]:
+        """Returns an :class:`Asset` for the banner the user has. Could be ``None``.
+
+        The format must be one of 'webp', 'jpeg', 'jpg', 'png' or 'gif', and
+        'gif' is only valid for animated banners. The size must be a power of 2
+        between 16 and 4096.
+
+        Parameters
+        -----------
+        format: Optional[:class:`str`]
+            The format to attempt to convert the banner to.
+            If the format is ``None``, then it is automatically
+            detected into either 'gif' or static_format depending on the
+            banner being animated or not.
+        static_format: Optional[:class:`str`]
+            Format to attempt to convert only non-animated banner to.
+            Defaults to 'webp'
+        size: :class:`int`
+            The size of the image to display.
+
+        Raises
+        ------
+        InvalidArgument
+            Bad image format passed to ``format`` or ``static_format``, or
+            invalid ``size``.
+
+        Returns
+        --------
+        Optional[:class:`Asset`]
+            The resulting CDN asset if any.
+        """
+        return Asset._from_banner(self._state, self, format=format, static_format=static_format, size=size)
+
+    def avatar_decoration_url_as(
+            self,
+            *,
+            format: Optional[Literal['png', 'jpg', 'jpeg', 'webp']] = None,
+            size: int = 1024
+    ) -> Optional[Asset]:
+        """Returns an :class:`Asset` for the avatar decoration the user has. Could be ``None``.
+
+        The format must be one of 'webp', 'jpeg', 'jpg', or 'png'.
+        The size must be a power of 2 between 16 and 4096.
+
+        Parameters
+        -----------
+        format: Optional[:class:`str`]
+            The format to attempt to convert the avatar decoration to.
+            If the format is ``None``, then it is automatically
+            detected into static_format.
+        size: :class:`int`
+            The size of the image to display.
+
+        Raises
+        ------
+        InvalidArgument
+            Bad image format passed to ``format``, or invalid ``size``.
+
+        Returns
+        --------
+        Optional[:class:`Asset`]
+            The resulting CDN asset if any.
+        """
+        return Asset._from_avatar_decoration(self._state, self, format=format, size=size)
 
     @property
-    def colour(self):
+    def colour(self) -> Colour:
         """:class:`Colour`: A property that returns a colour denoting the rendered colour
         for the user. This always returns :meth:`Colour.default`.
 
@@ -211,7 +373,7 @@ def colour(self):
         return Colour.default()
 
     @property
-    def color(self):
+    def color(self) -> Colour:
         """:class:`Colour`: A property that returns a color denoting the rendered color
         for the user. This always returns :meth:`Colour.default`.
 
@@ -220,11 +382,11 @@ def color(self):
         return self.colour
 
     @property
-    def mention(self):
+    def mention(self) -> str:
         """:class:`str`: Returns a string that allows you to mention the given user."""
-        return '<@{0.id}>'.format(self)
+        return f'<@{self.id}>'
 
-    def permissions_in(self, channel):
+    def permissions_in(self, channel: Union[GuildChannel, ThreadChannel]) -> Permissions:
         """An alias for :meth:`abc.GuildChannel.permissions_for`.
 
         Basically equivalent to:
@@ -241,23 +403,23 @@ def permissions_in(self, channel):
         return channel.permissions_for(self)
 
     @property
-    def created_at(self):
+    def created_at(self) -> datetime.datetime:
         """:class:`datetime.datetime`: Returns the user's creation time in UTC.
 
         This is when the user's Discord account was created."""
         return snowflake_time(self.id)
 
     @property
-    def display_name(self):
+    def display_name(self) -> str:
         """:class:`str`: Returns the user's display name.
 
-        For regular users this is just their username, but
+        For regular users this is just their :attr:`global_name` if set else their :attr:`username`, but
         if they have a guild specific nickname then that
         is returned instead.
         """
-        return self.name
+        return self.global_name or self.username
 
-    def mentioned_in(self, message):
+    def mentioned_in(self, message: Message) -> bool:
         """Checks if the user is mentioned in the specified message.
 
         Parameters
@@ -276,9 +438,14 @@ def mentioned_in(self, message):
 
         return any(user.id == self.id for user in message.mentions)
 
+
 class ClientUser(BaseUser):
     """Represents your Discord user.
 
+    .. versionchanged:: 2.0
+        The :attr:`name` attribute was renamed to :attr:`username` due to the (upcoming)
+        :dis-gd:`username changes <username>`.
+
     .. container:: operations
 
         .. describe:: x == y
@@ -295,12 +462,21 @@ class ClientUser(BaseUser):
 
         .. describe:: str(x)
 
-            Returns the user's name with discriminator.
+            Returns the :attr:`username` if :attr:`is_migrated` is true, else the user's name with discriminator.
+
+            .. note::
+
+                When the migration is complete, this will always return the :attr:`username` .
 
     Attributes
     -----------
-    name: :class:`str`
+    username: :class:`str`
         The user's username.
+    global_name: Optional[:class:`str`]
+        The user's global name if set.
+        In the client UI, this is referred to as "Display Name".
+
+        .. versionadded:: 2.0
     id: :class:`int`
         The user's unique ID.
     discriminator: :class:`str`
@@ -311,123 +487,40 @@ class ClientUser(BaseUser):
         Specifies if the user is a bot account.
     system: :class:`bool`
         Specifies if the user is a system user (i.e. represents Discord officially).
-
-        .. versionadded:: 1.3
-
-    verified: :class:`bool`
-        Specifies if the user's email is verified.
-    email: Optional[:class:`str`]
-        The email the user used when registering.
-
-        .. deprecated:: 1.7
-
     locale: Optional[:class:`str`]
         The IETF language tag used to identify the language the user is using.
     mfa_enabled: :class:`bool`
         Specifies if the user has MFA turned on and working.
-    premium: :class:`bool`
-        Specifies if the user is a premium user (e.g. has Discord Nitro).
-
-        .. deprecated:: 1.7
-
-    premium_type: Optional[:class:`PremiumType`]
-        Specifies the type of premium a user has (e.g. Nitro or Nitro Classic). Could be None if the user is not premium.
-
-        .. deprecated:: 1.7
     """
     __slots__ = BaseUser.__slots__ + \
-                ('email', 'locale', '_flags', 'verified', 'mfa_enabled',
-                 'premium', 'premium_type', '_relationships', '__weakref__')
+                ('locale', '_flags', 'verified', 'mfa_enabled', '__weakref__')
 
-    def __init__(self, *, state, data):
+    def __init__(self, *, state: ConnectionState, data: ClientUserData) -> None:
         super().__init__(state=state, data=data)
-        self._relationships = {}
 
-    def __repr__(self):
-        return '<ClientUser id={0.id} name={0.name!r} discriminator={0.discriminator!r}' \
-               ' bot={0.bot} verified={0.verified} mfa_enabled={0.mfa_enabled}>'.format(self)
+    def __repr__(self) -> str:
+        if not self.is_migrated:
+            return f'<ClientUser id={self.id} username={self.name!r} discriminator={self.discriminator!r} ' \
+                   f'global_name={self.global_name} bot={self.bot} mfa_enabled={self.mfa_enabled}>'
+        return f'<ClientUser id={self.id} username={self.name!r} global_name={self.global_name!r}' \
+               f' bot={self.bot} mfa_enabled={self.mfa_enabled}>'
 
-    def _update(self, data):
+    def _update(self, data: ClientUserData) -> None:
         super()._update(data)
-        # There's actually an Optional[str] phone field as well but I won't use it
-        self.verified = data.get('verified', False)
-        self.email = data.get('email')
         self.locale = data.get('locale')
         self._flags = data.get('flags', 0)
         self.mfa_enabled = data.get('mfa_enabled', False)
-        self.premium = data.get('premium', False)
-        self.premium_type = try_enum(PremiumType, data.get('premium_type', None))
-
-    @deprecated()
-    def get_relationship(self, user_id):
-        """Retrieves the :class:`Relationship` if applicable.
-
-        .. deprecated:: 1.7
-
-        .. note::
-
-            This can only be used by non-bot accounts.
-
-        Parameters
-        -----------
-        user_id: :class:`int`
-            The user ID to check if we have a relationship with them.
-
-        Returns
-        --------
-        Optional[:class:`Relationship`]
-            The relationship if available or ``None``.
-        """
-        return self._relationships.get(user_id)
 
-    @property
-    def relationships(self):
-        """List[:class:`User`]: Returns all the relationships that the user has.
-
-        .. deprecated:: 1.7
-
-        .. note::
-
-            This can only be used by non-bot accounts.
-        """
-        return list(self._relationships.values())
-
-    @property
-    def friends(self):
-        r"""List[:class:`User`]: Returns all the users that the user is friends with.
-
-        .. deprecated:: 1.7
-
-        .. note::
-
-            This can only be used by non-bot accounts.
-        """
-        return [r.user for r in self._relationships.values() if r.type is RelationshipType.friend]
-
-    @property
-    def blocked(self):
-        r"""List[:class:`User`]: Returns all the users that the user has blocked.
-
-        .. deprecated:: 1.7
-
-        .. note::
-
-            This can only be used by non-bot accounts.
-        """
-        return [r.user for r in self._relationships.values() if r.type is RelationshipType.blocked]
-
-    async def edit(self, **fields):
+    async def edit(
+            self,
+            username: str = MISSING,
+            global_name: str = MISSING,
+            avatar: bytes = MISSING
+    ) -> None:
         """|coro|
 
         Edits the current profile of the client.
 
-        If a bot account is used then a password field is optional,
-        otherwise it is required.
-
-        .. warning::
-
-            The user account-only fields are deprecated.
-
         .. note::
 
             To upload an avatar, a :term:`py:bytes-like object` must be passed in that
@@ -439,21 +532,10 @@ async def edit(self, **fields):
 
         Parameters
         -----------
-        password: :class:`str`
-            The current password for the client's account.
-            Only applicable to user accounts.
-        new_password: :class:`str`
-            The new password you wish to change to.
-            Only applicable to user accounts.
-        email: :class:`str`
-            The new email you wish to change to.
-            Only applicable to user accounts.
-        house: Optional[:class:`HypeSquadHouse`]
-            The hypesquad house you wish to change to.
-            Could be ``None`` to leave the current house.
-            Only applicable to user accounts.
         username: :class:`str`
             The new username you wish to change to.
+        global_name: :class:`str`
+            The new global name you wish to change to.
         avatar: :class:`bytes`
             A :term:`py:bytes-like object` representing the image to upload.
             Could be ``None`` to denote no avatar.
@@ -464,221 +546,30 @@ async def edit(self, **fields):
             Editing your profile failed.
         InvalidArgument
             Wrong image format passed for ``avatar``.
-        ClientException
-            Password is required for non-bot accounts.
-            House field was not a HypeSquadHouse.
-        """
-
-        try:
-            avatar_bytes = fields['avatar']
-        except KeyError:
-            avatar = self.avatar
-        else:
-            if avatar_bytes is not None:
-                avatar = _bytes_to_base64_data(avatar_bytes)
-            else:
-                avatar = None
-
-        not_bot_account = not self.bot
-        password = fields.get('password')
-        if not_bot_account and password is None:
-            raise ClientException('Password is required for non-bot accounts.')
-
-        args = {
-            'password': password,
-            'username': fields.get('username', self.name),
-            'avatar': avatar
-        }
-
-        if not_bot_account:
-            args['email'] = fields.get('email', self.email)
-
-            if 'new_password' in fields:
-                args['new_password'] = fields['new_password']
-
-        http = self._state.http
-
-        if 'house' in fields:
-            house = fields['house']
-            if house is None:
-                await http.leave_hypesquad_house()
-            elif not isinstance(house, HypeSquadHouse):
-                raise ClientException('`house` parameter was not a HypeSquadHouse')
-            else:
-                value = house.value
-
-            await http.change_hypesquad_house(value)
-
-        data = await http.edit_profile(**args)
-        if not_bot_account:
-            self.email = data['email']
-            try:
-                http._token(data['token'], bot=False)
-            except KeyError:
-                pass
-
-        self._update(data)
-
-    @deprecated()
-    async def create_group(self, *recipients):
-        r"""|coro|
-
-        Creates a group direct message with the recipients
-        provided. These recipients must be have a relationship
-        of type :attr:`RelationshipType.friend`.
-
-        .. deprecated:: 1.7
-
-        .. note::
-
-            This can only be used by non-bot accounts.
-
-        Parameters
-        -----------
-        \*recipients: :class:`User`
-            An argument :class:`list` of :class:`User` to have in
-            your group.
-
-        Raises
-        -------
-        HTTPException
-            Failed to create the group direct message.
-        ClientException
-            Attempted to create a group with only one recipient.
-            This does not include yourself.
-
-        Returns
-        -------
-        :class:`GroupChannel`
-            The new group channel.
         """
 
-        from .channel import GroupChannel
-
-        if len(recipients) < 2:
-            raise ClientException('You must have two or more recipients to create a group.')
-
-        users = [str(u.id) for u in recipients]
-        data = await self._state.http.start_group(self.id, users)
-        return GroupChannel(me=self, data=data, state=self._state)
-
-    @deprecated()
-    async def edit_settings(self, **kwargs):
-        """|coro|
-
-        Edits the client user's settings.
-
-        .. deprecated:: 1.7
-
-        .. note::
-
-            This can only be used by non-bot accounts.
-
-        Parameters
-        -------
-        afk_timeout: :class:`int`
-            How long (in seconds) the user needs to be AFK until Discord
-            sends push notifications to your mobile device.
-        animate_emojis: :class:`bool`
-            Whether or not to animate emojis in the chat.
-        convert_emoticons: :class:`bool`
-            Whether or not to automatically convert emoticons into emojis.
-            e.g. :-) -> 😃
-        default_guilds_restricted: :class:`bool`
-            Whether or not to automatically disable DMs between you and
-            members of new guilds you join.
-        detect_platform_accounts: :class:`bool`
-            Whether or not to automatically detect accounts from services
-            like Steam and Blizzard when you open the Discord client.
-        developer_mode: :class:`bool`
-            Whether or not to enable developer mode.
-        disable_games_tab: :class:`bool`
-            Whether or not to disable the showing of the Games tab.
-        enable_tts_command: :class:`bool`
-            Whether or not to allow tts messages to be played/sent.
-        explicit_content_filter: :class:`UserContentFilter`
-            The filter for explicit content in all messages.
-        friend_source_flags: :class:`FriendFlags`
-            Who can add you as a friend.
-        gif_auto_play: :class:`bool`
-            Whether or not to automatically play gifs that are in the chat.
-        guild_positions: List[:class:`abc.Snowflake`]
-            A list of guilds in order of the guild/guild icons that are on
-            the left hand side of the UI.
-        inline_attachment_media: :class:`bool`
-            Whether or not to display attachments when they are uploaded in chat.
-        inline_embed_media: :class:`bool`
-            Whether or not to display videos and images from links posted in chat.
-        locale: :class:`str`
-            The :rfc:`3066` language identifier of the locale to use for the language
-            of the Discord client.
-        message_display_compact: :class:`bool`
-            Whether or not to use the compact Discord display mode.
-        render_embeds: :class:`bool`
-            Whether or not to render embeds that are sent in the chat.
-        render_reactions: :class:`bool`
-            Whether or not to render reactions that are added to messages.
-        restricted_guilds: List[:class:`abc.Snowflake`]
-            A list of guilds that you will not receive DMs from.
-        show_current_game: :class:`bool`
-            Whether or not to display the game that you are currently playing.
-        status: :class:`Status`
-            The clients status that is shown to others.
-        theme: :class:`Theme`
-            The theme of the Discord UI.
-        timezone_offset: :class:`int`
-            The timezone offset to use.
-
-        Raises
-        -------
-        HTTPException
-            Editing the settings failed.
-        Forbidden
-            The client is a bot user and not a user account.
-
-        Returns
-        -------
-        :class:`dict`
-            The client user's updated settings.
-        """
         payload = {}
 
-        content_filter = kwargs.pop('explicit_content_filter', None)
-        if content_filter:
-            payload.update({'explicit_content_filter': content_filter.value})
-
-        friend_flags = kwargs.pop('friend_source_flags', None)
-        if friend_flags:
-            dicts = [{}, {'mutual_guilds': True}, {'mutual_friends': True},
-            {'mutual_guilds': True, 'mutual_friends': True}, {'all': True}]
-            payload.update({'friend_source_flags': dicts[friend_flags.value]})
-
-        guild_positions = kwargs.pop('guild_positions', None)
-        if guild_positions:
-            guild_positions = [str(x.id) for x in guild_positions]
-            payload.update({'guild_positions': guild_positions})
+        if username is not MISSING:
+            payload['username'] = username
 
-        restricted_guilds = kwargs.pop('restricted_guilds', None)
-        if restricted_guilds:
-            restricted_guilds = [str(x.id) for x in restricted_guilds]
-            payload.update({'restricted_guilds': restricted_guilds})
+        if global_name is not MISSING:
+            payload['global_name'] = global_name
 
-        status = kwargs.pop('status', None)
-        if status:
-            payload.update({'status': status.value})
+        if avatar is not MISSING:
+            payload['avatar'] = None if avatar is None else _bytes_to_base64_data(avatar)
 
-        theme = kwargs.pop('theme', None)
-        if theme:
-            payload.update({'theme': theme.value})
-
-        payload.update(kwargs)
+        data = await self._state.http.edit_profile(payload)
+        self._update(data)
 
-        data = await self._state.http.edit_settings(**payload)
-        return data
 
-class User(BaseUser, discord.abc.Messageable):
+class User(BaseUser, abc.Messageable):
     """Represents a Discord user.
 
+    .. versionchanged:: 2.0
+        The :attr:`name` attribute was renamed to :attr:`username` due to the (upcoming)
+        :dis-gd:`username changes <username>`.
+
     .. container:: operations
 
         .. describe:: x == y
@@ -695,18 +586,44 @@ class User(BaseUser, discord.abc.Messageable):
 
         .. describe:: str(x)
 
-            Returns the user's name with discriminator.
+            Returns the :attr:`username` if :attr:`is_migrated` is true, else the user's name with discriminator.
+            
+            .. note::
+                When the migration is complete, this will always return the :attr:`username`.
 
     Attributes
     -----------
-    name: :class:`str`
+    username: :class:`str`
         The user's username.
+    global_name: Optional[:class:`str`]
+        The user's global name if set.
+        In the client UI, this is referred to as "Display Name".
+
+        .. versionadded:: 2.0
     id: :class:`int`
         The user's unique ID.
     discriminator: :class:`str`
-        The user's discriminator. This is given when the username has conflicts.
+        The user's discriminator.
+
+        .. deprecated:: 2.0
+
+        .. important::
+            This will be removed in the future.
+            Read more about it :dis-gd:`here <usernames>`.
     avatar: Optional[:class:`str`]
         The avatar hash the user has. Could be None.
+    banner: Optional[:class:`str`]
+        The banner hash the user has. Could be None.
+        
+        .. note::
+        
+            This is only available via :meth:`Client.fetch_user`.
+
+        .. versionadded:: 2.0
+    avatar_decoration: Optional[:class:`str`]
+        The avatar decoration hash the user has. Could be None.
+
+        .. versionadded:: 2.0
     bot: :class:`bool`
         Specifies if the user is a bot account.
     system: :class:`bool`
@@ -715,15 +632,17 @@ class User(BaseUser, discord.abc.Messageable):
 
     __slots__ = BaseUser.__slots__ + ('__weakref__',)
 
-    def __repr__(self):
-        return '<User id={0.id} name={0.name!r} discriminator={0.discriminator!r} bot={0.bot}>'.format(self)
+    def __repr__(self) -> str:
+        if not self.is_migrated:
+            return f'<User id={self.id} username={self.name!r} global_name={self.global_name!r} ' \
+                   f'discriminator={self.discriminator!r} bot={self.bot}>'
+        return f'<User id={self.id} username={self.name!r} global_name={self.global_name!r} bot={self.bot}>'
 
-    async def _get_channel(self):
-        ch = await self.create_dm()
-        return ch
+    async def _get_channel(self) -> DMChannel:
+        return await self.create_dm()
 
     @property
-    def dm_channel(self):
+    def dm_channel(self) -> Optional[DMChannel]:
         """Optional[:class:`DMChannel`]: Returns the channel associated with this user if it exists.
 
         If this returns ``None``, you can create a DM channel by calling the
@@ -732,7 +651,7 @@ def dm_channel(self):
         return self._state._get_private_channel_by_user(self.id)
 
     @property
-    def mutual_guilds(self):
+    def mutual_guilds(self) -> List[Guild]:
         """List[:class:`Guild`]: The guilds that the user shares with the client.
 
         .. note::
@@ -743,7 +662,7 @@ def mutual_guilds(self):
         """
         return [guild for guild in self._state._guilds.values() if guild.get_member(self.id)]
 
-    async def create_dm(self):
+    async def create_dm(self) -> DMChannel:
         """|coro|
 
         Creates a :class:`DMChannel` with this user.
@@ -763,197 +682,3 @@ async def create_dm(self):
         state = self._state
         data = await state.http.start_private_message(self.id)
         return state.add_dm_channel(data)
-
-    @property
-    def relationship(self):
-        """Optional[:class:`Relationship`]: Returns the :class:`Relationship` with this user if applicable, ``None`` otherwise.
-
-        .. deprecated:: 1.7
-
-        .. note::
-
-            This can only be used by non-bot accounts.
-        """
-        return self._state.user.get_relationship(self.id)
-
-    @deprecated()
-    async def mutual_friends(self):
-        """|coro|
-
-        Gets all mutual friends of this user.
-
-        .. deprecated:: 1.7
-
-        .. note::
-
-            This can only be used by non-bot accounts.
-
-        Raises
-        -------
-        Forbidden
-            Not allowed to get mutual friends of this user.
-        HTTPException
-            Getting mutual friends failed.
-
-        Returns
-        -------
-        List[:class:`User`]
-            The users that are mutual friends.
-        """
-        state = self._state
-        mutuals = await state.http.get_mutual_friends(self.id)
-        return [User(state=state, data=friend) for friend in mutuals]
-
-    @deprecated()
-    def is_friend(self):
-        """:class:`bool`: Checks if the user is your friend.
-
-        .. deprecated:: 1.7
-
-        .. note::
-
-            This can only be used by non-bot accounts.
-        """
-        r = self.relationship
-        if r is None:
-            return False
-        return r.type is RelationshipType.friend
-
-    @deprecated()
-    def is_blocked(self):
-        """:class:`bool`: Checks if the user is blocked.
-
-        .. deprecated:: 1.7
-
-        .. note::
-
-            This can only be used by non-bot accounts.
-        """
-        r = self.relationship
-        if r is None:
-            return False
-        return r.type is RelationshipType.blocked
-
-    @deprecated()
-    async def block(self):
-        """|coro|
-
-        Blocks the user.
-
-        .. deprecated:: 1.7
-
-        .. note::
-
-            This can only be used by non-bot accounts.
-
-        Raises
-        -------
-        Forbidden
-            Not allowed to block this user.
-        HTTPException
-            Blocking the user failed.
-        """
-
-        await self._state.http.add_relationship(self.id, type=RelationshipType.blocked.value)
-
-    @deprecated()
-    async def unblock(self):
-        """|coro|
-
-        Unblocks the user.
-
-        .. deprecated:: 1.7
-
-        .. note::
-
-            This can only be used by non-bot accounts.
-
-        Raises
-        -------
-        Forbidden
-            Not allowed to unblock this user.
-        HTTPException
-            Unblocking the user failed.
-        """
-        await self._state.http.remove_relationship(self.id)
-
-    @deprecated()
-    async def remove_friend(self):
-        """|coro|
-
-        Removes the user as a friend.
-
-        .. deprecated:: 1.7
-
-        .. note::
-
-            This can only be used by non-bot accounts.
-
-        Raises
-        -------
-        Forbidden
-            Not allowed to remove this user as a friend.
-        HTTPException
-            Removing the user as a friend failed.
-        """
-        await self._state.http.remove_relationship(self.id)
-
-    @deprecated()
-    async def send_friend_request(self):
-        """|coro|
-
-        Sends the user a friend request.
-
-        .. deprecated:: 1.7
-
-        .. note::
-
-            This can only be used by non-bot accounts.
-
-        Raises
-        -------
-        Forbidden
-            Not allowed to send a friend request to the user.
-        HTTPException
-            Sending the friend request failed.
-        """
-        await self._state.http.send_friend_request(username=self.name, discriminator=self.discriminator)
-
-    @deprecated()
-    async def profile(self):
-        """|coro|
-
-        Gets the user's profile.
-
-        .. deprecated:: 1.7
-
-        .. note::
-
-            This can only be used by non-bot accounts.
-
-        Raises
-        -------
-        Forbidden
-            Not allowed to fetch profiles.
-        HTTPException
-            Fetching the profile failed.
-
-        Returns
-        --------
-        :class:`Profile`
-            The profile of the user.
-        """
-
-        state = self._state
-        data = await state.http.get_user_profile(self.id)
-
-        def transform(d):
-            return state._get_guild(int(d['id']))
-
-        since = data.get('premium_since')
-        mutual_guilds = list(filter(None, map(transform, data.get('mutual_guilds', []))))
-        return Profile(flags=data['user'].get('flags', 0),
-                       premium_since=parse_time(since),
-                       mutual_guilds=mutual_guilds,
-                       user=self,
-                       connected_accounts=data['connected_accounts'])
diff --git a/discord/utils.py b/discord/utils.py
index f1f22cd3..f3808906 100644
--- a/discord/utils.py
+++ b/discord/utils.py
@@ -3,7 +3,7 @@
 """
 The MIT License (MIT)
 
-Copyright (c) 2015-present Rapptz
+Copyright (c) 2015-2021 Rapptz & (c) 2021.present mccoderpy
 
 Permission is hereby granted, free of charge, to any person obtaining a
 copy of this software and associated documentation files (the "Software"),
@@ -23,35 +23,66 @@
 FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 DEALINGS IN THE SOFTWARE.
 """
-
+from __future__ import annotations
+
+from typing import (
+    Any,
+    Set,
+    Dict,
+    Generic,
+    List,
+    Union,
+    Type,
+    Tuple,
+    Awaitable,
+    Coroutine,
+    Sequence,
+    Optional,
+    Iterable,
+    Callable,
+    TypeVar,
+    Protocol,
+    overload,
+    TYPE_CHECKING,
+    runtime_checkable, Generic,
+)
+
+import os
+import re
+import sys
+import json
 import array
 import asyncio
+import logging
+
+import aiohttp
+import colorama
+import warnings
+import datetime
+import functools
+
 import collections.abc
 import unicodedata
 from base64 import b64encode
 from bisect import bisect_left
-import datetime
-import typing
-from .enums import TimestampStyle
-import functools
+from abc import abstractmethod
+
 from inspect import isawaitable as _isawaitable, signature as _signature
 from operator import attrgetter
-import json
-import re
-import warnings
 
 from .errors import InvalidArgument
+from .enums import TimestampStyle, InviteTargetType
 
 DISCORD_EPOCH = 1420070400000
 MAX_ASYNCIO_SECONDS = 3456000
 
 
-class cached_property:
-    def __init__(self, function):
-        self.function = function
+class _cached_property:
+    def __init__(self, function: Callable[..., T]) -> None:
+        self.function: Callable[..., T] = function
         self.__doc__ = getattr(function, '__doc__')
 
-    def __get__(self, instance, owner):
+    def __get__(self, instance: Any, owner: Type[Any]) -> T:
         if instance is None:
             return self
 
@@ -60,14 +91,149 @@ def __get__(self, instance, owner):
 
         return value
 
+    def __class_getitem__(cls, key: T) -> T:
+        return cls
+
+
+if TYPE_CHECKING:
+    from typing_extensions import ParamSpec, TypeGuard, Self
+    from functools import cached_property as cached_property
+    from .guild import Guild
+    from .channel import VoiceChannel
+    from .permissions import Permissions
+    from .invite import Invite
+    from .template import Template
+
+    P = ParamSpec('P')
+
+    MaybeAwaitableFunc = Callable[P, 'MaybeAwaitable[T]']  # We need to use it as a string here because it's not defined yet
+
+else:
+    cached_property = _cached_property
+
+T = TypeVar('T')
+T_co = TypeVar('T_co', covariant=True)
+R = TypeVar('R')
+_IT = TypeVar(
+    '_IT',
+    Type[list],
+    Type[tuple],
+    Type[set],
+    Type[frozenset],
+    Type[bytes],
+    Type[bytearray],
+    Type[str]
+)
+_IT2 = TypeVar(
+    '_IT2',
+    Type[list],
+    Type[tuple],
+    Type[set],
+    Type[frozenset],
+    Type[bytes],
+    Type[bytearray],
+    Type[str]
+)
+_Iterable = TypeVar('_Iterable', bound=Iterable)
+MaybeAwaitable = Union[Awaitable[T], T]
+
+
+colorama.init()
+
+__all__ = (
+    'MISSING',
+    'SupportsStr',
+    'cached_property',
+    'cached_slot_property',
+    'SequenceProxy',
+    'SnowflakeList',
+    '_bytes_to_base64_data',
+    '_get_as_snowflake',
+    '_get_mime_type_for_image',
+    '_parse_ratelimit_header',
+    '_string_width',
+    '_unique',
+    'async_all',
+    'copy_doc',
+    'create_voice_activity',
+    'deprecated',
+    'deprecation_warning',
+    'escape_markdown',
+    'escape_mentions',
+    'find',
+    'get',
+    'maybe_coroutine',
+    'oauth_url',
+    'parse_time',
+    'remove_markdown',
+    'resolve_invite',
+    'resolve_template',
+    'sane_wait_for',
+    'sleep_until',
+    'setup_logging',
+    'snowflake_time',
+    'stream_supports_colour',
+    'styled_timestamp',
+    'time_snowflake',
+    'to_json',
+    'utcnow',
+    'valid_icon_size',
+)
+
+
+class _MISSING:
+    """
+    A placeholder object for missing attributes.
+    """
+    __slots__ = ()
+
+    def __repr__(self):
+        return 'MISSING'
+
+    def __bool__(self) -> bool:
+        return False
+
+    def __eq__(self, other) -> bool:
+        return False
+
+    def __hash__(self):
+        return 0
+
+
+MISSING = _MISSING()
+
+
+@runtime_checkable
+class _SupportsStr(Protocol):
+    """
+    An ABC with one abstract method ``__str__``.
+    This as an annotation means that this can be any object that has a :meth:`object.__str__` method
+    """
+    __slots__ = ()
+
+    @abstractmethod
+    def __str__(self) -> int:
+        pass
+
+
+SupportsStr = Union[str, _SupportsStr]
 
-class CachedSlotProperty:
-    def __init__(self, name, function):
+
+class CachedSlotProperty(Generic[T, T_co]):
+    def __init__(self, name: str, function: Callable[[T], T_co]) -> None:
         self.name = name
         self.function = function
         self.__doc__ = getattr(function, '__doc__')
 
-    def __get__(self, instance, owner):
+    @overload
+    def __get__(self, instance: None, owner: Type[T]) -> CachedSlotProperty[T, T_co]:
+        ...
+
+    @overload
+    def __get__(self, instance: T, owner: Type[T]) -> T_co:
+        ...
+
+    def __get__(self, instance: Optional[T], owner: Type[T]) -> Any:
         if instance is None:
             return self
 
@@ -79,8 +245,8 @@ def __get__(self, instance, owner):
             return value
 
 
-def cached_slot_property(name):
-    def decorator(func):
+def cached_slot_property(name: str) -> Callable[[Callable[[T], T_co]], CachedSlotProperty[T, T_co]]:
+    def decorator(func: Callable[[T], T_co]) -> CachedSlotProperty[T, T_co]:
         return CachedSlotProperty(name, func)
 
     return decorator
@@ -106,46 +272,54 @@ def __iter__(self):
     def __reversed__(self):
         return reversed(self.__proxied)
 
-    def index(self, value, *args, **kwargs):
+    def index(self, value: Any, *args, **kwargs):
         return self.__proxied.index(value, *args, **kwargs)
 
     def count(self, value):
         return self.__proxied.count(value)
 
 
-def parse_time(timestamp):
+def parse_time(timestamp: str) -> Optional[datetime.datetime]:
     if timestamp:
-
-        return datetime.datetime(*map(int, re.split(r'[^\d]', timestamp.replace('+00:00', ''))))
+        return datetime.datetime(*map(int, re.split(r'\D', timestamp.replace('+00:00', ''))))
     return None
 
 
-def copy_doc(original):
-    def decorator(overriden):
-        overriden.__doc__ = original.__doc__
+def copy_doc(original: Callable) -> Callable[[T], T]:
+    def decorator(overriden: T) -> T:
+        overriden.__doc__ = f'{overriden.__doc__}\n\n' if overriden.__doc__ else "" + original.__doc__
         overriden.__signature__ = _signature(original)
         return overriden
     return decorator
 
 
-def deprecated(instead=None):
-    def actual_decorator(func):
+def deprecated(instead: Optional[str] = None) -> Callable[[Callable[P, T]], Callable[P, T]]:
+    def actual_decorator(func: Callable[P, T]) -> Callable[P, T]:
         @functools.wraps(func)
-        def decorated(*args, **kwargs):
-            warnings.simplefilter('always', DeprecationWarning)  # turn off filter
-            if instead:
-                fmt = "{0.__name__} is deprecated, use {1} instead."
-            else:
-                fmt = '{0.__name__} is deprecated.'
-
-            warnings.warn(fmt.format(func, instead), stacklevel=3, category=DeprecationWarning)
-            warnings.simplefilter('default', DeprecationWarning)  # reset filter
+        def decorated(*args: P.args, **kwargs: P.kwargs) -> T:
+            deprecation_warning(func.__name__, instead)
             return func(*args, **kwargs)
         return decorated
     return actual_decorator
 
 
-def oauth_url(client_id, permissions=None, guild=None, redirect_uri=None, scopes=None):
+def deprecation_warning(target: str, instead: Optional[str] = None) -> None:
+    warnings.simplefilter('always', DeprecationWarning)  # turn off filter
+    if instead:
+        fmt = "{0} is deprecated, use {1} instead."
+    else:
+        fmt = '{0} is deprecated.'
+
+    warnings.warn(fmt.format(target, instead), stacklevel=3, category=DeprecationWarning)
+    warnings.simplefilter('default', DeprecationWarning)  # reset filter
+
+
+def oauth_url(
+        client_id: str,
+        permissions: Optional[Permissions] = None,
+        guild: Optional[Guild] = None,
+        redirect_uri: Optional[str] = None,
+        scopes: Iterable[str] = ('bot',)):
     """A helper function that returns the OAuth2 URL for inviting the bot
     into guilds.
 
@@ -182,7 +356,12 @@ def oauth_url(client_id, permissions=None, guild=None, redirect_uri=None, scopes
     return url
 
 
-def snowflake_time(id):
+def utcnow() -> datetime.datetime:
+    """:class:`datetime.datetime`: Returns a timezone aware :class:`datetime.datetime` object representing the current UTC time."""
+    return datetime.datetime.now(datetime.timezone.utc)
+
+
+def snowflake_time(id: int) -> datetime.datetime:
     """
     Parameters
     -----------
@@ -192,12 +371,14 @@ def snowflake_time(id):
     Returns
     --------
     :class:`datetime.datetime`
-        The creation date in UTC of a Discord snowflake ID."""
+        The creation date in UTC of a Discord snowflake ID.
+    """
     return datetime.datetime.utcfromtimestamp(((id >> 22) + DISCORD_EPOCH) / 1000)
 
 
-def time_snowflake(datetime_obj, high=False):
-    """Returns a numeric snowflake pretending to be created at the given date.
+def time_snowflake(datetime_obj: datetime.datetime, high: bool = False) -> int:
+    """
+    Returns a numeric snowflake pretending to be created at the given date.
 
     When using as the lower end of a range, use ``time_snowflake(high=False) - 1`` to be inclusive, ``high=True`` to be exclusive
     When using as the higher end of a range, use ``time_snowflake(high=True)`` + 1 to be inclusive, ``high=False`` to be exclusive
@@ -215,8 +396,9 @@ def time_snowflake(datetime_obj, high=False):
     return (discord_millis << 22) + (2**22-1 if high else 0)
 
 
-def find(predicate, seq):
-    """A helper to return the first element found in the sequence
+def find(predicate: Callable[[T], bool], seq: Iterable[T]) -> Optional[T]:
+    """
+    A helper to return the first element found in the sequence
     that meets the predicate. For example: ::
 
         member = discord.utils.find(lambda m: m.name == 'Mighty', channel.guild.members)
@@ -241,7 +423,7 @@ def find(predicate, seq):
     return None
 
 
-def get(iterable, **attrs):
+def get(iterable: Iterable[T], **attrs: Any) -> Optional[T]:
     r"""A helper that returns the first element in the iterable that meets
     all the traits passed in ``attrs``. This is an alternative for
     :func:`~discord.utils.find`.
@@ -310,21 +492,96 @@ def get(iterable, **attrs):
     return None
 
 
-def styled_timestamp(timestamp: typing.Union[datetime.datetime, int], style: typing.Union[TimestampStyle, str] = TimestampStyle.short):
-    unix_timestamp = int(timestamp.timestamp()) if isinstance(timestamp, datetime.datetime) else timestamp
+def styled_timestamp(
+        timestamp: Union[datetime.datetime, int],
+        style: Union[TimestampStyle, str] = TimestampStyle.short
+) -> str:
+    """
+    A small function that returns a styled timestamp for discord, this will be displayed accordingly in the Discord client depending on the :attr:`style` specified.
+
+    Timestamps will display the given timestamp in the user's timezone and locale.
+
+    Parameters
+    ----------
+    timestamp: Union[:class:`datetime.datetime`, :class:`int`]
+        The timestamp; A :class:`datetime.datetime` object or a unix timestamp as an :class:`int`.
+
+    style: Optional[Union[:class:`~discord.TimestampStyle`, :class:`str`]]
+        How the timestamp should be displayed in Discord; this can either be a :class:`~discord.TimestampStyle` or directly the associated value.
+
+        :default: :attr:`~discord.TimestampStyle.short`
+
+    Examples
+    --------
+    .. code-block:: python
+
+        # Normal timestamp
+        @client.command()
+        async def time(ctx):
+            await ctx.send(discord.utils.styled_timestamp(discord.utils.utcnow(), discord.TimestampStyle.long))
+
+        # Relative timestamp
+        @client.command()
+        async def countdown(ctx, seconds: int):
+            happens_in = discord.utils.utcnow() + datetime.timedelta(seconds=seconds)
+            await ctx.send(f'Happens {discord.utils.styled_timestamp(happens_in, discord.TimestampStyle.relative)}')
+
+    Raises
+    -------
+    AttributeError
+        If the :attr:`style` is not a valid member of :class:`~discord.TimestampStyle`
+
+    Returns
+    -------
+    :class:`str`
+        The formatted timestamp.
+    """
+    unix_timestamp = int(timestamp.timestamp()) if isinstance(timestamp, datetime.datetime) else int(timestamp)
     style = TimestampStyle.from_value(style) if isinstance(style, str) else style
     if not isinstance(style, TimestampStyle):
         raise AttributeError('style has to be a discord.TimestampStyle')
     return f'<t:{unix_timestamp}:{str(style)}>'
 
 
-def _unique(iterable):
+async def create_voice_activity(channel: VoiceChannel, target_application_id: int, **kwargs):
+    return await channel.create_invite(
+        target_type=InviteTargetType.embedded_application,
+        target_application_id=target_application_id,
+        **kwargs
+    )
+
+@overload
+def _unique(iterable: _Iterable[T]) -> List[T]: ...
+
+@overload
+def _unique(iterable: _IT[T], return_type: None) -> _IT[T]: ...
+
+@overload
+def _unique(iterable: _Iterable[T], return_type: None) -> List[T]: ...
+
+@overload
+def _unique(iterable: _IT[T]) -> _IT[T]: ...
+
+@overload
+def _unique(iterable: _Iterable[T], return_type: _IT) -> _IT[T]: ...
+
+@overload
+def _unique(iterable: _IT[T], return_type: _IT2) -> _IT2[T]: ...
+# idk why this typing doesn't work...
+
+def _unique(iterable, return_type = None):
     seen = set()
     adder = seen.add
-    return [x for x in iterable if not (x in seen or adder(x))]
+    if return_type is None:
+        return_type = type(iterable)
+    if return_type not in (list, tuple, set, frozenset, bytes, bytearray):
+        return_type = list
+    return return_type(x for x in iterable if not (x in seen or adder(x)))
 
+_unique({1: 2, 3: 1, 2: 3})
+_unique({1: 2, 3: 1, 2: 3}, return_type=set)
 
-def _get_as_snowflake(data, key):
+def _get_as_snowflake(data: Dict[str, Any], key: str) -> Optional[int]:
     try:
         value = data[key]
     except KeyError:
@@ -333,10 +590,10 @@ def _get_as_snowflake(data, key):
         return value and int(value)
 
 
-def _get_mime_type_for_image(data):
+def _get_mime_type_for_image(data: bytes) -> str:
     if data.startswith(b'\x89\x50\x4E\x47\x0D\x0A\x1A\x0A'):
         return 'image/png'
-    elif data[0:3] == b'\xff\xd8\xff' or data[6:10] in (b'JFIF', b'Exif'):
+    elif data[:3] == b'\xff\xd8\xff' or data[6:10] in (b'JFIF', b'Exif'):
         return 'image/jpeg'
     elif data.startswith((b'\x47\x49\x46\x38\x37\x61', b'\x47\x49\x46\x38\x39\x61')):
         return 'image/gif'
@@ -346,18 +603,18 @@ def _get_mime_type_for_image(data):
         raise InvalidArgument('Unsupported image type given')
 
 
-def _bytes_to_base64_data(data):
+def _bytes_to_base64_data(data: bytes) -> str:
     fmt = 'data:{mime};base64,{data}'
     mime = _get_mime_type_for_image(data)
     b64 = b64encode(data).decode('ascii')
     return fmt.format(mime=mime, data=b64)
 
 
-def to_json(obj):
+def to_json(obj: Any) -> str:
     return json.dumps(obj, separators=(',', ':'), ensure_ascii=True)
 
 
-def _parse_ratelimit_header(request, *, use_clock=False):
+def _parse_ratelimit_header(request: aiohttp.ClientResponse, *, use_clock: bool = False) -> float:
     reset_after = request.headers.get('X-Ratelimit-Reset-After')
     if use_clock or not reset_after:
         utc = datetime.timezone.utc
@@ -368,7 +625,7 @@ def _parse_ratelimit_header(request, *, use_clock=False):
         return float(reset_after)
 
 
-async def maybe_coroutine(f, *args, **kwargs):
+async def maybe_coroutine(f: MaybeAwaitableFunc[P, T], *args: P.args, **kwargs: P.kwargs) -> T:
     value = f(*args, **kwargs)
     if _isawaitable(value):
         return await value
@@ -376,7 +633,11 @@ async def maybe_coroutine(f, *args, **kwargs):
         return value
 
 
-async def async_all(gen, *, check=_isawaitable):
+async def async_all(
+        gen: Iterable[Union[T, Awaitable[T]]],
+        *,
+        check: Callable[[Union[T, Awaitable[T]]], TypeGuard[Awaitable[T]]] = _isawaitable
+) -> bool:
     for elem in gen:
         if check(elem):
             elem = await elem
@@ -384,7 +645,8 @@ async def async_all(gen, *, check=_isawaitable):
             return False
     return True
 
-async def sane_wait_for(futures, *, timeout):
+
+async def sane_wait_for(futures: Iterable[Awaitable[T]], *, timeout: Optional[float]) -> Set[asyncio.Task[T]]:
     ensured = [
         asyncio.ensure_future(fut) for fut in futures
     ]
@@ -395,7 +657,8 @@ async def sane_wait_for(futures, *, timeout):
 
     return done
 
-async def sleep_until(when, result=None):
+
+async def sleep_until(when: datetime.datetime, result: Optional[T] = None) -> Optional[T]:
     """|coro|
 
     Sleep until a specified time.
@@ -414,20 +677,19 @@ async def sleep_until(when, result=None):
     """
     if when.tzinfo is None:
         when = when.replace(tzinfo=datetime.timezone.utc)
-    now = datetime.datetime.now(datetime.timezone.utc)
-    delta = (when - now).total_seconds()
+    delta = (when - utcnow()).total_seconds()
     while delta > MAX_ASYNCIO_SECONDS:
         await asyncio.sleep(MAX_ASYNCIO_SECONDS)
         delta -= MAX_ASYNCIO_SECONDS
     return await asyncio.sleep(max(delta, 0), result)
 
 
-def valid_icon_size(size):
+def valid_icon_size(size: int) -> bool:
     """Icons must be power of 2 within [16, 4096]."""
     return not size & (size - 1) and size in range(16, 4097)
 
 
-class SnowflakeList(array.array):
+class SnowflakeList(array.array, Iterable[int]):
     """Internal data storage class to efficiently store a list of snowflakes.
 
     This should have the following characteristics:
@@ -441,18 +703,18 @@ class SnowflakeList(array.array):
 
     __slots__ = ()
 
-    def __new__(cls, data, *, is_sorted=False):
-        return array.array.__new__(cls, 'Q', data if is_sorted else sorted(data))
+    def __new__(cls, data, *, is_sorted=False) -> Self:
+        return array.array.__new__(cls, 'Q', data if is_sorted else sorted(data))  # type: ignore
 
-    def add(self, element):
+    def add(self, element: int) -> None:
         i = bisect_left(self, element)
         self.insert(i, element)
 
-    def get(self, element):
+    def get(self, element: int) -> Optional[int]:
         i = bisect_left(self, element)
         return self[i] if i != len(self) and self[i] == element else None
 
-    def has(self, element):
+    def has(self, element: int) -> bool:
         i = bisect_left(self, element)
         return i != len(self) and self[i] == element
 
@@ -460,7 +722,7 @@ def has(self, element):
 _IS_ASCII = re.compile(r'^[\x00-\x7f]+$')
 
 
-def _string_width(string, *, _IS_ASCII=_IS_ASCII):
+def _string_width(string: str, *, _IS_ASCII: re.Pattern = _IS_ASCII) -> int:
     """Returns string's width."""
     match = _IS_ASCII.match(string)
     if match:
@@ -471,7 +733,7 @@ def _string_width(string, *, _IS_ASCII=_IS_ASCII):
     return sum(2 if func(char) in UNICODE_WIDE_CHAR_TYPE else 1 for char in string)
 
 
-def resolve_invite(invite):
+def resolve_invite(invite: Union[Invite, str]) -> str:
     """
     Resolves an invite from a :class:`~discord.Invite`, URL or code.
 
@@ -496,7 +758,7 @@ def resolve_invite(invite):
     return invite
 
 
-def resolve_template(code):
+def resolve_template(code: Union[Template, str]) -> str:
     """
     Resolves a template code from a :class:`~discord.Template`, URL or code.
 
@@ -523,6 +785,35 @@ def resolve_template(code):
     return code
 
 
+_JUMP_URL_REGEX = re.compile(r'^https://(?:canary\.|ptb\.)?discord(?:app)?\.com/channels(?:/@me)?/([0-9]{15,21})(?:/([0-9]{15,21}))?.*$')
+
+def resolve_channel_from_url(jump_url: str) -> Tuple[Optional[int], int]:
+    """
+    Resolves a channel ID from a discord jump URL
+
+    Parameters
+    -----------
+    jump_url: :class:`str`
+        The jump URL.
+
+    Returns
+    --------
+    Tuple[Optional[:class:`int`], :class:`int`]
+        A tuple with the guild ID as the first and the channel ID as the second item.
+        If there is no guild ID then the first item is ``None``.
+
+    Raises
+    -------
+    :exc:`InvalidArgument`
+        The URL is invalid.
+    """
+    m = _JUMP_URL_REGEX.match(jump_url)
+    if m:
+        guild_id, channel_id = m.groups()
+        return int(guild_id) if guild_id else None, int(channel_id)
+    raise InvalidArgument(f'Invalid jump URL: {jump_url}')
+
+
 _MARKDOWN_ESCAPE_SUBREGEX = '|'.join(r'\{0}(?=([\s\S]*((?<!\{0})\{0})))'.format(c)
                                      for c in ('*', '`', '_', '~', '|'))
 
@@ -535,7 +826,7 @@ def resolve_template(code):
 _MARKDOWN_STOCK_REGEX = r'(?P<markdown>[_\\~|\*`]|%s)' % _MARKDOWN_ESCAPE_COMMON
 
 
-def remove_markdown(text, *, ignore_links=True):
+def remove_markdown(text: str, *, ignore_links: bool = True) -> str:
     """A helper function that removes markdown characters.
 
     .. versionadded:: 1.7
@@ -569,7 +860,7 @@ def replacement(match):
     return re.sub(regex, replacement, text, 0, re.MULTILINE)
 
 
-def escape_markdown(text, *, as_needed=False, ignore_links=True):
+def escape_markdown(text: str, *, as_needed: bool = False, ignore_links: bool = True) -> str:
     r"""A helper function that escapes Discord's markdown.
 
     Parameters
@@ -611,7 +902,7 @@ def replacement(match):
         return _MARKDOWN_ESCAPE_REGEX.sub(r'\\\1', text)
 
 
-def escape_mentions(text):
+def escape_mentions(text: str) -> str:
     """A helper function that escapes everyone, here, role, and user mentions.
 
     .. note::
@@ -635,3 +926,156 @@ def escape_mentions(text):
         The text with the mentions removed.
     """
     return re.sub(r'@(everyone|here|[!&]?[0-9]{17,20})', '@\u200b\\1', text)
+
+
+# Thanks discord.py for their concept for this, it's grat, so we build up on it :)
+def stream_supports_colour(stream: Any) -> bool:
+    # Pycharm and Vscode support colour in their inbuilt editors but normal files opened in them usually does not
+    if 'PYCHARM_HOSTED' in os.environ or os.environ.get('TERM_PROGRAM') == 'vscode':
+        return stream in (sys.stdout, sys.stderr)
+
+    is_a_tty = hasattr(stream, 'isatty') and stream.isatty()
+    if sys.platform != 'win32':
+        return is_a_tty
+
+    # ANSICON checks for things like ConEmu
+    # WT_SESSION checks if this is Windows Terminal
+    # SESSIONNAME checks if this is CMD
+    return is_a_tty and ('ANSICON' in os.environ or 'WT_SESSION' in os.environ or os.environ.get('SESSIONNAME', '') == 'Console')
+
+
+class _ColourFormatter(logging.Formatter):
+
+    # ANSI codes are a bit weird to decipher if you're unfamiliar with them, so here's a refresher
+    # It starts off with a format like \x1b[XXXm where XXX is a semicolon separated list of commands
+    # The important ones here relate to colour.
+    # 30-37 are black, red, green, yellow, blue, magenta, cyan and white in that order
+    # 40-47 are the same except for the background
+    # 90-97 are the same but "bright" foreground
+    # 100-107 are the same as the bright ones but for the background.
+    # 1 means bold, 2 means dim, 0 means reset, and 4 means underline.
+
+    LEVEL_COLOURS = [
+        (logging.DEBUG, colorama.Back.BLACK + colorama.Style.BRIGHT),
+        (logging.INFO, colorama.Fore.BLUE + colorama.Style.BRIGHT),
+        (logging.WARNING, colorama.Fore.YELLOW + colorama.Style.BRIGHT),
+        (logging.ERROR, colorama.Fore.RED),
+        (logging.CRITICAL, colorama.Back.RED),
+    ]
+
+    FORMATS = {
+        level: logging.Formatter(
+            f'\x1b[30;1m%(asctime)s\x1b[0m {colour}%(levelname)-8s\x1b[0m \x1b[35m%(name)s\x1b[0m %(message)s',
+            '%Y-%m-%d %H:%M:%S',
+        )
+        for level, colour in LEVEL_COLOURS
+    }
+
+    def __str__(self) -> str:
+        return 'ColorFormatter'
+
+    def format(self, record):
+        formatter = self.FORMATS.get(record.levelno)
+        if formatter is None:
+            formatter = self.FORMATS[logging.DEBUG]
+
+        # Override the traceback to always print in red
+        if record.exc_info:
+            text = formatter.formatException(record.exc_info)
+            record.exc_text = f'\x1b[31m{text}\x1b[0m'
+
+        output = formatter.format(record)
+
+        # Remove the cache layer
+        record.exc_text = None
+        return output
+
+
+def setup_logging(
+        name: str = MISSING,
+        *,
+        handler: logging.Handler = MISSING,
+        formatter: logging.Formatter = MISSING,
+        level: int = MISSING,
+        root: bool = True,
+
+) -> logging.Logger:
+    """A helper function to set up logging.
+    This is superficially similar to :func:`logging.basicConfig` but
+    uses different defaults and a colour formatter if the stream can
+    display colour.
+    This is used by the :class:`~discord.Client` to set up logging
+    if ``log_handler`` is not ``None``.
+
+    .. versionadded:: 2.0
+
+    Parameters
+    -----------
+    name: :class:`str`
+        The name that should be used for the logger if ``root`` is :obj:`False`. This defaults to the module name.
+    handler: :class:`logging.Handler`
+        The log handler to use for the library's logger.
+        The default log handler if not provided is :class:`logging.StreamHandler`.
+    formatter: :class:`logging.Formatter`
+        The formatter to use with the given log handler. If not provided then it
+        defaults to a colour based logging formatter (if available). If colour
+        is not available then a simple logging formatter is provided.
+    level: :class:`int`
+        The default log level for the library's logger. Defaults to :obj:`logging.INFO`.
+    root: :class:`bool`
+        Whether to set up the root logger rather than the library logger.
+        Unlike the default for :class:`~discord.Client`, this defaults to :obj:`True`.
+
+    Returns
+    -------
+    :class:`logging.Logger`
+        The logger that has been set up.
+    """
+
+    if level is MISSING:
+        level = logging.INFO
+
+    if handler is MISSING:
+        handler = logging.StreamHandler()
+        handler_name = 'default stream handler'
+    else:
+        handler_name = handler.name
+
+    if formatter is MISSING:
+        if isinstance(handler, logging.StreamHandler) and stream_supports_colour(handler.stream):
+            formatter = _ColourFormatter()
+            supports_color = True
+        else:
+            dt_fmt = '%Y-%m-%d %H:%M:%S'
+            formatter = logging.Formatter('[{asctime}] [{levelname:<8}] {name}: {message}', dt_fmt, style='{')
+            supports_color = False
+    else:
+        supports_color = stream_supports_colour(handler.stream) if isinstance(handler, logging.StreamHandler) else False
+
+    if root:
+        logger = logging.getLogger()
+    else:
+        if name is not MISSING:
+            logger = logging.getLogger(name)
+        else:
+            library, _, _ = __name__.partition('.')
+            logger = logging.getLogger(library)
+
+    handler.setFormatter(formatter)
+    logger.setLevel(level)
+    logger.addHandler(handler)
+
+    if logger.isEnabledFor(logging.INFO):
+        level_name = logging.getLevelName(level)
+        if supports_color:
+            fmt = f'Started colored logging for \x1b[32m%s\x1b[0m with handler \x1b[32m%s\x1b[0m on level {dict(_ColourFormatter.LEVEL_COLOURS)[level]}%s\x1b[0m.'
+        else:
+            fmt = 'Started logging for %s with handler %s on level %s.'
+        logger.info(
+            fmt,
+            logger.name,
+            handler_name,
+            level_name
+        )
+
+    return logger
diff --git a/discord/voice_client.py b/discord/voice_client.py
index d24d022b..ab5c692d 100644
--- a/discord/voice_client.py
+++ b/discord/voice_client.py
@@ -3,7 +3,9 @@
 """
 The MIT License (MIT)
 
-Copyright (c) 2015-present Rapptz
+Copyright (c) 2015-2021 Rapptz & (c) 2021-present mccoderpy
+
+Implementation of voice-receiving was taken from PyCord
 
 Permission is hereby granted, free of charge, to any person obtaining a
 copy of this software and associated documentation files (the "Software"),
@@ -23,6 +25,7 @@
 FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 DEALINGS IN THE SOFTWARE.
 """
+from __future__ import annotations
 
 """Some documentation to refer to:
 
@@ -44,12 +47,29 @@
 import logging
 import struct
 import threading
+import select
+import time
+
+from typing import (
+    Any,
+    Callable,
+    List,
+    Optional,
+    TYPE_CHECKING,
+    Tuple
+)
+
+if TYPE_CHECKING:
+    from .types.voice import (
+        VoiceRegion as VoiceRegionData,
+    )
 
 from . import opus, utils
 from .backoff import ExponentialBackoff
 from .gateway import *
-from .errors import ClientException, ConnectionClosed
+from .errors import ClientException, ConnectionClosed, RecordingException
 from .player import AudioPlayer, AudioSource
+from .sink import Sink, RawData
 
 try:
     import nacl.secret
@@ -59,6 +79,85 @@
 
 log = logging.getLogger(__name__)
 
+__all__ = (
+    'VoiceRegionInfo',
+    'VoiceClient',
+    'VoiceProtocol',
+)
+
+
+class VoiceRegionInfo:
+    """A class containing info about a specific voice region.
+
+    These can be retrieved via :meth:`~discord.Client.fetch_voice_regions`.
+
+    .. versionadded:: 2.0
+
+    Attributes
+    ------------
+    id: :class:`str`
+        The unique ID of the region.
+    name: :class:`str`
+        The name of the region.
+    vip: :class:`bool`
+        Indicates if this is a VIP-only server.
+    optimal: :class:`bool`
+    	``True`` for a single server that is closest to the current user's client
+    deprecated: :class:`bool`
+        Indicates if this is a deprecated voice region (avoid switching to these).
+    custom: :class:`bool`
+        Indicates if this is a custom voice region (used for events/etc).
+
+    .. container:: operations
+
+        .. describe:: x == y
+            Whether two voice regions are equal.
+        .. describe:: x != y
+            Whether two voice regions are not equal.
+        .. describe:: x > y
+            Whether a voice region is optimal over another.
+        .. describe:: x < y
+            Whether a voice region is not optimal over another.
+        .. describe:: str(x)
+            Returns the id of the region.
+        .. describe:: repr(x)
+            Returns a representation of the region.
+        ..
+    """
+    def __init__(self, *, data: VoiceRegionData) -> None:
+        self.id: str = data['id']
+        self.name: str = data['name']
+        self.vip: bool = data['vip']
+        self.optimal: bool = data['optimal']
+        self.deprecated: bool = data['deprecated']
+        self.custom: bool = data['custom']
+
+    def __repr__(self) -> str:
+        return f'<VoiceRegion id={self.id} name={self.name!r} vip={self.vip} optimal={self.optimal}' \
+               f' deprecated={self.deprecated} custom={self.custom}>'
+
+    def __eq__(self, other: Any) -> bool:
+        return isinstance(other, VoiceRegionInfo) and other.id == self.id
+
+    def __ne__(self, other: Any) -> bool:
+        return not self.__eq__(other)
+
+    def __gt__(self, other: Any) -> bool:
+        return isinstance(other, VoiceRegionInfo) and self.optimal and not other.optimal
+
+    def __ge__(self, other: Any) -> bool:
+        return isinstance(other, VoiceRegionInfo) and self.optimal and not other.optimal
+
+    def __lt__(self, other: Any) -> bool:
+        return isinstance(other, VoiceRegionInfo) and not self.optimal and other.optimal
+
+    def __le__(self, other: Any) -> bool:
+        return isinstance(other, VoiceRegionInfo) and not self.optimal and other.optimal
+
+    def __str__(self) -> str:
+        return self.id
+
+
 class VoiceProtocol:
     """A class that represents the Discord voice protocol.
 
@@ -184,7 +283,7 @@ class VoiceClient(VoiceProtocol):
     Attributes
     -----------
     session_id: :class:`str`
-        The voice connection session ID.
+        The voice connection _session ID.
     token: :class:`str`
         The voice connection token.
     endpoint: :class:`str`
@@ -219,8 +318,16 @@ def __init__(self, client, channel):
         self._runner = None
         self._player = None
         self.encoder = None
+        self.decoder = None
         self._lite_nonce = 0
-        self.ws = None
+        self.ws: DiscordVoiceWebSocket = None
+
+        self.paused = False
+        self.recording = False
+        self.user_timestamps = {}
+        self.sink = None
+        self.starting_time = None
+        self.stopping_time = None
 
     warn_nacl = not has_nacl
     supported_modes = (
@@ -522,7 +629,47 @@ def _encrypt_xsalsa20_poly1305_lite(self, header, data):
 
         return header + box.encrypt(bytes(data), bytes(nonce)).ciphertext + nonce[:4]
 
-    def play(self, source, *, after=None):
+    def _decrypt_xsalsa20_poly1305(self, header, data):
+        box = nacl.secret.SecretBox(bytes(self.secret_key))
+
+        nonce = bytearray(24)
+        nonce[:12] = header
+
+        return self.strip_header_ext(box.decrypt(bytes(data), bytes(nonce)))
+
+    def _decrypt_xsalsa20_poly1305_suffix(self, header, data):
+        box = nacl.secret.SecretBox(bytes(self.secret_key))
+
+        nonce_size = nacl.secret.SecretBox.NONCE_SIZE
+        nonce = data[-nonce_size:]
+
+        return self.strip_header_ext(box.decrypt(bytes(data[:-nonce_size]), nonce))
+
+    def _decrypt_xsalsa20_poly1305_lite(self, header, data):
+        box = nacl.secret.SecretBox(bytes(self.secret_key))
+
+        nonce = bytearray(24)
+        nonce[:4] = data[-4:]
+        data = data[:-4]
+
+        return self.strip_header_ext(box.decrypt(bytes(data), bytes(nonce)))
+
+    @staticmethod
+    def strip_header_ext(data):
+        if data[0] == 0xBE and data[1] == 0xDE and len(data) > 4:
+            _, length = struct.unpack_from(">HH", data)
+            offset = 4 + length * 4
+            data = data[offset:]
+        return data
+
+    def get_ssrc(self, user_id):
+        return {info["user_id"]: ssrc for ssrc, info in self.ws.ssrc_map.items()}[
+            user_id
+        ]
+
+    def play(
+            self, source: AudioSource, *, after: Callable[[Optional[Exception]], Any] = None
+    ) -> None:
         """Plays an :class:`AudioSource`.
 
         The finalizer, ``after`` is called after the source has been exhausted
@@ -640,3 +787,149 @@ def send_audio_packet(self, data, *, encode=True):
             log.warning('A packet has been dropped (seq: %s, timestamp: %s)', self.sequence, self.timestamp)
 
         self.checked_add('timestamp', opus.Encoder.SAMPLES_PER_FRAME, 4294967295)
+
+    def unpack_audio(self, data):
+        """Takes an audio packet received from Discord and decodes it into pcm audio data.
+        If there are no users talking in the channel, `None` will be returned.
+        You must be connected to receive audio.
+        Parameters
+        ---------
+        data: :class:`bytes`
+            Bytes received by Discord via the UDP connection used for sending and receiving voice data.
+        """
+        if 200 <= data[1] <= 204:
+            # RTCP received.
+            # RTCP provides information about the connection
+            # as opposed to actual audio data, so it's not
+            # important at the moment.
+            return
+        if self.paused:
+            return
+
+        data = RawData(data, self)
+
+        if data.decrypted_data == b'\xf8\xff\xfe':  # Frame of silence
+            return
+
+        self.decoder.decode(data)
+
+    def start_recording(self, sink, callback, *args):
+        """The bot will begin recording audio from the current voice channel it is in.
+        This function uses a thread so the current code line will not be stopped.
+        Must be in a voice channel to use.
+        Must not be already recording.
+        Parameters
+        ----------
+        sink: :class:`Sink`
+            A Sink which will "store" all the audio data.
+        callback: :class:`asynchronous function`
+            A function which is called after the bot has stopped recording.
+        *args:
+            Args which will be passed to the callback function.
+        Raises
+        ------
+        RecordingException
+            Not connected to a voice channel.
+        RecordingException
+            Already recording.
+        RecordingException
+            Must provide a Sink object.
+        """
+        if not self.is_connected():
+            raise RecordingException('Not connected to voice channel.')
+        if self.recording:
+            raise RecordingException("Already recording.")
+        if not isinstance(sink, Sink):
+            raise RecordingException("Must provide a Sink object.")
+
+        self.empty_socket()
+
+        self.decoder = opus.DecodeManager(self)
+        self.decoder.start()
+        self.recording = True
+        self.sink = sink
+        sink.init(self)
+
+        t = threading.Thread(target=self.recv_audio, args=(sink, callback, *args,))
+        t.start()
+
+    def stop_recording(self):
+        """Stops the recording.
+        Must be already recording.
+        Raises
+        ------
+        RecordingException
+            Not currently recording.
+        """
+        if not self.recording:
+            raise RecordingException("Not currently recording audio.")
+        self.decoder.stop()
+        self.recording = False
+        self.paused = False
+
+    def toggle_pause(self):
+        """Pauses or unpauses the recording.
+        Must be already recording.
+        Raises
+        ------
+        RecordingException
+            Not currently recording.
+         """
+        if not self.recording:
+            raise RecordingException("Not currently recording audio.")
+        self.paused = not self.paused
+
+    def empty_socket(self):
+        while True:
+            ready, _, _ = select.select([self.socket], [], [], 0.0)
+            if not ready:
+                break
+            for s in ready:
+                s.recv(4096)
+
+    def recv_audio(self, sink, callback, *args):
+        #  Gets data from _recv_audio and sorts
+        #  it by user, handles pcm files and
+        #  silence that should be added.
+
+        self.user_timestamps = {}
+        self.starting_time = time.perf_counter()
+        while self.recording:
+            ready, _, err = select.select([self.socket], [],
+                                          [self.socket], 0.01)
+            if not ready:
+                if err:
+                    print(f"Socket error: {err}")
+                continue
+
+            try:
+                data = self.socket.recv(4096)
+            except OSError:
+                self.stop_recording()
+                continue
+
+            self.unpack_audio(data)
+
+        self.stopping_time = time.perf_counter()
+        self.sink.cleanup()
+        callback = asyncio.run_coroutine_threadsafe(callback(self.sink, *args), self.loop)
+        result = callback.result()
+
+        if result is not None:
+            print(result)
+
+    def recv_decoded_audio(self, data):
+        if data.ssrc not in self.user_timestamps:
+            self.user_timestamps.update({data.ssrc: data.timestamp})
+            # Add silence of when they were not being recorded.
+            data.decoded_data = struct.pack('<h', 0) * round(
+                self.decoder.CHANNELS * self.decoder.SAMPLING_RATE * (time.perf_counter() - self.starting_time)
+            ) + data.decoded_data
+        else:
+            self.user_timestamps[data.ssrc] = data.timestamp
+
+        silence = data.timestamp - self.user_timestamps[data.ssrc] - 960
+        data.decoded_data = struct.pack('<h', 0) * silence + data.decoded_data
+        while data.ssrc not in self.ws.ssrc_map:
+            time.sleep(0.05)
+        self.sink.write(data.decoded_data, self.ws.ssrc_map[data.ssrc]['user_id'])
\ No newline at end of file
diff --git a/discord/webhook.py b/discord/webhook.py
index af29a47a..929bca1b 100644
--- a/discord/webhook.py
+++ b/discord/webhook.py
@@ -23,23 +23,61 @@
 FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 DEALINGS IN THE SOFTWARE.
 """
+from __future__ import annotations
 
-import logging
 import asyncio
 import json
-import time
+import logging
 import re
+import time
+from typing import (
+    Any,
+    List,
+    Dict,
+    overload,
+    Optional,
+    Sequence,
+    Coroutine,
+    Callable,
+    TypeVar,
+    TYPE_CHECKING,
+    Union,
+)
+from typing_extensions import Literal
 from urllib.parse import quote as _uriquote
 
 import aiohttp
 
 from . import utils
-from .errors import InvalidArgument, HTTPException, Forbidden, NotFound, DiscordServerError
-from .message import Message
-from .enums import try_enum, WebhookType
-from .user import BaseUser, User
 from .asset import Asset
+from .enums import try_enum, WebhookType
+from .flags import MessageFlags
+from .errors import DiscordServerError, Forbidden, HTTPException, InvalidArgument, NotFound
+from .http import handle_message_parameters, MultipartParameters
+from .message import Message, Attachment
 from .mixins import Hashable
+from .user import BaseUser, User
+
+if TYPE_CHECKING:
+    from datetime import datetime
+    from .types.webhook import (
+        Webhook as WebhookData,
+        PartialWebhook as PartialWebhookData,
+    )
+    from .oauth2.client import OAuth2Client
+    from .state import ConnectionState
+    from .embeds import Embed
+    from .file import File
+    from .guild import Guild
+    from .channel import TextChannel, ForumChannel
+    from .components import BaseSelect, Button, ActionRow
+    from .mentions import AllowedMentions
+
+    State = Union[ConnectionState, '_PartialWebhookState']
+
+
+T = TypeVar('T')
+Coro = Coroutine[Any, Any, T]
 
 __all__ = (
     'WebhookAdapter',
@@ -49,8 +87,14 @@
     'WebhookMessage',
 )
 
+MISSING = utils.MISSING
+WEBHOOK_URL_REGEX = re.compile(
+    r'discord(?:app)?.com/api(?:/v\d+)?/webhooks/(?P<id>[0-9]{17,20})/(?P<token>[A-Za-z0-9.\-_]{60,68})'
+)
+
 log = logging.getLogger(__name__)
 
+
 class WebhookAdapter:
     """Base class for all webhook adapters.
 
@@ -59,19 +103,27 @@ class WebhookAdapter:
     webhook: :class:`Webhook`
         The webhook that owns this adapter.
     """
+    webhook: Webhook
 
-    BASE = 'https://discord.com/api/v7'
+    BASE = 'https://discord.com/api/v10'
 
-    def _prepare(self, webhook):
+    def _prepare(self, webhook: Webhook) -> None:
         self._webhook_id = webhook.id
         self._webhook_token = webhook.token
         self._request_url = '{0.BASE}/webhooks/{1}/{2}'.format(self, webhook.id, webhook.token)
         self.webhook = webhook
 
-    def is_async(self):
+    def is_async(self) -> bool:
         return False
 
-    def request(self, verb, url, payload=None, multipart=None):
+    def request(
+            self,
+            verb,
+            url: str,
+            multipart: Optional[List[Dict[str, Any]]] = None,
+            payload: Optional[Dict[str, Any]] = None,
+            **kwargs: Any
+    ) -> Any:
         """Actually does the request.
 
         Subclasses must implement this.
@@ -93,19 +145,28 @@ def request(self, verb, url, payload=None, multipart=None):
         """
         raise NotImplementedError()
 
-    def delete_webhook(self, *, reason=None):
+    def delete_webhook(self, *, reason: Optional[str] = None):
         return self.request('DELETE', self._request_url, reason=reason)
 
-    def edit_webhook(self, *, reason=None, **payload):
+    def edit_webhook(self, *, reason: Optional[str] = None, **payload):
         return self.request('PATCH', self._request_url, payload=payload, reason=reason)
 
-    def edit_webhook_message(self, message_id, payload):
-        return self.request('PATCH', '{}/messages/{}'.format(self._request_url, message_id), payload=payload)
-
-    def delete_webhook_message(self, message_id):
-        return self.request('DELETE', '{}/messages/{}'.format(self._request_url, message_id))
-
-    def handle_execution_response(self, data, *, wait):
+    def edit_webhook_message(self, message_id: int, params: MultipartParameters, thread_id: Optional[int] = None):
+        url = f'{self._request_url}/messages/{message_id}'
+        if thread_id:
+            url += f'?thread_id={thread_id}'
+        if params.files:
+            return self.request('PATCH', url, form=params.multipart)
+        return self.request('PATCH', url, payload=params.payload)
+    # TODO: Fix file sending with webhooks
+
+    def delete_webhook_message(self, message_id: int, thread_id: Optional[int] = None):
+        url = '{}/messages/{}'.format(self._request_url, message_id)
+        if thread_id:
+            url += f'?thread_id={thread_id}'
+        return self.request('DELETE', url)
+
+    def handle_execution_response(self, data, *, wait: bool) -> Optional[WebhookMessage]:
         """Transforms the webhook execution response into something
         more meaningful.
 
@@ -123,79 +184,64 @@ def handle_execution_response(self, data, *, wait):
         """
         raise NotImplementedError()
 
-    async def _wrap_coroutine_and_cleanup(self, coro, cleanup):
+    async def foo(self) -> int: ...
+
+    async def _wrap_coroutine_and_cleanup(self, coro: Coro[T], cleanup: Callable[[], Any]) -> T:
         try:
             return await coro
         finally:
             cleanup()
 
-    def execute_webhook(self, *, payload, wait=False, file=None, files=None):
-        cleanup = None
-        if file is not None:
-            multipart = {
-                'file': (file.filename, file.fp, 'application/octet-stream'),
-                'payload_json': utils.to_json(payload)
-            }
-            data = None
-            cleanup = file.close
-            files_to_pass = [file]
-        elif files is not None:
-            multipart = {
-                'payload_json': utils.to_json(payload)
-            }
-            for i, file in enumerate(files):
-                multipart['file%i' % i] = (file.filename, file.fp, 'application/octet-stream')
-            data = None
-
-            def _anon():
-                for f in files:
-                    f.close()
-
-            cleanup = _anon
-            files_to_pass = files
+    def execute_webhook(self, *, wait: bool =False, thread_id: Optional[int] = None, params: MultipartParameters):
+        url = f'{self._request_url}?wait={wait}'
+        if thread_id:
+            url += f'&thread_id={thread_id}'
+        if params.files:
+            maybe_coro = self.request('POST', url, multipart=params.multipart, files=params.files)
         else:
-            data = payload
-            multipart = None
-            files_to_pass = None
-
-        url = '%s?wait=%d' % (self._request_url, wait)
-        maybe_coro = None
-        try:
-            maybe_coro = self.request('POST', url, multipart=multipart, payload=data, files=files_to_pass)
-        finally:
-            if maybe_coro is not None and cleanup is not None:
-                if not asyncio.iscoroutine(maybe_coro):
-                    cleanup()
-                else:
-                    maybe_coro = self._wrap_coroutine_and_cleanup(maybe_coro, cleanup)
+            maybe_coro = self.request('POST', url, payload=params.payload)
 
         # if request raises up there then this should never be `None`
         return self.handle_execution_response(maybe_coro, wait=wait)
 
+
 class AsyncWebhookAdapter(WebhookAdapter):
     """A webhook adapter suited for use with aiohttp.
 
     .. note::
 
-        You are responsible for cleaning up the client session.
+        You are responsible for cleaning up the client _session.
 
     Parameters
     -----------
     session: :class:`aiohttp.ClientSession`
-        The session to use to send requests.
+        The _session to use to send requests.
     """
 
-    def __init__(self, session):
-        self.session = session
-        self.loop = asyncio.get_event_loop()
+    def __init__(self, session: aiohttp.ClientSession) -> None:
+        self.session: aiohttp.ClientSession = session
+        self.loop: asyncio.AbstractEventLoop = asyncio.get_event_loop()
 
-    def is_async(self):
+    def is_async(self) -> bool:
         return True
 
-    async def request(self, verb, url, payload=None, multipart=None, *, files=None, reason=None):
-        headers = {}
-        data = None
+    async def request(
+            self,
+            verb: str,
+            url: str,
+            *,
+            payload: Optional[Dict[str, Any]] = None,
+            multipart: Optional[List[Dict[str, Any]]] = None,
+            proxy: Optional[str] = None,
+            proxy_auth: Optional[aiohttp.BasicAuth] = None,
+            files: Optional[Sequence[File]] = None,
+            reason: Optional[str] = None,
+            params: Optional[Dict[str, Any]] = None,
+    ):
+        headers: Dict[str, str] = {}
+        data: Union[str, aiohttp.FormData, None] = None
         files = files or []
+
         if payload:
             headers['Content-Type'] = 'application/json'
             data = utils.to_json(payload)
@@ -203,7 +249,6 @@ async def request(self, verb, url, payload=None, multipart=None, *, files=None,
         if reason:
             headers['X-Audit-Log-Reason'] = _uriquote(reason, safe='/ ')
 
-
         base_url = url.replace(self._request_url, '/') or '/'
         _id = self._webhook_id
         for tries in range(5):
@@ -211,14 +256,19 @@ async def request(self, verb, url, payload=None, multipart=None, *, files=None,
                 file.reset(seek=tries)
 
             if multipart:
-                data = aiohttp.FormData()
-                for key, value in multipart.items():
-                    if key.startswith('file'):
-                        data.add_field(key, value[1], filename=value[0], content_type=value[2])
-                    else:
-                        data.add_field(key, value)
-
-            async with self.session.request(verb, url, headers=headers, data=data) as r:
+                data = aiohttp.FormData(quote_fields=False)
+                for p in multipart:
+                    data.add_field(**p)
+
+            async with self.session.request(
+                verb,
+                url,
+                headers=headers,
+                data=data,
+                params=params,
+                proxy=proxy,
+                proxy_auth=proxy_auth,
+            ) as r:
                 log.debug('Webhook ID %s with %s %s has returned status code %s', _id, verb, base_url, r.status)
                 # Coerce empty strings to return None for hygiene purposes
                 response = (await r.text(encoding='utf-8')) or None
@@ -241,7 +291,7 @@ async def request(self, verb, url, payload=None, multipart=None, *, files=None,
                         # Banned by Cloudflare more than likely.
                         raise HTTPException(r, data)
 
-                    retry_after = response['retry_after'] / 1000.0
+                    retry_after = response['retry_after']
                     log.warning('Webhook ID %s is rate limited. Retrying in %.2f seconds', _id, retry_after)
                     await asyncio.sleep(retry_after)
                     continue
@@ -262,7 +312,7 @@ async def request(self, verb, url, payload=None, multipart=None, *, files=None,
             raise DiscordServerError(r, response)
         raise HTTPException(r, response)
 
-    async def handle_execution_response(self, response, *, wait):
+    async def handle_execution_response(self, response, *, wait: bool) -> Optional[WebhookMessage]:
         data = await response
         if not wait:
             return data
@@ -272,6 +322,7 @@ async def handle_execution_response(self, response, *, wait):
         state = _PartialWebhookState(self, self.webhook, parent=self.webhook._state)
         return WebhookMessage(data=data, state=state, channel=self.webhook.channel)
 
+
 class RequestsWebhookAdapter(WebhookAdapter):
     """A webhook adapter suited for use with ``requests``.
 
@@ -280,10 +331,10 @@ class RequestsWebhookAdapter(WebhookAdapter):
     Parameters
     -----------
     session: Optional[`requests.Session <http://docs.python-requests.org/en/latest/api/#requests.Session>`_]
-        The requests session to use for sending requests. If not given then
-        each request will create a new session. Note if a session is given,
+        The requests _session to use for sending requests. If not given then
+        each request will create a new _session. Note if a _session is given,
         the webhook adapter **will not** clean it up for you. You must close
-        the session yourself.
+        the _session yourself.
     sleep: :class:`bool`
         Whether to sleep the thread when encountering a 429 or pre-emptive
         rate limit or a 5xx status code. Defaults to ``True``. If set to
@@ -344,7 +395,7 @@ def request(self, verb, url, payload=None, multipart=None, *, files=None, reason
                         # Banned by Cloudflare more than likely.
                         raise HTTPException(r, data)
 
-                    retry_after = response['retry_after'] / 1000.0
+                    retry_after = response['retry_after']
                     log.warning('Webhook ID %s is rate limited. Retrying in %.2f seconds', _id, retry_after)
                     time.sleep(retry_after)
                     continue
@@ -376,17 +427,20 @@ def handle_execution_response(self, response, *, wait):
         state = _PartialWebhookState(self, self.webhook, parent=self.webhook._state)
         return WebhookMessage(data=response, state=state, channel=self.webhook.channel)
 
+
 class _FriendlyHttpAttributeErrorHelper:
     __slots__ = ()
 
     def __getattr__(self, attr):
         raise AttributeError('PartialWebhookState does not support http methods.')
 
+
 class _PartialWebhookState:
     __slots__ = ('loop', 'parent', '_webhook')
+    loop: Optional[asyncio.AbstractEventLoop]
 
     def __init__(self, adapter, webhook, parent):
-        self._webhook = webhook
+        self._webhook: Webhook = webhook
 
         if isinstance(parent, self.__class__):
             self.parent = None
@@ -399,14 +453,14 @@ def __init__(self, adapter, webhook, parent):
         except AttributeError:
             self.loop = None
 
-    def _get_guild(self, guild_id):
+    def _get_guild(self, guild_id: int) -> None:
         return None
 
-    def store_user(self, data):
+    def store_user(self, data) -> BaseUser:
         return BaseUser(state=self, data=data)
 
     @property
-    def is_bot(self):
+    def is_bot(self) -> bool:
         return True
 
     @property
@@ -418,11 +472,12 @@ def http(self):
         # however, using it should result in a late-binding error.
         return _FriendlyHttpAttributeErrorHelper()
 
-    def __getattr__(self, attr):
+    def __getattr__(self, attr: str) -> Any:
         if self.parent is not None:
             return getattr(self.parent, attr)
 
-        raise AttributeError('PartialWebhookState does not support {0!r}.'.format(attr))
+        raise AttributeError(f'PartialWebhookState does not support {attr!r}.')
+
 
 class WebhookMessage(Message):
     """Represents a message sent from your webhook.
@@ -435,28 +490,77 @@ class WebhookMessage(Message):
 
     .. versionadded:: 1.6
     """
-
-    def edit(self, **fields):
+    _state: _PartialWebhookState
+
+    def edit(
+        self,
+        *,
+        content: Any = MISSING,
+        embed: Optional[Embed] = MISSING,
+        embeds: Sequence[Embed] = MISSING,
+        components: List[Union[ActionRow, List[Union[Button, BaseSelect]]]] = MISSING,
+        attachments: Sequence[Union[Attachment, File]] = MISSING,
+        keep_existing_attachments: bool = False,
+        allowed_mentions: AllowedMentions = MISSING,
+        suppress_embeds: bool = MISSING
+    ) -> Union[Coro[WebhookMessage], WebhookMessage]:
         """|maybecoro|
 
-        Edits the message.
+        Edits a message owned by this webhook.
 
-        The content must be able to be transformed into a string via ``str(content)``.
+        This is a lower level interface to :meth:`WebhookMessage.edit` in case
+        you only have an ID.
+        
+        .. warning::
+            Since API v10, the ``attachments`` (when passed) **must contain all attachments** that should be present after edit,
+            **including retained** and new attachments.
+            
+            As this requires to know the current attachments consider either storing the attachments that were sent with a message or
+            using a fetched version of the message to edit it.
 
         .. versionadded:: 1.6
+        
+        .. versionchanged:: 2.0
+            The ``suppress`` keyword-only parameter was renamed to ``suppress_embeds``.
 
         Parameters
         ------------
         content: Optional[:class:`str`]
             The content to edit the message with or ``None`` to clear it.
-        embeds: List[:class:`Embed`]
-            A list of embeds to edit the message with.
         embed: Optional[:class:`Embed`]
-            The embed to edit the message with. ``None`` suppresses the embeds.
-            This should not be mixed with the ``embeds`` parameter.
+            The new embed to replace the original with.
+            Could be ``None`` to remove all embeds.
+        embeds: Optional[List[:class:`Embed`]]
+            A list containing up to 10 embeds. If ``None`` empty, all embeds will be removed.
+        components: List[Union[:class:`~discord.ActionRow`, List[Union[:class:`~discord.Button`, :ref:`Select <select-like-objects>`]]]]
+            A list of up to five :class:`~discord.ActionRow`s or :class:`list`,
+            each containing up to five :class:`~discord.Button` or one :ref:`Select <select-like-objects>` like object.
+            
+            .. note::
+                Due to discord limitations this can only be used when the webhook is owned by an application.
+            
+            .. versionadded:: 2.0
+        attachments: List[Union[:class:`Attachment`, :class:`File`]]
+            A list containing previous attachments to keep as well as new files to upload.
+            
+            When empty, all attachment will be removed.
+
+            .. note::
+
+                New files will always appear under existing ones.
+            
+            .. versionadded:: 2.0
+        keep_existing_attachments: :class:`bool`
+            Whether to auto-add existing attachments to ``attachments``, defaults to :obj:`False`.
+
+            .. note::
+
+                Only needed when ``attachments`` are passed, otherwise will be ignored.
         allowed_mentions: :class:`AllowedMentions`
             Controls the mentions being processed in this message.
             See :meth:`.abc.Messageable.send` for more information.
+        suppress_embeds: :class:`bool`
+            Whether to suppress embeds send with the message.
 
         Raises
         -------
@@ -465,17 +569,28 @@ def edit(self, **fields):
         Forbidden
             Edited a message that is not yours.
         InvalidArgument
-            You specified both ``embed`` and ``embeds`` or the length of
-            ``embeds`` was invalid or there was no token associated with
+            The length of ``embeds`` was invalid or there was no token associated with
             this webhook.
         """
-        return self._state._webhook.edit_message(self.id, **fields)
-
-    def _delete_delay_sync(self, delay):
+        if keep_existing_attachments and attachments is not MISSING:
+            attachments = [*self.attachments, *attachments]
+        
+        return self._state._webhook.edit_message(
+            self.id,
+            content=content,
+            embed=embed,
+            embeds=embeds,
+            components=components,
+            attachments=attachments,
+            allowed_mentions=allowed_mentions,
+            suppress_embeds=suppress_embeds
+        )
+
+    def _delete_delay_sync(self, delay: float) -> None:
         time.sleep(delay)
         return self._state._webhook.delete_message(self.id)
 
-    async def _delete_delay_async(self, delay):
+    async def _delete_delay_async(self, delay: float) -> None:
         async def inner_call():
             await asyncio.sleep(delay)
             try:
@@ -486,7 +601,7 @@ async def inner_call():
         asyncio.ensure_future(inner_call(), loop=self._state.loop)
         return await asyncio.sleep(0)
 
-    def delete(self, *, delay=None):
+    def delete(self, *, delay: Optional[float] = None) -> Union[Coro[None], None]:
         """|coro|
 
         Deletes the message.
@@ -516,6 +631,7 @@ def delete(self, *, delay=None):
 
         return self._state._webhook.delete_message(self.id)
 
+
 class Webhook(Hashable):
     """Represents a Discord webhook.
 
@@ -525,7 +641,7 @@ class Webhook(Hashable):
     There are two main ways to use Webhooks. The first is through the ones
     received by the library such as :meth:`.Guild.webhooks` and
     :meth:`.TextChannel.webhooks`. The ones received by the library will
-    automatically have an adapter bound using the library's HTTP session.
+    automatically have an adapter bound using the library's HTTP _session.
     Those webhooks will have :meth:`~.Webhook.send`, :meth:`~.Webhook.delete` and
     :meth:`~.Webhook.edit` as coroutines.
 
@@ -543,8 +659,8 @@ class Webhook(Hashable):
         import aiohttp
 
         async def foo():
-            async with aiohttp.ClientSession() as session:
-                webhook = Webhook.from_url('url-here', adapter=AsyncWebhookAdapter(session))
+            async with aiohttp.ClientSession() as _session:
+                webhook = Webhook.from_url('url-here', adapter=AsyncWebhookAdapter(_session))
                 await webhook.send('Hello World', username='Foo')
 
     Or creating a webhook from an ID and token and using :doc:`req:index`:
@@ -573,6 +689,8 @@ async def foo():
 
     .. versionchanged:: 1.4
         Webhooks are now comparable and hashable.
+    .. versionchanged:: 2.0
+        Added support for forum channels, threads, components, the ability to edit attachments and to suppress notifications.
 
     Attributes
     ------------
@@ -602,36 +720,66 @@ async def foo():
     __slots__ = ('id', 'type', 'guild_id', 'channel_id', 'user', 'name',
                  'avatar', 'token', '_state', '_adapter')
 
-    def __init__(self, data, *, adapter, state=None):
-        self.id = int(data['id'])
-        self.type = try_enum(WebhookType, int(data['type']))
-        self.channel_id = utils._get_as_snowflake(data, 'channel_id')
-        self.guild_id = utils._get_as_snowflake(data, 'guild_id')
-        self.name = data.get('name')
-        self.avatar = data.get('avatar')
-        self.token = data.get('token')
-        self._state = state or _PartialWebhookState(adapter, self, parent=state)
-        self._adapter = adapter
+    @overload
+    def __init__(self, data: Union[PartialWebhookData, WebhookData], *, adapter: WebhookAdapter) -> None:
+        self.user: Optional[BaseUser]
+
+    @overload
+    def __init__(
+            self,
+            data: Union[PartialWebhookData, WebhookData],
+            *,
+            adapter: WebhookAdapter,
+            state: None = ...
+    ) -> None:
+        self.user: Optional[BaseUser]
+
+    @overload
+    def __init__(
+            self,
+            data: Union[PartialWebhookData, WebhookData],
+            *,
+            adapter: WebhookAdapter,
+            state: ConnectionState
+    ) -> None:
+        self.user: Optional[User]
+
+    def __init__(
+            self,
+            data: Union[PartialWebhookData, WebhookData],
+            *,
+            adapter: WebhookAdapter,
+            state: Optional[ConnectionState] = None
+    ) -> None:
+        self.id: int = int(data['id'])
+        self.type: WebhookType = try_enum(WebhookType, int(data['type']))
+        self.channel_id: Optional[int] = utils._get_as_snowflake(data, 'channel_id')
+        self.guild_id: Optional[int] = utils._get_as_snowflake(data, 'guild_id')
+        self.name: Optional[str] = data.get('name')
+        self.avatar: Optional[str] = data.get('avatar')
+        self.token: Optional[str] = data.get('token')
+        self._state: State = state or _PartialWebhookState(adapter, self, parent=state)
+        self._adapter: WebhookAdapter = adapter
         self._adapter._prepare(self)
 
         user = data.get('user')
         if user is None:
             self.user = None
         elif state is None:
-            self.user = BaseUser(state=None, data=user)
+            self.user = BaseUser(state=self._state, data=user)
         else:
-            self.user = User(state=state, data=user)
+            self.user: User = User(state=state, data=user)
 
-    def __repr__(self):
-        return '<Webhook id=%r>' % self.id
+    def __repr__(self) -> str:
+        return f'<Webhook id={self.id}>'
 
     @property
-    def url(self):
+    def url(self) -> str:
         """:class:`str` : Returns the webhook's url."""
-        return 'https://discord.com/api/webhooks/{}/{}'.format(self.id, self.token)
+        return f'{WebhookAdapter.BASE}/webhooks/{self.id}/{self.token}'
 
     @classmethod
-    def partial(cls, id, token, *, adapter):
+    def partial(cls, id: int, token: str, *, adapter: WebhookAdapter) -> Webhook:
         """Creates a partial :class:`Webhook`.
 
         Parameters
@@ -655,7 +803,7 @@ def partial(cls, id, token, *, adapter):
         if not isinstance(adapter, WebhookAdapter):
             raise TypeError('adapter must be a subclass of WebhookAdapter')
 
-        data = {
+        data: PartialWebhookData = {
             'id': id,
             'type': 1,
             'token': token
@@ -664,7 +812,7 @@ def partial(cls, id, token, *, adapter):
         return cls(data, adapter=adapter)
 
     @classmethod
-    def from_url(cls, url, *, adapter):
+    def from_url(cls, url: str, *, adapter: WebhookAdapter) -> Webhook:
         """Creates a partial :class:`Webhook` from a webhook URL.
 
         Parameters
@@ -688,7 +836,7 @@ def from_url(cls, url, *, adapter):
             A partial webhook is just a webhook object with an ID and a token.
         """
 
-        m = re.search(r'discord(?:app)?.com/api/webhooks/(?P<id>[0-9]{17,20})/(?P<token>[A-Za-z0-9\.\-\_]{60,68})', url)
+        m = WEBHOOK_URL_REGEX.search(url)
         if m is None:
             raise InvalidArgument('Invalid webhook URL given.')
         data = m.groupdict()
@@ -696,9 +844,9 @@ def from_url(cls, url, *, adapter):
         return cls(data, adapter=adapter)
 
     @classmethod
-    def _as_follower(cls, data, *, channel, user):
-        name = "{} #{}".format(channel.guild, channel)
-        feed = {
+    def _as_follower(cls, data, *, channel, user: BaseUser) -> Webhook:
+        name = f"{channel.guild} #{channel}"
+        feed: WebhookData = {
             'id': data['webhook_id'],
             'type': 2,
             'name': name,
@@ -707,6 +855,7 @@ def _as_follower(cls, data, *, channel, user):
             'user': {
                 'username': user.name,
                 'discriminator': user.discriminator,
+                'global_name': user.global_name,
                 'id': user.id,
                 'avatar': user.avatar
             }
@@ -716,12 +865,17 @@ def _as_follower(cls, data, *, channel, user):
         return cls(feed, adapter=AsyncWebhookAdapter(session=session))
 
     @classmethod
-    def from_state(cls, data, state):
-        session = state.http._HTTPClient__session
+    def from_state(cls, data: WebhookData, state: ConnectionState) -> Webhook:
+        session = state.http._HTTPClient__session # type: ignore
         return cls(data, adapter=AsyncWebhookAdapter(session=session), state=state)
+    
+    @classmethod
+    def from_oauth2(cls, data: WebhookData, client: OAuth2Client) -> Webhook:
+        session = client.http._OAuth2HTTPClient__session
+        return cls(data, adapter=AsyncWebhookAdapter(session=session))
 
     @property
-    def guild(self):
+    def guild(self) -> Optional[Guild]:
         """Optional[:class:`Guild`]: The guild this webhook belongs to.
 
         If this is a partial webhook, then this will always return ``None``.
@@ -729,8 +883,8 @@ def guild(self):
         return self._state._get_guild(self.guild_id)
 
     @property
-    def channel(self):
-        """Optional[:class:`TextChannel`]: The text channel this webhook belongs to.
+    def channel(self) -> Optional[Union[TextChannel, ForumChannel]]:
+        """Optional[:class:`TextChannel`, :class:`ForumChannel`]: The text or forum channel this webhook belongs to.
 
         If this is a partial webhook, then this will always return ``None``.
         """
@@ -738,12 +892,12 @@ def channel(self):
         return guild and guild.get_channel(self.channel_id)
 
     @property
-    def created_at(self):
+    def created_at(self) -> datetime:
         """:class:`datetime.datetime`: Returns the webhook's creation time in UTC."""
         return utils.snowflake_time(self.id)
 
     @property
-    def avatar_url(self):
+    def avatar_url(self) -> Asset:
         """:class:`Asset`: Returns an :class:`Asset` for the avatar the webhook has.
 
         If the webhook does not have a traditional avatar, an asset for
@@ -754,7 +908,12 @@ def avatar_url(self):
         """
         return self.avatar_url_as()
 
-    def avatar_url_as(self, *, format=None, size=1024):
+    def avatar_url_as(
+            self,
+            *,
+            format: Optional[Literal['webp', 'jpeg', 'jpg', 'png']] = None,
+            size: int = 1024
+    ):
         """Returns an :class:`Asset` for the avatar the webhook has.
 
         If the webhook does not have a traditional avatar, an asset for
@@ -796,7 +955,7 @@ def avatar_url_as(self, *, format=None, size=1024):
         url = '/avatars/{0.id}/{0.avatar}.{1}?size={2}'.format(self, format, size)
         return Asset(self._state, url)
 
-    def delete(self, *, reason=None):
+    def delete(self, *, reason: Optional[str] = None):
         """|maybecoro|
 
         Deletes this Webhook.
@@ -826,8 +985,8 @@ def delete(self, *, reason=None):
             raise InvalidArgument('This webhook does not have a token associated with it')
 
         return self._adapter.delete_webhook(reason=reason)
-
-    def edit(self, *, reason=None, **kwargs):
+    
+    def edit(self, *, reason: Optional[str] = None, **kwargs):
         """|maybecoro|
 
         Edits this Webhook.
@@ -858,7 +1017,7 @@ def edit(self, *, reason=None, **kwargs):
         if self.token is None:
             raise InvalidArgument('This webhook does not have a token associated with it')
 
-        payload = {}
+        payload: Dict[str, Any] = {}
 
         try:
             name = kwargs['name']
@@ -882,8 +1041,41 @@ def edit(self, *, reason=None, **kwargs):
 
         return self._adapter.edit_webhook(reason=reason, **payload)
 
-    def send(self, content=None, *, wait=False, username=None, avatar_url=None, tts=False,
-                                    file=None, files=None, embed=None, embeds=None, allowed_mentions=None):
+    @overload
+    def send(
+            self,
+            content: Optional[str] = None,
+            *, wait: Literal[False] = False,
+            **kwargs: Any
+    ) -> None: ...
+
+    @overload
+    def send(
+            self,
+            content: Optional[str] = None,
+            *, wait: Literal[True] = True,
+            **kwargs: Any
+    ) -> Coroutine[Any, Any, WebhookMessage]: ...
+
+    def send(
+            self,
+            content: Optional[str] = None,
+            *,
+            wait: bool = False,
+            thread_id: int = MISSING,
+            thread_name: str = MISSING,
+            username: str = MISSING,
+            avatar_url: Union[str, Asset] = MISSING,
+            tts: bool = False,
+            file: Optional[File] = MISSING,
+            files: Optional[Sequence[File]] = MISSING,
+            embed: Optional[Embed] = MISSING,
+            embeds: Optional[Sequence[Embed]] = MISSING,
+            components: Optional[List[Union[ActionRow, List[Union[Button, BaseSelect]]]]] = MISSING,
+            allowed_mentions: Optional[AllowedMentions] = MISSING,
+            suppress_embeds: bool = False,
+            suppress_notifications: bool = False
+    ) -> Union[WebhookMessage, Coroutine[Any, Any, WebhookMessage]]:
         """|maybecoro|
 
         Sends a message using the webhook.
@@ -892,13 +1084,18 @@ def send(self, content=None, *, wait=False, username=None, avatar_url=None, tts=
         not a coroutine.
 
         The content must be a type that can convert to a string through ``str(content)``.
-
+        
+        All parameters are optional
+        but at least one of ``content``, ``file``/``files``, ``embed``/``embeds`` or if possible ``components`` must be provided.
+        
+        If the webhook belongs to a :class:`ForumChannel` then either ``thread_id``(to send the message to an existing post)
+        or ``thread_name`` (to create a new post) must be provided.
+        
         To upload a single file, the ``file`` parameter should be used with a
         single :class:`File` object.
 
         If the ``embed`` parameter is provided, it must be of type :class:`Embed` and
-        it must be a rich embed type. You cannot mix the ``embed`` parameter with the
-        ``embeds`` parameter, which must be a :class:`list` of :class:`Embed` objects to send.
+        it must be a rich embed type..
 
         Parameters
         ------------
@@ -908,6 +1105,15 @@ def send(self, content=None, *, wait=False, username=None, avatar_url=None, tts=
             Whether the server should wait before sending a response. This essentially
             means that the return type of this function changes from ``None`` to
             a :class:`WebhookMessage` if set to ``True``.
+        thread_id: :class:`int`
+            Send a message to the specified thread/forum-post within a webhook's channel.
+            The thread/forum-post will automatically be unarchived.
+            
+            ..versionadded:: 2.0
+        thread_name: :class:`str`
+            :class:`.ForumChannel` webhooks only: Will create a new post with the webhook message will be the starter message.
+            
+            ..versionadded:: 2.0
         username: :class:`str`
             The username to send with this message. If no username is provided
             then the default username for the webhook is used.
@@ -927,11 +1133,29 @@ def send(self, content=None, *, wait=False, username=None, avatar_url=None, tts=
         embeds: List[:class:`Embed`]
             A list of embeds to send with the content. Maximum of 10. This cannot
             be mixed with the ``embed`` parameter.
+        components: List[Union[:class:`~discord.ActionRow`, List[Union[:class:`~discord.Button`, :ref:`Select <select-like-objects>`]]]]
+            A list of up to five :class:`~discord.ActionRow`s or :class:`list`,
+            each containing up to five :class:`~discord.Button` or one :ref:`Select <select-like-objects>` like object.
+            
+            .. note::
+                Due to discord limitations this can only be used when the Webhook was created by a bot.
+            
+            .. versionadded:: 2.0
         allowed_mentions: :class:`AllowedMentions`
             Controls the mentions being processed in this message.
 
             .. versionadded:: 1.4
-
+        suppress_embeds: :class:`bool`
+            Whether to suppress embeds send with the message, defaults to ``False``.
+            
+            .. versionadded:: 2.0
+        suppress_notifications: :class:`bool`
+            Whether to suppress desktop- & push-notifications for the message.
+            
+            Users will still see a ping-symbol when they are mentioned in the message.
+            
+            .. versionadded:: 2.0
+        
         Raises
         --------
         HTTPException
@@ -941,9 +1165,7 @@ def send(self, content=None, *, wait=False, username=None, avatar_url=None, tts=
         Forbidden
             The authorization token for the webhook is incorrect.
         InvalidArgument
-            You specified both ``embed`` and ``embeds`` or the length of
-            ``embeds`` was invalid or there was no token associated with
-            this webhook.
+            The length of ``embeds`` was invalid or there was no token associated with this webhook.
 
         Returns
         ---------
@@ -951,56 +1173,73 @@ def send(self, content=None, *, wait=False, username=None, avatar_url=None, tts=
             The message that was sent.
         """
 
-        payload = {}
         if self.token is None:
             raise InvalidArgument('This webhook does not have a token associated with it')
-        if files is not None and file is not None:
-            raise InvalidArgument('Cannot mix file and files keyword arguments.')
-        if embeds is not None and embed is not None:
-            raise InvalidArgument('Cannot mix embed and embeds keyword arguments.')
-
-        if embeds is not None:
-            if len(embeds) > 10:
-                raise InvalidArgument('embeds has a maximum of 10 elements.')
-            payload['embeds'] = [e.to_dict() for e in embeds]
-
-        if embed is not None:
-            payload['embeds'] = [embed.to_dict()]
-
-        if content is not None:
-            payload['content'] = str(content)
-
-        payload['tts'] = tts
-        if avatar_url:
-            payload['avatar_url'] = str(avatar_url)
-        if username:
-            payload['username'] = username
-
-        previous_mentions = getattr(self._state, 'allowed_mentions', None)
-
-        if allowed_mentions:
-            if previous_mentions is not None:
-                payload['allowed_mentions'] = previous_mentions.merge(allowed_mentions).to_dict()
-            else:
-                payload['allowed_mentions'] = allowed_mentions.to_dict()
-        elif previous_mentions is not None:
-            payload['allowed_mentions'] = previous_mentions.to_dict()
-
-        return self._adapter.execute_webhook(wait=wait, file=file, files=files, payload=payload)
+        
+        previous_allowed_mentions = getattr(self._state, 'allowed_mentions', None)
+        
+        if suppress_embeds or suppress_notifications:
+            flags = MessageFlags._from_value(0)
+            flags.suppress_embeds = suppress_embeds
+            flags.suppress_notifications = suppress_notifications
+        else:
+            flags = MISSING
+        
+        with handle_message_parameters(
+            content=content,
+            username=username,
+            avatar_url=avatar_url,
+            tts=tts,
+            flags=flags,
+            file=file,
+            files=files,
+            embed=embed,
+            embeds=embeds,
+            components=components,
+            allowed_mentions=allowed_mentions,
+            previous_allowed_mentions=previous_allowed_mentions,
+            thread_name=thread_name
+        ) as params:
+            return self._adapter.execute_webhook(
+                wait=wait,
+                thread_id=thread_id,
+                params=params
+            )
 
     def execute(self, *args, **kwargs):
         """An alias for :meth:`~.Webhook.send`."""
         return self.send(*args, **kwargs)
 
-    def edit_message(self, message_id, **fields):
+    def edit_message(
+            self,
+            message_id: int,
+            *,
+            content: Optional[str] = MISSING,
+            embed: Optional[Embed] = MISSING,
+            embeds: Optional[Sequence[Embed]] = MISSING,
+            components: Optional[List[Union[ActionRow, List[Union[Button, BaseSelect]]]]] = MISSING,
+            attachments: Optional[Sequence[Union[Attachment, File]]] = MISSING,
+            allowed_mentions: Optional[AllowedMentions] = MISSING,
+            suppress_embeds: Optional[bool] = MISSING
+    ):
         """|maybecoro|
 
         Edits a message owned by this webhook.
 
         This is a lower level interface to :meth:`WebhookMessage.edit` in case
         you only have an ID.
+        
+        .. warning::
+            Since API v10, the ``attachments`` (when passed) **must contain all attachments** that should be present after edit,
+            **including retained** and new attachments.
+            
+            As this requires to know the current attachments consider either storing the attachments that were sent with a message or
+            using a fetched version of the message to edit it.
 
         .. versionadded:: 1.6
+        
+        .. versionchanged:: 2.0
+            The ``suppress`` keyword-only parameter was renamed to ``suppress_embeds``.
 
         Parameters
         ------------
@@ -1008,14 +1247,34 @@ def edit_message(self, message_id, **fields):
             The message ID to edit.
         content: Optional[:class:`str`]
             The content to edit the message with or ``None`` to clear it.
-        embeds: List[:class:`Embed`]
-            A list of embeds to edit the message with.
         embed: Optional[:class:`Embed`]
-            The embed to edit the message with. ``None`` suppresses the embeds.
-            This should not be mixed with the ``embeds`` parameter.
+            The new embed to replace the original with.
+            Could be ``None`` to remove all embeds.
+        embeds: Optional[List[:class:`Embed`]]
+            A list containing up to 10 embeds. If ``None`` empty, all embeds will be removed.
+        components: List[Union[:class:`~discord.ActionRow`, List[Union[:class:`~discord.Button`, :ref:`Select <select-like-objects>`]]]]
+            A list of up to five :class:`~discord.ActionRow`s or :class:`list`,
+            each containing up to five :class:`~discord.Button` or one :ref:`Select <select-like-objects>` like object.
+            
+            .. note::
+                Due to discord limitations this can only be used when the webhook is owned by an application.
+            
+            .. versionadded:: 2.0
+        attachments: List[Union[:class:`Attachment`, :class:`File`]]
+            A list containing previous attachments to keep as well as new files to upload.
+            
+            When empty, all attachment will be removed.
+
+            .. note::
+
+                New files will always appear under existing ones.
+            
+            .. versionadded:: 2.0
         allowed_mentions: :class:`AllowedMentions`
             Controls the mentions being processed in this message.
             See :meth:`.abc.Messageable.send` for more information.
+        suppress_embeds: :class:`bool`
+            Whether to suppress embeds send with the message.
 
         Raises
         -------
@@ -1024,63 +1283,34 @@ def edit_message(self, message_id, **fields):
         Forbidden
             Edited a message that is not yours.
         InvalidArgument
-            You specified both ``embed`` and ``embeds`` or the length of
-            ``embeds`` was invalid or there was no token associated with
+            The length of ``embeds`` was invalid or there was no token associated with
             this webhook.
         """
 
-        payload = {}
-
         if self.token is None:
             raise InvalidArgument('This webhook does not have a token associated with it')
 
-        try:
-            content = fields['content']
-        except KeyError:
-            pass
-        else:
-            if content is not None:
-                content = str(content)
-            payload['content'] = content
-
-        # Check if the embeds interface is being used
-        try:
-            embeds = fields['embeds']
-        except KeyError:
-            # Nope
-            pass
-        else:
-            if embeds is None or len(embeds) > 10:
-                raise InvalidArgument('embeds has a maximum of 10 elements')
-            payload['embeds'] = [e.to_dict() for e in embeds]
-
-        try:
-            embed = fields['embed']
-        except KeyError:
-            pass
-        else:
-            if 'embeds' in payload:
-                raise InvalidArgument('Cannot mix embed and embeds keyword arguments')
-
-            if embed is None:
-                payload['embeds'] = []
-            else:
-                payload['embeds'] = [embed.to_dict()]
-
-        allowed_mentions = fields.pop('allowed_mentions', None)
         previous_mentions = getattr(self._state, 'allowed_mentions', None)
-
-        if allowed_mentions:
-            if previous_mentions is not None:
-                payload['allowed_mentions'] = previous_mentions.merge(allowed_mentions).to_dict()
-            else:
-                payload['allowed_mentions'] = allowed_mentions.to_dict()
-        elif previous_mentions is not None:
-            payload['allowed_mentions'] = previous_mentions.to_dict()
-
-        return self._adapter.edit_webhook_message(message_id, payload=payload)
-
-    def delete_message(self, message_id):
+        
+        if suppress_embeds:
+            flags = MessageFlags._from_value(0)
+            flags.suppress_embeds = suppress_embeds
+        else:
+            flags = MISSING
+        
+        with handle_message_parameters(
+            content=content,
+            embed=embed,
+            embeds=embeds,
+            components=components,
+            attachments=attachments,
+            allowed_mentions=allowed_mentions,
+            previous_allowed_mentions=previous_mentions,
+            flags=flags
+        ) as params:
+            return self._adapter.edit_webhook_message(message_id, payload=params)
+
+    def delete_message(self, message_id: int, /):
         """|maybecoro|
 
         Deletes a message owned by this webhook.
diff --git a/discord/welcome_screen.py b/discord/welcome_screen.py
new file mode 100644
index 00000000..f175184f
--- /dev/null
+++ b/discord/welcome_screen.py
@@ -0,0 +1,126 @@
+from typing import Optional, List, Union, TYPE_CHECKING
+
+from .partial_emoji import PartialEmoji
+
+if TYPE_CHECKING:
+    from .abc import GuildChannel
+
+__all__ = (
+    'WelcomeScreenChannel',
+    'WelcomeScreen'
+)
+
+
+class WelcomeScreenChannel:
+    r"""Represents a channel shown in a welcome screen.
+
+    Attributes
+    -----------
+    channel: :class:`~discord.Snowflake`
+        The channel the welcome screen channel belongs to
+    description: :class:`str`
+        The description of the welcome screen channel
+    emoji: Optional[:class:`~discord.PartialEmoji`]
+        The emoji that is shown on the left side of the welcome screen channel
+    """
+    def __init__(self, channel: 'GuildChannel', description: str = None, emoji: Optional[Union[PartialEmoji, str]] = None):
+        """
+        Represents a channel shown in a welcome screen.
+
+        Parameters
+        -----------
+        channel: :class:`~discord.Snowflake`
+            The channel the welcome screen channel belongs to
+        description: :class:`str`
+            The description of the welcome screen channel
+        emoji: Optional[Union[:class:`~discord.PartialEmoji`, :class:`str`]
+            The emoji that is shown on the left side of the welcome screen channel
+        """
+        try:
+            self._state = channel._state
+        except AttributeError:
+            pass
+        self.channel = channel
+        self.description: Optional[str] = description
+        if emoji and isinstance(emoji, str):
+            emoji = PartialEmoji.from_string(emoji)
+        self.emoji: Optional[PartialEmoji] = emoji
+
+    @classmethod
+    def _from_data(cls, state, guild, data):
+        channel = guild.get_channel(int(data['channel_id']))
+        description = data.get('description', None)
+        custom_emoji = data.get('emoji_id', None)
+        if custom_emoji:
+            emoji = state.get_emoji(int(custom_emoji))
+        else:
+            emoji_name = data.get('emoji_name', None)
+            if emoji_name:
+                emoji = PartialEmoji(name=emoji_name)
+            else:
+                emoji = None
+        return cls(channel=channel, description=description, emoji=emoji)
+
+    def to_dict(self):
+        base = {'channel_id': str(self.channel.id)}
+        if self.description:
+            base['description'] = str(self.description)
+        if self.emoji:
+            base['emoji_name'] = self.emoji.name
+            if self.emoji.id:
+                base['emoji_id'] = self.emoji.id
+        return base
+
+
+class WelcomeScreen:
+    """
+    Represents a welcome screen for a guild returned by :meth:`~Guild.welcome_screen`.
+
+    .. warning::
+        Do not initialize this class directly. Use :meth:`~Guild.welcome_screen` instead.
+
+    Attributes
+    -----------
+    guild: :class:`~discord.Guild`
+        The guild the welcome screen belongs to
+    description: :class:`str`
+        The description of the welcome screen
+    welcome_channels: List[:class:`WelcomeScreenChannel`]
+    """
+    def __init__(self, state, guild, data):
+        self._state = state
+        self.guild = guild
+        self.description = data.get('description', None)
+        self.welcome_channels = [WelcomeScreenChannel._from_data(state=state, guild=guild, data=c) for c in data.get('welcome_channels', [])]
+
+    def _update(self, data):
+        self.description = data.get('description', self.description)
+        self.welcome_channels = [WelcomeScreenChannel._from_data(state=self._state, guild=self.guild, data=c) for c in data.get('welcome_channels', [])]
+
+    async def edit(self, *, reason: str = None, **fields):
+        try:
+            enabled: bool = fields['enabled']
+        except KeyError:
+            pass
+        else:
+            if enabled is not None:
+                fields['enabled'] = bool(enabled)
+
+        try:
+            welcome_channels: Optional[List[WelcomeScreenChannel]] = fields['welcome_channels']
+        except KeyError:
+            pass
+        else:
+            if welcome_channels is not None:
+                fields['welcome_channels'] = [wc.to_dict() for wc in welcome_channels]
+
+        try:
+            description: Optional[str] = fields['description']
+        except KeyError:
+            pass
+        else:
+            if description is not None:
+                fields['description'] = str(description)
+        data = await self._state.http.edit_welcome_screen(guild_id=self.guild.id, reason=reason, **fields)
+        self._update(data)
+        return self
diff --git a/discord/widget.py b/discord/widget.py
index 252cebe2..4353c89e 100644
--- a/discord/widget.py
+++ b/discord/widget.py
@@ -3,7 +3,7 @@
 """
 The MIT License (MIT)
 
-Copyright (c) 2015-present Rapptz
+Copyright (c) 2015-2021 Rapptz & (c) 2021-present mccoderpy
 
 Permission is hereby granted, free of charge, to any person obtaining a
 copy of this software and associated documentation files (the "Software"),
@@ -84,9 +84,14 @@ def created_at(self):
         """:class:`datetime.datetime`: Returns the channel's creation time in UTC."""
         return snowflake_time(self.id)
 
+
 class WidgetMember(BaseUser):
     """Represents a "partial" member of the widget's guild.
 
+    .. versionchanged:: 2.0
+        The :attr:`name` attribute was renamed to :attr:`username` due to the (upcoming)
+        :dis-gd:`username changes <username>`.
+
     .. container:: operations
 
         .. describe:: x == y
@@ -103,16 +108,29 @@ class WidgetMember(BaseUser):
 
         .. describe:: str(x)
 
-            Returns the widget member's `name#discriminator`.
+            Returns the :attr:`username` if :attr:`is_migrated` is true, else the user's name with discriminator.
+
+            .. note::
+
+                When the migration is complete, this will always return the :attr:`username`.
 
     Attributes
     -----------
     id: :class:`int`
         The member's ID.
-    name: :class:`str`
+    username: :class:`str`
         The member's username.
+    global_name: Optional[:class:`str`]
+        The member's global name if set.
+        In the client UI this is referred to as "Display Name".
+
+        .. versionadded:: 2.0
     discriminator: :class:`str`
         The member's discriminator.
+
+        .. important::
+            This will be removed in a future API version.
+            Read more about it :dis-gd:`here <usernames>`.
     bot: :class:`bool`
         Whether the member is a bot.
     status: :class:`Status`
@@ -158,6 +176,7 @@ def display_name(self):
         """:class:`str`: Returns the member's display name."""
         return self.nick or self.name
 
+
 class Widget:
     """Represents a :class:`Guild` widget.
 
diff --git a/docs/Interactions/application-commands.rst b/docs/Interactions/application-commands.rst
new file mode 100644
index 00000000..7b389f89
--- /dev/null
+++ b/docs/Interactions/application-commands.rst
@@ -0,0 +1,101 @@
+.. currentmodule:: discord
+
+
+ApplicationCommand
+~~~~~~~~~~~~~~~~~~~
+
+.. attributetable:: ApplicationCommand
+
+.. autoclass:: ApplicationCommand()
+    :exclude-members: error
+    :members:
+
+    .. automethod:: error
+        :decorator:
+
+SlashCommand
+~~~~~~~~~~~~~
+
+.. attributetable:: SlashCommand
+
+.. autoclass:: SlashCommand()
+    :members:
+    :inherited-members:
+    :exclude-members: autocomplete_callback
+
+    .. automethod:: autocomplete_callback
+        :decorator:
+
+
+.. attributetable:: SubCommand
+
+.. autoclass:: SubCommand()
+    :members:
+    :exclude-members: autocomplete_callback, error
+
+    .. automethod:: autocomplete_callback
+        :decorator:
+
+    .. automethod:: error
+        :decorator:
+
+SlashCommandOption
+~~~~~~~~~~~~~~~~~~~
+
+.. attributetable:: SlashCommandOption
+
+.. autoclass:: SlashCommandOption()
+    :members:
+    :inherited-members:
+
+SlashCommandOptionChoice
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. attributetable:: SlashCommandOptionChoice
+
+.. autoclass:: SlashCommandOptionChoice()
+    :members:
+    :inherited-members:
+
+UserCommand
+~~~~~~~~~~~~~
+
+.. attributetable:: UserCommand
+
+.. autoclass:: UserCommand()
+    :members:
+    :inherited-members:
+
+MessageCommand
+~~~~~~~~~~~~~~~
+
+.. attributetable:: MessageCommand
+
+.. autoclass:: MessageCommand()
+    :members:
+    :inherited-members:
+
+GuildAppCommandPermissions
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. attributetable:: GuildAppCommandPermissions
+
+.. autoclass:: GuildAppCommandPermissions()
+    :members:
+
+AppCommandPermissions
+~~~~~~~~~~~~~~~~~~~~~
+
+.. attributetable:: AppCommandPermission
+
+.. autoclass:: AppCommandPermission()
+    :members:
+
+
+Miscellaneous
+~~~~~~~~~~~~~
+
+.. attributetable:: Mentionable
+
+.. autoclass:: Mentionable()
+    :members:
\ No newline at end of file
diff --git a/docs/Interactions/data-models.rst b/docs/Interactions/data-models.rst
new file mode 100644
index 00000000..95678783
--- /dev/null
+++ b/docs/Interactions/data-models.rst
@@ -0,0 +1,68 @@
+.. currentmodule:: discord
+
+BaseInteraction
+~~~~~~~~~~~~~~~
+
+.. attributetable:: BaseInteraction
+
+.. autoclass:: BaseInteraction()
+    :members:
+    :exclude-members: from_type
+
+ApplicationCommandInteraction
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. attributetable:: ApplicationCommandInteraction
+
+.. autoclass:: ApplicationCommandInteraction()
+    :members:
+    :inherited-members:
+    :exclude-members: from_type
+
+ComponentInteraction
+~~~~~~~~~~~~~~~~~~~~~
+
+.. attributetable:: ComponentInteraction
+
+.. autoclass:: ComponentInteraction()
+    :members:
+    :inherited-members:
+    :exclude-members: from_type
+
+AutocompleteInteraction
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. attributetable:: AutocompleteInteraction
+
+.. autoclass:: AutocompleteInteraction()
+    :members:
+    :inherited-members:
+    :exclude-members: defer, respond, edit, respond_with_modal, from_type, get_followup, message_is_hidden, messages
+
+ModalSubmitInteraction
+~~~~~~~~~~~~~~~~~~~~~~~
+
+.. attributetable:: ModalSubmitInteraction
+
+.. autoclass:: ModalSubmitInteraction
+    :members:
+    :inherited-members:
+    :exclude-members: defer, respond_with_modal, from_type
+
+
+Localizations
+~~~~~~~~~~~~~~~
+
+.. attributetable:: Localizations
+
+.. autoclass:: Localizations()
+    :members:
+    :inherited-members:
+
+InteractionDataOption
+~~~~~~~~~~~~~~~~~~~~~~~
+
+.. attributetable:: discord.interactions.InteractionDataOption
+
+.. autoclass:: discord.interactions.InteractionDataOption()
+    :members:
diff --git a/docs/Interactions/index.rst b/docs/Interactions/index.rst
new file mode 100644
index 00000000..7a7b836b
--- /dev/null
+++ b/docs/Interactions/index.rst
@@ -0,0 +1,17 @@
+.. _interactions:
+
+``Interactions``
+=================
+
+.. note::
+    This part of the docs is still in work! and many things are uncompleted or completely missing.
+
+``discord.py-message-components`` support for all the beautifully interactions by discord.
+Here you find the most staff related to interactions.
+
+.. toctree::
+    :maxdepth: 1
+
+    application-commands
+    message-components
+    data-models
diff --git a/docs/Interactions/message-components.rst b/docs/Interactions/message-components.rst
new file mode 100644
index 00000000..8587d724
--- /dev/null
+++ b/docs/Interactions/message-components.rst
@@ -0,0 +1,106 @@
+.. currentmodule:: discord
+
+ActionRow
+~~~~~~~~~~
+
+.. attributetable:: ActionRow
+
+.. autoclass:: ActionRow()
+    :members:
+
+-----------------------
+
+Button
+~~~~~~~
+
+.. attributetable:: Button
+
+.. autoclass:: Button()
+    :members:
+    :inherited-members:
+
+-----------------------
+
+.. _select-like-objects:
+
+SelectMenu
+~~~~~~~~~~~
+
+.. attributetable:: SelectMenu
+
+.. autoclass:: SelectMenu()
+    :members:
+    :inherited-members:
+
+SelectOption
+~~~~~~~~~~~~~
+
+.. attributetable:: SelectOption
+
+.. autoclass:: SelectOption()
+    :members:
+
+SelectDefaultValue
+~~~~~~~~~~~~~~~~~~~~
+
+.. attributetable:: SelectDefaultValue
+
+.. autoclass:: SelectDefaultValue()
+    :members:
+
+UserSelect
+~~~~~~~~~~~
+
+.. attributetable:: UserSelect
+
+.. autoclass:: UserSelect()
+    :members:
+    :inherited-members:
+
+RoleSelect
+~~~~~~~~~~~
+
+.. attributetable:: RoleSelect
+
+.. autoclass:: RoleSelect()
+    :members:
+    :inherited-members:
+
+MentionableSelect
+~~~~~~~~~~~~~~~~~~
+
+.. attributetable:: MentionableSelect
+
+.. autoclass:: MentionableSelect()
+    :members:
+    :inherited-members:
+
+ChannelSelect
+~~~~~~~~~~~~~~
+
+.. attributetable:: ChannelSelect
+
+.. autoclass:: ChannelSelect()
+    :members:
+    :inherited-members:
+
+----------------------------
+
+Modal
+~~~~~~
+
+.. attributetable:: Modal
+
+.. autoclass:: Modal()
+    :members:
+    :inherited-members:
+
+
+TextInput
+~~~~~~~~~~
+
+.. attributetable:: TextInput
+
+.. autoclass:: TextInput()
+    :members:
+    :inherited-members:
diff --git a/docs/Makefile b/docs/Makefile
index d4bb2cbb..1408f39d 100644
--- a/docs/Makefile
+++ b/docs/Makefile
@@ -18,3 +18,6 @@ help:
 # "make mode" option.  $(O) is meant as a shortcut for $(SPHINXOPTS).
 %: Makefile
 	@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
+
+livehtml:
+	sphinx-autobuild "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
\ No newline at end of file
diff --git a/docs/_build/doctrees/components.doctree b/docs/_build/doctrees/components.doctree
deleted file mode 100644
index 4cb23bf4..00000000
Binary files a/docs/_build/doctrees/components.doctree and /dev/null differ
diff --git a/docs/_build/doctrees/environment.pickle b/docs/_build/doctrees/environment.pickle
deleted file mode 100644
index 31145a19..00000000
Binary files a/docs/_build/doctrees/environment.pickle and /dev/null differ
diff --git a/docs/_build/doctrees/index.doctree b/docs/_build/doctrees/index.doctree
deleted file mode 100644
index d9a727ea..00000000
Binary files a/docs/_build/doctrees/index.doctree and /dev/null differ
diff --git a/docs/_build/doctrees/interaction.doctree b/docs/_build/doctrees/interaction.doctree
deleted file mode 100644
index 1daaa3c7..00000000
Binary files a/docs/_build/doctrees/interaction.doctree and /dev/null differ
diff --git a/docs/_build/html/_sources/components.rst.txt b/docs/_build/html/_sources/components.rst.txt
deleted file mode 100644
index 09e192d8..00000000
--- a/docs/_build/html/_sources/components.rst.txt
+++ /dev/null
@@ -1,173 +0,0 @@
-.. discord.py-message-components documentation master file, created by
-   sphinx-quickstart on Sat Jun 26 14:55:47 2021.
-   You can adapt this file completely to your liking, but it should at least
-   contain the root `toctree` directive.
-
-Components
-==========
-
-.. _buttoncolor:
-
-:class:`discord.ButtonColor`
-============================
-    * ``blurple`` = 1
-    * ``grey`` = 2
-    * ``green`` = 3
-    * ``red`` = 4
-    * ``grey_url`` (navigates to an URL) = 5
-
-.. _actionrow:
-
-:class:`discord.ActionRow(*args, **kwargs)`
-===========================================
-
-Represents an ``ActionRow``-Part for the components of an :class:`discord.Message`
-
-.. note::
-
-    You could use an :class:`list` instead of this but you dont have the functions and oarameters of this class then.
-
-.. _actionrow-attributes:
-
-Attributes
-----------
-
-    * :attr:`*args`: [Union[:class:`Button`, :class:`SelectionMenu`]]
-        An array of :class:`Button`/s and/or :class:`SelectionMenu`/s.
-
-    .. _actionrow-force:
-
-    * :attr:`force`: Optional[Bool]
-        When set to ``True`` an Empty :class:`ActionRow` will be ignored
-
-    .. note::
-        For more information about ActionRow's visit the `Discord-API Documentation <https://discord.com/developers/docs/interactions/message-components#actionrow>`_.
-
-.. _actionrow-methodes:
-
-Methodes
---------
-    .. _actionrow-sendable:
-
-    :meth:`sendable` -> Dict
-        Makes the :class:`ActionRow` sendable to discord.
-
-    .. _actionrow-disable_all_buttons:
-
-    :meth:`disable_all_buttons()`
-        Disable all objects's of type :class:`discord.Button` in this :class:`ActionRow`.
-        
-        :return: :class:`discord.ActionRow`
-    
-    .. _actionrow-disable_all_buttons_if:
-
-    :meth:`disable_all_buttons_if(check: Union[Bool, Callable], **kwargs)`
-        Disable all :class:`discord.Button` in this :class:`ActionRow` if the passed :attr:`check` ``True``.
-
-        **Parameters**
-
-            * :attr:`check`: Union[Bool, Callable]
-                could be an :class:`bool` or usually any :obj:`Callable` that returns an :class:`bool`
-            
-            * :attr:`**kwargs`
-                :obj:`kwargs` that should passed in to the :attr:`check` if it is an :obj:`Callable`
-
-        :return: :class:`ActionRow`
-
-.. _button:
-
-:class:`discord.Button(**kwargs)`
-=================================
-
-Represents an ``Discord-Button``
-
-.. note::
-    For more information Discord-Button's visit the `Discord-API Documentation <https://discord.com/developers/docs/interactions/message-components#buttons>`_.
-
-.. _button-attributes:
-
-Attributes
-----------
-
-    .. _button-label:
-
-    :attr:`label`: :class:`str`
-        The Text displayed in discord on the Button. Maximal lenght is 80 Chars.
-    
-    .. _button-custom_id:
-
-    :attr:`custom_id`: Union[:class:`str`, :class:`int`]
-        The custom_id discord send us when a User press the Button. The max. lenght of this is 100.
-    
-    .. _button-style:
-
-    :attr:`style`: Union[:class:`ButtonColor`, :class:`ButtonStyle`, Any[1, 2, 3, 4, 5]]
-        The Style of the Button.
-
-        .. note::
-            To get more infos about the styles wisit
-            `the Discord-API Documentation <https://discord.com/developers/docs/interactions/message-components#buttons-button-styles>`_.
-
-    .. _button-emoji:
-
-    :attr:`emoji`: Optional[Union[:class:`discord.PartialEmoji`, :class:`discord.Emoji`, :class:`str`]]
-        The Emoji that will be displayed on the left side of the Button.
-
-    .. _button-url:
-
-    :attr:`url`: Optional[:class:`str`]
-        The URL the Button links too.
-
-        .. note::
-            if you set this, the :attr:`style` will automaticly set to :class:`ButtonStyle.Link_Button`
-
-        .. warning::
-            
-            You cant pass an :attr:`custom_id` and a :attr:`url` beacuse discord dont send anything when clicking on an ``URL-Button`` so it dont accept both; :attr:`url`/ButtonStyle.Link_Button and :attr:`custom_id`!
-    
-    .. _button-disabled:
-
-    :attr:`disabled`: :class:`Bool`
-        Whether the Button is disabled; defauld False.
-
-.. _button-methodes:
-
-Methodes
---------
-
-    .. _button-disable_if:
-
-    :meth:`disable_if`
-    
-    Disable the :class:`Button` if the passed :attr:`check` returns ``True``.
-        * :attr:`check`: typing.Union[bool, typing.Callable]
-            Could be an :class:`bool` or usually any :class:`Callable` that returns an :class:`bool`
-        * :attr:`**kwargs`: Any[SupportsIndex]
-            Arguments that should passed in to the :attr:`check` if it is an :class:`Callable`
-
-        :return: :class:`discord.Button`
-    
-    .. _button-set_color_if:
-
-    :meth:`set_color_if`
-
-    Sets the Color(Style) of an :class:`discord.Button` to the provided :attr:`color` if the passed :attr:`check` returns ``True``.
-        
-        * :attr:`check`: could be an :class:`bool` or usaly any :obj:`Callable` that returns an :class:`bool`
-        
-        * :attr:`color`: the Color(Style) that should set if the :attr:`check` returns ``True``
-    
-        * :attr:`**kwargs`: ``kwargs`` that should passed in to the :attr:`check` if it is an :class:`Callable`
-
-        :return: :class:`discord.Button`
-
-.. toctree::   
-   :maxdepth: 3
-   :caption: Contents: 
-
-Indices and tables
-~~~~~~~~~~~~~~~~~~
-
-* :ref:`genindex`
-* :ref:`modindex`
-* :ref:`search`
diff --git a/docs/_build/html/_sources/index.rst.txt b/docs/_build/html/_sources/index.rst.txt
deleted file mode 100644
index 4d4dab6d..00000000
--- a/docs/_build/html/_sources/index.rst.txt
+++ /dev/null
@@ -1,164 +0,0 @@
-.. discord.py-message-components documentation master file, created by
-   sphinx-quickstart on Sat Jun 26 14:55:47 2021.
-   You can adapt this file completely to your liking, but it should at least
-   contain the root `toctree` directive.
-
-Welcome to discord.py-message-component's documentation!
-=========================================================
-
-.. image:: https://cdn.discordapp.com/attachments/852872100073963532/854711446767796286/discord.py-message-components.png
-    :target: https://pypi.org/project/discord.py-message-components
-    :alt: Name of the project
-            
-.. image:: https://discord.com/api/guilds/852871920411475968/embed.png
-  :target: https://discord.gg/sb69muSqsg
-  :alt: Discord Server Invite
-
-.. image:: https://img.shields.io/pypi/v/discord.py-message-components.svg
-  :target: https://pypi.python.org/pypi/discord.py-message-components
-  :alt: PyPI version info
-
-.. image:: https://img.shields.io/pypi/pyversions/discord.py-message-components.svg
-  :target: https://pypi.python.org/pypi/discord.py-message-components
-  :alt: PyPI supported Python versions
-  
-.. image:: https://static.pepy.tech/personalized-badge/discord-py-message-components?period=total&units=international_system&left_color=grey&right_color=green&left_text=Downloads
-  :target: https://pepy.tech/project/discord.py-message-components
-  :alt: Total downloads for the project
-
-.. image:: https://readthedocs.org/projects/discordpy-message-components/badge/?version=latest
-  :target: https://discordpy-message-components.readthedocs.io/en/latest/
-  :alt: Documentation Status
-
-The Original `discord.py <https://pypi.org/project/discord.py>`_ Library made by `Rapptz <https://github.com/Rapptz>`_ with implementation of the `Discord-Message-Components <https://discord.com/developers/docs/interactions/message-components>`_ by `mccoderpy <https://github.com/mccoderpy/>`_
-
-- `read the docs <https://discordpy-message-components.readthedocs.io/en/latest/>`_
-
-Installing:
-___________
-
-**Python 3.5.3 or higher is required**
-
-first uninstall the original `discord.py <https://pypi.org/project/discord.py>`_ Library:
-
-.. code:: sh
-
-    # Linux/macOS
-    python3 -m pip uninstall discord.py
-
-    # Windows
-    py -3 -m pip uninstall discord.py
-
-then install `this Library <https://pypi.org/project/discord.py-message-components>`_ using:
-
-.. code:: sh
-
-    # Linux/macOS
-    python3 -m pip install -U discord.py-message-components
-
-    # Windows
-    py -3 -m pip install -U discord.py-message-components
-
-
-
-quickstart
-__________
-
-sending-buttons
-~~~~~~~~~~~~~~~~
-
-.. code-block:: python
-
-   import discord
-   from discord.ext import commands
-   from discord.components import Button, ButtonColor
-
-
-   client = commands.Bot(command_prefix=commands.when_mentioned_or('!'))
-
-
-   @client.command()
-   async def buttons(ctx):
-      await ctx.send('Hey here are some Buttons', components=[[
-         Button(label="Hey i\'m a red Button",
-                  custom_id="this is an custom_id",
-                  style=ButtonColor.red),
-         Button(label="Hey i\'m a green Button",
-                  custom_id="this is an custom_id",
-                  style=ButtonColor.green),
-         Button(label="Hey i\'m a blue Button",
-                  custom_id="this is an custom_id",
-                  style=ButtonColor.blurple),
-         Button(label="Hey i\'m a grey Button",
-                  custom_id="this is an custom_id",
-                  style=ButtonColor.grey),
-         Button(label="Hey i\'m a URL Button",
-                  url="https://pypi.org/project/discord.py-message-components",
-                  style=ButtonColor.grey_url)
-      ]])
-
-   client.run('Your Bot-Token')
-
-
-respond to an button when he pressed by a user
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-         
-.. code-block:: python
-
-   import discord
-   from discord.ext import commands
-   from discord.components import Button, ButtonColor
-
-
-   client = commands.Bot(command_prefix=commands.when_mentioned_or('!'))
-
-
-   @client.command()
-   async def buttons(ctx):
-      msg_with_buttons = await ctx.send('Hey here are some Buttons', components=[[
-          Button(label="Hey i\'m a red Button",
-                 custom_id="red",
-                 style=ButtonColor.red),
-          Button(label="Hey i\'m a green Button",
-                 custom_id="green",
-                 style=ButtonColor.green),
-          Button(label="Hey i\'m a blue Button",
-                 custom_id="blue",
-                 style=ButtonColor.blurple),
-          Button(label="Hey i\'m a grey Button",
-                 custom_id="grey",
-                 style=ButtonColor.grey)
-      ]])
-      
-      def check_button(i: discord.Interaction, b: discord.ButtonClick):
-          return i.author == ctx.author and i.message == msg_with_buttons
-      
-      interaction, button = await client.wait_for('button_click', check=check_button)
-
-      embed = discord.Embed(title='You pressed an Button',
-      description=f'You pressed a {button.custom_id} button.',
-      color=discord.Color.random()) 
-      await interaction.respond(embed=embed)
-      
-   client.run('Your Bot-Token')
-
-.. note:: 
-
-   You could set the parameter :attr:`hidden` in the respond to ``True`` to make the message ephemeral.
-   Visit `discord.Interaction.respond <./interaction.html#interaction-respond>`_ for more information about :meth:`respond()`.
-
-
-.. toctree:: 
-   :maxdepth: 3
-   :caption: Contents: 
-
-   components.rst
-   interaction.rst
-
-
-Indices and tables
-__________________
-
-* :ref:`genindex`
-* :ref:`modindex`
-* :ref:`search`
diff --git a/docs/_build/html/_sources/interaction.rst.txt b/docs/_build/html/_sources/interaction.rst.txt
deleted file mode 100644
index 42ba9771..00000000
--- a/docs/_build/html/_sources/interaction.rst.txt
+++ /dev/null
@@ -1,107 +0,0 @@
-.. discord.py-message-components documentation master file, created by
-   sphinx-quickstart on Sat Jun 26 14:55:47 2021.
-   You can adapt this file completely to your liking, but it should at least
-   contain the root `toctree` directive.
-
-Interaction
-===========
-
-:ref:`Hallo <interaction-respond>`
-
-:class:`discord.Interaction`
-____________________________
-
-Represents an interaction createt in discord like click an :class:`discord.Button` or select an option of :class:`discord.SelectionMenu`
-   
-.. note::
-   For more informations about Interactions visit the Documentation of the `Discord-API <https://discord.com/developers/docs/interactions/slash-commands#interaction-object>`_
-   
-.. warning::
-   Do not initiate this Class manually
-   
-Attributes
-----------
-
-   .. _interaction-author:
-
-   :attr:`author`: :class:`discord.abc.User`
-      A :class:`Member` that invoked the interaction. If :attr:`channel` is a
-      private channel or the user has left the guild, then it is a :class:`User` instead.
-   
-   .. _interaction-message:
-
-   :attr:`message`: :class:`discord.Message`
-      The message the component was attachet to.
-      This will be equal to ``None`` if the :attr:`component_type` is ``None`` or the message the component is attached to is ``emphemberal``.
-
-      .. note::
-         In this version, this parameter should alwasys be an object of type :class:`discord.Message`
-         (or ``None`` if the message is emphemberal) beacuse it only gets initiatet when the interaction_type is highter than 2
-
-   .. _interaction-channel:
-
-   :attr:`channel`: Union[:class:`discord.TextChannel`, :class:`discord.DMChannel`]
-      The Channel the interaction was createt in this is aiter an object of :class:`discord.TextChannel` if it's
-      inside a guild else it's an object of type :class:`discord.DMChannel`.
-   
-   .. _interaction-guild:
-
-   :attr:`guild`: Union[:class:`discord.Guild`, :class:`None`]
-      The guild asotiatet with the interaction; aiter an object of type :class:`discord.Guild`,
-      except the interaction was inside an dm-channel then this would be equal to ``None``
-   
-   .. _interaction-component:
-   
-   :attr:`component`: Union[:class:`ButtonClick`, :class:`SelectionSelect`]
-      The component that invoked this interaction: Aiter an object of type :class:`ButtonClick` or :class:`SelectionSelect`
-         
-      .. note::
-         If this is passed in an ``[on_]button_click`` or ``[on_]selection_select`` Event there wuild be a second parameter that includes this attribute.
-
-Methodes
---------
-
-   .. _interaction-defer:
-
-   :meth:`defer`: None
-      'Defers' the response, showing a loading state to the use.
-
-      .. important::
-         If you dont respond with an message using :meth:`respond` 
-         or edit the original message using :meth:`edit` within less than 3 seconds,
-         discord will indicates that the interaction failed and the interaction-token will be invalidated.
-         To provide this us this method
-
-      .. note::
-         A Token will be Valid for 15 Minutes so you could edit the original :attr:`message` with :meth:`edit`, :meth:`respond` or doing anything other with this interaction for 15 minutes.
-         After that time you have to edit the original message with the Methode :meth:`edit` of the :attr:`message` and sending new messages with the :meth:`send` Methode of :attr:`channel`
-         (you could not do this hidden as it isn't an respond anymore and also you could not pass more than one :class:`Embed`)
-   
-   .. _interaction-respond:
-
-   :meth:`respond`: Union[:class:`discord.Message`, :class:`discord.EphemeralMessage`] 
-      You could pass the same Paramerts as using :meth:`discord.Messageable.send` but there are two more optional:
-            
-      * :attr:`embeds` Optional[List[discord.Embed]]
-         An :class:`list` containing up to 10 Embeds that should send with the respond.
-            
-      * :attr:`hidden` Optional[Bool]
-         If set to ``True``, the message will be only vible for the :attr:`author` of the Interaction and will disapears  if the :attr:`author` click on ``delete this message`` or reloads the client.
-               
-         .. note::
-            If you send an ``hidden`` (emphemberal)-respond, discord dont returns any data like an message you could edit,
-            **but** you could resive Interactions when the Author interact with an component
-
-      Responds to an interaction by sending a message that can be made visible only to the person who invoked the interaction by setting the :attr:`hidden` to ``True``.
-
-
-.. toctree:: 
-   :maxdepth: 3
-   :caption: Contents: 
-
-Indices and tables
-__________________
-
-* :ref:`genindex`
-* :ref:`modindex`
-* :ref:`search`
diff --git a/docs/_build/html/_static/alabaster.css b/docs/_build/html/_static/alabaster.css
deleted file mode 100644
index 8c8c06d2..00000000
--- a/docs/_build/html/_static/alabaster.css
+++ /dev/null
@@ -1,701 +0,0 @@
-@import url("basic.css");
-
-/* -- page layout ----------------------------------------------------------- */
-
-body {
-    font-family: Georgia, serif;
-    font-size: 17px;
-    background-color: #fff;
-    color: #000;
-    margin: 0;
-    padding: 0;
-}
-
-
-div.document {
-    width: 940px;
-    margin: 30px auto 0 auto;
-}
-
-div.documentwrapper {
-    float: left;
-    width: 100%;
-}
-
-div.bodywrapper {
-    margin: 0 0 0 220px;
-}
-
-div.sphinxsidebar {
-    width: 220px;
-    font-size: 14px;
-    line-height: 1.5;
-}
-
-hr {
-    border: 1px solid #B1B4B6;
-}
-
-div.body {
-    background-color: #fff;
-    color: #3E4349;
-    padding: 0 30px 0 30px;
-}
-
-div.body > .section {
-    text-align: left;
-}
-
-div.footer {
-    width: 940px;
-    margin: 20px auto 30px auto;
-    font-size: 14px;
-    color: #888;
-    text-align: right;
-}
-
-div.footer a {
-    color: #888;
-}
-
-p.caption {
-    font-family: inherit;
-    font-size: inherit;
-}
-
-
-div.relations {
-    display: none;
-}
-
-
-div.sphinxsidebar a {
-    color: #444;
-    text-decoration: none;
-    border-bottom: 1px dotted #999;
-}
-
-div.sphinxsidebar a:hover {
-    border-bottom: 1px solid #999;
-}
-
-div.sphinxsidebarwrapper {
-    padding: 18px 10px;
-}
-
-div.sphinxsidebarwrapper p.logo {
-    padding: 0;
-    margin: -10px 0 0 0px;
-    text-align: center;
-}
-
-div.sphinxsidebarwrapper h1.logo {
-    margin-top: -10px;
-    text-align: center;
-    margin-bottom: 5px;
-    text-align: left;
-}
-
-div.sphinxsidebarwrapper h1.logo-name {
-    margin-top: 0px;
-}
-
-div.sphinxsidebarwrapper p.blurb {
-    margin-top: 0;
-    font-style: normal;
-}
-
-div.sphinxsidebar h3,
-div.sphinxsidebar h4 {
-    font-family: Georgia, serif;
-    color: #444;
-    font-size: 24px;
-    font-weight: normal;
-    margin: 0 0 5px 0;
-    padding: 0;
-}
-
-div.sphinxsidebar h4 {
-    font-size: 20px;
-}
-
-div.sphinxsidebar h3 a {
-    color: #444;
-}
-
-div.sphinxsidebar p.logo a,
-div.sphinxsidebar h3 a,
-div.sphinxsidebar p.logo a:hover,
-div.sphinxsidebar h3 a:hover {
-    border: none;
-}
-
-div.sphinxsidebar p {
-    color: #555;
-    margin: 10px 0;
-}
-
-div.sphinxsidebar ul {
-    margin: 10px 0;
-    padding: 0;
-    color: #000;
-}
-
-div.sphinxsidebar ul li.toctree-l1 > a {
-    font-size: 120%;
-}
-
-div.sphinxsidebar ul li.toctree-l2 > a {
-    font-size: 110%;
-}
-
-div.sphinxsidebar input {
-    border: 1px solid #CCC;
-    font-family: Georgia, serif;
-    font-size: 1em;
-}
-
-div.sphinxsidebar hr {
-    border: none;
-    height: 1px;
-    color: #AAA;
-    background: #AAA;
-
-    text-align: left;
-    margin-left: 0;
-    width: 50%;
-}
-
-div.sphinxsidebar .badge {
-    border-bottom: none;
-}
-
-div.sphinxsidebar .badge:hover {
-    border-bottom: none;
-}
-
-/* To address an issue with donation coming after search */
-div.sphinxsidebar h3.donation {
-    margin-top: 10px;
-}
-
-/* -- body styles ----------------------------------------------------------- */
-
-a {
-    color: #004B6B;
-    text-decoration: underline;
-}
-
-a:hover {
-    color: #6D4100;
-    text-decoration: underline;
-}
-
-div.body h1,
-div.body h2,
-div.body h3,
-div.body h4,
-div.body h5,
-div.body h6 {
-    font-family: Georgia, serif;
-    font-weight: normal;
-    margin: 30px 0px 10px 0px;
-    padding: 0;
-}
-
-div.body h1 { margin-top: 0; padding-top: 0; font-size: 240%; }
-div.body h2 { font-size: 180%; }
-div.body h3 { font-size: 150%; }
-div.body h4 { font-size: 130%; }
-div.body h5 { font-size: 100%; }
-div.body h6 { font-size: 100%; }
-
-a.headerlink {
-    color: #DDD;
-    padding: 0 4px;
-    text-decoration: none;
-}
-
-a.headerlink:hover {
-    color: #444;
-    background: #EAEAEA;
-}
-
-div.body p, div.body dd, div.body li {
-    line-height: 1.4em;
-}
-
-div.admonition {
-    margin: 20px 0px;
-    padding: 10px 30px;
-    background-color: #EEE;
-    border: 1px solid #CCC;
-}
-
-div.admonition tt.xref, div.admonition code.xref, div.admonition a tt {
-    background-color: #FBFBFB;
-    border-bottom: 1px solid #fafafa;
-}
-
-div.admonition p.admonition-title {
-    font-family: Georgia, serif;
-    font-weight: normal;
-    font-size: 24px;
-    margin: 0 0 10px 0;
-    padding: 0;
-    line-height: 1;
-}
-
-div.admonition p.last {
-    margin-bottom: 0;
-}
-
-div.highlight {
-    background-color: #fff;
-}
-
-dt:target, .highlight {
-    background: #FAF3E8;
-}
-
-div.warning {
-    background-color: #FCC;
-    border: 1px solid #FAA;
-}
-
-div.danger {
-    background-color: #FCC;
-    border: 1px solid #FAA;
-    -moz-box-shadow: 2px 2px 4px #D52C2C;
-    -webkit-box-shadow: 2px 2px 4px #D52C2C;
-    box-shadow: 2px 2px 4px #D52C2C;
-}
-
-div.error {
-    background-color: #FCC;
-    border: 1px solid #FAA;
-    -moz-box-shadow: 2px 2px 4px #D52C2C;
-    -webkit-box-shadow: 2px 2px 4px #D52C2C;
-    box-shadow: 2px 2px 4px #D52C2C;
-}
-
-div.caution {
-    background-color: #FCC;
-    border: 1px solid #FAA;
-}
-
-div.attention {
-    background-color: #FCC;
-    border: 1px solid #FAA;
-}
-
-div.important {
-    background-color: #EEE;
-    border: 1px solid #CCC;
-}
-
-div.note {
-    background-color: #EEE;
-    border: 1px solid #CCC;
-}
-
-div.tip {
-    background-color: #EEE;
-    border: 1px solid #CCC;
-}
-
-div.hint {
-    background-color: #EEE;
-    border: 1px solid #CCC;
-}
-
-div.seealso {
-    background-color: #EEE;
-    border: 1px solid #CCC;
-}
-
-div.topic {
-    background-color: #EEE;
-}
-
-p.admonition-title {
-    display: inline;
-}
-
-p.admonition-title:after {
-    content: ":";
-}
-
-pre, tt, code {
-    font-family: 'Consolas', 'Menlo', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', monospace;
-    font-size: 0.9em;
-}
-
-.hll {
-    background-color: #FFC;
-    margin: 0 -12px;
-    padding: 0 12px;
-    display: block;
-}
-
-img.screenshot {
-}
-
-tt.descname, tt.descclassname, code.descname, code.descclassname {
-    font-size: 0.95em;
-}
-
-tt.descname, code.descname {
-    padding-right: 0.08em;
-}
-
-img.screenshot {
-    -moz-box-shadow: 2px 2px 4px #EEE;
-    -webkit-box-shadow: 2px 2px 4px #EEE;
-    box-shadow: 2px 2px 4px #EEE;
-}
-
-table.docutils {
-    border: 1px solid #888;
-    -moz-box-shadow: 2px 2px 4px #EEE;
-    -webkit-box-shadow: 2px 2px 4px #EEE;
-    box-shadow: 2px 2px 4px #EEE;
-}
-
-table.docutils td, table.docutils th {
-    border: 1px solid #888;
-    padding: 0.25em 0.7em;
-}
-
-table.field-list, table.footnote {
-    border: none;
-    -moz-box-shadow: none;
-    -webkit-box-shadow: none;
-    box-shadow: none;
-}
-
-table.footnote {
-    margin: 15px 0;
-    width: 100%;
-    border: 1px solid #EEE;
-    background: #FDFDFD;
-    font-size: 0.9em;
-}
-
-table.footnote + table.footnote {
-    margin-top: -15px;
-    border-top: none;
-}
-
-table.field-list th {
-    padding: 0 0.8em 0 0;
-}
-
-table.field-list td {
-    padding: 0;
-}
-
-table.field-list p {
-    margin-bottom: 0.8em;
-}
-
-/* Cloned from
- * https://github.com/sphinx-doc/sphinx/commit/ef60dbfce09286b20b7385333d63a60321784e68
- */
-.field-name {
-    -moz-hyphens: manual;
-    -ms-hyphens: manual;
-    -webkit-hyphens: manual;
-    hyphens: manual;
-}
-
-table.footnote td.label {
-    width: .1px;
-    padding: 0.3em 0 0.3em 0.5em;
-}
-
-table.footnote td {
-    padding: 0.3em 0.5em;
-}
-
-dl {
-    margin: 0;
-    padding: 0;
-}
-
-dl dd {
-    margin-left: 30px;
-}
-
-blockquote {
-    margin: 0 0 0 30px;
-    padding: 0;
-}
-
-ul, ol {
-    /* Matches the 30px from the narrow-screen "li > ul" selector below */
-    margin: 10px 0 10px 30px;
-    padding: 0;
-}
-
-pre {
-    background: #EEE;
-    padding: 7px 30px;
-    margin: 15px 0px;
-    line-height: 1.3em;
-}
-
-div.viewcode-block:target {
-    background: #ffd;
-}
-
-dl pre, blockquote pre, li pre {
-    margin-left: 0;
-    padding-left: 30px;
-}
-
-tt, code {
-    background-color: #ecf0f3;
-    color: #222;
-    /* padding: 1px 2px; */
-}
-
-tt.xref, code.xref, a tt {
-    background-color: #FBFBFB;
-    border-bottom: 1px solid #fff;
-}
-
-a.reference {
-    text-decoration: none;
-    border-bottom: 1px dotted #004B6B;
-}
-
-/* Don't put an underline on images */
-a.image-reference, a.image-reference:hover {
-    border-bottom: none;
-}
-
-a.reference:hover {
-    border-bottom: 1px solid #6D4100;
-}
-
-a.footnote-reference {
-    text-decoration: none;
-    font-size: 0.7em;
-    vertical-align: top;
-    border-bottom: 1px dotted #004B6B;
-}
-
-a.footnote-reference:hover {
-    border-bottom: 1px solid #6D4100;
-}
-
-a:hover tt, a:hover code {
-    background: #EEE;
-}
-
-
-@media screen and (max-width: 870px) {
-
-    div.sphinxsidebar {
-    	display: none;
-    }
-
-    div.document {
-       width: 100%;
-
-    }
-
-    div.documentwrapper {
-    	margin-left: 0;
-    	margin-top: 0;
-    	margin-right: 0;
-    	margin-bottom: 0;
-    }
-
-    div.bodywrapper {
-    	margin-top: 0;
-    	margin-right: 0;
-    	margin-bottom: 0;
-    	margin-left: 0;
-    }
-
-    ul {
-    	margin-left: 0;
-    }
-
-	li > ul {
-        /* Matches the 30px from the "ul, ol" selector above */
-		margin-left: 30px;
-	}
-
-    .document {
-    	width: auto;
-    }
-
-    .footer {
-    	width: auto;
-    }
-
-    .bodywrapper {
-    	margin: 0;
-    }
-
-    .footer {
-    	width: auto;
-    }
-
-    .github {
-        display: none;
-    }
-
-
-
-}
-
-
-
-@media screen and (max-width: 875px) {
-
-    body {
-        margin: 0;
-        padding: 20px 30px;
-    }
-
-    div.documentwrapper {
-        float: none;
-        background: #fff;
-    }
-
-    div.sphinxsidebar {
-        display: block;
-        float: none;
-        width: 102.5%;
-        margin: 50px -30px -20px -30px;
-        padding: 10px 20px;
-        background: #333;
-        color: #FFF;
-    }
-
-    div.sphinxsidebar h3, div.sphinxsidebar h4, div.sphinxsidebar p,
-    div.sphinxsidebar h3 a {
-        color: #fff;
-    }
-
-    div.sphinxsidebar a {
-        color: #AAA;
-    }
-
-    div.sphinxsidebar p.logo {
-        display: none;
-    }
-
-    div.document {
-        width: 100%;
-        margin: 0;
-    }
-
-    div.footer {
-        display: none;
-    }
-
-    div.bodywrapper {
-        margin: 0;
-    }
-
-    div.body {
-        min-height: 0;
-        padding: 0;
-    }
-
-    .rtd_doc_footer {
-        display: none;
-    }
-
-    .document {
-        width: auto;
-    }
-
-    .footer {
-        width: auto;
-    }
-
-    .footer {
-        width: auto;
-    }
-
-    .github {
-        display: none;
-    }
-}
-
-
-/* misc. */
-
-.revsys-inline {
-    display: none!important;
-}
-
-/* Make nested-list/multi-paragraph items look better in Releases changelog
- * pages. Without this, docutils' magical list fuckery causes inconsistent
- * formatting between different release sub-lists.
- */
-div#changelog > div.section > ul > li > p:only-child {
-    margin-bottom: 0;
-}
-
-/* Hide fugly table cell borders in ..bibliography:: directive output */
-table.docutils.citation, table.docutils.citation td, table.docutils.citation th {
-  border: none;
-  /* Below needed in some edge cases; if not applied, bottom shadows appear */
-  -moz-box-shadow: none;
-  -webkit-box-shadow: none;
-  box-shadow: none;
-}
-
-
-/* relbar */
-
-.related {
-    line-height: 30px;
-    width: 100%;
-    font-size: 0.9rem;
-}
-
-.related.top {
-    border-bottom: 1px solid #EEE;
-    margin-bottom: 20px;
-}
-
-.related.bottom {
-    border-top: 1px solid #EEE;
-}
-
-.related ul {
-    padding: 0;
-    margin: 0;
-    list-style: none;
-}
-
-.related li {
-    display: inline;
-}
-
-nav#rellinks {
-    float: right;
-}
-
-nav#rellinks li+li:before {
-    content: "|";
-}
-
-nav#breadcrumbs li+li:before {
-    content: "\00BB";
-}
-
-/* Hide certain items when printing */
-@media print {
-    div.related {
-        display: none;
-    }
-}
\ No newline at end of file
diff --git a/docs/_build/html/_static/basic.css b/docs/_build/html/_static/basic.css
deleted file mode 100644
index c2e4f880..00000000
--- a/docs/_build/html/_static/basic.css
+++ /dev/null
@@ -1,904 +0,0 @@
-/*
- * basic.css
- * ~~~~~~~~~
- *
- * Sphinx stylesheet -- basic theme.
- *
- * :copyright: Copyright 2007-2021 by the Sphinx team, see AUTHORS.
- * :license: BSD, see LICENSE for details.
- *
- */
-
-/* -- main layout ----------------------------------------------------------- */
-
-div.clearer {
-    clear: both;
-}
-
-div.section::after {
-    display: block;
-    content: '';
-    clear: left;
-}
-
-/* -- relbar ---------------------------------------------------------------- */
-
-div.related {
-    width: 100%;
-    font-size: 90%;
-}
-
-div.related h3 {
-    display: none;
-}
-
-div.related ul {
-    margin: 0;
-    padding: 0 0 0 10px;
-    list-style: none;
-}
-
-div.related li {
-    display: inline;
-}
-
-div.related li.right {
-    float: right;
-    margin-right: 5px;
-}
-
-/* -- sidebar --------------------------------------------------------------- */
-
-div.sphinxsidebarwrapper {
-    padding: 10px 5px 0 10px;
-}
-
-div.sphinxsidebar {
-    float: left;
-    width: 230px;
-    margin-left: -100%;
-    font-size: 90%;
-    word-wrap: break-word;
-    overflow-wrap : break-word;
-}
-
-div.sphinxsidebar ul {
-    list-style: none;
-}
-
-div.sphinxsidebar ul ul,
-div.sphinxsidebar ul.want-points {
-    margin-left: 20px;
-    list-style: square;
-}
-
-div.sphinxsidebar ul ul {
-    margin-top: 0;
-    margin-bottom: 0;
-}
-
-div.sphinxsidebar form {
-    margin-top: 10px;
-}
-
-div.sphinxsidebar input {
-    border: 1px solid #98dbcc;
-    font-family: sans-serif;
-    font-size: 1em;
-}
-
-div.sphinxsidebar #searchbox form.search {
-    overflow: hidden;
-}
-
-div.sphinxsidebar #searchbox input[type="text"] {
-    float: left;
-    width: 80%;
-    padding: 0.25em;
-    box-sizing: border-box;
-}
-
-div.sphinxsidebar #searchbox input[type="submit"] {
-    float: left;
-    width: 20%;
-    border-left: none;
-    padding: 0.25em;
-    box-sizing: border-box;
-}
-
-
-img {
-    border: 0;
-    max-width: 100%;
-}
-
-/* -- search page ----------------------------------------------------------- */
-
-ul.search {
-    margin: 10px 0 0 20px;
-    padding: 0;
-}
-
-ul.search li {
-    padding: 5px 0 5px 20px;
-    background-image: url(file.png);
-    background-repeat: no-repeat;
-    background-position: 0 7px;
-}
-
-ul.search li a {
-    font-weight: bold;
-}
-
-ul.search li p.context {
-    color: #888;
-    margin: 2px 0 0 30px;
-    text-align: left;
-}
-
-ul.keywordmatches li.goodmatch a {
-    font-weight: bold;
-}
-
-/* -- index page ------------------------------------------------------------ */
-
-table.contentstable {
-    width: 90%;
-    margin-left: auto;
-    margin-right: auto;
-}
-
-table.contentstable p.biglink {
-    line-height: 150%;
-}
-
-a.biglink {
-    font-size: 1.3em;
-}
-
-span.linkdescr {
-    font-style: italic;
-    padding-top: 5px;
-    font-size: 90%;
-}
-
-/* -- general index --------------------------------------------------------- */
-
-table.indextable {
-    width: 100%;
-}
-
-table.indextable td {
-    text-align: left;
-    vertical-align: top;
-}
-
-table.indextable ul {
-    margin-top: 0;
-    margin-bottom: 0;
-    list-style-type: none;
-}
-
-table.indextable > tbody > tr > td > ul {
-    padding-left: 0em;
-}
-
-table.indextable tr.pcap {
-    height: 10px;
-}
-
-table.indextable tr.cap {
-    margin-top: 10px;
-    background-color: #f2f2f2;
-}
-
-img.toggler {
-    margin-right: 3px;
-    margin-top: 3px;
-    cursor: pointer;
-}
-
-div.modindex-jumpbox {
-    border-top: 1px solid #ddd;
-    border-bottom: 1px solid #ddd;
-    margin: 1em 0 1em 0;
-    padding: 0.4em;
-}
-
-div.genindex-jumpbox {
-    border-top: 1px solid #ddd;
-    border-bottom: 1px solid #ddd;
-    margin: 1em 0 1em 0;
-    padding: 0.4em;
-}
-
-/* -- domain module index --------------------------------------------------- */
-
-table.modindextable td {
-    padding: 2px;
-    border-collapse: collapse;
-}
-
-/* -- general body styles --------------------------------------------------- */
-
-div.body {
-    min-width: 450px;
-    max-width: 800px;
-}
-
-div.body p, div.body dd, div.body li, div.body blockquote {
-    -moz-hyphens: auto;
-    -ms-hyphens: auto;
-    -webkit-hyphens: auto;
-    hyphens: auto;
-}
-
-a.headerlink {
-    visibility: hidden;
-}
-
-a.brackets:before,
-span.brackets > a:before{
-    content: "[";
-}
-
-a.brackets:after,
-span.brackets > a:after {
-    content: "]";
-}
-
-h1:hover > a.headerlink,
-h2:hover > a.headerlink,
-h3:hover > a.headerlink,
-h4:hover > a.headerlink,
-h5:hover > a.headerlink,
-h6:hover > a.headerlink,
-dt:hover > a.headerlink,
-caption:hover > a.headerlink,
-p.caption:hover > a.headerlink,
-div.code-block-caption:hover > a.headerlink {
-    visibility: visible;
-}
-
-div.body p.caption {
-    text-align: inherit;
-}
-
-div.body td {
-    text-align: left;
-}
-
-.first {
-    margin-top: 0 !important;
-}
-
-p.rubric {
-    margin-top: 30px;
-    font-weight: bold;
-}
-
-img.align-left, figure.align-left, .figure.align-left, object.align-left {
-    clear: left;
-    float: left;
-    margin-right: 1em;
-}
-
-img.align-right, figure.align-right, .figure.align-right, object.align-right {
-    clear: right;
-    float: right;
-    margin-left: 1em;
-}
-
-img.align-center, figure.align-center, .figure.align-center, object.align-center {
-  display: block;
-  margin-left: auto;
-  margin-right: auto;
-}
-
-img.align-default, figure.align-default, .figure.align-default {
-  display: block;
-  margin-left: auto;
-  margin-right: auto;
-}
-
-.align-left {
-    text-align: left;
-}
-
-.align-center {
-    text-align: center;
-}
-
-.align-default {
-    text-align: center;
-}
-
-.align-right {
-    text-align: right;
-}
-
-/* -- sidebars -------------------------------------------------------------- */
-
-div.sidebar,
-aside.sidebar {
-    margin: 0 0 0.5em 1em;
-    border: 1px solid #ddb;
-    padding: 7px;
-    background-color: #ffe;
-    width: 40%;
-    float: right;
-    clear: right;
-    overflow-x: auto;
-}
-
-p.sidebar-title {
-    font-weight: bold;
-}
-
-div.admonition, div.topic, blockquote {
-    clear: left;
-}
-
-/* -- topics ---------------------------------------------------------------- */
-
-div.topic {
-    border: 1px solid #ccc;
-    padding: 7px;
-    margin: 10px 0 10px 0;
-}
-
-p.topic-title {
-    font-size: 1.1em;
-    font-weight: bold;
-    margin-top: 10px;
-}
-
-/* -- admonitions ----------------------------------------------------------- */
-
-div.admonition {
-    margin-top: 10px;
-    margin-bottom: 10px;
-    padding: 7px;
-}
-
-div.admonition dt {
-    font-weight: bold;
-}
-
-p.admonition-title {
-    margin: 0px 10px 5px 0px;
-    font-weight: bold;
-}
-
-div.body p.centered {
-    text-align: center;
-    margin-top: 25px;
-}
-
-/* -- content of sidebars/topics/admonitions -------------------------------- */
-
-div.sidebar > :last-child,
-aside.sidebar > :last-child,
-div.topic > :last-child,
-div.admonition > :last-child {
-    margin-bottom: 0;
-}
-
-div.sidebar::after,
-aside.sidebar::after,
-div.topic::after,
-div.admonition::after,
-blockquote::after {
-    display: block;
-    content: '';
-    clear: both;
-}
-
-/* -- tables ---------------------------------------------------------------- */
-
-table.docutils {
-    margin-top: 10px;
-    margin-bottom: 10px;
-    border: 0;
-    border-collapse: collapse;
-}
-
-table.align-center {
-    margin-left: auto;
-    margin-right: auto;
-}
-
-table.align-default {
-    margin-left: auto;
-    margin-right: auto;
-}
-
-table caption span.caption-number {
-    font-style: italic;
-}
-
-table caption span.caption-text {
-}
-
-table.docutils td, table.docutils th {
-    padding: 1px 8px 1px 5px;
-    border-top: 0;
-    border-left: 0;
-    border-right: 0;
-    border-bottom: 1px solid #aaa;
-}
-
-table.footnote td, table.footnote th {
-    border: 0 !important;
-}
-
-th {
-    text-align: left;
-    padding-right: 5px;
-}
-
-table.citation {
-    border-left: solid 1px gray;
-    margin-left: 1px;
-}
-
-table.citation td {
-    border-bottom: none;
-}
-
-th > :first-child,
-td > :first-child {
-    margin-top: 0px;
-}
-
-th > :last-child,
-td > :last-child {
-    margin-bottom: 0px;
-}
-
-/* -- figures --------------------------------------------------------------- */
-
-div.figure, figure {
-    margin: 0.5em;
-    padding: 0.5em;
-}
-
-div.figure p.caption, figcaption {
-    padding: 0.3em;
-}
-
-div.figure p.caption span.caption-number,
-figcaption span.caption-number {
-    font-style: italic;
-}
-
-div.figure p.caption span.caption-text,
-figcaption span.caption-text {
-}
-
-/* -- field list styles ----------------------------------------------------- */
-
-table.field-list td, table.field-list th {
-    border: 0 !important;
-}
-
-.field-list ul {
-    margin: 0;
-    padding-left: 1em;
-}
-
-.field-list p {
-    margin: 0;
-}
-
-.field-name {
-    -moz-hyphens: manual;
-    -ms-hyphens: manual;
-    -webkit-hyphens: manual;
-    hyphens: manual;
-}
-
-/* -- hlist styles ---------------------------------------------------------- */
-
-table.hlist {
-    margin: 1em 0;
-}
-
-table.hlist td {
-    vertical-align: top;
-}
-
-/* -- object description styles --------------------------------------------- */
-
-.sig {
-	font-family: 'Consolas', 'Menlo', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', monospace;
-}
-
-.sig-name, code.descname {
-    background-color: transparent;
-    font-weight: bold;
-}
-
-.sig-name {
-	font-size: 1.1em;
-}
-
-code.descname {
-    font-size: 1.2em;
-}
-
-.sig-prename, code.descclassname {
-    background-color: transparent;
-}
-
-.optional {
-    font-size: 1.3em;
-}
-
-.sig-paren {
-    font-size: larger;
-}
-
-.sig-param.n {
-	font-style: italic;
-}
-
-/* C++ specific styling */
-
-.sig-inline.c-texpr,
-.sig-inline.cpp-texpr {
-	font-family: unset;
-}
-
-.sig.c   .k, .sig.c   .kt,
-.sig.cpp .k, .sig.cpp .kt {
-	color: #0033B3;
-}
-
-.sig.c   .m,
-.sig.cpp .m {
-	color: #1750EB;
-}
-
-.sig.c   .s, .sig.c   .sc,
-.sig.cpp .s, .sig.cpp .sc {
-	color: #067D17;
-}
-
-
-/* -- other body styles ----------------------------------------------------- */
-
-ol.arabic {
-    list-style: decimal;
-}
-
-ol.loweralpha {
-    list-style: lower-alpha;
-}
-
-ol.upperalpha {
-    list-style: upper-alpha;
-}
-
-ol.lowerroman {
-    list-style: lower-roman;
-}
-
-ol.upperroman {
-    list-style: upper-roman;
-}
-
-:not(li) > ol > li:first-child > :first-child,
-:not(li) > ul > li:first-child > :first-child {
-    margin-top: 0px;
-}
-
-:not(li) > ol > li:last-child > :last-child,
-:not(li) > ul > li:last-child > :last-child {
-    margin-bottom: 0px;
-}
-
-ol.simple ol p,
-ol.simple ul p,
-ul.simple ol p,
-ul.simple ul p {
-    margin-top: 0;
-}
-
-ol.simple > li:not(:first-child) > p,
-ul.simple > li:not(:first-child) > p {
-    margin-top: 0;
-}
-
-ol.simple p,
-ul.simple p {
-    margin-bottom: 0;
-}
-
-dl.footnote > dt,
-dl.citation > dt {
-    float: left;
-    margin-right: 0.5em;
-}
-
-dl.footnote > dd,
-dl.citation > dd {
-    margin-bottom: 0em;
-}
-
-dl.footnote > dd:after,
-dl.citation > dd:after {
-    content: "";
-    clear: both;
-}
-
-dl.field-list {
-    display: grid;
-    grid-template-columns: fit-content(30%) auto;
-}
-
-dl.field-list > dt {
-    font-weight: bold;
-    word-break: break-word;
-    padding-left: 0.5em;
-    padding-right: 5px;
-}
-
-dl.field-list > dt:after {
-    content: ":";
-}
-
-dl.field-list > dd {
-    padding-left: 0.5em;
-    margin-top: 0em;
-    margin-left: 0em;
-    margin-bottom: 0em;
-}
-
-dl {
-    margin-bottom: 15px;
-}
-
-dd > :first-child {
-    margin-top: 0px;
-}
-
-dd ul, dd table {
-    margin-bottom: 10px;
-}
-
-dd {
-    margin-top: 3px;
-    margin-bottom: 10px;
-    margin-left: 30px;
-}
-
-dl > dd:last-child,
-dl > dd:last-child > :last-child {
-    margin-bottom: 0;
-}
-
-dt:target, span.highlighted {
-    background-color: #fbe54e;
-}
-
-rect.highlighted {
-    fill: #fbe54e;
-}
-
-dl.glossary dt {
-    font-weight: bold;
-    font-size: 1.1em;
-}
-
-.versionmodified {
-    font-style: italic;
-}
-
-.system-message {
-    background-color: #fda;
-    padding: 5px;
-    border: 3px solid red;
-}
-
-.footnote:target  {
-    background-color: #ffa;
-}
-
-.line-block {
-    display: block;
-    margin-top: 1em;
-    margin-bottom: 1em;
-}
-
-.line-block .line-block {
-    margin-top: 0;
-    margin-bottom: 0;
-    margin-left: 1.5em;
-}
-
-.guilabel, .menuselection {
-    font-family: sans-serif;
-}
-
-.accelerator {
-    text-decoration: underline;
-}
-
-.classifier {
-    font-style: oblique;
-}
-
-.classifier:before {
-    font-style: normal;
-    margin: 0.5em;
-    content: ":";
-}
-
-abbr, acronym {
-    border-bottom: dotted 1px;
-    cursor: help;
-}
-
-/* -- code displays --------------------------------------------------------- */
-
-pre {
-    overflow: auto;
-    overflow-y: hidden;  /* fixes display issues on Chrome browsers */
-}
-
-pre, div[class*="highlight-"] {
-    clear: both;
-}
-
-span.pre {
-    -moz-hyphens: none;
-    -ms-hyphens: none;
-    -webkit-hyphens: none;
-    hyphens: none;
-}
-
-div[class*="highlight-"] {
-    margin: 1em 0;
-}
-
-td.linenos pre {
-    border: 0;
-    background-color: transparent;
-    color: #aaa;
-}
-
-table.highlighttable {
-    display: block;
-}
-
-table.highlighttable tbody {
-    display: block;
-}
-
-table.highlighttable tr {
-    display: flex;
-}
-
-table.highlighttable td {
-    margin: 0;
-    padding: 0;
-}
-
-table.highlighttable td.linenos {
-    padding-right: 0.5em;
-}
-
-table.highlighttable td.code {
-    flex: 1;
-    overflow: hidden;
-}
-
-.highlight .hll {
-    display: block;
-}
-
-div.highlight pre,
-table.highlighttable pre {
-    margin: 0;
-}
-
-div.code-block-caption + div {
-    margin-top: 0;
-}
-
-div.code-block-caption {
-    margin-top: 1em;
-    padding: 2px 5px;
-    font-size: small;
-}
-
-div.code-block-caption code {
-    background-color: transparent;
-}
-
-table.highlighttable td.linenos,
-span.linenos,
-div.doctest > div.highlight span.gp {  /* gp: Generic.Prompt */
-  user-select: none;
-  -webkit-user-select: text; /* Safari fallback only */
-  -webkit-user-select: none; /* Chrome/Safari */
-  -moz-user-select: none; /* Firefox */
-  -ms-user-select: none; /* IE10+ */
-}
-
-div.code-block-caption span.caption-number {
-    padding: 0.1em 0.3em;
-    font-style: italic;
-}
-
-div.code-block-caption span.caption-text {
-}
-
-div.literal-block-wrapper {
-    margin: 1em 0;
-}
-
-code.xref, a code {
-    background-color: transparent;
-    font-weight: bold;
-}
-
-h1 code, h2 code, h3 code, h4 code, h5 code, h6 code {
-    background-color: transparent;
-}
-
-.viewcode-link {
-    float: right;
-}
-
-.viewcode-back {
-    float: right;
-    font-family: sans-serif;
-}
-
-div.viewcode-block:target {
-    margin: -1px -10px;
-    padding: 0 10px;
-}
-
-/* -- math display ---------------------------------------------------------- */
-
-img.math {
-    vertical-align: middle;
-}
-
-div.body div.math p {
-    text-align: center;
-}
-
-span.eqno {
-    float: right;
-}
-
-span.eqno a.headerlink {
-    position: absolute;
-    z-index: 1;
-}
-
-div.math:hover a.headerlink {
-    visibility: visible;
-}
-
-/* -- printout stylesheet --------------------------------------------------- */
-
-@media print {
-    div.document,
-    div.documentwrapper,
-    div.bodywrapper {
-        margin: 0 !important;
-        width: 100%;
-    }
-
-    div.sphinxsidebar,
-    div.related,
-    div.footer,
-    #top-link {
-        display: none;
-    }
-}
\ No newline at end of file
diff --git a/docs/_build/html/_static/codeblocks.css b/docs/_build/html/_static/codeblocks.css
deleted file mode 100644
index aa19bf1d..00000000
--- a/docs/_build/html/_static/codeblocks.css
+++ /dev/null
@@ -1,143 +0,0 @@
-/* light theme: default */
-.highlight .hll { background-color: #ffffcc }
-.highlight  { background: #f0f0f0; }
-.highlight .c { color: #60a0b0; font-style: italic } /* Comment */
-.highlight .err { border: 1px solid #FF0000 } /* Error */
-.highlight .k { color: #007020; font-weight: bold } /* Keyword */
-.highlight .o { color: #666666 } /* Operator */
-.highlight .ch { color: #60a0b0; font-style: italic } /* Comment.Hashbang */
-.highlight .cm { color: #60a0b0; font-style: italic } /* Comment.Multiline */
-.highlight .cp { color: #007020 } /* Comment.Preproc */
-.highlight .cpf { color: #60a0b0; font-style: italic } /* Comment.PreprocFile */
-.highlight .c1 { color: #60a0b0; font-style: italic } /* Comment.Single */
-.highlight .cs { color: #60a0b0; background-color: #fff0f0 } /* Comment.Special */
-.highlight .gd { color: #A00000 } /* Generic.Deleted */
-.highlight .ge { font-style: italic } /* Generic.Emph */
-.highlight .gr { color: #FF0000 } /* Generic.Error */
-.highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */
-.highlight .gi { color: #00A000 } /* Generic.Inserted */
-.highlight .go { color: #888888 } /* Generic.Output */
-.highlight .gp { color: #c65d09; font-weight: bold } /* Generic.Prompt */
-.highlight .gs { font-weight: bold } /* Generic.Strong */
-.highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */
-.highlight .gt { color: #0044DD } /* Generic.Traceback */
-.highlight .kc { color: #007020; font-weight: bold } /* Keyword.Constant */
-.highlight .kd { color: #007020; font-weight: bold } /* Keyword.Declaration */
-.highlight .kn { color: #007020; font-weight: bold } /* Keyword.Namespace */
-.highlight .kp { color: #007020 } /* Keyword.Pseudo */
-.highlight .kr { color: #007020; font-weight: bold } /* Keyword.Reserved */
-.highlight .kt { color: #902000 } /* Keyword.Type */
-.highlight .m { color: #40a070 } /* Literal.Number */
-.highlight .s { color: #4070a0 } /* Literal.String */
-.highlight .na { color: #4070a0 } /* Name.Attribute */
-.highlight .nb { color: #007020 } /* Name.Builtin */
-.highlight .nc { color: #0e84b5; font-weight: bold } /* Name.Class */
-.highlight .no { color: #60add5 } /* Name.Constant */
-.highlight .nd { color: #555555; font-weight: bold } /* Name.Decorator */
-.highlight .ni { color: #d55537; font-weight: bold } /* Name.Entity */
-.highlight .ne { color: #007020 } /* Name.Exception */
-.highlight .nf { color: #06287e } /* Name.Function */
-.highlight .nl { color: #002070; font-weight: bold } /* Name.Label */
-.highlight .nn { color: #0e84b5; font-weight: bold } /* Name.Namespace */
-.highlight .nt { color: #062873; font-weight: bold } /* Name.Tag */
-.highlight .nv { color: #bb60d5 } /* Name.Variable */
-.highlight .ow { color: #007020; font-weight: bold } /* Operator.Word */
-.highlight .w { color: #bbbbbb } /* Text.Whitespace */
-.highlight .mb { color: #40a070 } /* Literal.Number.Bin */
-.highlight .mf { color: #40a070 } /* Literal.Number.Float */
-.highlight .mh { color: #40a070 } /* Literal.Number.Hex */
-.highlight .mi { color: #40a070 } /* Literal.Number.Integer */
-.highlight .mo { color: #40a070 } /* Literal.Number.Oct */
-.highlight .sa { color: #4070a0 } /* Literal.String.Affix */
-.highlight .sb { color: #4070a0 } /* Literal.String.Backtick */
-.highlight .sc { color: #4070a0 } /* Literal.String.Char */
-.highlight .dl { color: #4070a0 } /* Literal.String.Delimiter */
-.highlight .sd { color: #4070a0; font-style: italic } /* Literal.String.Doc */
-.highlight .s2 { color: #4070a0 } /* Literal.String.Double */
-.highlight .se { color: #4070a0; font-weight: bold } /* Literal.String.Escape */
-.highlight .sh { color: #4070a0 } /* Literal.String.Heredoc */
-.highlight .si { color: #70a0d0; font-style: italic } /* Literal.String.Interpol */
-.highlight .sx { color: #c65d09 } /* Literal.String.Other */
-.highlight .sr { color: #235388 } /* Literal.String.Regex */
-.highlight .s1 { color: #4070a0 } /* Literal.String.Single */
-.highlight .ss { color: #517918 } /* Literal.String.Symbol */
-.highlight .bp { color: #007020 } /* Name.Builtin.Pseudo */
-.highlight .fm { color: #06287e } /* Name.Function.Magic */
-.highlight .vc { color: #bb60d5 } /* Name.Variable.Class */
-.highlight .vg { color: #bb60d5 } /* Name.Variable.Global */
-.highlight .vi { color: #bb60d5 } /* Name.Variable.Instance */
-.highlight .vm { color: #bb60d5 } /* Name.Variable.Magic */
-.highlight .il { color: #40a070 } /* Literal.Number.Integer.Long */
-
-/* dark theme: modified "native" */
-:root[data-theme="dark"] .highlight pre { background-color: #2a2a2e }
-:root[data-theme="dark"] .highlight .hll { background-color: #2a2a2e }
-:root[data-theme="dark"] .highlight .c { color: #999999; font-style: italic } /* Comment */
-:root[data-theme="dark"] .highlight .err { color: #a61717; background-color: #e3d2d2 } /* Error */
-:root[data-theme="dark"] .highlight .g { color: #d0d0d0 } /* Generic */
-:root[data-theme="dark"] .highlight .k { color: #6ab825; font-weight: bold } /* Keyword */
-:root[data-theme="dark"] .highlight .l { color: #d0d0d0 } /* Literal */
-:root[data-theme="dark"] .highlight .n { color: #d0d0d0 } /* Name */
-:root[data-theme="dark"] .highlight .o { color: #d0d0d0 } /* Operator */
-:root[data-theme="dark"] .highlight .x { color: #d0d0d0 } /* Other */
-:root[data-theme="dark"] .highlight .p { color: #d0d0d0 } /* Punctuation */
-:root[data-theme="dark"] .highlight .cm { color: #999999; font-style: italic } /* Comment.Multiline */
-:root[data-theme="dark"] .highlight .cp { color: #cd2828; font-weight: bold } /* Comment.Preproc */
-:root[data-theme="dark"] .highlight .c1 { color: #999999; font-style: italic } /* Comment.Single */
-:root[data-theme="dark"] .highlight .cs { color: #e50808; font-weight: bold; background-color: #520000 } /* Comment.Special */
-:root[data-theme="dark"] .highlight .gd { color: #d22323 } /* Generic.Deleted */
-:root[data-theme="dark"] .highlight .ge { color: #d0d0d0; font-style: italic } /* Generic.Emph */
-:root[data-theme="dark"] .highlight .gr { color: #d22323 } /* Generic.Error */
-:root[data-theme="dark"] .highlight .gh { color: #ffffff; font-weight: bold } /* Generic.Heading */
-:root[data-theme="dark"] .highlight .gi { color: #589819 } /* Generic.Inserted */
-:root[data-theme="dark"] .highlight .go { color: #cccccc } /* Generic.Output */
-:root[data-theme="dark"] .highlight .gp { color: #aaaaaa } /* Generic.Prompt */
-:root[data-theme="dark"] .highlight .gs { color: #d0d0d0; font-weight: bold } /* Generic.Strong */
-:root[data-theme="dark"] .highlight .gu { color: #ffffff; text-decoration: underline } /* Generic.Subheading */
-:root[data-theme="dark"] .highlight .gt { color: #d22323 } /* Generic.Traceback */
-:root[data-theme="dark"] .highlight .kc { color: #6ab825; font-weight: bold } /* Keyword.Constant */
-:root[data-theme="dark"] .highlight .kd { color: #6ab825; font-weight: bold } /* Keyword.Declaration */
-:root[data-theme="dark"] .highlight .kn { color: #6ab825; font-weight: bold } /* Keyword.Namespace */
-:root[data-theme="dark"] .highlight .kp { color: #6ab825 } /* Keyword.Pseudo */
-:root[data-theme="dark"] .highlight .kr { color: #6ab825; font-weight: bold } /* Keyword.Reserved */
-:root[data-theme="dark"] .highlight .kt { color: #6ab825; font-weight: bold } /* Keyword.Type */
-:root[data-theme="dark"] .highlight .ld { color: #d0d0d0 } /* Literal.Date */
-:root[data-theme="dark"] .highlight .m { color: #7fb1d7 } /* Literal.Number */
-:root[data-theme="dark"] .highlight .s { color: #ed9d13 } /* Literal.String */
-:root[data-theme="dark"] .highlight .na { color: #bbbbbb; } /* Name.Attribute */
-:root[data-theme="dark"] .highlight .nb { color: #29a5b3; } /* Name.Builtin */
-:root[data-theme="dark"] .highlight .nc { color: #6494d8;} /* Name.Class */
-:root[data-theme="dark"] .highlight .no { color: #40ffff; } /* Name.Constant */
-:root[data-theme="dark"] .highlight .nd { color: #ffa500; } /* Name.Decorator */
-:root[data-theme="dark"] .highlight .ni { color: #d0d0d0; } /* Name.Entity */
-:root[data-theme="dark"] .highlight .ne { color: #bbbbbb; } /* Name.Exception */
-:root[data-theme="dark"] .highlight .nf { color: #6494d8; } /* Name.Function */
-:root[data-theme="dark"] .highlight .fm { color: #6494d8; } /* Name.Function.Magic */
-:root[data-theme="dark"] .highlight .nl { color: #d0d0d0; } /* Name.Label */
-:root[data-theme="dark"] .highlight .nn { color: #6494d8;} /* Name.Namespace */
-:root[data-theme="dark"] .highlight .nx { color: #d0d0d0; } /* Name.Other */
-:root[data-theme="dark"] .highlight .py { color: #d0d0d0; } /* Name.Property */
-:root[data-theme="dark"] .highlight .nt { color: #6ab825; font-weight: bold } /* Name.Tag */
-:root[data-theme="dark"] .highlight .nv { color: #40ffff; } /* Name.Variable */
-:root[data-theme="dark"] .highlight .ow { color: #6ab825; font-weight: bold } /* Operator.Word */
-:root[data-theme="dark"] .highlight .w  { color: #666666; } /* Text.Whitespace */
-:root[data-theme="dark"] .highlight .mf { color: #7fb1d7; } /* Literal.Number.Float */
-:root[data-theme="dark"] .highlight .mh { color: #7fb1d7; } /* Literal.Number.Hex */
-:root[data-theme="dark"] .highlight .mi { color: #7fb1d7; } /* Literal.Number.Integer */
-:root[data-theme="dark"] .highlight .mo { color: #7fb1d7; } /* Literal.Number.Oct */
-:root[data-theme="dark"] .highlight .sb { color: #ed9d13; } /* Literal.String.Backtick */
-:root[data-theme="dark"] .highlight .sc { color: #ed9d13; } /* Literal.String.Char */
-:root[data-theme="dark"] .highlight .sd { color: #ed9d13; } /* Literal.String.Doc */
-:root[data-theme="dark"] .highlight .s2 { color: #ed9d13; } /* Literal.String.Double */
-:root[data-theme="dark"] .highlight .se { color: #ed9d13; } /* Literal.String.Escape */
-:root[data-theme="dark"] .highlight .sh { color: #ed9d13; } /* Literal.String.Heredoc */
-:root[data-theme="dark"] .highlight .si { color: #ed9d13; } /* Literal.String.Interpol */
-:root[data-theme="dark"] .highlight .sx { color: #ffa500; } /* Literal.String.Other */
-:root[data-theme="dark"] .highlight .sr { color: #ed9d13; } /* Literal.String.Regex */
-:root[data-theme="dark"] .highlight .s1 { color: #ed9d13; } /* Literal.String.Single */
-:root[data-theme="dark"] .highlight .ss { color: #ed9d13; } /* Literal.String.Symbol */
-:root[data-theme="dark"] .highlight .bp { color: #29a5b3; } /* Name.Builtin.Pseudo */
-:root[data-theme="dark"] .highlight .vc { color: #40ffff; } /* Name.Variable.Class */
-:root[data-theme="dark"] .highlight .vg { color: #40ffff; } /* Name.Variable.Global */
-:root[data-theme="dark"] .highlight .vi { color: #40ffff; } /* Name.Variable.Instance */
-:root[data-theme="dark"] .highlight .il { color: #7fb1d7; } /* Literal.Number.Integer.Long */
\ No newline at end of file
diff --git a/docs/_build/html/_static/css/badge_only.css b/docs/_build/html/_static/css/badge_only.css
deleted file mode 100644
index e380325b..00000000
--- a/docs/_build/html/_static/css/badge_only.css
+++ /dev/null
@@ -1 +0,0 @@
-.fa:before{-webkit-font-smoothing:antialiased}.clearfix{*zoom:1}.clearfix:after,.clearfix:before{display:table;content:""}.clearfix:after{clear:both}@font-face{font-family:FontAwesome;font-style:normal;font-weight:400;src:url(fonts/fontawesome-webfont.eot?674f50d287a8c48dc19ba404d20fe713?#iefix) format("embedded-opentype"),url(fonts/fontawesome-webfont.woff2?af7ae505a9eed503f8b8e6982036873e) format("woff2"),url(fonts/fontawesome-webfont.woff?fee66e712a8a08eef5805a46892932ad) format("woff"),url(fonts/fontawesome-webfont.ttf?b06871f281fee6b241d60582ae9369b9) format("truetype"),url(fonts/fontawesome-webfont.svg?912ec66d7572ff821749319396470bde#FontAwesome) format("svg")}.fa:before{font-family:FontAwesome;font-style:normal;font-weight:400;line-height:1}.fa:before,a .fa{text-decoration:inherit}.fa:before,a .fa,li .fa{display:inline-block}li .fa-large:before{width:1.875em}ul.fas{list-style-type:none;margin-left:2em;text-indent:-.8em}ul.fas li .fa{width:.8em}ul.fas li .fa-large:before{vertical-align:baseline}.fa-book:before,.icon-book:before{content:"\f02d"}.fa-caret-down:before,.icon-caret-down:before{content:"\f0d7"}.fa-caret-up:before,.icon-caret-up:before{content:"\f0d8"}.fa-caret-left:before,.icon-caret-left:before{content:"\f0d9"}.fa-caret-right:before,.icon-caret-right:before{content:"\f0da"}.rst-versions{position:fixed;bottom:0;left:0;width:300px;color:#fcfcfc;background:#1f1d1d;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;z-index:400}.rst-versions a{color:#2980b9;text-decoration:none}.rst-versions .rst-badge-small{display:none}.rst-versions .rst-current-version{padding:12px;background-color:#272525;display:block;text-align:right;font-size:90%;cursor:pointer;color:#27ae60}.rst-versions .rst-current-version:after{clear:both;content:"";display:block}.rst-versions .rst-current-version .fa{color:#fcfcfc}.rst-versions .rst-current-version .fa-book,.rst-versions .rst-current-version .icon-book{float:left}.rst-versions .rst-current-version.rst-out-of-date{background-color:#e74c3c;color:#fff}.rst-versions .rst-current-version.rst-active-old-version{background-color:#f1c40f;color:#000}.rst-versions.shift-up{height:auto;max-height:100%;overflow-y:scroll}.rst-versions.shift-up .rst-other-versions{display:block}.rst-versions .rst-other-versions{font-size:90%;padding:12px;color:grey;display:none}.rst-versions .rst-other-versions hr{display:block;height:1px;border:0;margin:20px 0;padding:0;border-top:1px solid #413d3d}.rst-versions .rst-other-versions dd{display:inline-block;margin:0}.rst-versions .rst-other-versions dd a{display:inline-block;padding:6px;color:#fcfcfc}.rst-versions.rst-badge{width:auto;bottom:20px;right:20px;left:auto;border:none;max-width:300px;max-height:90%}.rst-versions.rst-badge .fa-book,.rst-versions.rst-badge .icon-book{float:none;line-height:30px}.rst-versions.rst-badge.shift-up .rst-current-version{text-align:right}.rst-versions.rst-badge.shift-up .rst-current-version .fa-book,.rst-versions.rst-badge.shift-up .rst-current-version .icon-book{float:left}.rst-versions.rst-badge>.rst-current-version{width:auto;height:30px;line-height:30px;padding:0 6px;display:block;text-align:center}@media screen and (max-width:768px){.rst-versions{width:85%;display:none}.rst-versions.shift{display:block}}
\ No newline at end of file
diff --git a/docs/_build/html/_static/css/fonts/Roboto-Slab-Bold.woff b/docs/_build/html/_static/css/fonts/Roboto-Slab-Bold.woff
deleted file mode 100644
index 6cb60000..00000000
Binary files a/docs/_build/html/_static/css/fonts/Roboto-Slab-Bold.woff and /dev/null differ
diff --git a/docs/_build/html/_static/css/fonts/Roboto-Slab-Bold.woff2 b/docs/_build/html/_static/css/fonts/Roboto-Slab-Bold.woff2
deleted file mode 100644
index 7059e231..00000000
Binary files a/docs/_build/html/_static/css/fonts/Roboto-Slab-Bold.woff2 and /dev/null differ
diff --git a/docs/_build/html/_static/css/fonts/Roboto-Slab-Regular.woff b/docs/_build/html/_static/css/fonts/Roboto-Slab-Regular.woff
deleted file mode 100644
index f815f63f..00000000
Binary files a/docs/_build/html/_static/css/fonts/Roboto-Slab-Regular.woff and /dev/null differ
diff --git a/docs/_build/html/_static/css/fonts/Roboto-Slab-Regular.woff2 b/docs/_build/html/_static/css/fonts/Roboto-Slab-Regular.woff2
deleted file mode 100644
index f2c76e5b..00000000
Binary files a/docs/_build/html/_static/css/fonts/Roboto-Slab-Regular.woff2 and /dev/null differ
diff --git a/docs/_build/html/_static/css/fonts/fontawesome-webfont.eot b/docs/_build/html/_static/css/fonts/fontawesome-webfont.eot
deleted file mode 100644
index e9f60ca9..00000000
Binary files a/docs/_build/html/_static/css/fonts/fontawesome-webfont.eot and /dev/null differ
diff --git a/docs/_build/html/_static/css/fonts/fontawesome-webfont.svg b/docs/_build/html/_static/css/fonts/fontawesome-webfont.svg
deleted file mode 100644
index 855c845e..00000000
--- a/docs/_build/html/_static/css/fonts/fontawesome-webfont.svg
+++ /dev/null
@@ -1,2671 +0,0 @@
-<?xml version="1.0" standalone="no"?>
-<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" >
-<svg>
-<metadata>
-Created by FontForge 20120731 at Mon Oct 24 17:37:40 2016
- By ,,,
-Copyright Dave Gandy 2016. All rights reserved.
-</metadata>
-<defs>
-<font id="FontAwesome" horiz-adv-x="1536" >
-  <font-face 
-    font-family="FontAwesome"
-    font-weight="400"
-    font-stretch="normal"
-    units-per-em="1792"
-    panose-1="0 0 0 0 0 0 0 0 0 0"
-    ascent="1536"
-    descent="-256"
-    bbox="-1.02083 -256.962 2304.6 1537.02"
-    underline-thickness="0"
-    underline-position="0"
-    unicode-range="U+0020-F500"
-  />
-<missing-glyph horiz-adv-x="896" 
-d="M224 112h448v1312h-448v-1312zM112 0v1536h672v-1536h-672z" />
-    <glyph glyph-name=".notdef" horiz-adv-x="896" 
-d="M224 112h448v1312h-448v-1312zM112 0v1536h672v-1536h-672z" />
-    <glyph glyph-name=".null" horiz-adv-x="0" 
- />
-    <glyph glyph-name="nonmarkingreturn" horiz-adv-x="597" 
- />
-    <glyph glyph-name="space" unicode=" " horiz-adv-x="448" 
- />
-    <glyph glyph-name="dieresis" unicode="&#xa8;" horiz-adv-x="1792" 
- />
-    <glyph glyph-name="copyright" unicode="&#xa9;" horiz-adv-x="1792" 
- />
-    <glyph glyph-name="registered" unicode="&#xae;" horiz-adv-x="1792" 
- />
-    <glyph glyph-name="acute" unicode="&#xb4;" horiz-adv-x="1792" 
- />
-    <glyph glyph-name="AE" unicode="&#xc6;" horiz-adv-x="1792" 
- />
-    <glyph glyph-name="Oslash" unicode="&#xd8;" horiz-adv-x="1792" 
- />
-    <glyph glyph-name="trademark" unicode="&#x2122;" horiz-adv-x="1792" 
- />
-    <glyph glyph-name="infinity" unicode="&#x221e;" horiz-adv-x="1792" 
- />
-    <glyph glyph-name="notequal" unicode="&#x2260;" horiz-adv-x="1792" 
- />
-    <glyph glyph-name="glass" unicode="&#xf000;" horiz-adv-x="1792" 
-d="M1699 1350q0 -35 -43 -78l-632 -632v-768h320q26 0 45 -19t19 -45t-19 -45t-45 -19h-896q-26 0 -45 19t-19 45t19 45t45 19h320v768l-632 632q-43 43 -43 78q0 23 18 36.5t38 17.5t43 4h1408q23 0 43 -4t38 -17.5t18 -36.5z" />
-    <glyph glyph-name="music" unicode="&#xf001;" 
-d="M1536 1312v-1120q0 -50 -34 -89t-86 -60.5t-103.5 -32t-96.5 -10.5t-96.5 10.5t-103.5 32t-86 60.5t-34 89t34 89t86 60.5t103.5 32t96.5 10.5q105 0 192 -39v537l-768 -237v-709q0 -50 -34 -89t-86 -60.5t-103.5 -32t-96.5 -10.5t-96.5 10.5t-103.5 32t-86 60.5t-34 89
-t34 89t86 60.5t103.5 32t96.5 10.5q105 0 192 -39v967q0 31 19 56.5t49 35.5l832 256q12 4 28 4q40 0 68 -28t28 -68z" />
-    <glyph glyph-name="search" unicode="&#xf002;" horiz-adv-x="1664" 
-d="M1152 704q0 185 -131.5 316.5t-316.5 131.5t-316.5 -131.5t-131.5 -316.5t131.5 -316.5t316.5 -131.5t316.5 131.5t131.5 316.5zM1664 -128q0 -52 -38 -90t-90 -38q-54 0 -90 38l-343 342q-179 -124 -399 -124q-143 0 -273.5 55.5t-225 150t-150 225t-55.5 273.5
-t55.5 273.5t150 225t225 150t273.5 55.5t273.5 -55.5t225 -150t150 -225t55.5 -273.5q0 -220 -124 -399l343 -343q37 -37 37 -90z" />
-    <glyph glyph-name="envelope" unicode="&#xf003;" horiz-adv-x="1792" 
-d="M1664 32v768q-32 -36 -69 -66q-268 -206 -426 -338q-51 -43 -83 -67t-86.5 -48.5t-102.5 -24.5h-1h-1q-48 0 -102.5 24.5t-86.5 48.5t-83 67q-158 132 -426 338q-37 30 -69 66v-768q0 -13 9.5 -22.5t22.5 -9.5h1472q13 0 22.5 9.5t9.5 22.5zM1664 1083v11v13.5t-0.5 13
-t-3 12.5t-5.5 9t-9 7.5t-14 2.5h-1472q-13 0 -22.5 -9.5t-9.5 -22.5q0 -168 147 -284q193 -152 401 -317q6 -5 35 -29.5t46 -37.5t44.5 -31.5t50.5 -27.5t43 -9h1h1q20 0 43 9t50.5 27.5t44.5 31.5t46 37.5t35 29.5q208 165 401 317q54 43 100.5 115.5t46.5 131.5z
-M1792 1120v-1088q0 -66 -47 -113t-113 -47h-1472q-66 0 -113 47t-47 113v1088q0 66 47 113t113 47h1472q66 0 113 -47t47 -113z" />
-    <glyph glyph-name="heart" unicode="&#xf004;" horiz-adv-x="1792" 
-d="M896 -128q-26 0 -44 18l-624 602q-10 8 -27.5 26t-55.5 65.5t-68 97.5t-53.5 121t-23.5 138q0 220 127 344t351 124q62 0 126.5 -21.5t120 -58t95.5 -68.5t76 -68q36 36 76 68t95.5 68.5t120 58t126.5 21.5q224 0 351 -124t127 -344q0 -221 -229 -450l-623 -600
-q-18 -18 -44 -18z" />
-    <glyph glyph-name="star" unicode="&#xf005;" horiz-adv-x="1664" 
-d="M1664 889q0 -22 -26 -48l-363 -354l86 -500q1 -7 1 -20q0 -21 -10.5 -35.5t-30.5 -14.5q-19 0 -40 12l-449 236l-449 -236q-22 -12 -40 -12q-21 0 -31.5 14.5t-10.5 35.5q0 6 2 20l86 500l-364 354q-25 27 -25 48q0 37 56 46l502 73l225 455q19 41 49 41t49 -41l225 -455
-l502 -73q56 -9 56 -46z" />
-    <glyph glyph-name="star_empty" unicode="&#xf006;" horiz-adv-x="1664" 
-d="M1137 532l306 297l-422 62l-189 382l-189 -382l-422 -62l306 -297l-73 -421l378 199l377 -199zM1664 889q0 -22 -26 -48l-363 -354l86 -500q1 -7 1 -20q0 -50 -41 -50q-19 0 -40 12l-449 236l-449 -236q-22 -12 -40 -12q-21 0 -31.5 14.5t-10.5 35.5q0 6 2 20l86 500
-l-364 354q-25 27 -25 48q0 37 56 46l502 73l225 455q19 41 49 41t49 -41l225 -455l502 -73q56 -9 56 -46z" />
-    <glyph glyph-name="user" unicode="&#xf007;" horiz-adv-x="1280" 
-d="M1280 137q0 -109 -62.5 -187t-150.5 -78h-854q-88 0 -150.5 78t-62.5 187q0 85 8.5 160.5t31.5 152t58.5 131t94 89t134.5 34.5q131 -128 313 -128t313 128q76 0 134.5 -34.5t94 -89t58.5 -131t31.5 -152t8.5 -160.5zM1024 1024q0 -159 -112.5 -271.5t-271.5 -112.5
-t-271.5 112.5t-112.5 271.5t112.5 271.5t271.5 112.5t271.5 -112.5t112.5 -271.5z" />
-    <glyph glyph-name="film" unicode="&#xf008;" horiz-adv-x="1920" 
-d="M384 -64v128q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45t45 -19h128q26 0 45 19t19 45zM384 320v128q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45t45 -19h128q26 0 45 19t19 45zM384 704v128q0 26 -19 45t-45 19h-128
-q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45t45 -19h128q26 0 45 19t19 45zM1408 -64v512q0 26 -19 45t-45 19h-768q-26 0 -45 -19t-19 -45v-512q0 -26 19 -45t45 -19h768q26 0 45 19t19 45zM384 1088v128q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45
-t45 -19h128q26 0 45 19t19 45zM1792 -64v128q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45t45 -19h128q26 0 45 19t19 45zM1408 704v512q0 26 -19 45t-45 19h-768q-26 0 -45 -19t-19 -45v-512q0 -26 19 -45t45 -19h768q26 0 45 19t19 45zM1792 320v128
-q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45t45 -19h128q26 0 45 19t19 45zM1792 704v128q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45t45 -19h128q26 0 45 19t19 45zM1792 1088v128q0 26 -19 45t-45 19h-128q-26 0 -45 -19
-t-19 -45v-128q0 -26 19 -45t45 -19h128q26 0 45 19t19 45zM1920 1248v-1344q0 -66 -47 -113t-113 -47h-1600q-66 0 -113 47t-47 113v1344q0 66 47 113t113 47h1600q66 0 113 -47t47 -113z" />
-    <glyph glyph-name="th_large" unicode="&#xf009;" horiz-adv-x="1664" 
-d="M768 512v-384q0 -52 -38 -90t-90 -38h-512q-52 0 -90 38t-38 90v384q0 52 38 90t90 38h512q52 0 90 -38t38 -90zM768 1280v-384q0 -52 -38 -90t-90 -38h-512q-52 0 -90 38t-38 90v384q0 52 38 90t90 38h512q52 0 90 -38t38 -90zM1664 512v-384q0 -52 -38 -90t-90 -38
-h-512q-52 0 -90 38t-38 90v384q0 52 38 90t90 38h512q52 0 90 -38t38 -90zM1664 1280v-384q0 -52 -38 -90t-90 -38h-512q-52 0 -90 38t-38 90v384q0 52 38 90t90 38h512q52 0 90 -38t38 -90z" />
-    <glyph glyph-name="th" unicode="&#xf00a;" horiz-adv-x="1792" 
-d="M512 288v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68zM512 800v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68zM1152 288v-192q0 -40 -28 -68t-68 -28h-320
-q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68zM512 1312v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68zM1152 800v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v192q0 40 28 68t68 28
-h320q40 0 68 -28t28 -68zM1792 288v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68zM1152 1312v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68zM1792 800v-192
-q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68zM1792 1312v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68z" />
-    <glyph glyph-name="th_list" unicode="&#xf00b;" horiz-adv-x="1792" 
-d="M512 288v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68zM512 800v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68zM1792 288v-192q0 -40 -28 -68t-68 -28h-960
-q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h960q40 0 68 -28t28 -68zM512 1312v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68zM1792 800v-192q0 -40 -28 -68t-68 -28h-960q-40 0 -68 28t-28 68v192q0 40 28 68t68 28
-h960q40 0 68 -28t28 -68zM1792 1312v-192q0 -40 -28 -68t-68 -28h-960q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h960q40 0 68 -28t28 -68z" />
-    <glyph glyph-name="ok" unicode="&#xf00c;" horiz-adv-x="1792" 
-d="M1671 970q0 -40 -28 -68l-724 -724l-136 -136q-28 -28 -68 -28t-68 28l-136 136l-362 362q-28 28 -28 68t28 68l136 136q28 28 68 28t68 -28l294 -295l656 657q28 28 68 28t68 -28l136 -136q28 -28 28 -68z" />
-    <glyph glyph-name="remove" unicode="&#xf00d;" horiz-adv-x="1408" 
-d="M1298 214q0 -40 -28 -68l-136 -136q-28 -28 -68 -28t-68 28l-294 294l-294 -294q-28 -28 -68 -28t-68 28l-136 136q-28 28 -28 68t28 68l294 294l-294 294q-28 28 -28 68t28 68l136 136q28 28 68 28t68 -28l294 -294l294 294q28 28 68 28t68 -28l136 -136q28 -28 28 -68
-t-28 -68l-294 -294l294 -294q28 -28 28 -68z" />
-    <glyph glyph-name="zoom_in" unicode="&#xf00e;" horiz-adv-x="1664" 
-d="M1024 736v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-224v-224q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v224h-224q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h224v224q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5v-224h224
-q13 0 22.5 -9.5t9.5 -22.5zM1152 704q0 185 -131.5 316.5t-316.5 131.5t-316.5 -131.5t-131.5 -316.5t131.5 -316.5t316.5 -131.5t316.5 131.5t131.5 316.5zM1664 -128q0 -53 -37.5 -90.5t-90.5 -37.5q-54 0 -90 38l-343 342q-179 -124 -399 -124q-143 0 -273.5 55.5
-t-225 150t-150 225t-55.5 273.5t55.5 273.5t150 225t225 150t273.5 55.5t273.5 -55.5t225 -150t150 -225t55.5 -273.5q0 -220 -124 -399l343 -343q37 -37 37 -90z" />
-    <glyph glyph-name="zoom_out" unicode="&#xf010;" horiz-adv-x="1664" 
-d="M1024 736v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-576q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h576q13 0 22.5 -9.5t9.5 -22.5zM1152 704q0 185 -131.5 316.5t-316.5 131.5t-316.5 -131.5t-131.5 -316.5t131.5 -316.5t316.5 -131.5t316.5 131.5t131.5 316.5z
-M1664 -128q0 -53 -37.5 -90.5t-90.5 -37.5q-54 0 -90 38l-343 342q-179 -124 -399 -124q-143 0 -273.5 55.5t-225 150t-150 225t-55.5 273.5t55.5 273.5t150 225t225 150t273.5 55.5t273.5 -55.5t225 -150t150 -225t55.5 -273.5q0 -220 -124 -399l343 -343q37 -37 37 -90z
-" />
-    <glyph glyph-name="off" unicode="&#xf011;" 
-d="M1536 640q0 -156 -61 -298t-164 -245t-245 -164t-298 -61t-298 61t-245 164t-164 245t-61 298q0 182 80.5 343t226.5 270q43 32 95.5 25t83.5 -50q32 -42 24.5 -94.5t-49.5 -84.5q-98 -74 -151.5 -181t-53.5 -228q0 -104 40.5 -198.5t109.5 -163.5t163.5 -109.5
-t198.5 -40.5t198.5 40.5t163.5 109.5t109.5 163.5t40.5 198.5q0 121 -53.5 228t-151.5 181q-42 32 -49.5 84.5t24.5 94.5q31 43 84 50t95 -25q146 -109 226.5 -270t80.5 -343zM896 1408v-640q0 -52 -38 -90t-90 -38t-90 38t-38 90v640q0 52 38 90t90 38t90 -38t38 -90z" />
-    <glyph glyph-name="signal" unicode="&#xf012;" horiz-adv-x="1792" 
-d="M256 96v-192q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h192q14 0 23 -9t9 -23zM640 224v-320q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v320q0 14 9 23t23 9h192q14 0 23 -9t9 -23zM1024 480v-576q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23
-v576q0 14 9 23t23 9h192q14 0 23 -9t9 -23zM1408 864v-960q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v960q0 14 9 23t23 9h192q14 0 23 -9t9 -23zM1792 1376v-1472q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v1472q0 14 9 23t23 9h192q14 0 23 -9t9 -23z" />
-    <glyph glyph-name="cog" unicode="&#xf013;" 
-d="M1024 640q0 106 -75 181t-181 75t-181 -75t-75 -181t75 -181t181 -75t181 75t75 181zM1536 749v-222q0 -12 -8 -23t-20 -13l-185 -28q-19 -54 -39 -91q35 -50 107 -138q10 -12 10 -25t-9 -23q-27 -37 -99 -108t-94 -71q-12 0 -26 9l-138 108q-44 -23 -91 -38
-q-16 -136 -29 -186q-7 -28 -36 -28h-222q-14 0 -24.5 8.5t-11.5 21.5l-28 184q-49 16 -90 37l-141 -107q-10 -9 -25 -9q-14 0 -25 11q-126 114 -165 168q-7 10 -7 23q0 12 8 23q15 21 51 66.5t54 70.5q-27 50 -41 99l-183 27q-13 2 -21 12.5t-8 23.5v222q0 12 8 23t19 13
-l186 28q14 46 39 92q-40 57 -107 138q-10 12 -10 24q0 10 9 23q26 36 98.5 107.5t94.5 71.5q13 0 26 -10l138 -107q44 23 91 38q16 136 29 186q7 28 36 28h222q14 0 24.5 -8.5t11.5 -21.5l28 -184q49 -16 90 -37l142 107q9 9 24 9q13 0 25 -10q129 -119 165 -170q7 -8 7 -22
-q0 -12 -8 -23q-15 -21 -51 -66.5t-54 -70.5q26 -50 41 -98l183 -28q13 -2 21 -12.5t8 -23.5z" />
-    <glyph glyph-name="trash" unicode="&#xf014;" horiz-adv-x="1408" 
-d="M512 800v-576q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v576q0 14 9 23t23 9h64q14 0 23 -9t9 -23zM768 800v-576q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v576q0 14 9 23t23 9h64q14 0 23 -9t9 -23zM1024 800v-576q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v576
-q0 14 9 23t23 9h64q14 0 23 -9t9 -23zM1152 76v948h-896v-948q0 -22 7 -40.5t14.5 -27t10.5 -8.5h832q3 0 10.5 8.5t14.5 27t7 40.5zM480 1152h448l-48 117q-7 9 -17 11h-317q-10 -2 -17 -11zM1408 1120v-64q0 -14 -9 -23t-23 -9h-96v-948q0 -83 -47 -143.5t-113 -60.5h-832
-q-66 0 -113 58.5t-47 141.5v952h-96q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h309l70 167q15 37 54 63t79 26h320q40 0 79 -26t54 -63l70 -167h309q14 0 23 -9t9 -23z" />
-    <glyph glyph-name="home" unicode="&#xf015;" horiz-adv-x="1664" 
-d="M1408 544v-480q0 -26 -19 -45t-45 -19h-384v384h-256v-384h-384q-26 0 -45 19t-19 45v480q0 1 0.5 3t0.5 3l575 474l575 -474q1 -2 1 -6zM1631 613l-62 -74q-8 -9 -21 -11h-3q-13 0 -21 7l-692 577l-692 -577q-12 -8 -24 -7q-13 2 -21 11l-62 74q-8 10 -7 23.5t11 21.5
-l719 599q32 26 76 26t76 -26l244 -204v195q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-408l219 -182q10 -8 11 -21.5t-7 -23.5z" />
-    <glyph glyph-name="file_alt" unicode="&#xf016;" 
-d="M1468 1156q28 -28 48 -76t20 -88v-1152q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68v1600q0 40 28 68t68 28h896q40 0 88 -20t76 -48zM1024 1400v-376h376q-10 29 -22 41l-313 313q-12 12 -41 22zM1408 -128v1024h-416q-40 0 -68 28t-28 68v416h-768v-1536h1280z
-" />
-    <glyph glyph-name="time" unicode="&#xf017;" 
-d="M896 992v-448q0 -14 -9 -23t-23 -9h-320q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h224v352q0 14 9 23t23 9h64q14 0 23 -9t9 -23zM1312 640q0 148 -73 273t-198 198t-273 73t-273 -73t-198 -198t-73 -273t73 -273t198 -198t273 -73t273 73t198 198t73 273zM1536 640
-q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
-    <glyph glyph-name="road" unicode="&#xf018;" horiz-adv-x="1920" 
-d="M1111 540v4l-24 320q-1 13 -11 22.5t-23 9.5h-186q-13 0 -23 -9.5t-11 -22.5l-24 -320v-4q-1 -12 8 -20t21 -8h244q12 0 21 8t8 20zM1870 73q0 -73 -46 -73h-704q13 0 22 9.5t8 22.5l-20 256q-1 13 -11 22.5t-23 9.5h-272q-13 0 -23 -9.5t-11 -22.5l-20 -256
-q-1 -13 8 -22.5t22 -9.5h-704q-46 0 -46 73q0 54 26 116l417 1044q8 19 26 33t38 14h339q-13 0 -23 -9.5t-11 -22.5l-15 -192q-1 -14 8 -23t22 -9h166q13 0 22 9t8 23l-15 192q-1 13 -11 22.5t-23 9.5h339q20 0 38 -14t26 -33l417 -1044q26 -62 26 -116z" />
-    <glyph glyph-name="download_alt" unicode="&#xf019;" horiz-adv-x="1664" 
-d="M1280 192q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1536 192q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1664 416v-320q0 -40 -28 -68t-68 -28h-1472q-40 0 -68 28t-28 68v320q0 40 28 68t68 28h465l135 -136
-q58 -56 136 -56t136 56l136 136h464q40 0 68 -28t28 -68zM1339 985q17 -41 -14 -70l-448 -448q-18 -19 -45 -19t-45 19l-448 448q-31 29 -14 70q17 39 59 39h256v448q0 26 19 45t45 19h256q26 0 45 -19t19 -45v-448h256q42 0 59 -39z" />
-    <glyph glyph-name="download" unicode="&#xf01a;" 
-d="M1120 608q0 -12 -10 -24l-319 -319q-11 -9 -23 -9t-23 9l-320 320q-15 16 -7 35q8 20 30 20h192v352q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-352h192q14 0 23 -9t9 -23zM768 1184q-148 0 -273 -73t-198 -198t-73 -273t73 -273t198 -198t273 -73t273 73t198 198t73 273
-t-73 273t-198 198t-273 73zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
-    <glyph glyph-name="upload" unicode="&#xf01b;" 
-d="M1118 660q-8 -20 -30 -20h-192v-352q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v352h-192q-14 0 -23 9t-9 23q0 12 10 24l319 319q11 9 23 9t23 -9l320 -320q15 -16 7 -35zM768 1184q-148 0 -273 -73t-198 -198t-73 -273t73 -273t198 -198t273 -73t273 73t198 198
-t73 273t-73 273t-198 198t-273 73zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
-    <glyph glyph-name="inbox" unicode="&#xf01c;" 
-d="M1023 576h316q-1 3 -2.5 8.5t-2.5 7.5l-212 496h-708l-212 -496q-1 -3 -2.5 -8.5t-2.5 -7.5h316l95 -192h320zM1536 546v-482q0 -26 -19 -45t-45 -19h-1408q-26 0 -45 19t-19 45v482q0 62 25 123l238 552q10 25 36.5 42t52.5 17h832q26 0 52.5 -17t36.5 -42l238 -552
-q25 -61 25 -123z" />
-    <glyph glyph-name="play_circle" unicode="&#xf01d;" 
-d="M1184 640q0 -37 -32 -55l-544 -320q-15 -9 -32 -9q-16 0 -32 8q-32 19 -32 56v640q0 37 32 56q33 18 64 -1l544 -320q32 -18 32 -55zM1312 640q0 148 -73 273t-198 198t-273 73t-273 -73t-198 -198t-73 -273t73 -273t198 -198t273 -73t273 73t198 198t73 273zM1536 640
-q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
-    <glyph glyph-name="repeat" unicode="&#xf01e;" 
-d="M1536 1280v-448q0 -26 -19 -45t-45 -19h-448q-42 0 -59 40q-17 39 14 69l138 138q-148 137 -349 137q-104 0 -198.5 -40.5t-163.5 -109.5t-109.5 -163.5t-40.5 -198.5t40.5 -198.5t109.5 -163.5t163.5 -109.5t198.5 -40.5q119 0 225 52t179 147q7 10 23 12q15 0 25 -9
-l137 -138q9 -8 9.5 -20.5t-7.5 -22.5q-109 -132 -264 -204.5t-327 -72.5q-156 0 -298 61t-245 164t-164 245t-61 298t61 298t164 245t245 164t298 61q147 0 284.5 -55.5t244.5 -156.5l130 129q29 31 70 14q39 -17 39 -59z" />
-    <glyph glyph-name="refresh" unicode="&#xf021;" 
-d="M1511 480q0 -5 -1 -7q-64 -268 -268 -434.5t-478 -166.5q-146 0 -282.5 55t-243.5 157l-129 -129q-19 -19 -45 -19t-45 19t-19 45v448q0 26 19 45t45 19h448q26 0 45 -19t19 -45t-19 -45l-137 -137q71 -66 161 -102t187 -36q134 0 250 65t186 179q11 17 53 117
-q8 23 30 23h192q13 0 22.5 -9.5t9.5 -22.5zM1536 1280v-448q0 -26 -19 -45t-45 -19h-448q-26 0 -45 19t-19 45t19 45l138 138q-148 137 -349 137q-134 0 -250 -65t-186 -179q-11 -17 -53 -117q-8 -23 -30 -23h-199q-13 0 -22.5 9.5t-9.5 22.5v7q65 268 270 434.5t480 166.5
-q146 0 284 -55.5t245 -156.5l130 129q19 19 45 19t45 -19t19 -45z" />
-    <glyph glyph-name="list_alt" unicode="&#xf022;" horiz-adv-x="1792" 
-d="M384 352v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM384 608v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z
-M384 864v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM1536 352v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-960q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h960q13 0 22.5 -9.5t9.5 -22.5z
-M1536 608v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-960q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h960q13 0 22.5 -9.5t9.5 -22.5zM1536 864v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-960q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h960q13 0 22.5 -9.5
-t9.5 -22.5zM1664 160v832q0 13 -9.5 22.5t-22.5 9.5h-1472q-13 0 -22.5 -9.5t-9.5 -22.5v-832q0 -13 9.5 -22.5t22.5 -9.5h1472q13 0 22.5 9.5t9.5 22.5zM1792 1248v-1088q0 -66 -47 -113t-113 -47h-1472q-66 0 -113 47t-47 113v1088q0 66 47 113t113 47h1472q66 0 113 -47
-t47 -113z" />
-    <glyph glyph-name="lock" unicode="&#xf023;" horiz-adv-x="1152" 
-d="M320 768h512v192q0 106 -75 181t-181 75t-181 -75t-75 -181v-192zM1152 672v-576q0 -40 -28 -68t-68 -28h-960q-40 0 -68 28t-28 68v576q0 40 28 68t68 28h32v192q0 184 132 316t316 132t316 -132t132 -316v-192h32q40 0 68 -28t28 -68z" />
-    <glyph glyph-name="flag" unicode="&#xf024;" horiz-adv-x="1792" 
-d="M320 1280q0 -72 -64 -110v-1266q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v1266q-64 38 -64 110q0 53 37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1792 1216v-763q0 -25 -12.5 -38.5t-39.5 -27.5q-215 -116 -369 -116q-61 0 -123.5 22t-108.5 48
-t-115.5 48t-142.5 22q-192 0 -464 -146q-17 -9 -33 -9q-26 0 -45 19t-19 45v742q0 32 31 55q21 14 79 43q236 120 421 120q107 0 200 -29t219 -88q38 -19 88 -19q54 0 117.5 21t110 47t88 47t54.5 21q26 0 45 -19t19 -45z" />
-    <glyph glyph-name="headphones" unicode="&#xf025;" horiz-adv-x="1664" 
-d="M1664 650q0 -166 -60 -314l-20 -49l-185 -33q-22 -83 -90.5 -136.5t-156.5 -53.5v-32q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v576q0 14 9 23t23 9h64q14 0 23 -9t9 -23v-32q71 0 130 -35.5t93 -95.5l68 12q29 95 29 193q0 148 -88 279t-236.5 209t-315.5 78
-t-315.5 -78t-236.5 -209t-88 -279q0 -98 29 -193l68 -12q34 60 93 95.5t130 35.5v32q0 14 9 23t23 9h64q14 0 23 -9t9 -23v-576q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v32q-88 0 -156.5 53.5t-90.5 136.5l-185 33l-20 49q-60 148 -60 314q0 151 67 291t179 242.5
-t266 163.5t320 61t320 -61t266 -163.5t179 -242.5t67 -291z" />
-    <glyph glyph-name="volume_off" unicode="&#xf026;" horiz-adv-x="768" 
-d="M768 1184v-1088q0 -26 -19 -45t-45 -19t-45 19l-333 333h-262q-26 0 -45 19t-19 45v384q0 26 19 45t45 19h262l333 333q19 19 45 19t45 -19t19 -45z" />
-    <glyph glyph-name="volume_down" unicode="&#xf027;" horiz-adv-x="1152" 
-d="M768 1184v-1088q0 -26 -19 -45t-45 -19t-45 19l-333 333h-262q-26 0 -45 19t-19 45v384q0 26 19 45t45 19h262l333 333q19 19 45 19t45 -19t19 -45zM1152 640q0 -76 -42.5 -141.5t-112.5 -93.5q-10 -5 -25 -5q-26 0 -45 18.5t-19 45.5q0 21 12 35.5t29 25t34 23t29 36
-t12 56.5t-12 56.5t-29 36t-34 23t-29 25t-12 35.5q0 27 19 45.5t45 18.5q15 0 25 -5q70 -27 112.5 -93t42.5 -142z" />
-    <glyph glyph-name="volume_up" unicode="&#xf028;" horiz-adv-x="1664" 
-d="M768 1184v-1088q0 -26 -19 -45t-45 -19t-45 19l-333 333h-262q-26 0 -45 19t-19 45v384q0 26 19 45t45 19h262l333 333q19 19 45 19t45 -19t19 -45zM1152 640q0 -76 -42.5 -141.5t-112.5 -93.5q-10 -5 -25 -5q-26 0 -45 18.5t-19 45.5q0 21 12 35.5t29 25t34 23t29 36
-t12 56.5t-12 56.5t-29 36t-34 23t-29 25t-12 35.5q0 27 19 45.5t45 18.5q15 0 25 -5q70 -27 112.5 -93t42.5 -142zM1408 640q0 -153 -85 -282.5t-225 -188.5q-13 -5 -25 -5q-27 0 -46 19t-19 45q0 39 39 59q56 29 76 44q74 54 115.5 135.5t41.5 173.5t-41.5 173.5
-t-115.5 135.5q-20 15 -76 44q-39 20 -39 59q0 26 19 45t45 19q13 0 26 -5q140 -59 225 -188.5t85 -282.5zM1664 640q0 -230 -127 -422.5t-338 -283.5q-13 -5 -26 -5q-26 0 -45 19t-19 45q0 36 39 59q7 4 22.5 10.5t22.5 10.5q46 25 82 51q123 91 192 227t69 289t-69 289
-t-192 227q-36 26 -82 51q-7 4 -22.5 10.5t-22.5 10.5q-39 23 -39 59q0 26 19 45t45 19q13 0 26 -5q211 -91 338 -283.5t127 -422.5z" />
-    <glyph glyph-name="qrcode" unicode="&#xf029;" horiz-adv-x="1408" 
-d="M384 384v-128h-128v128h128zM384 1152v-128h-128v128h128zM1152 1152v-128h-128v128h128zM128 129h384v383h-384v-383zM128 896h384v384h-384v-384zM896 896h384v384h-384v-384zM640 640v-640h-640v640h640zM1152 128v-128h-128v128h128zM1408 128v-128h-128v128h128z
-M1408 640v-384h-384v128h-128v-384h-128v640h384v-128h128v128h128zM640 1408v-640h-640v640h640zM1408 1408v-640h-640v640h640z" />
-    <glyph glyph-name="barcode" unicode="&#xf02a;" horiz-adv-x="1792" 
-d="M63 0h-63v1408h63v-1408zM126 1h-32v1407h32v-1407zM220 1h-31v1407h31v-1407zM377 1h-31v1407h31v-1407zM534 1h-62v1407h62v-1407zM660 1h-31v1407h31v-1407zM723 1h-31v1407h31v-1407zM786 1h-31v1407h31v-1407zM943 1h-63v1407h63v-1407zM1100 1h-63v1407h63v-1407z
-M1226 1h-63v1407h63v-1407zM1352 1h-63v1407h63v-1407zM1446 1h-63v1407h63v-1407zM1635 1h-94v1407h94v-1407zM1698 1h-32v1407h32v-1407zM1792 0h-63v1408h63v-1408z" />
-    <glyph glyph-name="tag" unicode="&#xf02b;" 
-d="M448 1088q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1515 512q0 -53 -37 -90l-491 -492q-39 -37 -91 -37q-53 0 -90 37l-715 716q-38 37 -64.5 101t-26.5 117v416q0 52 38 90t90 38h416q53 0 117 -26.5t102 -64.5
-l715 -714q37 -39 37 -91z" />
-    <glyph glyph-name="tags" unicode="&#xf02c;" horiz-adv-x="1920" 
-d="M448 1088q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1515 512q0 -53 -37 -90l-491 -492q-39 -37 -91 -37q-53 0 -90 37l-715 716q-38 37 -64.5 101t-26.5 117v416q0 52 38 90t90 38h416q53 0 117 -26.5t102 -64.5
-l715 -714q37 -39 37 -91zM1899 512q0 -53 -37 -90l-491 -492q-39 -37 -91 -37q-36 0 -59 14t-53 45l470 470q37 37 37 90q0 52 -37 91l-715 714q-38 38 -102 64.5t-117 26.5h224q53 0 117 -26.5t102 -64.5l715 -714q37 -39 37 -91z" />
-    <glyph glyph-name="book" unicode="&#xf02d;" horiz-adv-x="1664" 
-d="M1639 1058q40 -57 18 -129l-275 -906q-19 -64 -76.5 -107.5t-122.5 -43.5h-923q-77 0 -148.5 53.5t-99.5 131.5q-24 67 -2 127q0 4 3 27t4 37q1 8 -3 21.5t-3 19.5q2 11 8 21t16.5 23.5t16.5 23.5q23 38 45 91.5t30 91.5q3 10 0.5 30t-0.5 28q3 11 17 28t17 23
-q21 36 42 92t25 90q1 9 -2.5 32t0.5 28q4 13 22 30.5t22 22.5q19 26 42.5 84.5t27.5 96.5q1 8 -3 25.5t-2 26.5q2 8 9 18t18 23t17 21q8 12 16.5 30.5t15 35t16 36t19.5 32t26.5 23.5t36 11.5t47.5 -5.5l-1 -3q38 9 51 9h761q74 0 114 -56t18 -130l-274 -906
-q-36 -119 -71.5 -153.5t-128.5 -34.5h-869q-27 0 -38 -15q-11 -16 -1 -43q24 -70 144 -70h923q29 0 56 15.5t35 41.5l300 987q7 22 5 57q38 -15 59 -43zM575 1056q-4 -13 2 -22.5t20 -9.5h608q13 0 25.5 9.5t16.5 22.5l21 64q4 13 -2 22.5t-20 9.5h-608q-13 0 -25.5 -9.5
-t-16.5 -22.5zM492 800q-4 -13 2 -22.5t20 -9.5h608q13 0 25.5 9.5t16.5 22.5l21 64q4 13 -2 22.5t-20 9.5h-608q-13 0 -25.5 -9.5t-16.5 -22.5z" />
-    <glyph glyph-name="bookmark" unicode="&#xf02e;" horiz-adv-x="1280" 
-d="M1164 1408q23 0 44 -9q33 -13 52.5 -41t19.5 -62v-1289q0 -34 -19.5 -62t-52.5 -41q-19 -8 -44 -8q-48 0 -83 32l-441 424l-441 -424q-36 -33 -83 -33q-23 0 -44 9q-33 13 -52.5 41t-19.5 62v1289q0 34 19.5 62t52.5 41q21 9 44 9h1048z" />
-    <glyph glyph-name="print" unicode="&#xf02f;" horiz-adv-x="1664" 
-d="M384 0h896v256h-896v-256zM384 640h896v384h-160q-40 0 -68 28t-28 68v160h-640v-640zM1536 576q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1664 576v-416q0 -13 -9.5 -22.5t-22.5 -9.5h-224v-160q0 -40 -28 -68t-68 -28h-960q-40 0 -68 28t-28 68
-v160h-224q-13 0 -22.5 9.5t-9.5 22.5v416q0 79 56.5 135.5t135.5 56.5h64v544q0 40 28 68t68 28h672q40 0 88 -20t76 -48l152 -152q28 -28 48 -76t20 -88v-256h64q79 0 135.5 -56.5t56.5 -135.5z" />
-    <glyph glyph-name="camera" unicode="&#xf030;" horiz-adv-x="1920" 
-d="M960 864q119 0 203.5 -84.5t84.5 -203.5t-84.5 -203.5t-203.5 -84.5t-203.5 84.5t-84.5 203.5t84.5 203.5t203.5 84.5zM1664 1280q106 0 181 -75t75 -181v-896q0 -106 -75 -181t-181 -75h-1408q-106 0 -181 75t-75 181v896q0 106 75 181t181 75h224l51 136
-q19 49 69.5 84.5t103.5 35.5h512q53 0 103.5 -35.5t69.5 -84.5l51 -136h224zM960 128q185 0 316.5 131.5t131.5 316.5t-131.5 316.5t-316.5 131.5t-316.5 -131.5t-131.5 -316.5t131.5 -316.5t316.5 -131.5z" />
-    <glyph glyph-name="font" unicode="&#xf031;" horiz-adv-x="1664" 
-d="M725 977l-170 -450q33 0 136.5 -2t160.5 -2q19 0 57 2q-87 253 -184 452zM0 -128l2 79q23 7 56 12.5t57 10.5t49.5 14.5t44.5 29t31 50.5l237 616l280 724h75h53q8 -14 11 -21l205 -480q33 -78 106 -257.5t114 -274.5q15 -34 58 -144.5t72 -168.5q20 -45 35 -57
-q19 -15 88 -29.5t84 -20.5q6 -38 6 -57q0 -5 -0.5 -13.5t-0.5 -12.5q-63 0 -190 8t-191 8q-76 0 -215 -7t-178 -8q0 43 4 78l131 28q1 0 12.5 2.5t15.5 3.5t14.5 4.5t15 6.5t11 8t9 11t2.5 14q0 16 -31 96.5t-72 177.5t-42 100l-450 2q-26 -58 -76.5 -195.5t-50.5 -162.5
-q0 -22 14 -37.5t43.5 -24.5t48.5 -13.5t57 -8.5t41 -4q1 -19 1 -58q0 -9 -2 -27q-58 0 -174.5 10t-174.5 10q-8 0 -26.5 -4t-21.5 -4q-80 -14 -188 -14z" />
-    <glyph glyph-name="bold" unicode="&#xf032;" horiz-adv-x="1408" 
-d="M555 15q74 -32 140 -32q376 0 376 335q0 114 -41 180q-27 44 -61.5 74t-67.5 46.5t-80.5 25t-84 10.5t-94.5 2q-73 0 -101 -10q0 -53 -0.5 -159t-0.5 -158q0 -8 -1 -67.5t-0.5 -96.5t4.5 -83.5t12 -66.5zM541 761q42 -7 109 -7q82 0 143 13t110 44.5t74.5 89.5t25.5 142
-q0 70 -29 122.5t-79 82t-108 43.5t-124 14q-50 0 -130 -13q0 -50 4 -151t4 -152q0 -27 -0.5 -80t-0.5 -79q0 -46 1 -69zM0 -128l2 94q15 4 85 16t106 27q7 12 12.5 27t8.5 33.5t5.5 32.5t3 37.5t0.5 34v35.5v30q0 982 -22 1025q-4 8 -22 14.5t-44.5 11t-49.5 7t-48.5 4.5
-t-30.5 3l-4 83q98 2 340 11.5t373 9.5q23 0 68 -0.5t68 -0.5q70 0 136.5 -13t128.5 -42t108 -71t74 -104.5t28 -137.5q0 -52 -16.5 -95.5t-39 -72t-64.5 -57.5t-73 -45t-84 -40q154 -35 256.5 -134t102.5 -248q0 -100 -35 -179.5t-93.5 -130.5t-138 -85.5t-163.5 -48.5
-t-176 -14q-44 0 -132 3t-132 3q-106 0 -307 -11t-231 -12z" />
-    <glyph glyph-name="italic" unicode="&#xf033;" horiz-adv-x="1024" 
-d="M0 -126l17 85q22 7 61.5 16.5t72 19t59.5 23.5q28 35 41 101q1 7 62 289t114 543.5t52 296.5v25q-24 13 -54.5 18.5t-69.5 8t-58 5.5l19 103q33 -2 120 -6.5t149.5 -7t120.5 -2.5q48 0 98.5 2.5t121 7t98.5 6.5q-5 -39 -19 -89q-30 -10 -101.5 -28.5t-108.5 -33.5
-q-8 -19 -14 -42.5t-9 -40t-7.5 -45.5t-6.5 -42q-27 -148 -87.5 -419.5t-77.5 -355.5q-2 -9 -13 -58t-20 -90t-16 -83.5t-6 -57.5l1 -18q17 -4 185 -31q-3 -44 -16 -99q-11 0 -32.5 -1.5t-32.5 -1.5q-29 0 -87 10t-86 10q-138 2 -206 2q-51 0 -143 -9t-121 -11z" />
-    <glyph glyph-name="text_height" unicode="&#xf034;" horiz-adv-x="1792" 
-d="M1744 128q33 0 42 -18.5t-11 -44.5l-126 -162q-20 -26 -49 -26t-49 26l-126 162q-20 26 -11 44.5t42 18.5h80v1024h-80q-33 0 -42 18.5t11 44.5l126 162q20 26 49 26t49 -26l126 -162q20 -26 11 -44.5t-42 -18.5h-80v-1024h80zM81 1407l54 -27q12 -5 211 -5q44 0 132 2
-t132 2q36 0 107.5 -0.5t107.5 -0.5h293q6 0 21 -0.5t20.5 0t16 3t17.5 9t15 17.5l42 1q4 0 14 -0.5t14 -0.5q2 -112 2 -336q0 -80 -5 -109q-39 -14 -68 -18q-25 44 -54 128q-3 9 -11 48t-14.5 73.5t-7.5 35.5q-6 8 -12 12.5t-15.5 6t-13 2.5t-18 0.5t-16.5 -0.5
-q-17 0 -66.5 0.5t-74.5 0.5t-64 -2t-71 -6q-9 -81 -8 -136q0 -94 2 -388t2 -455q0 -16 -2.5 -71.5t0 -91.5t12.5 -69q40 -21 124 -42.5t120 -37.5q5 -40 5 -50q0 -14 -3 -29l-34 -1q-76 -2 -218 8t-207 10q-50 0 -151 -9t-152 -9q-3 51 -3 52v9q17 27 61.5 43t98.5 29t78 27
-q19 42 19 383q0 101 -3 303t-3 303v117q0 2 0.5 15.5t0.5 25t-1 25.5t-3 24t-5 14q-11 12 -162 12q-33 0 -93 -12t-80 -26q-19 -13 -34 -72.5t-31.5 -111t-42.5 -53.5q-42 26 -56 44v383z" />
-    <glyph glyph-name="text_width" unicode="&#xf035;" 
-d="M81 1407l54 -27q12 -5 211 -5q44 0 132 2t132 2q70 0 246.5 1t304.5 0.5t247 -4.5q33 -1 56 31l42 1q4 0 14 -0.5t14 -0.5q2 -112 2 -336q0 -80 -5 -109q-39 -14 -68 -18q-25 44 -54 128q-3 9 -11 47.5t-15 73.5t-7 36q-10 13 -27 19q-5 2 -66 2q-30 0 -93 1t-103 1
-t-94 -2t-96 -7q-9 -81 -8 -136l1 -152v52q0 -55 1 -154t1.5 -180t0.5 -153q0 -16 -2.5 -71.5t0 -91.5t12.5 -69q40 -21 124 -42.5t120 -37.5q5 -40 5 -50q0 -14 -3 -29l-34 -1q-76 -2 -218 8t-207 10q-50 0 -151 -9t-152 -9q-3 51 -3 52v9q17 27 61.5 43t98.5 29t78 27
-q7 16 11.5 74t6 145.5t1.5 155t-0.5 153.5t-0.5 89q0 7 -2.5 21.5t-2.5 22.5q0 7 0.5 44t1 73t0 76.5t-3 67.5t-6.5 32q-11 12 -162 12q-41 0 -163 -13.5t-138 -24.5q-19 -12 -34 -71.5t-31.5 -111.5t-42.5 -54q-42 26 -56 44v383zM1310 125q12 0 42 -19.5t57.5 -41.5
-t59.5 -49t36 -30q26 -21 26 -49t-26 -49q-4 -3 -36 -30t-59.5 -49t-57.5 -41.5t-42 -19.5q-13 0 -20.5 10.5t-10 28.5t-2.5 33.5t1.5 33t1.5 19.5h-1024q0 -2 1.5 -19.5t1.5 -33t-2.5 -33.5t-10 -28.5t-20.5 -10.5q-12 0 -42 19.5t-57.5 41.5t-59.5 49t-36 30q-26 21 -26 49
-t26 49q4 3 36 30t59.5 49t57.5 41.5t42 19.5q13 0 20.5 -10.5t10 -28.5t2.5 -33.5t-1.5 -33t-1.5 -19.5h1024q0 2 -1.5 19.5t-1.5 33t2.5 33.5t10 28.5t20.5 10.5z" />
-    <glyph glyph-name="align_left" unicode="&#xf036;" horiz-adv-x="1792" 
-d="M1792 192v-128q0 -26 -19 -45t-45 -19h-1664q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1664q26 0 45 -19t19 -45zM1408 576v-128q0 -26 -19 -45t-45 -19h-1280q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1280q26 0 45 -19t19 -45zM1664 960v-128q0 -26 -19 -45
-t-45 -19h-1536q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1536q26 0 45 -19t19 -45zM1280 1344v-128q0 -26 -19 -45t-45 -19h-1152q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1152q26 0 45 -19t19 -45z" />
-    <glyph glyph-name="align_center" unicode="&#xf037;" horiz-adv-x="1792" 
-d="M1792 192v-128q0 -26 -19 -45t-45 -19h-1664q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1664q26 0 45 -19t19 -45zM1408 576v-128q0 -26 -19 -45t-45 -19h-896q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h896q26 0 45 -19t19 -45zM1664 960v-128q0 -26 -19 -45t-45 -19
-h-1408q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1408q26 0 45 -19t19 -45zM1280 1344v-128q0 -26 -19 -45t-45 -19h-640q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h640q26 0 45 -19t19 -45z" />
-    <glyph glyph-name="align_right" unicode="&#xf038;" horiz-adv-x="1792" 
-d="M1792 192v-128q0 -26 -19 -45t-45 -19h-1664q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1664q26 0 45 -19t19 -45zM1792 576v-128q0 -26 -19 -45t-45 -19h-1280q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1280q26 0 45 -19t19 -45zM1792 960v-128q0 -26 -19 -45
-t-45 -19h-1536q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1536q26 0 45 -19t19 -45zM1792 1344v-128q0 -26 -19 -45t-45 -19h-1152q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1152q26 0 45 -19t19 -45z" />
-    <glyph glyph-name="align_justify" unicode="&#xf039;" horiz-adv-x="1792" 
-d="M1792 192v-128q0 -26 -19 -45t-45 -19h-1664q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1664q26 0 45 -19t19 -45zM1792 576v-128q0 -26 -19 -45t-45 -19h-1664q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1664q26 0 45 -19t19 -45zM1792 960v-128q0 -26 -19 -45
-t-45 -19h-1664q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1664q26 0 45 -19t19 -45zM1792 1344v-128q0 -26 -19 -45t-45 -19h-1664q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1664q26 0 45 -19t19 -45z" />
-    <glyph glyph-name="list" unicode="&#xf03a;" horiz-adv-x="1792" 
-d="M256 224v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-192q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h192q13 0 22.5 -9.5t9.5 -22.5zM256 608v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-192q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h192q13 0 22.5 -9.5
-t9.5 -22.5zM256 992v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-192q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h192q13 0 22.5 -9.5t9.5 -22.5zM1792 224v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1344q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1344
-q13 0 22.5 -9.5t9.5 -22.5zM256 1376v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-192q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h192q13 0 22.5 -9.5t9.5 -22.5zM1792 608v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1344q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5
-t22.5 9.5h1344q13 0 22.5 -9.5t9.5 -22.5zM1792 992v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1344q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1344q13 0 22.5 -9.5t9.5 -22.5zM1792 1376v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1344q-13 0 -22.5 9.5t-9.5 22.5v192
-q0 13 9.5 22.5t22.5 9.5h1344q13 0 22.5 -9.5t9.5 -22.5z" />
-    <glyph glyph-name="indent_left" unicode="&#xf03b;" horiz-adv-x="1792" 
-d="M384 992v-576q0 -13 -9.5 -22.5t-22.5 -9.5q-14 0 -23 9l-288 288q-9 9 -9 23t9 23l288 288q9 9 23 9q13 0 22.5 -9.5t9.5 -22.5zM1792 224v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1728q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1728q13 0 22.5 -9.5
-t9.5 -22.5zM1792 608v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1088q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1088q13 0 22.5 -9.5t9.5 -22.5zM1792 992v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1088q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1088
-q13 0 22.5 -9.5t9.5 -22.5zM1792 1376v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1728q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1728q13 0 22.5 -9.5t9.5 -22.5z" />
-    <glyph glyph-name="indent_right" unicode="&#xf03c;" horiz-adv-x="1792" 
-d="M352 704q0 -14 -9 -23l-288 -288q-9 -9 -23 -9q-13 0 -22.5 9.5t-9.5 22.5v576q0 13 9.5 22.5t22.5 9.5q14 0 23 -9l288 -288q9 -9 9 -23zM1792 224v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1728q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1728q13 0 22.5 -9.5
-t9.5 -22.5zM1792 608v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1088q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1088q13 0 22.5 -9.5t9.5 -22.5zM1792 992v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1088q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1088
-q13 0 22.5 -9.5t9.5 -22.5zM1792 1376v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1728q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1728q13 0 22.5 -9.5t9.5 -22.5z" />
-    <glyph glyph-name="facetime_video" unicode="&#xf03d;" horiz-adv-x="1792" 
-d="M1792 1184v-1088q0 -42 -39 -59q-13 -5 -25 -5q-27 0 -45 19l-403 403v-166q0 -119 -84.5 -203.5t-203.5 -84.5h-704q-119 0 -203.5 84.5t-84.5 203.5v704q0 119 84.5 203.5t203.5 84.5h704q119 0 203.5 -84.5t84.5 -203.5v-165l403 402q18 19 45 19q12 0 25 -5
-q39 -17 39 -59z" />
-    <glyph glyph-name="picture" unicode="&#xf03e;" horiz-adv-x="1920" 
-d="M640 960q0 -80 -56 -136t-136 -56t-136 56t-56 136t56 136t136 56t136 -56t56 -136zM1664 576v-448h-1408v192l320 320l160 -160l512 512zM1760 1280h-1600q-13 0 -22.5 -9.5t-9.5 -22.5v-1216q0 -13 9.5 -22.5t22.5 -9.5h1600q13 0 22.5 9.5t9.5 22.5v1216
-q0 13 -9.5 22.5t-22.5 9.5zM1920 1248v-1216q0 -66 -47 -113t-113 -47h-1600q-66 0 -113 47t-47 113v1216q0 66 47 113t113 47h1600q66 0 113 -47t47 -113z" />
-    <glyph glyph-name="pencil" unicode="&#xf040;" 
-d="M363 0l91 91l-235 235l-91 -91v-107h128v-128h107zM886 928q0 22 -22 22q-10 0 -17 -7l-542 -542q-7 -7 -7 -17q0 -22 22 -22q10 0 17 7l542 542q7 7 7 17zM832 1120l416 -416l-832 -832h-416v416zM1515 1024q0 -53 -37 -90l-166 -166l-416 416l166 165q36 38 90 38
-q53 0 91 -38l235 -234q37 -39 37 -91z" />
-    <glyph glyph-name="map_marker" unicode="&#xf041;" horiz-adv-x="1024" 
-d="M768 896q0 106 -75 181t-181 75t-181 -75t-75 -181t75 -181t181 -75t181 75t75 181zM1024 896q0 -109 -33 -179l-364 -774q-16 -33 -47.5 -52t-67.5 -19t-67.5 19t-46.5 52l-365 774q-33 70 -33 179q0 212 150 362t362 150t362 -150t150 -362z" />
-    <glyph glyph-name="adjust" unicode="&#xf042;" 
-d="M768 96v1088q-148 0 -273 -73t-198 -198t-73 -273t73 -273t198 -198t273 -73zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
-    <glyph glyph-name="tint" unicode="&#xf043;" horiz-adv-x="1024" 
-d="M512 384q0 36 -20 69q-1 1 -15.5 22.5t-25.5 38t-25 44t-21 50.5q-4 16 -21 16t-21 -16q-7 -23 -21 -50.5t-25 -44t-25.5 -38t-15.5 -22.5q-20 -33 -20 -69q0 -53 37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1024 512q0 -212 -150 -362t-362 -150t-362 150t-150 362
-q0 145 81 275q6 9 62.5 90.5t101 151t99.5 178t83 201.5q9 30 34 47t51 17t51.5 -17t33.5 -47q28 -93 83 -201.5t99.5 -178t101 -151t62.5 -90.5q81 -127 81 -275z" />
-    <glyph glyph-name="edit" unicode="&#xf044;" horiz-adv-x="1792" 
-d="M888 352l116 116l-152 152l-116 -116v-56h96v-96h56zM1328 1072q-16 16 -33 -1l-350 -350q-17 -17 -1 -33t33 1l350 350q17 17 1 33zM1408 478v-190q0 -119 -84.5 -203.5t-203.5 -84.5h-832q-119 0 -203.5 84.5t-84.5 203.5v832q0 119 84.5 203.5t203.5 84.5h832
-q63 0 117 -25q15 -7 18 -23q3 -17 -9 -29l-49 -49q-14 -14 -32 -8q-23 6 -45 6h-832q-66 0 -113 -47t-47 -113v-832q0 -66 47 -113t113 -47h832q66 0 113 47t47 113v126q0 13 9 22l64 64q15 15 35 7t20 -29zM1312 1216l288 -288l-672 -672h-288v288zM1756 1084l-92 -92
-l-288 288l92 92q28 28 68 28t68 -28l152 -152q28 -28 28 -68t-28 -68z" />
-    <glyph glyph-name="share" unicode="&#xf045;" horiz-adv-x="1664" 
-d="M1408 547v-259q0 -119 -84.5 -203.5t-203.5 -84.5h-832q-119 0 -203.5 84.5t-84.5 203.5v832q0 119 84.5 203.5t203.5 84.5h255v0q13 0 22.5 -9.5t9.5 -22.5q0 -27 -26 -32q-77 -26 -133 -60q-10 -4 -16 -4h-112q-66 0 -113 -47t-47 -113v-832q0 -66 47 -113t113 -47h832
-q66 0 113 47t47 113v214q0 19 18 29q28 13 54 37q16 16 35 8q21 -9 21 -29zM1645 1043l-384 -384q-18 -19 -45 -19q-12 0 -25 5q-39 17 -39 59v192h-160q-323 0 -438 -131q-119 -137 -74 -473q3 -23 -20 -34q-8 -2 -12 -2q-16 0 -26 13q-10 14 -21 31t-39.5 68.5t-49.5 99.5
-t-38.5 114t-17.5 122q0 49 3.5 91t14 90t28 88t47 81.5t68.5 74t94.5 61.5t124.5 48.5t159.5 30.5t196.5 11h160v192q0 42 39 59q13 5 25 5q26 0 45 -19l384 -384q19 -19 19 -45t-19 -45z" />
-    <glyph glyph-name="check" unicode="&#xf046;" horiz-adv-x="1664" 
-d="M1408 606v-318q0 -119 -84.5 -203.5t-203.5 -84.5h-832q-119 0 -203.5 84.5t-84.5 203.5v832q0 119 84.5 203.5t203.5 84.5h832q63 0 117 -25q15 -7 18 -23q3 -17 -9 -29l-49 -49q-10 -10 -23 -10q-3 0 -9 2q-23 6 -45 6h-832q-66 0 -113 -47t-47 -113v-832
-q0 -66 47 -113t113 -47h832q66 0 113 47t47 113v254q0 13 9 22l64 64q10 10 23 10q6 0 12 -3q20 -8 20 -29zM1639 1095l-814 -814q-24 -24 -57 -24t-57 24l-430 430q-24 24 -24 57t24 57l110 110q24 24 57 24t57 -24l263 -263l647 647q24 24 57 24t57 -24l110 -110
-q24 -24 24 -57t-24 -57z" />
-    <glyph glyph-name="move" unicode="&#xf047;" horiz-adv-x="1792" 
-d="M1792 640q0 -26 -19 -45l-256 -256q-19 -19 -45 -19t-45 19t-19 45v128h-384v-384h128q26 0 45 -19t19 -45t-19 -45l-256 -256q-19 -19 -45 -19t-45 19l-256 256q-19 19 -19 45t19 45t45 19h128v384h-384v-128q0 -26 -19 -45t-45 -19t-45 19l-256 256q-19 19 -19 45
-t19 45l256 256q19 19 45 19t45 -19t19 -45v-128h384v384h-128q-26 0 -45 19t-19 45t19 45l256 256q19 19 45 19t45 -19l256 -256q19 -19 19 -45t-19 -45t-45 -19h-128v-384h384v128q0 26 19 45t45 19t45 -19l256 -256q19 -19 19 -45z" />
-    <glyph glyph-name="step_backward" unicode="&#xf048;" horiz-adv-x="1024" 
-d="M979 1395q19 19 32 13t13 -32v-1472q0 -26 -13 -32t-32 13l-710 710q-9 9 -13 19v-678q0 -26 -19 -45t-45 -19h-128q-26 0 -45 19t-19 45v1408q0 26 19 45t45 19h128q26 0 45 -19t19 -45v-678q4 10 13 19z" />
-    <glyph glyph-name="fast_backward" unicode="&#xf049;" horiz-adv-x="1792" 
-d="M1747 1395q19 19 32 13t13 -32v-1472q0 -26 -13 -32t-32 13l-710 710q-9 9 -13 19v-710q0 -26 -13 -32t-32 13l-710 710q-9 9 -13 19v-678q0 -26 -19 -45t-45 -19h-128q-26 0 -45 19t-19 45v1408q0 26 19 45t45 19h128q26 0 45 -19t19 -45v-678q4 10 13 19l710 710
-q19 19 32 13t13 -32v-710q4 10 13 19z" />
-    <glyph glyph-name="backward" unicode="&#xf04a;" horiz-adv-x="1664" 
-d="M1619 1395q19 19 32 13t13 -32v-1472q0 -26 -13 -32t-32 13l-710 710q-9 9 -13 19v-710q0 -26 -13 -32t-32 13l-710 710q-19 19 -19 45t19 45l710 710q19 19 32 13t13 -32v-710q4 10 13 19z" />
-    <glyph glyph-name="play" unicode="&#xf04b;" horiz-adv-x="1408" 
-d="M1384 609l-1328 -738q-23 -13 -39.5 -3t-16.5 36v1472q0 26 16.5 36t39.5 -3l1328 -738q23 -13 23 -31t-23 -31z" />
-    <glyph glyph-name="pause" unicode="&#xf04c;" 
-d="M1536 1344v-1408q0 -26 -19 -45t-45 -19h-512q-26 0 -45 19t-19 45v1408q0 26 19 45t45 19h512q26 0 45 -19t19 -45zM640 1344v-1408q0 -26 -19 -45t-45 -19h-512q-26 0 -45 19t-19 45v1408q0 26 19 45t45 19h512q26 0 45 -19t19 -45z" />
-    <glyph glyph-name="stop" unicode="&#xf04d;" 
-d="M1536 1344v-1408q0 -26 -19 -45t-45 -19h-1408q-26 0 -45 19t-19 45v1408q0 26 19 45t45 19h1408q26 0 45 -19t19 -45z" />
-    <glyph glyph-name="forward" unicode="&#xf04e;" horiz-adv-x="1664" 
-d="M45 -115q-19 -19 -32 -13t-13 32v1472q0 26 13 32t32 -13l710 -710q9 -9 13 -19v710q0 26 13 32t32 -13l710 -710q19 -19 19 -45t-19 -45l-710 -710q-19 -19 -32 -13t-13 32v710q-4 -10 -13 -19z" />
-    <glyph glyph-name="fast_forward" unicode="&#xf050;" horiz-adv-x="1792" 
-d="M45 -115q-19 -19 -32 -13t-13 32v1472q0 26 13 32t32 -13l710 -710q9 -9 13 -19v710q0 26 13 32t32 -13l710 -710q9 -9 13 -19v678q0 26 19 45t45 19h128q26 0 45 -19t19 -45v-1408q0 -26 -19 -45t-45 -19h-128q-26 0 -45 19t-19 45v678q-4 -10 -13 -19l-710 -710
-q-19 -19 -32 -13t-13 32v710q-4 -10 -13 -19z" />
-    <glyph glyph-name="step_forward" unicode="&#xf051;" horiz-adv-x="1024" 
-d="M45 -115q-19 -19 -32 -13t-13 32v1472q0 26 13 32t32 -13l710 -710q9 -9 13 -19v678q0 26 19 45t45 19h128q26 0 45 -19t19 -45v-1408q0 -26 -19 -45t-45 -19h-128q-26 0 -45 19t-19 45v678q-4 -10 -13 -19z" />
-    <glyph glyph-name="eject" unicode="&#xf052;" horiz-adv-x="1538" 
-d="M14 557l710 710q19 19 45 19t45 -19l710 -710q19 -19 13 -32t-32 -13h-1472q-26 0 -32 13t13 32zM1473 0h-1408q-26 0 -45 19t-19 45v256q0 26 19 45t45 19h1408q26 0 45 -19t19 -45v-256q0 -26 -19 -45t-45 -19z" />
-    <glyph glyph-name="chevron_left" unicode="&#xf053;" horiz-adv-x="1280" 
-d="M1171 1235l-531 -531l531 -531q19 -19 19 -45t-19 -45l-166 -166q-19 -19 -45 -19t-45 19l-742 742q-19 19 -19 45t19 45l742 742q19 19 45 19t45 -19l166 -166q19 -19 19 -45t-19 -45z" />
-    <glyph glyph-name="chevron_right" unicode="&#xf054;" horiz-adv-x="1280" 
-d="M1107 659l-742 -742q-19 -19 -45 -19t-45 19l-166 166q-19 19 -19 45t19 45l531 531l-531 531q-19 19 -19 45t19 45l166 166q19 19 45 19t45 -19l742 -742q19 -19 19 -45t-19 -45z" />
-    <glyph glyph-name="plus_sign" unicode="&#xf055;" 
-d="M1216 576v128q0 26 -19 45t-45 19h-256v256q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-256h-256q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45t45 -19h256v-256q0 -26 19 -45t45 -19h128q26 0 45 19t19 45v256h256q26 0 45 19t19 45zM1536 640q0 -209 -103 -385.5
-t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
-    <glyph glyph-name="minus_sign" unicode="&#xf056;" 
-d="M1216 576v128q0 26 -19 45t-45 19h-768q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45t45 -19h768q26 0 45 19t19 45zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5
-t103 -385.5z" />
-    <glyph glyph-name="remove_sign" unicode="&#xf057;" 
-d="M1149 414q0 26 -19 45l-181 181l181 181q19 19 19 45q0 27 -19 46l-90 90q-19 19 -46 19q-26 0 -45 -19l-181 -181l-181 181q-19 19 -45 19q-27 0 -46 -19l-90 -90q-19 -19 -19 -46q0 -26 19 -45l181 -181l-181 -181q-19 -19 -19 -45q0 -27 19 -46l90 -90q19 -19 46 -19
-q26 0 45 19l181 181l181 -181q19 -19 45 -19q27 0 46 19l90 90q19 19 19 46zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
-    <glyph glyph-name="ok_sign" unicode="&#xf058;" 
-d="M1284 802q0 28 -18 46l-91 90q-19 19 -45 19t-45 -19l-408 -407l-226 226q-19 19 -45 19t-45 -19l-91 -90q-18 -18 -18 -46q0 -27 18 -45l362 -362q19 -19 45 -19q27 0 46 19l543 543q18 18 18 45zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103
-t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
-    <glyph glyph-name="question_sign" unicode="&#xf059;" 
-d="M896 160v192q0 14 -9 23t-23 9h-192q-14 0 -23 -9t-9 -23v-192q0 -14 9 -23t23 -9h192q14 0 23 9t9 23zM1152 832q0 88 -55.5 163t-138.5 116t-170 41q-243 0 -371 -213q-15 -24 8 -42l132 -100q7 -6 19 -6q16 0 25 12q53 68 86 92q34 24 86 24q48 0 85.5 -26t37.5 -59
-q0 -38 -20 -61t-68 -45q-63 -28 -115.5 -86.5t-52.5 -125.5v-36q0 -14 9 -23t23 -9h192q14 0 23 9t9 23q0 19 21.5 49.5t54.5 49.5q32 18 49 28.5t46 35t44.5 48t28 60.5t12.5 81zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5
-t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
-    <glyph glyph-name="info_sign" unicode="&#xf05a;" 
-d="M1024 160v160q0 14 -9 23t-23 9h-96v512q0 14 -9 23t-23 9h-320q-14 0 -23 -9t-9 -23v-160q0 -14 9 -23t23 -9h96v-320h-96q-14 0 -23 -9t-9 -23v-160q0 -14 9 -23t23 -9h448q14 0 23 9t9 23zM896 1056v160q0 14 -9 23t-23 9h-192q-14 0 -23 -9t-9 -23v-160q0 -14 9 -23
-t23 -9h192q14 0 23 9t9 23zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
-    <glyph glyph-name="screenshot" unicode="&#xf05b;" 
-d="M1197 512h-109q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h109q-32 108 -112.5 188.5t-188.5 112.5v-109q0 -26 -19 -45t-45 -19h-128q-26 0 -45 19t-19 45v109q-108 -32 -188.5 -112.5t-112.5 -188.5h109q26 0 45 -19t19 -45v-128q0 -26 -19 -45t-45 -19h-109
-q32 -108 112.5 -188.5t188.5 -112.5v109q0 26 19 45t45 19h128q26 0 45 -19t19 -45v-109q108 32 188.5 112.5t112.5 188.5zM1536 704v-128q0 -26 -19 -45t-45 -19h-143q-37 -161 -154.5 -278.5t-278.5 -154.5v-143q0 -26 -19 -45t-45 -19h-128q-26 0 -45 19t-19 45v143
-q-161 37 -278.5 154.5t-154.5 278.5h-143q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h143q37 161 154.5 278.5t278.5 154.5v143q0 26 19 45t45 19h128q26 0 45 -19t19 -45v-143q161 -37 278.5 -154.5t154.5 -278.5h143q26 0 45 -19t19 -45z" />
-    <glyph glyph-name="remove_circle" unicode="&#xf05c;" 
-d="M1097 457l-146 -146q-10 -10 -23 -10t-23 10l-137 137l-137 -137q-10 -10 -23 -10t-23 10l-146 146q-10 10 -10 23t10 23l137 137l-137 137q-10 10 -10 23t10 23l146 146q10 10 23 10t23 -10l137 -137l137 137q10 10 23 10t23 -10l146 -146q10 -10 10 -23t-10 -23
-l-137 -137l137 -137q10 -10 10 -23t-10 -23zM1312 640q0 148 -73 273t-198 198t-273 73t-273 -73t-198 -198t-73 -273t73 -273t198 -198t273 -73t273 73t198 198t73 273zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5
-t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
-    <glyph glyph-name="ok_circle" unicode="&#xf05d;" 
-d="M1171 723l-422 -422q-19 -19 -45 -19t-45 19l-294 294q-19 19 -19 45t19 45l102 102q19 19 45 19t45 -19l147 -147l275 275q19 19 45 19t45 -19l102 -102q19 -19 19 -45t-19 -45zM1312 640q0 148 -73 273t-198 198t-273 73t-273 -73t-198 -198t-73 -273t73 -273t198 -198
-t273 -73t273 73t198 198t73 273zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
-    <glyph glyph-name="ban_circle" unicode="&#xf05e;" 
-d="M1312 643q0 161 -87 295l-754 -753q137 -89 297 -89q111 0 211.5 43.5t173.5 116.5t116 174.5t43 212.5zM313 344l755 754q-135 91 -300 91q-148 0 -273 -73t-198 -199t-73 -274q0 -162 89 -299zM1536 643q0 -157 -61 -300t-163.5 -246t-245 -164t-298.5 -61t-298.5 61
-t-245 164t-163.5 246t-61 300t61 299.5t163.5 245.5t245 164t298.5 61t298.5 -61t245 -164t163.5 -245.5t61 -299.5z" />
-    <glyph glyph-name="arrow_left" unicode="&#xf060;" 
-d="M1536 640v-128q0 -53 -32.5 -90.5t-84.5 -37.5h-704l293 -294q38 -36 38 -90t-38 -90l-75 -76q-37 -37 -90 -37q-52 0 -91 37l-651 652q-37 37 -37 90q0 52 37 91l651 650q38 38 91 38q52 0 90 -38l75 -74q38 -38 38 -91t-38 -91l-293 -293h704q52 0 84.5 -37.5
-t32.5 -90.5z" />
-    <glyph glyph-name="arrow_right" unicode="&#xf061;" 
-d="M1472 576q0 -54 -37 -91l-651 -651q-39 -37 -91 -37q-51 0 -90 37l-75 75q-38 38 -38 91t38 91l293 293h-704q-52 0 -84.5 37.5t-32.5 90.5v128q0 53 32.5 90.5t84.5 37.5h704l-293 294q-38 36 -38 90t38 90l75 75q38 38 90 38q53 0 91 -38l651 -651q37 -35 37 -90z" />
-    <glyph glyph-name="arrow_up" unicode="&#xf062;" horiz-adv-x="1664" 
-d="M1611 565q0 -51 -37 -90l-75 -75q-38 -38 -91 -38q-54 0 -90 38l-294 293v-704q0 -52 -37.5 -84.5t-90.5 -32.5h-128q-53 0 -90.5 32.5t-37.5 84.5v704l-294 -293q-36 -38 -90 -38t-90 38l-75 75q-38 38 -38 90q0 53 38 91l651 651q35 37 90 37q54 0 91 -37l651 -651
-q37 -39 37 -91z" />
-    <glyph glyph-name="arrow_down" unicode="&#xf063;" horiz-adv-x="1664" 
-d="M1611 704q0 -53 -37 -90l-651 -652q-39 -37 -91 -37q-53 0 -90 37l-651 652q-38 36 -38 90q0 53 38 91l74 75q39 37 91 37q53 0 90 -37l294 -294v704q0 52 38 90t90 38h128q52 0 90 -38t38 -90v-704l294 294q37 37 90 37q52 0 91 -37l75 -75q37 -39 37 -91z" />
-    <glyph glyph-name="share_alt" unicode="&#xf064;" horiz-adv-x="1792" 
-d="M1792 896q0 -26 -19 -45l-512 -512q-19 -19 -45 -19t-45 19t-19 45v256h-224q-98 0 -175.5 -6t-154 -21.5t-133 -42.5t-105.5 -69.5t-80 -101t-48.5 -138.5t-17.5 -181q0 -55 5 -123q0 -6 2.5 -23.5t2.5 -26.5q0 -15 -8.5 -25t-23.5 -10q-16 0 -28 17q-7 9 -13 22
-t-13.5 30t-10.5 24q-127 285 -127 451q0 199 53 333q162 403 875 403h224v256q0 26 19 45t45 19t45 -19l512 -512q19 -19 19 -45z" />
-    <glyph glyph-name="resize_full" unicode="&#xf065;" 
-d="M755 480q0 -13 -10 -23l-332 -332l144 -144q19 -19 19 -45t-19 -45t-45 -19h-448q-26 0 -45 19t-19 45v448q0 26 19 45t45 19t45 -19l144 -144l332 332q10 10 23 10t23 -10l114 -114q10 -10 10 -23zM1536 1344v-448q0 -26 -19 -45t-45 -19t-45 19l-144 144l-332 -332
-q-10 -10 -23 -10t-23 10l-114 114q-10 10 -10 23t10 23l332 332l-144 144q-19 19 -19 45t19 45t45 19h448q26 0 45 -19t19 -45z" />
-    <glyph glyph-name="resize_small" unicode="&#xf066;" 
-d="M768 576v-448q0 -26 -19 -45t-45 -19t-45 19l-144 144l-332 -332q-10 -10 -23 -10t-23 10l-114 114q-10 10 -10 23t10 23l332 332l-144 144q-19 19 -19 45t19 45t45 19h448q26 0 45 -19t19 -45zM1523 1248q0 -13 -10 -23l-332 -332l144 -144q19 -19 19 -45t-19 -45
-t-45 -19h-448q-26 0 -45 19t-19 45v448q0 26 19 45t45 19t45 -19l144 -144l332 332q10 10 23 10t23 -10l114 -114q10 -10 10 -23z" />
-    <glyph glyph-name="plus" unicode="&#xf067;" horiz-adv-x="1408" 
-d="M1408 800v-192q0 -40 -28 -68t-68 -28h-416v-416q0 -40 -28 -68t-68 -28h-192q-40 0 -68 28t-28 68v416h-416q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h416v416q0 40 28 68t68 28h192q40 0 68 -28t28 -68v-416h416q40 0 68 -28t28 -68z" />
-    <glyph glyph-name="minus" unicode="&#xf068;" horiz-adv-x="1408" 
-d="M1408 800v-192q0 -40 -28 -68t-68 -28h-1216q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h1216q40 0 68 -28t28 -68z" />
-    <glyph glyph-name="asterisk" unicode="&#xf069;" horiz-adv-x="1664" 
-d="M1482 486q46 -26 59.5 -77.5t-12.5 -97.5l-64 -110q-26 -46 -77.5 -59.5t-97.5 12.5l-266 153v-307q0 -52 -38 -90t-90 -38h-128q-52 0 -90 38t-38 90v307l-266 -153q-46 -26 -97.5 -12.5t-77.5 59.5l-64 110q-26 46 -12.5 97.5t59.5 77.5l266 154l-266 154
-q-46 26 -59.5 77.5t12.5 97.5l64 110q26 46 77.5 59.5t97.5 -12.5l266 -153v307q0 52 38 90t90 38h128q52 0 90 -38t38 -90v-307l266 153q46 26 97.5 12.5t77.5 -59.5l64 -110q26 -46 12.5 -97.5t-59.5 -77.5l-266 -154z" />
-    <glyph glyph-name="exclamation_sign" unicode="&#xf06a;" 
-d="M768 1408q209 0 385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103zM896 161v190q0 14 -9 23.5t-22 9.5h-192q-13 0 -23 -10t-10 -23v-190q0 -13 10 -23t23 -10h192
-q13 0 22 9.5t9 23.5zM894 505l18 621q0 12 -10 18q-10 8 -24 8h-220q-14 0 -24 -8q-10 -6 -10 -18l17 -621q0 -10 10 -17.5t24 -7.5h185q14 0 23.5 7.5t10.5 17.5z" />
-    <glyph glyph-name="gift" unicode="&#xf06b;" 
-d="M928 180v56v468v192h-320v-192v-468v-56q0 -25 18 -38.5t46 -13.5h192q28 0 46 13.5t18 38.5zM472 1024h195l-126 161q-26 31 -69 31q-40 0 -68 -28t-28 -68t28 -68t68 -28zM1160 1120q0 40 -28 68t-68 28q-43 0 -69 -31l-125 -161h194q40 0 68 28t28 68zM1536 864v-320
-q0 -14 -9 -23t-23 -9h-96v-416q0 -40 -28 -68t-68 -28h-1088q-40 0 -68 28t-28 68v416h-96q-14 0 -23 9t-9 23v320q0 14 9 23t23 9h440q-93 0 -158.5 65.5t-65.5 158.5t65.5 158.5t158.5 65.5q107 0 168 -77l128 -165l128 165q61 77 168 77q93 0 158.5 -65.5t65.5 -158.5
-t-65.5 -158.5t-158.5 -65.5h440q14 0 23 -9t9 -23z" />
-    <glyph glyph-name="leaf" unicode="&#xf06c;" horiz-adv-x="1792" 
-d="M1280 832q0 26 -19 45t-45 19q-172 0 -318 -49.5t-259.5 -134t-235.5 -219.5q-19 -21 -19 -45q0 -26 19 -45t45 -19q24 0 45 19q27 24 74 71t67 66q137 124 268.5 176t313.5 52q26 0 45 19t19 45zM1792 1030q0 -95 -20 -193q-46 -224 -184.5 -383t-357.5 -268
-q-214 -108 -438 -108q-148 0 -286 47q-15 5 -88 42t-96 37q-16 0 -39.5 -32t-45 -70t-52.5 -70t-60 -32q-43 0 -63.5 17.5t-45.5 59.5q-2 4 -6 11t-5.5 10t-3 9.5t-1.5 13.5q0 35 31 73.5t68 65.5t68 56t31 48q0 4 -14 38t-16 44q-9 51 -9 104q0 115 43.5 220t119 184.5
-t170.5 139t204 95.5q55 18 145 25.5t179.5 9t178.5 6t163.5 24t113.5 56.5l29.5 29.5t29.5 28t27 20t36.5 16t43.5 4.5q39 0 70.5 -46t47.5 -112t24 -124t8 -96z" />
-    <glyph glyph-name="fire" unicode="&#xf06d;" horiz-adv-x="1408" 
-d="M1408 -160v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-1344q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h1344q13 0 22.5 -9.5t9.5 -22.5zM1152 896q0 -78 -24.5 -144t-64 -112.5t-87.5 -88t-96 -77.5t-87.5 -72t-64 -81.5t-24.5 -96.5q0 -96 67 -224l-4 1l1 -1
-q-90 41 -160 83t-138.5 100t-113.5 122.5t-72.5 150.5t-27.5 184q0 78 24.5 144t64 112.5t87.5 88t96 77.5t87.5 72t64 81.5t24.5 96.5q0 94 -66 224l3 -1l-1 1q90 -41 160 -83t138.5 -100t113.5 -122.5t72.5 -150.5t27.5 -184z" />
-    <glyph glyph-name="eye_open" unicode="&#xf06e;" horiz-adv-x="1792" 
-d="M1664 576q-152 236 -381 353q61 -104 61 -225q0 -185 -131.5 -316.5t-316.5 -131.5t-316.5 131.5t-131.5 316.5q0 121 61 225q-229 -117 -381 -353q133 -205 333.5 -326.5t434.5 -121.5t434.5 121.5t333.5 326.5zM944 960q0 20 -14 34t-34 14q-125 0 -214.5 -89.5
-t-89.5 -214.5q0 -20 14 -34t34 -14t34 14t14 34q0 86 61 147t147 61q20 0 34 14t14 34zM1792 576q0 -34 -20 -69q-140 -230 -376.5 -368.5t-499.5 -138.5t-499.5 139t-376.5 368q-20 35 -20 69t20 69q140 229 376.5 368t499.5 139t499.5 -139t376.5 -368q20 -35 20 -69z" />
-    <glyph glyph-name="eye_close" unicode="&#xf070;" horiz-adv-x="1792" 
-d="M555 201l78 141q-87 63 -136 159t-49 203q0 121 61 225q-229 -117 -381 -353q167 -258 427 -375zM944 960q0 20 -14 34t-34 14q-125 0 -214.5 -89.5t-89.5 -214.5q0 -20 14 -34t34 -14t34 14t14 34q0 86 61 147t147 61q20 0 34 14t14 34zM1307 1151q0 -7 -1 -9
-q-106 -189 -316 -567t-315 -566l-49 -89q-10 -16 -28 -16q-12 0 -134 70q-16 10 -16 28q0 12 44 87q-143 65 -263.5 173t-208.5 245q-20 31 -20 69t20 69q153 235 380 371t496 136q89 0 180 -17l54 97q10 16 28 16q5 0 18 -6t31 -15.5t33 -18.5t31.5 -18.5t19.5 -11.5
-q16 -10 16 -27zM1344 704q0 -139 -79 -253.5t-209 -164.5l280 502q8 -45 8 -84zM1792 576q0 -35 -20 -69q-39 -64 -109 -145q-150 -172 -347.5 -267t-419.5 -95l74 132q212 18 392.5 137t301.5 307q-115 179 -282 294l63 112q95 -64 182.5 -153t144.5 -184q20 -34 20 -69z
-" />
-    <glyph glyph-name="warning_sign" unicode="&#xf071;" horiz-adv-x="1792" 
-d="M1024 161v190q0 14 -9.5 23.5t-22.5 9.5h-192q-13 0 -22.5 -9.5t-9.5 -23.5v-190q0 -14 9.5 -23.5t22.5 -9.5h192q13 0 22.5 9.5t9.5 23.5zM1022 535l18 459q0 12 -10 19q-13 11 -24 11h-220q-11 0 -24 -11q-10 -7 -10 -21l17 -457q0 -10 10 -16.5t24 -6.5h185
-q14 0 23.5 6.5t10.5 16.5zM1008 1469l768 -1408q35 -63 -2 -126q-17 -29 -46.5 -46t-63.5 -17h-1536q-34 0 -63.5 17t-46.5 46q-37 63 -2 126l768 1408q17 31 47 49t65 18t65 -18t47 -49z" />
-    <glyph glyph-name="plane" unicode="&#xf072;" horiz-adv-x="1408" 
-d="M1376 1376q44 -52 12 -148t-108 -172l-161 -161l160 -696q5 -19 -12 -33l-128 -96q-7 -6 -19 -6q-4 0 -7 1q-15 3 -21 16l-279 508l-259 -259l53 -194q5 -17 -8 -31l-96 -96q-9 -9 -23 -9h-2q-15 2 -24 13l-189 252l-252 189q-11 7 -13 23q-1 13 9 25l96 97q9 9 23 9
-q6 0 8 -1l194 -53l259 259l-508 279q-14 8 -17 24q-2 16 9 27l128 128q14 13 30 8l665 -159l160 160q76 76 172 108t148 -12z" />
-    <glyph glyph-name="calendar" unicode="&#xf073;" horiz-adv-x="1664" 
-d="M128 -128h288v288h-288v-288zM480 -128h320v288h-320v-288zM128 224h288v320h-288v-320zM480 224h320v320h-320v-320zM128 608h288v288h-288v-288zM864 -128h320v288h-320v-288zM480 608h320v288h-320v-288zM1248 -128h288v288h-288v-288zM864 224h320v320h-320v-320z
-M512 1088v288q0 13 -9.5 22.5t-22.5 9.5h-64q-13 0 -22.5 -9.5t-9.5 -22.5v-288q0 -13 9.5 -22.5t22.5 -9.5h64q13 0 22.5 9.5t9.5 22.5zM1248 224h288v320h-288v-320zM864 608h320v288h-320v-288zM1248 608h288v288h-288v-288zM1280 1088v288q0 13 -9.5 22.5t-22.5 9.5h-64
-q-13 0 -22.5 -9.5t-9.5 -22.5v-288q0 -13 9.5 -22.5t22.5 -9.5h64q13 0 22.5 9.5t9.5 22.5zM1664 1152v-1280q0 -52 -38 -90t-90 -38h-1408q-52 0 -90 38t-38 90v1280q0 52 38 90t90 38h128v96q0 66 47 113t113 47h64q66 0 113 -47t47 -113v-96h384v96q0 66 47 113t113 47
-h64q66 0 113 -47t47 -113v-96h128q52 0 90 -38t38 -90z" />
-    <glyph glyph-name="random" unicode="&#xf074;" horiz-adv-x="1792" 
-d="M666 1055q-60 -92 -137 -273q-22 45 -37 72.5t-40.5 63.5t-51 56.5t-63 35t-81.5 14.5h-224q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h224q250 0 410 -225zM1792 256q0 -14 -9 -23l-320 -320q-9 -9 -23 -9q-13 0 -22.5 9.5t-9.5 22.5v192q-32 0 -85 -0.5t-81 -1t-73 1
-t-71 5t-64 10.5t-63 18.5t-58 28.5t-59 40t-55 53.5t-56 69.5q59 93 136 273q22 -45 37 -72.5t40.5 -63.5t51 -56.5t63 -35t81.5 -14.5h256v192q0 14 9 23t23 9q12 0 24 -10l319 -319q9 -9 9 -23zM1792 1152q0 -14 -9 -23l-320 -320q-9 -9 -23 -9q-13 0 -22.5 9.5t-9.5 22.5
-v192h-256q-48 0 -87 -15t-69 -45t-51 -61.5t-45 -77.5q-32 -62 -78 -171q-29 -66 -49.5 -111t-54 -105t-64 -100t-74 -83t-90 -68.5t-106.5 -42t-128 -16.5h-224q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h224q48 0 87 15t69 45t51 61.5t45 77.5q32 62 78 171q29 66 49.5 111
-t54 105t64 100t74 83t90 68.5t106.5 42t128 16.5h256v192q0 14 9 23t23 9q12 0 24 -10l319 -319q9 -9 9 -23z" />
-    <glyph glyph-name="comment" unicode="&#xf075;" horiz-adv-x="1792" 
-d="M1792 640q0 -174 -120 -321.5t-326 -233t-450 -85.5q-70 0 -145 8q-198 -175 -460 -242q-49 -14 -114 -22q-17 -2 -30.5 9t-17.5 29v1q-3 4 -0.5 12t2 10t4.5 9.5l6 9t7 8.5t8 9q7 8 31 34.5t34.5 38t31 39.5t32.5 51t27 59t26 76q-157 89 -247.5 220t-90.5 281
-q0 130 71 248.5t191 204.5t286 136.5t348 50.5q244 0 450 -85.5t326 -233t120 -321.5z" />
-    <glyph glyph-name="magnet" unicode="&#xf076;" 
-d="M1536 704v-128q0 -201 -98.5 -362t-274 -251.5t-395.5 -90.5t-395.5 90.5t-274 251.5t-98.5 362v128q0 26 19 45t45 19h384q26 0 45 -19t19 -45v-128q0 -52 23.5 -90t53.5 -57t71 -30t64 -13t44 -2t44 2t64 13t71 30t53.5 57t23.5 90v128q0 26 19 45t45 19h384
-q26 0 45 -19t19 -45zM512 1344v-384q0 -26 -19 -45t-45 -19h-384q-26 0 -45 19t-19 45v384q0 26 19 45t45 19h384q26 0 45 -19t19 -45zM1536 1344v-384q0 -26 -19 -45t-45 -19h-384q-26 0 -45 19t-19 45v384q0 26 19 45t45 19h384q26 0 45 -19t19 -45z" />
-    <glyph glyph-name="chevron_up" unicode="&#xf077;" horiz-adv-x="1792" 
-d="M1683 205l-166 -165q-19 -19 -45 -19t-45 19l-531 531l-531 -531q-19 -19 -45 -19t-45 19l-166 165q-19 19 -19 45.5t19 45.5l742 741q19 19 45 19t45 -19l742 -741q19 -19 19 -45.5t-19 -45.5z" />
-    <glyph glyph-name="chevron_down" unicode="&#xf078;" horiz-adv-x="1792" 
-d="M1683 728l-742 -741q-19 -19 -45 -19t-45 19l-742 741q-19 19 -19 45.5t19 45.5l166 165q19 19 45 19t45 -19l531 -531l531 531q19 19 45 19t45 -19l166 -165q19 -19 19 -45.5t-19 -45.5z" />
-    <glyph glyph-name="retweet" unicode="&#xf079;" horiz-adv-x="1920" 
-d="M1280 32q0 -13 -9.5 -22.5t-22.5 -9.5h-960q-8 0 -13.5 2t-9 7t-5.5 8t-3 11.5t-1 11.5v13v11v160v416h-192q-26 0 -45 19t-19 45q0 24 15 41l320 384q19 22 49 22t49 -22l320 -384q15 -17 15 -41q0 -26 -19 -45t-45 -19h-192v-384h576q16 0 25 -11l160 -192q7 -10 7 -21
-zM1920 448q0 -24 -15 -41l-320 -384q-20 -23 -49 -23t-49 23l-320 384q-15 17 -15 41q0 26 19 45t45 19h192v384h-576q-16 0 -25 12l-160 192q-7 9 -7 20q0 13 9.5 22.5t22.5 9.5h960q8 0 13.5 -2t9 -7t5.5 -8t3 -11.5t1 -11.5v-13v-11v-160v-416h192q26 0 45 -19t19 -45z
-" />
-    <glyph glyph-name="shopping_cart" unicode="&#xf07a;" horiz-adv-x="1664" 
-d="M640 0q0 -52 -38 -90t-90 -38t-90 38t-38 90t38 90t90 38t90 -38t38 -90zM1536 0q0 -52 -38 -90t-90 -38t-90 38t-38 90t38 90t90 38t90 -38t38 -90zM1664 1088v-512q0 -24 -16.5 -42.5t-40.5 -21.5l-1044 -122q13 -60 13 -70q0 -16 -24 -64h920q26 0 45 -19t19 -45
-t-19 -45t-45 -19h-1024q-26 0 -45 19t-19 45q0 11 8 31.5t16 36t21.5 40t15.5 29.5l-177 823h-204q-26 0 -45 19t-19 45t19 45t45 19h256q16 0 28.5 -6.5t19.5 -15.5t13 -24.5t8 -26t5.5 -29.5t4.5 -26h1201q26 0 45 -19t19 -45z" />
-    <glyph glyph-name="folder_close" unicode="&#xf07b;" horiz-adv-x="1664" 
-d="M1664 928v-704q0 -92 -66 -158t-158 -66h-1216q-92 0 -158 66t-66 158v960q0 92 66 158t158 66h320q92 0 158 -66t66 -158v-32h672q92 0 158 -66t66 -158z" />
-    <glyph glyph-name="folder_open" unicode="&#xf07c;" horiz-adv-x="1920" 
-d="M1879 584q0 -31 -31 -66l-336 -396q-43 -51 -120.5 -86.5t-143.5 -35.5h-1088q-34 0 -60.5 13t-26.5 43q0 31 31 66l336 396q43 51 120.5 86.5t143.5 35.5h1088q34 0 60.5 -13t26.5 -43zM1536 928v-160h-832q-94 0 -197 -47.5t-164 -119.5l-337 -396l-5 -6q0 4 -0.5 12.5
-t-0.5 12.5v960q0 92 66 158t158 66h320q92 0 158 -66t66 -158v-32h544q92 0 158 -66t66 -158z" />
-    <glyph glyph-name="resize_vertical" unicode="&#xf07d;" horiz-adv-x="768" 
-d="M704 1216q0 -26 -19 -45t-45 -19h-128v-1024h128q26 0 45 -19t19 -45t-19 -45l-256 -256q-19 -19 -45 -19t-45 19l-256 256q-19 19 -19 45t19 45t45 19h128v1024h-128q-26 0 -45 19t-19 45t19 45l256 256q19 19 45 19t45 -19l256 -256q19 -19 19 -45z" />
-    <glyph glyph-name="resize_horizontal" unicode="&#xf07e;" horiz-adv-x="1792" 
-d="M1792 640q0 -26 -19 -45l-256 -256q-19 -19 -45 -19t-45 19t-19 45v128h-1024v-128q0 -26 -19 -45t-45 -19t-45 19l-256 256q-19 19 -19 45t19 45l256 256q19 19 45 19t45 -19t19 -45v-128h1024v128q0 26 19 45t45 19t45 -19l256 -256q19 -19 19 -45z" />
-    <glyph glyph-name="bar_chart" unicode="&#xf080;" horiz-adv-x="2048" 
-d="M640 640v-512h-256v512h256zM1024 1152v-1024h-256v1024h256zM2048 0v-128h-2048v1536h128v-1408h1920zM1408 896v-768h-256v768h256zM1792 1280v-1152h-256v1152h256z" />
-    <glyph glyph-name="twitter_sign" unicode="&#xf081;" 
-d="M1280 926q-56 -25 -121 -34q68 40 93 117q-65 -38 -134 -51q-61 66 -153 66q-87 0 -148.5 -61.5t-61.5 -148.5q0 -29 5 -48q-129 7 -242 65t-192 155q-29 -50 -29 -106q0 -114 91 -175q-47 1 -100 26v-2q0 -75 50 -133.5t123 -72.5q-29 -8 -51 -8q-13 0 -39 4
-q21 -63 74.5 -104t121.5 -42q-116 -90 -261 -90q-26 0 -50 3q148 -94 322 -94q112 0 210 35.5t168 95t120.5 137t75 162t24.5 168.5q0 18 -1 27q63 45 105 109zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5
-t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
-    <glyph glyph-name="facebook_sign" unicode="&#xf082;" 
-d="M1248 1408q119 0 203.5 -84.5t84.5 -203.5v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-188v595h199l30 232h-229v148q0 56 23.5 84t91.5 28l122 1v207q-63 9 -178 9q-136 0 -217.5 -80t-81.5 -226v-171h-200v-232h200v-595h-532q-119 0 -203.5 84.5t-84.5 203.5v960
-q0 119 84.5 203.5t203.5 84.5h960z" />
-    <glyph glyph-name="camera_retro" unicode="&#xf083;" horiz-adv-x="1792" 
-d="M928 704q0 14 -9 23t-23 9q-66 0 -113 -47t-47 -113q0 -14 9 -23t23 -9t23 9t9 23q0 40 28 68t68 28q14 0 23 9t9 23zM1152 574q0 -106 -75 -181t-181 -75t-181 75t-75 181t75 181t181 75t181 -75t75 -181zM128 0h1536v128h-1536v-128zM1280 574q0 159 -112.5 271.5
-t-271.5 112.5t-271.5 -112.5t-112.5 -271.5t112.5 -271.5t271.5 -112.5t271.5 112.5t112.5 271.5zM256 1216h384v128h-384v-128zM128 1024h1536v118v138h-828l-64 -128h-644v-128zM1792 1280v-1280q0 -53 -37.5 -90.5t-90.5 -37.5h-1536q-53 0 -90.5 37.5t-37.5 90.5v1280
-q0 53 37.5 90.5t90.5 37.5h1536q53 0 90.5 -37.5t37.5 -90.5z" />
-    <glyph glyph-name="key" unicode="&#xf084;" horiz-adv-x="1792" 
-d="M832 1024q0 80 -56 136t-136 56t-136 -56t-56 -136q0 -42 19 -83q-41 19 -83 19q-80 0 -136 -56t-56 -136t56 -136t136 -56t136 56t56 136q0 42 -19 83q41 -19 83 -19q80 0 136 56t56 136zM1683 320q0 -17 -49 -66t-66 -49q-9 0 -28.5 16t-36.5 33t-38.5 40t-24.5 26
-l-96 -96l220 -220q28 -28 28 -68q0 -42 -39 -81t-81 -39q-40 0 -68 28l-671 671q-176 -131 -365 -131q-163 0 -265.5 102.5t-102.5 265.5q0 160 95 313t248 248t313 95q163 0 265.5 -102.5t102.5 -265.5q0 -189 -131 -365l355 -355l96 96q-3 3 -26 24.5t-40 38.5t-33 36.5
-t-16 28.5q0 17 49 66t66 49q13 0 23 -10q6 -6 46 -44.5t82 -79.5t86.5 -86t73 -78t28.5 -41z" />
-    <glyph glyph-name="cogs" unicode="&#xf085;" horiz-adv-x="1920" 
-d="M896 640q0 106 -75 181t-181 75t-181 -75t-75 -181t75 -181t181 -75t181 75t75 181zM1664 128q0 52 -38 90t-90 38t-90 -38t-38 -90q0 -53 37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1664 1152q0 52 -38 90t-90 38t-90 -38t-38 -90q0 -53 37.5 -90.5t90.5 -37.5
-t90.5 37.5t37.5 90.5zM1280 731v-185q0 -10 -7 -19.5t-16 -10.5l-155 -24q-11 -35 -32 -76q34 -48 90 -115q7 -11 7 -20q0 -12 -7 -19q-23 -30 -82.5 -89.5t-78.5 -59.5q-11 0 -21 7l-115 90q-37 -19 -77 -31q-11 -108 -23 -155q-7 -24 -30 -24h-186q-11 0 -20 7.5t-10 17.5
-l-23 153q-34 10 -75 31l-118 -89q-7 -7 -20 -7q-11 0 -21 8q-144 133 -144 160q0 9 7 19q10 14 41 53t47 61q-23 44 -35 82l-152 24q-10 1 -17 9.5t-7 19.5v185q0 10 7 19.5t16 10.5l155 24q11 35 32 76q-34 48 -90 115q-7 11 -7 20q0 12 7 20q22 30 82 89t79 59q11 0 21 -7
-l115 -90q34 18 77 32q11 108 23 154q7 24 30 24h186q11 0 20 -7.5t10 -17.5l23 -153q34 -10 75 -31l118 89q8 7 20 7q11 0 21 -8q144 -133 144 -160q0 -8 -7 -19q-12 -16 -42 -54t-45 -60q23 -48 34 -82l152 -23q10 -2 17 -10.5t7 -19.5zM1920 198v-140q0 -16 -149 -31
-q-12 -27 -30 -52q51 -113 51 -138q0 -4 -4 -7q-122 -71 -124 -71q-8 0 -46 47t-52 68q-20 -2 -30 -2t-30 2q-14 -21 -52 -68t-46 -47q-2 0 -124 71q-4 3 -4 7q0 25 51 138q-18 25 -30 52q-149 15 -149 31v140q0 16 149 31q13 29 30 52q-51 113 -51 138q0 4 4 7q4 2 35 20
-t59 34t30 16q8 0 46 -46.5t52 -67.5q20 2 30 2t30 -2q51 71 92 112l6 2q4 0 124 -70q4 -3 4 -7q0 -25 -51 -138q17 -23 30 -52q149 -15 149 -31zM1920 1222v-140q0 -16 -149 -31q-12 -27 -30 -52q51 -113 51 -138q0 -4 -4 -7q-122 -71 -124 -71q-8 0 -46 47t-52 68
-q-20 -2 -30 -2t-30 2q-14 -21 -52 -68t-46 -47q-2 0 -124 71q-4 3 -4 7q0 25 51 138q-18 25 -30 52q-149 15 -149 31v140q0 16 149 31q13 29 30 52q-51 113 -51 138q0 4 4 7q4 2 35 20t59 34t30 16q8 0 46 -46.5t52 -67.5q20 2 30 2t30 -2q51 71 92 112l6 2q4 0 124 -70
-q4 -3 4 -7q0 -25 -51 -138q17 -23 30 -52q149 -15 149 -31z" />
-    <glyph glyph-name="comments" unicode="&#xf086;" horiz-adv-x="1792" 
-d="M1408 768q0 -139 -94 -257t-256.5 -186.5t-353.5 -68.5q-86 0 -176 16q-124 -88 -278 -128q-36 -9 -86 -16h-3q-11 0 -20.5 8t-11.5 21q-1 3 -1 6.5t0.5 6.5t2 6l2.5 5t3.5 5.5t4 5t4.5 5t4 4.5q5 6 23 25t26 29.5t22.5 29t25 38.5t20.5 44q-124 72 -195 177t-71 224
-q0 139 94 257t256.5 186.5t353.5 68.5t353.5 -68.5t256.5 -186.5t94 -257zM1792 512q0 -120 -71 -224.5t-195 -176.5q10 -24 20.5 -44t25 -38.5t22.5 -29t26 -29.5t23 -25q1 -1 4 -4.5t4.5 -5t4 -5t3.5 -5.5l2.5 -5t2 -6t0.5 -6.5t-1 -6.5q-3 -14 -13 -22t-22 -7
-q-50 7 -86 16q-154 40 -278 128q-90 -16 -176 -16q-271 0 -472 132q58 -4 88 -4q161 0 309 45t264 129q125 92 192 212t67 254q0 77 -23 152q129 -71 204 -178t75 -230z" />
-    <glyph glyph-name="thumbs_up_alt" unicode="&#xf087;" 
-d="M256 192q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1408 768q0 51 -39 89.5t-89 38.5h-352q0 58 48 159.5t48 160.5q0 98 -32 145t-128 47q-26 -26 -38 -85t-30.5 -125.5t-59.5 -109.5q-22 -23 -77 -91q-4 -5 -23 -30t-31.5 -41t-34.5 -42.5
-t-40 -44t-38.5 -35.5t-40 -27t-35.5 -9h-32v-640h32q13 0 31.5 -3t33 -6.5t38 -11t35 -11.5t35.5 -12.5t29 -10.5q211 -73 342 -73h121q192 0 192 167q0 26 -5 56q30 16 47.5 52.5t17.5 73.5t-18 69q53 50 53 119q0 25 -10 55.5t-25 47.5q32 1 53.5 47t21.5 81zM1536 769
-q0 -89 -49 -163q9 -33 9 -69q0 -77 -38 -144q3 -21 3 -43q0 -101 -60 -178q1 -139 -85 -219.5t-227 -80.5h-36h-93q-96 0 -189.5 22.5t-216.5 65.5q-116 40 -138 40h-288q-53 0 -90.5 37.5t-37.5 90.5v640q0 53 37.5 90.5t90.5 37.5h274q36 24 137 155q58 75 107 128
-q24 25 35.5 85.5t30.5 126.5t62 108q39 37 90 37q84 0 151 -32.5t102 -101.5t35 -186q0 -93 -48 -192h176q104 0 180 -76t76 -179z" />
-    <glyph glyph-name="thumbs_down_alt" unicode="&#xf088;" 
-d="M256 1088q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1408 512q0 35 -21.5 81t-53.5 47q15 17 25 47.5t10 55.5q0 69 -53 119q18 31 18 69q0 37 -17.5 73.5t-47.5 52.5q5 30 5 56q0 85 -49 126t-136 41h-128q-131 0 -342 -73q-5 -2 -29 -10.5
-t-35.5 -12.5t-35 -11.5t-38 -11t-33 -6.5t-31.5 -3h-32v-640h32q16 0 35.5 -9t40 -27t38.5 -35.5t40 -44t34.5 -42.5t31.5 -41t23 -30q55 -68 77 -91q41 -43 59.5 -109.5t30.5 -125.5t38 -85q96 0 128 47t32 145q0 59 -48 160.5t-48 159.5h352q50 0 89 38.5t39 89.5z
-M1536 511q0 -103 -76 -179t-180 -76h-176q48 -99 48 -192q0 -118 -35 -186q-35 -69 -102 -101.5t-151 -32.5q-51 0 -90 37q-34 33 -54 82t-25.5 90.5t-17.5 84.5t-31 64q-48 50 -107 127q-101 131 -137 155h-274q-53 0 -90.5 37.5t-37.5 90.5v640q0 53 37.5 90.5t90.5 37.5
-h288q22 0 138 40q128 44 223 66t200 22h112q140 0 226.5 -79t85.5 -216v-5q60 -77 60 -178q0 -22 -3 -43q38 -67 38 -144q0 -36 -9 -69q49 -73 49 -163z" />
-    <glyph glyph-name="star_half" unicode="&#xf089;" horiz-adv-x="896" 
-d="M832 1504v-1339l-449 -236q-22 -12 -40 -12q-21 0 -31.5 14.5t-10.5 35.5q0 6 2 20l86 500l-364 354q-25 27 -25 48q0 37 56 46l502 73l225 455q19 41 49 41z" />
-    <glyph glyph-name="heart_empty" unicode="&#xf08a;" horiz-adv-x="1792" 
-d="M1664 940q0 81 -21.5 143t-55 98.5t-81.5 59.5t-94 31t-98 8t-112 -25.5t-110.5 -64t-86.5 -72t-60 -61.5q-18 -22 -49 -22t-49 22q-24 28 -60 61.5t-86.5 72t-110.5 64t-112 25.5t-98 -8t-94 -31t-81.5 -59.5t-55 -98.5t-21.5 -143q0 -168 187 -355l581 -560l580 559
-q188 188 188 356zM1792 940q0 -221 -229 -450l-623 -600q-18 -18 -44 -18t-44 18l-624 602q-10 8 -27.5 26t-55.5 65.5t-68 97.5t-53.5 121t-23.5 138q0 220 127 344t351 124q62 0 126.5 -21.5t120 -58t95.5 -68.5t76 -68q36 36 76 68t95.5 68.5t120 58t126.5 21.5
-q224 0 351 -124t127 -344z" />
-    <glyph glyph-name="signout" unicode="&#xf08b;" horiz-adv-x="1664" 
-d="M640 96q0 -4 1 -20t0.5 -26.5t-3 -23.5t-10 -19.5t-20.5 -6.5h-320q-119 0 -203.5 84.5t-84.5 203.5v704q0 119 84.5 203.5t203.5 84.5h320q13 0 22.5 -9.5t9.5 -22.5q0 -4 1 -20t0.5 -26.5t-3 -23.5t-10 -19.5t-20.5 -6.5h-320q-66 0 -113 -47t-47 -113v-704
-q0 -66 47 -113t113 -47h288h11h13t11.5 -1t11.5 -3t8 -5.5t7 -9t2 -13.5zM1568 640q0 -26 -19 -45l-544 -544q-19 -19 -45 -19t-45 19t-19 45v288h-448q-26 0 -45 19t-19 45v384q0 26 19 45t45 19h448v288q0 26 19 45t45 19t45 -19l544 -544q19 -19 19 -45z" />
-    <glyph glyph-name="linkedin_sign" unicode="&#xf08c;" 
-d="M237 122h231v694h-231v-694zM483 1030q-1 52 -36 86t-93 34t-94.5 -34t-36.5 -86q0 -51 35.5 -85.5t92.5 -34.5h1q59 0 95 34.5t36 85.5zM1068 122h231v398q0 154 -73 233t-193 79q-136 0 -209 -117h2v101h-231q3 -66 0 -694h231v388q0 38 7 56q15 35 45 59.5t74 24.5
-q116 0 116 -157v-371zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
-    <glyph glyph-name="pushpin" unicode="&#xf08d;" horiz-adv-x="1152" 
-d="M480 672v448q0 14 -9 23t-23 9t-23 -9t-9 -23v-448q0 -14 9 -23t23 -9t23 9t9 23zM1152 320q0 -26 -19 -45t-45 -19h-429l-51 -483q-2 -12 -10.5 -20.5t-20.5 -8.5h-1q-27 0 -32 27l-76 485h-404q-26 0 -45 19t-19 45q0 123 78.5 221.5t177.5 98.5v512q-52 0 -90 38
-t-38 90t38 90t90 38h640q52 0 90 -38t38 -90t-38 -90t-90 -38v-512q99 0 177.5 -98.5t78.5 -221.5z" />
-    <glyph glyph-name="external_link" unicode="&#xf08e;" horiz-adv-x="1792" 
-d="M1408 608v-320q0 -119 -84.5 -203.5t-203.5 -84.5h-832q-119 0 -203.5 84.5t-84.5 203.5v832q0 119 84.5 203.5t203.5 84.5h704q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-704q-66 0 -113 -47t-47 -113v-832q0 -66 47 -113t113 -47h832q66 0 113 47t47 113v320
-q0 14 9 23t23 9h64q14 0 23 -9t9 -23zM1792 1472v-512q0 -26 -19 -45t-45 -19t-45 19l-176 176l-652 -652q-10 -10 -23 -10t-23 10l-114 114q-10 10 -10 23t10 23l652 652l-176 176q-19 19 -19 45t19 45t45 19h512q26 0 45 -19t19 -45z" />
-    <glyph glyph-name="signin" unicode="&#xf090;" 
-d="M1184 640q0 -26 -19 -45l-544 -544q-19 -19 -45 -19t-45 19t-19 45v288h-448q-26 0 -45 19t-19 45v384q0 26 19 45t45 19h448v288q0 26 19 45t45 19t45 -19l544 -544q19 -19 19 -45zM1536 992v-704q0 -119 -84.5 -203.5t-203.5 -84.5h-320q-13 0 -22.5 9.5t-9.5 22.5
-q0 4 -1 20t-0.5 26.5t3 23.5t10 19.5t20.5 6.5h320q66 0 113 47t47 113v704q0 66 -47 113t-113 47h-288h-11h-13t-11.5 1t-11.5 3t-8 5.5t-7 9t-2 13.5q0 4 -1 20t-0.5 26.5t3 23.5t10 19.5t20.5 6.5h320q119 0 203.5 -84.5t84.5 -203.5z" />
-    <glyph glyph-name="trophy" unicode="&#xf091;" horiz-adv-x="1664" 
-d="M458 653q-74 162 -74 371h-256v-96q0 -78 94.5 -162t235.5 -113zM1536 928v96h-256q0 -209 -74 -371q141 29 235.5 113t94.5 162zM1664 1056v-128q0 -71 -41.5 -143t-112 -130t-173 -97.5t-215.5 -44.5q-42 -54 -95 -95q-38 -34 -52.5 -72.5t-14.5 -89.5q0 -54 30.5 -91
-t97.5 -37q75 0 133.5 -45.5t58.5 -114.5v-64q0 -14 -9 -23t-23 -9h-832q-14 0 -23 9t-9 23v64q0 69 58.5 114.5t133.5 45.5q67 0 97.5 37t30.5 91q0 51 -14.5 89.5t-52.5 72.5q-53 41 -95 95q-113 5 -215.5 44.5t-173 97.5t-112 130t-41.5 143v128q0 40 28 68t68 28h288v96
-q0 66 47 113t113 47h576q66 0 113 -47t47 -113v-96h288q40 0 68 -28t28 -68z" />
-    <glyph glyph-name="github_sign" unicode="&#xf092;" 
-d="M519 336q4 6 -3 13q-9 7 -14 2q-4 -6 3 -13q9 -7 14 -2zM491 377q-5 7 -12 4q-6 -4 0 -12q7 -8 12 -5q6 4 0 13zM450 417q2 4 -5 8q-7 2 -8 -2q-3 -5 4 -8q8 -2 9 2zM471 394q2 1 1.5 4.5t-3.5 5.5q-6 7 -10 3t1 -11q6 -6 11 -2zM557 319q2 7 -9 11q-9 3 -13 -4
-q-2 -7 9 -11q9 -3 13 4zM599 316q0 8 -12 8q-10 0 -10 -8t11 -8t11 8zM638 323q-2 7 -13 5t-9 -9q2 -8 12 -6t10 10zM1280 640q0 212 -150 362t-362 150t-362 -150t-150 -362q0 -167 98 -300.5t252 -185.5q18 -3 26.5 5t8.5 20q0 52 -1 95q-6 -1 -15.5 -2.5t-35.5 -2t-48 4
-t-43.5 20t-29.5 41.5q-23 59 -57 74q-2 1 -4.5 3.5l-8 8t-7 9.5t4 7.5t19.5 3.5q6 0 15 -2t30 -15.5t33 -35.5q16 -28 37.5 -42t43.5 -14t38 3.5t30 9.5q7 47 33 69q-49 6 -86 18.5t-73 39t-55.5 76t-19.5 119.5q0 79 53 137q-24 62 5 136q19 6 54.5 -7.5t60.5 -29.5l26 -16
-q58 17 128 17t128 -17q11 7 28.5 18t55.5 26t57 9q29 -74 5 -136q53 -58 53 -137q0 -57 -14 -100.5t-35.5 -70t-53.5 -44.5t-62.5 -26t-68.5 -12q35 -31 35 -95q0 -40 -0.5 -89t-0.5 -51q0 -12 8.5 -20t26.5 -5q154 52 252 185.5t98 300.5zM1536 1120v-960
-q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
-    <glyph glyph-name="upload_alt" unicode="&#xf093;" horiz-adv-x="1664" 
-d="M1280 64q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1536 64q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1664 288v-320q0 -40 -28 -68t-68 -28h-1472q-40 0 -68 28t-28 68v320q0 40 28 68t68 28h427q21 -56 70.5 -92
-t110.5 -36h256q61 0 110.5 36t70.5 92h427q40 0 68 -28t28 -68zM1339 936q-17 -40 -59 -40h-256v-448q0 -26 -19 -45t-45 -19h-256q-26 0 -45 19t-19 45v448h-256q-42 0 -59 40q-17 39 14 69l448 448q18 19 45 19t45 -19l448 -448q31 -30 14 -69z" />
-    <glyph glyph-name="lemon" unicode="&#xf094;" 
-d="M1407 710q0 44 -7 113.5t-18 96.5q-12 30 -17 44t-9 36.5t-4 48.5q0 23 5 68.5t5 67.5q0 37 -10 55q-4 1 -13 1q-19 0 -58 -4.5t-59 -4.5q-60 0 -176 24t-175 24q-43 0 -94.5 -11.5t-85 -23.5t-89.5 -34q-137 -54 -202 -103q-96 -73 -159.5 -189.5t-88 -236t-24.5 -248.5
-q0 -40 12.5 -120t12.5 -121q0 -23 -11 -66.5t-11 -65.5t12 -36.5t34 -14.5q24 0 72.5 11t73.5 11q57 0 169.5 -15.5t169.5 -15.5q181 0 284 36q129 45 235.5 152.5t166 245.5t59.5 275zM1535 712q0 -165 -70 -327.5t-196 -288t-281 -180.5q-124 -44 -326 -44
-q-57 0 -170 14.5t-169 14.5q-24 0 -72.5 -14.5t-73.5 -14.5q-73 0 -123.5 55.5t-50.5 128.5q0 24 11 68t11 67q0 40 -12.5 120.5t-12.5 121.5q0 111 18 217.5t54.5 209.5t100.5 194t150 156q78 59 232 120q194 78 316 78q60 0 175.5 -24t173.5 -24q19 0 57 5t58 5
-q81 0 118 -50.5t37 -134.5q0 -23 -5 -68t-5 -68q0 -13 2 -25t3.5 -16.5t7.5 -20.5t8 -20q16 -40 25 -118.5t9 -136.5z" />
-    <glyph glyph-name="phone" unicode="&#xf095;" horiz-adv-x="1408" 
-d="M1408 296q0 -27 -10 -70.5t-21 -68.5q-21 -50 -122 -106q-94 -51 -186 -51q-27 0 -53 3.5t-57.5 12.5t-47 14.5t-55.5 20.5t-49 18q-98 35 -175 83q-127 79 -264 216t-216 264q-48 77 -83 175q-3 9 -18 49t-20.5 55.5t-14.5 47t-12.5 57.5t-3.5 53q0 92 51 186
-q56 101 106 122q25 11 68.5 21t70.5 10q14 0 21 -3q18 -6 53 -76q11 -19 30 -54t35 -63.5t31 -53.5q3 -4 17.5 -25t21.5 -35.5t7 -28.5q0 -20 -28.5 -50t-62 -55t-62 -53t-28.5 -46q0 -9 5 -22.5t8.5 -20.5t14 -24t11.5 -19q76 -137 174 -235t235 -174q2 -1 19 -11.5t24 -14
-t20.5 -8.5t22.5 -5q18 0 46 28.5t53 62t55 62t50 28.5q14 0 28.5 -7t35.5 -21.5t25 -17.5q25 -15 53.5 -31t63.5 -35t54 -30q70 -35 76 -53q3 -7 3 -21z" />
-    <glyph glyph-name="check_empty" unicode="&#xf096;" horiz-adv-x="1408" 
-d="M1120 1280h-832q-66 0 -113 -47t-47 -113v-832q0 -66 47 -113t113 -47h832q66 0 113 47t47 113v832q0 66 -47 113t-113 47zM1408 1120v-832q0 -119 -84.5 -203.5t-203.5 -84.5h-832q-119 0 -203.5 84.5t-84.5 203.5v832q0 119 84.5 203.5t203.5 84.5h832
-q119 0 203.5 -84.5t84.5 -203.5z" />
-    <glyph glyph-name="bookmark_empty" unicode="&#xf097;" horiz-adv-x="1280" 
-d="M1152 1280h-1024v-1242l423 406l89 85l89 -85l423 -406v1242zM1164 1408q23 0 44 -9q33 -13 52.5 -41t19.5 -62v-1289q0 -34 -19.5 -62t-52.5 -41q-19 -8 -44 -8q-48 0 -83 32l-441 424l-441 -424q-36 -33 -83 -33q-23 0 -44 9q-33 13 -52.5 41t-19.5 62v1289
-q0 34 19.5 62t52.5 41q21 9 44 9h1048z" />
-    <glyph glyph-name="phone_sign" unicode="&#xf098;" 
-d="M1280 343q0 11 -2 16t-18 16.5t-40.5 25t-47.5 26.5t-45.5 25t-28.5 15q-5 3 -19 13t-25 15t-21 5q-15 0 -36.5 -20.5t-39.5 -45t-38.5 -45t-33.5 -20.5q-7 0 -16.5 3.5t-15.5 6.5t-17 9.5t-14 8.5q-99 55 -170 126.5t-127 170.5q-2 3 -8.5 14t-9.5 17t-6.5 15.5
-t-3.5 16.5q0 13 20.5 33.5t45 38.5t45 39.5t20.5 36.5q0 10 -5 21t-15 25t-13 19q-3 6 -15 28.5t-25 45.5t-26.5 47.5t-25 40.5t-16.5 18t-16 2q-48 0 -101 -22q-46 -21 -80 -94.5t-34 -130.5q0 -16 2.5 -34t5 -30.5t9 -33t10 -29.5t12.5 -33t11 -30q60 -164 216.5 -320.5
-t320.5 -216.5q6 -2 30 -11t33 -12.5t29.5 -10t33 -9t30.5 -5t34 -2.5q57 0 130.5 34t94.5 80q22 53 22 101zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z
-" />
-    <glyph glyph-name="twitter" unicode="&#xf099;" horiz-adv-x="1664" 
-d="M1620 1128q-67 -98 -162 -167q1 -14 1 -42q0 -130 -38 -259.5t-115.5 -248.5t-184.5 -210.5t-258 -146t-323 -54.5q-271 0 -496 145q35 -4 78 -4q225 0 401 138q-105 2 -188 64.5t-114 159.5q33 -5 61 -5q43 0 85 11q-112 23 -185.5 111.5t-73.5 205.5v4q68 -38 146 -41
-q-66 44 -105 115t-39 154q0 88 44 163q121 -149 294.5 -238.5t371.5 -99.5q-8 38 -8 74q0 134 94.5 228.5t228.5 94.5q140 0 236 -102q109 21 205 78q-37 -115 -142 -178q93 10 186 50z" />
-    <glyph glyph-name="facebook" unicode="&#xf09a;" horiz-adv-x="1024" 
-d="M959 1524v-264h-157q-86 0 -116 -36t-30 -108v-189h293l-39 -296h-254v-759h-306v759h-255v296h255v218q0 186 104 288.5t277 102.5q147 0 228 -12z" />
-    <glyph glyph-name="github" unicode="&#xf09b;" 
-d="M768 1408q209 0 385.5 -103t279.5 -279.5t103 -385.5q0 -251 -146.5 -451.5t-378.5 -277.5q-27 -5 -40 7t-13 30q0 3 0.5 76.5t0.5 134.5q0 97 -52 142q57 6 102.5 18t94 39t81 66.5t53 105t20.5 150.5q0 119 -79 206q37 91 -8 204q-28 9 -81 -11t-92 -44l-38 -24
-q-93 26 -192 26t-192 -26q-16 11 -42.5 27t-83.5 38.5t-85 13.5q-45 -113 -8 -204q-79 -87 -79 -206q0 -85 20.5 -150t52.5 -105t80.5 -67t94 -39t102.5 -18q-39 -36 -49 -103q-21 -10 -45 -15t-57 -5t-65.5 21.5t-55.5 62.5q-19 32 -48.5 52t-49.5 24l-20 3q-21 0 -29 -4.5
-t-5 -11.5t9 -14t13 -12l7 -5q22 -10 43.5 -38t31.5 -51l10 -23q13 -38 44 -61.5t67 -30t69.5 -7t55.5 3.5l23 4q0 -38 0.5 -88.5t0.5 -54.5q0 -18 -13 -30t-40 -7q-232 77 -378.5 277.5t-146.5 451.5q0 209 103 385.5t279.5 279.5t385.5 103zM291 305q3 7 -7 12
-q-10 3 -13 -2q-3 -7 7 -12q9 -6 13 2zM322 271q7 5 -2 16q-10 9 -16 3q-7 -5 2 -16q10 -10 16 -3zM352 226q9 7 0 19q-8 13 -17 6q-9 -5 0 -18t17 -7zM394 184q8 8 -4 19q-12 12 -20 3q-9 -8 4 -19q12 -12 20 -3zM451 159q3 11 -13 16q-15 4 -19 -7t13 -15q15 -6 19 6z
-M514 154q0 13 -17 11q-16 0 -16 -11q0 -13 17 -11q16 0 16 11zM572 164q-2 11 -18 9q-16 -3 -14 -15t18 -8t14 14z" />
-    <glyph glyph-name="unlock" unicode="&#xf09c;" horiz-adv-x="1664" 
-d="M1664 960v-256q0 -26 -19 -45t-45 -19h-64q-26 0 -45 19t-19 45v256q0 106 -75 181t-181 75t-181 -75t-75 -181v-192h96q40 0 68 -28t28 -68v-576q0 -40 -28 -68t-68 -28h-960q-40 0 -68 28t-28 68v576q0 40 28 68t68 28h672v192q0 185 131.5 316.5t316.5 131.5
-t316.5 -131.5t131.5 -316.5z" />
-    <glyph glyph-name="credit_card" unicode="&#xf09d;" horiz-adv-x="1920" 
-d="M1760 1408q66 0 113 -47t47 -113v-1216q0 -66 -47 -113t-113 -47h-1600q-66 0 -113 47t-47 113v1216q0 66 47 113t113 47h1600zM160 1280q-13 0 -22.5 -9.5t-9.5 -22.5v-224h1664v224q0 13 -9.5 22.5t-22.5 9.5h-1600zM1760 0q13 0 22.5 9.5t9.5 22.5v608h-1664v-608
-q0 -13 9.5 -22.5t22.5 -9.5h1600zM256 128v128h256v-128h-256zM640 128v128h384v-128h-384z" />
-    <glyph glyph-name="rss" unicode="&#xf09e;" horiz-adv-x="1408" 
-d="M384 192q0 -80 -56 -136t-136 -56t-136 56t-56 136t56 136t136 56t136 -56t56 -136zM896 69q2 -28 -17 -48q-18 -21 -47 -21h-135q-25 0 -43 16.5t-20 41.5q-22 229 -184.5 391.5t-391.5 184.5q-25 2 -41.5 20t-16.5 43v135q0 29 21 47q17 17 43 17h5q160 -13 306 -80.5
-t259 -181.5q114 -113 181.5 -259t80.5 -306zM1408 67q2 -27 -18 -47q-18 -20 -46 -20h-143q-26 0 -44.5 17.5t-19.5 42.5q-12 215 -101 408.5t-231.5 336t-336 231.5t-408.5 102q-25 1 -42.5 19.5t-17.5 43.5v143q0 28 20 46q18 18 44 18h3q262 -13 501.5 -120t425.5 -294
-q187 -186 294 -425.5t120 -501.5z" />
-    <glyph glyph-name="hdd" unicode="&#xf0a0;" 
-d="M1040 320q0 -33 -23.5 -56.5t-56.5 -23.5t-56.5 23.5t-23.5 56.5t23.5 56.5t56.5 23.5t56.5 -23.5t23.5 -56.5zM1296 320q0 -33 -23.5 -56.5t-56.5 -23.5t-56.5 23.5t-23.5 56.5t23.5 56.5t56.5 23.5t56.5 -23.5t23.5 -56.5zM1408 160v320q0 13 -9.5 22.5t-22.5 9.5
-h-1216q-13 0 -22.5 -9.5t-9.5 -22.5v-320q0 -13 9.5 -22.5t22.5 -9.5h1216q13 0 22.5 9.5t9.5 22.5zM178 640h1180l-157 482q-4 13 -16 21.5t-26 8.5h-782q-14 0 -26 -8.5t-16 -21.5zM1536 480v-320q0 -66 -47 -113t-113 -47h-1216q-66 0 -113 47t-47 113v320q0 25 16 75
-l197 606q17 53 63 86t101 33h782q55 0 101 -33t63 -86l197 -606q16 -50 16 -75z" />
-    <glyph glyph-name="bullhorn" unicode="&#xf0a1;" horiz-adv-x="1792" 
-d="M1664 896q53 0 90.5 -37.5t37.5 -90.5t-37.5 -90.5t-90.5 -37.5v-384q0 -52 -38 -90t-90 -38q-417 347 -812 380q-58 -19 -91 -66t-31 -100.5t40 -92.5q-20 -33 -23 -65.5t6 -58t33.5 -55t48 -50t61.5 -50.5q-29 -58 -111.5 -83t-168.5 -11.5t-132 55.5q-7 23 -29.5 87.5
-t-32 94.5t-23 89t-15 101t3.5 98.5t22 110.5h-122q-66 0 -113 47t-47 113v192q0 66 47 113t113 47h480q435 0 896 384q52 0 90 -38t38 -90v-384zM1536 292v954q-394 -302 -768 -343v-270q377 -42 768 -341z" />
-    <glyph glyph-name="bell" unicode="&#xf0a2;" horiz-adv-x="1792" 
-d="M912 -160q0 16 -16 16q-59 0 -101.5 42.5t-42.5 101.5q0 16 -16 16t-16 -16q0 -73 51.5 -124.5t124.5 -51.5q16 0 16 16zM246 128h1300q-266 300 -266 832q0 51 -24 105t-69 103t-121.5 80.5t-169.5 31.5t-169.5 -31.5t-121.5 -80.5t-69 -103t-24 -105q0 -532 -266 -832z
-M1728 128q0 -52 -38 -90t-90 -38h-448q0 -106 -75 -181t-181 -75t-181 75t-75 181h-448q-52 0 -90 38t-38 90q50 42 91 88t85 119.5t74.5 158.5t50 206t19.5 260q0 152 117 282.5t307 158.5q-8 19 -8 39q0 40 28 68t68 28t68 -28t28 -68q0 -20 -8 -39q190 -28 307 -158.5
-t117 -282.5q0 -139 19.5 -260t50 -206t74.5 -158.5t85 -119.5t91 -88z" />
-    <glyph glyph-name="certificate" unicode="&#xf0a3;" 
-d="M1376 640l138 -135q30 -28 20 -70q-12 -41 -52 -51l-188 -48l53 -186q12 -41 -19 -70q-29 -31 -70 -19l-186 53l-48 -188q-10 -40 -51 -52q-12 -2 -19 -2q-31 0 -51 22l-135 138l-135 -138q-28 -30 -70 -20q-41 11 -51 52l-48 188l-186 -53q-41 -12 -70 19q-31 29 -19 70
-l53 186l-188 48q-40 10 -52 51q-10 42 20 70l138 135l-138 135q-30 28 -20 70q12 41 52 51l188 48l-53 186q-12 41 19 70q29 31 70 19l186 -53l48 188q10 41 51 51q41 12 70 -19l135 -139l135 139q29 30 70 19q41 -10 51 -51l48 -188l186 53q41 12 70 -19q31 -29 19 -70
-l-53 -186l188 -48q40 -10 52 -51q10 -42 -20 -70z" />
-    <glyph glyph-name="hand_right" unicode="&#xf0a4;" horiz-adv-x="1792" 
-d="M256 192q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1664 768q0 51 -39 89.5t-89 38.5h-576q0 20 15 48.5t33 55t33 68t15 84.5q0 67 -44.5 97.5t-115.5 30.5q-24 0 -90 -139q-24 -44 -37 -65q-40 -64 -112 -145q-71 -81 -101 -106
-q-69 -57 -140 -57h-32v-640h32q72 0 167 -32t193.5 -64t179.5 -32q189 0 189 167q0 26 -5 56q30 16 47.5 52.5t17.5 73.5t-18 69q53 50 53 119q0 25 -10 55.5t-25 47.5h331q52 0 90 38t38 90zM1792 769q0 -105 -75.5 -181t-180.5 -76h-169q-4 -62 -37 -119q3 -21 3 -43
-q0 -101 -60 -178q1 -139 -85 -219.5t-227 -80.5q-133 0 -322 69q-164 59 -223 59h-288q-53 0 -90.5 37.5t-37.5 90.5v640q0 53 37.5 90.5t90.5 37.5h288q10 0 21.5 4.5t23.5 14t22.5 18t24 22.5t20.5 21.5t19 21.5t14 17q65 74 100 129q13 21 33 62t37 72t40.5 63t55 49.5
-t69.5 17.5q125 0 206.5 -67t81.5 -189q0 -68 -22 -128h374q104 0 180 -76t76 -179z" />
-    <glyph glyph-name="hand_left" unicode="&#xf0a5;" horiz-adv-x="1792" 
-d="M1376 128h32v640h-32q-35 0 -67.5 12t-62.5 37t-50 46t-49 54q-8 9 -12 14q-72 81 -112 145q-14 22 -38 68q-1 3 -10.5 22.5t-18.5 36t-20 35.5t-21.5 30.5t-18.5 11.5q-71 0 -115.5 -30.5t-44.5 -97.5q0 -43 15 -84.5t33 -68t33 -55t15 -48.5h-576q-50 0 -89 -38.5
-t-39 -89.5q0 -52 38 -90t90 -38h331q-15 -17 -25 -47.5t-10 -55.5q0 -69 53 -119q-18 -32 -18 -69t17.5 -73.5t47.5 -52.5q-4 -24 -4 -56q0 -85 48.5 -126t135.5 -41q84 0 183 32t194 64t167 32zM1664 192q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45z
-M1792 768v-640q0 -53 -37.5 -90.5t-90.5 -37.5h-288q-59 0 -223 -59q-190 -69 -317 -69q-142 0 -230 77.5t-87 217.5l1 5q-61 76 -61 178q0 22 3 43q-33 57 -37 119h-169q-105 0 -180.5 76t-75.5 181q0 103 76 179t180 76h374q-22 60 -22 128q0 122 81.5 189t206.5 67
-q38 0 69.5 -17.5t55 -49.5t40.5 -63t37 -72t33 -62q35 -55 100 -129q2 -3 14 -17t19 -21.5t20.5 -21.5t24 -22.5t22.5 -18t23.5 -14t21.5 -4.5h288q53 0 90.5 -37.5t37.5 -90.5z" />
-    <glyph glyph-name="hand_up" unicode="&#xf0a6;" 
-d="M1280 -64q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1408 700q0 189 -167 189q-26 0 -56 -5q-16 30 -52.5 47.5t-73.5 17.5t-69 -18q-50 53 -119 53q-25 0 -55.5 -10t-47.5 -25v331q0 52 -38 90t-90 38q-51 0 -89.5 -39t-38.5 -89v-576
-q-20 0 -48.5 15t-55 33t-68 33t-84.5 15q-67 0 -97.5 -44.5t-30.5 -115.5q0 -24 139 -90q44 -24 65 -37q64 -40 145 -112q81 -71 106 -101q57 -69 57 -140v-32h640v32q0 72 32 167t64 193.5t32 179.5zM1536 705q0 -133 -69 -322q-59 -164 -59 -223v-288q0 -53 -37.5 -90.5
-t-90.5 -37.5h-640q-53 0 -90.5 37.5t-37.5 90.5v288q0 10 -4.5 21.5t-14 23.5t-18 22.5t-22.5 24t-21.5 20.5t-21.5 19t-17 14q-74 65 -129 100q-21 13 -62 33t-72 37t-63 40.5t-49.5 55t-17.5 69.5q0 125 67 206.5t189 81.5q68 0 128 -22v374q0 104 76 180t179 76
-q105 0 181 -75.5t76 -180.5v-169q62 -4 119 -37q21 3 43 3q101 0 178 -60q139 1 219.5 -85t80.5 -227z" />
-    <glyph glyph-name="hand_down" unicode="&#xf0a7;" 
-d="M1408 576q0 84 -32 183t-64 194t-32 167v32h-640v-32q0 -35 -12 -67.5t-37 -62.5t-46 -50t-54 -49q-9 -8 -14 -12q-81 -72 -145 -112q-22 -14 -68 -38q-3 -1 -22.5 -10.5t-36 -18.5t-35.5 -20t-30.5 -21.5t-11.5 -18.5q0 -71 30.5 -115.5t97.5 -44.5q43 0 84.5 15t68 33
-t55 33t48.5 15v-576q0 -50 38.5 -89t89.5 -39q52 0 90 38t38 90v331q46 -35 103 -35q69 0 119 53q32 -18 69 -18t73.5 17.5t52.5 47.5q24 -4 56 -4q85 0 126 48.5t41 135.5zM1280 1344q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1536 580
-q0 -142 -77.5 -230t-217.5 -87l-5 1q-76 -61 -178 -61q-22 0 -43 3q-54 -30 -119 -37v-169q0 -105 -76 -180.5t-181 -75.5q-103 0 -179 76t-76 180v374q-54 -22 -128 -22q-121 0 -188.5 81.5t-67.5 206.5q0 38 17.5 69.5t49.5 55t63 40.5t72 37t62 33q55 35 129 100
-q3 2 17 14t21.5 19t21.5 20.5t22.5 24t18 22.5t14 23.5t4.5 21.5v288q0 53 37.5 90.5t90.5 37.5h640q53 0 90.5 -37.5t37.5 -90.5v-288q0 -59 59 -223q69 -190 69 -317z" />
-    <glyph glyph-name="circle_arrow_left" unicode="&#xf0a8;" 
-d="M1280 576v128q0 26 -19 45t-45 19h-502l189 189q19 19 19 45t-19 45l-91 91q-18 18 -45 18t-45 -18l-362 -362l-91 -91q-18 -18 -18 -45t18 -45l91 -91l362 -362q18 -18 45 -18t45 18l91 91q18 18 18 45t-18 45l-189 189h502q26 0 45 19t19 45zM1536 640
-q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
-    <glyph glyph-name="circle_arrow_right" unicode="&#xf0a9;" 
-d="M1285 640q0 27 -18 45l-91 91l-362 362q-18 18 -45 18t-45 -18l-91 -91q-18 -18 -18 -45t18 -45l189 -189h-502q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45t45 -19h502l-189 -189q-19 -19 -19 -45t19 -45l91 -91q18 -18 45 -18t45 18l362 362l91 91q18 18 18 45zM1536 640
-q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
-    <glyph glyph-name="circle_arrow_up" unicode="&#xf0aa;" 
-d="M1284 641q0 27 -18 45l-362 362l-91 91q-18 18 -45 18t-45 -18l-91 -91l-362 -362q-18 -18 -18 -45t18 -45l91 -91q18 -18 45 -18t45 18l189 189v-502q0 -26 19 -45t45 -19h128q26 0 45 19t19 45v502l189 -189q19 -19 45 -19t45 19l91 91q18 18 18 45zM1536 640
-q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
-    <glyph glyph-name="circle_arrow_down" unicode="&#xf0ab;" 
-d="M1284 639q0 27 -18 45l-91 91q-18 18 -45 18t-45 -18l-189 -189v502q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-502l-189 189q-19 19 -45 19t-45 -19l-91 -91q-18 -18 -18 -45t18 -45l362 -362l91 -91q18 -18 45 -18t45 18l91 91l362 362q18 18 18 45zM1536 640
-q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
-    <glyph glyph-name="globe" unicode="&#xf0ac;" 
-d="M768 1408q209 0 385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103zM1042 887q-2 -1 -9.5 -9.5t-13.5 -9.5q2 0 4.5 5t5 11t3.5 7q6 7 22 15q14 6 52 12q34 8 51 -11
-q-2 2 9.5 13t14.5 12q3 2 15 4.5t15 7.5l2 22q-12 -1 -17.5 7t-6.5 21q0 -2 -6 -8q0 7 -4.5 8t-11.5 -1t-9 -1q-10 3 -15 7.5t-8 16.5t-4 15q-2 5 -9.5 11t-9.5 10q-1 2 -2.5 5.5t-3 6.5t-4 5.5t-5.5 2.5t-7 -5t-7.5 -10t-4.5 -5q-3 2 -6 1.5t-4.5 -1t-4.5 -3t-5 -3.5
-q-3 -2 -8.5 -3t-8.5 -2q15 5 -1 11q-10 4 -16 3q9 4 7.5 12t-8.5 14h5q-1 4 -8.5 8.5t-17.5 8.5t-13 6q-8 5 -34 9.5t-33 0.5q-5 -6 -4.5 -10.5t4 -14t3.5 -12.5q1 -6 -5.5 -13t-6.5 -12q0 -7 14 -15.5t10 -21.5q-3 -8 -16 -16t-16 -12q-5 -8 -1.5 -18.5t10.5 -16.5
-q2 -2 1.5 -4t-3.5 -4.5t-5.5 -4t-6.5 -3.5l-3 -2q-11 -5 -20.5 6t-13.5 26q-7 25 -16 30q-23 8 -29 -1q-5 13 -41 26q-25 9 -58 4q6 1 0 15q-7 15 -19 12q3 6 4 17.5t1 13.5q3 13 12 23q1 1 7 8.5t9.5 13.5t0.5 6q35 -4 50 11q5 5 11.5 17t10.5 17q9 6 14 5.5t14.5 -5.5
-t14.5 -5q14 -1 15.5 11t-7.5 20q12 -1 3 17q-4 7 -8 9q-12 4 -27 -5q-8 -4 2 -8q-1 1 -9.5 -10.5t-16.5 -17.5t-16 5q-1 1 -5.5 13.5t-9.5 13.5q-8 0 -16 -15q3 8 -11 15t-24 8q19 12 -8 27q-7 4 -20.5 5t-19.5 -4q-5 -7 -5.5 -11.5t5 -8t10.5 -5.5t11.5 -4t8.5 -3
-q14 -10 8 -14q-2 -1 -8.5 -3.5t-11.5 -4.5t-6 -4q-3 -4 0 -14t-2 -14q-5 5 -9 17.5t-7 16.5q7 -9 -25 -6l-10 1q-4 0 -16 -2t-20.5 -1t-13.5 8q-4 8 0 20q1 4 4 2q-4 3 -11 9.5t-10 8.5q-46 -15 -94 -41q6 -1 12 1q5 2 13 6.5t10 5.5q34 14 42 7l5 5q14 -16 20 -25
-q-7 4 -30 1q-20 -6 -22 -12q7 -12 5 -18q-4 3 -11.5 10t-14.5 11t-15 5q-16 0 -22 -1q-146 -80 -235 -222q7 -7 12 -8q4 -1 5 -9t2.5 -11t11.5 3q9 -8 3 -19q1 1 44 -27q19 -17 21 -21q3 -11 -10 -18q-1 2 -9 9t-9 4q-3 -5 0.5 -18.5t10.5 -12.5q-7 0 -9.5 -16t-2.5 -35.5
-t-1 -23.5l2 -1q-3 -12 5.5 -34.5t21.5 -19.5q-13 -3 20 -43q6 -8 8 -9q3 -2 12 -7.5t15 -10t10 -10.5q4 -5 10 -22.5t14 -23.5q-2 -6 9.5 -20t10.5 -23q-1 0 -2.5 -1t-2.5 -1q3 -7 15.5 -14t15.5 -13q1 -3 2 -10t3 -11t8 -2q2 20 -24 62q-15 25 -17 29q-3 5 -5.5 15.5
-t-4.5 14.5q2 0 6 -1.5t8.5 -3.5t7.5 -4t2 -3q-3 -7 2 -17.5t12 -18.5t17 -19t12 -13q6 -6 14 -19.5t0 -13.5q9 0 20 -10.5t17 -19.5q5 -8 8 -26t5 -24q2 -7 8.5 -13.5t12.5 -9.5l16 -8t13 -7q5 -2 18.5 -10.5t21.5 -11.5q10 -4 16 -4t14.5 2.5t13.5 3.5q15 2 29 -15t21 -21
-q36 -19 55 -11q-2 -1 0.5 -7.5t8 -15.5t9 -14.5t5.5 -8.5q5 -6 18 -15t18 -15q6 4 7 9q-3 -8 7 -20t18 -10q14 3 14 32q-31 -15 -49 18q0 1 -2.5 5.5t-4 8.5t-2.5 8.5t0 7.5t5 3q9 0 10 3.5t-2 12.5t-4 13q-1 8 -11 20t-12 15q-5 -9 -16 -8t-16 9q0 -1 -1.5 -5.5t-1.5 -6.5
-q-13 0 -15 1q1 3 2.5 17.5t3.5 22.5q1 4 5.5 12t7.5 14.5t4 12.5t-4.5 9.5t-17.5 2.5q-19 -1 -26 -20q-1 -3 -3 -10.5t-5 -11.5t-9 -7q-7 -3 -24 -2t-24 5q-13 8 -22.5 29t-9.5 37q0 10 2.5 26.5t3 25t-5.5 24.5q3 2 9 9.5t10 10.5q2 1 4.5 1.5t4.5 0t4 1.5t3 6q-1 1 -4 3
-q-3 3 -4 3q7 -3 28.5 1.5t27.5 -1.5q15 -11 22 2q0 1 -2.5 9.5t-0.5 13.5q5 -27 29 -9q3 -3 15.5 -5t17.5 -5q3 -2 7 -5.5t5.5 -4.5t5 0.5t8.5 6.5q10 -14 12 -24q11 -40 19 -44q7 -3 11 -2t4.5 9.5t0 14t-1.5 12.5l-1 8v18l-1 8q-15 3 -18.5 12t1.5 18.5t15 18.5q1 1 8 3.5
-t15.5 6.5t12.5 8q21 19 15 35q7 0 11 9q-1 0 -5 3t-7.5 5t-4.5 2q9 5 2 16q5 3 7.5 11t7.5 10q9 -12 21 -2q8 8 1 16q5 7 20.5 10.5t18.5 9.5q7 -2 8 2t1 12t3 12q4 5 15 9t13 5l17 11q3 4 0 4q18 -2 31 11q10 11 -6 20q3 6 -3 9.5t-15 5.5q3 1 11.5 0.5t10.5 1.5
-q15 10 -7 16q-17 5 -43 -12zM879 10q206 36 351 189q-3 3 -12.5 4.5t-12.5 3.5q-18 7 -24 8q1 7 -2.5 13t-8 9t-12.5 8t-11 7q-2 2 -7 6t-7 5.5t-7.5 4.5t-8.5 2t-10 -1l-3 -1q-3 -1 -5.5 -2.5t-5.5 -3t-4 -3t0 -2.5q-21 17 -36 22q-5 1 -11 5.5t-10.5 7t-10 1.5t-11.5 -7
-q-5 -5 -6 -15t-2 -13q-7 5 0 17.5t2 18.5q-3 6 -10.5 4.5t-12 -4.5t-11.5 -8.5t-9 -6.5t-8.5 -5.5t-8.5 -7.5q-3 -4 -6 -12t-5 -11q-2 4 -11.5 6.5t-9.5 5.5q2 -10 4 -35t5 -38q7 -31 -12 -48q-27 -25 -29 -40q-4 -22 12 -26q0 -7 -8 -20.5t-7 -21.5q0 -6 2 -16z" />
-    <glyph glyph-name="wrench" unicode="&#xf0ad;" horiz-adv-x="1664" 
-d="M384 64q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1028 484l-682 -682q-37 -37 -90 -37q-52 0 -91 37l-106 108q-38 36 -38 90q0 53 38 91l681 681q39 -98 114.5 -173.5t173.5 -114.5zM1662 919q0 -39 -23 -106q-47 -134 -164.5 -217.5
-t-258.5 -83.5q-185 0 -316.5 131.5t-131.5 316.5t131.5 316.5t316.5 131.5q58 0 121.5 -16.5t107.5 -46.5q16 -11 16 -28t-16 -28l-293 -169v-224l193 -107q5 3 79 48.5t135.5 81t70.5 35.5q15 0 23.5 -10t8.5 -25z" />
-    <glyph glyph-name="tasks" unicode="&#xf0ae;" horiz-adv-x="1792" 
-d="M1024 128h640v128h-640v-128zM640 640h1024v128h-1024v-128zM1280 1152h384v128h-384v-128zM1792 320v-256q0 -26 -19 -45t-45 -19h-1664q-26 0 -45 19t-19 45v256q0 26 19 45t45 19h1664q26 0 45 -19t19 -45zM1792 832v-256q0 -26 -19 -45t-45 -19h-1664q-26 0 -45 19
-t-19 45v256q0 26 19 45t45 19h1664q26 0 45 -19t19 -45zM1792 1344v-256q0 -26 -19 -45t-45 -19h-1664q-26 0 -45 19t-19 45v256q0 26 19 45t45 19h1664q26 0 45 -19t19 -45z" />
-    <glyph glyph-name="filter" unicode="&#xf0b0;" horiz-adv-x="1408" 
-d="M1403 1241q17 -41 -14 -70l-493 -493v-742q0 -42 -39 -59q-13 -5 -25 -5q-27 0 -45 19l-256 256q-19 19 -19 45v486l-493 493q-31 29 -14 70q17 39 59 39h1280q42 0 59 -39z" />
-    <glyph glyph-name="briefcase" unicode="&#xf0b1;" horiz-adv-x="1792" 
-d="M640 1280h512v128h-512v-128zM1792 640v-480q0 -66 -47 -113t-113 -47h-1472q-66 0 -113 47t-47 113v480h672v-160q0 -26 19 -45t45 -19h320q26 0 45 19t19 45v160h672zM1024 640v-128h-256v128h256zM1792 1120v-384h-1792v384q0 66 47 113t113 47h352v160q0 40 28 68
-t68 28h576q40 0 68 -28t28 -68v-160h352q66 0 113 -47t47 -113z" />
-    <glyph glyph-name="fullscreen" unicode="&#xf0b2;" 
-d="M1283 995l-355 -355l355 -355l144 144q29 31 70 14q39 -17 39 -59v-448q0 -26 -19 -45t-45 -19h-448q-42 0 -59 40q-17 39 14 69l144 144l-355 355l-355 -355l144 -144q31 -30 14 -69q-17 -40 -59 -40h-448q-26 0 -45 19t-19 45v448q0 42 40 59q39 17 69 -14l144 -144
-l355 355l-355 355l-144 -144q-19 -19 -45 -19q-12 0 -24 5q-40 17 -40 59v448q0 26 19 45t45 19h448q42 0 59 -40q17 -39 -14 -69l-144 -144l355 -355l355 355l-144 144q-31 30 -14 69q17 40 59 40h448q26 0 45 -19t19 -45v-448q0 -42 -39 -59q-13 -5 -25 -5q-26 0 -45 19z
-" />
-    <glyph glyph-name="group" unicode="&#xf0c0;" horiz-adv-x="1920" 
-d="M593 640q-162 -5 -265 -128h-134q-82 0 -138 40.5t-56 118.5q0 353 124 353q6 0 43.5 -21t97.5 -42.5t119 -21.5q67 0 133 23q-5 -37 -5 -66q0 -139 81 -256zM1664 3q0 -120 -73 -189.5t-194 -69.5h-874q-121 0 -194 69.5t-73 189.5q0 53 3.5 103.5t14 109t26.5 108.5
-t43 97.5t62 81t85.5 53.5t111.5 20q10 0 43 -21.5t73 -48t107 -48t135 -21.5t135 21.5t107 48t73 48t43 21.5q61 0 111.5 -20t85.5 -53.5t62 -81t43 -97.5t26.5 -108.5t14 -109t3.5 -103.5zM640 1280q0 -106 -75 -181t-181 -75t-181 75t-75 181t75 181t181 75t181 -75
-t75 -181zM1344 896q0 -159 -112.5 -271.5t-271.5 -112.5t-271.5 112.5t-112.5 271.5t112.5 271.5t271.5 112.5t271.5 -112.5t112.5 -271.5zM1920 671q0 -78 -56 -118.5t-138 -40.5h-134q-103 123 -265 128q81 117 81 256q0 29 -5 66q66 -23 133 -23q59 0 119 21.5t97.5 42.5
-t43.5 21q124 0 124 -353zM1792 1280q0 -106 -75 -181t-181 -75t-181 75t-75 181t75 181t181 75t181 -75t75 -181z" />
-    <glyph glyph-name="link" unicode="&#xf0c1;" horiz-adv-x="1664" 
-d="M1456 320q0 40 -28 68l-208 208q-28 28 -68 28q-42 0 -72 -32q3 -3 19 -18.5t21.5 -21.5t15 -19t13 -25.5t3.5 -27.5q0 -40 -28 -68t-68 -28q-15 0 -27.5 3.5t-25.5 13t-19 15t-21.5 21.5t-18.5 19q-33 -31 -33 -73q0 -40 28 -68l206 -207q27 -27 68 -27q40 0 68 26
-l147 146q28 28 28 67zM753 1025q0 40 -28 68l-206 207q-28 28 -68 28q-39 0 -68 -27l-147 -146q-28 -28 -28 -67q0 -40 28 -68l208 -208q27 -27 68 -27q42 0 72 31q-3 3 -19 18.5t-21.5 21.5t-15 19t-13 25.5t-3.5 27.5q0 40 28 68t68 28q15 0 27.5 -3.5t25.5 -13t19 -15
-t21.5 -21.5t18.5 -19q33 31 33 73zM1648 320q0 -120 -85 -203l-147 -146q-83 -83 -203 -83q-121 0 -204 85l-206 207q-83 83 -83 203q0 123 88 209l-88 88q-86 -88 -208 -88q-120 0 -204 84l-208 208q-84 84 -84 204t85 203l147 146q83 83 203 83q121 0 204 -85l206 -207
-q83 -83 83 -203q0 -123 -88 -209l88 -88q86 88 208 88q120 0 204 -84l208 -208q84 -84 84 -204z" />
-    <glyph glyph-name="cloud" unicode="&#xf0c2;" horiz-adv-x="1920" 
-d="M1920 384q0 -159 -112.5 -271.5t-271.5 -112.5h-1088q-185 0 -316.5 131.5t-131.5 316.5q0 132 71 241.5t187 163.5q-2 28 -2 43q0 212 150 362t362 150q158 0 286.5 -88t187.5 -230q70 62 166 62q106 0 181 -75t75 -181q0 -75 -41 -138q129 -30 213 -134.5t84 -239.5z
-" />
-    <glyph glyph-name="beaker" unicode="&#xf0c3;" horiz-adv-x="1664" 
-d="M1527 88q56 -89 21.5 -152.5t-140.5 -63.5h-1152q-106 0 -140.5 63.5t21.5 152.5l503 793v399h-64q-26 0 -45 19t-19 45t19 45t45 19h512q26 0 45 -19t19 -45t-19 -45t-45 -19h-64v-399zM748 813l-272 -429h712l-272 429l-20 31v37v399h-128v-399v-37z" />
-    <glyph glyph-name="cut" unicode="&#xf0c4;" horiz-adv-x="1792" 
-d="M960 640q26 0 45 -19t19 -45t-19 -45t-45 -19t-45 19t-19 45t19 45t45 19zM1260 576l507 -398q28 -20 25 -56q-5 -35 -35 -51l-128 -64q-13 -7 -29 -7q-17 0 -31 8l-690 387l-110 -66q-8 -4 -12 -5q14 -49 10 -97q-7 -77 -56 -147.5t-132 -123.5q-132 -84 -277 -84
-q-136 0 -222 78q-90 84 -79 207q7 76 56 147t131 124q132 84 278 84q83 0 151 -31q9 13 22 22l122 73l-122 73q-13 9 -22 22q-68 -31 -151 -31q-146 0 -278 84q-82 53 -131 124t-56 147q-5 59 15.5 113t63.5 93q85 79 222 79q145 0 277 -84q83 -52 132 -123t56 -148
-q4 -48 -10 -97q4 -1 12 -5l110 -66l690 387q14 8 31 8q16 0 29 -7l128 -64q30 -16 35 -51q3 -36 -25 -56zM579 836q46 42 21 108t-106 117q-92 59 -192 59q-74 0 -113 -36q-46 -42 -21 -108t106 -117q92 -59 192 -59q74 0 113 36zM494 91q81 51 106 117t-21 108
-q-39 36 -113 36q-100 0 -192 -59q-81 -51 -106 -117t21 -108q39 -36 113 -36q100 0 192 59zM672 704l96 -58v11q0 36 33 56l14 8l-79 47l-26 -26q-3 -3 -10 -11t-12 -12q-2 -2 -4 -3.5t-3 -2.5zM896 480l96 -32l736 576l-128 64l-768 -431v-113l-160 -96l9 -8q2 -2 7 -6
-q4 -4 11 -12t11 -12l26 -26zM1600 64l128 64l-520 408l-177 -138q-2 -3 -13 -7z" />
-    <glyph glyph-name="copy" unicode="&#xf0c5;" horiz-adv-x="1792" 
-d="M1696 1152q40 0 68 -28t28 -68v-1216q0 -40 -28 -68t-68 -28h-960q-40 0 -68 28t-28 68v288h-544q-40 0 -68 28t-28 68v672q0 40 20 88t48 76l408 408q28 28 76 48t88 20h416q40 0 68 -28t28 -68v-328q68 40 128 40h416zM1152 939l-299 -299h299v299zM512 1323l-299 -299
-h299v299zM708 676l316 316v416h-384v-416q0 -40 -28 -68t-68 -28h-416v-640h512v256q0 40 20 88t48 76zM1664 -128v1152h-384v-416q0 -40 -28 -68t-68 -28h-416v-640h896z" />
-    <glyph glyph-name="paper_clip" unicode="&#xf0c6;" horiz-adv-x="1408" 
-d="M1404 151q0 -117 -79 -196t-196 -79q-135 0 -235 100l-777 776q-113 115 -113 271q0 159 110 270t269 111q158 0 273 -113l605 -606q10 -10 10 -22q0 -16 -30.5 -46.5t-46.5 -30.5q-13 0 -23 10l-606 607q-79 77 -181 77q-106 0 -179 -75t-73 -181q0 -105 76 -181
-l776 -777q63 -63 145 -63q64 0 106 42t42 106q0 82 -63 145l-581 581q-26 24 -60 24q-29 0 -48 -19t-19 -48q0 -32 25 -59l410 -410q10 -10 10 -22q0 -16 -31 -47t-47 -31q-12 0 -22 10l-410 410q-63 61 -63 149q0 82 57 139t139 57q88 0 149 -63l581 -581q100 -98 100 -235
-z" />
-    <glyph glyph-name="save" unicode="&#xf0c7;" 
-d="M384 0h768v384h-768v-384zM1280 0h128v896q0 14 -10 38.5t-20 34.5l-281 281q-10 10 -34 20t-39 10v-416q0 -40 -28 -68t-68 -28h-576q-40 0 -68 28t-28 68v416h-128v-1280h128v416q0 40 28 68t68 28h832q40 0 68 -28t28 -68v-416zM896 928v320q0 13 -9.5 22.5t-22.5 9.5
-h-192q-13 0 -22.5 -9.5t-9.5 -22.5v-320q0 -13 9.5 -22.5t22.5 -9.5h192q13 0 22.5 9.5t9.5 22.5zM1536 896v-928q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68v1344q0 40 28 68t68 28h928q40 0 88 -20t76 -48l280 -280q28 -28 48 -76t20 -88z" />
-    <glyph glyph-name="sign_blank" unicode="&#xf0c8;" 
-d="M1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
-    <glyph glyph-name="reorder" unicode="&#xf0c9;" 
-d="M1536 192v-128q0 -26 -19 -45t-45 -19h-1408q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1408q26 0 45 -19t19 -45zM1536 704v-128q0 -26 -19 -45t-45 -19h-1408q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1408q26 0 45 -19t19 -45zM1536 1216v-128q0 -26 -19 -45
-t-45 -19h-1408q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1408q26 0 45 -19t19 -45z" />
-    <glyph glyph-name="ul" unicode="&#xf0ca;" horiz-adv-x="1792" 
-d="M384 128q0 -80 -56 -136t-136 -56t-136 56t-56 136t56 136t136 56t136 -56t56 -136zM384 640q0 -80 -56 -136t-136 -56t-136 56t-56 136t56 136t136 56t136 -56t56 -136zM1792 224v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1216q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5
-t22.5 9.5h1216q13 0 22.5 -9.5t9.5 -22.5zM384 1152q0 -80 -56 -136t-136 -56t-136 56t-56 136t56 136t136 56t136 -56t56 -136zM1792 736v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1216q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1216q13 0 22.5 -9.5t9.5 -22.5z
-M1792 1248v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1216q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1216q13 0 22.5 -9.5t9.5 -22.5z" />
-    <glyph glyph-name="ol" unicode="&#xf0cb;" horiz-adv-x="1792" 
-d="M381 -84q0 -80 -54.5 -126t-135.5 -46q-106 0 -172 66l57 88q49 -45 106 -45q29 0 50.5 14.5t21.5 42.5q0 64 -105 56l-26 56q8 10 32.5 43.5t42.5 54t37 38.5v1q-16 0 -48.5 -1t-48.5 -1v-53h-106v152h333v-88l-95 -115q51 -12 81 -49t30 -88zM383 543v-159h-362
-q-6 36 -6 54q0 51 23.5 93t56.5 68t66 47.5t56.5 43.5t23.5 45q0 25 -14.5 38.5t-39.5 13.5q-46 0 -81 -58l-85 59q24 51 71.5 79.5t105.5 28.5q73 0 123 -41.5t50 -112.5q0 -50 -34 -91.5t-75 -64.5t-75.5 -50.5t-35.5 -52.5h127v60h105zM1792 224v-192q0 -13 -9.5 -22.5
-t-22.5 -9.5h-1216q-13 0 -22.5 9.5t-9.5 22.5v192q0 14 9 23t23 9h1216q13 0 22.5 -9.5t9.5 -22.5zM384 1123v-99h-335v99h107q0 41 0.5 121.5t0.5 121.5v12h-2q-8 -17 -50 -54l-71 76l136 127h106v-404h108zM1792 736v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1216
-q-13 0 -22.5 9.5t-9.5 22.5v192q0 14 9 23t23 9h1216q13 0 22.5 -9.5t9.5 -22.5zM1792 1248v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1216q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1216q13 0 22.5 -9.5t9.5 -22.5z" />
-    <glyph glyph-name="strikethrough" unicode="&#xf0cc;" horiz-adv-x="1792" 
-d="M1760 640q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-1728q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h1728zM483 704q-28 35 -51 80q-48 98 -48 188q0 181 134 309q133 127 393 127q50 0 167 -19q66 -12 177 -48q10 -38 21 -118q14 -123 14 -183q0 -18 -5 -45l-12 -3l-84 6
-l-14 2q-50 149 -103 205q-88 91 -210 91q-114 0 -182 -59q-67 -58 -67 -146q0 -73 66 -140t279 -129q69 -20 173 -66q58 -28 95 -52h-743zM990 448h411q7 -39 7 -92q0 -111 -41 -212q-23 -56 -71 -104q-37 -35 -109 -81q-80 -48 -153 -66q-80 -21 -203 -21q-114 0 -195 23
-l-140 40q-57 16 -72 28q-8 8 -8 22v13q0 108 -2 156q-1 30 0 68l2 37v44l102 2q15 -34 30 -71t22.5 -56t12.5 -27q35 -57 80 -94q43 -36 105 -57q59 -22 132 -22q64 0 139 27q77 26 122 86q47 61 47 129q0 84 -81 157q-34 29 -137 71z" />
-    <glyph glyph-name="underline" unicode="&#xf0cd;" 
-d="M48 1313q-37 2 -45 4l-3 88q13 1 40 1q60 0 112 -4q132 -7 166 -7q86 0 168 3q116 4 146 5q56 0 86 2l-1 -14l2 -64v-9q-60 -9 -124 -9q-60 0 -79 -25q-13 -14 -13 -132q0 -13 0.5 -32.5t0.5 -25.5l1 -229l14 -280q6 -124 51 -202q35 -59 96 -92q88 -47 177 -47
-q104 0 191 28q56 18 99 51q48 36 65 64q36 56 53 114q21 73 21 229q0 79 -3.5 128t-11 122.5t-13.5 159.5l-4 59q-5 67 -24 88q-34 35 -77 34l-100 -2l-14 3l2 86h84l205 -10q76 -3 196 10l18 -2q6 -38 6 -51q0 -7 -4 -31q-45 -12 -84 -13q-73 -11 -79 -17q-15 -15 -15 -41
-q0 -7 1.5 -27t1.5 -31q8 -19 22 -396q6 -195 -15 -304q-15 -76 -41 -122q-38 -65 -112 -123q-75 -57 -182 -89q-109 -33 -255 -33q-167 0 -284 46q-119 47 -179 122q-61 76 -83 195q-16 80 -16 237v333q0 188 -17 213q-25 36 -147 39zM1536 -96v64q0 14 -9 23t-23 9h-1472
-q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h1472q14 0 23 9t9 23z" />
-    <glyph glyph-name="table" unicode="&#xf0ce;" horiz-adv-x="1664" 
-d="M512 160v192q0 14 -9 23t-23 9h-320q-14 0 -23 -9t-9 -23v-192q0 -14 9 -23t23 -9h320q14 0 23 9t9 23zM512 544v192q0 14 -9 23t-23 9h-320q-14 0 -23 -9t-9 -23v-192q0 -14 9 -23t23 -9h320q14 0 23 9t9 23zM1024 160v192q0 14 -9 23t-23 9h-320q-14 0 -23 -9t-9 -23
-v-192q0 -14 9 -23t23 -9h320q14 0 23 9t9 23zM512 928v192q0 14 -9 23t-23 9h-320q-14 0 -23 -9t-9 -23v-192q0 -14 9 -23t23 -9h320q14 0 23 9t9 23zM1024 544v192q0 14 -9 23t-23 9h-320q-14 0 -23 -9t-9 -23v-192q0 -14 9 -23t23 -9h320q14 0 23 9t9 23zM1536 160v192
-q0 14 -9 23t-23 9h-320q-14 0 -23 -9t-9 -23v-192q0 -14 9 -23t23 -9h320q14 0 23 9t9 23zM1024 928v192q0 14 -9 23t-23 9h-320q-14 0 -23 -9t-9 -23v-192q0 -14 9 -23t23 -9h320q14 0 23 9t9 23zM1536 544v192q0 14 -9 23t-23 9h-320q-14 0 -23 -9t-9 -23v-192
-q0 -14 9 -23t23 -9h320q14 0 23 9t9 23zM1536 928v192q0 14 -9 23t-23 9h-320q-14 0 -23 -9t-9 -23v-192q0 -14 9 -23t23 -9h320q14 0 23 9t9 23zM1664 1248v-1088q0 -66 -47 -113t-113 -47h-1344q-66 0 -113 47t-47 113v1088q0 66 47 113t113 47h1344q66 0 113 -47t47 -113
-z" />
-    <glyph glyph-name="magic" unicode="&#xf0d0;" horiz-adv-x="1664" 
-d="M1190 955l293 293l-107 107l-293 -293zM1637 1248q0 -27 -18 -45l-1286 -1286q-18 -18 -45 -18t-45 18l-198 198q-18 18 -18 45t18 45l1286 1286q18 18 45 18t45 -18l198 -198q18 -18 18 -45zM286 1438l98 -30l-98 -30l-30 -98l-30 98l-98 30l98 30l30 98zM636 1276
-l196 -60l-196 -60l-60 -196l-60 196l-196 60l196 60l60 196zM1566 798l98 -30l-98 -30l-30 -98l-30 98l-98 30l98 30l30 98zM926 1438l98 -30l-98 -30l-30 -98l-30 98l-98 30l98 30l30 98z" />
-    <glyph glyph-name="truck" unicode="&#xf0d1;" horiz-adv-x="1792" 
-d="M640 128q0 52 -38 90t-90 38t-90 -38t-38 -90t38 -90t90 -38t90 38t38 90zM256 640h384v256h-158q-13 0 -22 -9l-195 -195q-9 -9 -9 -22v-30zM1536 128q0 52 -38 90t-90 38t-90 -38t-38 -90t38 -90t90 -38t90 38t38 90zM1792 1216v-1024q0 -15 -4 -26.5t-13.5 -18.5
-t-16.5 -11.5t-23.5 -6t-22.5 -2t-25.5 0t-22.5 0.5q0 -106 -75 -181t-181 -75t-181 75t-75 181h-384q0 -106 -75 -181t-181 -75t-181 75t-75 181h-64q-3 0 -22.5 -0.5t-25.5 0t-22.5 2t-23.5 6t-16.5 11.5t-13.5 18.5t-4 26.5q0 26 19 45t45 19v320q0 8 -0.5 35t0 38
-t2.5 34.5t6.5 37t14 30.5t22.5 30l198 198q19 19 50.5 32t58.5 13h160v192q0 26 19 45t45 19h1024q26 0 45 -19t19 -45z" />
-    <glyph glyph-name="pinterest" unicode="&#xf0d2;" 
-d="M1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103q-111 0 -218 32q59 93 78 164q9 34 54 211q20 -39 73 -67.5t114 -28.5q121 0 216 68.5t147 188.5t52 270q0 114 -59.5 214t-172.5 163t-255 63q-105 0 -196 -29t-154.5 -77t-109 -110.5t-67 -129.5t-21.5 -134
-q0 -104 40 -183t117 -111q30 -12 38 20q2 7 8 31t8 30q6 23 -11 43q-51 61 -51 151q0 151 104.5 259.5t273.5 108.5q151 0 235.5 -82t84.5 -213q0 -170 -68.5 -289t-175.5 -119q-61 0 -98 43.5t-23 104.5q8 35 26.5 93.5t30 103t11.5 75.5q0 50 -27 83t-77 33
-q-62 0 -105 -57t-43 -142q0 -73 25 -122l-99 -418q-17 -70 -13 -177q-206 91 -333 281t-127 423q0 209 103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
-    <glyph glyph-name="pinterest_sign" unicode="&#xf0d3;" 
-d="M1248 1408q119 0 203.5 -84.5t84.5 -203.5v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-725q85 122 108 210q9 34 53 209q21 -39 73.5 -67t112.5 -28q181 0 295.5 147.5t114.5 373.5q0 84 -35 162.5t-96.5 139t-152.5 97t-197 36.5q-104 0 -194.5 -28.5t-153 -76.5
-t-107.5 -109.5t-66.5 -128t-21.5 -132.5q0 -102 39.5 -180t116.5 -110q13 -5 23.5 0t14.5 19q10 44 15 61q6 23 -11 42q-50 62 -50 150q0 150 103.5 256.5t270.5 106.5q149 0 232.5 -81t83.5 -210q0 -168 -67.5 -286t-173.5 -118q-60 0 -97 43.5t-23 103.5q8 34 26.5 92.5
-t29.5 102t11 74.5q0 49 -26.5 81.5t-75.5 32.5q-61 0 -103.5 -56.5t-42.5 -139.5q0 -72 24 -121l-98 -414q-24 -100 -7 -254h-183q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960z" />
-    <glyph glyph-name="google_plus_sign" unicode="&#xf0d4;" 
-d="M917 631q0 26 -6 64h-362v-132h217q-3 -24 -16.5 -50t-37.5 -53t-66.5 -44.5t-96.5 -17.5q-99 0 -169 71t-70 171t70 171t169 71q92 0 153 -59l104 101q-108 100 -257 100q-160 0 -272 -112.5t-112 -271.5t112 -271.5t272 -112.5q165 0 266.5 105t101.5 270zM1262 585
-h109v110h-109v110h-110v-110h-110v-110h110v-110h110v110zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
-    <glyph glyph-name="google_plus" unicode="&#xf0d5;" horiz-adv-x="2304" 
-d="M1437 623q0 -208 -87 -370.5t-248 -254t-369 -91.5q-149 0 -285 58t-234 156t-156 234t-58 285t58 285t156 234t234 156t285 58q286 0 491 -192l-199 -191q-117 113 -292 113q-123 0 -227.5 -62t-165.5 -168.5t-61 -232.5t61 -232.5t165.5 -168.5t227.5 -62
-q83 0 152.5 23t114.5 57.5t78.5 78.5t49 83t21.5 74h-416v252h692q12 -63 12 -122zM2304 745v-210h-209v-209h-210v209h-209v210h209v209h210v-209h209z" />
-    <glyph glyph-name="money" unicode="&#xf0d6;" horiz-adv-x="1920" 
-d="M768 384h384v96h-128v448h-114l-148 -137l77 -80q42 37 55 57h2v-288h-128v-96zM1280 640q0 -70 -21 -142t-59.5 -134t-101.5 -101t-138 -39t-138 39t-101.5 101t-59.5 134t-21 142t21 142t59.5 134t101.5 101t138 39t138 -39t101.5 -101t59.5 -134t21 -142zM1792 384
-v512q-106 0 -181 75t-75 181h-1152q0 -106 -75 -181t-181 -75v-512q106 0 181 -75t75 -181h1152q0 106 75 181t181 75zM1920 1216v-1152q0 -26 -19 -45t-45 -19h-1792q-26 0 -45 19t-19 45v1152q0 26 19 45t45 19h1792q26 0 45 -19t19 -45z" />
-    <glyph glyph-name="caret_down" unicode="&#xf0d7;" horiz-adv-x="1024" 
-d="M1024 832q0 -26 -19 -45l-448 -448q-19 -19 -45 -19t-45 19l-448 448q-19 19 -19 45t19 45t45 19h896q26 0 45 -19t19 -45z" />
-    <glyph glyph-name="caret_up" unicode="&#xf0d8;" horiz-adv-x="1024" 
-d="M1024 320q0 -26 -19 -45t-45 -19h-896q-26 0 -45 19t-19 45t19 45l448 448q19 19 45 19t45 -19l448 -448q19 -19 19 -45z" />
-    <glyph glyph-name="caret_left" unicode="&#xf0d9;" horiz-adv-x="640" 
-d="M640 1088v-896q0 -26 -19 -45t-45 -19t-45 19l-448 448q-19 19 -19 45t19 45l448 448q19 19 45 19t45 -19t19 -45z" />
-    <glyph glyph-name="caret_right" unicode="&#xf0da;" horiz-adv-x="640" 
-d="M576 640q0 -26 -19 -45l-448 -448q-19 -19 -45 -19t-45 19t-19 45v896q0 26 19 45t45 19t45 -19l448 -448q19 -19 19 -45z" />
-    <glyph glyph-name="columns" unicode="&#xf0db;" horiz-adv-x="1664" 
-d="M160 0h608v1152h-640v-1120q0 -13 9.5 -22.5t22.5 -9.5zM1536 32v1120h-640v-1152h608q13 0 22.5 9.5t9.5 22.5zM1664 1248v-1216q0 -66 -47 -113t-113 -47h-1344q-66 0 -113 47t-47 113v1216q0 66 47 113t113 47h1344q66 0 113 -47t47 -113z" />
-    <glyph glyph-name="sort" unicode="&#xf0dc;" horiz-adv-x="1024" 
-d="M1024 448q0 -26 -19 -45l-448 -448q-19 -19 -45 -19t-45 19l-448 448q-19 19 -19 45t19 45t45 19h896q26 0 45 -19t19 -45zM1024 832q0 -26 -19 -45t-45 -19h-896q-26 0 -45 19t-19 45t19 45l448 448q19 19 45 19t45 -19l448 -448q19 -19 19 -45z" />
-    <glyph glyph-name="sort_down" unicode="&#xf0dd;" horiz-adv-x="1024" 
-d="M1024 448q0 -26 -19 -45l-448 -448q-19 -19 -45 -19t-45 19l-448 448q-19 19 -19 45t19 45t45 19h896q26 0 45 -19t19 -45z" />
-    <glyph glyph-name="sort_up" unicode="&#xf0de;" horiz-adv-x="1024" 
-d="M1024 832q0 -26 -19 -45t-45 -19h-896q-26 0 -45 19t-19 45t19 45l448 448q19 19 45 19t45 -19l448 -448q19 -19 19 -45z" />
-    <glyph glyph-name="envelope_alt" unicode="&#xf0e0;" horiz-adv-x="1792" 
-d="M1792 826v-794q0 -66 -47 -113t-113 -47h-1472q-66 0 -113 47t-47 113v794q44 -49 101 -87q362 -246 497 -345q57 -42 92.5 -65.5t94.5 -48t110 -24.5h1h1q51 0 110 24.5t94.5 48t92.5 65.5q170 123 498 345q57 39 100 87zM1792 1120q0 -79 -49 -151t-122 -123
-q-376 -261 -468 -325q-10 -7 -42.5 -30.5t-54 -38t-52 -32.5t-57.5 -27t-50 -9h-1h-1q-23 0 -50 9t-57.5 27t-52 32.5t-54 38t-42.5 30.5q-91 64 -262 182.5t-205 142.5q-62 42 -117 115.5t-55 136.5q0 78 41.5 130t118.5 52h1472q65 0 112.5 -47t47.5 -113z" />
-    <glyph glyph-name="linkedin" unicode="&#xf0e1;" 
-d="M349 911v-991h-330v991h330zM370 1217q1 -73 -50.5 -122t-135.5 -49h-2q-82 0 -132 49t-50 122q0 74 51.5 122.5t134.5 48.5t133 -48.5t51 -122.5zM1536 488v-568h-329v530q0 105 -40.5 164.5t-126.5 59.5q-63 0 -105.5 -34.5t-63.5 -85.5q-11 -30 -11 -81v-553h-329
-q2 399 2 647t-1 296l-1 48h329v-144h-2q20 32 41 56t56.5 52t87 43.5t114.5 15.5q171 0 275 -113.5t104 -332.5z" />
-    <glyph glyph-name="undo" unicode="&#xf0e2;" 
-d="M1536 640q0 -156 -61 -298t-164 -245t-245 -164t-298 -61q-172 0 -327 72.5t-264 204.5q-7 10 -6.5 22.5t8.5 20.5l137 138q10 9 25 9q16 -2 23 -12q73 -95 179 -147t225 -52q104 0 198.5 40.5t163.5 109.5t109.5 163.5t40.5 198.5t-40.5 198.5t-109.5 163.5
-t-163.5 109.5t-198.5 40.5q-98 0 -188 -35.5t-160 -101.5l137 -138q31 -30 14 -69q-17 -40 -59 -40h-448q-26 0 -45 19t-19 45v448q0 42 40 59q39 17 69 -14l130 -129q107 101 244.5 156.5t284.5 55.5q156 0 298 -61t245 -164t164 -245t61 -298z" />
-    <glyph glyph-name="legal" unicode="&#xf0e3;" horiz-adv-x="1792" 
-d="M1771 0q0 -53 -37 -90l-107 -108q-39 -37 -91 -37q-53 0 -90 37l-363 364q-38 36 -38 90q0 53 43 96l-256 256l-126 -126q-14 -14 -34 -14t-34 14q2 -2 12.5 -12t12.5 -13t10 -11.5t10 -13.5t6 -13.5t5.5 -16.5t1.5 -18q0 -38 -28 -68q-3 -3 -16.5 -18t-19 -20.5
-t-18.5 -16.5t-22 -15.5t-22 -9t-26 -4.5q-40 0 -68 28l-408 408q-28 28 -28 68q0 13 4.5 26t9 22t15.5 22t16.5 18.5t20.5 19t18 16.5q30 28 68 28q10 0 18 -1.5t16.5 -5.5t13.5 -6t13.5 -10t11.5 -10t13 -12.5t12 -12.5q-14 14 -14 34t14 34l348 348q14 14 34 14t34 -14
-q-2 2 -12.5 12t-12.5 13t-10 11.5t-10 13.5t-6 13.5t-5.5 16.5t-1.5 18q0 38 28 68q3 3 16.5 18t19 20.5t18.5 16.5t22 15.5t22 9t26 4.5q40 0 68 -28l408 -408q28 -28 28 -68q0 -13 -4.5 -26t-9 -22t-15.5 -22t-16.5 -18.5t-20.5 -19t-18 -16.5q-30 -28 -68 -28
-q-10 0 -18 1.5t-16.5 5.5t-13.5 6t-13.5 10t-11.5 10t-13 12.5t-12 12.5q14 -14 14 -34t-14 -34l-126 -126l256 -256q43 43 96 43q52 0 91 -37l363 -363q37 -39 37 -91z" />
-    <glyph glyph-name="dashboard" unicode="&#xf0e4;" horiz-adv-x="1792" 
-d="M384 384q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM576 832q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1004 351l101 382q6 26 -7.5 48.5t-38.5 29.5
-t-48 -6.5t-30 -39.5l-101 -382q-60 -5 -107 -43.5t-63 -98.5q-20 -77 20 -146t117 -89t146 20t89 117q16 60 -6 117t-72 91zM1664 384q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1024 1024q0 53 -37.5 90.5
-t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1472 832q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1792 384q0 -261 -141 -483q-19 -29 -54 -29h-1402q-35 0 -54 29
-q-141 221 -141 483q0 182 71 348t191 286t286 191t348 71t348 -71t286 -191t191 -286t71 -348z" />
-    <glyph glyph-name="comment_alt" unicode="&#xf0e5;" horiz-adv-x="1792" 
-d="M896 1152q-204 0 -381.5 -69.5t-282 -187.5t-104.5 -255q0 -112 71.5 -213.5t201.5 -175.5l87 -50l-27 -96q-24 -91 -70 -172q152 63 275 171l43 38l57 -6q69 -8 130 -8q204 0 381.5 69.5t282 187.5t104.5 255t-104.5 255t-282 187.5t-381.5 69.5zM1792 640
-q0 -174 -120 -321.5t-326 -233t-450 -85.5q-70 0 -145 8q-198 -175 -460 -242q-49 -14 -114 -22h-5q-15 0 -27 10.5t-16 27.5v1q-3 4 -0.5 12t2 10t4.5 9.5l6 9t7 8.5t8 9q7 8 31 34.5t34.5 38t31 39.5t32.5 51t27 59t26 76q-157 89 -247.5 220t-90.5 281q0 174 120 321.5
-t326 233t450 85.5t450 -85.5t326 -233t120 -321.5z" />
-    <glyph glyph-name="comments_alt" unicode="&#xf0e6;" horiz-adv-x="1792" 
-d="M704 1152q-153 0 -286 -52t-211.5 -141t-78.5 -191q0 -82 53 -158t149 -132l97 -56l-35 -84q34 20 62 39l44 31l53 -10q78 -14 153 -14q153 0 286 52t211.5 141t78.5 191t-78.5 191t-211.5 141t-286 52zM704 1280q191 0 353.5 -68.5t256.5 -186.5t94 -257t-94 -257
-t-256.5 -186.5t-353.5 -68.5q-86 0 -176 16q-124 -88 -278 -128q-36 -9 -86 -16h-3q-11 0 -20.5 8t-11.5 21q-1 3 -1 6.5t0.5 6.5t2 6l2.5 5t3.5 5.5t4 5t4.5 5t4 4.5q5 6 23 25t26 29.5t22.5 29t25 38.5t20.5 44q-124 72 -195 177t-71 224q0 139 94 257t256.5 186.5
-t353.5 68.5zM1526 111q10 -24 20.5 -44t25 -38.5t22.5 -29t26 -29.5t23 -25q1 -1 4 -4.5t4.5 -5t4 -5t3.5 -5.5l2.5 -5t2 -6t0.5 -6.5t-1 -6.5q-3 -14 -13 -22t-22 -7q-50 7 -86 16q-154 40 -278 128q-90 -16 -176 -16q-271 0 -472 132q58 -4 88 -4q161 0 309 45t264 129
-q125 92 192 212t67 254q0 77 -23 152q129 -71 204 -178t75 -230q0 -120 -71 -224.5t-195 -176.5z" />
-    <glyph glyph-name="bolt" unicode="&#xf0e7;" horiz-adv-x="896" 
-d="M885 970q18 -20 7 -44l-540 -1157q-13 -25 -42 -25q-4 0 -14 2q-17 5 -25.5 19t-4.5 30l197 808l-406 -101q-4 -1 -12 -1q-18 0 -31 11q-18 15 -13 39l201 825q4 14 16 23t28 9h328q19 0 32 -12.5t13 -29.5q0 -8 -5 -18l-171 -463l396 98q8 2 12 2q19 0 34 -15z" />
-    <glyph glyph-name="sitemap" unicode="&#xf0e8;" horiz-adv-x="1792" 
-d="M1792 288v-320q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v320q0 40 28 68t68 28h96v192h-512v-192h96q40 0 68 -28t28 -68v-320q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v320q0 40 28 68t68 28h96v192h-512v-192h96q40 0 68 -28t28 -68v-320
-q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v320q0 40 28 68t68 28h96v192q0 52 38 90t90 38h512v192h-96q-40 0 -68 28t-28 68v320q0 40 28 68t68 28h320q40 0 68 -28t28 -68v-320q0 -40 -28 -68t-68 -28h-96v-192h512q52 0 90 -38t38 -90v-192h96q40 0 68 -28t28 -68
-z" />
-    <glyph glyph-name="umbrella" unicode="&#xf0e9;" horiz-adv-x="1664" 
-d="M896 708v-580q0 -104 -76 -180t-180 -76t-180 76t-76 180q0 26 19 45t45 19t45 -19t19 -45q0 -50 39 -89t89 -39t89 39t39 89v580q33 11 64 11t64 -11zM1664 681q0 -13 -9.5 -22.5t-22.5 -9.5q-11 0 -23 10q-49 46 -93 69t-102 23q-68 0 -128 -37t-103 -97
-q-7 -10 -17.5 -28t-14.5 -24q-11 -17 -28 -17q-18 0 -29 17q-4 6 -14.5 24t-17.5 28q-43 60 -102.5 97t-127.5 37t-127.5 -37t-102.5 -97q-7 -10 -17.5 -28t-14.5 -24q-11 -17 -29 -17q-17 0 -28 17q-4 6 -14.5 24t-17.5 28q-43 60 -103 97t-128 37q-58 0 -102 -23t-93 -69
-q-12 -10 -23 -10q-13 0 -22.5 9.5t-9.5 22.5q0 5 1 7q45 183 172.5 319.5t298 204.5t360.5 68q140 0 274.5 -40t246.5 -113.5t194.5 -187t115.5 -251.5q1 -2 1 -7zM896 1408v-98q-42 2 -64 2t-64 -2v98q0 26 19 45t45 19t45 -19t19 -45z" />
-    <glyph glyph-name="paste" unicode="&#xf0ea;" horiz-adv-x="1792" 
-d="M768 -128h896v640h-416q-40 0 -68 28t-28 68v416h-384v-1152zM1024 1312v64q0 13 -9.5 22.5t-22.5 9.5h-704q-13 0 -22.5 -9.5t-9.5 -22.5v-64q0 -13 9.5 -22.5t22.5 -9.5h704q13 0 22.5 9.5t9.5 22.5zM1280 640h299l-299 299v-299zM1792 512v-672q0 -40 -28 -68t-68 -28
-h-960q-40 0 -68 28t-28 68v160h-544q-40 0 -68 28t-28 68v1344q0 40 28 68t68 28h1088q40 0 68 -28t28 -68v-328q21 -13 36 -28l408 -408q28 -28 48 -76t20 -88z" />
-    <glyph glyph-name="light_bulb" unicode="&#xf0eb;" horiz-adv-x="1024" 
-d="M736 960q0 -13 -9.5 -22.5t-22.5 -9.5t-22.5 9.5t-9.5 22.5q0 46 -54 71t-106 25q-13 0 -22.5 9.5t-9.5 22.5t9.5 22.5t22.5 9.5q50 0 99.5 -16t87 -54t37.5 -90zM896 960q0 72 -34.5 134t-90 101.5t-123 62t-136.5 22.5t-136.5 -22.5t-123 -62t-90 -101.5t-34.5 -134
-q0 -101 68 -180q10 -11 30.5 -33t30.5 -33q128 -153 141 -298h228q13 145 141 298q10 11 30.5 33t30.5 33q68 79 68 180zM1024 960q0 -155 -103 -268q-45 -49 -74.5 -87t-59.5 -95.5t-34 -107.5q47 -28 47 -82q0 -37 -25 -64q25 -27 25 -64q0 -52 -45 -81q13 -23 13 -47
-q0 -46 -31.5 -71t-77.5 -25q-20 -44 -60 -70t-87 -26t-87 26t-60 70q-46 0 -77.5 25t-31.5 71q0 24 13 47q-45 29 -45 81q0 37 25 64q-25 27 -25 64q0 54 47 82q-4 50 -34 107.5t-59.5 95.5t-74.5 87q-103 113 -103 268q0 99 44.5 184.5t117 142t164 89t186.5 32.5
-t186.5 -32.5t164 -89t117 -142t44.5 -184.5z" />
-    <glyph glyph-name="exchange" unicode="&#xf0ec;" horiz-adv-x="1792" 
-d="M1792 352v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1376v-192q0 -13 -9.5 -22.5t-22.5 -9.5q-12 0 -24 10l-319 320q-9 9 -9 22q0 14 9 23l320 320q9 9 23 9q13 0 22.5 -9.5t9.5 -22.5v-192h1376q13 0 22.5 -9.5t9.5 -22.5zM1792 896q0 -14 -9 -23l-320 -320q-9 -9 -23 -9
-q-13 0 -22.5 9.5t-9.5 22.5v192h-1376q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1376v192q0 14 9 23t23 9q12 0 24 -10l319 -319q9 -9 9 -23z" />
-    <glyph glyph-name="cloud_download" unicode="&#xf0ed;" horiz-adv-x="1920" 
-d="M1280 608q0 14 -9 23t-23 9h-224v352q0 13 -9.5 22.5t-22.5 9.5h-192q-13 0 -22.5 -9.5t-9.5 -22.5v-352h-224q-13 0 -22.5 -9.5t-9.5 -22.5q0 -14 9 -23l352 -352q9 -9 23 -9t23 9l351 351q10 12 10 24zM1920 384q0 -159 -112.5 -271.5t-271.5 -112.5h-1088
-q-185 0 -316.5 131.5t-131.5 316.5q0 130 70 240t188 165q-2 30 -2 43q0 212 150 362t362 150q156 0 285.5 -87t188.5 -231q71 62 166 62q106 0 181 -75t75 -181q0 -76 -41 -138q130 -31 213.5 -135.5t83.5 -238.5z" />
-    <glyph glyph-name="cloud_upload" unicode="&#xf0ee;" horiz-adv-x="1920" 
-d="M1280 672q0 14 -9 23l-352 352q-9 9 -23 9t-23 -9l-351 -351q-10 -12 -10 -24q0 -14 9 -23t23 -9h224v-352q0 -13 9.5 -22.5t22.5 -9.5h192q13 0 22.5 9.5t9.5 22.5v352h224q13 0 22.5 9.5t9.5 22.5zM1920 384q0 -159 -112.5 -271.5t-271.5 -112.5h-1088
-q-185 0 -316.5 131.5t-131.5 316.5q0 130 70 240t188 165q-2 30 -2 43q0 212 150 362t362 150q156 0 285.5 -87t188.5 -231q71 62 166 62q106 0 181 -75t75 -181q0 -76 -41 -138q130 -31 213.5 -135.5t83.5 -238.5z" />
-    <glyph glyph-name="user_md" unicode="&#xf0f0;" horiz-adv-x="1408" 
-d="M384 192q0 -26 -19 -45t-45 -19t-45 19t-19 45t19 45t45 19t45 -19t19 -45zM1408 131q0 -121 -73 -190t-194 -69h-874q-121 0 -194 69t-73 190q0 68 5.5 131t24 138t47.5 132.5t81 103t120 60.5q-22 -52 -22 -120v-203q-58 -20 -93 -70t-35 -111q0 -80 56 -136t136 -56
-t136 56t56 136q0 61 -35.5 111t-92.5 70v203q0 62 25 93q132 -104 295 -104t295 104q25 -31 25 -93v-64q-106 0 -181 -75t-75 -181v-89q-32 -29 -32 -71q0 -40 28 -68t68 -28t68 28t28 68q0 42 -32 71v89q0 52 38 90t90 38t90 -38t38 -90v-89q-32 -29 -32 -71q0 -40 28 -68
-t68 -28t68 28t28 68q0 42 -32 71v89q0 68 -34.5 127.5t-93.5 93.5q0 10 0.5 42.5t0 48t-2.5 41.5t-7 47t-13 40q68 -15 120 -60.5t81 -103t47.5 -132.5t24 -138t5.5 -131zM1088 1024q0 -159 -112.5 -271.5t-271.5 -112.5t-271.5 112.5t-112.5 271.5t112.5 271.5t271.5 112.5
-t271.5 -112.5t112.5 -271.5z" />
-    <glyph glyph-name="stethoscope" unicode="&#xf0f1;" horiz-adv-x="1408" 
-d="M1280 832q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1408 832q0 -62 -35.5 -111t-92.5 -70v-395q0 -159 -131.5 -271.5t-316.5 -112.5t-316.5 112.5t-131.5 271.5v132q-164 20 -274 128t-110 252v512q0 26 19 45t45 19q6 0 16 -2q17 30 47 48
-t65 18q53 0 90.5 -37.5t37.5 -90.5t-37.5 -90.5t-90.5 -37.5q-33 0 -64 18v-402q0 -106 94 -181t226 -75t226 75t94 181v402q-31 -18 -64 -18q-53 0 -90.5 37.5t-37.5 90.5t37.5 90.5t90.5 37.5q35 0 65 -18t47 -48q10 2 16 2q26 0 45 -19t19 -45v-512q0 -144 -110 -252
-t-274 -128v-132q0 -106 94 -181t226 -75t226 75t94 181v395q-57 21 -92.5 70t-35.5 111q0 80 56 136t136 56t136 -56t56 -136z" />
-    <glyph glyph-name="suitcase" unicode="&#xf0f2;" horiz-adv-x="1792" 
-d="M640 1152h512v128h-512v-128zM288 1152v-1280h-64q-92 0 -158 66t-66 158v832q0 92 66 158t158 66h64zM1408 1152v-1280h-1024v1280h128v160q0 40 28 68t68 28h576q40 0 68 -28t28 -68v-160h128zM1792 928v-832q0 -92 -66 -158t-158 -66h-64v1280h64q92 0 158 -66
-t66 -158z" />
-    <glyph glyph-name="bell_alt" unicode="&#xf0f3;" horiz-adv-x="1792" 
-d="M912 -160q0 16 -16 16q-59 0 -101.5 42.5t-42.5 101.5q0 16 -16 16t-16 -16q0 -73 51.5 -124.5t124.5 -51.5q16 0 16 16zM1728 128q0 -52 -38 -90t-90 -38h-448q0 -106 -75 -181t-181 -75t-181 75t-75 181h-448q-52 0 -90 38t-38 90q50 42 91 88t85 119.5t74.5 158.5
-t50 206t19.5 260q0 152 117 282.5t307 158.5q-8 19 -8 39q0 40 28 68t68 28t68 -28t28 -68q0 -20 -8 -39q190 -28 307 -158.5t117 -282.5q0 -139 19.5 -260t50 -206t74.5 -158.5t85 -119.5t91 -88z" />
-    <glyph glyph-name="coffee" unicode="&#xf0f4;" horiz-adv-x="1920" 
-d="M1664 896q0 80 -56 136t-136 56h-64v-384h64q80 0 136 56t56 136zM0 128h1792q0 -106 -75 -181t-181 -75h-1280q-106 0 -181 75t-75 181zM1856 896q0 -159 -112.5 -271.5t-271.5 -112.5h-64v-32q0 -92 -66 -158t-158 -66h-704q-92 0 -158 66t-66 158v736q0 26 19 45
-t45 19h1152q159 0 271.5 -112.5t112.5 -271.5z" />
-    <glyph glyph-name="food" unicode="&#xf0f5;" horiz-adv-x="1408" 
-d="M640 1472v-640q0 -61 -35.5 -111t-92.5 -70v-779q0 -52 -38 -90t-90 -38h-128q-52 0 -90 38t-38 90v779q-57 20 -92.5 70t-35.5 111v640q0 26 19 45t45 19t45 -19t19 -45v-416q0 -26 19 -45t45 -19t45 19t19 45v416q0 26 19 45t45 19t45 -19t19 -45v-416q0 -26 19 -45
-t45 -19t45 19t19 45v416q0 26 19 45t45 19t45 -19t19 -45zM1408 1472v-1600q0 -52 -38 -90t-90 -38h-128q-52 0 -90 38t-38 90v512h-224q-13 0 -22.5 9.5t-9.5 22.5v800q0 132 94 226t226 94h256q26 0 45 -19t19 -45z" />
-    <glyph glyph-name="file_text_alt" unicode="&#xf0f6;" 
-d="M1468 1156q28 -28 48 -76t20 -88v-1152q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68v1600q0 40 28 68t68 28h896q40 0 88 -20t76 -48zM1024 1400v-376h376q-10 29 -22 41l-313 313q-12 12 -41 22zM1408 -128v1024h-416q-40 0 -68 28t-28 68v416h-768v-1536h1280z
-M384 736q0 14 9 23t23 9h704q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-704q-14 0 -23 9t-9 23v64zM1120 512q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-704q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h704zM1120 256q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-704
-q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h704z" />
-    <glyph glyph-name="building" unicode="&#xf0f7;" horiz-adv-x="1408" 
-d="M384 224v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM384 480v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z
-M640 480v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM384 736v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z
-M1152 224v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM896 480v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z
-M640 736v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM384 992v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z
-M1152 480v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM896 736v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z
-M640 992v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM384 1248v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z
-M1152 736v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM896 992v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z
-M640 1248v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM1152 992v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z
-M896 1248v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM1152 1248v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z
-M896 -128h384v1536h-1152v-1536h384v224q0 13 9.5 22.5t22.5 9.5h320q13 0 22.5 -9.5t9.5 -22.5v-224zM1408 1472v-1664q0 -26 -19 -45t-45 -19h-1280q-26 0 -45 19t-19 45v1664q0 26 19 45t45 19h1280q26 0 45 -19t19 -45z" />
-    <glyph glyph-name="hospital" unicode="&#xf0f8;" horiz-adv-x="1408" 
-d="M384 224v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM384 480v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z
-M640 480v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM384 736v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z
-M1152 224v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM896 480v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z
-M640 736v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM1152 480v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z
-M896 736v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM1152 736v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z
-M896 -128h384v1152h-256v-32q0 -40 -28 -68t-68 -28h-448q-40 0 -68 28t-28 68v32h-256v-1152h384v224q0 13 9.5 22.5t22.5 9.5h320q13 0 22.5 -9.5t9.5 -22.5v-224zM896 1056v320q0 13 -9.5 22.5t-22.5 9.5h-64q-13 0 -22.5 -9.5t-9.5 -22.5v-96h-128v96q0 13 -9.5 22.5
-t-22.5 9.5h-64q-13 0 -22.5 -9.5t-9.5 -22.5v-320q0 -13 9.5 -22.5t22.5 -9.5h64q13 0 22.5 9.5t9.5 22.5v96h128v-96q0 -13 9.5 -22.5t22.5 -9.5h64q13 0 22.5 9.5t9.5 22.5zM1408 1088v-1280q0 -26 -19 -45t-45 -19h-1280q-26 0 -45 19t-19 45v1280q0 26 19 45t45 19h320
-v288q0 40 28 68t68 28h448q40 0 68 -28t28 -68v-288h320q26 0 45 -19t19 -45z" />
-    <glyph glyph-name="ambulance" unicode="&#xf0f9;" horiz-adv-x="1920" 
-d="M640 128q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM256 640h384v256h-158q-14 -2 -22 -9l-195 -195q-7 -12 -9 -22v-30zM1536 128q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5
-t90.5 37.5t37.5 90.5zM1664 800v192q0 14 -9 23t-23 9h-224v224q0 14 -9 23t-23 9h-192q-14 0 -23 -9t-9 -23v-224h-224q-14 0 -23 -9t-9 -23v-192q0 -14 9 -23t23 -9h224v-224q0 -14 9 -23t23 -9h192q14 0 23 9t9 23v224h224q14 0 23 9t9 23zM1920 1344v-1152
-q0 -26 -19 -45t-45 -19h-192q0 -106 -75 -181t-181 -75t-181 75t-75 181h-384q0 -106 -75 -181t-181 -75t-181 75t-75 181h-128q-26 0 -45 19t-19 45t19 45t45 19v416q0 26 13 58t32 51l198 198q19 19 51 32t58 13h160v320q0 26 19 45t45 19h1152q26 0 45 -19t19 -45z" />
-    <glyph glyph-name="medkit" unicode="&#xf0fa;" horiz-adv-x="1792" 
-d="M1280 416v192q0 14 -9 23t-23 9h-224v224q0 14 -9 23t-23 9h-192q-14 0 -23 -9t-9 -23v-224h-224q-14 0 -23 -9t-9 -23v-192q0 -14 9 -23t23 -9h224v-224q0 -14 9 -23t23 -9h192q14 0 23 9t9 23v224h224q14 0 23 9t9 23zM640 1152h512v128h-512v-128zM256 1152v-1280h-32
-q-92 0 -158 66t-66 158v832q0 92 66 158t158 66h32zM1440 1152v-1280h-1088v1280h160v160q0 40 28 68t68 28h576q40 0 68 -28t28 -68v-160h160zM1792 928v-832q0 -92 -66 -158t-158 -66h-32v1280h32q92 0 158 -66t66 -158z" />
-    <glyph glyph-name="fighter_jet" unicode="&#xf0fb;" horiz-adv-x="1920" 
-d="M1920 576q-1 -32 -288 -96l-352 -32l-224 -64h-64l-293 -352h69q26 0 45 -4.5t19 -11.5t-19 -11.5t-45 -4.5h-96h-160h-64v32h64v416h-160l-192 -224h-96l-32 32v192h32v32h128v8l-192 24v128l192 24v8h-128v32h-32v192l32 32h96l192 -224h160v416h-64v32h64h160h96
-q26 0 45 -4.5t19 -11.5t-19 -11.5t-45 -4.5h-69l293 -352h64l224 -64l352 -32q128 -28 200 -52t80 -34z" />
-    <glyph glyph-name="beer" unicode="&#xf0fc;" horiz-adv-x="1664" 
-d="M640 640v384h-256v-256q0 -53 37.5 -90.5t90.5 -37.5h128zM1664 192v-192h-1152v192l128 192h-128q-159 0 -271.5 112.5t-112.5 271.5v320l-64 64l32 128h480l32 128h960l32 -192l-64 -32v-800z" />
-    <glyph glyph-name="h_sign" unicode="&#xf0fd;" 
-d="M1280 192v896q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-320h-512v320q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-896q0 -26 19 -45t45 -19h128q26 0 45 19t19 45v320h512v-320q0 -26 19 -45t45 -19h128q26 0 45 19t19 45zM1536 1120v-960
-q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
-    <glyph glyph-name="f0fe" unicode="&#xf0fe;" 
-d="M1280 576v128q0 26 -19 45t-45 19h-320v320q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-320h-320q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45t45 -19h320v-320q0 -26 19 -45t45 -19h128q26 0 45 19t19 45v320h320q26 0 45 19t19 45zM1536 1120v-960
-q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
-    <glyph glyph-name="double_angle_left" unicode="&#xf100;" horiz-adv-x="1024" 
-d="M627 160q0 -13 -10 -23l-50 -50q-10 -10 -23 -10t-23 10l-466 466q-10 10 -10 23t10 23l466 466q10 10 23 10t23 -10l50 -50q10 -10 10 -23t-10 -23l-393 -393l393 -393q10 -10 10 -23zM1011 160q0 -13 -10 -23l-50 -50q-10 -10 -23 -10t-23 10l-466 466q-10 10 -10 23
-t10 23l466 466q10 10 23 10t23 -10l50 -50q10 -10 10 -23t-10 -23l-393 -393l393 -393q10 -10 10 -23z" />
-    <glyph glyph-name="double_angle_right" unicode="&#xf101;" horiz-adv-x="1024" 
-d="M595 576q0 -13 -10 -23l-466 -466q-10 -10 -23 -10t-23 10l-50 50q-10 10 -10 23t10 23l393 393l-393 393q-10 10 -10 23t10 23l50 50q10 10 23 10t23 -10l466 -466q10 -10 10 -23zM979 576q0 -13 -10 -23l-466 -466q-10 -10 -23 -10t-23 10l-50 50q-10 10 -10 23t10 23
-l393 393l-393 393q-10 10 -10 23t10 23l50 50q10 10 23 10t23 -10l466 -466q10 -10 10 -23z" />
-    <glyph glyph-name="double_angle_up" unicode="&#xf102;" horiz-adv-x="1152" 
-d="M1075 224q0 -13 -10 -23l-50 -50q-10 -10 -23 -10t-23 10l-393 393l-393 -393q-10 -10 -23 -10t-23 10l-50 50q-10 10 -10 23t10 23l466 466q10 10 23 10t23 -10l466 -466q10 -10 10 -23zM1075 608q0 -13 -10 -23l-50 -50q-10 -10 -23 -10t-23 10l-393 393l-393 -393
-q-10 -10 -23 -10t-23 10l-50 50q-10 10 -10 23t10 23l466 466q10 10 23 10t23 -10l466 -466q10 -10 10 -23z" />
-    <glyph glyph-name="double_angle_down" unicode="&#xf103;" horiz-adv-x="1152" 
-d="M1075 672q0 -13 -10 -23l-466 -466q-10 -10 -23 -10t-23 10l-466 466q-10 10 -10 23t10 23l50 50q10 10 23 10t23 -10l393 -393l393 393q10 10 23 10t23 -10l50 -50q10 -10 10 -23zM1075 1056q0 -13 -10 -23l-466 -466q-10 -10 -23 -10t-23 10l-466 466q-10 10 -10 23
-t10 23l50 50q10 10 23 10t23 -10l393 -393l393 393q10 10 23 10t23 -10l50 -50q10 -10 10 -23z" />
-    <glyph glyph-name="angle_left" unicode="&#xf104;" horiz-adv-x="640" 
-d="M627 992q0 -13 -10 -23l-393 -393l393 -393q10 -10 10 -23t-10 -23l-50 -50q-10 -10 -23 -10t-23 10l-466 466q-10 10 -10 23t10 23l466 466q10 10 23 10t23 -10l50 -50q10 -10 10 -23z" />
-    <glyph glyph-name="angle_right" unicode="&#xf105;" horiz-adv-x="640" 
-d="M595 576q0 -13 -10 -23l-466 -466q-10 -10 -23 -10t-23 10l-50 50q-10 10 -10 23t10 23l393 393l-393 393q-10 10 -10 23t10 23l50 50q10 10 23 10t23 -10l466 -466q10 -10 10 -23z" />
-    <glyph glyph-name="angle_up" unicode="&#xf106;" horiz-adv-x="1152" 
-d="M1075 352q0 -13 -10 -23l-50 -50q-10 -10 -23 -10t-23 10l-393 393l-393 -393q-10 -10 -23 -10t-23 10l-50 50q-10 10 -10 23t10 23l466 466q10 10 23 10t23 -10l466 -466q10 -10 10 -23z" />
-    <glyph glyph-name="angle_down" unicode="&#xf107;" horiz-adv-x="1152" 
-d="M1075 800q0 -13 -10 -23l-466 -466q-10 -10 -23 -10t-23 10l-466 466q-10 10 -10 23t10 23l50 50q10 10 23 10t23 -10l393 -393l393 393q10 10 23 10t23 -10l50 -50q10 -10 10 -23z" />
-    <glyph glyph-name="desktop" unicode="&#xf108;" horiz-adv-x="1920" 
-d="M1792 544v832q0 13 -9.5 22.5t-22.5 9.5h-1600q-13 0 -22.5 -9.5t-9.5 -22.5v-832q0 -13 9.5 -22.5t22.5 -9.5h1600q13 0 22.5 9.5t9.5 22.5zM1920 1376v-1088q0 -66 -47 -113t-113 -47h-544q0 -37 16 -77.5t32 -71t16 -43.5q0 -26 -19 -45t-45 -19h-512q-26 0 -45 19
-t-19 45q0 14 16 44t32 70t16 78h-544q-66 0 -113 47t-47 113v1088q0 66 47 113t113 47h1600q66 0 113 -47t47 -113z" />
-    <glyph glyph-name="laptop" unicode="&#xf109;" horiz-adv-x="1920" 
-d="M416 256q-66 0 -113 47t-47 113v704q0 66 47 113t113 47h1088q66 0 113 -47t47 -113v-704q0 -66 -47 -113t-113 -47h-1088zM384 1120v-704q0 -13 9.5 -22.5t22.5 -9.5h1088q13 0 22.5 9.5t9.5 22.5v704q0 13 -9.5 22.5t-22.5 9.5h-1088q-13 0 -22.5 -9.5t-9.5 -22.5z
-M1760 192h160v-96q0 -40 -47 -68t-113 -28h-1600q-66 0 -113 28t-47 68v96h160h1600zM1040 96q16 0 16 16t-16 16h-160q-16 0 -16 -16t16 -16h160z" />
-    <glyph glyph-name="tablet" unicode="&#xf10a;" horiz-adv-x="1152" 
-d="M640 128q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1024 288v960q0 13 -9.5 22.5t-22.5 9.5h-832q-13 0 -22.5 -9.5t-9.5 -22.5v-960q0 -13 9.5 -22.5t22.5 -9.5h832q13 0 22.5 9.5t9.5 22.5zM1152 1248v-1088q0 -66 -47 -113t-113 -47h-832
-q-66 0 -113 47t-47 113v1088q0 66 47 113t113 47h832q66 0 113 -47t47 -113z" />
-    <glyph glyph-name="mobile_phone" unicode="&#xf10b;" horiz-adv-x="768" 
-d="M464 128q0 33 -23.5 56.5t-56.5 23.5t-56.5 -23.5t-23.5 -56.5t23.5 -56.5t56.5 -23.5t56.5 23.5t23.5 56.5zM672 288v704q0 13 -9.5 22.5t-22.5 9.5h-512q-13 0 -22.5 -9.5t-9.5 -22.5v-704q0 -13 9.5 -22.5t22.5 -9.5h512q13 0 22.5 9.5t9.5 22.5zM480 1136
-q0 16 -16 16h-160q-16 0 -16 -16t16 -16h160q16 0 16 16zM768 1152v-1024q0 -52 -38 -90t-90 -38h-512q-52 0 -90 38t-38 90v1024q0 52 38 90t90 38h512q52 0 90 -38t38 -90z" />
-    <glyph glyph-name="circle_blank" unicode="&#xf10c;" 
-d="M768 1184q-148 0 -273 -73t-198 -198t-73 -273t73 -273t198 -198t273 -73t273 73t198 198t73 273t-73 273t-198 198t-273 73zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103
-t279.5 -279.5t103 -385.5z" />
-    <glyph glyph-name="quote_left" unicode="&#xf10d;" horiz-adv-x="1664" 
-d="M768 576v-384q0 -80 -56 -136t-136 -56h-384q-80 0 -136 56t-56 136v704q0 104 40.5 198.5t109.5 163.5t163.5 109.5t198.5 40.5h64q26 0 45 -19t19 -45v-128q0 -26 -19 -45t-45 -19h-64q-106 0 -181 -75t-75 -181v-32q0 -40 28 -68t68 -28h224q80 0 136 -56t56 -136z
-M1664 576v-384q0 -80 -56 -136t-136 -56h-384q-80 0 -136 56t-56 136v704q0 104 40.5 198.5t109.5 163.5t163.5 109.5t198.5 40.5h64q26 0 45 -19t19 -45v-128q0 -26 -19 -45t-45 -19h-64q-106 0 -181 -75t-75 -181v-32q0 -40 28 -68t68 -28h224q80 0 136 -56t56 -136z" />
-    <glyph glyph-name="quote_right" unicode="&#xf10e;" horiz-adv-x="1664" 
-d="M768 1216v-704q0 -104 -40.5 -198.5t-109.5 -163.5t-163.5 -109.5t-198.5 -40.5h-64q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h64q106 0 181 75t75 181v32q0 40 -28 68t-68 28h-224q-80 0 -136 56t-56 136v384q0 80 56 136t136 56h384q80 0 136 -56t56 -136zM1664 1216
-v-704q0 -104 -40.5 -198.5t-109.5 -163.5t-163.5 -109.5t-198.5 -40.5h-64q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h64q106 0 181 75t75 181v32q0 40 -28 68t-68 28h-224q-80 0 -136 56t-56 136v384q0 80 56 136t136 56h384q80 0 136 -56t56 -136z" />
-    <glyph glyph-name="spinner" unicode="&#xf110;" horiz-adv-x="1792" 
-d="M526 142q0 -53 -37.5 -90.5t-90.5 -37.5q-52 0 -90 38t-38 90q0 53 37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1024 -64q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM320 640q0 -53 -37.5 -90.5t-90.5 -37.5
-t-90.5 37.5t-37.5 90.5t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1522 142q0 -52 -38 -90t-90 -38q-53 0 -90.5 37.5t-37.5 90.5t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM558 1138q0 -66 -47 -113t-113 -47t-113 47t-47 113t47 113t113 47t113 -47t47 -113z
-M1728 640q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1088 1344q0 -80 -56 -136t-136 -56t-136 56t-56 136t56 136t136 56t136 -56t56 -136zM1618 1138q0 -93 -66 -158.5t-158 -65.5q-93 0 -158.5 65.5t-65.5 158.5
-q0 92 65.5 158t158.5 66q92 0 158 -66t66 -158z" />
-    <glyph glyph-name="circle" unicode="&#xf111;" 
-d="M1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
-    <glyph glyph-name="reply" unicode="&#xf112;" horiz-adv-x="1792" 
-d="M1792 416q0 -166 -127 -451q-3 -7 -10.5 -24t-13.5 -30t-13 -22q-12 -17 -28 -17q-15 0 -23.5 10t-8.5 25q0 9 2.5 26.5t2.5 23.5q5 68 5 123q0 101 -17.5 181t-48.5 138.5t-80 101t-105.5 69.5t-133 42.5t-154 21.5t-175.5 6h-224v-256q0 -26 -19 -45t-45 -19t-45 19
-l-512 512q-19 19 -19 45t19 45l512 512q19 19 45 19t45 -19t19 -45v-256h224q713 0 875 -403q53 -134 53 -333z" />
-    <glyph glyph-name="github_alt" unicode="&#xf113;" horiz-adv-x="1664" 
-d="M640 320q0 -40 -12.5 -82t-43 -76t-72.5 -34t-72.5 34t-43 76t-12.5 82t12.5 82t43 76t72.5 34t72.5 -34t43 -76t12.5 -82zM1280 320q0 -40 -12.5 -82t-43 -76t-72.5 -34t-72.5 34t-43 76t-12.5 82t12.5 82t43 76t72.5 34t72.5 -34t43 -76t12.5 -82zM1440 320
-q0 120 -69 204t-187 84q-41 0 -195 -21q-71 -11 -157 -11t-157 11q-152 21 -195 21q-118 0 -187 -84t-69 -204q0 -88 32 -153.5t81 -103t122 -60t140 -29.5t149 -7h168q82 0 149 7t140 29.5t122 60t81 103t32 153.5zM1664 496q0 -207 -61 -331q-38 -77 -105.5 -133t-141 -86
-t-170 -47.5t-171.5 -22t-167 -4.5q-78 0 -142 3t-147.5 12.5t-152.5 30t-137 51.5t-121 81t-86 115q-62 123 -62 331q0 237 136 396q-27 82 -27 170q0 116 51 218q108 0 190 -39.5t189 -123.5q147 35 309 35q148 0 280 -32q105 82 187 121t189 39q51 -102 51 -218
-q0 -87 -27 -168q136 -160 136 -398z" />
-    <glyph glyph-name="folder_close_alt" unicode="&#xf114;" horiz-adv-x="1664" 
-d="M1536 224v704q0 40 -28 68t-68 28h-704q-40 0 -68 28t-28 68v64q0 40 -28 68t-68 28h-320q-40 0 -68 -28t-28 -68v-960q0 -40 28 -68t68 -28h1216q40 0 68 28t28 68zM1664 928v-704q0 -92 -66 -158t-158 -66h-1216q-92 0 -158 66t-66 158v960q0 92 66 158t158 66h320
-q92 0 158 -66t66 -158v-32h672q92 0 158 -66t66 -158z" />
-    <glyph glyph-name="folder_open_alt" unicode="&#xf115;" horiz-adv-x="1920" 
-d="M1781 605q0 35 -53 35h-1088q-40 0 -85.5 -21.5t-71.5 -52.5l-294 -363q-18 -24 -18 -40q0 -35 53 -35h1088q40 0 86 22t71 53l294 363q18 22 18 39zM640 768h768v160q0 40 -28 68t-68 28h-576q-40 0 -68 28t-28 68v64q0 40 -28 68t-68 28h-320q-40 0 -68 -28t-28 -68
-v-853l256 315q44 53 116 87.5t140 34.5zM1909 605q0 -62 -46 -120l-295 -363q-43 -53 -116 -87.5t-140 -34.5h-1088q-92 0 -158 66t-66 158v960q0 92 66 158t158 66h320q92 0 158 -66t66 -158v-32h544q92 0 158 -66t66 -158v-160h192q54 0 99 -24.5t67 -70.5q15 -32 15 -68z
-" />
-    <glyph glyph-name="expand_alt" unicode="&#xf116;" horiz-adv-x="1792" 
- />
-    <glyph glyph-name="collapse_alt" unicode="&#xf117;" horiz-adv-x="1792" 
- />
-    <glyph glyph-name="smile" unicode="&#xf118;" 
-d="M1134 461q-37 -121 -138 -195t-228 -74t-228 74t-138 195q-8 25 4 48.5t38 31.5q25 8 48.5 -4t31.5 -38q25 -80 92.5 -129.5t151.5 -49.5t151.5 49.5t92.5 129.5q8 26 32 38t49 4t37 -31.5t4 -48.5zM640 896q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5
-t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1152 896q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1408 640q0 130 -51 248.5t-136.5 204t-204 136.5t-248.5 51t-248.5 -51t-204 -136.5t-136.5 -204t-51 -248.5
-t51 -248.5t136.5 -204t204 -136.5t248.5 -51t248.5 51t204 136.5t136.5 204t51 248.5zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
-    <glyph glyph-name="frown" unicode="&#xf119;" 
-d="M1134 307q8 -25 -4 -48.5t-37 -31.5t-49 4t-32 38q-25 80 -92.5 129.5t-151.5 49.5t-151.5 -49.5t-92.5 -129.5q-8 -26 -31.5 -38t-48.5 -4q-26 8 -38 31.5t-4 48.5q37 121 138 195t228 74t228 -74t138 -195zM640 896q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5
-t-37.5 90.5t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1152 896q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1408 640q0 130 -51 248.5t-136.5 204t-204 136.5t-248.5 51t-248.5 -51t-204 -136.5t-136.5 -204
-t-51 -248.5t51 -248.5t136.5 -204t204 -136.5t248.5 -51t248.5 51t204 136.5t136.5 204t51 248.5zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
-    <glyph glyph-name="meh" unicode="&#xf11a;" 
-d="M1152 448q0 -26 -19 -45t-45 -19h-640q-26 0 -45 19t-19 45t19 45t45 19h640q26 0 45 -19t19 -45zM640 896q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1152 896q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5
-t-37.5 90.5t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1408 640q0 130 -51 248.5t-136.5 204t-204 136.5t-248.5 51t-248.5 -51t-204 -136.5t-136.5 -204t-51 -248.5t51 -248.5t136.5 -204t204 -136.5t248.5 -51t248.5 51t204 136.5t136.5 204t51 248.5zM1536 640
-q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
-    <glyph glyph-name="gamepad" unicode="&#xf11b;" horiz-adv-x="1920" 
-d="M832 448v128q0 14 -9 23t-23 9h-192v192q0 14 -9 23t-23 9h-128q-14 0 -23 -9t-9 -23v-192h-192q-14 0 -23 -9t-9 -23v-128q0 -14 9 -23t23 -9h192v-192q0 -14 9 -23t23 -9h128q14 0 23 9t9 23v192h192q14 0 23 9t9 23zM1408 384q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5
-t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1664 640q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1920 512q0 -212 -150 -362t-362 -150q-192 0 -338 128h-220q-146 -128 -338 -128q-212 0 -362 150
-t-150 362t150 362t362 150h896q212 0 362 -150t150 -362z" />
-    <glyph glyph-name="keyboard" unicode="&#xf11c;" horiz-adv-x="1920" 
-d="M384 368v-96q0 -16 -16 -16h-96q-16 0 -16 16v96q0 16 16 16h96q16 0 16 -16zM512 624v-96q0 -16 -16 -16h-224q-16 0 -16 16v96q0 16 16 16h224q16 0 16 -16zM384 880v-96q0 -16 -16 -16h-96q-16 0 -16 16v96q0 16 16 16h96q16 0 16 -16zM1408 368v-96q0 -16 -16 -16
-h-864q-16 0 -16 16v96q0 16 16 16h864q16 0 16 -16zM768 624v-96q0 -16 -16 -16h-96q-16 0 -16 16v96q0 16 16 16h96q16 0 16 -16zM640 880v-96q0 -16 -16 -16h-96q-16 0 -16 16v96q0 16 16 16h96q16 0 16 -16zM1024 624v-96q0 -16 -16 -16h-96q-16 0 -16 16v96q0 16 16 16
-h96q16 0 16 -16zM896 880v-96q0 -16 -16 -16h-96q-16 0 -16 16v96q0 16 16 16h96q16 0 16 -16zM1280 624v-96q0 -16 -16 -16h-96q-16 0 -16 16v96q0 16 16 16h96q16 0 16 -16zM1664 368v-96q0 -16 -16 -16h-96q-16 0 -16 16v96q0 16 16 16h96q16 0 16 -16zM1152 880v-96
-q0 -16 -16 -16h-96q-16 0 -16 16v96q0 16 16 16h96q16 0 16 -16zM1408 880v-96q0 -16 -16 -16h-96q-16 0 -16 16v96q0 16 16 16h96q16 0 16 -16zM1664 880v-352q0 -16 -16 -16h-224q-16 0 -16 16v96q0 16 16 16h112v240q0 16 16 16h96q16 0 16 -16zM1792 128v896h-1664v-896
-h1664zM1920 1024v-896q0 -53 -37.5 -90.5t-90.5 -37.5h-1664q-53 0 -90.5 37.5t-37.5 90.5v896q0 53 37.5 90.5t90.5 37.5h1664q53 0 90.5 -37.5t37.5 -90.5z" />
-    <glyph glyph-name="flag_alt" unicode="&#xf11d;" horiz-adv-x="1792" 
-d="M1664 491v616q-169 -91 -306 -91q-82 0 -145 32q-100 49 -184 76.5t-178 27.5q-173 0 -403 -127v-599q245 113 433 113q55 0 103.5 -7.5t98 -26t77 -31t82.5 -39.5l28 -14q44 -22 101 -22q120 0 293 92zM320 1280q0 -35 -17.5 -64t-46.5 -46v-1266q0 -14 -9 -23t-23 -9
-h-64q-14 0 -23 9t-9 23v1266q-29 17 -46.5 46t-17.5 64q0 53 37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1792 1216v-763q0 -39 -35 -57q-10 -5 -17 -9q-218 -116 -369 -116q-88 0 -158 35l-28 14q-64 33 -99 48t-91 29t-114 14q-102 0 -235.5 -44t-228.5 -102
-q-15 -9 -33 -9q-16 0 -32 8q-32 19 -32 56v742q0 35 31 55q35 21 78.5 42.5t114 52t152.5 49.5t155 19q112 0 209 -31t209 -86q38 -19 89 -19q122 0 310 112q22 12 31 17q31 16 62 -2q31 -20 31 -55z" />
-    <glyph glyph-name="flag_checkered" unicode="&#xf11e;" horiz-adv-x="1792" 
-d="M832 536v192q-181 -16 -384 -117v-185q205 96 384 110zM832 954v197q-172 -8 -384 -126v-189q215 111 384 118zM1664 491v184q-235 -116 -384 -71v224q-20 6 -39 15q-5 3 -33 17t-34.5 17t-31.5 15t-34.5 15.5t-32.5 13t-36 12.5t-35 8.5t-39.5 7.5t-39.5 4t-44 2
-q-23 0 -49 -3v-222h19q102 0 192.5 -29t197.5 -82q19 -9 39 -15v-188q42 -17 91 -17q120 0 293 92zM1664 918v189q-169 -91 -306 -91q-45 0 -78 8v-196q148 -42 384 90zM320 1280q0 -35 -17.5 -64t-46.5 -46v-1266q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v1266
-q-29 17 -46.5 46t-17.5 64q0 53 37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1792 1216v-763q0 -39 -35 -57q-10 -5 -17 -9q-218 -116 -369 -116q-88 0 -158 35l-28 14q-64 33 -99 48t-91 29t-114 14q-102 0 -235.5 -44t-228.5 -102q-15 -9 -33 -9q-16 0 -32 8
-q-32 19 -32 56v742q0 35 31 55q35 21 78.5 42.5t114 52t152.5 49.5t155 19q112 0 209 -31t209 -86q38 -19 89 -19q122 0 310 112q22 12 31 17q31 16 62 -2q31 -20 31 -55z" />
-    <glyph glyph-name="terminal" unicode="&#xf120;" horiz-adv-x="1664" 
-d="M585 553l-466 -466q-10 -10 -23 -10t-23 10l-50 50q-10 10 -10 23t10 23l393 393l-393 393q-10 10 -10 23t10 23l50 50q10 10 23 10t23 -10l466 -466q10 -10 10 -23t-10 -23zM1664 96v-64q0 -14 -9 -23t-23 -9h-960q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h960q14 0 23 -9
-t9 -23z" />
-    <glyph glyph-name="code" unicode="&#xf121;" horiz-adv-x="1920" 
-d="M617 137l-50 -50q-10 -10 -23 -10t-23 10l-466 466q-10 10 -10 23t10 23l466 466q10 10 23 10t23 -10l50 -50q10 -10 10 -23t-10 -23l-393 -393l393 -393q10 -10 10 -23t-10 -23zM1208 1204l-373 -1291q-4 -13 -15.5 -19.5t-23.5 -2.5l-62 17q-13 4 -19.5 15.5t-2.5 24.5
-l373 1291q4 13 15.5 19.5t23.5 2.5l62 -17q13 -4 19.5 -15.5t2.5 -24.5zM1865 553l-466 -466q-10 -10 -23 -10t-23 10l-50 50q-10 10 -10 23t10 23l393 393l-393 393q-10 10 -10 23t10 23l50 50q10 10 23 10t23 -10l466 -466q10 -10 10 -23t-10 -23z" />
-    <glyph glyph-name="reply_all" unicode="&#xf122;" horiz-adv-x="1792" 
-d="M640 454v-70q0 -42 -39 -59q-13 -5 -25 -5q-27 0 -45 19l-512 512q-19 19 -19 45t19 45l512 512q29 31 70 14q39 -17 39 -59v-69l-397 -398q-19 -19 -19 -45t19 -45zM1792 416q0 -58 -17 -133.5t-38.5 -138t-48 -125t-40.5 -90.5l-20 -40q-8 -17 -28 -17q-6 0 -9 1
-q-25 8 -23 34q43 400 -106 565q-64 71 -170.5 110.5t-267.5 52.5v-251q0 -42 -39 -59q-13 -5 -25 -5q-27 0 -45 19l-512 512q-19 19 -19 45t19 45l512 512q29 31 70 14q39 -17 39 -59v-262q411 -28 599 -221q169 -173 169 -509z" />
-    <glyph glyph-name="star_half_empty" unicode="&#xf123;" horiz-adv-x="1664" 
-d="M1186 579l257 250l-356 52l-66 10l-30 60l-159 322v-963l59 -31l318 -168l-60 355l-12 66zM1638 841l-363 -354l86 -500q5 -33 -6 -51.5t-34 -18.5q-17 0 -40 12l-449 236l-449 -236q-23 -12 -40 -12q-23 0 -34 18.5t-6 51.5l86 500l-364 354q-32 32 -23 59.5t54 34.5
-l502 73l225 455q20 41 49 41q28 0 49 -41l225 -455l502 -73q45 -7 54 -34.5t-24 -59.5z" />
-    <glyph glyph-name="location_arrow" unicode="&#xf124;" horiz-adv-x="1408" 
-d="M1401 1187l-640 -1280q-17 -35 -57 -35q-5 0 -15 2q-22 5 -35.5 22.5t-13.5 39.5v576h-576q-22 0 -39.5 13.5t-22.5 35.5t4 42t29 30l1280 640q13 7 29 7q27 0 45 -19q15 -14 18.5 -34.5t-6.5 -39.5z" />
-    <glyph glyph-name="crop" unicode="&#xf125;" horiz-adv-x="1664" 
-d="M557 256h595v595zM512 301l595 595h-595v-595zM1664 224v-192q0 -14 -9 -23t-23 -9h-224v-224q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v224h-864q-14 0 -23 9t-9 23v864h-224q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h224v224q0 14 9 23t23 9h192q14 0 23 -9t9 -23
-v-224h851l246 247q10 9 23 9t23 -9q9 -10 9 -23t-9 -23l-247 -246v-851h224q14 0 23 -9t9 -23z" />
-    <glyph glyph-name="code_fork" unicode="&#xf126;" horiz-adv-x="1024" 
-d="M288 64q0 40 -28 68t-68 28t-68 -28t-28 -68t28 -68t68 -28t68 28t28 68zM288 1216q0 40 -28 68t-68 28t-68 -28t-28 -68t28 -68t68 -28t68 28t28 68zM928 1088q0 40 -28 68t-68 28t-68 -28t-28 -68t28 -68t68 -28t68 28t28 68zM1024 1088q0 -52 -26 -96.5t-70 -69.5
-q-2 -287 -226 -414q-67 -38 -203 -81q-128 -40 -169.5 -71t-41.5 -100v-26q44 -25 70 -69.5t26 -96.5q0 -80 -56 -136t-136 -56t-136 56t-56 136q0 52 26 96.5t70 69.5v820q-44 25 -70 69.5t-26 96.5q0 80 56 136t136 56t136 -56t56 -136q0 -52 -26 -96.5t-70 -69.5v-497
-q54 26 154 57q55 17 87.5 29.5t70.5 31t59 39.5t40.5 51t28 69.5t8.5 91.5q-44 25 -70 69.5t-26 96.5q0 80 56 136t136 56t136 -56t56 -136z" />
-    <glyph glyph-name="unlink" unicode="&#xf127;" horiz-adv-x="1664" 
-d="M439 265l-256 -256q-11 -9 -23 -9t-23 9q-9 10 -9 23t9 23l256 256q10 9 23 9t23 -9q9 -10 9 -23t-9 -23zM608 224v-320q0 -14 -9 -23t-23 -9t-23 9t-9 23v320q0 14 9 23t23 9t23 -9t9 -23zM384 448q0 -14 -9 -23t-23 -9h-320q-14 0 -23 9t-9 23t9 23t23 9h320
-q14 0 23 -9t9 -23zM1648 320q0 -120 -85 -203l-147 -146q-83 -83 -203 -83q-121 0 -204 85l-334 335q-21 21 -42 56l239 18l273 -274q27 -27 68 -27.5t68 26.5l147 146q28 28 28 67q0 40 -28 68l-274 275l18 239q35 -21 56 -42l336 -336q84 -86 84 -204zM1031 1044l-239 -18
-l-273 274q-28 28 -68 28q-39 0 -68 -27l-147 -146q-28 -28 -28 -67q0 -40 28 -68l274 -274l-18 -240q-35 21 -56 42l-336 336q-84 86 -84 204q0 120 85 203l147 146q83 83 203 83q121 0 204 -85l334 -335q21 -21 42 -56zM1664 960q0 -14 -9 -23t-23 -9h-320q-14 0 -23 9
-t-9 23t9 23t23 9h320q14 0 23 -9t9 -23zM1120 1504v-320q0 -14 -9 -23t-23 -9t-23 9t-9 23v320q0 14 9 23t23 9t23 -9t9 -23zM1527 1353l-256 -256q-11 -9 -23 -9t-23 9q-9 10 -9 23t9 23l256 256q10 9 23 9t23 -9q9 -10 9 -23t-9 -23z" />
-    <glyph glyph-name="question" unicode="&#xf128;" horiz-adv-x="1024" 
-d="M704 280v-240q0 -16 -12 -28t-28 -12h-240q-16 0 -28 12t-12 28v240q0 16 12 28t28 12h240q16 0 28 -12t12 -28zM1020 880q0 -54 -15.5 -101t-35 -76.5t-55 -59.5t-57.5 -43.5t-61 -35.5q-41 -23 -68.5 -65t-27.5 -67q0 -17 -12 -32.5t-28 -15.5h-240q-15 0 -25.5 18.5
-t-10.5 37.5v45q0 83 65 156.5t143 108.5q59 27 84 56t25 76q0 42 -46.5 74t-107.5 32q-65 0 -108 -29q-35 -25 -107 -115q-13 -16 -31 -16q-12 0 -25 8l-164 125q-13 10 -15.5 25t5.5 28q160 266 464 266q80 0 161 -31t146 -83t106 -127.5t41 -158.5z" />
-    <glyph glyph-name="_279" unicode="&#xf129;" horiz-adv-x="640" 
-d="M640 192v-128q0 -26 -19 -45t-45 -19h-512q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h64v384h-64q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h384q26 0 45 -19t19 -45v-576h64q26 0 45 -19t19 -45zM512 1344v-192q0 -26 -19 -45t-45 -19h-256q-26 0 -45 19t-19 45v192
-q0 26 19 45t45 19h256q26 0 45 -19t19 -45z" />
-    <glyph glyph-name="exclamation" unicode="&#xf12a;" horiz-adv-x="640" 
-d="M512 288v-224q0 -26 -19 -45t-45 -19h-256q-26 0 -45 19t-19 45v224q0 26 19 45t45 19h256q26 0 45 -19t19 -45zM542 1344l-28 -768q-1 -26 -20.5 -45t-45.5 -19h-256q-26 0 -45.5 19t-20.5 45l-28 768q-1 26 17.5 45t44.5 19h320q26 0 44.5 -19t17.5 -45z" />
-    <glyph glyph-name="superscript" unicode="&#xf12b;" 
-d="M897 167v-167h-248l-159 252l-24 42q-8 9 -11 21h-3q-1 -3 -2.5 -6.5t-3.5 -8t-3 -6.5q-10 -20 -25 -44l-155 -250h-258v167h128l197 291l-185 272h-137v168h276l139 -228q2 -4 23 -42q8 -9 11 -21h3q3 9 11 21l25 42l140 228h257v-168h-125l-184 -267l204 -296h109z
-M1534 846v-206h-514l-3 27q-4 28 -4 46q0 64 26 117t65 86.5t84 65t84 54.5t65 54t26 64q0 38 -29.5 62.5t-70.5 24.5q-51 0 -97 -39q-14 -11 -36 -38l-105 92q26 37 63 66q83 65 188 65q110 0 178 -59.5t68 -158.5q0 -56 -24.5 -103t-62 -76.5t-81.5 -58.5t-82 -50.5
-t-65.5 -51.5t-30.5 -63h232v80h126z" />
-    <glyph glyph-name="subscript" unicode="&#xf12c;" 
-d="M897 167v-167h-248l-159 252l-24 42q-8 9 -11 21h-3q-1 -3 -2.5 -6.5t-3.5 -8t-3 -6.5q-10 -20 -25 -44l-155 -250h-258v167h128l197 291l-185 272h-137v168h276l139 -228q2 -4 23 -42q8 -9 11 -21h3q3 9 11 21l25 42l140 228h257v-168h-125l-184 -267l204 -296h109z
-M1536 -50v-206h-514l-4 27q-3 45 -3 46q0 64 26 117t65 86.5t84 65t84 54.5t65 54t26 64q0 38 -29.5 62.5t-70.5 24.5q-51 0 -97 -39q-14 -11 -36 -38l-105 92q26 37 63 66q80 65 188 65q110 0 178 -59.5t68 -158.5q0 -66 -34.5 -118.5t-84 -86t-99.5 -62.5t-87 -63t-41 -73
-h232v80h126z" />
-    <glyph glyph-name="_283" unicode="&#xf12d;" horiz-adv-x="1920" 
-d="M896 128l336 384h-768l-336 -384h768zM1909 1205q15 -34 9.5 -71.5t-30.5 -65.5l-896 -1024q-38 -44 -96 -44h-768q-38 0 -69.5 20.5t-47.5 54.5q-15 34 -9.5 71.5t30.5 65.5l896 1024q38 44 96 44h768q38 0 69.5 -20.5t47.5 -54.5z" />
-    <glyph glyph-name="puzzle_piece" unicode="&#xf12e;" horiz-adv-x="1664" 
-d="M1664 438q0 -81 -44.5 -135t-123.5 -54q-41 0 -77.5 17.5t-59 38t-56.5 38t-71 17.5q-110 0 -110 -124q0 -39 16 -115t15 -115v-5q-22 0 -33 -1q-34 -3 -97.5 -11.5t-115.5 -13.5t-98 -5q-61 0 -103 26.5t-42 83.5q0 37 17.5 71t38 56.5t38 59t17.5 77.5q0 79 -54 123.5
-t-135 44.5q-84 0 -143 -45.5t-59 -127.5q0 -43 15 -83t33.5 -64.5t33.5 -53t15 -50.5q0 -45 -46 -89q-37 -35 -117 -35q-95 0 -245 24q-9 2 -27.5 4t-27.5 4l-13 2q-1 0 -3 1q-2 0 -2 1v1024q2 -1 17.5 -3.5t34 -5t21.5 -3.5q150 -24 245 -24q80 0 117 35q46 44 46 89
-q0 22 -15 50.5t-33.5 53t-33.5 64.5t-15 83q0 82 59 127.5t144 45.5q80 0 134 -44.5t54 -123.5q0 -41 -17.5 -77.5t-38 -59t-38 -56.5t-17.5 -71q0 -57 42 -83.5t103 -26.5q64 0 180 15t163 17v-2q-1 -2 -3.5 -17.5t-5 -34t-3.5 -21.5q-24 -150 -24 -245q0 -80 35 -117
-q44 -46 89 -46q22 0 50.5 15t53 33.5t64.5 33.5t83 15q82 0 127.5 -59t45.5 -143z" />
-    <glyph glyph-name="microphone" unicode="&#xf130;" horiz-adv-x="1152" 
-d="M1152 832v-128q0 -221 -147.5 -384.5t-364.5 -187.5v-132h256q26 0 45 -19t19 -45t-19 -45t-45 -19h-640q-26 0 -45 19t-19 45t19 45t45 19h256v132q-217 24 -364.5 187.5t-147.5 384.5v128q0 26 19 45t45 19t45 -19t19 -45v-128q0 -185 131.5 -316.5t316.5 -131.5
-t316.5 131.5t131.5 316.5v128q0 26 19 45t45 19t45 -19t19 -45zM896 1216v-512q0 -132 -94 -226t-226 -94t-226 94t-94 226v512q0 132 94 226t226 94t226 -94t94 -226z" />
-    <glyph glyph-name="microphone_off" unicode="&#xf131;" horiz-adv-x="1408" 
-d="M271 591l-101 -101q-42 103 -42 214v128q0 26 19 45t45 19t45 -19t19 -45v-128q0 -53 15 -113zM1385 1193l-361 -361v-128q0 -132 -94 -226t-226 -94q-55 0 -109 19l-96 -96q97 -51 205 -51q185 0 316.5 131.5t131.5 316.5v128q0 26 19 45t45 19t45 -19t19 -45v-128
-q0 -221 -147.5 -384.5t-364.5 -187.5v-132h256q26 0 45 -19t19 -45t-19 -45t-45 -19h-640q-26 0 -45 19t-19 45t19 45t45 19h256v132q-125 13 -235 81l-254 -254q-10 -10 -23 -10t-23 10l-82 82q-10 10 -10 23t10 23l1234 1234q10 10 23 10t23 -10l82 -82q10 -10 10 -23
-t-10 -23zM1005 1325l-621 -621v512q0 132 94 226t226 94q102 0 184.5 -59t116.5 -152z" />
-    <glyph glyph-name="shield" unicode="&#xf132;" horiz-adv-x="1280" 
-d="M1088 576v640h-448v-1137q119 63 213 137q235 184 235 360zM1280 1344v-768q0 -86 -33.5 -170.5t-83 -150t-118 -127.5t-126.5 -103t-121 -77.5t-89.5 -49.5t-42.5 -20q-12 -6 -26 -6t-26 6q-16 7 -42.5 20t-89.5 49.5t-121 77.5t-126.5 103t-118 127.5t-83 150
-t-33.5 170.5v768q0 26 19 45t45 19h1152q26 0 45 -19t19 -45z" />
-    <glyph glyph-name="calendar_empty" unicode="&#xf133;" horiz-adv-x="1664" 
-d="M128 -128h1408v1024h-1408v-1024zM512 1088v288q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-288q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM1280 1088v288q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-288q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM1664 1152v-1280
-q0 -52 -38 -90t-90 -38h-1408q-52 0 -90 38t-38 90v1280q0 52 38 90t90 38h128v96q0 66 47 113t113 47h64q66 0 113 -47t47 -113v-96h384v96q0 66 47 113t113 47h64q66 0 113 -47t47 -113v-96h128q52 0 90 -38t38 -90z" />
-    <glyph glyph-name="fire_extinguisher" unicode="&#xf134;" horiz-adv-x="1408" 
-d="M512 1344q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1408 1376v-320q0 -16 -12 -25q-8 -7 -20 -7q-4 0 -7 1l-448 96q-11 2 -18 11t-7 20h-256v-102q111 -23 183.5 -111t72.5 -203v-800q0 -26 -19 -45t-45 -19h-512q-26 0 -45 19t-19 45v800
-q0 106 62.5 190.5t161.5 114.5v111h-32q-59 0 -115 -23.5t-91.5 -53t-66 -66.5t-40.5 -53.5t-14 -24.5q-17 -35 -57 -35q-16 0 -29 7q-23 12 -31.5 37t3.5 49q5 10 14.5 26t37.5 53.5t60.5 70t85 67t108.5 52.5q-25 42 -25 86q0 66 47 113t113 47t113 -47t47 -113
-q0 -33 -14 -64h302q0 11 7 20t18 11l448 96q3 1 7 1q12 0 20 -7q12 -9 12 -25z" />
-    <glyph glyph-name="rocket" unicode="&#xf135;" horiz-adv-x="1664" 
-d="M1440 1088q0 40 -28 68t-68 28t-68 -28t-28 -68t28 -68t68 -28t68 28t28 68zM1664 1376q0 -249 -75.5 -430.5t-253.5 -360.5q-81 -80 -195 -176l-20 -379q-2 -16 -16 -26l-384 -224q-7 -4 -16 -4q-12 0 -23 9l-64 64q-13 14 -8 32l85 276l-281 281l-276 -85q-3 -1 -9 -1
-q-14 0 -23 9l-64 64q-17 19 -5 39l224 384q10 14 26 16l379 20q96 114 176 195q188 187 358 258t431 71q14 0 24 -9.5t10 -22.5z" />
-    <glyph glyph-name="maxcdn" unicode="&#xf136;" horiz-adv-x="1792" 
-d="M1745 763l-164 -763h-334l178 832q13 56 -15 88q-27 33 -83 33h-169l-204 -953h-334l204 953h-286l-204 -953h-334l204 953l-153 327h1276q101 0 189.5 -40.5t147.5 -113.5q60 -73 81 -168.5t0 -194.5z" />
-    <glyph glyph-name="chevron_sign_left" unicode="&#xf137;" 
-d="M909 141l102 102q19 19 19 45t-19 45l-307 307l307 307q19 19 19 45t-19 45l-102 102q-19 19 -45 19t-45 -19l-454 -454q-19 -19 -19 -45t19 -45l454 -454q19 -19 45 -19t45 19zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5
-t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
-    <glyph glyph-name="chevron_sign_right" unicode="&#xf138;" 
-d="M717 141l454 454q19 19 19 45t-19 45l-454 454q-19 19 -45 19t-45 -19l-102 -102q-19 -19 -19 -45t19 -45l307 -307l-307 -307q-19 -19 -19 -45t19 -45l102 -102q19 -19 45 -19t45 19zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5
-t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
-    <glyph glyph-name="chevron_sign_up" unicode="&#xf139;" 
-d="M1165 397l102 102q19 19 19 45t-19 45l-454 454q-19 19 -45 19t-45 -19l-454 -454q-19 -19 -19 -45t19 -45l102 -102q19 -19 45 -19t45 19l307 307l307 -307q19 -19 45 -19t45 19zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5
-t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
-    <glyph glyph-name="chevron_sign_down" unicode="&#xf13a;" 
-d="M813 237l454 454q19 19 19 45t-19 45l-102 102q-19 19 -45 19t-45 -19l-307 -307l-307 307q-19 19 -45 19t-45 -19l-102 -102q-19 -19 -19 -45t19 -45l454 -454q19 -19 45 -19t45 19zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5
-t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
-    <glyph glyph-name="html5" unicode="&#xf13b;" horiz-adv-x="1408" 
-d="M1130 939l16 175h-884l47 -534h612l-22 -228l-197 -53l-196 53l-13 140h-175l22 -278l362 -100h4v1l359 99l50 544h-644l-15 181h674zM0 1408h1408l-128 -1438l-578 -162l-574 162z" />
-    <glyph glyph-name="css3" unicode="&#xf13c;" horiz-adv-x="1792" 
-d="M275 1408h1505l-266 -1333l-804 -267l-698 267l71 356h297l-29 -147l422 -161l486 161l68 339h-1208l58 297h1209l38 191h-1208z" />
-    <glyph glyph-name="anchor" unicode="&#xf13d;" horiz-adv-x="1792" 
-d="M960 1280q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1792 352v-352q0 -22 -20 -30q-8 -2 -12 -2q-12 0 -23 9l-93 93q-119 -143 -318.5 -226.5t-429.5 -83.5t-429.5 83.5t-318.5 226.5l-93 -93q-9 -9 -23 -9q-4 0 -12 2q-20 8 -20 30v352
-q0 14 9 23t23 9h352q22 0 30 -20q8 -19 -7 -35l-100 -100q67 -91 189.5 -153.5t271.5 -82.5v647h-192q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h192v163q-58 34 -93 92.5t-35 128.5q0 106 75 181t181 75t181 -75t75 -181q0 -70 -35 -128.5t-93 -92.5v-163h192q26 0 45 -19
-t19 -45v-128q0 -26 -19 -45t-45 -19h-192v-647q149 20 271.5 82.5t189.5 153.5l-100 100q-15 16 -7 35q8 20 30 20h352q14 0 23 -9t9 -23z" />
-    <glyph glyph-name="unlock_alt" unicode="&#xf13e;" horiz-adv-x="1152" 
-d="M1056 768q40 0 68 -28t28 -68v-576q0 -40 -28 -68t-68 -28h-960q-40 0 -68 28t-28 68v576q0 40 28 68t68 28h32v320q0 185 131.5 316.5t316.5 131.5t316.5 -131.5t131.5 -316.5q0 -26 -19 -45t-45 -19h-64q-26 0 -45 19t-19 45q0 106 -75 181t-181 75t-181 -75t-75 -181
-v-320h736z" />
-    <glyph glyph-name="bullseye" unicode="&#xf140;" 
-d="M1024 640q0 -106 -75 -181t-181 -75t-181 75t-75 181t75 181t181 75t181 -75t75 -181zM1152 640q0 159 -112.5 271.5t-271.5 112.5t-271.5 -112.5t-112.5 -271.5t112.5 -271.5t271.5 -112.5t271.5 112.5t112.5 271.5zM1280 640q0 -212 -150 -362t-362 -150t-362 150
-t-150 362t150 362t362 150t362 -150t150 -362zM1408 640q0 130 -51 248.5t-136.5 204t-204 136.5t-248.5 51t-248.5 -51t-204 -136.5t-136.5 -204t-51 -248.5t51 -248.5t136.5 -204t204 -136.5t248.5 -51t248.5 51t204 136.5t136.5 204t51 248.5zM1536 640
-q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
-    <glyph glyph-name="ellipsis_horizontal" unicode="&#xf141;" horiz-adv-x="1408" 
-d="M384 800v-192q0 -40 -28 -68t-68 -28h-192q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h192q40 0 68 -28t28 -68zM896 800v-192q0 -40 -28 -68t-68 -28h-192q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h192q40 0 68 -28t28 -68zM1408 800v-192q0 -40 -28 -68t-68 -28h-192
-q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h192q40 0 68 -28t28 -68z" />
-    <glyph glyph-name="ellipsis_vertical" unicode="&#xf142;" horiz-adv-x="384" 
-d="M384 288v-192q0 -40 -28 -68t-68 -28h-192q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h192q40 0 68 -28t28 -68zM384 800v-192q0 -40 -28 -68t-68 -28h-192q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h192q40 0 68 -28t28 -68zM384 1312v-192q0 -40 -28 -68t-68 -28h-192
-q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h192q40 0 68 -28t28 -68z" />
-    <glyph glyph-name="_303" unicode="&#xf143;" 
-d="M512 256q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM863 162q-13 233 -176.5 396.5t-396.5 176.5q-14 1 -24 -9t-10 -23v-128q0 -13 8.5 -22t21.5 -10q154 -11 264 -121t121 -264q1 -13 10 -21.5t22 -8.5h128
-q13 0 23 10t9 24zM1247 161q-5 154 -56 297.5t-139.5 260t-205 205t-260 139.5t-297.5 56q-14 1 -23 -9q-10 -10 -10 -23v-128q0 -13 9 -22t22 -10q204 -7 378 -111.5t278.5 -278.5t111.5 -378q1 -13 10 -22t22 -9h128q13 0 23 10q11 9 9 23zM1536 1120v-960
-q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
-    <glyph glyph-name="play_sign" unicode="&#xf144;" 
-d="M768 1408q209 0 385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103zM1152 585q32 18 32 55t-32 55l-544 320q-31 19 -64 1q-32 -19 -32 -56v-640q0 -37 32 -56
-q16 -8 32 -8q17 0 32 9z" />
-    <glyph glyph-name="ticket" unicode="&#xf145;" horiz-adv-x="1792" 
-d="M1024 1084l316 -316l-572 -572l-316 316zM813 105l618 618q19 19 19 45t-19 45l-362 362q-18 18 -45 18t-45 -18l-618 -618q-19 -19 -19 -45t19 -45l362 -362q18 -18 45 -18t45 18zM1702 742l-907 -908q-37 -37 -90.5 -37t-90.5 37l-126 126q56 56 56 136t-56 136
-t-136 56t-136 -56l-125 126q-37 37 -37 90.5t37 90.5l907 906q37 37 90.5 37t90.5 -37l125 -125q-56 -56 -56 -136t56 -136t136 -56t136 56l126 -125q37 -37 37 -90.5t-37 -90.5z" />
-    <glyph glyph-name="minus_sign_alt" unicode="&#xf146;" 
-d="M1280 576v128q0 26 -19 45t-45 19h-896q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45t45 -19h896q26 0 45 19t19 45zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5
-t84.5 -203.5z" />
-    <glyph glyph-name="check_minus" unicode="&#xf147;" horiz-adv-x="1408" 
-d="M1152 736v-64q0 -14 -9 -23t-23 -9h-832q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h832q14 0 23 -9t9 -23zM1280 288v832q0 66 -47 113t-113 47h-832q-66 0 -113 -47t-47 -113v-832q0 -66 47 -113t113 -47h832q66 0 113 47t47 113zM1408 1120v-832q0 -119 -84.5 -203.5
-t-203.5 -84.5h-832q-119 0 -203.5 84.5t-84.5 203.5v832q0 119 84.5 203.5t203.5 84.5h832q119 0 203.5 -84.5t84.5 -203.5z" />
-    <glyph glyph-name="level_up" unicode="&#xf148;" horiz-adv-x="1024" 
-d="M1018 933q-18 -37 -58 -37h-192v-864q0 -14 -9 -23t-23 -9h-704q-21 0 -29 18q-8 20 4 35l160 192q9 11 25 11h320v640h-192q-40 0 -58 37q-17 37 9 68l320 384q18 22 49 22t49 -22l320 -384q27 -32 9 -68z" />
-    <glyph glyph-name="level_down" unicode="&#xf149;" horiz-adv-x="1024" 
-d="M32 1280h704q13 0 22.5 -9.5t9.5 -23.5v-863h192q40 0 58 -37t-9 -69l-320 -384q-18 -22 -49 -22t-49 22l-320 384q-26 31 -9 69q18 37 58 37h192v640h-320q-14 0 -25 11l-160 192q-13 14 -4 34q9 19 29 19z" />
-    <glyph glyph-name="check_sign" unicode="&#xf14a;" 
-d="M685 237l614 614q19 19 19 45t-19 45l-102 102q-19 19 -45 19t-45 -19l-467 -467l-211 211q-19 19 -45 19t-45 -19l-102 -102q-19 -19 -19 -45t19 -45l358 -358q19 -19 45 -19t45 19zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5
-t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
-    <glyph glyph-name="edit_sign" unicode="&#xf14b;" 
-d="M404 428l152 -152l-52 -52h-56v96h-96v56zM818 818q14 -13 -3 -30l-291 -291q-17 -17 -30 -3q-14 13 3 30l291 291q17 17 30 3zM544 128l544 544l-288 288l-544 -544v-288h288zM1152 736l92 92q28 28 28 68t-28 68l-152 152q-28 28 -68 28t-68 -28l-92 -92zM1536 1120
-v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
-    <glyph glyph-name="_312" unicode="&#xf14c;" 
-d="M1280 608v480q0 26 -19 45t-45 19h-480q-42 0 -59 -39q-17 -41 14 -70l144 -144l-534 -534q-19 -19 -19 -45t19 -45l102 -102q19 -19 45 -19t45 19l534 534l144 -144q18 -19 45 -19q12 0 25 5q39 17 39 59zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960
-q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
-    <glyph glyph-name="share_sign" unicode="&#xf14d;" 
-d="M1005 435l352 352q19 19 19 45t-19 45l-352 352q-30 31 -69 14q-40 -17 -40 -59v-160q-119 0 -216 -19.5t-162.5 -51t-114 -79t-76.5 -95.5t-44.5 -109t-21.5 -111.5t-5 -110.5q0 -181 167 -404q11 -12 25 -12q7 0 13 3q22 9 19 33q-44 354 62 473q46 52 130 75.5
-t224 23.5v-160q0 -42 40 -59q12 -5 24 -5q26 0 45 19zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
-    <glyph glyph-name="compass" unicode="&#xf14e;" 
-d="M640 448l256 128l-256 128v-256zM1024 1039v-542l-512 -256v542zM1312 640q0 148 -73 273t-198 198t-273 73t-273 -73t-198 -198t-73 -273t73 -273t198 -198t273 -73t273 73t198 198t73 273zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103
-t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
-    <glyph glyph-name="collapse" unicode="&#xf150;" 
-d="M1145 861q18 -35 -5 -66l-320 -448q-19 -27 -52 -27t-52 27l-320 448q-23 31 -5 66q17 35 57 35h640q40 0 57 -35zM1280 160v960q0 13 -9.5 22.5t-22.5 9.5h-960q-13 0 -22.5 -9.5t-9.5 -22.5v-960q0 -13 9.5 -22.5t22.5 -9.5h960q13 0 22.5 9.5t9.5 22.5zM1536 1120
-v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
-    <glyph glyph-name="collapse_top" unicode="&#xf151;" 
-d="M1145 419q-17 -35 -57 -35h-640q-40 0 -57 35q-18 35 5 66l320 448q19 27 52 27t52 -27l320 -448q23 -31 5 -66zM1280 160v960q0 13 -9.5 22.5t-22.5 9.5h-960q-13 0 -22.5 -9.5t-9.5 -22.5v-960q0 -13 9.5 -22.5t22.5 -9.5h960q13 0 22.5 9.5t9.5 22.5zM1536 1120v-960
-q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
-    <glyph glyph-name="_317" unicode="&#xf152;" 
-d="M1088 640q0 -33 -27 -52l-448 -320q-31 -23 -66 -5q-35 17 -35 57v640q0 40 35 57q35 18 66 -5l448 -320q27 -19 27 -52zM1280 160v960q0 14 -9 23t-23 9h-960q-14 0 -23 -9t-9 -23v-960q0 -14 9 -23t23 -9h960q14 0 23 9t9 23zM1536 1120v-960q0 -119 -84.5 -203.5
-t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
-    <glyph glyph-name="eur" unicode="&#xf153;" horiz-adv-x="1024" 
-d="M976 229l35 -159q3 -12 -3 -22.5t-17 -14.5l-5 -1q-4 -2 -10.5 -3.5t-16 -4.5t-21.5 -5.5t-25.5 -5t-30 -5t-33.5 -4.5t-36.5 -3t-38.5 -1q-234 0 -409 130.5t-238 351.5h-95q-13 0 -22.5 9.5t-9.5 22.5v113q0 13 9.5 22.5t22.5 9.5h66q-2 57 1 105h-67q-14 0 -23 9
-t-9 23v114q0 14 9 23t23 9h98q67 210 243.5 338t400.5 128q102 0 194 -23q11 -3 20 -15q6 -11 3 -24l-43 -159q-3 -13 -14 -19.5t-24 -2.5l-4 1q-4 1 -11.5 2.5l-17.5 3.5t-22.5 3.5t-26 3t-29 2.5t-29.5 1q-126 0 -226 -64t-150 -176h468q16 0 25 -12q10 -12 7 -26
-l-24 -114q-5 -26 -32 -26h-488q-3 -37 0 -105h459q15 0 25 -12q9 -12 6 -27l-24 -112q-2 -11 -11 -18.5t-20 -7.5h-387q48 -117 149.5 -185.5t228.5 -68.5q18 0 36 1.5t33.5 3.5t29.5 4.5t24.5 5t18.5 4.5l12 3l5 2q13 5 26 -2q12 -7 15 -21z" />
-    <glyph glyph-name="gbp" unicode="&#xf154;" horiz-adv-x="1024" 
-d="M1020 399v-367q0 -14 -9 -23t-23 -9h-956q-14 0 -23 9t-9 23v150q0 13 9.5 22.5t22.5 9.5h97v383h-95q-14 0 -23 9.5t-9 22.5v131q0 14 9 23t23 9h95v223q0 171 123.5 282t314.5 111q185 0 335 -125q9 -8 10 -20.5t-7 -22.5l-103 -127q-9 -11 -22 -12q-13 -2 -23 7
-q-5 5 -26 19t-69 32t-93 18q-85 0 -137 -47t-52 -123v-215h305q13 0 22.5 -9t9.5 -23v-131q0 -13 -9.5 -22.5t-22.5 -9.5h-305v-379h414v181q0 13 9 22.5t23 9.5h162q14 0 23 -9.5t9 -22.5z" />
-    <glyph glyph-name="usd" unicode="&#xf155;" horiz-adv-x="1024" 
-d="M978 351q0 -153 -99.5 -263.5t-258.5 -136.5v-175q0 -14 -9 -23t-23 -9h-135q-13 0 -22.5 9.5t-9.5 22.5v175q-66 9 -127.5 31t-101.5 44.5t-74 48t-46.5 37.5t-17.5 18q-17 21 -2 41l103 135q7 10 23 12q15 2 24 -9l2 -2q113 -99 243 -125q37 -8 74 -8q81 0 142.5 43
-t61.5 122q0 28 -15 53t-33.5 42t-58.5 37.5t-66 32t-80 32.5q-39 16 -61.5 25t-61.5 26.5t-62.5 31t-56.5 35.5t-53.5 42.5t-43.5 49t-35.5 58t-21 66.5t-8.5 78q0 138 98 242t255 134v180q0 13 9.5 22.5t22.5 9.5h135q14 0 23 -9t9 -23v-176q57 -6 110.5 -23t87 -33.5
-t63.5 -37.5t39 -29t15 -14q17 -18 5 -38l-81 -146q-8 -15 -23 -16q-14 -3 -27 7q-3 3 -14.5 12t-39 26.5t-58.5 32t-74.5 26t-85.5 11.5q-95 0 -155 -43t-60 -111q0 -26 8.5 -48t29.5 -41.5t39.5 -33t56 -31t60.5 -27t70 -27.5q53 -20 81 -31.5t76 -35t75.5 -42.5t62 -50
-t53 -63.5t31.5 -76.5t13 -94z" />
-    <glyph glyph-name="inr" unicode="&#xf156;" horiz-adv-x="898" 
-d="M898 1066v-102q0 -14 -9 -23t-23 -9h-168q-23 -144 -129 -234t-276 -110q167 -178 459 -536q14 -16 4 -34q-8 -18 -29 -18h-195q-16 0 -25 12q-306 367 -498 571q-9 9 -9 22v127q0 13 9.5 22.5t22.5 9.5h112q132 0 212.5 43t102.5 125h-427q-14 0 -23 9t-9 23v102
-q0 14 9 23t23 9h413q-57 113 -268 113h-145q-13 0 -22.5 9.5t-9.5 22.5v133q0 14 9 23t23 9h832q14 0 23 -9t9 -23v-102q0 -14 -9 -23t-23 -9h-233q47 -61 64 -144h171q14 0 23 -9t9 -23z" />
-    <glyph glyph-name="jpy" unicode="&#xf157;" horiz-adv-x="1027" 
-d="M603 0h-172q-13 0 -22.5 9t-9.5 23v330h-288q-13 0 -22.5 9t-9.5 23v103q0 13 9.5 22.5t22.5 9.5h288v85h-288q-13 0 -22.5 9t-9.5 23v104q0 13 9.5 22.5t22.5 9.5h214l-321 578q-8 16 0 32q10 16 28 16h194q19 0 29 -18l215 -425q19 -38 56 -125q10 24 30.5 68t27.5 61
-l191 420q8 19 29 19h191q17 0 27 -16q9 -14 1 -31l-313 -579h215q13 0 22.5 -9.5t9.5 -22.5v-104q0 -14 -9.5 -23t-22.5 -9h-290v-85h290q13 0 22.5 -9.5t9.5 -22.5v-103q0 -14 -9.5 -23t-22.5 -9h-290v-330q0 -13 -9.5 -22.5t-22.5 -9.5z" />
-    <glyph glyph-name="rub" unicode="&#xf158;" horiz-adv-x="1280" 
-d="M1043 971q0 100 -65 162t-171 62h-320v-448h320q106 0 171 62t65 162zM1280 971q0 -193 -126.5 -315t-326.5 -122h-340v-118h505q14 0 23 -9t9 -23v-128q0 -14 -9 -23t-23 -9h-505v-192q0 -14 -9.5 -23t-22.5 -9h-167q-14 0 -23 9t-9 23v192h-224q-14 0 -23 9t-9 23v128
-q0 14 9 23t23 9h224v118h-224q-14 0 -23 9t-9 23v149q0 13 9 22.5t23 9.5h224v629q0 14 9 23t23 9h539q200 0 326.5 -122t126.5 -315z" />
-    <glyph glyph-name="krw" unicode="&#xf159;" horiz-adv-x="1792" 
-d="M514 341l81 299h-159l75 -300q1 -1 1 -3t1 -3q0 1 0.5 3.5t0.5 3.5zM630 768l35 128h-292l32 -128h225zM822 768h139l-35 128h-70zM1271 340l78 300h-162l81 -299q0 -1 0.5 -3.5t1.5 -3.5q0 1 0.5 3t0.5 3zM1382 768l33 128h-297l34 -128h230zM1792 736v-64q0 -14 -9 -23
-t-23 -9h-213l-164 -616q-7 -24 -31 -24h-159q-24 0 -31 24l-166 616h-209l-167 -616q-7 -24 -31 -24h-159q-11 0 -19.5 7t-10.5 17l-160 616h-208q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h175l-33 128h-142q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h109l-89 344q-5 15 5 28
-q10 12 26 12h137q26 0 31 -24l90 -360h359l97 360q7 24 31 24h126q24 0 31 -24l98 -360h365l93 360q5 24 31 24h137q16 0 26 -12q10 -13 5 -28l-91 -344h111q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-145l-34 -128h179q14 0 23 -9t9 -23z" />
-    <glyph glyph-name="btc" unicode="&#xf15a;" horiz-adv-x="1280" 
-d="M1167 896q18 -182 -131 -258q117 -28 175 -103t45 -214q-7 -71 -32.5 -125t-64.5 -89t-97 -58.5t-121.5 -34.5t-145.5 -15v-255h-154v251q-80 0 -122 1v-252h-154v255q-18 0 -54 0.5t-55 0.5h-200l31 183h111q50 0 58 51v402h16q-6 1 -16 1v287q-13 68 -89 68h-111v164
-l212 -1q64 0 97 1v252h154v-247q82 2 122 2v245h154v-252q79 -7 140 -22.5t113 -45t82.5 -78t36.5 -114.5zM952 351q0 36 -15 64t-37 46t-57.5 30.5t-65.5 18.5t-74 9t-69 3t-64.5 -1t-47.5 -1v-338q8 0 37 -0.5t48 -0.5t53 1.5t58.5 4t57 8.5t55.5 14t47.5 21t39.5 30
-t24.5 40t9.5 51zM881 827q0 33 -12.5 58.5t-30.5 42t-48 28t-55 16.5t-61.5 8t-58 2.5t-54 -1t-39.5 -0.5v-307q5 0 34.5 -0.5t46.5 0t50 2t55 5.5t51.5 11t48.5 18.5t37 27t27 38.5t9 51z" />
-    <glyph glyph-name="file" unicode="&#xf15b;" 
-d="M1024 1024v472q22 -14 36 -28l408 -408q14 -14 28 -36h-472zM896 992q0 -40 28 -68t68 -28h544v-1056q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68v1600q0 40 28 68t68 28h800v-544z" />
-    <glyph glyph-name="file_text" unicode="&#xf15c;" 
-d="M1468 1060q14 -14 28 -36h-472v472q22 -14 36 -28zM992 896h544v-1056q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68v1600q0 40 28 68t68 28h800v-544q0 -40 28 -68t68 -28zM1152 160v64q0 14 -9 23t-23 9h-704q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h704
-q14 0 23 9t9 23zM1152 416v64q0 14 -9 23t-23 9h-704q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h704q14 0 23 9t9 23zM1152 672v64q0 14 -9 23t-23 9h-704q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h704q14 0 23 9t9 23z" />
-    <glyph glyph-name="sort_by_alphabet" unicode="&#xf15d;" horiz-adv-x="1664" 
-d="M1191 1128h177l-72 218l-12 47q-2 16 -2 20h-4l-3 -20q0 -1 -3.5 -18t-7.5 -29zM736 96q0 -12 -10 -24l-319 -319q-10 -9 -23 -9q-12 0 -23 9l-320 320q-15 16 -7 35q8 20 30 20h192v1376q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-1376h192q14 0 23 -9t9 -23zM1572 -23
-v-233h-584v90l369 529q12 18 21 27l11 9v3q-2 0 -6.5 -0.5t-7.5 -0.5q-12 -3 -30 -3h-232v-115h-120v229h567v-89l-369 -530q-6 -8 -21 -26l-11 -11v-2l14 2q9 2 30 2h248v119h121zM1661 874v-106h-288v106h75l-47 144h-243l-47 -144h75v-106h-287v106h70l230 662h162
-l230 -662h70z" />
-    <glyph glyph-name="_329" unicode="&#xf15e;" horiz-adv-x="1664" 
-d="M1191 104h177l-72 218l-12 47q-2 16 -2 20h-4l-3 -20q0 -1 -3.5 -18t-7.5 -29zM736 96q0 -12 -10 -24l-319 -319q-10 -9 -23 -9q-12 0 -23 9l-320 320q-15 16 -7 35q8 20 30 20h192v1376q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-1376h192q14 0 23 -9t9 -23zM1661 -150
-v-106h-288v106h75l-47 144h-243l-47 -144h75v-106h-287v106h70l230 662h162l230 -662h70zM1572 1001v-233h-584v90l369 529q12 18 21 27l11 9v3q-2 0 -6.5 -0.5t-7.5 -0.5q-12 -3 -30 -3h-232v-115h-120v229h567v-89l-369 -530q-6 -8 -21 -26l-11 -10v-3l14 3q9 1 30 1h248
-v119h121z" />
-    <glyph glyph-name="sort_by_attributes" unicode="&#xf160;" horiz-adv-x="1792" 
-d="M736 96q0 -12 -10 -24l-319 -319q-10 -9 -23 -9q-12 0 -23 9l-320 320q-15 16 -7 35q8 20 30 20h192v1376q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-1376h192q14 0 23 -9t9 -23zM1792 -32v-192q0 -14 -9 -23t-23 -9h-832q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h832
-q14 0 23 -9t9 -23zM1600 480v-192q0 -14 -9 -23t-23 -9h-640q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h640q14 0 23 -9t9 -23zM1408 992v-192q0 -14 -9 -23t-23 -9h-448q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h448q14 0 23 -9t9 -23zM1216 1504v-192q0 -14 -9 -23t-23 -9h-256
-q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h256q14 0 23 -9t9 -23z" />
-    <glyph glyph-name="sort_by_attributes_alt" unicode="&#xf161;" horiz-adv-x="1792" 
-d="M1216 -32v-192q0 -14 -9 -23t-23 -9h-256q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h256q14 0 23 -9t9 -23zM736 96q0 -12 -10 -24l-319 -319q-10 -9 -23 -9q-12 0 -23 9l-320 320q-15 16 -7 35q8 20 30 20h192v1376q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-1376h192
-q14 0 23 -9t9 -23zM1408 480v-192q0 -14 -9 -23t-23 -9h-448q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h448q14 0 23 -9t9 -23zM1600 992v-192q0 -14 -9 -23t-23 -9h-640q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h640q14 0 23 -9t9 -23zM1792 1504v-192q0 -14 -9 -23t-23 -9h-832
-q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h832q14 0 23 -9t9 -23z" />
-    <glyph glyph-name="sort_by_order" unicode="&#xf162;" 
-d="M1346 223q0 63 -44 116t-103 53q-52 0 -83 -37t-31 -94t36.5 -95t104.5 -38q50 0 85 27t35 68zM736 96q0 -12 -10 -24l-319 -319q-10 -9 -23 -9q-12 0 -23 9l-320 320q-15 16 -7 35q8 20 30 20h192v1376q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-1376h192q14 0 23 -9t9 -23
-zM1486 165q0 -62 -13 -121.5t-41 -114t-68 -95.5t-98.5 -65.5t-127.5 -24.5q-62 0 -108 16q-24 8 -42 15l39 113q15 -7 31 -11q37 -13 75 -13q84 0 134.5 58.5t66.5 145.5h-2q-21 -23 -61.5 -37t-84.5 -14q-106 0 -173 71.5t-67 172.5q0 105 72 178t181 73q123 0 205 -94.5
-t82 -252.5zM1456 882v-114h-469v114h167v432q0 7 0.5 19t0.5 17v16h-2l-7 -12q-8 -13 -26 -31l-62 -58l-82 86l192 185h123v-654h165z" />
-    <glyph glyph-name="sort_by_order_alt" unicode="&#xf163;" 
-d="M1346 1247q0 63 -44 116t-103 53q-52 0 -83 -37t-31 -94t36.5 -95t104.5 -38q50 0 85 27t35 68zM736 96q0 -12 -10 -24l-319 -319q-10 -9 -23 -9q-12 0 -23 9l-320 320q-15 16 -7 35q8 20 30 20h192v1376q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-1376h192q14 0 23 -9
-t9 -23zM1456 -142v-114h-469v114h167v432q0 7 0.5 19t0.5 17v16h-2l-7 -12q-8 -13 -26 -31l-62 -58l-82 86l192 185h123v-654h165zM1486 1189q0 -62 -13 -121.5t-41 -114t-68 -95.5t-98.5 -65.5t-127.5 -24.5q-62 0 -108 16q-24 8 -42 15l39 113q15 -7 31 -11q37 -13 75 -13
-q84 0 134.5 58.5t66.5 145.5h-2q-21 -23 -61.5 -37t-84.5 -14q-106 0 -173 71.5t-67 172.5q0 105 72 178t181 73q123 0 205 -94.5t82 -252.5z" />
-    <glyph glyph-name="_334" unicode="&#xf164;" horiz-adv-x="1664" 
-d="M256 192q0 26 -19 45t-45 19q-27 0 -45.5 -19t-18.5 -45q0 -27 18.5 -45.5t45.5 -18.5q26 0 45 18.5t19 45.5zM416 704v-640q0 -26 -19 -45t-45 -19h-288q-26 0 -45 19t-19 45v640q0 26 19 45t45 19h288q26 0 45 -19t19 -45zM1600 704q0 -86 -55 -149q15 -44 15 -76
-q3 -76 -43 -137q17 -56 0 -117q-15 -57 -54 -94q9 -112 -49 -181q-64 -76 -197 -78h-36h-76h-17q-66 0 -144 15.5t-121.5 29t-120.5 39.5q-123 43 -158 44q-26 1 -45 19.5t-19 44.5v641q0 25 18 43.5t43 20.5q24 2 76 59t101 121q68 87 101 120q18 18 31 48t17.5 48.5
-t13.5 60.5q7 39 12.5 61t19.5 52t34 50q19 19 45 19q46 0 82.5 -10.5t60 -26t40 -40.5t24 -45t12 -50t5 -45t0.5 -39q0 -38 -9.5 -76t-19 -60t-27.5 -56q-3 -6 -10 -18t-11 -22t-8 -24h277q78 0 135 -57t57 -135z" />
-    <glyph glyph-name="_335" unicode="&#xf165;" horiz-adv-x="1664" 
-d="M256 960q0 -26 -19 -45t-45 -19q-27 0 -45.5 19t-18.5 45q0 27 18.5 45.5t45.5 18.5q26 0 45 -18.5t19 -45.5zM416 448v640q0 26 -19 45t-45 19h-288q-26 0 -45 -19t-19 -45v-640q0 -26 19 -45t45 -19h288q26 0 45 19t19 45zM1545 597q55 -61 55 -149q-1 -78 -57.5 -135
-t-134.5 -57h-277q4 -14 8 -24t11 -22t10 -18q18 -37 27 -57t19 -58.5t10 -76.5q0 -24 -0.5 -39t-5 -45t-12 -50t-24 -45t-40 -40.5t-60 -26t-82.5 -10.5q-26 0 -45 19q-20 20 -34 50t-19.5 52t-12.5 61q-9 42 -13.5 60.5t-17.5 48.5t-31 48q-33 33 -101 120q-49 64 -101 121
-t-76 59q-25 2 -43 20.5t-18 43.5v641q0 26 19 44.5t45 19.5q35 1 158 44q77 26 120.5 39.5t121.5 29t144 15.5h17h76h36q133 -2 197 -78q58 -69 49 -181q39 -37 54 -94q17 -61 0 -117q46 -61 43 -137q0 -32 -15 -76z" />
-    <glyph glyph-name="youtube_sign" unicode="&#xf166;" 
-d="M919 233v157q0 50 -29 50q-17 0 -33 -16v-224q16 -16 33 -16q29 0 29 49zM1103 355h66v34q0 51 -33 51t-33 -51v-34zM532 621v-70h-80v-423h-74v423h-78v70h232zM733 495v-367h-67v40q-39 -45 -76 -45q-33 0 -42 28q-6 17 -6 54v290h66v-270q0 -24 1 -26q1 -15 15 -15
-q20 0 42 31v280h67zM985 384v-146q0 -52 -7 -73q-12 -42 -53 -42q-35 0 -68 41v-36h-67v493h67v-161q32 40 68 40q41 0 53 -42q7 -21 7 -74zM1236 255v-9q0 -29 -2 -43q-3 -22 -15 -40q-27 -40 -80 -40q-52 0 -81 38q-21 27 -21 86v129q0 59 20 86q29 38 80 38t78 -38
-q21 -29 21 -86v-76h-133v-65q0 -51 34 -51q24 0 30 26q0 1 0.5 7t0.5 16.5v21.5h68zM785 1079v-156q0 -51 -32 -51t-32 51v156q0 52 32 52t32 -52zM1318 366q0 177 -19 260q-10 44 -43 73.5t-76 34.5q-136 15 -412 15q-275 0 -411 -15q-44 -5 -76.5 -34.5t-42.5 -73.5
-q-20 -87 -20 -260q0 -176 20 -260q10 -43 42.5 -73t75.5 -35q137 -15 412 -15t412 15q43 5 75.5 35t42.5 73q20 84 20 260zM563 1017l90 296h-75l-51 -195l-53 195h-78q7 -23 23 -69l24 -69q35 -103 46 -158v-201h74v201zM852 936v130q0 58 -21 87q-29 38 -78 38
-q-51 0 -78 -38q-21 -29 -21 -87v-130q0 -58 21 -87q27 -38 78 -38q49 0 78 38q21 27 21 87zM1033 816h67v370h-67v-283q-22 -31 -42 -31q-15 0 -16 16q-1 2 -1 26v272h-67v-293q0 -37 6 -55q11 -27 43 -27q36 0 77 45v-40zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5
-h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
-    <glyph glyph-name="youtube" unicode="&#xf167;" 
-d="M971 292v-211q0 -67 -39 -67q-23 0 -45 22v301q22 22 45 22q39 0 39 -67zM1309 291v-46h-90v46q0 68 45 68t45 -68zM343 509h107v94h-312v-94h105v-569h100v569zM631 -60h89v494h-89v-378q-30 -42 -57 -42q-18 0 -21 21q-1 3 -1 35v364h-89v-391q0 -49 8 -73
-q12 -37 58 -37q48 0 102 61v-54zM1060 88v197q0 73 -9 99q-17 56 -71 56q-50 0 -93 -54v217h-89v-663h89v48q45 -55 93 -55q54 0 71 55q9 27 9 100zM1398 98v13h-91q0 -51 -2 -61q-7 -36 -40 -36q-46 0 -46 69v87h179v103q0 79 -27 116q-39 51 -106 51q-68 0 -107 -51
-q-28 -37 -28 -116v-173q0 -79 29 -116q39 -51 108 -51q72 0 108 53q18 27 21 54q2 9 2 58zM790 1011v210q0 69 -43 69t-43 -69v-210q0 -70 43 -70t43 70zM1509 260q0 -234 -26 -350q-14 -59 -58 -99t-102 -46q-184 -21 -555 -21t-555 21q-58 6 -102.5 46t-57.5 99
-q-26 112 -26 350q0 234 26 350q14 59 58 99t103 47q183 20 554 20t555 -20q58 -7 102.5 -47t57.5 -99q26 -112 26 -350zM511 1536h102l-121 -399v-271h-100v271q-14 74 -61 212q-37 103 -65 187h106l71 -263zM881 1203v-175q0 -81 -28 -118q-38 -51 -106 -51q-67 0 -105 51
-q-28 38 -28 118v175q0 80 28 117q38 51 105 51q68 0 106 -51q28 -37 28 -117zM1216 1365v-499h-91v55q-53 -62 -103 -62q-46 0 -59 37q-8 24 -8 75v394h91v-367q0 -33 1 -35q3 -22 21 -22q27 0 57 43v381h91z" />
-    <glyph glyph-name="xing" unicode="&#xf168;" horiz-adv-x="1408" 
-d="M597 869q-10 -18 -257 -456q-27 -46 -65 -46h-239q-21 0 -31 17t0 36l253 448q1 0 0 1l-161 279q-12 22 -1 37q9 15 32 15h239q40 0 66 -45zM1403 1511q11 -16 0 -37l-528 -934v-1l336 -615q11 -20 1 -37q-10 -15 -32 -15h-239q-42 0 -66 45l-339 622q18 32 531 942
-q25 45 64 45h241q22 0 31 -15z" />
-    <glyph glyph-name="xing_sign" unicode="&#xf169;" 
-d="M685 771q0 1 -126 222q-21 34 -52 34h-184q-18 0 -26 -11q-7 -12 1 -29l125 -216v-1l-196 -346q-9 -14 0 -28q8 -13 24 -13h185q31 0 50 36zM1309 1268q-7 12 -24 12h-187q-30 0 -49 -35l-411 -729q1 -2 262 -481q20 -35 52 -35h184q18 0 25 12q8 13 -1 28l-260 476v1
-l409 723q8 16 0 28zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
-    <glyph glyph-name="youtube_play" unicode="&#xf16a;" horiz-adv-x="1792" 
-d="M711 408l484 250l-484 253v-503zM896 1270q168 0 324.5 -4.5t229.5 -9.5l73 -4q1 0 17 -1.5t23 -3t23.5 -4.5t28.5 -8t28 -13t31 -19.5t29 -26.5q6 -6 15.5 -18.5t29 -58.5t26.5 -101q8 -64 12.5 -136.5t5.5 -113.5v-40v-136q1 -145 -18 -290q-7 -55 -25 -99.5t-32 -61.5
-l-14 -17q-14 -15 -29 -26.5t-31 -19t-28 -12.5t-28.5 -8t-24 -4.5t-23 -3t-16.5 -1.5q-251 -19 -627 -19q-207 2 -359.5 6.5t-200.5 7.5l-49 4l-36 4q-36 5 -54.5 10t-51 21t-56.5 41q-6 6 -15.5 18.5t-29 58.5t-26.5 101q-8 64 -12.5 136.5t-5.5 113.5v40v136
-q-1 145 18 290q7 55 25 99.5t32 61.5l14 17q14 15 29 26.5t31 19.5t28 13t28.5 8t23.5 4.5t23 3t17 1.5q251 18 627 18z" />
-    <glyph glyph-name="dropbox" unicode="&#xf16b;" horiz-adv-x="1792" 
-d="M402 829l494 -305l-342 -285l-490 319zM1388 274v-108l-490 -293v-1l-1 1l-1 -1v1l-489 293v108l147 -96l342 284v2l1 -1l1 1v-2l343 -284zM554 1418l342 -285l-494 -304l-338 270zM1390 829l338 -271l-489 -319l-343 285zM1239 1418l489 -319l-338 -270l-494 304z" />
-    <glyph glyph-name="stackexchange" unicode="&#xf16c;" 
-d="M1289 -96h-1118v480h-160v-640h1438v640h-160v-480zM347 428l33 157l783 -165l-33 -156zM450 802l67 146l725 -339l-67 -145zM651 1158l102 123l614 -513l-102 -123zM1048 1536l477 -641l-128 -96l-477 641zM330 65v159h800v-159h-800z" />
-    <glyph glyph-name="instagram" unicode="&#xf16d;" 
-d="M1024 640q0 106 -75 181t-181 75t-181 -75t-75 -181t75 -181t181 -75t181 75t75 181zM1162 640q0 -164 -115 -279t-279 -115t-279 115t-115 279t115 279t279 115t279 -115t115 -279zM1270 1050q0 -38 -27 -65t-65 -27t-65 27t-27 65t27 65t65 27t65 -27t27 -65zM768 1270
-q-7 0 -76.5 0.5t-105.5 0t-96.5 -3t-103 -10t-71.5 -18.5q-50 -20 -88 -58t-58 -88q-11 -29 -18.5 -71.5t-10 -103t-3 -96.5t0 -105.5t0.5 -76.5t-0.5 -76.5t0 -105.5t3 -96.5t10 -103t18.5 -71.5q20 -50 58 -88t88 -58q29 -11 71.5 -18.5t103 -10t96.5 -3t105.5 0t76.5 0.5
-t76.5 -0.5t105.5 0t96.5 3t103 10t71.5 18.5q50 20 88 58t58 88q11 29 18.5 71.5t10 103t3 96.5t0 105.5t-0.5 76.5t0.5 76.5t0 105.5t-3 96.5t-10 103t-18.5 71.5q-20 50 -58 88t-88 58q-29 11 -71.5 18.5t-103 10t-96.5 3t-105.5 0t-76.5 -0.5zM1536 640q0 -229 -5 -317
-q-10 -208 -124 -322t-322 -124q-88 -5 -317 -5t-317 5q-208 10 -322 124t-124 322q-5 88 -5 317t5 317q10 208 124 322t322 124q88 5 317 5t317 -5q208 -10 322 -124t124 -322q5 -88 5 -317z" />
-    <glyph glyph-name="flickr" unicode="&#xf16e;" 
-d="M1248 1408q119 0 203.5 -84.5t84.5 -203.5v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960zM698 640q0 88 -62 150t-150 62t-150 -62t-62 -150t62 -150t150 -62t150 62t62 150zM1262 640q0 88 -62 150
-t-150 62t-150 -62t-62 -150t62 -150t150 -62t150 62t62 150z" />
-    <glyph glyph-name="adn" unicode="&#xf170;" 
-d="M768 914l201 -306h-402zM1133 384h94l-459 691l-459 -691h94l104 160h522zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
-    <glyph glyph-name="f171" unicode="&#xf171;" horiz-adv-x="1408" 
-d="M815 677q8 -63 -50.5 -101t-111.5 -6q-39 17 -53.5 58t-0.5 82t52 58q36 18 72.5 12t64 -35.5t27.5 -67.5zM926 698q-14 107 -113 164t-197 13q-63 -28 -100.5 -88.5t-34.5 -129.5q4 -91 77.5 -155t165.5 -56q91 8 152 84t50 168zM1165 1240q-20 27 -56 44.5t-58 22
-t-71 12.5q-291 47 -566 -2q-43 -7 -66 -12t-55 -22t-50 -43q30 -28 76 -45.5t73.5 -22t87.5 -11.5q228 -29 448 -1q63 8 89.5 12t72.5 21.5t75 46.5zM1222 205q-8 -26 -15.5 -76.5t-14 -84t-28.5 -70t-58 -56.5q-86 -48 -189.5 -71.5t-202 -22t-201.5 18.5q-46 8 -81.5 18
-t-76.5 27t-73 43.5t-52 61.5q-25 96 -57 292l6 16l18 9q223 -148 506.5 -148t507.5 148q21 -6 24 -23t-5 -45t-8 -37zM1403 1166q-26 -167 -111 -655q-5 -30 -27 -56t-43.5 -40t-54.5 -31q-252 -126 -610 -88q-248 27 -394 139q-15 12 -25.5 26.5t-17 35t-9 34t-6 39.5
-t-5.5 35q-9 50 -26.5 150t-28 161.5t-23.5 147.5t-22 158q3 26 17.5 48.5t31.5 37.5t45 30t46 22.5t48 18.5q125 46 313 64q379 37 676 -50q155 -46 215 -122q16 -20 16.5 -51t-5.5 -54z" />
-    <glyph glyph-name="bitbucket_sign" unicode="&#xf172;" 
-d="M848 666q0 43 -41 66t-77 1q-43 -20 -42.5 -72.5t43.5 -70.5q39 -23 81 4t36 72zM928 682q8 -66 -36 -121t-110 -61t-119 40t-56 113q-2 49 25.5 93t72.5 64q70 31 141.5 -10t81.5 -118zM1100 1073q-20 -21 -53.5 -34t-53 -16t-63.5 -8q-155 -20 -324 0q-44 6 -63 9.5
-t-52.5 16t-54.5 32.5q13 19 36 31t40 15.5t47 8.5q198 35 408 1q33 -5 51 -8.5t43 -16t39 -31.5zM1142 327q0 7 5.5 26.5t3 32t-17.5 16.5q-161 -106 -365 -106t-366 106l-12 -6l-5 -12q26 -154 41 -210q47 -81 204 -108q249 -46 428 53q34 19 49 51.5t22.5 85.5t12.5 71z
-M1272 1020q9 53 -8 75q-43 55 -155 88q-216 63 -487 36q-132 -12 -226 -46q-38 -15 -59.5 -25t-47 -34t-29.5 -54q8 -68 19 -138t29 -171t24 -137q1 -5 5 -31t7 -36t12 -27t22 -28q105 -80 284 -100q259 -28 440 63q24 13 39.5 23t31 29t19.5 40q48 267 80 473zM1536 1120
-v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
-    <glyph glyph-name="tumblr" unicode="&#xf173;" horiz-adv-x="1024" 
-d="M944 207l80 -237q-23 -35 -111 -66t-177 -32q-104 -2 -190.5 26t-142.5 74t-95 106t-55.5 120t-16.5 118v544h-168v215q72 26 129 69.5t91 90t58 102t34 99t15 88.5q1 5 4.5 8.5t7.5 3.5h244v-424h333v-252h-334v-518q0 -30 6.5 -56t22.5 -52.5t49.5 -41.5t81.5 -14
-q78 2 134 29z" />
-    <glyph glyph-name="tumblr_sign" unicode="&#xf174;" 
-d="M1136 75l-62 183q-44 -22 -103 -22q-36 -1 -62 10.5t-38.5 31.5t-17.5 40.5t-5 43.5v398h257v194h-256v326h-188q-8 0 -9 -10q-5 -44 -17.5 -87t-39 -95t-77 -95t-118.5 -68v-165h130v-418q0 -57 21.5 -115t65 -111t121 -85.5t176.5 -30.5q69 1 136.5 25t85.5 50z
-M1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
-    <glyph glyph-name="long_arrow_down" unicode="&#xf175;" horiz-adv-x="768" 
-d="M765 237q8 -19 -5 -35l-350 -384q-10 -10 -23 -10q-14 0 -24 10l-355 384q-13 16 -5 35q9 19 29 19h224v1248q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-1248h224q21 0 29 -19z" />
-    <glyph glyph-name="long_arrow_up" unicode="&#xf176;" horiz-adv-x="768" 
-d="M765 1043q-9 -19 -29 -19h-224v-1248q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v1248h-224q-21 0 -29 19t5 35l350 384q10 10 23 10q14 0 24 -10l355 -384q13 -16 5 -35z" />
-    <glyph glyph-name="long_arrow_left" unicode="&#xf177;" horiz-adv-x="1792" 
-d="M1792 736v-192q0 -14 -9 -23t-23 -9h-1248v-224q0 -21 -19 -29t-35 5l-384 350q-10 10 -10 23q0 14 10 24l384 354q16 14 35 6q19 -9 19 -29v-224h1248q14 0 23 -9t9 -23z" />
-    <glyph glyph-name="long_arrow_right" unicode="&#xf178;" horiz-adv-x="1792" 
-d="M1728 643q0 -14 -10 -24l-384 -354q-16 -14 -35 -6q-19 9 -19 29v224h-1248q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h1248v224q0 21 19 29t35 -5l384 -350q10 -10 10 -23z" />
-    <glyph glyph-name="apple" unicode="&#xf179;" horiz-adv-x="1408" 
-d="M1393 321q-39 -125 -123 -250q-129 -196 -257 -196q-49 0 -140 32q-86 32 -151 32q-61 0 -142 -33q-81 -34 -132 -34q-152 0 -301 259q-147 261 -147 503q0 228 113 374q113 144 284 144q72 0 177 -30q104 -30 138 -30q45 0 143 34q102 34 173 34q119 0 213 -65
-q52 -36 104 -100q-79 -67 -114 -118q-65 -94 -65 -207q0 -124 69 -223t158 -126zM1017 1494q0 -61 -29 -136q-30 -75 -93 -138q-54 -54 -108 -72q-37 -11 -104 -17q3 149 78 257q74 107 250 148q1 -3 2.5 -11t2.5 -11q0 -4 0.5 -10t0.5 -10z" />
-    <glyph glyph-name="windows" unicode="&#xf17a;" horiz-adv-x="1664" 
-d="M682 530v-651l-682 94v557h682zM682 1273v-659h-682v565zM1664 530v-786l-907 125v661h907zM1664 1408v-794h-907v669z" />
-    <glyph glyph-name="android" unicode="&#xf17b;" horiz-adv-x="1408" 
-d="M493 1053q16 0 27.5 11.5t11.5 27.5t-11.5 27.5t-27.5 11.5t-27 -11.5t-11 -27.5t11 -27.5t27 -11.5zM915 1053q16 0 27 11.5t11 27.5t-11 27.5t-27 11.5t-27.5 -11.5t-11.5 -27.5t11.5 -27.5t27.5 -11.5zM103 869q42 0 72 -30t30 -72v-430q0 -43 -29.5 -73t-72.5 -30
-t-73 30t-30 73v430q0 42 30 72t73 30zM1163 850v-666q0 -46 -32 -78t-77 -32h-75v-227q0 -43 -30 -73t-73 -30t-73 30t-30 73v227h-138v-227q0 -43 -30 -73t-73 -30q-42 0 -72 30t-30 73l-1 227h-74q-46 0 -78 32t-32 78v666h918zM931 1255q107 -55 171 -153.5t64 -215.5
-h-925q0 117 64 215.5t172 153.5l-71 131q-7 13 5 20q13 6 20 -6l72 -132q95 42 201 42t201 -42l72 132q7 12 20 6q12 -7 5 -20zM1408 767v-430q0 -43 -30 -73t-73 -30q-42 0 -72 30t-30 73v430q0 43 30 72.5t72 29.5q43 0 73 -29.5t30 -72.5z" />
-    <glyph glyph-name="linux" unicode="&#xf17c;" 
-d="M663 1125q-11 -1 -15.5 -10.5t-8.5 -9.5q-5 -1 -5 5q0 12 19 15h10zM750 1111q-4 -1 -11.5 6.5t-17.5 4.5q24 11 32 -2q3 -6 -3 -9zM399 684q-4 1 -6 -3t-4.5 -12.5t-5.5 -13.5t-10 -13q-10 -11 -1 -12q4 -1 12.5 7t12.5 18q1 3 2 7t2 6t1.5 4.5t0.5 4v3t-1 2.5t-3 2z
-M1254 325q0 18 -55 42q4 15 7.5 27.5t5 26t3 21.5t0.5 22.5t-1 19.5t-3.5 22t-4 20.5t-5 25t-5.5 26.5q-10 48 -47 103t-72 75q24 -20 57 -83q87 -162 54 -278q-11 -40 -50 -42q-31 -4 -38.5 18.5t-8 83.5t-11.5 107q-9 39 -19.5 69t-19.5 45.5t-15.5 24.5t-13 15t-7.5 7
-q-14 62 -31 103t-29.5 56t-23.5 33t-15 40q-4 21 6 53.5t4.5 49.5t-44.5 25q-15 3 -44.5 18t-35.5 16q-8 1 -11 26t8 51t36 27q37 3 51 -30t4 -58q-11 -19 -2 -26.5t30 -0.5q13 4 13 36v37q-5 30 -13.5 50t-21 30.5t-23.5 15t-27 7.5q-107 -8 -89 -134q0 -15 -1 -15
-q-9 9 -29.5 10.5t-33 -0.5t-15.5 5q1 57 -16 90t-45 34q-27 1 -41.5 -27.5t-16.5 -59.5q-1 -15 3.5 -37t13 -37.5t15.5 -13.5q10 3 16 14q4 9 -7 8q-7 0 -15.5 14.5t-9.5 33.5q-1 22 9 37t34 14q17 0 27 -21t9.5 -39t-1.5 -22q-22 -15 -31 -29q-8 -12 -27.5 -23.5
-t-20.5 -12.5q-13 -14 -15.5 -27t7.5 -18q14 -8 25 -19.5t16 -19t18.5 -13t35.5 -6.5q47 -2 102 15q2 1 23 7t34.5 10.5t29.5 13t21 17.5q9 14 20 8q5 -3 6.5 -8.5t-3 -12t-16.5 -9.5q-20 -6 -56.5 -21.5t-45.5 -19.5q-44 -19 -70 -23q-25 -5 -79 2q-10 2 -9 -2t17 -19
-q25 -23 67 -22q17 1 36 7t36 14t33.5 17.5t30 17t24.5 12t17.5 2.5t8.5 -11q0 -2 -1 -4.5t-4 -5t-6 -4.5t-8.5 -5t-9 -4.5t-10 -5t-9.5 -4.5q-28 -14 -67.5 -44t-66.5 -43t-49 -1q-21 11 -63 73q-22 31 -25 22q-1 -3 -1 -10q0 -25 -15 -56.5t-29.5 -55.5t-21 -58t11.5 -63
-q-23 -6 -62.5 -90t-47.5 -141q-2 -18 -1.5 -69t-5.5 -59q-8 -24 -29 -3q-32 31 -36 94q-2 28 4 56q4 19 -1 18q-2 -1 -4 -5q-36 -65 10 -166q5 -12 25 -28t24 -20q20 -23 104 -90.5t93 -76.5q16 -15 17.5 -38t-14 -43t-45.5 -23q8 -15 29 -44.5t28 -54t7 -70.5q46 24 7 92
-q-4 8 -10.5 16t-9.5 12t-2 6q3 5 13 9.5t20 -2.5q46 -52 166 -36q133 15 177 87q23 38 34 30q12 -6 10 -52q-1 -25 -23 -92q-9 -23 -6 -37.5t24 -15.5q3 19 14.5 77t13.5 90q2 21 -6.5 73.5t-7.5 97t23 70.5q15 18 51 18q1 37 34.5 53t72.5 10.5t60 -22.5zM626 1152
-q3 17 -2.5 30t-11.5 15q-9 2 -9 -7q2 -5 5 -6q10 0 7 -15q-3 -20 8 -20q3 0 3 3zM1045 955q-2 8 -6.5 11.5t-13 5t-14.5 5.5q-5 3 -9.5 8t-7 8t-5.5 6.5t-4 4t-4 -1.5q-14 -16 7 -43.5t39 -31.5q9 -1 14.5 8t3.5 20zM867 1168q0 11 -5 19.5t-11 12.5t-9 3q-6 0 -8 -2t0 -4
-t5 -3q14 -4 18 -31q0 -3 8 2q2 2 2 3zM921 1401q0 2 -2.5 5t-9 7t-9.5 6q-15 15 -24 15q-9 -1 -11.5 -7.5t-1 -13t-0.5 -12.5q-1 -4 -6 -10.5t-6 -9t3 -8.5q4 -3 8 0t11 9t15 9q1 1 9 1t15 2t9 7zM1486 60q20 -12 31 -24.5t12 -24t-2.5 -22.5t-15.5 -22t-23.5 -19.5
-t-30 -18.5t-31.5 -16.5t-32 -15.5t-27 -13q-38 -19 -85.5 -56t-75.5 -64q-17 -16 -68 -19.5t-89 14.5q-18 9 -29.5 23.5t-16.5 25.5t-22 19.5t-47 9.5q-44 1 -130 1q-19 0 -57 -1.5t-58 -2.5q-44 -1 -79.5 -15t-53.5 -30t-43.5 -28.5t-53.5 -11.5q-29 1 -111 31t-146 43
-q-19 4 -51 9.5t-50 9t-39.5 9.5t-33.5 14.5t-17 19.5q-10 23 7 66.5t18 54.5q1 16 -4 40t-10 42.5t-4.5 36.5t10.5 27q14 12 57 14t60 12q30 18 42 35t12 51q21 -73 -32 -106q-32 -20 -83 -15q-34 3 -43 -10q-13 -15 5 -57q2 -6 8 -18t8.5 -18t4.5 -17t1 -22q0 -15 -17 -49
-t-14 -48q3 -17 37 -26q20 -6 84.5 -18.5t99.5 -20.5q24 -6 74 -22t82.5 -23t55.5 -4q43 6 64.5 28t23 48t-7.5 58.5t-19 52t-20 36.5q-121 190 -169 242q-68 74 -113 40q-11 -9 -15 15q-3 16 -2 38q1 29 10 52t24 47t22 42q8 21 26.5 72t29.5 78t30 61t39 54
-q110 143 124 195q-12 112 -16 310q-2 90 24 151.5t106 104.5q39 21 104 21q53 1 106 -13.5t89 -41.5q57 -42 91.5 -121.5t29.5 -147.5q-5 -95 30 -214q34 -113 133 -218q55 -59 99.5 -163t59.5 -191q8 -49 5 -84.5t-12 -55.5t-20 -22q-10 -2 -23.5 -19t-27 -35.5
-t-40.5 -33.5t-61 -14q-18 1 -31.5 5t-22.5 13.5t-13.5 15.5t-11.5 20.5t-9 19.5q-22 37 -41 30t-28 -49t7 -97q20 -70 1 -195q-10 -65 18 -100.5t73 -33t85 35.5q59 49 89.5 66.5t103.5 42.5q53 18 77 36.5t18.5 34.5t-25 28.5t-51.5 23.5q-33 11 -49.5 48t-15 72.5
-t15.5 47.5q1 -31 8 -56.5t14.5 -40.5t20.5 -28.5t21 -19t21.5 -13t16.5 -9.5z" />
-    <glyph glyph-name="dribble" unicode="&#xf17d;" 
-d="M1024 36q-42 241 -140 498h-2l-2 -1q-16 -6 -43 -16.5t-101 -49t-137 -82t-131 -114.5t-103 -148l-15 11q184 -150 418 -150q132 0 256 52zM839 643q-21 49 -53 111q-311 -93 -673 -93q-1 -7 -1 -21q0 -124 44 -236.5t124 -201.5q50 89 123.5 166.5t142.5 124.5t130.5 81
-t99.5 48l37 13q4 1 13 3.5t13 4.5zM732 855q-120 213 -244 378q-138 -65 -234 -186t-128 -272q302 0 606 80zM1416 536q-210 60 -409 29q87 -239 128 -469q111 75 185 189.5t96 250.5zM611 1277q-1 0 -2 -1q1 1 2 1zM1201 1132q-185 164 -433 164q-76 0 -155 -19
-q131 -170 246 -382q69 26 130 60.5t96.5 61.5t65.5 57t37.5 40.5zM1424 647q-3 232 -149 410l-1 -1q-9 -12 -19 -24.5t-43.5 -44.5t-71 -60.5t-100 -65t-131.5 -64.5q25 -53 44 -95q2 -5 6.5 -17t7.5 -17q36 5 74.5 7t73.5 2t69 -1.5t64 -4t56.5 -5.5t48 -6.5t36.5 -6
-t25 -4.5zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
-    <glyph glyph-name="skype" unicode="&#xf17e;" 
-d="M1173 473q0 50 -19.5 91.5t-48.5 68.5t-73 49t-82.5 34t-87.5 23l-104 24q-30 7 -44 10.5t-35 11.5t-30 16t-16.5 21t-7.5 30q0 77 144 77q43 0 77 -12t54 -28.5t38 -33.5t40 -29t48 -12q47 0 75.5 32t28.5 77q0 55 -56 99.5t-142 67.5t-182 23q-68 0 -132 -15.5
-t-119.5 -47t-89 -87t-33.5 -128.5q0 -61 19 -106.5t56 -75.5t80 -48.5t103 -32.5l146 -36q90 -22 112 -36q32 -20 32 -60q0 -39 -40 -64.5t-105 -25.5q-51 0 -91.5 16t-65 38.5t-45.5 45t-46 38.5t-54 16q-50 0 -75.5 -30t-25.5 -75q0 -92 122 -157.5t291 -65.5
-q73 0 140 18.5t122.5 53.5t88.5 93.5t33 131.5zM1536 256q0 -159 -112.5 -271.5t-271.5 -112.5q-130 0 -234 80q-77 -16 -150 -16q-143 0 -273.5 55.5t-225 150t-150 225t-55.5 273.5q0 73 16 150q-80 104 -80 234q0 159 112.5 271.5t271.5 112.5q130 0 234 -80
-q77 16 150 16q143 0 273.5 -55.5t225 -150t150 -225t55.5 -273.5q0 -73 -16 -150q80 -104 80 -234z" />
-    <glyph glyph-name="foursquare" unicode="&#xf180;" horiz-adv-x="1280" 
-d="M1000 1102l37 194q5 23 -9 40t-35 17h-712q-23 0 -38.5 -17t-15.5 -37v-1101q0 -7 6 -1l291 352q23 26 38 33.5t48 7.5h239q22 0 37 14.5t18 29.5q24 130 37 191q4 21 -11.5 40t-36.5 19h-294q-29 0 -48 19t-19 48v42q0 29 19 47.5t48 18.5h346q18 0 35 13.5t20 29.5z
-M1227 1324q-15 -73 -53.5 -266.5t-69.5 -350t-35 -173.5q-6 -22 -9 -32.5t-14 -32.5t-24.5 -33t-38.5 -21t-58 -10h-271q-13 0 -22 -10q-8 -9 -426 -494q-22 -25 -58.5 -28.5t-48.5 5.5q-55 22 -55 98v1410q0 55 38 102.5t120 47.5h888q95 0 127 -53t10 -159zM1227 1324
-l-158 -790q4 17 35 173.5t69.5 350t53.5 266.5z" />
-    <glyph glyph-name="trello" unicode="&#xf181;" 
-d="M704 192v1024q0 14 -9 23t-23 9h-480q-14 0 -23 -9t-9 -23v-1024q0 -14 9 -23t23 -9h480q14 0 23 9t9 23zM1376 576v640q0 14 -9 23t-23 9h-480q-14 0 -23 -9t-9 -23v-640q0 -14 9 -23t23 -9h480q14 0 23 9t9 23zM1536 1344v-1408q0 -26 -19 -45t-45 -19h-1408
-q-26 0 -45 19t-19 45v1408q0 26 19 45t45 19h1408q26 0 45 -19t19 -45z" />
-    <glyph glyph-name="female" unicode="&#xf182;" horiz-adv-x="1280" 
-d="M1280 480q0 -40 -28 -68t-68 -28q-51 0 -80 43l-227 341h-45v-132l247 -411q9 -15 9 -33q0 -26 -19 -45t-45 -19h-192v-272q0 -46 -33 -79t-79 -33h-160q-46 0 -79 33t-33 79v272h-192q-26 0 -45 19t-19 45q0 18 9 33l247 411v132h-45l-227 -341q-29 -43 -80 -43
-q-40 0 -68 28t-28 68q0 29 16 53l256 384q73 107 176 107h384q103 0 176 -107l256 -384q16 -24 16 -53zM864 1280q0 -93 -65.5 -158.5t-158.5 -65.5t-158.5 65.5t-65.5 158.5t65.5 158.5t158.5 65.5t158.5 -65.5t65.5 -158.5z" />
-    <glyph glyph-name="male" unicode="&#xf183;" horiz-adv-x="1024" 
-d="M1024 832v-416q0 -40 -28 -68t-68 -28t-68 28t-28 68v352h-64v-912q0 -46 -33 -79t-79 -33t-79 33t-33 79v464h-64v-464q0 -46 -33 -79t-79 -33t-79 33t-33 79v912h-64v-352q0 -40 -28 -68t-68 -28t-68 28t-28 68v416q0 80 56 136t136 56h640q80 0 136 -56t56 -136z
-M736 1280q0 -93 -65.5 -158.5t-158.5 -65.5t-158.5 65.5t-65.5 158.5t65.5 158.5t158.5 65.5t158.5 -65.5t65.5 -158.5z" />
-    <glyph glyph-name="gittip" unicode="&#xf184;" 
-d="M773 234l350 473q16 22 24.5 59t-6 85t-61.5 79q-40 26 -83 25.5t-73.5 -17.5t-54.5 -45q-36 -40 -96 -40q-59 0 -95 40q-24 28 -54.5 45t-73.5 17.5t-84 -25.5q-46 -31 -60.5 -79t-6 -85t24.5 -59zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103
-t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
-    <glyph glyph-name="sun" unicode="&#xf185;" horiz-adv-x="1792" 
-d="M1472 640q0 117 -45.5 223.5t-123 184t-184 123t-223.5 45.5t-223.5 -45.5t-184 -123t-123 -184t-45.5 -223.5t45.5 -223.5t123 -184t184 -123t223.5 -45.5t223.5 45.5t184 123t123 184t45.5 223.5zM1748 363q-4 -15 -20 -20l-292 -96v-306q0 -16 -13 -26q-15 -10 -29 -4
-l-292 94l-180 -248q-10 -13 -26 -13t-26 13l-180 248l-292 -94q-14 -6 -29 4q-13 10 -13 26v306l-292 96q-16 5 -20 20q-5 17 4 29l180 248l-180 248q-9 13 -4 29q4 15 20 20l292 96v306q0 16 13 26q15 10 29 4l292 -94l180 248q9 12 26 12t26 -12l180 -248l292 94
-q14 6 29 -4q13 -10 13 -26v-306l292 -96q16 -5 20 -20q5 -16 -4 -29l-180 -248l180 -248q9 -12 4 -29z" />
-    <glyph glyph-name="_366" unicode="&#xf186;" 
-d="M1262 233q-54 -9 -110 -9q-182 0 -337 90t-245 245t-90 337q0 192 104 357q-201 -60 -328.5 -229t-127.5 -384q0 -130 51 -248.5t136.5 -204t204 -136.5t248.5 -51q144 0 273.5 61.5t220.5 171.5zM1465 318q-94 -203 -283.5 -324.5t-413.5 -121.5q-156 0 -298 61
-t-245 164t-164 245t-61 298q0 153 57.5 292.5t156 241.5t235.5 164.5t290 68.5q44 2 61 -39q18 -41 -15 -72q-86 -78 -131.5 -181.5t-45.5 -218.5q0 -148 73 -273t198 -198t273 -73q118 0 228 51q41 18 72 -13q14 -14 17.5 -34t-4.5 -38z" />
-    <glyph glyph-name="archive" unicode="&#xf187;" horiz-adv-x="1792" 
-d="M1088 704q0 26 -19 45t-45 19h-256q-26 0 -45 -19t-19 -45t19 -45t45 -19h256q26 0 45 19t19 45zM1664 896v-960q0 -26 -19 -45t-45 -19h-1408q-26 0 -45 19t-19 45v960q0 26 19 45t45 19h1408q26 0 45 -19t19 -45zM1728 1344v-256q0 -26 -19 -45t-45 -19h-1536
-q-26 0 -45 19t-19 45v256q0 26 19 45t45 19h1536q26 0 45 -19t19 -45z" />
-    <glyph glyph-name="bug" unicode="&#xf188;" horiz-adv-x="1664" 
-d="M1632 576q0 -26 -19 -45t-45 -19h-224q0 -171 -67 -290l208 -209q19 -19 19 -45t-19 -45q-18 -19 -45 -19t-45 19l-198 197q-5 -5 -15 -13t-42 -28.5t-65 -36.5t-82 -29t-97 -13v896h-128v-896q-51 0 -101.5 13.5t-87 33t-66 39t-43.5 32.5l-15 14l-183 -207
-q-20 -21 -48 -21q-24 0 -43 16q-19 18 -20.5 44.5t15.5 46.5l202 227q-58 114 -58 274h-224q-26 0 -45 19t-19 45t19 45t45 19h224v294l-173 173q-19 19 -19 45t19 45t45 19t45 -19l173 -173h844l173 173q19 19 45 19t45 -19t19 -45t-19 -45l-173 -173v-294h224q26 0 45 -19
-t19 -45zM1152 1152h-640q0 133 93.5 226.5t226.5 93.5t226.5 -93.5t93.5 -226.5z" />
-    <glyph glyph-name="vk" unicode="&#xf189;" horiz-adv-x="1920" 
-d="M1917 1016q23 -64 -150 -294q-24 -32 -65 -85q-40 -51 -55 -72t-30.5 -49.5t-12 -42t13 -34.5t32.5 -43t57 -53q4 -2 5 -4q141 -131 191 -221q3 -5 6.5 -12.5t7 -26.5t-0.5 -34t-25 -27.5t-59 -12.5l-256 -4q-24 -5 -56 5t-52 22l-20 12q-30 21 -70 64t-68.5 77.5t-61 58
-t-56.5 15.5q-3 -1 -8 -3.5t-17 -14.5t-21.5 -29.5t-17 -52t-6.5 -77.5q0 -15 -3.5 -27.5t-7.5 -18.5l-4 -5q-18 -19 -53 -22h-115q-71 -4 -146 16.5t-131.5 53t-103 66t-70.5 57.5l-25 24q-10 10 -27.5 30t-71.5 91t-106 151t-122.5 211t-130.5 272q-6 16 -6 27t3 16l4 6
-q15 19 57 19l274 2q12 -2 23 -6.5t16 -8.5l5 -3q16 -11 24 -32q20 -50 46 -103.5t41 -81.5l16 -29q29 -60 56 -104t48.5 -68.5t41.5 -38.5t34 -14t27 5q2 1 5 5t12 22t13.5 47t9.5 81t0 125q-2 40 -9 73t-14 46l-6 12q-25 34 -85 43q-13 2 5 24q16 19 38 30q53 26 239 24
-q82 -1 135 -13q20 -5 33.5 -13.5t20.5 -24t10.5 -32t3.5 -45.5t-1 -55t-2.5 -70.5t-1.5 -82.5q0 -11 -1 -42t-0.5 -48t3.5 -40.5t11.5 -39t22.5 -24.5q8 -2 17 -4t26 11t38 34.5t52 67t68 107.5q60 104 107 225q4 10 10 17.5t11 10.5l4 3l5 2.5t13 3t20 0.5l288 2
-q39 5 64 -2.5t31 -16.5z" />
-    <glyph glyph-name="weibo" unicode="&#xf18a;" horiz-adv-x="1792" 
-d="M675 252q21 34 11 69t-45 50q-34 14 -73 1t-60 -46q-22 -34 -13 -68.5t43 -50.5t74.5 -2.5t62.5 47.5zM769 373q8 13 3.5 26.5t-17.5 18.5q-14 5 -28.5 -0.5t-21.5 -18.5q-17 -31 13 -45q14 -5 29 0.5t22 18.5zM943 266q-45 -102 -158 -150t-224 -12
-q-107 34 -147.5 126.5t6.5 187.5q47 93 151.5 139t210.5 19q111 -29 158.5 -119.5t2.5 -190.5zM1255 426q-9 96 -89 170t-208.5 109t-274.5 21q-223 -23 -369.5 -141.5t-132.5 -264.5q9 -96 89 -170t208.5 -109t274.5 -21q223 23 369.5 141.5t132.5 264.5zM1563 422
-q0 -68 -37 -139.5t-109 -137t-168.5 -117.5t-226 -83t-270.5 -31t-275 33.5t-240.5 93t-171.5 151t-65 199.5q0 115 69.5 245t197.5 258q169 169 341.5 236t246.5 -7q65 -64 20 -209q-4 -14 -1 -20t10 -7t14.5 0.5t13.5 3.5l6 2q139 59 246 59t153 -61q45 -63 0 -178
-q-2 -13 -4.5 -20t4.5 -12.5t12 -7.5t17 -6q57 -18 103 -47t80 -81.5t34 -116.5zM1489 1046q42 -47 54.5 -108.5t-6.5 -117.5q-8 -23 -29.5 -34t-44.5 -4q-23 8 -34 29.5t-4 44.5q20 63 -24 111t-107 35q-24 -5 -45 8t-25 37q-5 24 8 44.5t37 25.5q60 13 119 -5.5t101 -65.5z
-M1670 1209q87 -96 112.5 -222.5t-13.5 -241.5q-9 -27 -34 -40t-52 -4t-40 34t-5 52q28 82 10 172t-80 158q-62 69 -148 95.5t-173 8.5q-28 -6 -52 9.5t-30 43.5t9.5 51.5t43.5 29.5q123 26 244 -11.5t208 -134.5z" />
-    <glyph glyph-name="renren" unicode="&#xf18b;" 
-d="M1133 -34q-171 -94 -368 -94q-196 0 -367 94q138 87 235.5 211t131.5 268q35 -144 132.5 -268t235.5 -211zM638 1394v-485q0 -252 -126.5 -459.5t-330.5 -306.5q-181 215 -181 495q0 187 83.5 349.5t229.5 269.5t325 137zM1536 638q0 -280 -181 -495
-q-204 99 -330.5 306.5t-126.5 459.5v485q179 -30 325 -137t229.5 -269.5t83.5 -349.5z" />
-    <glyph glyph-name="_372" unicode="&#xf18c;" horiz-adv-x="1408" 
-d="M1402 433q-32 -80 -76 -138t-91 -88.5t-99 -46.5t-101.5 -14.5t-96.5 8.5t-86.5 22t-69.5 27.5t-46 22.5l-17 10q-113 -228 -289.5 -359.5t-384.5 -132.5q-19 0 -32 13t-13 32t13 31.5t32 12.5q173 1 322.5 107.5t251.5 294.5q-36 -14 -72 -23t-83 -13t-91 2.5t-93 28.5
-t-92 59t-84.5 100t-74.5 146q114 47 214 57t167.5 -7.5t124.5 -56.5t88.5 -77t56.5 -82q53 131 79 291q-7 -1 -18 -2.5t-46.5 -2.5t-69.5 0.5t-81.5 10t-88.5 23t-84 42.5t-75 65t-54.5 94.5t-28.5 127.5q70 28 133.5 36.5t112.5 -1t92 -30t73.5 -50t56 -61t42 -63t27.5 -56
-t16 -39.5l4 -16q12 122 12 195q-8 6 -21.5 16t-49 44.5t-63.5 71.5t-54 93t-33 112.5t12 127t70 138.5q73 -25 127.5 -61.5t84.5 -76.5t48 -85t20.5 -89t-0.5 -85.5t-13 -76.5t-19 -62t-17 -42l-7 -15q1 -4 1 -50t-1 -72q3 7 10 18.5t30.5 43t50.5 58t71 55.5t91.5 44.5
-t112 14.5t132.5 -24q-2 -78 -21.5 -141.5t-50 -104.5t-69.5 -71.5t-81.5 -45.5t-84.5 -24t-80 -9.5t-67.5 1t-46.5 4.5l-17 3q-23 -147 -73 -283q6 7 18 18.5t49.5 41t77.5 52.5t99.5 42t117.5 20t129 -23.5t137 -77.5z" />
-    <glyph glyph-name="stack_exchange" unicode="&#xf18d;" horiz-adv-x="1280" 
-d="M1259 283v-66q0 -85 -57.5 -144.5t-138.5 -59.5h-57l-260 -269v269h-529q-81 0 -138.5 59.5t-57.5 144.5v66h1238zM1259 609v-255h-1238v255h1238zM1259 937v-255h-1238v255h1238zM1259 1077v-67h-1238v67q0 84 57.5 143.5t138.5 59.5h846q81 0 138.5 -59.5t57.5 -143.5z
-" />
-    <glyph glyph-name="_374" unicode="&#xf18e;" 
-d="M1152 640q0 -14 -9 -23l-320 -320q-9 -9 -23 -9q-13 0 -22.5 9.5t-9.5 22.5v192h-352q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h352v192q0 14 9 23t23 9q12 0 24 -10l319 -319q9 -9 9 -23zM1312 640q0 148 -73 273t-198 198t-273 73t-273 -73t-198 -198
-t-73 -273t73 -273t198 -198t273 -73t273 73t198 198t73 273zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
-    <glyph glyph-name="arrow_circle_alt_left" unicode="&#xf190;" 
-d="M1152 736v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-352v-192q0 -14 -9 -23t-23 -9q-12 0 -24 10l-319 319q-9 9 -9 23t9 23l320 320q9 9 23 9q13 0 22.5 -9.5t9.5 -22.5v-192h352q13 0 22.5 -9.5t9.5 -22.5zM1312 640q0 148 -73 273t-198 198t-273 73t-273 -73t-198 -198
-t-73 -273t73 -273t198 -198t273 -73t273 73t198 198t73 273zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
-    <glyph glyph-name="_376" unicode="&#xf191;" 
-d="M1024 960v-640q0 -26 -19 -45t-45 -19q-20 0 -37 12l-448 320q-27 19 -27 52t27 52l448 320q17 12 37 12q26 0 45 -19t19 -45zM1280 160v960q0 13 -9.5 22.5t-22.5 9.5h-960q-13 0 -22.5 -9.5t-9.5 -22.5v-960q0 -13 9.5 -22.5t22.5 -9.5h960q13 0 22.5 9.5t9.5 22.5z
-M1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
-    <glyph glyph-name="dot_circle_alt" unicode="&#xf192;" 
-d="M1024 640q0 -106 -75 -181t-181 -75t-181 75t-75 181t75 181t181 75t181 -75t75 -181zM768 1184q-148 0 -273 -73t-198 -198t-73 -273t73 -273t198 -198t273 -73t273 73t198 198t73 273t-73 273t-198 198t-273 73zM1536 640q0 -209 -103 -385.5t-279.5 -279.5
-t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
-    <glyph glyph-name="_378" unicode="&#xf193;" horiz-adv-x="1664" 
-d="M1023 349l102 -204q-58 -179 -210 -290t-339 -111q-156 0 -288.5 77.5t-210 210t-77.5 288.5q0 181 104.5 330t274.5 211l17 -131q-122 -54 -195 -165.5t-73 -244.5q0 -185 131.5 -316.5t316.5 -131.5q126 0 232.5 65t165 175.5t49.5 236.5zM1571 249l58 -114l-256 -128
-q-13 -7 -29 -7q-40 0 -57 35l-239 477h-472q-24 0 -42.5 16.5t-21.5 40.5l-96 779q-2 17 6 42q14 51 57 82.5t97 31.5q66 0 113 -47t47 -113q0 -69 -52 -117.5t-120 -41.5l37 -289h423v-128h-407l16 -128h455q40 0 57 -35l228 -455z" />
-    <glyph glyph-name="vimeo_square" unicode="&#xf194;" 
-d="M1292 898q10 216 -161 222q-231 8 -312 -261q44 19 82 19q85 0 74 -96q-4 -57 -74 -167t-105 -110q-43 0 -82 169q-13 54 -45 255q-30 189 -160 177q-59 -7 -164 -100l-81 -72l-81 -72l52 -67q76 52 87 52q57 0 107 -179q15 -55 45 -164.5t45 -164.5q68 -179 164 -179
-q157 0 383 294q220 283 226 444zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
-    <glyph glyph-name="_380" unicode="&#xf195;" horiz-adv-x="1152" 
-d="M1152 704q0 -191 -94.5 -353t-256.5 -256.5t-353 -94.5h-160q-14 0 -23 9t-9 23v611l-215 -66q-3 -1 -9 -1q-10 0 -19 6q-13 10 -13 26v128q0 23 23 31l233 71v93l-215 -66q-3 -1 -9 -1q-10 0 -19 6q-13 10 -13 26v128q0 23 23 31l233 71v250q0 14 9 23t23 9h160
-q14 0 23 -9t9 -23v-181l375 116q15 5 28 -5t13 -26v-128q0 -23 -23 -31l-393 -121v-93l375 116q15 5 28 -5t13 -26v-128q0 -23 -23 -31l-393 -121v-487q188 13 318 151t130 328q0 14 9 23t23 9h160q14 0 23 -9t9 -23z" />
-    <glyph glyph-name="plus_square_o" unicode="&#xf196;" horiz-adv-x="1408" 
-d="M1152 736v-64q0 -14 -9 -23t-23 -9h-352v-352q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v352h-352q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h352v352q0 14 9 23t23 9h64q14 0 23 -9t9 -23v-352h352q14 0 23 -9t9 -23zM1280 288v832q0 66 -47 113t-113 47h-832
-q-66 0 -113 -47t-47 -113v-832q0 -66 47 -113t113 -47h832q66 0 113 47t47 113zM1408 1120v-832q0 -119 -84.5 -203.5t-203.5 -84.5h-832q-119 0 -203.5 84.5t-84.5 203.5v832q0 119 84.5 203.5t203.5 84.5h832q119 0 203.5 -84.5t84.5 -203.5z" />
-    <glyph glyph-name="_382" unicode="&#xf197;" horiz-adv-x="2176" 
-d="M620 416q-110 -64 -268 -64h-128v64h-64q-13 0 -22.5 23.5t-9.5 56.5q0 24 7 49q-58 2 -96.5 10.5t-38.5 20.5t38.5 20.5t96.5 10.5q-7 25 -7 49q0 33 9.5 56.5t22.5 23.5h64v64h128q158 0 268 -64h1113q42 -7 106.5 -18t80.5 -14q89 -15 150 -40.5t83.5 -47.5t22.5 -40
-t-22.5 -40t-83.5 -47.5t-150 -40.5q-16 -3 -80.5 -14t-106.5 -18h-1113zM1739 668q53 -36 53 -92t-53 -92l81 -30q68 48 68 122t-68 122zM625 400h1015q-217 -38 -456 -80q-57 0 -113 -24t-83 -48l-28 -24l-288 -288q-26 -26 -70.5 -45t-89.5 -19h-96l-93 464h29
-q157 0 273 64zM352 816h-29l93 464h96q46 0 90 -19t70 -45l288 -288q4 -4 11 -10.5t30.5 -23t48.5 -29t61.5 -23t72.5 -10.5l456 -80h-1015q-116 64 -273 64z" />
-    <glyph glyph-name="_383" unicode="&#xf198;" horiz-adv-x="1664" 
-d="M1519 760q62 0 103.5 -40.5t41.5 -101.5q0 -97 -93 -130l-172 -59l56 -167q7 -21 7 -47q0 -59 -42 -102t-101 -43q-47 0 -85.5 27t-53.5 72l-55 165l-310 -106l55 -164q8 -24 8 -47q0 -59 -42 -102t-102 -43q-47 0 -85 27t-53 72l-55 163l-153 -53q-29 -9 -50 -9
-q-61 0 -101.5 40t-40.5 101q0 47 27.5 85t71.5 53l156 53l-105 313l-156 -54q-26 -8 -48 -8q-60 0 -101 40.5t-41 100.5q0 47 27.5 85t71.5 53l157 53l-53 159q-8 24 -8 47q0 60 42 102.5t102 42.5q47 0 85 -27t53 -72l54 -160l310 105l-54 160q-8 24 -8 47q0 59 42.5 102
-t101.5 43q47 0 85.5 -27.5t53.5 -71.5l53 -161l162 55q21 6 43 6q60 0 102.5 -39.5t42.5 -98.5q0 -45 -30 -81.5t-74 -51.5l-157 -54l105 -316l164 56q24 8 46 8zM725 498l310 105l-105 315l-310 -107z" />
-    <glyph glyph-name="_384" unicode="&#xf199;" 
-d="M1248 1408q119 0 203.5 -84.5t84.5 -203.5v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960zM1280 352v436q-31 -35 -64 -55q-34 -22 -132.5 -85t-151.5 -99q-98 -69 -164 -69v0v0q-66 0 -164 69
-q-47 32 -142 92.5t-142 92.5q-12 8 -33 27t-31 27v-436q0 -40 28 -68t68 -28h832q40 0 68 28t28 68zM1280 925q0 41 -27.5 70t-68.5 29h-832q-40 0 -68 -28t-28 -68q0 -37 30.5 -76.5t67.5 -64.5q47 -32 137.5 -89t129.5 -83q3 -2 17 -11.5t21 -14t21 -13t23.5 -13
-t21.5 -9.5t22.5 -7.5t20.5 -2.5t20.5 2.5t22.5 7.5t21.5 9.5t23.5 13t21 13t21 14t17 11.5l267 174q35 23 66.5 62.5t31.5 73.5z" />
-    <glyph glyph-name="_385" unicode="&#xf19a;" horiz-adv-x="1792" 
-d="M127 640q0 163 67 313l367 -1005q-196 95 -315 281t-119 411zM1415 679q0 -19 -2.5 -38.5t-10 -49.5t-11.5 -44t-17.5 -59t-17.5 -58l-76 -256l-278 826q46 3 88 8q19 2 26 18.5t-2.5 31t-28.5 13.5l-205 -10q-75 1 -202 10q-12 1 -20.5 -5t-11.5 -15t-1.5 -18.5t9 -16.5
-t19.5 -8l80 -8l120 -328l-168 -504l-280 832q46 3 88 8q19 2 26 18.5t-2.5 31t-28.5 13.5l-205 -10q-7 0 -23 0.5t-26 0.5q105 160 274.5 253.5t367.5 93.5q147 0 280.5 -53t238.5 -149h-10q-55 0 -92 -40.5t-37 -95.5q0 -12 2 -24t4 -21.5t8 -23t9 -21t12 -22.5t12.5 -21
-t14.5 -24t14 -23q63 -107 63 -212zM909 573l237 -647q1 -6 5 -11q-126 -44 -255 -44q-112 0 -217 32zM1570 1009q95 -174 95 -369q0 -209 -104 -385.5t-279 -278.5l235 678q59 169 59 276q0 42 -6 79zM896 1536q182 0 348 -71t286 -191t191 -286t71 -348t-71 -348t-191 -286
-t-286 -191t-348 -71t-348 71t-286 191t-191 286t-71 348t71 348t191 286t286 191t348 71zM896 -215q173 0 331.5 68t273 182.5t182.5 273t68 331.5t-68 331.5t-182.5 273t-273 182.5t-331.5 68t-331.5 -68t-273 -182.5t-182.5 -273t-68 -331.5t68 -331.5t182.5 -273
-t273 -182.5t331.5 -68z" />
-    <glyph glyph-name="_386" unicode="&#xf19b;" horiz-adv-x="1792" 
-d="M1086 1536v-1536l-272 -128q-228 20 -414 102t-293 208.5t-107 272.5q0 140 100.5 263.5t275 205.5t391.5 108v-172q-217 -38 -356.5 -150t-139.5 -255q0 -152 154.5 -267t388.5 -145v1360zM1755 954l37 -390l-525 114l147 83q-119 70 -280 99v172q277 -33 481 -157z" />
-    <glyph glyph-name="_387" unicode="&#xf19c;" horiz-adv-x="2048" 
-d="M960 1536l960 -384v-128h-128q0 -26 -20.5 -45t-48.5 -19h-1526q-28 0 -48.5 19t-20.5 45h-128v128zM256 896h256v-768h128v768h256v-768h128v768h256v-768h128v768h256v-768h59q28 0 48.5 -19t20.5 -45v-64h-1664v64q0 26 20.5 45t48.5 19h59v768zM1851 -64
-q28 0 48.5 -19t20.5 -45v-128h-1920v128q0 26 20.5 45t48.5 19h1782z" />
-    <glyph glyph-name="_388" unicode="&#xf19d;" horiz-adv-x="2304" 
-d="M1774 700l18 -316q4 -69 -82 -128t-235 -93.5t-323 -34.5t-323 34.5t-235 93.5t-82 128l18 316l574 -181q22 -7 48 -7t48 7zM2304 1024q0 -23 -22 -31l-1120 -352q-4 -1 -10 -1t-10 1l-652 206q-43 -34 -71 -111.5t-34 -178.5q63 -36 63 -109q0 -69 -58 -107l58 -433
-q2 -14 -8 -25q-9 -11 -24 -11h-192q-15 0 -24 11q-10 11 -8 25l58 433q-58 38 -58 107q0 73 65 111q11 207 98 330l-333 104q-22 8 -22 31t22 31l1120 352q4 1 10 1t10 -1l1120 -352q22 -8 22 -31z" />
-    <glyph glyph-name="_389" unicode="&#xf19e;" 
-d="M859 579l13 -707q-62 11 -105 11q-41 0 -105 -11l13 707q-40 69 -168.5 295.5t-216.5 374.5t-181 287q58 -15 108 -15q44 0 111 15q63 -111 133.5 -229.5t167 -276.5t138.5 -227q37 61 109.5 177.5t117.5 190t105 176t107 189.5q54 -14 107 -14q56 0 114 14v0
-q-28 -39 -60 -88.5t-49.5 -78.5t-56.5 -96t-49 -84q-146 -248 -353 -610z" />
-    <glyph glyph-name="uniF1A0" unicode="&#xf1a0;" 
-d="M768 750h725q12 -67 12 -128q0 -217 -91 -387.5t-259.5 -266.5t-386.5 -96q-157 0 -299 60.5t-245 163.5t-163.5 245t-60.5 299t60.5 299t163.5 245t245 163.5t299 60.5q300 0 515 -201l-209 -201q-123 119 -306 119q-129 0 -238.5 -65t-173.5 -176.5t-64 -243.5
-t64 -243.5t173.5 -176.5t238.5 -65q87 0 160 24t120 60t82 82t51.5 87t22.5 78h-436v264z" />
-    <glyph glyph-name="f1a1" unicode="&#xf1a1;" horiz-adv-x="1792" 
-d="M1095 369q16 -16 0 -31q-62 -62 -199 -62t-199 62q-16 15 0 31q6 6 15 6t15 -6q48 -49 169 -49q120 0 169 49q6 6 15 6t15 -6zM788 550q0 -37 -26 -63t-63 -26t-63.5 26t-26.5 63q0 38 26.5 64t63.5 26t63 -26.5t26 -63.5zM1183 550q0 -37 -26.5 -63t-63.5 -26t-63 26
-t-26 63t26 63.5t63 26.5t63.5 -26t26.5 -64zM1434 670q0 49 -35 84t-85 35t-86 -36q-130 90 -311 96l63 283l200 -45q0 -37 26 -63t63 -26t63.5 26.5t26.5 63.5t-26.5 63.5t-63.5 26.5q-54 0 -80 -50l-221 49q-19 5 -25 -16l-69 -312q-180 -7 -309 -97q-35 37 -87 37
-q-50 0 -85 -35t-35 -84q0 -35 18.5 -64t49.5 -44q-6 -27 -6 -56q0 -142 140 -243t337 -101q198 0 338 101t140 243q0 32 -7 57q30 15 48 43.5t18 63.5zM1792 640q0 -182 -71 -348t-191 -286t-286 -191t-348 -71t-348 71t-286 191t-191 286t-71 348t71 348t191 286t286 191
-t348 71t348 -71t286 -191t191 -286t71 -348z" />
-    <glyph glyph-name="_392" unicode="&#xf1a2;" 
-d="M939 407q13 -13 0 -26q-53 -53 -171 -53t-171 53q-13 13 0 26q5 6 13 6t13 -6q42 -42 145 -42t145 42q5 6 13 6t13 -6zM676 563q0 -31 -23 -54t-54 -23t-54 23t-23 54q0 32 22.5 54.5t54.5 22.5t54.5 -22.5t22.5 -54.5zM1014 563q0 -31 -23 -54t-54 -23t-54 23t-23 54
-q0 32 22.5 54.5t54.5 22.5t54.5 -22.5t22.5 -54.5zM1229 666q0 42 -30 72t-73 30q-42 0 -73 -31q-113 78 -267 82l54 243l171 -39q1 -32 23.5 -54t53.5 -22q32 0 54.5 22.5t22.5 54.5t-22.5 54.5t-54.5 22.5q-48 0 -69 -43l-189 42q-17 5 -21 -13l-60 -268q-154 -6 -265 -83
-q-30 32 -74 32q-43 0 -73 -30t-30 -72q0 -30 16 -55t42 -38q-5 -25 -5 -48q0 -122 120 -208.5t289 -86.5q170 0 290 86.5t120 208.5q0 25 -6 49q25 13 40.5 37.5t15.5 54.5zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960
-q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
-    <glyph glyph-name="_393" unicode="&#xf1a3;" 
-d="M866 697l90 27v62q0 79 -58 135t-138 56t-138 -55.5t-58 -134.5v-283q0 -20 -14 -33.5t-33 -13.5t-32.5 13.5t-13.5 33.5v120h-151v-122q0 -82 57.5 -139t139.5 -57q81 0 138.5 56.5t57.5 136.5v280q0 19 13.5 33t33.5 14q19 0 32.5 -14t13.5 -33v-54zM1199 502v122h-150
-v-126q0 -20 -13.5 -33.5t-33.5 -13.5q-19 0 -32.5 14t-13.5 33v123l-90 -26l-60 28v-123q0 -80 58 -137t139 -57t138.5 57t57.5 139zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103
-t385.5 -103t279.5 -279.5t103 -385.5z" />
-    <glyph glyph-name="f1a4" unicode="&#xf1a4;" horiz-adv-x="1920" 
-d="M1062 824v118q0 42 -30 72t-72 30t-72 -30t-30 -72v-612q0 -175 -126 -299t-303 -124q-178 0 -303.5 125.5t-125.5 303.5v266h328v-262q0 -43 30 -72.5t72 -29.5t72 29.5t30 72.5v620q0 171 126.5 292t301.5 121q176 0 302 -122t126 -294v-136l-195 -58zM1592 602h328
-v-266q0 -178 -125.5 -303.5t-303.5 -125.5q-177 0 -303 124.5t-126 300.5v268l131 -61l195 58v-270q0 -42 30 -71.5t72 -29.5t72 29.5t30 71.5v275z" />
-    <glyph glyph-name="_395" unicode="&#xf1a5;" 
-d="M1472 160v480h-704v704h-480q-93 0 -158.5 -65.5t-65.5 -158.5v-480h704v-704h480q93 0 158.5 65.5t65.5 158.5zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5
-t84.5 -203.5z" />
-    <glyph glyph-name="_396" unicode="&#xf1a6;" horiz-adv-x="2048" 
-d="M328 1254h204v-983h-532v697h328v286zM328 435v369h-123v-369h123zM614 968v-697h205v697h-205zM614 1254v-204h205v204h-205zM901 968h533v-942h-533v163h328v82h-328v697zM1229 435v369h-123v-369h123zM1516 968h532v-942h-532v163h327v82h-327v697zM1843 435v369h-123
-v-369h123z" />
-    <glyph glyph-name="_397" unicode="&#xf1a7;" 
-d="M1046 516q0 -64 -38 -109t-91 -45q-43 0 -70 15v277q28 17 70 17q53 0 91 -45.5t38 -109.5zM703 944q0 -64 -38 -109.5t-91 -45.5q-43 0 -70 15v277q28 17 70 17q53 0 91 -45t38 -109zM1265 513q0 134 -88 229t-213 95q-20 0 -39 -3q-23 -78 -78 -136q-87 -95 -211 -101
-v-636l211 41v206q51 -19 117 -19q125 0 213 95t88 229zM922 940q0 134 -88.5 229t-213.5 95q-74 0 -141 -36h-186v-840l211 41v206q55 -19 116 -19q125 0 213.5 95t88.5 229zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960
-q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
-    <glyph glyph-name="_398" unicode="&#xf1a8;" horiz-adv-x="2038" 
-d="M1222 607q75 3 143.5 -20.5t118 -58.5t101 -94.5t84 -108t75.5 -120.5q33 -56 78.5 -109t75.5 -80.5t99 -88.5q-48 -30 -108.5 -57.5t-138.5 -59t-114 -47.5q-44 37 -74 115t-43.5 164.5t-33 180.5t-42.5 168.5t-72.5 123t-122.5 48.5l-10 -2l-6 -4q4 -5 13 -14
-q6 -5 28 -23.5t25.5 -22t19 -18t18 -20.5t11.5 -21t10.5 -27.5t4.5 -31t4 -40.5l1 -33q1 -26 -2.5 -57.5t-7.5 -52t-12.5 -58.5t-11.5 -53q-35 1 -101 -9.5t-98 -10.5q-39 0 -72 10q-2 16 -2 47q0 74 3 96q2 13 31.5 41.5t57 59t26.5 51.5q-24 2 -43 -24
-q-36 -53 -111.5 -99.5t-136.5 -46.5q-25 0 -75.5 63t-106.5 139.5t-84 96.5q-6 4 -27 30q-482 -112 -513 -112q-16 0 -28 11t-12 27q0 15 8.5 26.5t22.5 14.5l486 106q-8 14 -8 25t5.5 17.5t16 11.5t20 7t23 4.5t18.5 4.5q4 1 15.5 7.5t17.5 6.5q15 0 28 -16t20 -33
-q163 37 172 37q17 0 29.5 -11t12.5 -28q0 -15 -8.5 -26t-23.5 -14l-182 -40l-1 -16q-1 -26 81.5 -117.5t104.5 -91.5q47 0 119 80t72 129q0 36 -23.5 53t-51 18.5t-51 11.5t-23.5 34q0 16 10 34l-68 19q43 44 43 117q0 26 -5 58q82 16 144 16q44 0 71.5 -1.5t48.5 -8.5
-t31 -13.5t20.5 -24.5t15.5 -33.5t17 -47.5t24 -60l50 25q-3 -40 -23 -60t-42.5 -21t-40 -6.5t-16.5 -20.5zM1282 842q-5 5 -13.5 15.5t-12 14.5t-10.5 11.5t-10 10.5l-8 8t-8.5 7.5t-8 5t-8.5 4.5q-7 3 -14.5 5t-20.5 2.5t-22 0.5h-32.5h-37.5q-126 0 -217 -43
-q16 30 36 46.5t54 29.5t65.5 36t46 36.5t50 55t43.5 50.5q12 -9 28 -31.5t32 -36.5t38 -13l12 1v-76l22 -1q247 95 371 190q28 21 50 39t42.5 37.5t33 31t29.5 34t24 31t24.5 37t23 38t27 47.5t29.5 53l7 9q-2 -53 -43 -139q-79 -165 -205 -264t-306 -142q-14 -3 -42 -7.5
-t-50 -9.5t-39 -14q3 -19 24.5 -46t21.5 -34q0 -11 -26 -30zM1061 -79q39 26 131.5 47.5t146.5 21.5q9 0 22.5 -15.5t28 -42.5t26 -50t24 -51t14.5 -33q-121 -45 -244 -45q-61 0 -125 11zM822 568l48 12l109 -177l-73 -48zM1323 51q3 -15 3 -16q0 -7 -17.5 -14.5t-46 -13
-t-54 -9.5t-53.5 -7.5t-32 -4.5l-7 43q21 2 60.5 8.5t72 10t60.5 3.5h14zM866 679l-96 -20l-6 17q10 1 32.5 7t34.5 6q19 0 35 -10zM1061 45h31l10 -83l-41 -12v95zM1950 1535v1v-1zM1950 1535l-1 -5l-2 -2l1 3zM1950 1535l1 1z" />
-    <glyph glyph-name="_399" unicode="&#xf1a9;" 
-d="M1167 -50q-5 19 -24 5q-30 -22 -87 -39t-131 -17q-129 0 -193 49q-5 4 -13 4q-11 0 -26 -12q-7 -6 -7.5 -16t7.5 -20q34 -32 87.5 -46t102.5 -12.5t99 4.5q41 4 84.5 20.5t65 30t28.5 20.5q12 12 7 29zM1128 65q-19 47 -39 61q-23 15 -76 15q-47 0 -71 -10
-q-29 -12 -78 -56q-26 -24 -12 -44q9 -8 17.5 -4.5t31.5 23.5q3 2 10.5 8.5t10.5 8.5t10 7t11.5 7t12.5 5t15 4.5t16.5 2.5t20.5 1q27 0 44.5 -7.5t23 -14.5t13.5 -22q10 -17 12.5 -20t12.5 1q23 12 14 34zM1483 346q0 22 -5 44.5t-16.5 45t-34 36.5t-52.5 14
-q-33 0 -97 -41.5t-129 -83.5t-101 -42q-27 -1 -63.5 19t-76 49t-83.5 58t-100 49t-111 19q-115 -1 -197 -78.5t-84 -178.5q-2 -112 74 -164q29 -20 62.5 -28.5t103.5 -8.5q57 0 132 32.5t134 71t120 70.5t93 31q26 -1 65 -31.5t71.5 -67t68 -67.5t55.5 -32q35 -3 58.5 14
-t55.5 63q28 41 42.5 101t14.5 106zM1536 506q0 -164 -62 -304.5t-166 -236t-242.5 -149.5t-290.5 -54t-293 57.5t-247.5 157t-170.5 241.5t-64 302q0 89 19.5 172.5t49 145.5t70.5 118.5t78.5 94t78.5 69.5t64.5 46.5t42.5 24.5q14 8 51 26.5t54.5 28.5t48 30t60.5 44
-q36 28 58 72.5t30 125.5q129 -155 186 -193q44 -29 130 -68t129 -66q21 -13 39 -25t60.5 -46.5t76 -70.5t75 -95t69 -122t47 -148.5t19.5 -177.5z" />
-    <glyph glyph-name="_400" unicode="&#xf1aa;" 
-d="M1070 463l-160 -160l-151 -152l-30 -30q-65 -64 -151.5 -87t-171.5 -2q-16 -70 -72 -115t-129 -45q-85 0 -145 60.5t-60 145.5q0 72 44.5 128t113.5 72q-22 86 1 173t88 152l12 12l151 -152l-11 -11q-37 -37 -37 -89t37 -90q37 -37 89 -37t89 37l30 30l151 152l161 160z
-M729 1145l12 -12l-152 -152l-12 12q-37 37 -89 37t-89 -37t-37 -89.5t37 -89.5l29 -29l152 -152l160 -160l-151 -152l-161 160l-151 152l-30 30q-68 67 -90 159.5t5 179.5q-70 15 -115 71t-45 129q0 85 60 145.5t145 60.5q76 0 133.5 -49t69.5 -123q84 20 169.5 -3.5
-t149.5 -87.5zM1536 78q0 -85 -60 -145.5t-145 -60.5q-74 0 -131 47t-71 118q-86 -28 -179.5 -6t-161.5 90l-11 12l151 152l12 -12q37 -37 89 -37t89 37t37 89t-37 89l-30 30l-152 152l-160 160l152 152l160 -160l152 -152l29 -30q64 -64 87.5 -150.5t2.5 -171.5
-q76 -11 126.5 -68.5t50.5 -134.5zM1534 1202q0 -77 -51 -135t-127 -69q26 -85 3 -176.5t-90 -158.5l-12 -12l-151 152l12 12q37 37 37 89t-37 89t-89 37t-89 -37l-30 -30l-152 -152l-160 -160l-152 152l161 160l152 152l29 30q67 67 159 89.5t178 -3.5q11 75 68.5 126
-t135.5 51q85 0 145 -60.5t60 -145.5z" />
-    <glyph glyph-name="f1ab" unicode="&#xf1ab;" 
-d="M654 458q-1 -3 -12.5 0.5t-31.5 11.5l-20 9q-44 20 -87 49q-7 5 -41 31.5t-38 28.5q-67 -103 -134 -181q-81 -95 -105 -110q-4 -2 -19.5 -4t-18.5 0q6 4 82 92q21 24 85.5 115t78.5 118q17 30 51 98.5t36 77.5q-8 1 -110 -33q-8 -2 -27.5 -7.5t-34.5 -9.5t-17 -5
-q-2 -2 -2 -10.5t-1 -9.5q-5 -10 -31 -15q-23 -7 -47 0q-18 4 -28 21q-4 6 -5 23q6 2 24.5 5t29.5 6q58 16 105 32q100 35 102 35q10 2 43 19.5t44 21.5q9 3 21.5 8t14.5 5.5t6 -0.5q2 -12 -1 -33q0 -2 -12.5 -27t-26.5 -53.5t-17 -33.5q-25 -50 -77 -131l64 -28
-q12 -6 74.5 -32t67.5 -28q4 -1 10.5 -25.5t4.5 -30.5zM449 944q3 -15 -4 -28q-12 -23 -50 -38q-30 -12 -60 -12q-26 3 -49 26q-14 15 -18 41l1 3q3 -3 19.5 -5t26.5 0t58 16q36 12 55 14q17 0 21 -17zM1147 815l63 -227l-139 42zM39 15l694 232v1032l-694 -233v-1031z
-M1280 332l102 -31l-181 657l-100 31l-216 -536l102 -31l45 110l211 -65zM777 1294l573 -184v380zM1088 -29l158 -13l-54 -160l-40 66q-130 -83 -276 -108q-58 -12 -91 -12h-84q-79 0 -199.5 39t-183.5 85q-8 7 -8 16q0 8 5 13.5t13 5.5q4 0 18 -7.5t30.5 -16.5t20.5 -11
-q73 -37 159.5 -61.5t157.5 -24.5q95 0 167 14.5t157 50.5q15 7 30.5 15.5t34 19t28.5 16.5zM1536 1050v-1079l-774 246q-14 -6 -375 -127.5t-368 -121.5q-13 0 -18 13q0 1 -1 3v1078q3 9 4 10q5 6 20 11q107 36 149 50v384l558 -198q2 0 160.5 55t316 108.5t161.5 53.5
-q20 0 20 -21v-418z" />
-    <glyph glyph-name="_402" unicode="&#xf1ac;" horiz-adv-x="1792" 
-d="M288 1152q66 0 113 -47t47 -113v-1088q0 -66 -47 -113t-113 -47h-128q-66 0 -113 47t-47 113v1088q0 66 47 113t113 47h128zM1664 989q58 -34 93 -93t35 -128v-768q0 -106 -75 -181t-181 -75h-864q-66 0 -113 47t-47 113v1536q0 40 28 68t68 28h672q40 0 88 -20t76 -48
-l152 -152q28 -28 48 -76t20 -88v-163zM928 0v128q0 14 -9 23t-23 9h-128q-14 0 -23 -9t-9 -23v-128q0 -14 9 -23t23 -9h128q14 0 23 9t9 23zM928 256v128q0 14 -9 23t-23 9h-128q-14 0 -23 -9t-9 -23v-128q0 -14 9 -23t23 -9h128q14 0 23 9t9 23zM928 512v128q0 14 -9 23
-t-23 9h-128q-14 0 -23 -9t-9 -23v-128q0 -14 9 -23t23 -9h128q14 0 23 9t9 23zM1184 0v128q0 14 -9 23t-23 9h-128q-14 0 -23 -9t-9 -23v-128q0 -14 9 -23t23 -9h128q14 0 23 9t9 23zM1184 256v128q0 14 -9 23t-23 9h-128q-14 0 -23 -9t-9 -23v-128q0 -14 9 -23t23 -9h128
-q14 0 23 9t9 23zM1184 512v128q0 14 -9 23t-23 9h-128q-14 0 -23 -9t-9 -23v-128q0 -14 9 -23t23 -9h128q14 0 23 9t9 23zM1440 0v128q0 14 -9 23t-23 9h-128q-14 0 -23 -9t-9 -23v-128q0 -14 9 -23t23 -9h128q14 0 23 9t9 23zM1440 256v128q0 14 -9 23t-23 9h-128
-q-14 0 -23 -9t-9 -23v-128q0 -14 9 -23t23 -9h128q14 0 23 9t9 23zM1440 512v128q0 14 -9 23t-23 9h-128q-14 0 -23 -9t-9 -23v-128q0 -14 9 -23t23 -9h128q14 0 23 9t9 23zM1536 896v256h-160q-40 0 -68 28t-28 68v160h-640v-512h896z" />
-    <glyph glyph-name="_403" unicode="&#xf1ad;" 
-d="M1344 1536q26 0 45 -19t19 -45v-1664q0 -26 -19 -45t-45 -19h-1280q-26 0 -45 19t-19 45v1664q0 26 19 45t45 19h1280zM512 1248v-64q0 -14 9 -23t23 -9h64q14 0 23 9t9 23v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23zM512 992v-64q0 -14 9 -23t23 -9h64q14 0 23 9
-t9 23v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23zM512 736v-64q0 -14 9 -23t23 -9h64q14 0 23 9t9 23v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23zM512 480v-64q0 -14 9 -23t23 -9h64q14 0 23 9t9 23v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23zM384 160v64
-q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM384 416v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM384 672v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h64
-q14 0 23 9t9 23zM384 928v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM384 1184v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM896 -96v192q0 14 -9 23t-23 9h-320q-14 0 -23 -9
-t-9 -23v-192q0 -14 9 -23t23 -9h320q14 0 23 9t9 23zM896 416v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM896 672v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM896 928v64
-q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM896 1184v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM1152 160v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h64
-q14 0 23 9t9 23zM1152 416v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM1152 672v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM1152 928v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9
-t-9 -23v-64q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM1152 1184v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h64q14 0 23 9t9 23z" />
-    <glyph glyph-name="_404" unicode="&#xf1ae;" horiz-adv-x="1280" 
-d="M1188 988l-292 -292v-824q0 -46 -33 -79t-79 -33t-79 33t-33 79v384h-64v-384q0 -46 -33 -79t-79 -33t-79 33t-33 79v824l-292 292q-28 28 -28 68t28 68q29 28 68.5 28t67.5 -28l228 -228h368l228 228q28 28 68 28t68 -28q28 -29 28 -68.5t-28 -67.5zM864 1152
-q0 -93 -65.5 -158.5t-158.5 -65.5t-158.5 65.5t-65.5 158.5t65.5 158.5t158.5 65.5t158.5 -65.5t65.5 -158.5z" />
-    <glyph glyph-name="uniF1B1" unicode="&#xf1b0;" horiz-adv-x="1664" 
-d="M780 1064q0 -60 -19 -113.5t-63 -92.5t-105 -39q-76 0 -138 57.5t-92 135.5t-30 151q0 60 19 113.5t63 92.5t105 39q77 0 138.5 -57.5t91.5 -135t30 -151.5zM438 581q0 -80 -42 -139t-119 -59q-76 0 -141.5 55.5t-100.5 133.5t-35 152q0 80 42 139.5t119 59.5
-q76 0 141.5 -55.5t100.5 -134t35 -152.5zM832 608q118 0 255 -97.5t229 -237t92 -254.5q0 -46 -17 -76.5t-48.5 -45t-64.5 -20t-76 -5.5q-68 0 -187.5 45t-182.5 45q-66 0 -192.5 -44.5t-200.5 -44.5q-183 0 -183 146q0 86 56 191.5t139.5 192.5t187.5 146t193 59zM1071 819
-q-61 0 -105 39t-63 92.5t-19 113.5q0 74 30 151.5t91.5 135t138.5 57.5q61 0 105 -39t63 -92.5t19 -113.5q0 -73 -30 -151t-92 -135.5t-138 -57.5zM1503 923q77 0 119 -59.5t42 -139.5q0 -74 -35 -152t-100.5 -133.5t-141.5 -55.5q-77 0 -119 59t-42 139q0 74 35 152.5
-t100.5 134t141.5 55.5z" />
-    <glyph glyph-name="_406" unicode="&#xf1b1;" horiz-adv-x="768" 
-d="M704 1008q0 -145 -57 -243.5t-152 -135.5l45 -821q2 -26 -16 -45t-44 -19h-192q-26 0 -44 19t-16 45l45 821q-95 37 -152 135.5t-57 243.5q0 128 42.5 249.5t117.5 200t160 78.5t160 -78.5t117.5 -200t42.5 -249.5z" />
-    <glyph glyph-name="_407" unicode="&#xf1b2;" horiz-adv-x="1792" 
-d="M896 -93l640 349v636l-640 -233v-752zM832 772l698 254l-698 254l-698 -254zM1664 1024v-768q0 -35 -18 -65t-49 -47l-704 -384q-28 -16 -61 -16t-61 16l-704 384q-31 17 -49 47t-18 65v768q0 40 23 73t61 47l704 256q22 8 44 8t44 -8l704 -256q38 -14 61 -47t23 -73z
-" />
-    <glyph glyph-name="_408" unicode="&#xf1b3;" horiz-adv-x="2304" 
-d="M640 -96l384 192v314l-384 -164v-342zM576 358l404 173l-404 173l-404 -173zM1664 -96l384 192v314l-384 -164v-342zM1600 358l404 173l-404 173l-404 -173zM1152 651l384 165v266l-384 -164v-267zM1088 1030l441 189l-441 189l-441 -189zM2176 512v-416q0 -36 -19 -67
-t-52 -47l-448 -224q-25 -14 -57 -14t-57 14l-448 224q-4 2 -7 4q-2 -2 -7 -4l-448 -224q-25 -14 -57 -14t-57 14l-448 224q-33 16 -52 47t-19 67v416q0 38 21.5 70t56.5 48l434 186v400q0 38 21.5 70t56.5 48l448 192q23 10 50 10t50 -10l448 -192q35 -16 56.5 -48t21.5 -70
-v-400l434 -186q36 -16 57 -48t21 -70z" />
-    <glyph glyph-name="_409" unicode="&#xf1b4;" horiz-adv-x="2048" 
-d="M1848 1197h-511v-124h511v124zM1596 771q-90 0 -146 -52.5t-62 -142.5h408q-18 195 -200 195zM1612 186q63 0 122 32t76 87h221q-100 -307 -427 -307q-214 0 -340.5 132t-126.5 347q0 208 130.5 345.5t336.5 137.5q138 0 240.5 -68t153 -179t50.5 -248q0 -17 -2 -47h-658
-q0 -111 57.5 -171.5t166.5 -60.5zM277 236h296q205 0 205 167q0 180 -199 180h-302v-347zM277 773h281q78 0 123.5 36.5t45.5 113.5q0 144 -190 144h-260v-294zM0 1282h594q87 0 155 -14t126.5 -47.5t90 -96.5t31.5 -154q0 -181 -172 -263q114 -32 172 -115t58 -204
-q0 -75 -24.5 -136.5t-66 -103.5t-98.5 -71t-121 -42t-134 -13h-611v1260z" />
-    <glyph glyph-name="_410" unicode="&#xf1b5;" 
-d="M1248 1408q119 0 203.5 -84.5t84.5 -203.5v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960zM499 1041h-371v-787h382q117 0 197 57.5t80 170.5q0 158 -143 200q107 52 107 164q0 57 -19.5 96.5
-t-56.5 60.5t-79 29.5t-97 8.5zM477 723h-176v184h163q119 0 119 -90q0 -94 -106 -94zM486 388h-185v217h189q124 0 124 -113q0 -104 -128 -104zM1136 356q-68 0 -104 38t-36 107h411q1 10 1 30q0 132 -74.5 220.5t-203.5 88.5q-128 0 -210 -86t-82 -216q0 -135 79 -217
-t213 -82q205 0 267 191h-138q-11 -34 -47.5 -54t-75.5 -20zM1126 722q113 0 124 -122h-254q4 56 39 89t91 33zM964 988h319v-77h-319v77z" />
-    <glyph glyph-name="_411" unicode="&#xf1b6;" horiz-adv-x="1792" 
-d="M1582 954q0 -101 -71.5 -172.5t-172.5 -71.5t-172.5 71.5t-71.5 172.5t71.5 172.5t172.5 71.5t172.5 -71.5t71.5 -172.5zM812 212q0 104 -73 177t-177 73q-27 0 -54 -6l104 -42q77 -31 109.5 -106.5t1.5 -151.5q-31 -77 -107 -109t-152 -1q-21 8 -62 24.5t-61 24.5
-q32 -60 91 -96.5t130 -36.5q104 0 177 73t73 177zM1642 953q0 126 -89.5 215.5t-215.5 89.5q-127 0 -216.5 -89.5t-89.5 -215.5q0 -127 89.5 -216t216.5 -89q126 0 215.5 89t89.5 216zM1792 953q0 -189 -133.5 -322t-321.5 -133l-437 -319q-12 -129 -109 -218t-229 -89
-q-121 0 -214 76t-118 192l-230 92v429l389 -157q79 48 173 48q13 0 35 -2l284 407q2 187 135.5 319t320.5 132q188 0 321.5 -133.5t133.5 -321.5z" />
-    <glyph glyph-name="_412" unicode="&#xf1b7;" 
-d="M1242 889q0 80 -57 136.5t-137 56.5t-136.5 -57t-56.5 -136q0 -80 56.5 -136.5t136.5 -56.5t137 56.5t57 136.5zM632 301q0 -83 -58 -140.5t-140 -57.5q-56 0 -103 29t-72 77q52 -20 98 -40q60 -24 120 1.5t85 86.5q24 60 -1.5 120t-86.5 84l-82 33q22 5 42 5
-q82 0 140 -57.5t58 -140.5zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v153l172 -69q20 -92 93.5 -152t168.5 -60q104 0 181 70t87 173l345 252q150 0 255.5 105.5t105.5 254.5q0 150 -105.5 255.5t-255.5 105.5
-q-148 0 -253 -104.5t-107 -252.5l-225 -322q-9 1 -28 1q-75 0 -137 -37l-297 119v468q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5zM1289 887q0 -100 -71 -170.5t-171 -70.5t-170.5 70.5t-70.5 170.5t70.5 171t170.5 71q101 0 171.5 -70.5t70.5 -171.5z
-" />
-    <glyph glyph-name="_413" unicode="&#xf1b8;" horiz-adv-x="1792" 
-d="M836 367l-15 -368l-2 -22l-420 29q-36 3 -67 31.5t-47 65.5q-11 27 -14.5 55t4 65t12 55t21.5 64t19 53q78 -12 509 -28zM449 953l180 -379l-147 92q-63 -72 -111.5 -144.5t-72.5 -125t-39.5 -94.5t-18.5 -63l-4 -21l-190 357q-17 26 -18 56t6 47l8 18q35 63 114 188
-l-140 86zM1680 436l-188 -359q-12 -29 -36.5 -46.5t-43.5 -20.5l-18 -4q-71 -7 -219 -12l8 -164l-230 367l211 362l7 -173q170 -16 283 -5t170 33zM895 1360q-47 -63 -265 -435l-317 187l-19 12l225 356q20 31 60 45t80 10q24 -2 48.5 -12t42 -21t41.5 -33t36 -34.5
-t36 -39.5t32 -35zM1550 1053l212 -363q18 -37 12.5 -76t-27.5 -74q-13 -20 -33 -37t-38 -28t-48.5 -22t-47 -16t-51.5 -14t-46 -12q-34 72 -265 436l313 195zM1407 1279l142 83l-220 -373l-419 20l151 86q-34 89 -75 166t-75.5 123.5t-64.5 80t-47 46.5l-17 13l405 -1
-q31 3 58 -10.5t39 -28.5l11 -15q39 -61 112 -190z" />
-    <glyph glyph-name="_414" unicode="&#xf1b9;" horiz-adv-x="2048" 
-d="M480 448q0 66 -47 113t-113 47t-113 -47t-47 -113t47 -113t113 -47t113 47t47 113zM516 768h1016l-89 357q-2 8 -14 17.5t-21 9.5h-768q-9 0 -21 -9.5t-14 -17.5zM1888 448q0 66 -47 113t-113 47t-113 -47t-47 -113t47 -113t113 -47t113 47t47 113zM2048 544v-384
-q0 -14 -9 -23t-23 -9h-96v-128q0 -80 -56 -136t-136 -56t-136 56t-56 136v128h-1024v-128q0 -80 -56 -136t-136 -56t-136 56t-56 136v128h-96q-14 0 -23 9t-9 23v384q0 93 65.5 158.5t158.5 65.5h28l105 419q23 94 104 157.5t179 63.5h768q98 0 179 -63.5t104 -157.5
-l105 -419h28q93 0 158.5 -65.5t65.5 -158.5z" />
-    <glyph glyph-name="_415" unicode="&#xf1ba;" horiz-adv-x="2048" 
-d="M1824 640q93 0 158.5 -65.5t65.5 -158.5v-384q0 -14 -9 -23t-23 -9h-96v-64q0 -80 -56 -136t-136 -56t-136 56t-56 136v64h-1024v-64q0 -80 -56 -136t-136 -56t-136 56t-56 136v64h-96q-14 0 -23 9t-9 23v384q0 93 65.5 158.5t158.5 65.5h28l105 419q23 94 104 157.5
-t179 63.5h128v224q0 14 9 23t23 9h448q14 0 23 -9t9 -23v-224h128q98 0 179 -63.5t104 -157.5l105 -419h28zM320 160q66 0 113 47t47 113t-47 113t-113 47t-113 -47t-47 -113t47 -113t113 -47zM516 640h1016l-89 357q-2 8 -14 17.5t-21 9.5h-768q-9 0 -21 -9.5t-14 -17.5z
-M1728 160q66 0 113 47t47 113t-47 113t-113 47t-113 -47t-47 -113t47 -113t113 -47z" />
-    <glyph glyph-name="_416" unicode="&#xf1bb;" 
-d="M1504 64q0 -26 -19 -45t-45 -19h-462q1 -17 6 -87.5t5 -108.5q0 -25 -18 -42.5t-43 -17.5h-320q-25 0 -43 17.5t-18 42.5q0 38 5 108.5t6 87.5h-462q-26 0 -45 19t-19 45t19 45l402 403h-229q-26 0 -45 19t-19 45t19 45l402 403h-197q-26 0 -45 19t-19 45t19 45l384 384
-q19 19 45 19t45 -19l384 -384q19 -19 19 -45t-19 -45t-45 -19h-197l402 -403q19 -19 19 -45t-19 -45t-45 -19h-229l402 -403q19 -19 19 -45z" />
-    <glyph glyph-name="_417" unicode="&#xf1bc;" 
-d="M1127 326q0 32 -30 51q-193 115 -447 115q-133 0 -287 -34q-42 -9 -42 -52q0 -20 13.5 -34.5t35.5 -14.5q5 0 37 8q132 27 243 27q226 0 397 -103q19 -11 33 -11q19 0 33 13.5t14 34.5zM1223 541q0 40 -35 61q-237 141 -548 141q-153 0 -303 -42q-48 -13 -48 -64
-q0 -25 17.5 -42.5t42.5 -17.5q7 0 37 8q122 33 251 33q279 0 488 -124q24 -13 38 -13q25 0 42.5 17.5t17.5 42.5zM1331 789q0 47 -40 70q-126 73 -293 110.5t-343 37.5q-204 0 -364 -47q-23 -7 -38.5 -25.5t-15.5 -48.5q0 -31 20.5 -52t51.5 -21q11 0 40 8q133 37 307 37
-q159 0 309.5 -34t253.5 -95q21 -12 40 -12q29 0 50.5 20.5t21.5 51.5zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
-    <glyph glyph-name="_418" unicode="&#xf1bd;" horiz-adv-x="1024" 
-d="M1024 1233l-303 -582l24 -31h279v-415h-507l-44 -30l-142 -273l-30 -30h-301v303l303 583l-24 30h-279v415h507l44 30l142 273l30 30h301v-303z" />
-    <glyph glyph-name="_419" unicode="&#xf1be;" horiz-adv-x="2304" 
-d="M784 164l16 241l-16 523q-1 10 -7.5 17t-16.5 7q-9 0 -16 -7t-7 -17l-14 -523l14 -241q1 -10 7.5 -16.5t15.5 -6.5q22 0 24 23zM1080 193l11 211l-12 586q0 16 -13 24q-8 5 -16 5t-16 -5q-13 -8 -13 -24l-1 -6l-10 -579q0 -1 11 -236v-1q0 -10 6 -17q9 -11 23 -11
-q11 0 20 9q9 7 9 20zM35 533l20 -128l-20 -126q-2 -9 -9 -9t-9 9l-17 126l17 128q2 9 9 9t9 -9zM121 612l26 -207l-26 -203q-2 -9 -10 -9q-9 0 -9 10l-23 202l23 207q0 9 9 9q8 0 10 -9zM401 159zM213 650l25 -245l-25 -237q0 -11 -11 -11q-10 0 -12 11l-21 237l21 245
-q2 12 12 12q11 0 11 -12zM307 657l23 -252l-23 -244q-2 -13 -14 -13q-13 0 -13 13l-21 244l21 252q0 13 13 13q12 0 14 -13zM401 639l21 -234l-21 -246q-2 -16 -16 -16q-6 0 -10.5 4.5t-4.5 11.5l-20 246l20 234q0 6 4.5 10.5t10.5 4.5q14 0 16 -15zM784 164zM495 785
-l21 -380l-21 -246q0 -7 -5 -12.5t-12 -5.5q-16 0 -18 18l-18 246l18 380q2 18 18 18q7 0 12 -5.5t5 -12.5zM589 871l19 -468l-19 -244q0 -8 -5.5 -13.5t-13.5 -5.5q-18 0 -20 19l-16 244l16 468q2 19 20 19q8 0 13.5 -5.5t5.5 -13.5zM687 911l18 -506l-18 -242
-q-2 -21 -22 -21q-19 0 -21 21l-16 242l16 506q0 9 6.5 15.5t14.5 6.5q9 0 15 -6.5t7 -15.5zM1079 169v0v0v0zM881 915l15 -510l-15 -239q0 -10 -7.5 -17.5t-17.5 -7.5t-17 7t-8 18l-14 239l14 510q0 11 7.5 18t17.5 7t17.5 -7t7.5 -18zM980 896l14 -492l-14 -236
-q0 -11 -8 -19t-19 -8t-19 8t-9 19l-12 236l12 492q1 12 9 20t19 8t18.5 -8t8.5 -20zM1192 404l-14 -231v0q0 -13 -9 -22t-22 -9t-22 9t-10 22l-6 114l-6 117l12 636v3q2 15 12 24q9 7 20 7q8 0 15 -5q14 -8 16 -26zM2304 423q0 -117 -83 -199.5t-200 -82.5h-786
-q-13 2 -22 11t-9 22v899q0 23 28 33q85 34 181 34q195 0 338 -131.5t160 -323.5q53 22 110 22q117 0 200 -83t83 -201z" />
-    <glyph glyph-name="uniF1C0" unicode="&#xf1c0;" 
-d="M768 768q237 0 443 43t325 127v-170q0 -69 -103 -128t-280 -93.5t-385 -34.5t-385 34.5t-280 93.5t-103 128v170q119 -84 325 -127t443 -43zM768 0q237 0 443 43t325 127v-170q0 -69 -103 -128t-280 -93.5t-385 -34.5t-385 34.5t-280 93.5t-103 128v170q119 -84 325 -127
-t443 -43zM768 384q237 0 443 43t325 127v-170q0 -69 -103 -128t-280 -93.5t-385 -34.5t-385 34.5t-280 93.5t-103 128v170q119 -84 325 -127t443 -43zM768 1536q208 0 385 -34.5t280 -93.5t103 -128v-128q0 -69 -103 -128t-280 -93.5t-385 -34.5t-385 34.5t-280 93.5
-t-103 128v128q0 69 103 128t280 93.5t385 34.5z" />
-    <glyph glyph-name="uniF1C1" unicode="&#xf1c1;" 
-d="M1468 1156q28 -28 48 -76t20 -88v-1152q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68v1600q0 40 28 68t68 28h896q40 0 88 -20t76 -48zM1024 1400v-376h376q-10 29 -22 41l-313 313q-12 12 -41 22zM1408 -128v1024h-416q-40 0 -68 28t-28 68v416h-768v-1536h1280z
-M894 465q33 -26 84 -56q59 7 117 7q147 0 177 -49q16 -22 2 -52q0 -1 -1 -2l-2 -2v-1q-6 -38 -71 -38q-48 0 -115 20t-130 53q-221 -24 -392 -83q-153 -262 -242 -262q-15 0 -28 7l-24 12q-1 1 -6 5q-10 10 -6 36q9 40 56 91.5t132 96.5q14 9 23 -6q2 -2 2 -4q52 85 107 197
-q68 136 104 262q-24 82 -30.5 159.5t6.5 127.5q11 40 42 40h21h1q23 0 35 -15q18 -21 9 -68q-2 -6 -4 -8q1 -3 1 -8v-30q-2 -123 -14 -192q55 -164 146 -238zM318 54q52 24 137 158q-51 -40 -87.5 -84t-49.5 -74zM716 974q-15 -42 -2 -132q1 7 7 44q0 3 7 43q1 4 4 8
-q-1 1 -1 2q-1 2 -1 3q-1 22 -13 36q0 -1 -1 -2v-2zM592 313q135 54 284 81q-2 1 -13 9.5t-16 13.5q-76 67 -127 176q-27 -86 -83 -197q-30 -56 -45 -83zM1238 329q-24 24 -140 24q76 -28 124 -28q14 0 18 1q0 1 -2 3z" />
-    <glyph glyph-name="_422" unicode="&#xf1c2;" 
-d="M1468 1156q28 -28 48 -76t20 -88v-1152q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68v1600q0 40 28 68t68 28h896q40 0 88 -20t76 -48zM1024 1400v-376h376q-10 29 -22 41l-313 313q-12 12 -41 22zM1408 -128v1024h-416q-40 0 -68 28t-28 68v416h-768v-1536h1280z
-M233 768v-107h70l164 -661h159l128 485q7 20 10 46q2 16 2 24h4l3 -24q1 -3 3.5 -20t5.5 -26l128 -485h159l164 661h70v107h-300v-107h90l-99 -438q-5 -20 -7 -46l-2 -21h-4q0 3 -0.5 6.5t-1.5 8t-1 6.5q-1 5 -4 21t-5 25l-144 545h-114l-144 -545q-2 -9 -4.5 -24.5
-t-3.5 -21.5l-4 -21h-4l-2 21q-2 26 -7 46l-99 438h90v107h-300z" />
-    <glyph glyph-name="_423" unicode="&#xf1c3;" 
-d="M1468 1156q28 -28 48 -76t20 -88v-1152q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68v1600q0 40 28 68t68 28h896q40 0 88 -20t76 -48zM1024 1400v-376h376q-10 29 -22 41l-313 313q-12 12 -41 22zM1408 -128v1024h-416q-40 0 -68 28t-28 68v416h-768v-1536h1280z
-M429 106v-106h281v106h-75l103 161q5 7 10 16.5t7.5 13.5t3.5 4h2q1 -4 5 -10q2 -4 4.5 -7.5t6 -8t6.5 -8.5l107 -161h-76v-106h291v106h-68l-192 273l195 282h67v107h-279v-107h74l-103 -159q-4 -7 -10 -16.5t-9 -13.5l-2 -3h-2q-1 4 -5 10q-6 11 -17 23l-106 159h76v107
-h-290v-107h68l189 -272l-194 -283h-68z" />
-    <glyph glyph-name="_424" unicode="&#xf1c4;" 
-d="M1468 1156q28 -28 48 -76t20 -88v-1152q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68v1600q0 40 28 68t68 28h896q40 0 88 -20t76 -48zM1024 1400v-376h376q-10 29 -22 41l-313 313q-12 12 -41 22zM1408 -128v1024h-416q-40 0 -68 28t-28 68v416h-768v-1536h1280z
-M416 106v-106h327v106h-93v167h137q76 0 118 15q67 23 106.5 87t39.5 146q0 81 -37 141t-100 87q-48 19 -130 19h-368v-107h92v-555h-92zM769 386h-119v268h120q52 0 83 -18q56 -33 56 -115q0 -89 -62 -120q-31 -15 -78 -15z" />
-    <glyph glyph-name="_425" unicode="&#xf1c5;" 
-d="M1468 1156q28 -28 48 -76t20 -88v-1152q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68v1600q0 40 28 68t68 28h896q40 0 88 -20t76 -48zM1024 1400v-376h376q-10 29 -22 41l-313 313q-12 12 -41 22zM1408 -128v1024h-416q-40 0 -68 28t-28 68v416h-768v-1536h1280z
-M1280 320v-320h-1024v192l192 192l128 -128l384 384zM448 512q-80 0 -136 56t-56 136t56 136t136 56t136 -56t56 -136t-56 -136t-136 -56z" />
-    <glyph glyph-name="_426" unicode="&#xf1c6;" 
-d="M640 1152v128h-128v-128h128zM768 1024v128h-128v-128h128zM640 896v128h-128v-128h128zM768 768v128h-128v-128h128zM1468 1156q28 -28 48 -76t20 -88v-1152q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68v1600q0 40 28 68t68 28h896q40 0 88 -20t76 -48zM1024 1400
-v-376h376q-10 29 -22 41l-313 313q-12 12 -41 22zM1408 -128v1024h-416q-40 0 -68 28t-28 68v416h-128v-128h-128v128h-512v-1536h1280zM781 593l107 -349q8 -27 8 -52q0 -83 -72.5 -137.5t-183.5 -54.5t-183.5 54.5t-72.5 137.5q0 25 8 52q21 63 120 396v128h128v-128h79
-q22 0 39 -13t23 -34zM640 128q53 0 90.5 19t37.5 45t-37.5 45t-90.5 19t-90.5 -19t-37.5 -45t37.5 -45t90.5 -19z" />
-    <glyph glyph-name="_427" unicode="&#xf1c7;" 
-d="M1468 1156q28 -28 48 -76t20 -88v-1152q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68v1600q0 40 28 68t68 28h896q40 0 88 -20t76 -48zM1024 1400v-376h376q-10 29 -22 41l-313 313q-12 12 -41 22zM1408 -128v1024h-416q-40 0 -68 28t-28 68v416h-768v-1536h1280z
-M620 686q20 -8 20 -30v-544q0 -22 -20 -30q-8 -2 -12 -2q-12 0 -23 9l-166 167h-131q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h131l166 167q16 15 35 7zM1037 -3q31 0 50 24q129 159 129 363t-129 363q-16 21 -43 24t-47 -14q-21 -17 -23.5 -43.5t14.5 -47.5
-q100 -123 100 -282t-100 -282q-17 -21 -14.5 -47.5t23.5 -42.5q18 -15 40 -15zM826 145q27 0 47 20q87 93 87 219t-87 219q-18 19 -45 20t-46 -17t-20 -44.5t18 -46.5q52 -57 52 -131t-52 -131q-19 -20 -18 -46.5t20 -44.5q20 -17 44 -17z" />
-    <glyph glyph-name="_428" unicode="&#xf1c8;" 
-d="M1468 1156q28 -28 48 -76t20 -88v-1152q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68v1600q0 40 28 68t68 28h896q40 0 88 -20t76 -48zM1024 1400v-376h376q-10 29 -22 41l-313 313q-12 12 -41 22zM1408 -128v1024h-416q-40 0 -68 28t-28 68v416h-768v-1536h1280z
-M768 768q52 0 90 -38t38 -90v-384q0 -52 -38 -90t-90 -38h-384q-52 0 -90 38t-38 90v384q0 52 38 90t90 38h384zM1260 766q20 -8 20 -30v-576q0 -22 -20 -30q-8 -2 -12 -2q-14 0 -23 9l-265 266v90l265 266q9 9 23 9q4 0 12 -2z" />
-    <glyph glyph-name="_429" unicode="&#xf1c9;" 
-d="M1468 1156q28 -28 48 -76t20 -88v-1152q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68v1600q0 40 28 68t68 28h896q40 0 88 -20t76 -48zM1024 1400v-376h376q-10 29 -22 41l-313 313q-12 12 -41 22zM1408 -128v1024h-416q-40 0 -68 28t-28 68v416h-768v-1536h1280z
-M480 768q8 11 21 12.5t24 -6.5l51 -38q11 -8 12.5 -21t-6.5 -24l-182 -243l182 -243q8 -11 6.5 -24t-12.5 -21l-51 -38q-11 -8 -24 -6.5t-21 12.5l-226 301q-14 19 0 38zM1282 467q14 -19 0 -38l-226 -301q-8 -11 -21 -12.5t-24 6.5l-51 38q-11 8 -12.5 21t6.5 24l182 243
-l-182 243q-8 11 -6.5 24t12.5 21l51 38q11 8 24 6.5t21 -12.5zM662 6q-13 2 -20.5 13t-5.5 24l138 831q2 13 13 20.5t24 5.5l63 -10q13 -2 20.5 -13t5.5 -24l-138 -831q-2 -13 -13 -20.5t-24 -5.5z" />
-    <glyph glyph-name="_430" unicode="&#xf1ca;" 
-d="M1497 709v-198q-101 -23 -198 -23q-65 -136 -165.5 -271t-181.5 -215.5t-128 -106.5q-80 -45 -162 3q-28 17 -60.5 43.5t-85 83.5t-102.5 128.5t-107.5 184t-105.5 244t-91.5 314.5t-70.5 390h283q26 -218 70 -398.5t104.5 -317t121.5 -235.5t140 -195q169 169 287 406
-q-142 72 -223 220t-81 333q0 192 104 314.5t284 122.5q178 0 273 -105.5t95 -297.5q0 -159 -58 -286q-7 -1 -19.5 -3t-46 -2t-63 6t-62 25.5t-50.5 51.5q31 103 31 184q0 87 -29 132t-79 45q-53 0 -85 -49.5t-32 -140.5q0 -186 105 -293.5t267 -107.5q62 0 121 14z" />
-    <glyph glyph-name="_431" unicode="&#xf1cb;" horiz-adv-x="1792" 
-d="M216 367l603 -402v359l-334 223zM154 511l193 129l-193 129v-258zM973 -35l603 402l-269 180l-334 -223v-359zM896 458l272 182l-272 182l-272 -182zM485 733l334 223v359l-603 -402zM1445 640l193 -129v258zM1307 733l269 180l-603 402v-359zM1792 913v-546
-q0 -41 -34 -64l-819 -546q-21 -13 -43 -13t-43 13l-819 546q-34 23 -34 64v546q0 41 34 64l819 546q21 13 43 13t43 -13l819 -546q34 -23 34 -64z" />
-    <glyph glyph-name="_432" unicode="&#xf1cc;" horiz-adv-x="2048" 
-d="M1800 764q111 -46 179.5 -145.5t68.5 -221.5q0 -164 -118 -280.5t-285 -116.5q-4 0 -11.5 0.5t-10.5 0.5h-1209h-1h-2h-5q-170 10 -288 125.5t-118 280.5q0 110 55 203t147 147q-12 39 -12 82q0 115 82 196t199 81q95 0 172 -58q75 154 222.5 248t326.5 94
-q166 0 306 -80.5t221.5 -218.5t81.5 -301q0 -6 -0.5 -18t-0.5 -18zM468 498q0 -122 84 -193t208 -71q137 0 240 99q-16 20 -47.5 56.5t-43.5 50.5q-67 -65 -144 -65q-55 0 -93.5 33.5t-38.5 87.5q0 53 38.5 87t91.5 34q44 0 84.5 -21t73 -55t65 -75t69 -82t77 -75t97 -55
-t121.5 -21q121 0 204.5 71.5t83.5 190.5q0 121 -84 192t-207 71q-143 0 -241 -97l93 -108q66 64 142 64q52 0 92 -33t40 -84q0 -57 -37 -91.5t-94 -34.5q-43 0 -82.5 21t-72 55t-65.5 75t-69.5 82t-77.5 75t-96.5 55t-118.5 21q-122 0 -207 -70.5t-85 -189.5z" />
-    <glyph glyph-name="_433" unicode="&#xf1cd;" horiz-adv-x="1792" 
-d="M896 1536q182 0 348 -71t286 -191t191 -286t71 -348t-71 -348t-191 -286t-286 -191t-348 -71t-348 71t-286 191t-191 286t-71 348t71 348t191 286t286 191t348 71zM896 1408q-190 0 -361 -90l194 -194q82 28 167 28t167 -28l194 194q-171 90 -361 90zM218 279l194 194
-q-28 82 -28 167t28 167l-194 194q-90 -171 -90 -361t90 -361zM896 -128q190 0 361 90l-194 194q-82 -28 -167 -28t-167 28l-194 -194q171 -90 361 -90zM896 256q159 0 271.5 112.5t112.5 271.5t-112.5 271.5t-271.5 112.5t-271.5 -112.5t-112.5 -271.5t112.5 -271.5
-t271.5 -112.5zM1380 473l194 -194q90 171 90 361t-90 361l-194 -194q28 -82 28 -167t-28 -167z" />
-    <glyph glyph-name="_434" unicode="&#xf1ce;" horiz-adv-x="1792" 
-d="M1760 640q0 -176 -68.5 -336t-184 -275.5t-275.5 -184t-336 -68.5t-336 68.5t-275.5 184t-184 275.5t-68.5 336q0 213 97 398.5t265 305.5t374 151v-228q-221 -45 -366.5 -221t-145.5 -406q0 -130 51 -248.5t136.5 -204t204 -136.5t248.5 -51t248.5 51t204 136.5
-t136.5 204t51 248.5q0 230 -145.5 406t-366.5 221v228q206 -31 374 -151t265 -305.5t97 -398.5z" />
-    <glyph glyph-name="uniF1D0" unicode="&#xf1d0;" horiz-adv-x="1792" 
-d="M19 662q8 217 116 406t305 318h5q0 -1 -1 -3q-8 -8 -28 -33.5t-52 -76.5t-60 -110.5t-44.5 -135.5t-14 -150.5t39 -157.5t108.5 -154q50 -50 102 -69.5t90.5 -11.5t69.5 23.5t47 32.5l16 16q39 51 53 116.5t6.5 122.5t-21 107t-26.5 80l-14 29q-10 25 -30.5 49.5t-43 41
-t-43.5 29.5t-35 19l-13 6l104 115q39 -17 78 -52t59 -61l19 -27q1 48 -18.5 103.5t-40.5 87.5l-20 31l161 183l160 -181q-33 -46 -52.5 -102.5t-22.5 -90.5l-4 -33q22 37 61.5 72.5t67.5 52.5l28 17l103 -115q-44 -14 -85 -50t-60 -65l-19 -29q-31 -56 -48 -133.5t-7 -170
-t57 -156.5q33 -45 77.5 -60.5t85 -5.5t76 26.5t57.5 33.5l21 16q60 53 96.5 115t48.5 121.5t10 121.5t-18 118t-37 107.5t-45.5 93t-45 72t-34.5 47.5l-13 17q-14 13 -7 13l10 -3q40 -29 62.5 -46t62 -50t64 -58t58.5 -65t55.5 -77t45.5 -88t38 -103t23.5 -117t10.5 -136
-q3 -259 -108 -465t-312 -321t-456 -115q-185 0 -351 74t-283.5 198t-184 293t-60.5 353z" />
-    <glyph glyph-name="uniF1D1" unicode="&#xf1d1;" horiz-adv-x="1792" 
-d="M874 -102v-66q-208 6 -385 109.5t-283 275.5l58 34q29 -49 73 -99l65 57q148 -168 368 -212l-17 -86q65 -12 121 -13zM276 428l-83 -28q22 -60 49 -112l-57 -33q-98 180 -98 385t98 385l57 -33q-30 -56 -49 -112l82 -28q-35 -100 -35 -212q0 -109 36 -212zM1528 251
-l58 -34q-106 -172 -283 -275.5t-385 -109.5v66q56 1 121 13l-17 86q220 44 368 212l65 -57q44 50 73 99zM1377 805l-233 -80q14 -42 14 -85t-14 -85l232 -80q-31 -92 -98 -169l-185 162q-57 -67 -147 -85l48 -241q-52 -10 -98 -10t-98 10l48 241q-90 18 -147 85l-185 -162
-q-67 77 -98 169l232 80q-14 42 -14 85t14 85l-233 80q33 93 99 169l185 -162q59 68 147 86l-48 240q44 10 98 10t98 -10l-48 -240q88 -18 147 -86l185 162q66 -76 99 -169zM874 1448v-66q-65 -2 -121 -13l17 -86q-220 -42 -368 -211l-65 56q-38 -42 -73 -98l-57 33
-q106 172 282 275.5t385 109.5zM1705 640q0 -205 -98 -385l-57 33q27 52 49 112l-83 28q36 103 36 212q0 112 -35 212l82 28q-19 56 -49 112l57 33q98 -180 98 -385zM1585 1063l-57 -33q-35 56 -73 98l-65 -56q-148 169 -368 211l17 86q-56 11 -121 13v66q209 -6 385 -109.5
-t282 -275.5zM1748 640q0 173 -67.5 331t-181.5 272t-272 181.5t-331 67.5t-331 -67.5t-272 -181.5t-181.5 -272t-67.5 -331t67.5 -331t181.5 -272t272 -181.5t331 -67.5t331 67.5t272 181.5t181.5 272t67.5 331zM1792 640q0 -182 -71 -348t-191 -286t-286 -191t-348 -71
-t-348 71t-286 191t-191 286t-71 348t71 348t191 286t286 191t348 71t348 -71t286 -191t191 -286t71 -348z" />
-    <glyph glyph-name="uniF1D2" unicode="&#xf1d2;" 
-d="M582 228q0 -66 -93 -66q-107 0 -107 63q0 64 98 64q102 0 102 -61zM546 694q0 -85 -74 -85q-77 0 -77 84q0 90 77 90q36 0 55 -25.5t19 -63.5zM712 769v125q-78 -29 -135 -29q-50 29 -110 29q-86 0 -145 -57t-59 -143q0 -50 29.5 -102t73.5 -67v-3q-38 -17 -38 -85
-q0 -53 41 -77v-3q-113 -37 -113 -139q0 -45 20 -78.5t54 -51t72 -25.5t81 -8q224 0 224 188q0 67 -48 99t-126 46q-27 5 -51.5 20.5t-24.5 39.5q0 44 49 52q77 15 122 70t45 134q0 24 -10 52q37 9 49 13zM771 350h137q-2 27 -2 82v387q0 46 2 69h-137q3 -23 3 -71v-392
-q0 -50 -3 -75zM1280 366v121q-30 -21 -68 -21q-53 0 -53 82v225h52q9 0 26.5 -1t26.5 -1v117h-105q0 82 3 102h-140q4 -24 4 -55v-47h-60v-117q36 3 37 3q3 0 11 -0.5t12 -0.5v-2h-2v-217q0 -37 2.5 -64t11.5 -56.5t24.5 -48.5t43.5 -31t66 -12q64 0 108 24zM924 1072
-q0 36 -24 63.5t-60 27.5t-60.5 -27t-24.5 -64q0 -36 25 -62.5t60 -26.5t59.5 27t24.5 62zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
-    <glyph glyph-name="_438" unicode="&#xf1d3;" horiz-adv-x="1792" 
-d="M595 22q0 100 -165 100q-158 0 -158 -104q0 -101 172 -101q151 0 151 105zM536 777q0 61 -30 102t-89 41q-124 0 -124 -145q0 -135 124 -135q119 0 119 137zM805 1101v-202q-36 -12 -79 -22q16 -43 16 -84q0 -127 -73 -216.5t-197 -112.5q-40 -8 -59.5 -27t-19.5 -58
-q0 -31 22.5 -51.5t58 -32t78.5 -22t86 -25.5t78.5 -37.5t58 -64t22.5 -98.5q0 -304 -363 -304q-69 0 -130 12.5t-116 41t-87.5 82t-32.5 127.5q0 165 182 225v4q-67 41 -67 126q0 109 63 137v4q-72 24 -119.5 108.5t-47.5 165.5q0 139 95 231.5t235 92.5q96 0 178 -47
-q98 0 218 47zM1123 220h-222q4 45 4 134v609q0 94 -4 128h222q-4 -33 -4 -124v-613q0 -89 4 -134zM1724 442v-196q-71 -39 -174 -39q-62 0 -107 20t-70 50t-39.5 78t-18.5 92t-4 103v351h2v4q-7 0 -19 1t-18 1q-21 0 -59 -6v190h96v76q0 54 -6 89h227q-6 -41 -6 -165h171
-v-190q-15 0 -43.5 2t-42.5 2h-85v-365q0 -131 87 -131q61 0 109 33zM1148 1389q0 -58 -39 -101.5t-96 -43.5q-58 0 -98 43.5t-40 101.5q0 59 39.5 103t98.5 44q58 0 96.5 -44.5t38.5 -102.5z" />
-    <glyph glyph-name="_439" unicode="&#xf1d4;" 
-d="M809 532l266 499h-112l-157 -312q-24 -48 -44 -92l-42 92l-155 312h-120l263 -493v-324h101v318zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
-    <glyph glyph-name="uniF1D5" unicode="&#xf1d5;" horiz-adv-x="1280" 
-d="M842 964q0 -80 -57 -136.5t-136 -56.5q-60 0 -111 35q-62 -67 -115 -146q-247 -371 -202 -859q1 -22 -12.5 -38.5t-34.5 -18.5h-5q-20 0 -35 13.5t-17 33.5q-14 126 -3.5 247.5t29.5 217t54 186t69 155.5t74 125q61 90 132 165q-16 35 -16 77q0 80 56.5 136.5t136.5 56.5
-t136.5 -56.5t56.5 -136.5zM1223 953q0 -158 -78 -292t-212.5 -212t-292.5 -78q-64 0 -131 14q-21 5 -32.5 23.5t-6.5 39.5q5 20 23 31.5t39 7.5q51 -13 108 -13q97 0 186 38t153 102t102 153t38 186t-38 186t-102 153t-153 102t-186 38t-186 -38t-153 -102t-102 -153
-t-38 -186q0 -114 52 -218q10 -20 3.5 -40t-25.5 -30t-39.5 -3t-30.5 26q-64 123 -64 265q0 119 46.5 227t124.5 186t186 124t226 46q158 0 292.5 -78t212.5 -212.5t78 -292.5z" />
-    <glyph glyph-name="uniF1D6" unicode="&#xf1d6;" horiz-adv-x="1792" 
-d="M270 730q-8 19 -8 52q0 20 11 49t24 45q-1 22 7.5 53t22.5 43q0 139 92.5 288.5t217.5 209.5q139 66 324 66q133 0 266 -55q49 -21 90 -48t71 -56t55 -68t42 -74t32.5 -84.5t25.5 -89.5t22 -98l1 -5q55 -83 55 -150q0 -14 -9 -40t-9 -38q0 -1 1.5 -3.5t3.5 -5t2 -3.5
-q77 -114 120.5 -214.5t43.5 -208.5q0 -43 -19.5 -100t-55.5 -57q-9 0 -19.5 7.5t-19 17.5t-19 26t-16 26.5t-13.5 26t-9 17.5q-1 1 -3 1l-5 -4q-59 -154 -132 -223q20 -20 61.5 -38.5t69 -41.5t35.5 -65q-2 -4 -4 -16t-7 -18q-64 -97 -302 -97q-53 0 -110.5 9t-98 20
-t-104.5 30q-15 5 -23 7q-14 4 -46 4.5t-40 1.5q-41 -45 -127.5 -65t-168.5 -20q-35 0 -69 1.5t-93 9t-101 20.5t-74.5 40t-32.5 64q0 40 10 59.5t41 48.5q11 2 40.5 13t49.5 12q4 0 14 2q2 2 2 4l-2 3q-48 11 -108 105.5t-73 156.5l-5 3q-4 0 -12 -20q-18 -41 -54.5 -74.5
-t-77.5 -37.5h-1q-4 0 -6 4.5t-5 5.5q-23 54 -23 100q0 275 252 466z" />
-    <glyph glyph-name="uniF1D7" unicode="&#xf1d7;" horiz-adv-x="2048" 
-d="M580 1075q0 41 -25 66t-66 25q-43 0 -76 -25.5t-33 -65.5q0 -39 33 -64.5t76 -25.5q41 0 66 24.5t25 65.5zM1323 568q0 28 -25.5 50t-65.5 22q-27 0 -49.5 -22.5t-22.5 -49.5q0 -28 22.5 -50.5t49.5 -22.5q40 0 65.5 22t25.5 51zM1087 1075q0 41 -24.5 66t-65.5 25
-q-43 0 -76 -25.5t-33 -65.5q0 -39 33 -64.5t76 -25.5q41 0 65.5 24.5t24.5 65.5zM1722 568q0 28 -26 50t-65 22q-27 0 -49.5 -22.5t-22.5 -49.5q0 -28 22.5 -50.5t49.5 -22.5q39 0 65 22t26 51zM1456 965q-31 4 -70 4q-169 0 -311 -77t-223.5 -208.5t-81.5 -287.5
-q0 -78 23 -152q-35 -3 -68 -3q-26 0 -50 1.5t-55 6.5t-44.5 7t-54.5 10.5t-50 10.5l-253 -127l72 218q-290 203 -290 490q0 169 97.5 311t264 223.5t363.5 81.5q176 0 332.5 -66t262 -182.5t136.5 -260.5zM2048 404q0 -117 -68.5 -223.5t-185.5 -193.5l55 -181l-199 109
-q-150 -37 -218 -37q-169 0 -311 70.5t-223.5 191.5t-81.5 264t81.5 264t223.5 191.5t311 70.5q161 0 303 -70.5t227.5 -192t85.5 -263.5z" />
-    <glyph glyph-name="_443" unicode="&#xf1d8;" horiz-adv-x="1792" 
-d="M1764 1525q33 -24 27 -64l-256 -1536q-5 -29 -32 -45q-14 -8 -31 -8q-11 0 -24 5l-453 185l-242 -295q-18 -23 -49 -23q-13 0 -22 4q-19 7 -30.5 23.5t-11.5 36.5v349l864 1059l-1069 -925l-395 162q-37 14 -40 55q-2 40 32 59l1664 960q15 9 32 9q20 0 36 -11z" />
-    <glyph glyph-name="_444" unicode="&#xf1d9;" horiz-adv-x="1792" 
-d="M1764 1525q33 -24 27 -64l-256 -1536q-5 -29 -32 -45q-14 -8 -31 -8q-11 0 -24 5l-527 215l-298 -327q-18 -21 -47 -21q-14 0 -23 4q-19 7 -30 23.5t-11 36.5v452l-472 193q-37 14 -40 55q-3 39 32 59l1664 960q35 21 68 -2zM1422 26l221 1323l-1434 -827l336 -137
-l863 639l-478 -797z" />
-    <glyph glyph-name="_445" unicode="&#xf1da;" 
-d="M1536 640q0 -156 -61 -298t-164 -245t-245 -164t-298 -61q-172 0 -327 72.5t-264 204.5q-7 10 -6.5 22.5t8.5 20.5l137 138q10 9 25 9q16 -2 23 -12q73 -95 179 -147t225 -52q104 0 198.5 40.5t163.5 109.5t109.5 163.5t40.5 198.5t-40.5 198.5t-109.5 163.5
-t-163.5 109.5t-198.5 40.5q-98 0 -188 -35.5t-160 -101.5l137 -138q31 -30 14 -69q-17 -40 -59 -40h-448q-26 0 -45 19t-19 45v448q0 42 40 59q39 17 69 -14l130 -129q107 101 244.5 156.5t284.5 55.5q156 0 298 -61t245 -164t164 -245t61 -298zM896 928v-448q0 -14 -9 -23
-t-23 -9h-320q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h224v352q0 14 9 23t23 9h64q14 0 23 -9t9 -23z" />
-    <glyph glyph-name="_446" unicode="&#xf1db;" 
-d="M768 1280q-130 0 -248.5 -51t-204 -136.5t-136.5 -204t-51 -248.5t51 -248.5t136.5 -204t204 -136.5t248.5 -51t248.5 51t204 136.5t136.5 204t51 248.5t-51 248.5t-136.5 204t-204 136.5t-248.5 51zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103
-t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
-    <glyph glyph-name="_447" unicode="&#xf1dc;" horiz-adv-x="1792" 
-d="M1682 -128q-44 0 -132.5 3.5t-133.5 3.5q-44 0 -132 -3.5t-132 -3.5q-24 0 -37 20.5t-13 45.5q0 31 17 46t39 17t51 7t45 15q33 21 33 140l-1 391q0 21 -1 31q-13 4 -50 4h-675q-38 0 -51 -4q-1 -10 -1 -31l-1 -371q0 -142 37 -164q16 -10 48 -13t57 -3.5t45 -15
-t20 -45.5q0 -26 -12.5 -48t-36.5 -22q-47 0 -139.5 3.5t-138.5 3.5q-43 0 -128 -3.5t-127 -3.5q-23 0 -35.5 21t-12.5 45q0 30 15.5 45t36 17.5t47.5 7.5t42 15q33 23 33 143l-1 57v813q0 3 0.5 26t0 36.5t-1.5 38.5t-3.5 42t-6.5 36.5t-11 31.5t-16 18q-15 10 -45 12t-53 2
-t-41 14t-18 45q0 26 12 48t36 22q46 0 138.5 -3.5t138.5 -3.5q42 0 126.5 3.5t126.5 3.5q25 0 37.5 -22t12.5 -48q0 -30 -17 -43.5t-38.5 -14.5t-49.5 -4t-43 -13q-35 -21 -35 -160l1 -320q0 -21 1 -32q13 -3 39 -3h699q25 0 38 3q1 11 1 32l1 320q0 139 -35 160
-q-18 11 -58.5 12.5t-66 13t-25.5 49.5q0 26 12.5 48t37.5 22q44 0 132 -3.5t132 -3.5q43 0 129 3.5t129 3.5q25 0 37.5 -22t12.5 -48q0 -30 -17.5 -44t-40 -14.5t-51.5 -3t-44 -12.5q-35 -23 -35 -161l1 -943q0 -119 34 -140q16 -10 46 -13.5t53.5 -4.5t41.5 -15.5t18 -44.5
-q0 -26 -12 -48t-36 -22z" />
-    <glyph glyph-name="_448" unicode="&#xf1dd;" horiz-adv-x="1280" 
-d="M1278 1347v-73q0 -29 -18.5 -61t-42.5 -32q-50 0 -54 -1q-26 -6 -32 -31q-3 -11 -3 -64v-1152q0 -25 -18 -43t-43 -18h-108q-25 0 -43 18t-18 43v1218h-143v-1218q0 -25 -17.5 -43t-43.5 -18h-108q-26 0 -43.5 18t-17.5 43v496q-147 12 -245 59q-126 58 -192 179
-q-64 117 -64 259q0 166 88 286q88 118 209 159q111 37 417 37h479q25 0 43 -18t18 -43z" />
-    <glyph glyph-name="_449" unicode="&#xf1de;" 
-d="M352 128v-128h-352v128h352zM704 256q26 0 45 -19t19 -45v-256q0 -26 -19 -45t-45 -19h-256q-26 0 -45 19t-19 45v256q0 26 19 45t45 19h256zM864 640v-128h-864v128h864zM224 1152v-128h-224v128h224zM1536 128v-128h-736v128h736zM576 1280q26 0 45 -19t19 -45v-256
-q0 -26 -19 -45t-45 -19h-256q-26 0 -45 19t-19 45v256q0 26 19 45t45 19h256zM1216 768q26 0 45 -19t19 -45v-256q0 -26 -19 -45t-45 -19h-256q-26 0 -45 19t-19 45v256q0 26 19 45t45 19h256zM1536 640v-128h-224v128h224zM1536 1152v-128h-864v128h864z" />
-    <glyph glyph-name="uniF1E0" unicode="&#xf1e0;" 
-d="M1216 512q133 0 226.5 -93.5t93.5 -226.5t-93.5 -226.5t-226.5 -93.5t-226.5 93.5t-93.5 226.5q0 12 2 34l-360 180q-92 -86 -218 -86q-133 0 -226.5 93.5t-93.5 226.5t93.5 226.5t226.5 93.5q126 0 218 -86l360 180q-2 22 -2 34q0 133 93.5 226.5t226.5 93.5
-t226.5 -93.5t93.5 -226.5t-93.5 -226.5t-226.5 -93.5q-126 0 -218 86l-360 -180q2 -22 2 -34t-2 -34l360 -180q92 86 218 86z" />
-    <glyph glyph-name="_451" unicode="&#xf1e1;" 
-d="M1280 341q0 88 -62.5 151t-150.5 63q-84 0 -145 -58l-241 120q2 16 2 23t-2 23l241 120q61 -58 145 -58q88 0 150.5 63t62.5 151t-62.5 150.5t-150.5 62.5t-151 -62.5t-63 -150.5q0 -7 2 -23l-241 -120q-62 57 -145 57q-88 0 -150.5 -62.5t-62.5 -150.5t62.5 -150.5
-t150.5 -62.5q83 0 145 57l241 -120q-2 -16 -2 -23q0 -88 63 -150.5t151 -62.5t150.5 62.5t62.5 150.5zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
-    <glyph glyph-name="_452" unicode="&#xf1e2;" horiz-adv-x="1792" 
-d="M571 947q-10 25 -34 35t-49 0q-108 -44 -191 -127t-127 -191q-10 -25 0 -49t35 -34q13 -5 24 -5q42 0 60 40q34 84 98.5 148.5t148.5 98.5q25 11 35 35t0 49zM1513 1303l46 -46l-244 -243l68 -68q19 -19 19 -45.5t-19 -45.5l-64 -64q89 -161 89 -343q0 -143 -55.5 -273.5
-t-150 -225t-225 -150t-273.5 -55.5t-273.5 55.5t-225 150t-150 225t-55.5 273.5t55.5 273.5t150 225t225 150t273.5 55.5q182 0 343 -89l64 64q19 19 45.5 19t45.5 -19l68 -68zM1521 1359q-10 -10 -22 -10q-13 0 -23 10l-91 90q-9 10 -9 23t9 23q10 9 23 9t23 -9l90 -91
-q10 -9 10 -22.5t-10 -22.5zM1751 1129q-11 -9 -23 -9t-23 9l-90 91q-10 9 -10 22.5t10 22.5q9 10 22.5 10t22.5 -10l91 -90q9 -10 9 -23t-9 -23zM1792 1312q0 -14 -9 -23t-23 -9h-96q-14 0 -23 9t-9 23t9 23t23 9h96q14 0 23 -9t9 -23zM1600 1504v-96q0 -14 -9 -23t-23 -9
-t-23 9t-9 23v96q0 14 9 23t23 9t23 -9t9 -23zM1751 1449l-91 -90q-10 -10 -22 -10q-13 0 -23 10q-10 9 -10 22.5t10 22.5l90 91q10 9 23 9t23 -9q9 -10 9 -23t-9 -23z" />
-    <glyph glyph-name="_453" unicode="&#xf1e3;" horiz-adv-x="1792" 
-d="M609 720l287 208l287 -208l-109 -336h-355zM896 1536q182 0 348 -71t286 -191t191 -286t71 -348t-71 -348t-191 -286t-286 -191t-348 -71t-348 71t-286 191t-191 286t-71 348t71 348t191 286t286 191t348 71zM1515 186q149 203 149 454v3l-102 -89l-240 224l63 323
-l134 -12q-150 206 -389 282l53 -124l-287 -159l-287 159l53 124q-239 -76 -389 -282l135 12l62 -323l-240 -224l-102 89v-3q0 -251 149 -454l30 132l326 -40l139 -298l-116 -69q117 -39 240 -39t240 39l-116 69l139 298l326 40z" />
-    <glyph glyph-name="_454" unicode="&#xf1e4;" horiz-adv-x="1792" 
-d="M448 224v-192q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h192q14 0 23 -9t9 -23zM256 608v-192q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h192q14 0 23 -9t9 -23zM832 224v-192q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23
-v192q0 14 9 23t23 9h192q14 0 23 -9t9 -23zM640 608v-192q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h192q14 0 23 -9t9 -23zM66 768q-28 0 -47 19t-19 46v129h514v-129q0 -27 -19 -46t-46 -19h-383zM1216 224v-192q0 -14 -9 -23t-23 -9h-192
-q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h192q14 0 23 -9t9 -23zM1024 608v-192q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h192q14 0 23 -9t9 -23zM1600 224v-192q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h192q14 0 23 -9t9 -23
-zM1408 608v-192q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h192q14 0 23 -9t9 -23zM1792 1016v-13h-514v10q0 104 -382 102q-382 -1 -382 -102v-10h-514v13q0 17 8.5 43t34 64t65.5 75.5t110.5 76t160 67.5t224 47.5t293.5 18.5t293 -18.5t224 -47.5
-t160.5 -67.5t110.5 -76t65.5 -75.5t34 -64t8.5 -43zM1792 608v-192q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h192q14 0 23 -9t9 -23zM1792 962v-129q0 -27 -19 -46t-46 -19h-384q-27 0 -46 19t-19 46v129h514z" />
-    <glyph glyph-name="_455" unicode="&#xf1e5;" horiz-adv-x="1792" 
-d="M704 1216v-768q0 -26 -19 -45t-45 -19v-576q0 -26 -19 -45t-45 -19h-512q-26 0 -45 19t-19 45v512l249 873q7 23 31 23h424zM1024 1216v-704h-256v704h256zM1792 320v-512q0 -26 -19 -45t-45 -19h-512q-26 0 -45 19t-19 45v576q-26 0 -45 19t-19 45v768h424q24 0 31 -23z
-M736 1504v-224h-352v224q0 14 9 23t23 9h288q14 0 23 -9t9 -23zM1408 1504v-224h-352v224q0 14 9 23t23 9h288q14 0 23 -9t9 -23z" />
-    <glyph glyph-name="_456" unicode="&#xf1e6;" horiz-adv-x="1792" 
-d="M1755 1083q37 -38 37 -90.5t-37 -90.5l-401 -400l150 -150l-160 -160q-163 -163 -389.5 -186.5t-411.5 100.5l-362 -362h-181v181l362 362q-124 185 -100.5 411.5t186.5 389.5l160 160l150 -150l400 401q38 37 91 37t90 -37t37 -90.5t-37 -90.5l-400 -401l234 -234
-l401 400q38 37 91 37t90 -37z" />
-    <glyph glyph-name="_457" unicode="&#xf1e7;" horiz-adv-x="1792" 
-d="M873 796q0 -83 -63.5 -142.5t-152.5 -59.5t-152.5 59.5t-63.5 142.5q0 84 63.5 143t152.5 59t152.5 -59t63.5 -143zM1375 796q0 -83 -63 -142.5t-153 -59.5q-89 0 -152.5 59.5t-63.5 142.5q0 84 63.5 143t152.5 59q90 0 153 -59t63 -143zM1600 616v667q0 87 -32 123.5
-t-111 36.5h-1112q-83 0 -112.5 -34t-29.5 -126v-673q43 -23 88.5 -40t81 -28t81 -18.5t71 -11t70 -4t58.5 -0.5t56.5 2t44.5 2q68 1 95 -27q6 -6 10 -9q26 -25 61 -51q7 91 118 87q5 0 36.5 -1.5t43 -2t45.5 -1t53 1t54.5 4.5t61 8.5t62 13.5t67 19.5t67.5 27t72 34.5z
-M1763 621q-121 -149 -372 -252q84 -285 -23 -465q-66 -113 -183 -148q-104 -32 -182 15q-86 51 -82 164l-1 326v1q-8 2 -24.5 6t-23.5 5l-1 -338q4 -114 -83 -164q-79 -47 -183 -15q-117 36 -182 150q-105 180 -22 463q-251 103 -372 252q-25 37 -4 63t60 -1q4 -2 11.5 -7
-t10.5 -8v694q0 72 47 123t114 51h1257q67 0 114 -51t47 -123v-694l21 15q39 27 60 1t-4 -63z" />
-    <glyph glyph-name="_458" unicode="&#xf1e8;" horiz-adv-x="1792" 
-d="M896 1102v-434h-145v434h145zM1294 1102v-434h-145v434h145zM1294 342l253 254v795h-1194v-1049h326v-217l217 217h398zM1692 1536v-1013l-434 -434h-326l-217 -217h-217v217h-398v1158l109 289h1483z" />
-    <glyph glyph-name="_459" unicode="&#xf1e9;" 
-d="M773 217v-127q-1 -292 -6 -305q-12 -32 -51 -40q-54 -9 -181.5 38t-162.5 89q-13 15 -17 36q-1 12 4 26q4 10 34 47t181 216q1 0 60 70q15 19 39.5 24.5t49.5 -3.5q24 -10 37.5 -29t12.5 -42zM624 468q-3 -55 -52 -70l-120 -39q-275 -88 -292 -88q-35 2 -54 36
-q-12 25 -17 75q-8 76 1 166.5t30 124.5t56 32q13 0 202 -77q71 -29 115 -47l84 -34q23 -9 35.5 -30.5t11.5 -48.5zM1450 171q-7 -54 -91.5 -161t-135.5 -127q-37 -14 -63 7q-14 10 -184 287l-47 77q-14 21 -11.5 46t19.5 46q35 43 83 26q1 -1 119 -40q203 -66 242 -79.5
-t47 -20.5q28 -22 22 -61zM778 803q5 -102 -54 -122q-58 -17 -114 71l-378 598q-8 35 19 62q41 43 207.5 89.5t224.5 31.5q40 -10 49 -45q3 -18 22 -305.5t24 -379.5zM1440 695q3 -39 -26 -59q-15 -10 -329 -86q-67 -15 -91 -23l1 2q-23 -6 -46 4t-37 32q-30 47 0 87
-q1 1 75 102q125 171 150 204t34 39q28 19 65 2q48 -23 123 -133.5t81 -167.5v-3z" />
-    <glyph glyph-name="_460" unicode="&#xf1ea;" horiz-adv-x="2048" 
-d="M1024 1024h-384v-384h384v384zM1152 384v-128h-640v128h640zM1152 1152v-640h-640v640h640zM1792 384v-128h-512v128h512zM1792 640v-128h-512v128h512zM1792 896v-128h-512v128h512zM1792 1152v-128h-512v128h512zM256 192v960h-128v-960q0 -26 19 -45t45 -19t45 19
-t19 45zM1920 192v1088h-1536v-1088q0 -33 -11 -64h1483q26 0 45 19t19 45zM2048 1408v-1216q0 -80 -56 -136t-136 -56h-1664q-80 0 -136 56t-56 136v1088h256v128h1792z" />
-    <glyph glyph-name="_461" unicode="&#xf1eb;" horiz-adv-x="2048" 
-d="M1024 13q-20 0 -93 73.5t-73 93.5q0 32 62.5 54t103.5 22t103.5 -22t62.5 -54q0 -20 -73 -93.5t-93 -73.5zM1294 284q-2 0 -40 25t-101.5 50t-128.5 25t-128.5 -25t-101 -50t-40.5 -25q-18 0 -93.5 75t-75.5 93q0 13 10 23q78 77 196 121t233 44t233 -44t196 -121
-q10 -10 10 -23q0 -18 -75.5 -93t-93.5 -75zM1567 556q-11 0 -23 8q-136 105 -252 154.5t-268 49.5q-85 0 -170.5 -22t-149 -53t-113.5 -62t-79 -53t-31 -22q-17 0 -92 75t-75 93q0 12 10 22q132 132 320 205t380 73t380 -73t320 -205q10 -10 10 -22q0 -18 -75 -93t-92 -75z
-M1838 827q-11 0 -22 9q-179 157 -371.5 236.5t-420.5 79.5t-420.5 -79.5t-371.5 -236.5q-11 -9 -22 -9q-17 0 -92.5 75t-75.5 93q0 13 10 23q187 186 445 288t527 102t527 -102t445 -288q10 -10 10 -23q0 -18 -75.5 -93t-92.5 -75z" />
-    <glyph glyph-name="_462" unicode="&#xf1ec;" horiz-adv-x="1792" 
-d="M384 0q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM768 0q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM384 384q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5
-t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1152 0q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM768 384q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5
-t37.5 90.5zM384 768q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1152 384q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM768 768q0 53 -37.5 90.5t-90.5 37.5
-t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1536 0v384q0 52 -38 90t-90 38t-90 -38t-38 -90v-384q0 -52 38 -90t90 -38t90 38t38 90zM1152 768q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5z
-M1536 1088v256q0 26 -19 45t-45 19h-1280q-26 0 -45 -19t-19 -45v-256q0 -26 19 -45t45 -19h1280q26 0 45 19t19 45zM1536 768q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1664 1408v-1536q0 -52 -38 -90t-90 -38
-h-1408q-52 0 -90 38t-38 90v1536q0 52 38 90t90 38h1408q52 0 90 -38t38 -90z" />
-    <glyph glyph-name="_463" unicode="&#xf1ed;" 
-d="M1519 890q18 -84 -4 -204q-87 -444 -565 -444h-44q-25 0 -44 -16.5t-24 -42.5l-4 -19l-55 -346l-2 -15q-5 -26 -24.5 -42.5t-44.5 -16.5h-251q-21 0 -33 15t-9 36q9 56 26.5 168t26.5 168t27 167.5t27 167.5q5 37 43 37h131q133 -2 236 21q175 39 287 144q102 95 155 246
-q24 70 35 133q1 6 2.5 7.5t3.5 1t6 -3.5q79 -59 98 -162zM1347 1172q0 -107 -46 -236q-80 -233 -302 -315q-113 -40 -252 -42q0 -1 -90 -1l-90 1q-100 0 -118 -96q-2 -8 -85 -530q-1 -10 -12 -10h-295q-22 0 -36.5 16.5t-11.5 38.5l232 1471q5 29 27.5 48t51.5 19h598
-q34 0 97.5 -13t111.5 -32q107 -41 163.5 -123t56.5 -196z" />
-    <glyph glyph-name="_464" unicode="&#xf1ee;" horiz-adv-x="1792" 
-d="M441 864q33 0 52 -26q266 -364 362 -774h-446q-127 441 -367 749q-12 16 -3 33.5t29 17.5h373zM1000 507q-49 -199 -125 -393q-79 310 -256 594q40 221 44 449q211 -340 337 -650zM1099 1216q235 -324 384.5 -698.5t184.5 -773.5h-451q-41 665 -553 1472h435zM1792 640
-q0 -424 -101 -812q-67 560 -359 1083q-25 301 -106 584q-4 16 5.5 28.5t25.5 12.5h359q21 0 38.5 -13t22.5 -33q115 -409 115 -850z" />
-    <glyph glyph-name="uniF1F0" unicode="&#xf1f0;" horiz-adv-x="2304" 
-d="M1975 546h-138q14 37 66 179l3 9q4 10 10 26t9 26l12 -55zM531 611l-58 295q-11 54 -75 54h-268l-2 -13q311 -79 403 -336zM710 960l-162 -438l-17 89q-26 70 -85 129.5t-131 88.5l135 -510h175l261 641h-176zM849 318h166l104 642h-166zM1617 944q-69 27 -149 27
-q-123 0 -201 -59t-79 -153q-1 -102 145 -174q48 -23 67 -41t19 -39q0 -30 -30 -46t-69 -16q-86 0 -156 33l-22 11l-23 -144q74 -34 185 -34q130 -1 208.5 59t80.5 160q0 106 -140 174q-49 25 -71 42t-22 38q0 22 24.5 38.5t70.5 16.5q70 1 124 -24l15 -8zM2042 960h-128
-q-65 0 -87 -54l-246 -588h174l35 96h212q5 -22 20 -96h154zM2304 1280v-1280q0 -52 -38 -90t-90 -38h-2048q-52 0 -90 38t-38 90v1280q0 52 38 90t90 38h2048q52 0 90 -38t38 -90z" />
-    <glyph glyph-name="_466" unicode="&#xf1f1;" horiz-adv-x="2304" 
-d="M1119 1195q-128 85 -281 85q-103 0 -197.5 -40.5t-162.5 -108.5t-108.5 -162t-40.5 -197q0 -104 40.5 -198t108.5 -162t162 -108.5t198 -40.5q153 0 281 85q-131 107 -178 265.5t0.5 316.5t177.5 265zM1152 1171q-126 -99 -172 -249.5t-0.5 -300.5t172.5 -249
-q127 99 172.5 249t-0.5 300.5t-172 249.5zM1185 1195q130 -107 177.5 -265.5t0.5 -317t-178 -264.5q128 -85 281 -85q104 0 198 40.5t162 108.5t108.5 162t40.5 198q0 103 -40.5 197t-108.5 162t-162.5 108.5t-197.5 40.5q-153 0 -281 -85zM1926 473h7v3h-17v-3h7v-17h3v17z
-M1955 456h4v20h-5l-6 -13l-6 13h-5v-20h3v15l6 -13h4l5 13v-15zM1947 16v-2h-2h-3v3h3h2v-1zM1947 7h3l-4 5h2l1 1q1 1 1 3t-1 3l-1 1h-3h-6v-13h3v5h1zM685 75q0 19 11 31t30 12q18 0 29 -12.5t11 -30.5q0 -19 -11 -31t-29 -12q-19 0 -30 12t-11 31zM1158 119q30 0 35 -32
-h-70q5 32 35 32zM1514 75q0 19 11 31t29 12t29.5 -12.5t11.5 -30.5q0 -19 -11 -31t-30 -12q-18 0 -29 12t-11 31zM1786 75q0 18 11.5 30.5t29.5 12.5t29.5 -12.5t11.5 -30.5q0 -19 -11.5 -31t-29.5 -12t-29.5 12.5t-11.5 30.5zM1944 3q-2 0 -4 1q-1 0 -3 2t-2 3q-1 2 -1 4
-q0 3 1 4q0 2 2 4l1 1q2 0 2 1q2 1 4 1q3 0 4 -1l4 -2l2 -4v-1q1 -2 1 -3l-1 -1v-3t-1 -1l-1 -2q-2 -2 -4 -2q-1 -1 -4 -1zM599 7h30v85q0 24 -14.5 38.5t-39.5 15.5q-32 0 -47 -24q-14 24 -45 24q-24 0 -39 -20v16h-30v-135h30v75q0 36 33 36q30 0 30 -36v-75h29v75
-q0 36 33 36q30 0 30 -36v-75zM765 7h29v68v67h-29v-16q-17 20 -43 20q-29 0 -48 -20t-19 -51t19 -51t48 -20q28 0 43 20v-17zM943 48q0 34 -47 40l-14 2q-23 4 -23 14q0 15 25 15q23 0 43 -11l12 24q-22 14 -55 14q-26 0 -41 -12t-15 -32q0 -33 47 -39l13 -2q24 -4 24 -14
-q0 -17 -31 -17q-25 0 -45 14l-13 -23q25 -17 58 -17q29 0 45.5 12t16.5 32zM1073 14l-8 25q-13 -7 -26 -7q-19 0 -19 22v61h48v27h-48v41h-30v-41h-28v-27h28v-61q0 -50 47 -50q21 0 36 10zM1159 146q-29 0 -48 -20t-19 -51q0 -32 19.5 -51.5t49.5 -19.5q33 0 55 19l-14 22
-q-18 -15 -39 -15q-34 0 -41 33h101v12q0 32 -18 51.5t-46 19.5zM1318 146q-23 0 -35 -20v16h-30v-135h30v76q0 35 29 35q10 0 18 -4l9 28q-9 4 -21 4zM1348 75q0 -31 19.5 -51t52.5 -20q29 0 48 16l-14 24q-18 -13 -35 -12q-18 0 -29.5 12t-11.5 31t11.5 31t29.5 12
-q19 0 35 -12l14 24q-20 16 -48 16q-33 0 -52.5 -20t-19.5 -51zM1593 7h30v68v67h-30v-16q-15 20 -42 20q-29 0 -48.5 -20t-19.5 -51t19.5 -51t48.5 -20q28 0 42 20v-17zM1726 146q-23 0 -35 -20v16h-29v-135h29v76q0 35 29 35q10 0 18 -4l9 28q-8 4 -21 4zM1866 7h29v68v122
-h-29v-71q-15 20 -43 20t-47.5 -20.5t-19.5 -50.5t19.5 -50.5t47.5 -20.5q29 0 43 20v-17zM1944 27l-2 -1h-3q-2 -1 -4 -3q-3 -1 -3 -4q-1 -2 -1 -6q0 -3 1 -5q0 -2 3 -4q2 -2 4 -3t5 -1q4 0 6 1q0 1 2 2l2 1q1 1 3 4q1 2 1 5q0 4 -1 6q-1 1 -3 4q0 1 -2 2l-2 1q-1 0 -3 0.5
-t-3 0.5zM2304 1280v-1280q0 -52 -38 -90t-90 -38h-2048q-52 0 -90 38t-38 90v1280q0 52 38 90t90 38h2048q52 0 90 -38t38 -90z" />
-    <glyph glyph-name="_467" unicode="&#xf1f2;" horiz-adv-x="2304" 
-d="M313 759q0 -51 -36 -84q-29 -26 -89 -26h-17v220h17q61 0 89 -27q36 -31 36 -83zM2089 824q0 -52 -64 -52h-19v101h20q63 0 63 -49zM380 759q0 74 -50 120.5t-129 46.5h-95v-333h95q74 0 119 38q60 51 60 128zM410 593h65v333h-65v-333zM730 694q0 40 -20.5 62t-75.5 42
-q-29 10 -39.5 19t-10.5 23q0 16 13.5 26.5t34.5 10.5q29 0 53 -27l34 44q-41 37 -98 37q-44 0 -74 -27.5t-30 -67.5q0 -35 18 -55.5t64 -36.5q37 -13 45 -19q19 -12 19 -34q0 -20 -14 -33.5t-36 -13.5q-48 0 -71 44l-42 -40q44 -64 115 -64q51 0 83 30.5t32 79.5zM1008 604
-v77q-37 -37 -78 -37q-49 0 -80.5 32.5t-31.5 82.5q0 48 31.5 81.5t77.5 33.5q43 0 81 -38v77q-40 20 -80 20q-74 0 -125.5 -50.5t-51.5 -123.5t51 -123.5t125 -50.5q42 0 81 19zM2240 0v527q-65 -40 -144.5 -84t-237.5 -117t-329.5 -137.5t-417.5 -134.5t-504 -118h1569
-q26 0 45 19t19 45zM1389 757q0 75 -53 128t-128 53t-128 -53t-53 -128t53 -128t128 -53t128 53t53 128zM1541 584l144 342h-71l-90 -224l-89 224h-71l142 -342h35zM1714 593h184v56h-119v90h115v56h-115v74h119v57h-184v-333zM2105 593h80l-105 140q76 16 76 94q0 47 -31 73
-t-87 26h-97v-333h65v133h9zM2304 1274v-1268q0 -56 -38.5 -95t-93.5 -39h-2040q-55 0 -93.5 39t-38.5 95v1268q0 56 38.5 95t93.5 39h2040q55 0 93.5 -39t38.5 -95z" />
-    <glyph glyph-name="f1f3" unicode="&#xf1f3;" horiz-adv-x="2304" 
-d="M119 854h89l-45 108zM740 328l74 79l-70 79h-163v-49h142v-55h-142v-54h159zM898 406l99 -110v217zM1186 453q0 33 -40 33h-84v-69h83q41 0 41 36zM1475 457q0 29 -42 29h-82v-61h81q43 0 43 32zM1197 923q0 29 -42 29h-82v-60h81q43 0 43 31zM1656 854h89l-44 108z
-M699 1009v-271h-66v212l-94 -212h-57l-94 212v-212h-132l-25 60h-135l-25 -60h-70l116 271h96l110 -257v257h106l85 -184l77 184h108zM1255 453q0 -20 -5.5 -35t-14 -25t-22.5 -16.5t-26 -10t-31.5 -4.5t-31.5 -1t-32.5 0.5t-29.5 0.5v-91h-126l-80 90l-83 -90h-256v271h260
-l80 -89l82 89h207q109 0 109 -89zM964 794v-56h-217v271h217v-57h-152v-49h148v-55h-148v-54h152zM2304 235v-229q0 -55 -38.5 -94.5t-93.5 -39.5h-2040q-55 0 -93.5 39.5t-38.5 94.5v678h111l25 61h55l25 -61h218v46l19 -46h113l20 47v-47h541v99l10 1q10 0 10 -14v-86h279
-v23q23 -12 55 -18t52.5 -6.5t63 0.5t51.5 1l25 61h56l25 -61h227v58l34 -58h182v378h-180v-44l-25 44h-185v-44l-23 44h-249q-69 0 -109 -22v22h-172v-22q-24 22 -73 22h-628l-43 -97l-43 97h-198v-44l-22 44h-169l-78 -179v391q0 55 38.5 94.5t93.5 39.5h2040
-q55 0 93.5 -39.5t38.5 -94.5v-678h-120q-51 0 -81 -22v22h-177q-55 0 -78 -22v22h-316v-22q-31 22 -87 22h-209v-22q-23 22 -91 22h-234l-54 -58l-50 58h-349v-378h343l55 59l52 -59h211v89h21q59 0 90 13v-102h174v99h8q8 0 10 -2t2 -10v-87h529q57 0 88 24v-24h168
-q60 0 95 17zM1546 469q0 -23 -12 -43t-34 -29q25 -9 34 -26t9 -46v-54h-65v45q0 33 -12 43.5t-46 10.5h-69v-99h-65v271h154q48 0 77 -15t29 -58zM1269 936q0 -24 -12.5 -44t-33.5 -29q26 -9 34.5 -25.5t8.5 -46.5v-53h-65q0 9 0.5 26.5t0 25t-3 18.5t-8.5 16t-17.5 8.5
-t-29.5 3.5h-70v-98h-64v271l153 -1q49 0 78 -14.5t29 -57.5zM1798 327v-56h-216v271h216v-56h-151v-49h148v-55h-148v-54zM1372 1009v-271h-66v271h66zM2065 357q0 -86 -102 -86h-126v58h126q34 0 34 25q0 16 -17 21t-41.5 5t-49.5 3.5t-42 22.5t-17 55q0 39 26 60t66 21
-h130v-57h-119q-36 0 -36 -25q0 -16 17.5 -20.5t42 -4t49 -2.5t42 -21.5t17.5 -54.5zM2304 407v-101q-24 -35 -88 -35h-125v58h125q33 0 33 25q0 13 -12.5 19t-31 5.5t-40 2t-40 8t-31 24t-12.5 48.5q0 39 26.5 60t66.5 21h129v-57h-118q-36 0 -36 -25q0 -20 29 -22t68.5 -5
-t56.5 -26zM2139 1008v-270h-92l-122 203v-203h-132l-26 60h-134l-25 -60h-75q-129 0 -129 133q0 138 133 138h63v-59q-7 0 -28 1t-28.5 0.5t-23 -2t-21.5 -6.5t-14.5 -13.5t-11.5 -23t-3 -33.5q0 -38 13.5 -58t49.5 -20h29l92 213h97l109 -256v256h99l114 -188v188h66z" />
-    <glyph glyph-name="_469" unicode="&#xf1f4;" horiz-adv-x="2304" 
-d="M745 630q0 -37 -25.5 -61.5t-62.5 -24.5q-29 0 -46.5 16t-17.5 44q0 37 25 62.5t62 25.5q28 0 46.5 -16.5t18.5 -45.5zM1530 779q0 -42 -22 -57t-66 -15l-32 -1l17 107q2 11 13 11h18q22 0 35 -2t25 -12.5t12 -30.5zM1881 630q0 -36 -25.5 -61t-61.5 -25q-29 0 -47 16
-t-18 44q0 37 25 62.5t62 25.5q28 0 46.5 -16.5t18.5 -45.5zM513 801q0 59 -38.5 85.5t-100.5 26.5h-160q-19 0 -21 -19l-65 -408q-1 -6 3 -11t10 -5h76q20 0 22 19l18 110q1 8 7 13t15 6.5t17 1.5t19 -1t14 -1q86 0 135 48.5t49 134.5zM822 489l41 261q1 6 -3 11t-10 5h-76
-q-14 0 -17 -33q-27 40 -95 40q-72 0 -122.5 -54t-50.5 -127q0 -59 34.5 -94t92.5 -35q28 0 58 12t48 32q-4 -12 -4 -21q0 -16 13 -16h69q19 0 22 19zM1269 752q0 5 -4 9.5t-9 4.5h-77q-11 0 -18 -10l-106 -156l-44 150q-5 16 -22 16h-75q-5 0 -9 -4.5t-4 -9.5q0 -2 19.5 -59
-t42 -123t23.5 -70q-82 -112 -82 -120q0 -13 13 -13h77q11 0 18 10l255 368q2 2 2 7zM1649 801q0 59 -38.5 85.5t-100.5 26.5h-159q-20 0 -22 -19l-65 -408q-1 -6 3 -11t10 -5h82q12 0 16 13l18 116q1 8 7 13t15 6.5t17 1.5t19 -1t14 -1q86 0 135 48.5t49 134.5zM1958 489
-l41 261q1 6 -3 11t-10 5h-76q-14 0 -17 -33q-26 40 -95 40q-72 0 -122.5 -54t-50.5 -127q0 -59 34.5 -94t92.5 -35q29 0 59 12t47 32q0 -1 -2 -9t-2 -12q0 -16 13 -16h69q19 0 22 19zM2176 898v1q0 14 -13 14h-74q-11 0 -13 -11l-65 -416l-1 -2q0 -5 4 -9.5t10 -4.5h66
-q19 0 21 19zM392 764q-5 -35 -26 -46t-60 -11l-33 -1l17 107q2 11 13 11h19q40 0 58 -11.5t12 -48.5zM2304 1280v-1280q0 -52 -38 -90t-90 -38h-2048q-52 0 -90 38t-38 90v1280q0 52 38 90t90 38h2048q52 0 90 -38t38 -90z" />
-    <glyph glyph-name="_470" unicode="&#xf1f5;" horiz-adv-x="2304" 
-d="M1597 633q0 -69 -21 -106q-19 -35 -52 -35q-23 0 -41 9v224q29 30 57 30q57 0 57 -122zM2035 669h-110q6 98 56 98q51 0 54 -98zM476 534q0 59 -33 91.5t-101 57.5q-36 13 -52 24t-16 25q0 26 38 26q58 0 124 -33l18 112q-67 32 -149 32q-77 0 -123 -38q-48 -39 -48 -109
-q0 -58 32.5 -90.5t99.5 -56.5q39 -14 54.5 -25.5t15.5 -27.5q0 -31 -48 -31q-29 0 -70 12.5t-72 30.5l-18 -113q72 -41 168 -41q81 0 129 37q51 41 51 117zM771 749l19 111h-96v135l-129 -21l-18 -114l-46 -8l-17 -103h62v-219q0 -84 44 -120q38 -30 111 -30q32 0 79 11v118
-q-32 -7 -44 -7q-42 0 -42 50v197h77zM1087 724v139q-15 3 -28 3q-32 0 -55.5 -16t-33.5 -46l-10 56h-131v-471h150v306q26 31 82 31q16 0 26 -2zM1124 389h150v471h-150v-471zM1746 638q0 122 -45 179q-40 52 -111 52q-64 0 -117 -56l-8 47h-132v-645l150 25v151
-q36 -11 68 -11q83 0 134 56q61 65 61 202zM1278 986q0 33 -23 56t-56 23t-56 -23t-23 -56t23 -56.5t56 -23.5t56 23.5t23 56.5zM2176 629q0 113 -48 176q-50 64 -144 64q-96 0 -151.5 -66t-55.5 -180q0 -128 63 -188q55 -55 161 -55q101 0 160 40l-16 103q-57 -31 -128 -31
-q-43 0 -63 19q-23 19 -28 66h248q2 14 2 52zM2304 1280v-1280q0 -52 -38 -90t-90 -38h-2048q-52 0 -90 38t-38 90v1280q0 52 38 90t90 38h2048q52 0 90 -38t38 -90z" />
-    <glyph glyph-name="_471" unicode="&#xf1f6;" horiz-adv-x="2048" 
-d="M1558 684q61 -356 298 -556q0 -52 -38 -90t-90 -38h-448q0 -106 -75 -181t-181 -75t-180.5 74.5t-75.5 180.5zM1024 -176q16 0 16 16t-16 16q-59 0 -101.5 42.5t-42.5 101.5q0 16 -16 16t-16 -16q0 -73 51.5 -124.5t124.5 -51.5zM2026 1424q8 -10 7.5 -23.5t-10.5 -22.5
-l-1872 -1622q-10 -8 -23.5 -7t-21.5 11l-84 96q-8 10 -7.5 23.5t10.5 21.5l186 161q-19 32 -19 66q50 42 91 88t85 119.5t74.5 158.5t50 206t19.5 260q0 152 117 282.5t307 158.5q-8 19 -8 39q0 40 28 68t68 28t68 -28t28 -68q0 -20 -8 -39q124 -18 219 -82.5t148 -157.5
-l418 363q10 8 23.5 7t21.5 -11z" />
-    <glyph glyph-name="_472" unicode="&#xf1f7;" horiz-adv-x="2048" 
-d="M1040 -160q0 16 -16 16q-59 0 -101.5 42.5t-42.5 101.5q0 16 -16 16t-16 -16q0 -73 51.5 -124.5t124.5 -51.5q16 0 16 16zM503 315l877 760q-42 88 -132.5 146.5t-223.5 58.5q-93 0 -169.5 -31.5t-121.5 -80.5t-69 -103t-24 -105q0 -384 -137 -645zM1856 128
-q0 -52 -38 -90t-90 -38h-448q0 -106 -75 -181t-181 -75t-180.5 74.5t-75.5 180.5l149 129h757q-166 187 -227 459l111 97q61 -356 298 -556zM1942 1520l84 -96q8 -10 7.5 -23.5t-10.5 -22.5l-1872 -1622q-10 -8 -23.5 -7t-21.5 11l-84 96q-8 10 -7.5 23.5t10.5 21.5l186 161
-q-19 32 -19 66q50 42 91 88t85 119.5t74.5 158.5t50 206t19.5 260q0 152 117 282.5t307 158.5q-8 19 -8 39q0 40 28 68t68 28t68 -28t28 -68q0 -20 -8 -39q124 -18 219 -82.5t148 -157.5l418 363q10 8 23.5 7t21.5 -11z" />
-    <glyph glyph-name="_473" unicode="&#xf1f8;" horiz-adv-x="1408" 
-d="M512 160v704q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-704q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM768 160v704q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-704q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM1024 160v704q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-704
-q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM480 1152h448l-48 117q-7 9 -17 11h-317q-10 -2 -17 -11zM1408 1120v-64q0 -14 -9 -23t-23 -9h-96v-948q0 -83 -47 -143.5t-113 -60.5h-832q-66 0 -113 58.5t-47 141.5v952h-96q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h309l70 167
-q15 37 54 63t79 26h320q40 0 79 -26t54 -63l70 -167h309q14 0 23 -9t9 -23z" />
-    <glyph glyph-name="_474" unicode="&#xf1f9;" 
-d="M1150 462v-109q0 -50 -36.5 -89t-94 -60.5t-118 -32.5t-117.5 -11q-205 0 -342.5 139t-137.5 346q0 203 136 339t339 136q34 0 75.5 -4.5t93 -18t92.5 -34t69 -56.5t28 -81v-109q0 -16 -16 -16h-118q-16 0 -16 16v70q0 43 -65.5 67.5t-137.5 24.5q-140 0 -228.5 -91.5
-t-88.5 -237.5q0 -151 91.5 -249.5t233.5 -98.5q68 0 138 24t70 66v70q0 7 4.5 11.5t10.5 4.5h119q6 0 11 -4.5t5 -11.5zM768 1280q-130 0 -248.5 -51t-204 -136.5t-136.5 -204t-51 -248.5t51 -248.5t136.5 -204t204 -136.5t248.5 -51t248.5 51t204 136.5t136.5 204t51 248.5
-t-51 248.5t-136.5 204t-204 136.5t-248.5 51zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
-    <glyph glyph-name="_475" unicode="&#xf1fa;" 
-d="M972 761q0 108 -53.5 169t-147.5 61q-63 0 -124 -30.5t-110 -84.5t-79.5 -137t-30.5 -180q0 -112 53.5 -173t150.5 -61q96 0 176 66.5t122.5 166t42.5 203.5zM1536 640q0 -111 -37 -197t-98.5 -135t-131.5 -74.5t-145 -27.5q-6 0 -15.5 -0.5t-16.5 -0.5q-95 0 -142 53
-q-28 33 -33 83q-52 -66 -131.5 -110t-173.5 -44q-161 0 -249.5 95.5t-88.5 269.5q0 157 66 290t179 210.5t246 77.5q87 0 155 -35.5t106 -99.5l2 19l11 56q1 6 5.5 12t9.5 6h118q5 0 13 -11q5 -5 3 -16l-120 -614q-5 -24 -5 -48q0 -39 12.5 -52t44.5 -13q28 1 57 5.5t73 24
-t77 50t57 89.5t24 137q0 292 -174 466t-466 174q-130 0 -248.5 -51t-204 -136.5t-136.5 -204t-51 -248.5t51 -248.5t136.5 -204t204 -136.5t248.5 -51q228 0 405 144q11 9 24 8t21 -12l41 -49q8 -12 7 -24q-2 -13 -12 -22q-102 -83 -227.5 -128t-258.5 -45q-156 0 -298 61
-t-245 164t-164 245t-61 298t61 298t164 245t245 164t298 61q344 0 556 -212t212 -556z" />
-    <glyph glyph-name="_476" unicode="&#xf1fb;" horiz-adv-x="1792" 
-d="M1698 1442q94 -94 94 -226.5t-94 -225.5l-225 -223l104 -104q10 -10 10 -23t-10 -23l-210 -210q-10 -10 -23 -10t-23 10l-105 105l-603 -603q-37 -37 -90 -37h-203l-256 -128l-64 64l128 256v203q0 53 37 90l603 603l-105 105q-10 10 -10 23t10 23l210 210q10 10 23 10
-t23 -10l104 -104l223 225q93 94 225.5 94t226.5 -94zM512 64l576 576l-192 192l-576 -576v-192h192z" />
-    <glyph glyph-name="f1fc" unicode="&#xf1fc;" horiz-adv-x="1792" 
-d="M1615 1536q70 0 122.5 -46.5t52.5 -116.5q0 -63 -45 -151q-332 -629 -465 -752q-97 -91 -218 -91q-126 0 -216.5 92.5t-90.5 219.5q0 128 92 212l638 579q59 54 130 54zM706 502q39 -76 106.5 -130t150.5 -76l1 -71q4 -213 -129.5 -347t-348.5 -134q-123 0 -218 46.5
-t-152.5 127.5t-86.5 183t-29 220q7 -5 41 -30t62 -44.5t59 -36.5t46 -17q41 0 55 37q25 66 57.5 112.5t69.5 76t88 47.5t103 25.5t125 10.5z" />
-    <glyph glyph-name="_478" unicode="&#xf1fd;" horiz-adv-x="1792" 
-d="M1792 128v-384h-1792v384q45 0 85 14t59 27.5t47 37.5q30 27 51.5 38t56.5 11q24 0 44 -7t31 -15t33 -27q29 -25 47 -38t58 -27t86 -14q45 0 85 14.5t58 27t48 37.5q21 19 32.5 27t31 15t43.5 7q35 0 56.5 -11t51.5 -38q28 -24 47 -37.5t59 -27.5t85 -14t85 14t59 27.5
-t47 37.5q30 27 51.5 38t56.5 11q34 0 55.5 -11t51.5 -38q28 -24 47 -37.5t59 -27.5t85 -14zM1792 448v-192q-24 0 -44 7t-31 15t-33 27q-29 25 -47 38t-58 27t-85 14q-46 0 -86 -14t-58 -27t-47 -38q-22 -19 -33 -27t-31 -15t-44 -7q-35 0 -56.5 11t-51.5 38q-29 25 -47 38
-t-58 27t-86 14q-45 0 -85 -14.5t-58 -27t-48 -37.5q-21 -19 -32.5 -27t-31 -15t-43.5 -7q-35 0 -56.5 11t-51.5 38q-28 24 -47 37.5t-59 27.5t-85 14q-46 0 -86 -14t-58 -27t-47 -38q-30 -27 -51.5 -38t-56.5 -11v192q0 80 56 136t136 56h64v448h256v-448h256v448h256v-448
-h256v448h256v-448h64q80 0 136 -56t56 -136zM512 1312q0 -77 -36 -118.5t-92 -41.5q-53 0 -90.5 37.5t-37.5 90.5q0 29 9.5 51t23.5 34t31 28t31 31.5t23.5 44.5t9.5 67q38 0 83 -74t45 -150zM1024 1312q0 -77 -36 -118.5t-92 -41.5q-53 0 -90.5 37.5t-37.5 90.5
-q0 29 9.5 51t23.5 34t31 28t31 31.5t23.5 44.5t9.5 67q38 0 83 -74t45 -150zM1536 1312q0 -77 -36 -118.5t-92 -41.5q-53 0 -90.5 37.5t-37.5 90.5q0 29 9.5 51t23.5 34t31 28t31 31.5t23.5 44.5t9.5 67q38 0 83 -74t45 -150z" />
-    <glyph glyph-name="_479" unicode="&#xf1fe;" horiz-adv-x="2048" 
-d="M2048 0v-128h-2048v1536h128v-1408h1920zM1664 1024l256 -896h-1664v576l448 576l576 -576z" />
-    <glyph glyph-name="_480" unicode="&#xf200;" horiz-adv-x="1792" 
-d="M768 646l546 -546q-106 -108 -247.5 -168t-298.5 -60q-209 0 -385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103v-762zM955 640h773q0 -157 -60 -298.5t-168 -247.5zM1664 768h-768v768q209 0 385.5 -103t279.5 -279.5t103 -385.5z" />
-    <glyph glyph-name="_481" unicode="&#xf201;" horiz-adv-x="2048" 
-d="M2048 0v-128h-2048v1536h128v-1408h1920zM1920 1248v-435q0 -21 -19.5 -29.5t-35.5 7.5l-121 121l-633 -633q-10 -10 -23 -10t-23 10l-233 233l-416 -416l-192 192l585 585q10 10 23 10t23 -10l233 -233l464 464l-121 121q-16 16 -7.5 35.5t29.5 19.5h435q14 0 23 -9
-t9 -23z" />
-    <glyph glyph-name="_482" unicode="&#xf202;" horiz-adv-x="1792" 
-d="M1292 832q0 -6 10 -41q10 -29 25 -49.5t41 -34t44 -20t55 -16.5q325 -91 325 -332q0 -146 -105.5 -242.5t-254.5 -96.5q-59 0 -111.5 18.5t-91.5 45.5t-77 74.5t-63 87.5t-53.5 103.5t-43.5 103t-39.5 106.5t-35.5 95q-32 81 -61.5 133.5t-73.5 96.5t-104 64t-142 20
-q-96 0 -183 -55.5t-138 -144.5t-51 -185q0 -160 106.5 -279.5t263.5 -119.5q177 0 258 95q56 63 83 116l84 -152q-15 -34 -44 -70l1 -1q-131 -152 -388 -152q-147 0 -269.5 79t-190.5 207.5t-68 274.5q0 105 43.5 206t116 176.5t172 121.5t204.5 46q87 0 159 -19t123.5 -50
-t95 -80t72.5 -99t58.5 -117t50.5 -124.5t50 -130.5t55 -127q96 -200 233 -200q81 0 138.5 48.5t57.5 128.5q0 42 -19 72t-50.5 46t-72.5 31.5t-84.5 27t-87.5 34t-81 52t-65 82t-39 122.5q-3 16 -3 33q0 110 87.5 192t198.5 78q78 -3 120.5 -14.5t90.5 -53.5h-1
-q12 -11 23 -24.5t26 -36t19 -27.5l-129 -99q-26 49 -54 70v1q-23 21 -97 21q-49 0 -84 -33t-35 -83z" />
-    <glyph glyph-name="_483" unicode="&#xf203;" 
-d="M1432 484q0 173 -234 239q-35 10 -53 16.5t-38 25t-29 46.5q0 2 -2 8.5t-3 12t-1 7.5q0 36 24.5 59.5t60.5 23.5q54 0 71 -15h-1q20 -15 39 -51l93 71q-39 54 -49 64q-33 29 -67.5 39t-85.5 10q-80 0 -142 -57.5t-62 -137.5q0 -7 2 -23q16 -96 64.5 -140t148.5 -73
-q29 -8 49 -15.5t45 -21.5t38.5 -34.5t13.5 -46.5v-5q1 -58 -40.5 -93t-100.5 -35q-97 0 -167 144q-23 47 -51.5 121.5t-48 125.5t-54 110.5t-74 95.5t-103.5 60.5t-147 24.5q-101 0 -192 -56t-144 -148t-50 -192v-1q4 -108 50.5 -199t133.5 -147.5t196 -56.5q186 0 279 110
-q20 27 31 51l-60 109q-42 -80 -99 -116t-146 -36q-115 0 -191 87t-76 204q0 105 82 189t186 84q112 0 170 -53.5t104 -172.5q8 -21 25.5 -68.5t28.5 -76.5t31.5 -74.5t38.5 -74t45.5 -62.5t55.5 -53.5t66 -33t80 -13.5q107 0 183 69.5t76 174.5zM1536 1120v-960
-q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
-    <glyph glyph-name="_484" unicode="&#xf204;" horiz-adv-x="2048" 
-d="M1152 640q0 104 -40.5 198.5t-109.5 163.5t-163.5 109.5t-198.5 40.5t-198.5 -40.5t-163.5 -109.5t-109.5 -163.5t-40.5 -198.5t40.5 -198.5t109.5 -163.5t163.5 -109.5t198.5 -40.5t198.5 40.5t163.5 109.5t109.5 163.5t40.5 198.5zM1920 640q0 104 -40.5 198.5
-t-109.5 163.5t-163.5 109.5t-198.5 40.5h-386q119 -90 188.5 -224t69.5 -288t-69.5 -288t-188.5 -224h386q104 0 198.5 40.5t163.5 109.5t109.5 163.5t40.5 198.5zM2048 640q0 -130 -51 -248.5t-136.5 -204t-204 -136.5t-248.5 -51h-768q-130 0 -248.5 51t-204 136.5
-t-136.5 204t-51 248.5t51 248.5t136.5 204t204 136.5t248.5 51h768q130 0 248.5 -51t204 -136.5t136.5 -204t51 -248.5z" />
-    <glyph glyph-name="_485" unicode="&#xf205;" horiz-adv-x="2048" 
-d="M0 640q0 130 51 248.5t136.5 204t204 136.5t248.5 51h768q130 0 248.5 -51t204 -136.5t136.5 -204t51 -248.5t-51 -248.5t-136.5 -204t-204 -136.5t-248.5 -51h-768q-130 0 -248.5 51t-204 136.5t-136.5 204t-51 248.5zM1408 128q104 0 198.5 40.5t163.5 109.5
-t109.5 163.5t40.5 198.5t-40.5 198.5t-109.5 163.5t-163.5 109.5t-198.5 40.5t-198.5 -40.5t-163.5 -109.5t-109.5 -163.5t-40.5 -198.5t40.5 -198.5t109.5 -163.5t163.5 -109.5t198.5 -40.5z" />
-    <glyph glyph-name="_486" unicode="&#xf206;" horiz-adv-x="2304" 
-d="M762 384h-314q-40 0 -57.5 35t6.5 67l188 251q-65 31 -137 31q-132 0 -226 -94t-94 -226t94 -226t226 -94q115 0 203 72.5t111 183.5zM576 512h186q-18 85 -75 148zM1056 512l288 384h-480l-99 -132q105 -103 126 -252h165zM2176 448q0 132 -94 226t-226 94
-q-60 0 -121 -24l174 -260q15 -23 10 -49t-27 -40q-15 -11 -36 -11q-35 0 -53 29l-174 260q-93 -95 -93 -225q0 -132 94 -226t226 -94t226 94t94 226zM2304 448q0 -185 -131.5 -316.5t-316.5 -131.5t-316.5 131.5t-131.5 316.5q0 97 39.5 183.5t109.5 149.5l-65 98l-353 -469
-q-18 -26 -51 -26h-197q-23 -164 -149 -274t-294 -110q-185 0 -316.5 131.5t-131.5 316.5t131.5 316.5t316.5 131.5q114 0 215 -55l137 183h-224q-26 0 -45 19t-19 45t19 45t45 19h384v-128h435l-85 128h-222q-26 0 -45 19t-19 45t19 45t45 19h256q33 0 53 -28l267 -400
-q91 44 192 44q185 0 316.5 -131.5t131.5 -316.5z" />
-    <glyph glyph-name="_487" unicode="&#xf207;" 
-d="M384 320q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1408 320q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1362 716l-72 384q-5 23 -22.5 37.5t-40.5 14.5
-h-918q-23 0 -40.5 -14.5t-22.5 -37.5l-72 -384q-5 -30 14 -53t49 -23h1062q30 0 49 23t14 53zM1136 1328q0 20 -14 34t-34 14h-640q-20 0 -34 -14t-14 -34t14 -34t34 -14h640q20 0 34 14t14 34zM1536 603v-603h-128v-128q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5
-t-37.5 90.5v128h-768v-128q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5v128h-128v603q0 112 25 223l103 454q9 78 97.5 137t230 89t312.5 30t312.5 -30t230 -89t97.5 -137l105 -454q23 -102 23 -223z" />
-    <glyph glyph-name="_488" unicode="&#xf208;" horiz-adv-x="2048" 
-d="M1463 704q0 -35 -25 -60.5t-61 -25.5h-702q-36 0 -61 25.5t-25 60.5t25 60.5t61 25.5h702q36 0 61 -25.5t25 -60.5zM1677 704q0 86 -23 170h-982q-36 0 -61 25t-25 60q0 36 25 61t61 25h908q-88 143 -235 227t-320 84q-177 0 -327.5 -87.5t-238 -237.5t-87.5 -327
-q0 -86 23 -170h982q36 0 61 -25t25 -60q0 -36 -25 -61t-61 -25h-908q88 -143 235.5 -227t320.5 -84q132 0 253 51.5t208 139t139 208t52 253.5zM2048 959q0 -35 -25 -60t-61 -25h-131q17 -85 17 -170q0 -167 -65.5 -319.5t-175.5 -263t-262.5 -176t-319.5 -65.5
-q-246 0 -448.5 133t-301.5 350h-189q-36 0 -61 25t-25 61q0 35 25 60t61 25h132q-17 85 -17 170q0 167 65.5 319.5t175.5 263t262.5 176t320.5 65.5q245 0 447.5 -133t301.5 -350h188q36 0 61 -25t25 -61z" />
-    <glyph glyph-name="_489" unicode="&#xf209;" horiz-adv-x="1280" 
-d="M953 1158l-114 -328l117 -21q165 451 165 518q0 56 -38 56q-57 0 -130 -225zM654 471l33 -88q37 42 71 67l-33 5.5t-38.5 7t-32.5 8.5zM362 1367q0 -98 159 -521q17 10 49 10q15 0 75 -5l-121 351q-75 220 -123 220q-19 0 -29 -17.5t-10 -37.5zM283 608q0 -36 51.5 -119
-t117.5 -153t100 -70q14 0 25.5 13t11.5 27q0 24 -32 102q-13 32 -32 72t-47.5 89t-61.5 81t-62 32q-20 0 -45.5 -27t-25.5 -47zM125 273q0 -41 25 -104q59 -145 183.5 -227t281.5 -82q227 0 382 170q152 169 152 427q0 43 -1 67t-11.5 62t-30.5 56q-56 49 -211.5 75.5
-t-270.5 26.5q-37 0 -49 -11q-12 -5 -12 -35q0 -34 21.5 -60t55.5 -40t77.5 -23.5t87.5 -11.5t85 -4t70 0h23q24 0 40 -19q15 -19 19 -55q-28 -28 -96 -54q-61 -22 -93 -46q-64 -46 -108.5 -114t-44.5 -137q0 -31 18.5 -88.5t18.5 -87.5l-3 -12q-4 -12 -4 -14
-q-137 10 -146 216q-8 -2 -41 -2q2 -7 2 -21q0 -53 -40.5 -89.5t-94.5 -36.5q-82 0 -166.5 78t-84.5 159q0 34 33 67q52 -64 60 -76q77 -104 133 -104q12 0 26.5 8.5t14.5 20.5q0 34 -87.5 145t-116.5 111q-43 0 -70 -44.5t-27 -90.5zM11 264q0 101 42.5 163t136.5 88
-q-28 74 -28 104q0 62 61 123t122 61q29 0 70 -15q-163 462 -163 567q0 80 41 130.5t119 50.5q131 0 325 -581q6 -17 8 -23q6 16 29 79.5t43.5 118.5t54 127.5t64.5 123t70.5 86.5t76.5 36q71 0 112 -49t41 -122q0 -108 -159 -550q61 -15 100.5 -46t58.5 -78t26 -93.5
-t7 -110.5q0 -150 -47 -280t-132 -225t-211 -150t-278 -55q-111 0 -223 42q-149 57 -258 191.5t-109 286.5z" />
-    <glyph glyph-name="_490" unicode="&#xf20a;" horiz-adv-x="2048" 
-d="M785 528h207q-14 -158 -98.5 -248.5t-214.5 -90.5q-162 0 -254.5 116t-92.5 316q0 194 93 311.5t233 117.5q148 0 232 -87t97 -247h-203q-5 64 -35.5 99t-81.5 35q-57 0 -88.5 -60.5t-31.5 -177.5q0 -48 5 -84t18 -69.5t40 -51.5t66 -18q95 0 109 139zM1497 528h206
-q-14 -158 -98 -248.5t-214 -90.5q-162 0 -254.5 116t-92.5 316q0 194 93 311.5t233 117.5q148 0 232 -87t97 -247h-204q-4 64 -35 99t-81 35q-57 0 -88.5 -60.5t-31.5 -177.5q0 -48 5 -84t18 -69.5t39.5 -51.5t65.5 -18q49 0 76.5 38t33.5 101zM1856 647q0 207 -15.5 307
-t-60.5 161q-6 8 -13.5 14t-21.5 15t-16 11q-86 63 -697 63q-625 0 -710 -63q-5 -4 -17.5 -11.5t-21 -14t-14.5 -14.5q-45 -60 -60 -159.5t-15 -308.5q0 -208 15 -307.5t60 -160.5q6 -8 15 -15t20.5 -14t17.5 -12q44 -33 239.5 -49t470.5 -16q610 0 697 65q5 4 17 11t20.5 14
-t13.5 16q46 60 61 159t15 309zM2048 1408v-1536h-2048v1536h2048z" />
-    <glyph glyph-name="_491" unicode="&#xf20b;" 
-d="M992 912v-496q0 -14 -9 -23t-23 -9h-160q-14 0 -23 9t-9 23v496q0 112 -80 192t-192 80h-272v-1152q0 -14 -9 -23t-23 -9h-160q-14 0 -23 9t-9 23v1344q0 14 9 23t23 9h464q135 0 249 -66.5t180.5 -180.5t66.5 -249zM1376 1376v-880q0 -135 -66.5 -249t-180.5 -180.5
-t-249 -66.5h-464q-14 0 -23 9t-9 23v960q0 14 9 23t23 9h160q14 0 23 -9t9 -23v-768h272q112 0 192 80t80 192v880q0 14 9 23t23 9h160q14 0 23 -9t9 -23z" />
-    <glyph glyph-name="_492" unicode="&#xf20c;" 
-d="M1311 694v-114q0 -24 -13.5 -38t-37.5 -14h-202q-24 0 -38 14t-14 38v114q0 24 14 38t38 14h202q24 0 37.5 -14t13.5 -38zM821 464v250q0 53 -32.5 85.5t-85.5 32.5h-133q-68 0 -96 -52q-28 52 -96 52h-130q-53 0 -85.5 -32.5t-32.5 -85.5v-250q0 -22 21 -22h55
-q22 0 22 22v230q0 24 13.5 38t38.5 14h94q24 0 38 -14t14 -38v-230q0 -22 21 -22h54q22 0 22 22v230q0 24 14 38t38 14h97q24 0 37.5 -14t13.5 -38v-230q0 -22 22 -22h55q21 0 21 22zM1410 560v154q0 53 -33 85.5t-86 32.5h-264q-53 0 -86 -32.5t-33 -85.5v-410
-q0 -21 22 -21h55q21 0 21 21v180q31 -42 94 -42h191q53 0 86 32.5t33 85.5zM1536 1176v-1072q0 -96 -68 -164t-164 -68h-1072q-96 0 -164 68t-68 164v1072q0 96 68 164t164 68h1072q96 0 164 -68t68 -164z" />
-    <glyph glyph-name="_493" unicode="&#xf20d;" 
-d="M915 450h-294l147 551zM1001 128h311l-324 1024h-440l-324 -1024h311l383 314zM1536 1120v-960q0 -118 -85 -203t-203 -85h-960q-118 0 -203 85t-85 203v960q0 118 85 203t203 85h960q118 0 203 -85t85 -203z" />
-    <glyph glyph-name="_494" unicode="&#xf20e;" horiz-adv-x="2048" 
-d="M2048 641q0 -21 -13 -36.5t-33 -19.5l-205 -356q3 -9 3 -18q0 -20 -12.5 -35.5t-32.5 -19.5l-193 -337q3 -8 3 -16q0 -23 -16.5 -40t-40.5 -17q-25 0 -41 18h-400q-17 -20 -43 -20t-43 20h-399q-17 -20 -43 -20q-23 0 -40 16.5t-17 40.5q0 8 4 20l-193 335
-q-20 4 -32.5 19.5t-12.5 35.5q0 9 3 18l-206 356q-20 5 -32.5 20.5t-12.5 35.5q0 21 13.5 36.5t33.5 19.5l199 344q0 1 -0.5 3t-0.5 3q0 36 34 51l209 363q-4 10 -4 18q0 24 17 40.5t40 16.5q26 0 44 -21h396q16 21 43 21t43 -21h398q18 21 44 21q23 0 40 -16.5t17 -40.5
-q0 -6 -4 -18l207 -358q23 -1 39 -17.5t16 -38.5q0 -13 -7 -27l187 -324q19 -4 31.5 -19.5t12.5 -35.5zM1063 -158h389l-342 354h-143l-342 -354h360q18 16 39 16t39 -16zM112 654q1 -4 1 -13q0 -10 -2 -15l208 -360l15 -6l188 199v347l-187 194q-13 -8 -29 -10zM986 1438
-h-388l190 -200l554 200h-280q-16 -16 -38 -16t-38 16zM1689 226q1 6 5 11l-64 68l-17 -79h76zM1583 226l22 105l-252 266l-296 -307l63 -64h463zM1495 -142l16 28l65 310h-427l333 -343q8 4 13 5zM578 -158h5l342 354h-373v-335l4 -6q14 -5 22 -13zM552 226h402l64 66
-l-309 321l-157 -166v-221zM359 226h163v189l-168 -177q4 -8 5 -12zM358 1051q0 -1 0.5 -2t0.5 -2q0 -16 -8 -29l171 -177v269zM552 1121v-311l153 -157l297 314l-223 236zM556 1425l-4 -8v-264l205 74l-191 201q-6 -2 -10 -3zM1447 1438h-16l-621 -224l213 -225zM1023 946
-l-297 -315l311 -319l296 307zM688 634l-136 141v-284zM1038 270l-42 -44h85zM1374 618l238 -251l132 624l-3 5l-1 1zM1718 1018q-8 13 -8 29v2l-216 376q-5 1 -13 5l-437 -463l310 -327zM522 1142v223l-163 -282zM522 196h-163l163 -283v283zM1607 196l-48 -227l130 227h-82
-zM1729 266l207 361q-2 10 -2 14q0 1 3 16l-171 296l-129 -612l77 -82q5 3 15 7z" />
-    <glyph glyph-name="f210" unicode="&#xf210;" 
-d="M0 856q0 131 91.5 226.5t222.5 95.5h742l352 358v-1470q0 -132 -91.5 -227t-222.5 -95h-780q-131 0 -222.5 95t-91.5 227v790zM1232 102l-176 180v425q0 46 -32 79t-78 33h-484q-46 0 -78 -33t-32 -79v-492q0 -46 32.5 -79.5t77.5 -33.5h770z" />
-    <glyph glyph-name="_496" unicode="&#xf211;" 
-d="M934 1386q-317 -121 -556 -362.5t-358 -560.5q-20 89 -20 176q0 208 102.5 384.5t278.5 279t384 102.5q82 0 169 -19zM1203 1267q93 -65 164 -155q-389 -113 -674.5 -400.5t-396.5 -676.5q-93 72 -155 162q112 386 395 671t667 399zM470 -67q115 356 379.5 622t619.5 384
-q40 -92 54 -195q-292 -120 -516 -345t-343 -518q-103 14 -194 52zM1536 -125q-193 50 -367 115q-135 -84 -290 -107q109 205 274 370.5t369 275.5q-21 -152 -101 -284q65 -175 115 -370z" />
-    <glyph glyph-name="f212" unicode="&#xf212;" horiz-adv-x="2048" 
-d="M1893 1144l155 -1272q-131 0 -257 57q-200 91 -393 91q-226 0 -374 -148q-148 148 -374 148q-193 0 -393 -91q-128 -57 -252 -57h-5l155 1272q224 127 482 127q233 0 387 -106q154 106 387 106q258 0 482 -127zM1398 157q129 0 232 -28.5t260 -93.5l-124 1021
-q-171 78 -368 78q-224 0 -374 -141q-150 141 -374 141q-197 0 -368 -78l-124 -1021q105 43 165.5 65t148.5 39.5t178 17.5q202 0 374 -108q172 108 374 108zM1438 191l-55 907q-211 -4 -359 -155q-152 155 -374 155q-176 0 -336 -66l-114 -941q124 51 228.5 76t221.5 25
-q209 0 374 -102q172 107 374 102z" />
-    <glyph glyph-name="_498" unicode="&#xf213;" horiz-adv-x="2048" 
-d="M1500 165v733q0 21 -15 36t-35 15h-93q-20 0 -35 -15t-15 -36v-733q0 -20 15 -35t35 -15h93q20 0 35 15t15 35zM1216 165v531q0 20 -15 35t-35 15h-101q-20 0 -35 -15t-15 -35v-531q0 -20 15 -35t35 -15h101q20 0 35 15t15 35zM924 165v429q0 20 -15 35t-35 15h-101
-q-20 0 -35 -15t-15 -35v-429q0 -20 15 -35t35 -15h101q20 0 35 15t15 35zM632 165v362q0 20 -15 35t-35 15h-101q-20 0 -35 -15t-15 -35v-362q0 -20 15 -35t35 -15h101q20 0 35 15t15 35zM2048 311q0 -166 -118 -284t-284 -118h-1244q-166 0 -284 118t-118 284
-q0 116 63 214.5t168 148.5q-10 34 -10 73q0 113 80.5 193.5t193.5 80.5q102 0 180 -67q45 183 194 300t338 117q149 0 275 -73.5t199.5 -199.5t73.5 -275q0 -66 -14 -122q135 -33 221 -142.5t86 -247.5z" />
-    <glyph glyph-name="_499" unicode="&#xf214;" 
-d="M0 1536h1536v-1392l-776 -338l-760 338v1392zM1436 209v926h-1336v-926l661 -294zM1436 1235v201h-1336v-201h1336zM181 937v-115h-37v115h37zM181 789v-115h-37v115h37zM181 641v-115h-37v115h37zM181 493v-115h-37v115h37zM181 345v-115h-37v115h37zM207 202l15 34
-l105 -47l-15 -33zM343 142l15 34l105 -46l-15 -34zM478 82l15 34l105 -46l-15 -34zM614 23l15 33l104 -46l-15 -34zM797 10l105 46l15 -33l-105 -47zM932 70l105 46l15 -34l-105 -46zM1068 130l105 46l15 -34l-105 -46zM1203 189l105 47l15 -34l-105 -46zM259 1389v-36h-114
-v36h114zM421 1389v-36h-115v36h115zM583 1389v-36h-115v36h115zM744 1389v-36h-114v36h114zM906 1389v-36h-114v36h114zM1068 1389v-36h-115v36h115zM1230 1389v-36h-115v36h115zM1391 1389v-36h-114v36h114zM181 1049v-79h-37v115h115v-36h-78zM421 1085v-36h-115v36h115z
-M583 1085v-36h-115v36h115zM744 1085v-36h-114v36h114zM906 1085v-36h-114v36h114zM1068 1085v-36h-115v36h115zM1230 1085v-36h-115v36h115zM1355 970v79h-78v36h115v-115h-37zM1355 822v115h37v-115h-37zM1355 674v115h37v-115h-37zM1355 526v115h37v-115h-37zM1355 378
-v115h37v-115h-37zM1355 230v115h37v-115h-37zM760 265q-129 0 -221 91.5t-92 221.5q0 129 92 221t221 92q130 0 221.5 -92t91.5 -221q0 -130 -91.5 -221.5t-221.5 -91.5zM595 646q0 -36 19.5 -56.5t49.5 -25t64 -7t64 -2t49.5 -9t19.5 -30.5q0 -49 -112 -49q-97 0 -123 51
-h-3l-31 -63q67 -42 162 -42q29 0 56.5 5t55.5 16t45.5 33t17.5 53q0 46 -27.5 69.5t-67.5 27t-79.5 3t-67 5t-27.5 25.5q0 21 20.5 33t40.5 15t41 3q34 0 70.5 -11t51.5 -34h3l30 58q-3 1 -21 8.5t-22.5 9t-19.5 7t-22 7t-20 4.5t-24 4t-23 1q-29 0 -56.5 -5t-54 -16.5
-t-43 -34t-16.5 -53.5z" />
-    <glyph glyph-name="_500" unicode="&#xf215;" horiz-adv-x="2048" 
-d="M863 504q0 112 -79.5 191.5t-191.5 79.5t-191 -79.5t-79 -191.5t79 -191t191 -79t191.5 79t79.5 191zM1726 505q0 112 -79 191t-191 79t-191.5 -79t-79.5 -191q0 -113 79.5 -192t191.5 -79t191 79.5t79 191.5zM2048 1314v-1348q0 -44 -31.5 -75.5t-76.5 -31.5h-1832
-q-45 0 -76.5 31.5t-31.5 75.5v1348q0 44 31.5 75.5t76.5 31.5h431q44 0 76 -31.5t32 -75.5v-161h754v161q0 44 32 75.5t76 31.5h431q45 0 76.5 -31.5t31.5 -75.5z" />
-    <glyph glyph-name="_501" unicode="&#xf216;" horiz-adv-x="2048" 
-d="M1430 953zM1690 749q148 0 253 -98.5t105 -244.5q0 -157 -109 -261.5t-267 -104.5q-85 0 -162 27.5t-138 73.5t-118 106t-109 126t-103.5 132.5t-108.5 126.5t-117 106t-136 73.5t-159 27.5q-154 0 -251.5 -91.5t-97.5 -244.5q0 -157 104 -250t263 -93q100 0 208 37.5
-t193 98.5q5 4 21 18.5t30 24t22 9.5q14 0 24.5 -10.5t10.5 -24.5q0 -24 -60 -77q-101 -88 -234.5 -142t-260.5 -54q-133 0 -245.5 58t-180 165t-67.5 241q0 205 141.5 341t347.5 136q120 0 226.5 -43.5t185.5 -113t151.5 -153t139 -167.5t133.5 -153.5t149.5 -113
-t172.5 -43.5q102 0 168.5 61.5t66.5 162.5q0 95 -64.5 159t-159.5 64q-30 0 -81.5 -18.5t-68.5 -18.5q-20 0 -35.5 15t-15.5 35q0 18 8.5 57t8.5 59q0 159 -107.5 263t-266.5 104q-58 0 -111.5 -18.5t-84 -40.5t-55.5 -40.5t-33 -18.5q-15 0 -25.5 10.5t-10.5 25.5
-q0 19 25 46q59 67 147 103.5t182 36.5q191 0 318 -125.5t127 -315.5q0 -37 -4 -66q57 15 115 15z" />
-    <glyph glyph-name="_502" unicode="&#xf217;" horiz-adv-x="1664" 
-d="M1216 832q0 26 -19 45t-45 19h-128v128q0 26 -19 45t-45 19t-45 -19t-19 -45v-128h-128q-26 0 -45 -19t-19 -45t19 -45t45 -19h128v-128q0 -26 19 -45t45 -19t45 19t19 45v128h128q26 0 45 19t19 45zM640 0q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5
-t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1536 0q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1664 1088v-512q0 -24 -16 -42.5t-41 -21.5l-1044 -122q1 -7 4.5 -21.5t6 -26.5t2.5 -22q0 -16 -24 -64h920
-q26 0 45 -19t19 -45t-19 -45t-45 -19h-1024q-26 0 -45 19t-19 45q0 14 11 39.5t29.5 59.5t20.5 38l-177 823h-204q-26 0 -45 19t-19 45t19 45t45 19h256q16 0 28.5 -6.5t20 -15.5t13 -24.5t7.5 -26.5t5.5 -29.5t4.5 -25.5h1201q26 0 45 -19t19 -45z" />
-    <glyph glyph-name="_503" unicode="&#xf218;" horiz-adv-x="1664" 
-d="M1280 832q0 26 -19 45t-45 19t-45 -19l-147 -146v293q0 26 -19 45t-45 19t-45 -19t-19 -45v-293l-147 146q-19 19 -45 19t-45 -19t-19 -45t19 -45l256 -256q19 -19 45 -19t45 19l256 256q19 19 19 45zM640 0q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5
-t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1536 0q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1664 1088v-512q0 -24 -16 -42.5t-41 -21.5l-1044 -122q1 -7 4.5 -21.5t6 -26.5t2.5 -22q0 -16 -24 -64h920
-q26 0 45 -19t19 -45t-19 -45t-45 -19h-1024q-26 0 -45 19t-19 45q0 14 11 39.5t29.5 59.5t20.5 38l-177 823h-204q-26 0 -45 19t-19 45t19 45t45 19h256q16 0 28.5 -6.5t20 -15.5t13 -24.5t7.5 -26.5t5.5 -29.5t4.5 -25.5h1201q26 0 45 -19t19 -45z" />
-    <glyph glyph-name="_504" unicode="&#xf219;" horiz-adv-x="2048" 
-d="M212 768l623 -665l-300 665h-323zM1024 -4l349 772h-698zM538 896l204 384h-262l-288 -384h346zM1213 103l623 665h-323zM683 896h682l-204 384h-274zM1510 896h346l-288 384h-262zM1651 1382l384 -512q14 -18 13 -41.5t-17 -40.5l-960 -1024q-18 -20 -47 -20t-47 20
-l-960 1024q-16 17 -17 40.5t13 41.5l384 512q18 26 51 26h1152q33 0 51 -26z" />
-    <glyph glyph-name="_505" unicode="&#xf21a;" horiz-adv-x="2048" 
-d="M1811 -19q19 19 45 19t45 -19l128 -128l-90 -90l-83 83l-83 -83q-18 -19 -45 -19t-45 19l-83 83l-83 -83q-19 -19 -45 -19t-45 19l-83 83l-83 -83q-19 -19 -45 -19t-45 19l-83 83l-83 -83q-19 -19 -45 -19t-45 19l-83 83l-83 -83q-19 -19 -45 -19t-45 19l-83 83l-83 -83
-q-19 -19 -45 -19t-45 19l-83 83l-83 -83q-19 -19 -45 -19t-45 19l-128 128l90 90l83 -83l83 83q19 19 45 19t45 -19l83 -83l83 83q19 19 45 19t45 -19l83 -83l83 83q19 19 45 19t45 -19l83 -83l83 83q19 19 45 19t45 -19l83 -83l83 83q19 19 45 19t45 -19l83 -83l83 83
-q19 19 45 19t45 -19l83 -83zM237 19q-19 -19 -45 -19t-45 19l-128 128l90 90l83 -82l83 82q19 19 45 19t45 -19l83 -82l64 64v293l-210 314q-17 26 -7 56.5t40 40.5l177 58v299h128v128h256v128h256v-128h256v-128h128v-299l177 -58q30 -10 40 -40.5t-7 -56.5l-210 -314
-v-293l19 18q19 19 45 19t45 -19l83 -82l83 82q19 19 45 19t45 -19l128 -128l-90 -90l-83 83l-83 -83q-18 -19 -45 -19t-45 19l-83 83l-83 -83q-19 -19 -45 -19t-45 19l-83 83l-83 -83q-19 -19 -45 -19t-45 19l-83 83l-83 -83q-19 -19 -45 -19t-45 19l-83 83l-83 -83
-q-19 -19 -45 -19t-45 19l-83 83l-83 -83q-19 -19 -45 -19t-45 19l-83 83zM640 1152v-128l384 128l384 -128v128h-128v128h-512v-128h-128z" />
-    <glyph glyph-name="_506" unicode="&#xf21b;" 
-d="M576 0l96 448l-96 128l-128 64zM832 0l128 640l-128 -64l-96 -128zM992 1010q-2 4 -4 6q-10 8 -96 8q-70 0 -167 -19q-7 -2 -21 -2t-21 2q-97 19 -167 19q-86 0 -96 -8q-2 -2 -4 -6q2 -18 4 -27q2 -3 7.5 -6.5t7.5 -10.5q2 -4 7.5 -20.5t7 -20.5t7.5 -17t8.5 -17t9 -14
-t12 -13.5t14 -9.5t17.5 -8t20.5 -4t24.5 -2q36 0 59 12.5t32.5 30t14.5 34.5t11.5 29.5t17.5 12.5h12q11 0 17.5 -12.5t11.5 -29.5t14.5 -34.5t32.5 -30t59 -12.5q13 0 24.5 2t20.5 4t17.5 8t14 9.5t12 13.5t9 14t8.5 17t7.5 17t7 20.5t7.5 20.5q2 7 7.5 10.5t7.5 6.5
-q2 9 4 27zM1408 131q0 -121 -73 -190t-194 -69h-874q-121 0 -194 69t-73 190q0 61 4.5 118t19 125.5t37.5 123.5t63.5 103.5t93.5 74.5l-90 220h214q-22 64 -22 128q0 12 2 32q-194 40 -194 96q0 57 210 99q17 62 51.5 134t70.5 114q32 37 76 37q30 0 84 -31t84 -31t84 31
-t84 31q44 0 76 -37q36 -42 70.5 -114t51.5 -134q210 -42 210 -99q0 -56 -194 -96q7 -81 -20 -160h214l-82 -225q63 -33 107.5 -96.5t65.5 -143.5t29 -151.5t8 -148.5z" />
-    <glyph glyph-name="_507" unicode="&#xf21c;" horiz-adv-x="2304" 
-d="M2301 500q12 -103 -22 -198.5t-99 -163.5t-158.5 -106t-196.5 -31q-161 11 -279.5 125t-134.5 274q-12 111 27.5 210.5t118.5 170.5l-71 107q-96 -80 -151 -194t-55 -244q0 -27 -18.5 -46.5t-45.5 -19.5h-256h-69q-23 -164 -149 -274t-294 -110q-185 0 -316.5 131.5
-t-131.5 316.5t131.5 316.5t316.5 131.5q76 0 152 -27l24 45q-123 110 -304 110h-64q-26 0 -45 19t-19 45t19 45t45 19h128q78 0 145 -13.5t116.5 -38.5t71.5 -39.5t51 -36.5h512h115l-85 128h-222q-30 0 -49 22.5t-14 52.5q4 23 23 38t43 15h253q33 0 53 -28l70 -105
-l114 114q19 19 46 19h101q26 0 45 -19t19 -45v-128q0 -26 -19 -45t-45 -19h-179l115 -172q131 63 275 36q143 -26 244 -134.5t118 -253.5zM448 128q115 0 203 72.5t111 183.5h-314q-35 0 -55 31q-18 32 -1 63l147 277q-47 13 -91 13q-132 0 -226 -94t-94 -226t94 -226
-t226 -94zM1856 128q132 0 226 94t94 226t-94 226t-226 94q-60 0 -121 -24l174 -260q15 -23 10 -49t-27 -40q-15 -11 -36 -11q-35 0 -53 29l-174 260q-93 -95 -93 -225q0 -132 94 -226t226 -94z" />
-    <glyph glyph-name="_508" unicode="&#xf21d;" 
-d="M1408 0q0 -63 -61.5 -113.5t-164 -81t-225 -46t-253.5 -15.5t-253.5 15.5t-225 46t-164 81t-61.5 113.5q0 49 33 88.5t91 66.5t118 44.5t131 29.5q26 5 48 -10.5t26 -41.5q5 -26 -10.5 -48t-41.5 -26q-58 -10 -106 -23.5t-76.5 -25.5t-48.5 -23.5t-27.5 -19.5t-8.5 -12
-q3 -11 27 -26.5t73 -33t114 -32.5t160.5 -25t201.5 -10t201.5 10t160.5 25t114 33t73 33.5t27 27.5q-1 4 -8.5 11t-27.5 19t-48.5 23.5t-76.5 25t-106 23.5q-26 4 -41.5 26t-10.5 48q4 26 26 41.5t48 10.5q71 -12 131 -29.5t118 -44.5t91 -66.5t33 -88.5zM1024 896v-384
-q0 -26 -19 -45t-45 -19h-64v-384q0 -26 -19 -45t-45 -19h-256q-26 0 -45 19t-19 45v384h-64q-26 0 -45 19t-19 45v384q0 53 37.5 90.5t90.5 37.5h384q53 0 90.5 -37.5t37.5 -90.5zM928 1280q0 -93 -65.5 -158.5t-158.5 -65.5t-158.5 65.5t-65.5 158.5t65.5 158.5t158.5 65.5
-t158.5 -65.5t65.5 -158.5z" />
-    <glyph glyph-name="_509" unicode="&#xf21e;" horiz-adv-x="1792" 
-d="M1280 512h305q-5 -6 -10 -10.5t-9 -7.5l-3 -4l-623 -600q-18 -18 -44 -18t-44 18l-624 602q-5 2 -21 20h369q22 0 39.5 13.5t22.5 34.5l70 281l190 -667q6 -20 23 -33t39 -13q21 0 38 13t23 33l146 485l56 -112q18 -35 57 -35zM1792 940q0 -145 -103 -300h-369l-111 221
-q-8 17 -25.5 27t-36.5 8q-45 -5 -56 -46l-129 -430l-196 686q-6 20 -23.5 33t-39.5 13t-39 -13.5t-22 -34.5l-116 -464h-423q-103 155 -103 300q0 220 127 344t351 124q62 0 126.5 -21.5t120 -58t95.5 -68.5t76 -68q36 36 76 68t95.5 68.5t120 58t126.5 21.5q224 0 351 -124
-t127 -344z" />
-    <glyph glyph-name="venus" unicode="&#xf221;" horiz-adv-x="1280" 
-d="M1152 960q0 -221 -147.5 -384.5t-364.5 -187.5v-260h224q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-224v-224q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v224h-224q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h224v260q-150 16 -271.5 103t-186 224t-52.5 292
-q11 134 80.5 249t182 188t245.5 88q170 19 319 -54t236 -212t87 -306zM128 960q0 -185 131.5 -316.5t316.5 -131.5t316.5 131.5t131.5 316.5t-131.5 316.5t-316.5 131.5t-316.5 -131.5t-131.5 -316.5z" />
-    <glyph glyph-name="_511" unicode="&#xf222;" 
-d="M1472 1408q26 0 45 -19t19 -45v-416q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v262l-382 -383q126 -156 126 -359q0 -117 -45.5 -223.5t-123 -184t-184 -123t-223.5 -45.5t-223.5 45.5t-184 123t-123 184t-45.5 223.5t45.5 223.5t123 184t184 123t223.5 45.5
-q203 0 359 -126l382 382h-261q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h416zM576 0q185 0 316.5 131.5t131.5 316.5t-131.5 316.5t-316.5 131.5t-316.5 -131.5t-131.5 -316.5t131.5 -316.5t316.5 -131.5z" />
-    <glyph glyph-name="_512" unicode="&#xf223;" horiz-adv-x="1280" 
-d="M830 1220q145 -72 233.5 -210.5t88.5 -305.5q0 -221 -147.5 -384.5t-364.5 -187.5v-132h96q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-96v-96q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v96h-96q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h96v132q-217 24 -364.5 187.5
-t-147.5 384.5q0 167 88.5 305.5t233.5 210.5q-165 96 -228 273q-6 16 3.5 29.5t26.5 13.5h69q21 0 29 -20q44 -106 140 -171t214 -65t214 65t140 171q8 20 37 20h61q17 0 26.5 -13.5t3.5 -29.5q-63 -177 -228 -273zM576 256q185 0 316.5 131.5t131.5 316.5t-131.5 316.5
-t-316.5 131.5t-316.5 -131.5t-131.5 -316.5t131.5 -316.5t316.5 -131.5z" />
-    <glyph glyph-name="_513" unicode="&#xf224;" 
-d="M1024 1504q0 14 9 23t23 9h288q26 0 45 -19t19 -45v-288q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v134l-254 -255q126 -158 126 -359q0 -221 -147.5 -384.5t-364.5 -187.5v-132h96q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-96v-96q0 -14 -9 -23t-23 -9h-64
-q-14 0 -23 9t-9 23v96h-96q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h96v132q-149 16 -270.5 103t-186.5 223.5t-53 291.5q16 204 160 353.5t347 172.5q118 14 228 -19t198 -103l255 254h-134q-14 0 -23 9t-9 23v64zM576 256q185 0 316.5 131.5t131.5 316.5t-131.5 316.5
-t-316.5 131.5t-316.5 -131.5t-131.5 -316.5t131.5 -316.5t316.5 -131.5z" />
-    <glyph glyph-name="_514" unicode="&#xf225;" horiz-adv-x="1792" 
-d="M1280 1504q0 14 9 23t23 9h288q26 0 45 -19t19 -45v-288q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v134l-254 -255q126 -158 126 -359q0 -221 -147.5 -384.5t-364.5 -187.5v-132h96q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-96v-96q0 -14 -9 -23t-23 -9h-64
-q-14 0 -23 9t-9 23v96h-96q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h96v132q-217 24 -364.5 187.5t-147.5 384.5q0 201 126 359l-52 53l-101 -111q-9 -10 -22 -10.5t-23 7.5l-48 44q-10 8 -10.5 21.5t8.5 23.5l105 115l-111 112v-134q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9
-t-9 23v288q0 26 19 45t45 19h288q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-133l106 -107l86 94q9 10 22 10.5t23 -7.5l48 -44q10 -8 10.5 -21.5t-8.5 -23.5l-90 -99l57 -56q158 126 359 126t359 -126l255 254h-134q-14 0 -23 9t-9 23v64zM832 256q185 0 316.5 131.5
-t131.5 316.5t-131.5 316.5t-316.5 131.5t-316.5 -131.5t-131.5 -316.5t131.5 -316.5t316.5 -131.5z" />
-    <glyph glyph-name="_515" unicode="&#xf226;" horiz-adv-x="1792" 
-d="M1790 1007q12 -155 -52.5 -292t-186 -224t-271.5 -103v-260h224q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-224v-224q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v224h-512v-224q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v224h-224q-14 0 -23 9t-9 23v64q0 14 9 23
-t23 9h224v260q-150 16 -271.5 103t-186 224t-52.5 292q17 206 164.5 356.5t352.5 169.5q206 21 377 -94q171 115 377 94q205 -19 352.5 -169.5t164.5 -356.5zM896 647q128 131 128 313t-128 313q-128 -131 -128 -313t128 -313zM576 512q115 0 218 57q-154 165 -154 391
-q0 224 154 391q-103 57 -218 57q-185 0 -316.5 -131.5t-131.5 -316.5t131.5 -316.5t316.5 -131.5zM1152 128v260q-137 15 -256 94q-119 -79 -256 -94v-260h512zM1216 512q185 0 316.5 131.5t131.5 316.5t-131.5 316.5t-316.5 131.5q-115 0 -218 -57q154 -167 154 -391
-q0 -226 -154 -391q103 -57 218 -57z" />
-    <glyph glyph-name="_516" unicode="&#xf227;" horiz-adv-x="1920" 
-d="M1536 1120q0 14 9 23t23 9h288q26 0 45 -19t19 -45v-288q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v134l-254 -255q76 -95 107.5 -214t9.5 -247q-31 -182 -166 -312t-318 -156q-210 -29 -384.5 80t-241.5 300q-117 6 -221 57.5t-177.5 133t-113.5 192.5t-32 230
-q9 135 78 252t182 191.5t248 89.5q118 14 227.5 -19t198.5 -103l255 254h-134q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h288q26 0 45 -19t19 -45v-288q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v134l-254 -255q59 -74 93 -169q182 -9 328 -124l255 254h-134q-14 0 -23 9
-t-9 23v64zM1024 704q0 20 -4 58q-162 -25 -271 -150t-109 -292q0 -20 4 -58q162 25 271 150t109 292zM128 704q0 -168 111 -294t276 -149q-3 29 -3 59q0 210 135 369.5t338 196.5q-53 120 -163.5 193t-245.5 73q-185 0 -316.5 -131.5t-131.5 -316.5zM1088 -128
-q185 0 316.5 131.5t131.5 316.5q0 168 -111 294t-276 149q3 -28 3 -59q0 -210 -135 -369.5t-338 -196.5q53 -120 163.5 -193t245.5 -73z" />
-    <glyph glyph-name="_517" unicode="&#xf228;" horiz-adv-x="2048" 
-d="M1664 1504q0 14 9 23t23 9h288q26 0 45 -19t19 -45v-288q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v134l-254 -255q76 -95 107.5 -214t9.5 -247q-32 -180 -164.5 -310t-313.5 -157q-223 -34 -409 90q-117 -78 -256 -93v-132h96q14 0 23 -9t9 -23v-64q0 -14 -9 -23
-t-23 -9h-96v-96q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v96h-96q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h96v132q-155 17 -279.5 109.5t-187 237.5t-39.5 307q25 187 159.5 322.5t320.5 164.5q224 34 410 -90q146 97 320 97q201 0 359 -126l255 254h-134q-14 0 -23 9
-t-9 23v64zM896 391q128 131 128 313t-128 313q-128 -131 -128 -313t128 -313zM128 704q0 -185 131.5 -316.5t316.5 -131.5q117 0 218 57q-154 167 -154 391t154 391q-101 57 -218 57q-185 0 -316.5 -131.5t-131.5 -316.5zM1216 256q185 0 316.5 131.5t131.5 316.5
-t-131.5 316.5t-316.5 131.5q-117 0 -218 -57q154 -167 154 -391t-154 -391q101 -57 218 -57z" />
-    <glyph glyph-name="_518" unicode="&#xf229;" 
-d="M1472 1408q26 0 45 -19t19 -45v-416q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v262l-213 -214l140 -140q9 -10 9 -23t-9 -22l-46 -46q-9 -9 -22 -9t-23 9l-140 141l-78 -79q126 -156 126 -359q0 -117 -45.5 -223.5t-123 -184t-184 -123t-223.5 -45.5t-223.5 45.5
-t-184 123t-123 184t-45.5 223.5t45.5 223.5t123 184t184 123t223.5 45.5q203 0 359 -126l78 78l-172 172q-9 10 -9 23t9 22l46 46q9 9 22 9t23 -9l172 -172l213 213h-261q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h416zM576 0q185 0 316.5 131.5t131.5 316.5t-131.5 316.5
-t-316.5 131.5t-316.5 -131.5t-131.5 -316.5t131.5 -316.5t316.5 -131.5z" />
-    <glyph glyph-name="_519" unicode="&#xf22a;" horiz-adv-x="1280" 
-d="M640 892q217 -24 364.5 -187.5t147.5 -384.5q0 -167 -87 -306t-236 -212t-319 -54q-133 15 -245.5 88t-182 188t-80.5 249q-12 155 52.5 292t186 224t271.5 103v132h-160q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h160v165l-92 -92q-10 -9 -23 -9t-22 9l-46 46q-9 9 -9 22
-t9 23l202 201q19 19 45 19t45 -19l202 -201q9 -10 9 -23t-9 -22l-46 -46q-9 -9 -22 -9t-23 9l-92 92v-165h160q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-160v-132zM576 -128q185 0 316.5 131.5t131.5 316.5t-131.5 316.5t-316.5 131.5t-316.5 -131.5t-131.5 -316.5
-t131.5 -316.5t316.5 -131.5z" />
-    <glyph glyph-name="_520" unicode="&#xf22b;" horiz-adv-x="2048" 
-d="M1901 621q19 -19 19 -45t-19 -45l-294 -294q-9 -10 -22.5 -10t-22.5 10l-45 45q-10 9 -10 22.5t10 22.5l185 185h-294v-224q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v224h-132q-24 -217 -187.5 -364.5t-384.5 -147.5q-167 0 -306 87t-212 236t-54 319q15 133 88 245.5
-t188 182t249 80.5q155 12 292 -52.5t224 -186t103 -271.5h132v224q0 14 9 23t23 9h64q14 0 23 -9t9 -23v-224h294l-185 185q-10 9 -10 22.5t10 22.5l45 45q9 10 22.5 10t22.5 -10zM576 128q185 0 316.5 131.5t131.5 316.5t-131.5 316.5t-316.5 131.5t-316.5 -131.5
-t-131.5 -316.5t131.5 -316.5t316.5 -131.5z" />
-    <glyph glyph-name="_521" unicode="&#xf22c;" horiz-adv-x="1280" 
-d="M1152 960q0 -221 -147.5 -384.5t-364.5 -187.5v-612q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v612q-217 24 -364.5 187.5t-147.5 384.5q0 117 45.5 223.5t123 184t184 123t223.5 45.5t223.5 -45.5t184 -123t123 -184t45.5 -223.5zM576 512q185 0 316.5 131.5
-t131.5 316.5t-131.5 316.5t-316.5 131.5t-316.5 -131.5t-131.5 -316.5t131.5 -316.5t316.5 -131.5z" />
-    <glyph glyph-name="_522" unicode="&#xf22d;" horiz-adv-x="1280" 
-d="M1024 576q0 185 -131.5 316.5t-316.5 131.5t-316.5 -131.5t-131.5 -316.5t131.5 -316.5t316.5 -131.5t316.5 131.5t131.5 316.5zM1152 576q0 -117 -45.5 -223.5t-123 -184t-184 -123t-223.5 -45.5t-223.5 45.5t-184 123t-123 184t-45.5 223.5t45.5 223.5t123 184t184 123
-t223.5 45.5t223.5 -45.5t184 -123t123 -184t45.5 -223.5z" />
-    <glyph glyph-name="_523" unicode="&#xf22e;" horiz-adv-x="1792" 
- />
-    <glyph glyph-name="_524" unicode="&#xf22f;" horiz-adv-x="1792" 
- />
-    <glyph glyph-name="_525" unicode="&#xf230;" 
-d="M1451 1408q35 0 60 -25t25 -60v-1366q0 -35 -25 -60t-60 -25h-391v595h199l30 232h-229v148q0 56 23.5 84t91.5 28l122 1v207q-63 9 -178 9q-136 0 -217.5 -80t-81.5 -226v-171h-200v-232h200v-595h-735q-35 0 -60 25t-25 60v1366q0 35 25 60t60 25h1366z" />
-    <glyph glyph-name="_526" unicode="&#xf231;" horiz-adv-x="1280" 
-d="M0 939q0 108 37.5 203.5t103.5 166.5t152 123t185 78t202 26q158 0 294 -66.5t221 -193.5t85 -287q0 -96 -19 -188t-60 -177t-100 -149.5t-145 -103t-189 -38.5q-68 0 -135 32t-96 88q-10 -39 -28 -112.5t-23.5 -95t-20.5 -71t-26 -71t-32 -62.5t-46 -77.5t-62 -86.5
-l-14 -5l-9 10q-15 157 -15 188q0 92 21.5 206.5t66.5 287.5t52 203q-32 65 -32 169q0 83 52 156t132 73q61 0 95 -40.5t34 -102.5q0 -66 -44 -191t-44 -187q0 -63 45 -104.5t109 -41.5q55 0 102 25t78.5 68t56 95t38 110.5t20 111t6.5 99.5q0 173 -109.5 269.5t-285.5 96.5
-q-200 0 -334 -129.5t-134 -328.5q0 -44 12.5 -85t27 -65t27 -45.5t12.5 -30.5q0 -28 -15 -73t-37 -45q-2 0 -17 3q-51 15 -90.5 56t-61 94.5t-32.5 108t-11 106.5z" />
-    <glyph glyph-name="_527" unicode="&#xf232;" 
-d="M985 562q13 0 97.5 -44t89.5 -53q2 -5 2 -15q0 -33 -17 -76q-16 -39 -71 -65.5t-102 -26.5q-57 0 -190 62q-98 45 -170 118t-148 185q-72 107 -71 194v8q3 91 74 158q24 22 52 22q6 0 18 -1.5t19 -1.5q19 0 26.5 -6.5t15.5 -27.5q8 -20 33 -88t25 -75q0 -21 -34.5 -57.5
-t-34.5 -46.5q0 -7 5 -15q34 -73 102 -137q56 -53 151 -101q12 -7 22 -7q15 0 54 48.5t52 48.5zM782 32q127 0 243.5 50t200.5 134t134 200.5t50 243.5t-50 243.5t-134 200.5t-200.5 134t-243.5 50t-243.5 -50t-200.5 -134t-134 -200.5t-50 -243.5q0 -203 120 -368l-79 -233
-l242 77q158 -104 345 -104zM782 1414q153 0 292.5 -60t240.5 -161t161 -240.5t60 -292.5t-60 -292.5t-161 -240.5t-240.5 -161t-292.5 -60q-195 0 -365 94l-417 -134l136 405q-108 178 -108 389q0 153 60 292.5t161 240.5t240.5 161t292.5 60z" />
-    <glyph glyph-name="_528" unicode="&#xf233;" horiz-adv-x="1792" 
-d="M128 128h1024v128h-1024v-128zM128 640h1024v128h-1024v-128zM1696 192q0 40 -28 68t-68 28t-68 -28t-28 -68t28 -68t68 -28t68 28t28 68zM128 1152h1024v128h-1024v-128zM1696 704q0 40 -28 68t-68 28t-68 -28t-28 -68t28 -68t68 -28t68 28t28 68zM1696 1216
-q0 40 -28 68t-68 28t-68 -28t-28 -68t28 -68t68 -28t68 28t28 68zM1792 384v-384h-1792v384h1792zM1792 896v-384h-1792v384h1792zM1792 1408v-384h-1792v384h1792z" />
-    <glyph glyph-name="_529" unicode="&#xf234;" horiz-adv-x="2048" 
-d="M704 640q-159 0 -271.5 112.5t-112.5 271.5t112.5 271.5t271.5 112.5t271.5 -112.5t112.5 -271.5t-112.5 -271.5t-271.5 -112.5zM1664 512h352q13 0 22.5 -9.5t9.5 -22.5v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-352v-352q0 -13 -9.5 -22.5t-22.5 -9.5h-192q-13 0 -22.5 9.5
-t-9.5 22.5v352h-352q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h352v352q0 13 9.5 22.5t22.5 9.5h192q13 0 22.5 -9.5t9.5 -22.5v-352zM928 288q0 -52 38 -90t90 -38h256v-238q-68 -50 -171 -50h-874q-121 0 -194 69t-73 190q0 53 3.5 103.5t14 109t26.5 108.5
-t43 97.5t62 81t85.5 53.5t111.5 20q19 0 39 -17q79 -61 154.5 -91.5t164.5 -30.5t164.5 30.5t154.5 91.5q20 17 39 17q132 0 217 -96h-223q-52 0 -90 -38t-38 -90v-192z" />
-    <glyph glyph-name="_530" unicode="&#xf235;" horiz-adv-x="2048" 
-d="M704 640q-159 0 -271.5 112.5t-112.5 271.5t112.5 271.5t271.5 112.5t271.5 -112.5t112.5 -271.5t-112.5 -271.5t-271.5 -112.5zM1781 320l249 -249q9 -9 9 -23q0 -13 -9 -22l-136 -136q-9 -9 -22 -9q-14 0 -23 9l-249 249l-249 -249q-9 -9 -23 -9q-13 0 -22 9l-136 136
-q-9 9 -9 22q0 14 9 23l249 249l-249 249q-9 9 -9 23q0 13 9 22l136 136q9 9 22 9q14 0 23 -9l249 -249l249 249q9 9 23 9q13 0 22 -9l136 -136q9 -9 9 -22q0 -14 -9 -23zM1283 320l-181 -181q-37 -37 -37 -91q0 -53 37 -90l83 -83q-21 -3 -44 -3h-874q-121 0 -194 69
-t-73 190q0 53 3.5 103.5t14 109t26.5 108.5t43 97.5t62 81t85.5 53.5t111.5 20q19 0 39 -17q154 -122 319 -122t319 122q20 17 39 17q28 0 57 -6q-28 -27 -41 -50t-13 -56q0 -54 37 -91z" />
-    <glyph glyph-name="_531" unicode="&#xf236;" horiz-adv-x="2048" 
-d="M256 512h1728q26 0 45 -19t19 -45v-448h-256v256h-1536v-256h-256v1216q0 26 19 45t45 19h128q26 0 45 -19t19 -45v-704zM832 832q0 106 -75 181t-181 75t-181 -75t-75 -181t75 -181t181 -75t181 75t75 181zM2048 576v64q0 159 -112.5 271.5t-271.5 112.5h-704
-q-26 0 -45 -19t-19 -45v-384h1152z" />
-    <glyph glyph-name="_532" unicode="&#xf237;" 
-d="M1536 1536l-192 -448h192v-192h-274l-55 -128h329v-192h-411l-357 -832l-357 832h-411v192h329l-55 128h-274v192h192l-192 448h256l323 -768h378l323 768h256zM768 320l108 256h-216z" />
-    <glyph glyph-name="_533" unicode="&#xf238;" 
-d="M1088 1536q185 0 316.5 -93.5t131.5 -226.5v-896q0 -130 -125.5 -222t-305.5 -97l213 -202q16 -15 8 -35t-30 -20h-1056q-22 0 -30 20t8 35l213 202q-180 5 -305.5 97t-125.5 222v896q0 133 131.5 226.5t316.5 93.5h640zM768 192q80 0 136 56t56 136t-56 136t-136 56
-t-136 -56t-56 -136t56 -136t136 -56zM1344 768v512h-1152v-512h1152z" />
-    <glyph glyph-name="_534" unicode="&#xf239;" 
-d="M1088 1536q185 0 316.5 -93.5t131.5 -226.5v-896q0 -130 -125.5 -222t-305.5 -97l213 -202q16 -15 8 -35t-30 -20h-1056q-22 0 -30 20t8 35l213 202q-180 5 -305.5 97t-125.5 222v896q0 133 131.5 226.5t316.5 93.5h640zM288 224q66 0 113 47t47 113t-47 113t-113 47
-t-113 -47t-47 -113t47 -113t113 -47zM704 768v512h-544v-512h544zM1248 224q66 0 113 47t47 113t-47 113t-113 47t-113 -47t-47 -113t47 -113t113 -47zM1408 768v512h-576v-512h576z" />
-    <glyph glyph-name="_535" unicode="&#xf23a;" horiz-adv-x="1792" 
-d="M597 1115v-1173q0 -25 -12.5 -42.5t-36.5 -17.5q-17 0 -33 8l-465 233q-21 10 -35.5 33.5t-14.5 46.5v1140q0 20 10 34t29 14q14 0 44 -15l511 -256q3 -3 3 -5zM661 1014l534 -866l-534 266v600zM1792 996v-1054q0 -25 -14 -40.5t-38 -15.5t-47 13l-441 220zM1789 1116
-q0 -3 -256.5 -419.5t-300.5 -487.5l-390 634l324 527q17 28 52 28q14 0 26 -6l541 -270q4 -2 4 -6z" />
-    <glyph glyph-name="_536" unicode="&#xf23b;" 
-d="M809 532l266 499h-112l-157 -312q-24 -48 -44 -92l-42 92l-155 312h-120l263 -493v-324h101v318zM1536 1408v-1536h-1536v1536h1536z" />
-    <glyph glyph-name="_537" unicode="&#xf23c;" horiz-adv-x="2296" 
-d="M478 -139q-8 -16 -27 -34.5t-37 -25.5q-25 -9 -51.5 3.5t-28.5 31.5q-1 22 40 55t68 38q23 4 34 -21.5t2 -46.5zM1819 -139q7 -16 26 -34.5t38 -25.5q25 -9 51.5 3.5t27.5 31.5q2 22 -39.5 55t-68.5 38q-22 4 -33 -21.5t-2 -46.5zM1867 -30q13 -27 56.5 -59.5t77.5 -41.5
-q45 -13 82 4.5t37 50.5q0 46 -67.5 100.5t-115.5 59.5q-40 5 -63.5 -37.5t-6.5 -76.5zM428 -30q-13 -27 -56 -59.5t-77 -41.5q-45 -13 -82 4.5t-37 50.5q0 46 67.5 100.5t115.5 59.5q40 5 63 -37.5t6 -76.5zM1158 1094h1q-41 0 -76 -15q27 -8 44 -30.5t17 -49.5
-q0 -35 -27 -60t-65 -25q-52 0 -80 43q-5 -23 -5 -42q0 -74 56 -126.5t135 -52.5q80 0 136 52.5t56 126.5t-56 126.5t-136 52.5zM1462 1312q-99 109 -220.5 131.5t-245.5 -44.5q27 60 82.5 96.5t118 39.5t121.5 -17t99.5 -74.5t44.5 -131.5zM2212 73q8 -11 -11 -42
-q7 -23 7 -40q1 -56 -44.5 -112.5t-109.5 -91.5t-118 -37q-48 -2 -92 21.5t-66 65.5q-687 -25 -1259 0q-23 -41 -66.5 -65t-92.5 -22q-86 3 -179.5 80.5t-92.5 160.5q2 22 7 40q-19 31 -11 42q6 10 31 1q14 22 41 51q-7 29 2 38q11 10 39 -4q29 20 59 34q0 29 13 37
-q23 12 51 -16q35 5 61 -2q18 -4 38 -19v73q-11 0 -18 2q-53 10 -97 44.5t-55 87.5q-9 38 0 81q15 62 93 95q2 17 19 35.5t36 23.5t33 -7.5t19 -30.5h13q46 -5 60 -23q3 -3 5 -7q10 1 30.5 3.5t30.5 3.5q-15 11 -30 17q-23 40 -91 43q0 6 1 10q-62 2 -118.5 18.5t-84.5 47.5
-q-32 36 -42.5 92t-2.5 112q16 126 90 179q23 16 52 4.5t32 -40.5q0 -1 1.5 -14t2.5 -21t3 -20t5.5 -19t8.5 -10q27 -14 76 -12q48 46 98 74q-40 4 -162 -14l47 46q61 58 163 111q145 73 282 86q-20 8 -41 15.5t-47 14t-42.5 10.5t-47.5 11t-43 10q595 126 904 -139
-q98 -84 158 -222q85 -10 121 9h1q5 3 8.5 10t5.5 19t3 19.5t3 21.5l1 14q3 28 32 40t52 -5q73 -52 91 -178q7 -57 -3.5 -113t-42.5 -91q-28 -32 -83.5 -48.5t-115.5 -18.5v-10q-71 -2 -95 -43q-14 -5 -31 -17q11 -1 32 -3.5t30 -3.5q1 5 5 8q16 18 60 23h13q5 18 19 30t33 8
-t36 -23t19 -36q79 -32 93 -95q9 -40 1 -81q-12 -53 -56 -88t-97 -44q-10 -2 -17 -2q0 -49 -1 -73q20 15 38 19q26 7 61 2q28 28 51 16q14 -9 14 -37q33 -16 59 -34q27 13 38 4q10 -10 2 -38q28 -30 41 -51q23 8 31 -1zM1937 1025q0 -29 -9 -54q82 -32 112 -132
-q4 37 -9.5 98.5t-41.5 90.5q-20 19 -36 17t-16 -20zM1859 925q35 -42 47.5 -108.5t-0.5 -124.5q67 13 97 45q13 14 18 28q-3 64 -31 114.5t-79 66.5q-15 -15 -52 -21zM1822 921q-30 0 -44 1q42 -115 53 -239q21 0 43 3q16 68 1 135t-53 100zM258 839q30 100 112 132
-q-9 25 -9 54q0 18 -16.5 20t-35.5 -17q-28 -29 -41.5 -90.5t-9.5 -98.5zM294 737q29 -31 97 -45q-13 58 -0.5 124.5t47.5 108.5v0q-37 6 -52 21q-51 -16 -78.5 -66t-31.5 -115q9 -17 18 -28zM471 683q14 124 73 235q-19 -4 -55 -18l-45 -19v1q-46 -89 -20 -196q25 -3 47 -3z
-M1434 644q8 -38 16.5 -108.5t11.5 -89.5q3 -18 9.5 -21.5t23.5 4.5q40 20 62 85.5t23 125.5q-24 2 -146 4zM1152 1285q-116 0 -199 -82.5t-83 -198.5q0 -117 83 -199.5t199 -82.5t199 82.5t83 199.5q0 116 -83 198.5t-199 82.5zM1380 646q-105 2 -211 0v1q-1 -27 2.5 -86
-t13.5 -66q29 -14 93.5 -14.5t95.5 10.5q9 3 11 39t-0.5 69.5t-4.5 46.5zM1112 447q8 4 9.5 48t-0.5 88t-4 63v1q-212 -3 -214 -3q-4 -20 -7 -62t0 -83t14 -46q34 -15 101 -16t101 10zM718 636q-16 -59 4.5 -118.5t77.5 -84.5q15 -8 24 -5t12 21q3 16 8 90t10 103
-q-69 -2 -136 -6zM591 510q3 -23 -34 -36q132 -141 271.5 -240t305.5 -154q172 49 310.5 146t293.5 250q-33 13 -30 34q0 2 0.5 3.5t1.5 3t1 2.5v1v-1q-17 2 -50 5.5t-48 4.5q-26 -90 -82 -132q-51 -38 -82 1q-5 6 -9 14q-7 13 -17 62q-2 -5 -5 -9t-7.5 -7t-8 -5.5t-9.5 -4
-l-10 -2.5t-12 -2l-12 -1.5t-13.5 -1t-13.5 -0.5q-106 -9 -163 11q-4 -17 -10 -26.5t-21 -15t-23 -7t-36 -3.5q-6 -1 -9 -1q-179 -17 -203 40q-2 -63 -56 -54q-47 8 -91 54q-12 13 -20 26q-17 29 -26 65q-58 -6 -87 -10q1 -2 4 -10zM507 -118q3 14 3 30q-17 71 -51 130
-t-73 70q-41 12 -101.5 -14.5t-104.5 -80t-39 -107.5q35 -53 100 -93t119 -42q51 -2 94 28t53 79zM510 53q23 -63 27 -119q195 113 392 174q-98 52 -180.5 120t-179.5 165q-6 -4 -29 -13q0 -1 -1 -4t-1 -5q31 -18 22 -37q-12 -23 -56 -34q-10 -13 -29 -24h-1q-2 -83 1 -150
-q19 -34 35 -73zM579 -113q532 -21 1145 0q-254 147 -428 196q-76 -35 -156 -57q-8 -3 -16 0q-65 21 -129 49q-208 -60 -416 -188h-1v-1q1 0 1 1zM1763 -67q4 54 28 120q14 38 33 71l-1 -1q3 77 3 153q-15 8 -30 25q-42 9 -56 33q-9 20 22 38q-2 4 -2 9q-16 4 -28 12
-q-204 -190 -383 -284q198 -59 414 -176zM2155 -90q5 54 -39 107.5t-104 80t-102 14.5q-38 -11 -72.5 -70.5t-51.5 -129.5q0 -16 3 -30q10 -49 53 -79t94 -28q54 2 119 42t100 93z" />
-    <glyph glyph-name="_538" unicode="&#xf23d;" horiz-adv-x="2304" 
-d="M1524 -25q0 -68 -48 -116t-116 -48t-116.5 48t-48.5 116t48.5 116.5t116.5 48.5t116 -48.5t48 -116.5zM775 -25q0 -68 -48.5 -116t-116.5 -48t-116 48t-48 116t48 116.5t116 48.5t116.5 -48.5t48.5 -116.5zM0 1469q57 -60 110.5 -104.5t121 -82t136 -63t166 -45.5
-t200 -31.5t250 -18.5t304 -9.5t372.5 -2.5q139 0 244.5 -5t181 -16.5t124 -27.5t71 -39.5t24 -51.5t-19.5 -64t-56.5 -76.5t-89.5 -91t-116 -104.5t-139 -119q-185 -157 -286 -247q29 51 76.5 109t94 105.5t94.5 98.5t83 91.5t54 80.5t13 70t-45.5 55.5t-116.5 41t-204 23.5
-t-304 5q-168 -2 -314 6t-256 23t-204.5 41t-159.5 51.5t-122.5 62.5t-91.5 66.5t-68 71.5t-50.5 69.5t-40 68t-36.5 59.5z" />
-    <glyph glyph-name="_539" unicode="&#xf23e;" horiz-adv-x="1792" 
-d="M896 1472q-169 0 -323 -66t-265.5 -177.5t-177.5 -265.5t-66 -323t66 -323t177.5 -265.5t265.5 -177.5t323 -66t323 66t265.5 177.5t177.5 265.5t66 323t-66 323t-177.5 265.5t-265.5 177.5t-323 66zM896 1536q182 0 348 -71t286 -191t191 -286t71 -348t-71 -348
-t-191 -286t-286 -191t-348 -71t-348 71t-286 191t-191 286t-71 348t71 348t191 286t286 191t348 71zM496 704q16 0 16 -16v-480q0 -16 -16 -16h-32q-16 0 -16 16v480q0 16 16 16h32zM896 640q53 0 90.5 -37.5t37.5 -90.5q0 -35 -17.5 -64t-46.5 -46v-114q0 -14 -9 -23
-t-23 -9h-64q-14 0 -23 9t-9 23v114q-29 17 -46.5 46t-17.5 64q0 53 37.5 90.5t90.5 37.5zM896 1408q209 0 385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103zM544 928v-96
-q0 -14 9 -23t23 -9h64q14 0 23 9t9 23v96q0 93 65.5 158.5t158.5 65.5t158.5 -65.5t65.5 -158.5v-96q0 -14 9 -23t23 -9h64q14 0 23 9t9 23v96q0 146 -103 249t-249 103t-249 -103t-103 -249zM1408 192v512q0 26 -19 45t-45 19h-896q-26 0 -45 -19t-19 -45v-512
-q0 -26 19 -45t45 -19h896q26 0 45 19t19 45z" />
-    <glyph glyph-name="_540" unicode="&#xf240;" horiz-adv-x="2304" 
-d="M1920 1024v-768h-1664v768h1664zM2048 448h128v384h-128v288q0 14 -9 23t-23 9h-1856q-14 0 -23 -9t-9 -23v-960q0 -14 9 -23t23 -9h1856q14 0 23 9t9 23v288zM2304 832v-384q0 -53 -37.5 -90.5t-90.5 -37.5v-160q0 -66 -47 -113t-113 -47h-1856q-66 0 -113 47t-47 113
-v960q0 66 47 113t113 47h1856q66 0 113 -47t47 -113v-160q53 0 90.5 -37.5t37.5 -90.5z" />
-    <glyph glyph-name="_541" unicode="&#xf241;" horiz-adv-x="2304" 
-d="M256 256v768h1280v-768h-1280zM2176 960q53 0 90.5 -37.5t37.5 -90.5v-384q0 -53 -37.5 -90.5t-90.5 -37.5v-160q0 -66 -47 -113t-113 -47h-1856q-66 0 -113 47t-47 113v960q0 66 47 113t113 47h1856q66 0 113 -47t47 -113v-160zM2176 448v384h-128v288q0 14 -9 23t-23 9
-h-1856q-14 0 -23 -9t-9 -23v-960q0 -14 9 -23t23 -9h1856q14 0 23 9t9 23v288h128z" />
-    <glyph glyph-name="_542" unicode="&#xf242;" horiz-adv-x="2304" 
-d="M256 256v768h896v-768h-896zM2176 960q53 0 90.5 -37.5t37.5 -90.5v-384q0 -53 -37.5 -90.5t-90.5 -37.5v-160q0 -66 -47 -113t-113 -47h-1856q-66 0 -113 47t-47 113v960q0 66 47 113t113 47h1856q66 0 113 -47t47 -113v-160zM2176 448v384h-128v288q0 14 -9 23t-23 9
-h-1856q-14 0 -23 -9t-9 -23v-960q0 -14 9 -23t23 -9h1856q14 0 23 9t9 23v288h128z" />
-    <glyph glyph-name="_543" unicode="&#xf243;" horiz-adv-x="2304" 
-d="M256 256v768h512v-768h-512zM2176 960q53 0 90.5 -37.5t37.5 -90.5v-384q0 -53 -37.5 -90.5t-90.5 -37.5v-160q0 -66 -47 -113t-113 -47h-1856q-66 0 -113 47t-47 113v960q0 66 47 113t113 47h1856q66 0 113 -47t47 -113v-160zM2176 448v384h-128v288q0 14 -9 23t-23 9
-h-1856q-14 0 -23 -9t-9 -23v-960q0 -14 9 -23t23 -9h1856q14 0 23 9t9 23v288h128z" />
-    <glyph glyph-name="_544" unicode="&#xf244;" horiz-adv-x="2304" 
-d="M2176 960q53 0 90.5 -37.5t37.5 -90.5v-384q0 -53 -37.5 -90.5t-90.5 -37.5v-160q0 -66 -47 -113t-113 -47h-1856q-66 0 -113 47t-47 113v960q0 66 47 113t113 47h1856q66 0 113 -47t47 -113v-160zM2176 448v384h-128v288q0 14 -9 23t-23 9h-1856q-14 0 -23 -9t-9 -23
-v-960q0 -14 9 -23t23 -9h1856q14 0 23 9t9 23v288h128z" />
-    <glyph glyph-name="_545" unicode="&#xf245;" horiz-adv-x="1280" 
-d="M1133 493q31 -30 14 -69q-17 -40 -59 -40h-382l201 -476q10 -25 0 -49t-34 -35l-177 -75q-25 -10 -49 0t-35 34l-191 452l-312 -312q-19 -19 -45 -19q-12 0 -24 5q-40 17 -40 59v1504q0 42 40 59q12 5 24 5q27 0 45 -19z" />
-    <glyph glyph-name="_546" unicode="&#xf246;" horiz-adv-x="1024" 
-d="M832 1408q-320 0 -320 -224v-416h128v-128h-128v-544q0 -224 320 -224h64v-128h-64q-272 0 -384 146q-112 -146 -384 -146h-64v128h64q320 0 320 224v544h-128v128h128v416q0 224 -320 224h-64v128h64q272 0 384 -146q112 146 384 146h64v-128h-64z" />
-    <glyph glyph-name="_547" unicode="&#xf247;" horiz-adv-x="2048" 
-d="M2048 1152h-128v-1024h128v-384h-384v128h-1280v-128h-384v384h128v1024h-128v384h384v-128h1280v128h384v-384zM1792 1408v-128h128v128h-128zM128 1408v-128h128v128h-128zM256 -128v128h-128v-128h128zM1664 0v128h128v1024h-128v128h-1280v-128h-128v-1024h128v-128
-h1280zM1920 -128v128h-128v-128h128zM1280 896h384v-768h-896v256h-384v768h896v-256zM512 512h640v512h-640v-512zM1536 256v512h-256v-384h-384v-128h640z" />
-    <glyph glyph-name="_548" unicode="&#xf248;" horiz-adv-x="2304" 
-d="M2304 768h-128v-640h128v-384h-384v128h-896v-128h-384v384h128v128h-384v-128h-384v384h128v640h-128v384h384v-128h896v128h384v-384h-128v-128h384v128h384v-384zM2048 1024v-128h128v128h-128zM1408 1408v-128h128v128h-128zM128 1408v-128h128v128h-128zM256 256
-v128h-128v-128h128zM1536 384h-128v-128h128v128zM384 384h896v128h128v640h-128v128h-896v-128h-128v-640h128v-128zM896 -128v128h-128v-128h128zM2176 -128v128h-128v-128h128zM2048 128v640h-128v128h-384v-384h128v-384h-384v128h-384v-128h128v-128h896v128h128z" />
-    <glyph glyph-name="_549" unicode="&#xf249;" 
-d="M1024 288v-416h-928q-40 0 -68 28t-28 68v1344q0 40 28 68t68 28h1344q40 0 68 -28t28 -68v-928h-416q-40 0 -68 -28t-28 -68zM1152 256h381q-15 -82 -65 -132l-184 -184q-50 -50 -132 -65v381z" />
-    <glyph glyph-name="_550" unicode="&#xf24a;" 
-d="M1400 256h-248v-248q29 10 41 22l185 185q12 12 22 41zM1120 384h288v896h-1280v-1280h896v288q0 40 28 68t68 28zM1536 1312v-1024q0 -40 -20 -88t-48 -76l-184 -184q-28 -28 -76 -48t-88 -20h-1024q-40 0 -68 28t-28 68v1344q0 40 28 68t68 28h1344q40 0 68 -28t28 -68
-z" />
-    <glyph glyph-name="_551" unicode="&#xf24b;" horiz-adv-x="2304" 
-d="M1951 538q0 -26 -15.5 -44.5t-38.5 -23.5q-8 -2 -18 -2h-153v140h153q10 0 18 -2q23 -5 38.5 -23.5t15.5 -44.5zM1933 751q0 -25 -15 -42t-38 -21q-3 -1 -15 -1h-139v129h139q3 0 8.5 -0.5t6.5 -0.5q23 -4 38 -21.5t15 -42.5zM728 587v308h-228v-308q0 -58 -38 -94.5
-t-105 -36.5q-108 0 -229 59v-112q53 -15 121 -23t109 -9l42 -1q328 0 328 217zM1442 403v113q-99 -52 -200 -59q-108 -8 -169 41t-61 142t61 142t169 41q101 -7 200 -58v112q-48 12 -100 19.5t-80 9.5l-28 2q-127 6 -218.5 -14t-140.5 -60t-71 -88t-22 -106t22 -106t71 -88
-t140.5 -60t218.5 -14q101 4 208 31zM2176 518q0 54 -43 88.5t-109 39.5v3q57 8 89 41.5t32 79.5q0 55 -41 88t-107 36q-3 0 -12 0.5t-14 0.5h-455v-510h491q74 0 121.5 36.5t47.5 96.5zM2304 1280v-1280q0 -52 -38 -90t-90 -38h-2048q-52 0 -90 38t-38 90v1280q0 52 38 90
-t90 38h2048q52 0 90 -38t38 -90z" />
-    <glyph glyph-name="_552" unicode="&#xf24c;" horiz-adv-x="2304" 
-d="M858 295v693q-106 -41 -172 -135.5t-66 -211.5t66 -211.5t172 -134.5zM1362 641q0 117 -66 211.5t-172 135.5v-694q106 41 172 135.5t66 211.5zM1577 641q0 -159 -78.5 -294t-213.5 -213.5t-294 -78.5q-119 0 -227.5 46.5t-187 125t-125 187t-46.5 227.5q0 159 78.5 294
-t213.5 213.5t294 78.5t294 -78.5t213.5 -213.5t78.5 -294zM1960 634q0 139 -55.5 261.5t-147.5 205.5t-213.5 131t-252.5 48h-301q-176 0 -323.5 -81t-235 -230t-87.5 -335q0 -171 87 -317.5t236 -231.5t323 -85h301q129 0 251.5 50.5t214.5 135t147.5 202.5t55.5 246z
-M2304 1280v-1280q0 -52 -38 -90t-90 -38h-2048q-52 0 -90 38t-38 90v1280q0 52 38 90t90 38h2048q52 0 90 -38t38 -90z" />
-    <glyph glyph-name="_553" unicode="&#xf24d;" horiz-adv-x="1792" 
-d="M1664 -96v1088q0 13 -9.5 22.5t-22.5 9.5h-1088q-13 0 -22.5 -9.5t-9.5 -22.5v-1088q0 -13 9.5 -22.5t22.5 -9.5h1088q13 0 22.5 9.5t9.5 22.5zM1792 992v-1088q0 -66 -47 -113t-113 -47h-1088q-66 0 -113 47t-47 113v1088q0 66 47 113t113 47h1088q66 0 113 -47t47 -113
-zM1408 1376v-160h-128v160q0 13 -9.5 22.5t-22.5 9.5h-1088q-13 0 -22.5 -9.5t-9.5 -22.5v-1088q0 -13 9.5 -22.5t22.5 -9.5h160v-128h-160q-66 0 -113 47t-47 113v1088q0 66 47 113t113 47h1088q66 0 113 -47t47 -113z" />
-    <glyph glyph-name="_554" unicode="&#xf24e;" horiz-adv-x="2304" 
-d="M1728 1088l-384 -704h768zM448 1088l-384 -704h768zM1269 1280q-14 -40 -45.5 -71.5t-71.5 -45.5v-1291h608q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-1344q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h608v1291q-40 14 -71.5 45.5t-45.5 71.5h-491q-14 0 -23 9t-9 23v64
-q0 14 9 23t23 9h491q21 57 70 92.5t111 35.5t111 -35.5t70 -92.5h491q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-491zM1088 1264q33 0 56.5 23.5t23.5 56.5t-23.5 56.5t-56.5 23.5t-56.5 -23.5t-23.5 -56.5t23.5 -56.5t56.5 -23.5zM2176 384q0 -73 -46.5 -131t-117.5 -91
-t-144.5 -49.5t-139.5 -16.5t-139.5 16.5t-144.5 49.5t-117.5 91t-46.5 131q0 11 35 81t92 174.5t107 195.5t102 184t56 100q18 33 56 33t56 -33q4 -7 56 -100t102 -184t107 -195.5t92 -174.5t35 -81zM896 384q0 -73 -46.5 -131t-117.5 -91t-144.5 -49.5t-139.5 -16.5
-t-139.5 16.5t-144.5 49.5t-117.5 91t-46.5 131q0 11 35 81t92 174.5t107 195.5t102 184t56 100q18 33 56 33t56 -33q4 -7 56 -100t102 -184t107 -195.5t92 -174.5t35 -81z" />
-    <glyph glyph-name="_555" unicode="&#xf250;" 
-d="M1408 1408q0 -261 -106.5 -461.5t-266.5 -306.5q160 -106 266.5 -306.5t106.5 -461.5h96q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-1472q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h96q0 261 106.5 461.5t266.5 306.5q-160 106 -266.5 306.5t-106.5 461.5h-96q-14 0 -23 9
-t-9 23v64q0 14 9 23t23 9h1472q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-96zM874 700q77 29 149 92.5t129.5 152.5t92.5 210t35 253h-1024q0 -132 35 -253t92.5 -210t129.5 -152.5t149 -92.5q19 -7 30.5 -23.5t11.5 -36.5t-11.5 -36.5t-30.5 -23.5q-77 -29 -149 -92.5
-t-129.5 -152.5t-92.5 -210t-35 -253h1024q0 132 -35 253t-92.5 210t-129.5 152.5t-149 92.5q-19 7 -30.5 23.5t-11.5 36.5t11.5 36.5t30.5 23.5z" />
-    <glyph glyph-name="_556" unicode="&#xf251;" 
-d="M1408 1408q0 -261 -106.5 -461.5t-266.5 -306.5q160 -106 266.5 -306.5t106.5 -461.5h96q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-1472q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h96q0 261 106.5 461.5t266.5 306.5q-160 106 -266.5 306.5t-106.5 461.5h-96q-14 0 -23 9
-t-9 23v64q0 14 9 23t23 9h1472q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-96zM1280 1408h-1024q0 -66 9 -128h1006q9 61 9 128zM1280 -128q0 130 -34 249.5t-90.5 208t-126.5 152t-146 94.5h-230q-76 -31 -146 -94.5t-126.5 -152t-90.5 -208t-34 -249.5h1024z" />
-    <glyph glyph-name="_557" unicode="&#xf252;" 
-d="M1408 1408q0 -261 -106.5 -461.5t-266.5 -306.5q160 -106 266.5 -306.5t106.5 -461.5h96q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-1472q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h96q0 261 106.5 461.5t266.5 306.5q-160 106 -266.5 306.5t-106.5 461.5h-96q-14 0 -23 9
-t-9 23v64q0 14 9 23t23 9h1472q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-96zM1280 1408h-1024q0 -206 85 -384h854q85 178 85 384zM1223 192q-54 141 -145.5 241.5t-194.5 142.5h-230q-103 -42 -194.5 -142.5t-145.5 -241.5h910z" />
-    <glyph glyph-name="_558" unicode="&#xf253;" 
-d="M1408 1408q0 -261 -106.5 -461.5t-266.5 -306.5q160 -106 266.5 -306.5t106.5 -461.5h96q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-1472q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h96q0 261 106.5 461.5t266.5 306.5q-160 106 -266.5 306.5t-106.5 461.5h-96q-14 0 -23 9
-t-9 23v64q0 14 9 23t23 9h1472q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-96zM874 700q77 29 149 92.5t129.5 152.5t92.5 210t35 253h-1024q0 -132 35 -253t92.5 -210t129.5 -152.5t149 -92.5q19 -7 30.5 -23.5t11.5 -36.5t-11.5 -36.5t-30.5 -23.5q-137 -51 -244 -196
-h700q-107 145 -244 196q-19 7 -30.5 23.5t-11.5 36.5t11.5 36.5t30.5 23.5z" />
-    <glyph glyph-name="_559" unicode="&#xf254;" 
-d="M1504 -64q14 0 23 -9t9 -23v-128q0 -14 -9 -23t-23 -9h-1472q-14 0 -23 9t-9 23v128q0 14 9 23t23 9h1472zM130 0q3 55 16 107t30 95t46 87t53.5 76t64.5 69.5t66 60t70.5 55t66.5 47.5t65 43q-43 28 -65 43t-66.5 47.5t-70.5 55t-66 60t-64.5 69.5t-53.5 76t-46 87
-t-30 95t-16 107h1276q-3 -55 -16 -107t-30 -95t-46 -87t-53.5 -76t-64.5 -69.5t-66 -60t-70.5 -55t-66.5 -47.5t-65 -43q43 -28 65 -43t66.5 -47.5t70.5 -55t66 -60t64.5 -69.5t53.5 -76t46 -87t30 -95t16 -107h-1276zM1504 1536q14 0 23 -9t9 -23v-128q0 -14 -9 -23t-23 -9
-h-1472q-14 0 -23 9t-9 23v128q0 14 9 23t23 9h1472z" />
-    <glyph glyph-name="_560" unicode="&#xf255;" 
-d="M768 1152q-53 0 -90.5 -37.5t-37.5 -90.5v-128h-32v93q0 48 -32 81.5t-80 33.5q-46 0 -79 -33t-33 -79v-429l-32 30v172q0 48 -32 81.5t-80 33.5q-46 0 -79 -33t-33 -79v-224q0 -47 35 -82l310 -296q39 -39 39 -102q0 -26 19 -45t45 -19h640q26 0 45 19t19 45v25
-q0 41 10 77l108 436q10 36 10 77v246q0 48 -32 81.5t-80 33.5q-46 0 -79 -33t-33 -79v-32h-32v125q0 40 -25 72.5t-64 40.5q-14 2 -23 2q-46 0 -79 -33t-33 -79v-128h-32v122q0 51 -32.5 89.5t-82.5 43.5q-5 1 -13 1zM768 1280q84 0 149 -50q57 34 123 34q59 0 111 -27
-t86 -76q27 7 59 7q100 0 170 -71.5t70 -171.5v-246q0 -51 -13 -108l-109 -436q-6 -24 -6 -71q0 -80 -56 -136t-136 -56h-640q-84 0 -138 58.5t-54 142.5l-308 296q-76 73 -76 175v224q0 99 70.5 169.5t169.5 70.5q11 0 16 -1q6 95 75.5 160t164.5 65q52 0 98 -21
-q72 69 174 69z" />
-    <glyph glyph-name="_561" unicode="&#xf256;" horiz-adv-x="1792" 
-d="M880 1408q-46 0 -79 -33t-33 -79v-656h-32v528q0 46 -33 79t-79 33t-79 -33t-33 -79v-528v-256l-154 205q-38 51 -102 51q-53 0 -90.5 -37.5t-37.5 -90.5q0 -43 26 -77l384 -512q38 -51 102 -51h688q34 0 61 22t34 56l76 405q5 32 5 59v498q0 46 -33 79t-79 33t-79 -33
-t-33 -79v-272h-32v528q0 46 -33 79t-79 33t-79 -33t-33 -79v-528h-32v656q0 46 -33 79t-79 33zM880 1536q68 0 125.5 -35.5t88.5 -96.5q19 4 42 4q99 0 169.5 -70.5t70.5 -169.5v-17q105 6 180.5 -64t75.5 -175v-498q0 -40 -8 -83l-76 -404q-14 -79 -76.5 -131t-143.5 -52
-h-688q-60 0 -114.5 27.5t-90.5 74.5l-384 512q-51 68 -51 154q0 106 75 181t181 75q78 0 128 -34v434q0 99 70.5 169.5t169.5 70.5q23 0 42 -4q31 61 88.5 96.5t125.5 35.5z" />
-    <glyph glyph-name="_562" unicode="&#xf257;" horiz-adv-x="1792" 
-d="M1073 -128h-177q-163 0 -226 141q-23 49 -23 102v5q-62 30 -98.5 88.5t-36.5 127.5q0 38 5 48h-261q-106 0 -181 75t-75 181t75 181t181 75h113l-44 17q-74 28 -119.5 93.5t-45.5 145.5q0 106 75 181t181 75q46 0 91 -17l628 -239h401q106 0 181 -75t75 -181v-668
-q0 -88 -54 -157.5t-140 -90.5l-339 -85q-92 -23 -186 -23zM1024 583l-155 -71l-163 -74q-30 -14 -48 -41.5t-18 -60.5q0 -46 33 -79t79 -33q26 0 46 10l338 154q-49 10 -80.5 50t-31.5 90v55zM1344 272q0 46 -33 79t-79 33q-26 0 -46 -10l-290 -132q-28 -13 -37 -17
-t-30.5 -17t-29.5 -23.5t-16 -29t-8 -40.5q0 -50 31.5 -82t81.5 -32q20 0 38 9l352 160q30 14 48 41.5t18 60.5zM1112 1024l-650 248q-24 8 -46 8q-53 0 -90.5 -37.5t-37.5 -90.5q0 -40 22.5 -73t59.5 -47l526 -200v-64h-640q-53 0 -90.5 -37.5t-37.5 -90.5t37.5 -90.5
-t90.5 -37.5h535l233 106v198q0 63 46 106l111 102h-69zM1073 0q82 0 155 19l339 85q43 11 70 45.5t27 78.5v668q0 53 -37.5 90.5t-90.5 37.5h-308l-136 -126q-36 -33 -36 -82v-296q0 -46 33 -77t79 -31t79 35t33 81v208h32v-208q0 -70 -57 -114q52 -8 86.5 -48.5t34.5 -93.5
-q0 -42 -23 -78t-61 -53l-310 -141h91z" />
-    <glyph glyph-name="_563" unicode="&#xf258;" horiz-adv-x="2048" 
-d="M1151 1536q61 0 116 -28t91 -77l572 -781q118 -159 118 -359v-355q0 -80 -56 -136t-136 -56h-384q-80 0 -136 56t-56 136v177l-286 143h-546q-80 0 -136 56t-56 136v32q0 119 84.5 203.5t203.5 84.5h420l42 128h-686q-100 0 -173.5 67.5t-81.5 166.5q-65 79 -65 182v32
-q0 80 56 136t136 56h959zM1920 -64v355q0 157 -93 284l-573 781q-39 52 -103 52h-959q-26 0 -45 -19t-19 -45q0 -32 1.5 -49.5t9.5 -40.5t25 -43q10 31 35.5 50t56.5 19h832v-32h-832q-26 0 -45 -19t-19 -45q0 -44 3 -58q8 -44 44 -73t81 -29h640h91q40 0 68 -28t28 -68
-q0 -15 -5 -30l-64 -192q-10 -29 -35 -47.5t-56 -18.5h-443q-66 0 -113 -47t-47 -113v-32q0 -26 19 -45t45 -19h561q16 0 29 -7l317 -158q24 -13 38.5 -36t14.5 -50v-197q0 -26 19 -45t45 -19h384q26 0 45 19t19 45z" />
-    <glyph glyph-name="_564" unicode="&#xf259;" horiz-adv-x="2048" 
-d="M459 -256q-77 0 -137.5 47.5t-79.5 122.5l-101 401q-13 57 -13 108q0 45 -5 67l-116 477q-7 27 -7 57q0 93 62 161t155 78q17 85 82.5 139t152.5 54q83 0 148 -51.5t85 -132.5l83 -348l103 428q20 81 85 132.5t148 51.5q89 0 155.5 -57.5t80.5 -144.5q92 -10 152 -79
-t60 -162q0 -24 -7 -59l-123 -512q10 7 37.5 28.5t38.5 29.5t35 23t41 20.5t41.5 11t49.5 5.5q105 0 180 -74t75 -179q0 -62 -28.5 -118t-78.5 -94l-507 -380q-68 -51 -153 -51h-694zM1104 1408q-38 0 -68.5 -24t-39.5 -62l-164 -682h-127l-145 602q-9 38 -39.5 62t-68.5 24
-q-48 0 -80 -33t-32 -80q0 -15 3 -28l132 -547h-26l-99 408q-9 37 -40 62.5t-69 25.5q-47 0 -80 -33t-33 -79q0 -14 3 -26l116 -478q7 -28 9 -86t10 -88l100 -401q8 -32 34 -52.5t59 -20.5h694q42 0 76 26l507 379q56 43 56 110q0 52 -37.5 88.5t-89.5 36.5q-43 0 -77 -26
-l-307 -230v227q0 4 32 138t68 282t39 161q4 18 4 29q0 47 -32 81t-79 34q-39 0 -69.5 -24t-39.5 -62l-116 -482h-26l150 624q3 14 3 28q0 48 -31.5 82t-79.5 34z" />
-    <glyph glyph-name="_565" unicode="&#xf25a;" horiz-adv-x="1792" 
-d="M640 1408q-53 0 -90.5 -37.5t-37.5 -90.5v-512v-384l-151 202q-41 54 -107 54q-52 0 -89 -38t-37 -90q0 -43 26 -77l384 -512q38 -51 102 -51h718q22 0 39.5 13.5t22.5 34.5l92 368q24 96 24 194v217q0 41 -28 71t-68 30t-68 -28t-28 -68h-32v61q0 48 -32 81.5t-80 33.5
-q-46 0 -79 -33t-33 -79v-64h-32v90q0 55 -37 94.5t-91 39.5q-53 0 -90.5 -37.5t-37.5 -90.5v-96h-32v570q0 55 -37 94.5t-91 39.5zM640 1536q107 0 181.5 -77.5t74.5 -184.5v-220q22 2 32 2q99 0 173 -69q47 21 99 21q113 0 184 -87q27 7 56 7q94 0 159 -67.5t65 -161.5
-v-217q0 -116 -28 -225l-92 -368q-16 -64 -68 -104.5t-118 -40.5h-718q-60 0 -114.5 27.5t-90.5 74.5l-384 512q-51 68 -51 154q0 105 74.5 180.5t179.5 75.5q71 0 130 -35v547q0 106 75 181t181 75zM768 128v384h-32v-384h32zM1024 128v384h-32v-384h32zM1280 128v384h-32
-v-384h32z" />
-    <glyph glyph-name="_566" unicode="&#xf25b;" 
-d="M1288 889q60 0 107 -23q141 -63 141 -226v-177q0 -94 -23 -186l-85 -339q-21 -86 -90.5 -140t-157.5 -54h-668q-106 0 -181 75t-75 181v401l-239 628q-17 45 -17 91q0 106 75 181t181 75q80 0 145.5 -45.5t93.5 -119.5l17 -44v113q0 106 75 181t181 75t181 -75t75 -181
-v-261q27 5 48 5q69 0 127.5 -36.5t88.5 -98.5zM1072 896q-33 0 -60.5 -18t-41.5 -48l-74 -163l-71 -155h55q50 0 90 -31.5t50 -80.5l154 338q10 20 10 46q0 46 -33 79t-79 33zM1293 761q-22 0 -40.5 -8t-29 -16t-23.5 -29.5t-17 -30.5t-17 -37l-132 -290q-10 -20 -10 -46
-q0 -46 33 -79t79 -33q33 0 60.5 18t41.5 48l160 352q9 18 9 38q0 50 -32 81.5t-82 31.5zM128 1120q0 -22 8 -46l248 -650v-69l102 111q43 46 106 46h198l106 233v535q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5v-640h-64l-200 526q-14 37 -47 59.5t-73 22.5
-q-53 0 -90.5 -37.5t-37.5 -90.5zM1180 -128q44 0 78.5 27t45.5 70l85 339q19 73 19 155v91l-141 -310q-17 -38 -53 -61t-78 -23q-53 0 -93.5 34.5t-48.5 86.5q-44 -57 -114 -57h-208v32h208q46 0 81 33t35 79t-31 79t-77 33h-296q-49 0 -82 -36l-126 -136v-308
-q0 -53 37.5 -90.5t90.5 -37.5h668z" />
-    <glyph glyph-name="_567" unicode="&#xf25c;" horiz-adv-x="1973" 
-d="M857 992v-117q0 -13 -9.5 -22t-22.5 -9h-298v-812q0 -13 -9 -22.5t-22 -9.5h-135q-13 0 -22.5 9t-9.5 23v812h-297q-13 0 -22.5 9t-9.5 22v117q0 14 9 23t23 9h793q13 0 22.5 -9.5t9.5 -22.5zM1895 995l77 -961q1 -13 -8 -24q-10 -10 -23 -10h-134q-12 0 -21 8.5
-t-10 20.5l-46 588l-189 -425q-8 -19 -29 -19h-120q-20 0 -29 19l-188 427l-45 -590q-1 -12 -10 -20.5t-21 -8.5h-135q-13 0 -23 10q-9 10 -9 24l78 961q1 12 10 20.5t21 8.5h142q20 0 29 -19l220 -520q10 -24 20 -51q3 7 9.5 24.5t10.5 26.5l221 520q9 19 29 19h141
-q13 0 22 -8.5t10 -20.5z" />
-    <glyph glyph-name="_568" unicode="&#xf25d;" horiz-adv-x="1792" 
-d="M1042 833q0 88 -60 121q-33 18 -117 18h-123v-281h162q66 0 102 37t36 105zM1094 548l205 -373q8 -17 -1 -31q-8 -16 -27 -16h-152q-20 0 -28 17l-194 365h-155v-350q0 -14 -9 -23t-23 -9h-134q-14 0 -23 9t-9 23v960q0 14 9 23t23 9h294q128 0 190 -24q85 -31 134 -109
-t49 -180q0 -92 -42.5 -165.5t-115.5 -109.5q6 -10 9 -16zM896 1376q-150 0 -286 -58.5t-234.5 -157t-157 -234.5t-58.5 -286t58.5 -286t157 -234.5t234.5 -157t286 -58.5t286 58.5t234.5 157t157 234.5t58.5 286t-58.5 286t-157 234.5t-234.5 157t-286 58.5zM1792 640
-q0 -182 -71 -348t-191 -286t-286 -191t-348 -71t-348 71t-286 191t-191 286t-71 348t71 348t191 286t286 191t348 71t348 -71t286 -191t191 -286t71 -348z" />
-    <glyph glyph-name="_569" unicode="&#xf25e;" horiz-adv-x="1792" 
-d="M605 303q153 0 257 104q14 18 3 36l-45 82q-6 13 -24 17q-16 2 -27 -11l-4 -3q-4 -4 -11.5 -10t-17.5 -13.5t-23.5 -14.5t-28.5 -13t-33.5 -9.5t-37.5 -3.5q-76 0 -125 50t-49 127q0 76 48 125.5t122 49.5q37 0 71.5 -14t50.5 -28l16 -14q11 -11 26 -10q16 2 24 14l53 78
-q13 20 -2 39q-3 4 -11 12t-30 23.5t-48.5 28t-67.5 22.5t-86 10q-148 0 -246 -96.5t-98 -240.5q0 -146 97 -241.5t247 -95.5zM1235 303q153 0 257 104q14 18 4 36l-45 82q-8 14 -25 17q-16 2 -27 -11l-4 -3q-4 -4 -11.5 -10t-17.5 -13.5t-23.5 -14.5t-28.5 -13t-33.5 -9.5
-t-37.5 -3.5q-76 0 -125 50t-49 127q0 76 48 125.5t122 49.5q37 0 71.5 -14t50.5 -28l16 -14q11 -11 26 -10q16 2 24 14l53 78q13 20 -2 39q-3 4 -11 12t-30 23.5t-48.5 28t-67.5 22.5t-86 10q-147 0 -245.5 -96.5t-98.5 -240.5q0 -146 97 -241.5t247 -95.5zM896 1376
-q-150 0 -286 -58.5t-234.5 -157t-157 -234.5t-58.5 -286t58.5 -286t157 -234.5t234.5 -157t286 -58.5t286 58.5t234.5 157t157 234.5t58.5 286t-58.5 286t-157 234.5t-234.5 157t-286 58.5zM896 1536q182 0 348 -71t286 -191t191 -286t71 -348t-71 -348t-191 -286t-286 -191
-t-348 -71t-348 71t-286 191t-191 286t-71 348t71 348t191 286t286 191t348 71z" />
-    <glyph glyph-name="f260" unicode="&#xf260;" horiz-adv-x="2048" 
-d="M736 736l384 -384l-384 -384l-672 672l672 672l168 -168l-96 -96l-72 72l-480 -480l480 -480l193 193l-289 287zM1312 1312l672 -672l-672 -672l-168 168l96 96l72 -72l480 480l-480 480l-193 -193l289 -287l-96 -96l-384 384z" />
-    <glyph glyph-name="f261" unicode="&#xf261;" horiz-adv-x="1792" 
-d="M717 182l271 271l-279 279l-88 -88l192 -191l-96 -96l-279 279l279 279l40 -40l87 87l-127 128l-454 -454zM1075 190l454 454l-454 454l-271 -271l279 -279l88 88l-192 191l96 96l279 -279l-279 -279l-40 40l-87 -88zM1792 640q0 -182 -71 -348t-191 -286t-286 -191
-t-348 -71t-348 71t-286 191t-191 286t-71 348t71 348t191 286t286 191t348 71t348 -71t286 -191t191 -286t71 -348z" />
-    <glyph glyph-name="_572" unicode="&#xf262;" horiz-adv-x="2304" 
-d="M651 539q0 -39 -27.5 -66.5t-65.5 -27.5q-39 0 -66.5 27.5t-27.5 66.5q0 38 27.5 65.5t66.5 27.5q38 0 65.5 -27.5t27.5 -65.5zM1805 540q0 -39 -27.5 -66.5t-66.5 -27.5t-66.5 27.5t-27.5 66.5t27.5 66t66.5 27t66.5 -27t27.5 -66zM765 539q0 79 -56.5 136t-136.5 57
-t-136.5 -56.5t-56.5 -136.5t56.5 -136.5t136.5 -56.5t136.5 56.5t56.5 136.5zM1918 540q0 80 -56.5 136.5t-136.5 56.5q-79 0 -136 -56.5t-57 -136.5t56.5 -136.5t136.5 -56.5t136.5 56.5t56.5 136.5zM850 539q0 -116 -81.5 -197.5t-196.5 -81.5q-116 0 -197.5 82t-81.5 197
-t82 196.5t197 81.5t196.5 -81.5t81.5 -196.5zM2004 540q0 -115 -81.5 -196.5t-197.5 -81.5q-115 0 -196.5 81.5t-81.5 196.5t81.5 196.5t196.5 81.5q116 0 197.5 -81.5t81.5 -196.5zM1040 537q0 191 -135.5 326.5t-326.5 135.5q-125 0 -231 -62t-168 -168.5t-62 -231.5
-t62 -231.5t168 -168.5t231 -62q191 0 326.5 135.5t135.5 326.5zM1708 1110q-254 111 -556 111q-319 0 -573 -110q117 0 223 -45.5t182.5 -122.5t122 -183t45.5 -223q0 115 43.5 219.5t118 180.5t177.5 123t217 50zM2187 537q0 191 -135 326.5t-326 135.5t-326.5 -135.5
-t-135.5 -326.5t135.5 -326.5t326.5 -135.5t326 135.5t135 326.5zM1921 1103h383q-44 -51 -75 -114.5t-40 -114.5q110 -151 110 -337q0 -156 -77 -288t-209 -208.5t-287 -76.5q-133 0 -249 56t-196 155q-47 -56 -129 -179q-11 22 -53.5 82.5t-74.5 97.5
-q-80 -99 -196.5 -155.5t-249.5 -56.5q-155 0 -287 76.5t-209 208.5t-77 288q0 186 110 337q-9 51 -40 114.5t-75 114.5h365q149 100 355 156.5t432 56.5q224 0 421 -56t348 -157z" />
-    <glyph glyph-name="f263" unicode="&#xf263;" horiz-adv-x="1280" 
-d="M640 629q-188 0 -321 133t-133 320q0 188 133 321t321 133t321 -133t133 -321q0 -187 -133 -320t-321 -133zM640 1306q-92 0 -157.5 -65.5t-65.5 -158.5q0 -92 65.5 -157.5t157.5 -65.5t157.5 65.5t65.5 157.5q0 93 -65.5 158.5t-157.5 65.5zM1163 574q13 -27 15 -49.5
-t-4.5 -40.5t-26.5 -38.5t-42.5 -37t-61.5 -41.5q-115 -73 -315 -94l73 -72l267 -267q30 -31 30 -74t-30 -73l-12 -13q-31 -30 -74 -30t-74 30q-67 68 -267 268l-267 -268q-31 -30 -74 -30t-73 30l-12 13q-31 30 -31 73t31 74l267 267l72 72q-203 21 -317 94
-q-39 25 -61.5 41.5t-42.5 37t-26.5 38.5t-4.5 40.5t15 49.5q10 20 28 35t42 22t56 -2t65 -35q5 -4 15 -11t43 -24.5t69 -30.5t92 -24t113 -11q91 0 174 25.5t120 50.5l38 25q33 26 65 35t56 2t42 -22t28 -35z" />
-    <glyph glyph-name="_574" unicode="&#xf264;" 
-d="M927 956q0 -66 -46.5 -112.5t-112.5 -46.5t-112.5 46.5t-46.5 112.5t46.5 112.5t112.5 46.5t112.5 -46.5t46.5 -112.5zM1141 593q-10 20 -28 32t-47.5 9.5t-60.5 -27.5q-10 -8 -29 -20t-81 -32t-127 -20t-124 18t-86 36l-27 18q-31 25 -60.5 27.5t-47.5 -9.5t-28 -32
-q-22 -45 -2 -74.5t87 -73.5q83 -53 226 -67l-51 -52q-142 -142 -191 -190q-22 -22 -22 -52.5t22 -52.5l9 -9q22 -22 52.5 -22t52.5 22l191 191q114 -115 191 -191q22 -22 52.5 -22t52.5 22l9 9q22 22 22 52.5t-22 52.5l-191 190l-52 52q141 14 225 67q67 44 87 73.5t-2 74.5
-zM1092 956q0 134 -95 229t-229 95t-229 -95t-95 -229t95 -229t229 -95t229 95t95 229zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
-    <glyph glyph-name="_575" unicode="&#xf265;" horiz-adv-x="1720" 
-d="M1565 1408q65 0 110 -45.5t45 -110.5v-519q0 -176 -68 -336t-182.5 -275t-274 -182.5t-334.5 -67.5q-176 0 -335.5 67.5t-274.5 182.5t-183 275t-68 336v519q0 64 46 110t110 46h1409zM861 344q47 0 82 33l404 388q37 35 37 85q0 49 -34.5 83.5t-83.5 34.5q-47 0 -82 -33
-l-323 -310l-323 310q-35 33 -81 33q-49 0 -83.5 -34.5t-34.5 -83.5q0 -51 36 -85l405 -388q33 -33 81 -33z" />
-    <glyph glyph-name="_576" unicode="&#xf266;" horiz-adv-x="2304" 
-d="M1494 -103l-295 695q-25 -49 -158.5 -305.5t-198.5 -389.5q-1 -1 -27.5 -0.5t-26.5 1.5q-82 193 -255.5 587t-259.5 596q-21 50 -66.5 107.5t-103.5 100.5t-102 43q0 5 -0.5 24t-0.5 27h583v-50q-39 -2 -79.5 -16t-66.5 -43t-10 -64q26 -59 216.5 -499t235.5 -540
-q31 61 140 266.5t131 247.5q-19 39 -126 281t-136 295q-38 69 -201 71v50l513 -1v-47q-60 -2 -93.5 -25t-12.5 -69q33 -70 87 -189.5t86 -187.5q110 214 173 363q24 55 -10 79.5t-129 26.5q1 7 1 25v24q64 0 170.5 0.5t180 1t92.5 0.5v-49q-62 -2 -119 -33t-90 -81
-l-213 -442q13 -33 127.5 -290t121.5 -274l441 1017q-14 38 -49.5 62.5t-65 31.5t-55.5 8v50l460 -4l1 -2l-1 -44q-139 -4 -201 -145q-526 -1216 -559 -1291h-49z" />
-    <glyph glyph-name="_577" unicode="&#xf267;" horiz-adv-x="1792" 
-d="M949 643q0 -26 -16.5 -45t-41.5 -19q-26 0 -45 16.5t-19 41.5q0 26 17 45t42 19t44 -16.5t19 -41.5zM964 585l350 581q-9 -8 -67.5 -62.5t-125.5 -116.5t-136.5 -127t-117 -110.5t-50.5 -51.5l-349 -580q7 7 67 62t126 116.5t136 127t117 111t50 50.5zM1611 640
-q0 -201 -104 -371q-3 2 -17 11t-26.5 16.5t-16.5 7.5q-13 0 -13 -13q0 -10 59 -44q-74 -112 -184.5 -190.5t-241.5 -110.5l-16 67q-1 10 -15 10q-5 0 -8 -5.5t-2 -9.5l16 -68q-72 -15 -146 -15q-199 0 -372 105q1 2 13 20.5t21.5 33.5t9.5 19q0 13 -13 13q-6 0 -17 -14.5
-t-22.5 -34.5t-13.5 -23q-113 75 -192 187.5t-110 244.5l69 15q10 3 10 15q0 5 -5.5 8t-10.5 2l-68 -15q-14 72 -14 139q0 206 109 379q2 -1 18.5 -12t30 -19t17.5 -8q13 0 13 12q0 6 -12.5 15.5t-32.5 21.5l-20 12q77 112 189 189t244 107l15 -67q2 -10 15 -10q5 0 8 5.5
-t2 10.5l-15 66q71 13 134 13q204 0 379 -109q-39 -56 -39 -65q0 -13 12 -13q11 0 48 64q111 -75 187.5 -186t107.5 -241l-56 -12q-10 -2 -10 -16q0 -5 5.5 -8t9.5 -2l57 13q14 -72 14 -140zM1696 640q0 163 -63.5 311t-170.5 255t-255 170.5t-311 63.5t-311 -63.5
-t-255 -170.5t-170.5 -255t-63.5 -311t63.5 -311t170.5 -255t255 -170.5t311 -63.5t311 63.5t255 170.5t170.5 255t63.5 311zM1792 640q0 -182 -71 -348t-191 -286t-286 -191t-348 -71t-348 71t-286 191t-191 286t-71 348t71 348t191 286t286 191t348 71t348 -71t286 -191
-t191 -286t71 -348z" />
-    <glyph glyph-name="_578" unicode="&#xf268;" horiz-adv-x="1792" 
-d="M893 1536q240 2 451 -120q232 -134 352 -372l-742 39q-160 9 -294 -74.5t-185 -229.5l-276 424q128 159 311 245.5t383 87.5zM146 1131l337 -663q72 -143 211 -217t293 -45l-230 -451q-212 33 -385 157.5t-272.5 316t-99.5 411.5q0 267 146 491zM1732 962
-q58 -150 59.5 -310.5t-48.5 -306t-153 -272t-246 -209.5q-230 -133 -498 -119l405 623q88 131 82.5 290.5t-106.5 277.5zM896 942q125 0 213.5 -88.5t88.5 -213.5t-88.5 -213.5t-213.5 -88.5t-213.5 88.5t-88.5 213.5t88.5 213.5t213.5 88.5z" />
-    <glyph glyph-name="_579" unicode="&#xf269;" horiz-adv-x="1792" 
-d="M903 -256q-283 0 -504.5 150.5t-329.5 398.5q-58 131 -67 301t26 332.5t111 312t179 242.5l-11 -281q11 14 68 15.5t70 -15.5q42 81 160.5 138t234.5 59q-54 -45 -119.5 -148.5t-58.5 -163.5q25 -8 62.5 -13.5t63 -7.5t68 -4t50.5 -3q15 -5 9.5 -45.5t-30.5 -75.5
-q-5 -7 -16.5 -18.5t-56.5 -35.5t-101 -34l15 -189l-139 67q-18 -43 -7.5 -81.5t36 -66.5t65.5 -41.5t81 -6.5q51 9 98 34.5t83.5 45t73.5 17.5q61 -4 89.5 -33t19.5 -65q-1 -2 -2.5 -5.5t-8.5 -12.5t-18 -15.5t-31.5 -10.5t-46.5 -1q-60 -95 -144.5 -135.5t-209.5 -29.5
-q74 -61 162.5 -82.5t168.5 -6t154.5 52t128 87.5t80.5 104q43 91 39 192.5t-37.5 188.5t-78.5 125q87 -38 137 -79.5t77 -112.5q15 170 -57.5 343t-209.5 284q265 -77 412 -279.5t151 -517.5q2 -127 -40.5 -255t-123.5 -238t-189 -196t-247.5 -135.5t-288.5 -49.5z" />
-    <glyph glyph-name="_580" unicode="&#xf26a;" horiz-adv-x="1792" 
-d="M1493 1308q-165 110 -359 110q-155 0 -293 -73t-240 -200q-75 -93 -119.5 -218t-48.5 -266v-42q4 -141 48.5 -266t119.5 -218q102 -127 240 -200t293 -73q194 0 359 110q-121 -108 -274.5 -168t-322.5 -60q-29 0 -43 1q-175 8 -333 82t-272 193t-181 281t-67 339
-q0 182 71 348t191 286t286 191t348 71h3q168 -1 320.5 -60.5t273.5 -167.5zM1792 640q0 -192 -77 -362.5t-213 -296.5q-104 -63 -222 -63q-137 0 -255 84q154 56 253.5 233t99.5 405q0 227 -99 404t-253 234q119 83 254 83q119 0 226 -65q135 -125 210.5 -295t75.5 -361z
-" />
-    <glyph glyph-name="_581" unicode="&#xf26b;" horiz-adv-x="1792" 
-d="M1792 599q0 -56 -7 -104h-1151q0 -146 109.5 -244.5t257.5 -98.5q99 0 185.5 46.5t136.5 130.5h423q-56 -159 -170.5 -281t-267.5 -188.5t-321 -66.5q-187 0 -356 83q-228 -116 -394 -116q-237 0 -237 263q0 115 45 275q17 60 109 229q199 360 475 606
-q-184 -79 -427 -354q63 274 283.5 449.5t501.5 175.5q30 0 45 -1q255 117 433 117q64 0 116 -13t94.5 -40.5t66.5 -76.5t24 -115q0 -116 -75 -286q101 -182 101 -390zM1722 1239q0 83 -53 132t-137 49q-108 0 -254 -70q121 -47 222.5 -131.5t170.5 -195.5q51 135 51 216z
-M128 2q0 -86 48.5 -132.5t134.5 -46.5q115 0 266 83q-122 72 -213.5 183t-137.5 245q-98 -205 -98 -332zM632 715h728q-5 142 -113 237t-251 95q-144 0 -251.5 -95t-112.5 -237z" />
-    <glyph glyph-name="_582" unicode="&#xf26c;" horiz-adv-x="2048" 
-d="M1792 288v960q0 13 -9.5 22.5t-22.5 9.5h-1600q-13 0 -22.5 -9.5t-9.5 -22.5v-960q0 -13 9.5 -22.5t22.5 -9.5h1600q13 0 22.5 9.5t9.5 22.5zM1920 1248v-960q0 -66 -47 -113t-113 -47h-736v-128h352q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-832q-14 0 -23 9t-9 23
-v64q0 14 9 23t23 9h352v128h-736q-66 0 -113 47t-47 113v960q0 66 47 113t113 47h1600q66 0 113 -47t47 -113z" />
-    <glyph glyph-name="_583" unicode="&#xf26d;" horiz-adv-x="1792" 
-d="M138 1408h197q-70 -64 -126 -149q-36 -56 -59 -115t-30 -125.5t-8.5 -120t10.5 -132t21 -126t28 -136.5q4 -19 6 -28q51 -238 81 -329q57 -171 152 -275h-272q-48 0 -82 34t-34 82v1304q0 48 34 82t82 34zM1346 1408h308q48 0 82 -34t34 -82v-1304q0 -48 -34 -82t-82 -34
-h-178q212 210 196 565l-469 -101q-2 -45 -12 -82t-31 -72t-59.5 -59.5t-93.5 -36.5q-123 -26 -199 40q-32 27 -53 61t-51.5 129t-64.5 258q-35 163 -45.5 263t-5.5 139t23 77q20 41 62.5 73t102.5 45q45 12 83.5 6.5t67 -17t54 -35t43 -48t34.5 -56.5l468 100
-q-68 175 -180 287z" />
-    <glyph glyph-name="_584" unicode="&#xf26e;" 
-d="M1401 -11l-6 -6q-113 -113 -259 -175q-154 -64 -317 -64q-165 0 -317 64q-148 63 -259 175q-113 112 -175 258q-42 103 -54 189q-4 28 48 36q51 8 56 -20q1 -1 1 -4q18 -90 46 -159q50 -124 152 -226q98 -98 226 -152q132 -56 276 -56q143 0 276 56q128 55 225 152l6 6
-q10 10 25 6q12 -3 33 -22q36 -37 17 -58zM929 604l-66 -66l63 -63q21 -21 -7 -49q-17 -17 -32 -17q-10 0 -19 10l-62 61l-66 -66q-5 -5 -15 -5q-15 0 -31 16l-2 2q-18 15 -18 29q0 7 8 17l66 65l-66 66q-16 16 14 45q18 18 31 18q6 0 13 -5l65 -66l65 65q18 17 48 -13
-q27 -27 11 -44zM1400 547q0 -118 -46 -228q-45 -105 -126 -186q-80 -80 -187 -126t-228 -46t-228 46t-187 126q-82 82 -125 186q-15 33 -15 40h-1q-9 27 43 44q50 16 60 -12q37 -99 97 -167h1v339v2q3 136 102 232q105 103 253 103q147 0 251 -103t104 -249
-q0 -147 -104.5 -251t-250.5 -104q-58 0 -112 16q-28 11 -13 61q16 51 44 43l14 -3q14 -3 33 -6t30 -3q104 0 176 71.5t72 174.5q0 101 -72 171q-71 71 -175 71q-107 0 -178 -80q-64 -72 -64 -160v-413q110 -67 242 -67q96 0 185 36.5t156 103.5t103.5 155t36.5 183
-q0 198 -141 339q-140 140 -339 140q-200 0 -340 -140q-53 -53 -77 -87l-2 -2q-8 -11 -13 -15.5t-21.5 -9.5t-38.5 3q-21 5 -36.5 16.5t-15.5 26.5v680q0 15 10.5 26.5t27.5 11.5h877q30 0 30 -55t-30 -55h-811v-483h1q40 42 102 84t108 61q109 46 231 46q121 0 228 -46
-t187 -126q81 -81 126 -186q46 -112 46 -229zM1369 1128q9 -8 9 -18t-5.5 -18t-16.5 -21q-26 -26 -39 -26q-9 0 -16 7q-106 91 -207 133q-128 56 -276 56q-133 0 -262 -49q-27 -10 -45 37q-9 25 -8 38q3 16 16 20q130 57 299 57q164 0 316 -64q137 -58 235 -152z" />
-    <glyph glyph-name="_585" unicode="&#xf270;" horiz-adv-x="1792" 
-d="M1551 60q15 6 26 3t11 -17.5t-15 -33.5q-13 -16 -44 -43.5t-95.5 -68t-141 -74t-188 -58t-229.5 -24.5q-119 0 -238 31t-209 76.5t-172.5 104t-132.5 105t-84 87.5q-8 9 -10 16.5t1 12t8 7t11.5 2t11.5 -4.5q192 -117 300 -166q389 -176 799 -90q190 40 391 135z
-M1758 175q11 -16 2.5 -69.5t-28.5 -102.5q-34 -83 -85 -124q-17 -14 -26 -9t0 24q21 45 44.5 121.5t6.5 98.5q-5 7 -15.5 11.5t-27 6t-29.5 2.5t-35 0t-31.5 -2t-31 -3t-22.5 -2q-6 -1 -13 -1.5t-11 -1t-8.5 -1t-7 -0.5h-5.5h-4.5t-3 0.5t-2 1.5l-1.5 3q-6 16 47 40t103 30
-q46 7 108 1t76 -24zM1364 618q0 -31 13.5 -64t32 -58t37.5 -46t33 -32l13 -11l-227 -224q-40 37 -79 75.5t-58 58.5l-19 20q-11 11 -25 33q-38 -59 -97.5 -102.5t-127.5 -63.5t-140 -23t-137.5 21t-117.5 65.5t-83 113t-31 162.5q0 84 28 154t72 116.5t106.5 83t122.5 57
-t130 34.5t119.5 18.5t99.5 6.5v127q0 65 -21 97q-34 53 -121 53q-6 0 -16.5 -1t-40.5 -12t-56 -29.5t-56 -59.5t-48 -96l-294 27q0 60 22 119t67 113t108 95t151.5 65.5t190.5 24.5q100 0 181 -25t129.5 -61.5t81 -83t45 -86t12.5 -73.5v-589zM692 597q0 -86 70 -133
-q66 -44 139 -22q84 25 114 123q14 45 14 101v162q-59 -2 -111 -12t-106.5 -33.5t-87 -71t-32.5 -114.5z" />
-    <glyph glyph-name="_586" unicode="&#xf271;" horiz-adv-x="1792" 
-d="M1536 1280q52 0 90 -38t38 -90v-1280q0 -52 -38 -90t-90 -38h-1408q-52 0 -90 38t-38 90v1280q0 52 38 90t90 38h128v96q0 66 47 113t113 47h64q66 0 113 -47t47 -113v-96h384v96q0 66 47 113t113 47h64q66 0 113 -47t47 -113v-96h128zM1152 1376v-288q0 -14 9 -23t23 -9
-h64q14 0 23 9t9 23v288q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23zM384 1376v-288q0 -14 9 -23t23 -9h64q14 0 23 9t9 23v288q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23zM1536 -128v1024h-1408v-1024h1408zM896 448h224q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-224
-v-224q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v224h-224q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h224v224q0 14 9 23t23 9h64q14 0 23 -9t9 -23v-224z" />
-    <glyph glyph-name="_587" unicode="&#xf272;" horiz-adv-x="1792" 
-d="M1152 416v-64q0 -14 -9 -23t-23 -9h-576q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h576q14 0 23 -9t9 -23zM128 -128h1408v1024h-1408v-1024zM512 1088v288q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-288q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM1280 1088v288q0 14 -9 23
-t-23 9h-64q-14 0 -23 -9t-9 -23v-288q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM1664 1152v-1280q0 -52 -38 -90t-90 -38h-1408q-52 0 -90 38t-38 90v1280q0 52 38 90t90 38h128v96q0 66 47 113t113 47h64q66 0 113 -47t47 -113v-96h384v96q0 66 47 113t113 47h64q66 0 113 -47
-t47 -113v-96h128q52 0 90 -38t38 -90z" />
-    <glyph glyph-name="_588" unicode="&#xf273;" horiz-adv-x="1792" 
-d="M1111 151l-46 -46q-9 -9 -22 -9t-23 9l-188 189l-188 -189q-10 -9 -23 -9t-22 9l-46 46q-9 9 -9 22t9 23l189 188l-189 188q-9 10 -9 23t9 22l46 46q9 9 22 9t23 -9l188 -188l188 188q10 9 23 9t22 -9l46 -46q9 -9 9 -22t-9 -23l-188 -188l188 -188q9 -10 9 -23t-9 -22z
-M128 -128h1408v1024h-1408v-1024zM512 1088v288q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-288q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM1280 1088v288q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-288q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM1664 1152v-1280
-q0 -52 -38 -90t-90 -38h-1408q-52 0 -90 38t-38 90v1280q0 52 38 90t90 38h128v96q0 66 47 113t113 47h64q66 0 113 -47t47 -113v-96h384v96q0 66 47 113t113 47h64q66 0 113 -47t47 -113v-96h128q52 0 90 -38t38 -90z" />
-    <glyph glyph-name="_589" unicode="&#xf274;" horiz-adv-x="1792" 
-d="M1303 572l-512 -512q-10 -9 -23 -9t-23 9l-288 288q-9 10 -9 23t9 22l46 46q9 9 22 9t23 -9l220 -220l444 444q10 9 23 9t22 -9l46 -46q9 -9 9 -22t-9 -23zM128 -128h1408v1024h-1408v-1024zM512 1088v288q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-288q0 -14 9 -23
-t23 -9h64q14 0 23 9t9 23zM1280 1088v288q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-288q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM1664 1152v-1280q0 -52 -38 -90t-90 -38h-1408q-52 0 -90 38t-38 90v1280q0 52 38 90t90 38h128v96q0 66 47 113t113 47h64q66 0 113 -47
-t47 -113v-96h384v96q0 66 47 113t113 47h64q66 0 113 -47t47 -113v-96h128q52 0 90 -38t38 -90z" />
-    <glyph glyph-name="_590" unicode="&#xf275;" horiz-adv-x="1792" 
-d="M448 1536q26 0 45 -19t19 -45v-891l536 429q17 14 40 14q26 0 45 -19t19 -45v-379l536 429q17 14 40 14q26 0 45 -19t19 -45v-1152q0 -26 -19 -45t-45 -19h-1664q-26 0 -45 19t-19 45v1664q0 26 19 45t45 19h384z" />
-    <glyph glyph-name="_591" unicode="&#xf276;" horiz-adv-x="1024" 
-d="M512 448q66 0 128 15v-655q0 -26 -19 -45t-45 -19h-128q-26 0 -45 19t-19 45v655q62 -15 128 -15zM512 1536q212 0 362 -150t150 -362t-150 -362t-362 -150t-362 150t-150 362t150 362t362 150zM512 1312q14 0 23 9t9 23t-9 23t-23 9q-146 0 -249 -103t-103 -249
-q0 -14 9 -23t23 -9t23 9t9 23q0 119 84.5 203.5t203.5 84.5z" />
-    <glyph glyph-name="_592" unicode="&#xf277;" horiz-adv-x="1792" 
-d="M1745 1239q10 -10 10 -23t-10 -23l-141 -141q-28 -28 -68 -28h-1344q-26 0 -45 19t-19 45v256q0 26 19 45t45 19h576v64q0 26 19 45t45 19h128q26 0 45 -19t19 -45v-64h512q40 0 68 -28zM768 320h256v-512q0 -26 -19 -45t-45 -19h-128q-26 0 -45 19t-19 45v512zM1600 768
-q26 0 45 -19t19 -45v-256q0 -26 -19 -45t-45 -19h-1344q-40 0 -68 28l-141 141q-10 10 -10 23t10 23l141 141q28 28 68 28h512v192h256v-192h576z" />
-    <glyph glyph-name="_593" unicode="&#xf278;" horiz-adv-x="2048" 
-d="M2020 1525q28 -20 28 -53v-1408q0 -20 -11 -36t-29 -23l-640 -256q-24 -11 -48 0l-616 246l-616 -246q-10 -5 -24 -5q-19 0 -36 11q-28 20 -28 53v1408q0 20 11 36t29 23l640 256q24 11 48 0l616 -246l616 246q32 13 60 -6zM736 1390v-1270l576 -230v1270zM128 1173
-v-1270l544 217v1270zM1920 107v1270l-544 -217v-1270z" />
-    <glyph glyph-name="_594" unicode="&#xf279;" horiz-adv-x="1792" 
-d="M512 1536q13 0 22.5 -9.5t9.5 -22.5v-1472q0 -20 -17 -28l-480 -256q-7 -4 -15 -4q-13 0 -22.5 9.5t-9.5 22.5v1472q0 20 17 28l480 256q7 4 15 4zM1760 1536q13 0 22.5 -9.5t9.5 -22.5v-1472q0 -20 -17 -28l-480 -256q-7 -4 -15 -4q-13 0 -22.5 9.5t-9.5 22.5v1472
-q0 20 17 28l480 256q7 4 15 4zM640 1536q8 0 14 -3l512 -256q18 -10 18 -29v-1472q0 -13 -9.5 -22.5t-22.5 -9.5q-8 0 -14 3l-512 256q-18 10 -18 29v1472q0 13 9.5 22.5t22.5 9.5z" />
-    <glyph glyph-name="_595" unicode="&#xf27a;" horiz-adv-x="1792" 
-d="M640 640q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1024 640q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1408 640q0 53 -37.5 90.5t-90.5 37.5
-t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1792 640q0 -174 -120 -321.5t-326 -233t-450 -85.5q-110 0 -211 18q-173 -173 -435 -229q-52 -10 -86 -13q-12 -1 -22 6t-13 18q-4 15 20 37q5 5 23.5 21.5t25.5 23.5t23.5 25.5t24 31.5t20.5 37
-t20 48t14.5 57.5t12.5 72.5q-146 90 -229.5 216.5t-83.5 269.5q0 174 120 321.5t326 233t450 85.5t450 -85.5t326 -233t120 -321.5z" />
-    <glyph glyph-name="_596" unicode="&#xf27b;" horiz-adv-x="1792" 
-d="M640 640q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1024 640q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1408 640q0 -53 -37.5 -90.5t-90.5 -37.5
-t-90.5 37.5t-37.5 90.5t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM896 1152q-204 0 -381.5 -69.5t-282 -187.5t-104.5 -255q0 -112 71.5 -213.5t201.5 -175.5l87 -50l-27 -96q-24 -91 -70 -172q152 63 275 171l43 38l57 -6q69 -8 130 -8q204 0 381.5 69.5t282 187.5
-t104.5 255t-104.5 255t-282 187.5t-381.5 69.5zM1792 640q0 -174 -120 -321.5t-326 -233t-450 -85.5q-70 0 -145 8q-198 -175 -460 -242q-49 -14 -114 -22h-5q-15 0 -27 10.5t-16 27.5v1q-3 4 -0.5 12t2 10t4.5 9.5l6 9t7 8.5t8 9q7 8 31 34.5t34.5 38t31 39.5t32.5 51
-t27 59t26 76q-157 89 -247.5 220t-90.5 281q0 130 71 248.5t191 204.5t286 136.5t348 50.5t348 -50.5t286 -136.5t191 -204.5t71 -248.5z" />
-    <glyph glyph-name="_597" unicode="&#xf27c;" horiz-adv-x="1024" 
-d="M512 345l512 295v-591l-512 -296v592zM0 640v-591l512 296zM512 1527v-591l-512 -296v591zM512 936l512 295v-591z" />
-    <glyph glyph-name="_598" unicode="&#xf27d;" horiz-adv-x="1792" 
-d="M1709 1018q-10 -236 -332 -651q-333 -431 -562 -431q-142 0 -240 263q-44 160 -132 482q-72 262 -157 262q-18 0 -127 -76l-77 98q24 21 108 96.5t130 115.5q156 138 241 146q95 9 153 -55.5t81 -203.5q44 -287 66 -373q55 -249 120 -249q51 0 154 161q101 161 109 246
-q13 139 -109 139q-57 0 -121 -26q120 393 459 382q251 -8 236 -326z" />
-    <glyph glyph-name="f27e" unicode="&#xf27e;" 
-d="M0 1408h1536v-1536h-1536v1536zM1085 293l-221 631l221 297h-634l221 -297l-221 -631l317 -304z" />
-    <glyph glyph-name="uniF280" unicode="&#xf280;" 
-d="M0 1408h1536v-1536h-1536v1536zM908 1088l-12 -33l75 -83l-31 -114l25 -25l107 57l107 -57l25 25l-31 114l75 83l-12 33h-95l-53 96h-32l-53 -96h-95zM641 925q32 0 44.5 -16t11.5 -63l174 21q0 55 -17.5 92.5t-50.5 56t-69 25.5t-85 7q-133 0 -199 -57.5t-66 -182.5v-72
-h-96v-128h76q20 0 20 -8v-382q0 -14 -5 -20t-18 -7l-73 -7v-88h448v86l-149 14q-6 1 -8.5 1.5t-3.5 2.5t-0.5 4t1 7t0.5 10v387h191l38 128h-231q-6 0 -2 6t4 9v80q0 27 1.5 40.5t7.5 28t19.5 20t36.5 5.5zM1248 96v86l-54 9q-7 1 -9.5 2.5t-2.5 3t1 7.5t1 12v520h-275
-l-23 -101l83 -22q23 -7 23 -27v-370q0 -14 -6 -18.5t-20 -6.5l-70 -9v-86h352z" />
-    <glyph glyph-name="uniF281" unicode="&#xf281;" horiz-adv-x="1792" 
-d="M1792 690q0 -58 -29.5 -105.5t-79.5 -72.5q12 -46 12 -96q0 -155 -106.5 -287t-290.5 -208.5t-400 -76.5t-399.5 76.5t-290 208.5t-106.5 287q0 47 11 94q-51 25 -82 73.5t-31 106.5q0 82 58 140.5t141 58.5q85 0 145 -63q218 152 515 162l116 521q3 13 15 21t26 5
-l369 -81q18 37 54 59.5t79 22.5q62 0 106 -43.5t44 -105.5t-44 -106t-106 -44t-105.5 43.5t-43.5 105.5l-334 74l-104 -472q300 -9 519 -160q58 61 143 61q83 0 141 -58.5t58 -140.5zM418 491q0 -62 43.5 -106t105.5 -44t106 44t44 106t-44 105.5t-106 43.5q-61 0 -105 -44
-t-44 -105zM1228 136q11 11 11 26t-11 26q-10 10 -25 10t-26 -10q-41 -42 -121 -62t-160 -20t-160 20t-121 62q-11 10 -26 10t-25 -10q-11 -10 -11 -25.5t11 -26.5q43 -43 118.5 -68t122.5 -29.5t91 -4.5t91 4.5t122.5 29.5t118.5 68zM1225 341q62 0 105.5 44t43.5 106
-q0 61 -44 105t-105 44q-62 0 -106 -43.5t-44 -105.5t44 -106t106 -44z" />
-    <glyph glyph-name="_602" unicode="&#xf282;" horiz-adv-x="1792" 
-d="M69 741h1q16 126 58.5 241.5t115 217t167.5 176t223.5 117.5t276.5 43q231 0 414 -105.5t294 -303.5q104 -187 104 -442v-188h-1125q1 -111 53.5 -192.5t136.5 -122.5t189.5 -57t213 -3t208 46.5t173.5 84.5v-377q-92 -55 -229.5 -92t-312.5 -38t-316 53
-q-189 73 -311.5 249t-124.5 372q-3 242 111 412t325 268q-48 -60 -78 -125.5t-46 -159.5h635q8 77 -8 140t-47 101.5t-70.5 66.5t-80.5 41t-75 20.5t-56 8.5l-22 1q-135 -5 -259.5 -44.5t-223.5 -104.5t-176 -140.5t-138 -163.5z" />
-    <glyph glyph-name="_603" unicode="&#xf283;" horiz-adv-x="2304" 
-d="M0 32v608h2304v-608q0 -66 -47 -113t-113 -47h-1984q-66 0 -113 47t-47 113zM640 256v-128h384v128h-384zM256 256v-128h256v128h-256zM2144 1408q66 0 113 -47t47 -113v-224h-2304v224q0 66 47 113t113 47h1984z" />
-    <glyph glyph-name="_604" unicode="&#xf284;" horiz-adv-x="1792" 
-d="M1584 246l-218 111q-74 -120 -196.5 -189t-263.5 -69q-147 0 -271 72t-196 196t-72 270q0 110 42.5 209.5t115 172t172 115t209.5 42.5q131 0 247.5 -60.5t192.5 -168.5l215 125q-110 169 -286.5 265t-378.5 96q-161 0 -308 -63t-253 -169t-169 -253t-63 -308t63 -308
-t169 -253t253 -169t308 -63q213 0 397.5 107t290.5 292zM1030 643l693 -352q-116 -253 -334.5 -400t-492.5 -147q-182 0 -348 71t-286 191t-191 286t-71 348t71 348t191 286t286 191t348 71q260 0 470.5 -133.5t335.5 -366.5zM1543 640h-39v-160h-96v352h136q32 0 54.5 -20
-t28.5 -48t1 -56t-27.5 -48t-57.5 -20z" />
-    <glyph glyph-name="uniF285" unicode="&#xf285;" horiz-adv-x="1792" 
-d="M1427 827l-614 386l92 151h855zM405 562l-184 116v858l1183 -743zM1424 697l147 -95v-858l-532 335zM1387 718l-500 -802h-855l356 571z" />
-    <glyph glyph-name="uniF286" unicode="&#xf286;" horiz-adv-x="1792" 
-d="M640 528v224q0 16 -16 16h-96q-16 0 -16 -16v-224q0 -16 16 -16h96q16 0 16 16zM1152 528v224q0 16 -16 16h-96q-16 0 -16 -16v-224q0 -16 16 -16h96q16 0 16 16zM1664 496v-752h-640v320q0 80 -56 136t-136 56t-136 -56t-56 -136v-320h-640v752q0 16 16 16h96
-q16 0 16 -16v-112h128v624q0 16 16 16h96q16 0 16 -16v-112h128v112q0 16 16 16h96q16 0 16 -16v-112h128v112q0 6 2.5 9.5t8.5 5t9.5 2t11.5 0t9 -0.5v391q-32 15 -32 50q0 23 16.5 39t38.5 16t38.5 -16t16.5 -39q0 -35 -32 -50v-17q45 10 83 10q21 0 59.5 -7.5t54.5 -7.5
-q17 0 47 7.5t37 7.5q16 0 16 -16v-210q0 -15 -35 -21.5t-62 -6.5q-18 0 -54.5 7.5t-55.5 7.5q-40 0 -90 -12v-133q1 0 9 0.5t11.5 0t9.5 -2t8.5 -5t2.5 -9.5v-112h128v112q0 16 16 16h96q16 0 16 -16v-112h128v112q0 16 16 16h96q16 0 16 -16v-624h128v112q0 16 16 16h96
-q16 0 16 -16z" />
-    <glyph glyph-name="_607" unicode="&#xf287;" horiz-adv-x="2304" 
-d="M2288 731q16 -8 16 -27t-16 -27l-320 -192q-8 -5 -16 -5q-9 0 -16 4q-16 10 -16 28v128h-858q37 -58 83 -165q16 -37 24.5 -55t24 -49t27 -47t27 -34t31.5 -26t33 -8h96v96q0 14 9 23t23 9h320q14 0 23 -9t9 -23v-320q0 -14 -9 -23t-23 -9h-320q-14 0 -23 9t-9 23v96h-96
-q-32 0 -61 10t-51 23.5t-45 40.5t-37 46t-33.5 57t-28.5 57.5t-28 60.5q-23 53 -37 81.5t-36 65t-44.5 53.5t-46.5 17h-360q-22 -84 -91 -138t-157 -54q-106 0 -181 75t-75 181t75 181t181 75q88 0 157 -54t91 -138h104q24 0 46.5 17t44.5 53.5t36 65t37 81.5q19 41 28 60.5
-t28.5 57.5t33.5 57t37 46t45 40.5t51 23.5t61 10h107q21 57 70 92.5t111 35.5q80 0 136 -56t56 -136t-56 -136t-136 -56q-62 0 -111 35.5t-70 92.5h-107q-17 0 -33 -8t-31.5 -26t-27 -34t-27 -47t-24 -49t-24.5 -55q-46 -107 -83 -165h1114v128q0 18 16 28t32 -1z" />
-    <glyph glyph-name="_608" unicode="&#xf288;" horiz-adv-x="1792" 
-d="M1150 774q0 -56 -39.5 -95t-95.5 -39h-253v269h253q56 0 95.5 -39.5t39.5 -95.5zM1329 774q0 130 -91.5 222t-222.5 92h-433v-896h180v269h253q130 0 222 91.5t92 221.5zM1792 640q0 -182 -71 -348t-191 -286t-286 -191t-348 -71t-348 71t-286 191t-191 286t-71 348
-t71 348t191 286t286 191t348 71t348 -71t286 -191t191 -286t71 -348z" />
-    <glyph glyph-name="_609" unicode="&#xf289;" horiz-adv-x="2304" 
-d="M1645 438q0 59 -34 106.5t-87 68.5q-7 -45 -23 -92q-7 -24 -27.5 -38t-44.5 -14q-12 0 -24 3q-31 10 -45 38.5t-4 58.5q23 71 23 143q0 123 -61 227.5t-166 165.5t-228 61q-134 0 -247 -73t-167 -194q108 -28 188 -106q22 -23 22 -55t-22 -54t-54 -22t-55 22
-q-75 75 -180 75q-106 0 -181 -74.5t-75 -180.5t75 -180.5t181 -74.5h1046q79 0 134.5 55.5t55.5 133.5zM1798 438q0 -142 -100.5 -242t-242.5 -100h-1046q-169 0 -289 119.5t-120 288.5q0 153 100 267t249 136q62 184 221 298t354 114q235 0 408.5 -158.5t196.5 -389.5
-q116 -25 192.5 -118.5t76.5 -214.5zM2048 438q0 -175 -97 -319q-23 -33 -64 -33q-24 0 -43 13q-26 17 -32 48.5t12 57.5q71 104 71 233t-71 233q-18 26 -12 57t32 49t57.5 11.5t49.5 -32.5q97 -142 97 -318zM2304 438q0 -244 -134 -443q-23 -34 -64 -34q-23 0 -42 13
-q-26 18 -32.5 49t11.5 57q108 164 108 358q0 195 -108 357q-18 26 -11.5 57.5t32.5 48.5q26 18 57 12t49 -33q134 -198 134 -442z" />
-    <glyph glyph-name="_610" unicode="&#xf28a;" 
-d="M1500 -13q0 -89 -63 -152.5t-153 -63.5t-153.5 63.5t-63.5 152.5q0 90 63.5 153.5t153.5 63.5t153 -63.5t63 -153.5zM1267 268q-115 -15 -192.5 -102.5t-77.5 -205.5q0 -74 33 -138q-146 -78 -379 -78q-109 0 -201 21t-153.5 54.5t-110.5 76.5t-76 85t-44.5 83
-t-23.5 66.5t-6 39.5q0 19 4.5 42.5t18.5 56t36.5 58t64 43.5t94.5 18t94 -17.5t63 -41t35.5 -53t17.5 -49t4 -33.5q0 -34 -23 -81q28 -27 82 -42t93 -17l40 -1q115 0 190 51t75 133q0 26 -9 48.5t-31.5 44.5t-49.5 41t-74 44t-93.5 47.5t-119.5 56.5q-28 13 -43 20
-q-116 55 -187 100t-122.5 102t-72 125.5t-20.5 162.5q0 78 20.5 150t66 137.5t112.5 114t166.5 77t221.5 28.5q120 0 220 -26t164.5 -67t109.5 -94t64 -105.5t19 -103.5q0 -46 -15 -82.5t-36.5 -58t-48.5 -36t-49 -19.5t-39 -5h-8h-32t-39 5t-44 14t-41 28t-37 46t-24 70.5
-t-10 97.5q-15 16 -59 25.5t-81 10.5l-37 1q-68 0 -117.5 -31t-70.5 -70t-21 -76q0 -24 5 -43t24 -46t53 -51t97 -53.5t150 -58.5q76 -25 138.5 -53.5t109 -55.5t83 -59t60.5 -59.5t41 -62.5t26.5 -62t14.5 -63.5t6 -62t1 -62.5z" />
-    <glyph glyph-name="_611" unicode="&#xf28b;" 
-d="M704 352v576q0 14 -9 23t-23 9h-256q-14 0 -23 -9t-9 -23v-576q0 -14 9 -23t23 -9h256q14 0 23 9t9 23zM1152 352v576q0 14 -9 23t-23 9h-256q-14 0 -23 -9t-9 -23v-576q0 -14 9 -23t23 -9h256q14 0 23 9t9 23zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103
-t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
-    <glyph glyph-name="_612" unicode="&#xf28c;" 
-d="M768 1408q209 0 385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103zM768 96q148 0 273 73t198 198t73 273t-73 273t-198 198t-273 73t-273 -73t-198 -198t-73 -273
-t73 -273t198 -198t273 -73zM864 320q-14 0 -23 9t-9 23v576q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-576q0 -14 -9 -23t-23 -9h-192zM480 320q-14 0 -23 9t-9 23v576q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-576q0 -14 -9 -23t-23 -9h-192z" />
-    <glyph glyph-name="_613" unicode="&#xf28d;" 
-d="M1088 352v576q0 14 -9 23t-23 9h-576q-14 0 -23 -9t-9 -23v-576q0 -14 9 -23t23 -9h576q14 0 23 9t9 23zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5
-t103 -385.5z" />
-    <glyph glyph-name="_614" unicode="&#xf28e;" 
-d="M768 1408q209 0 385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103zM768 96q148 0 273 73t198 198t73 273t-73 273t-198 198t-273 73t-273 -73t-198 -198t-73 -273
-t73 -273t198 -198t273 -73zM480 320q-14 0 -23 9t-9 23v576q0 14 9 23t23 9h576q14 0 23 -9t9 -23v-576q0 -14 -9 -23t-23 -9h-576z" />
-    <glyph glyph-name="_615" unicode="&#xf290;" horiz-adv-x="1792" 
-d="M1757 128l35 -313q3 -28 -16 -50q-19 -21 -48 -21h-1664q-29 0 -48 21q-19 22 -16 50l35 313h1722zM1664 967l86 -775h-1708l86 775q3 24 21 40.5t43 16.5h256v-128q0 -53 37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5v128h384v-128q0 -53 37.5 -90.5t90.5 -37.5
-t90.5 37.5t37.5 90.5v128h256q25 0 43 -16.5t21 -40.5zM1280 1152v-256q0 -26 -19 -45t-45 -19t-45 19t-19 45v256q0 106 -75 181t-181 75t-181 -75t-75 -181v-256q0 -26 -19 -45t-45 -19t-45 19t-19 45v256q0 159 112.5 271.5t271.5 112.5t271.5 -112.5t112.5 -271.5z" />
-    <glyph glyph-name="_616" unicode="&#xf291;" horiz-adv-x="2048" 
-d="M1920 768q53 0 90.5 -37.5t37.5 -90.5t-37.5 -90.5t-90.5 -37.5h-15l-115 -662q-8 -46 -44 -76t-82 -30h-1280q-46 0 -82 30t-44 76l-115 662h-15q-53 0 -90.5 37.5t-37.5 90.5t37.5 90.5t90.5 37.5h1792zM485 -32q26 2 43.5 22.5t15.5 46.5l-32 416q-2 26 -22.5 43.5
-t-46.5 15.5t-43.5 -22.5t-15.5 -46.5l32 -416q2 -25 20.5 -42t43.5 -17h5zM896 32v416q0 26 -19 45t-45 19t-45 -19t-19 -45v-416q0 -26 19 -45t45 -19t45 19t19 45zM1280 32v416q0 26 -19 45t-45 19t-45 -19t-19 -45v-416q0 -26 19 -45t45 -19t45 19t19 45zM1632 27l32 416
-q2 26 -15.5 46.5t-43.5 22.5t-46.5 -15.5t-22.5 -43.5l-32 -416q-2 -26 15.5 -46.5t43.5 -22.5h5q25 0 43.5 17t20.5 42zM476 1244l-93 -412h-132l101 441q19 88 89 143.5t160 55.5h167q0 26 19 45t45 19h384q26 0 45 -19t19 -45h167q90 0 160 -55.5t89 -143.5l101 -441
-h-132l-93 412q-11 44 -45.5 72t-79.5 28h-167q0 -26 -19 -45t-45 -19h-384q-26 0 -45 19t-19 45h-167q-45 0 -79.5 -28t-45.5 -72z" />
-    <glyph glyph-name="_617" unicode="&#xf292;" horiz-adv-x="1792" 
-d="M991 512l64 256h-254l-64 -256h254zM1759 1016l-56 -224q-7 -24 -31 -24h-327l-64 -256h311q15 0 25 -12q10 -14 6 -28l-56 -224q-5 -24 -31 -24h-327l-81 -328q-7 -24 -31 -24h-224q-16 0 -26 12q-9 12 -6 28l78 312h-254l-81 -328q-7 -24 -31 -24h-225q-15 0 -25 12
-q-9 12 -6 28l78 312h-311q-15 0 -25 12q-9 12 -6 28l56 224q7 24 31 24h327l64 256h-311q-15 0 -25 12q-10 14 -6 28l56 224q5 24 31 24h327l81 328q7 24 32 24h224q15 0 25 -12q9 -12 6 -28l-78 -312h254l81 328q7 24 32 24h224q15 0 25 -12q9 -12 6 -28l-78 -312h311
-q15 0 25 -12q9 -12 6 -28z" />
-    <glyph glyph-name="_618" unicode="&#xf293;" 
-d="M841 483l148 -148l-149 -149zM840 1094l149 -149l-148 -148zM710 -130l464 464l-306 306l306 306l-464 464v-611l-255 255l-93 -93l320 -321l-320 -321l93 -93l255 255v-611zM1429 640q0 -209 -32 -365.5t-87.5 -257t-140.5 -162.5t-181.5 -86.5t-219.5 -24.5
-t-219.5 24.5t-181.5 86.5t-140.5 162.5t-87.5 257t-32 365.5t32 365.5t87.5 257t140.5 162.5t181.5 86.5t219.5 24.5t219.5 -24.5t181.5 -86.5t140.5 -162.5t87.5 -257t32 -365.5z" />
-    <glyph glyph-name="_619" unicode="&#xf294;" horiz-adv-x="1024" 
-d="M596 113l173 172l-173 172v-344zM596 823l173 172l-173 172v-344zM628 640l356 -356l-539 -540v711l-297 -296l-108 108l372 373l-372 373l108 108l297 -296v711l539 -540z" />
-    <glyph glyph-name="_620" unicode="&#xf295;" 
-d="M1280 256q0 52 -38 90t-90 38t-90 -38t-38 -90t38 -90t90 -38t90 38t38 90zM512 1024q0 52 -38 90t-90 38t-90 -38t-38 -90t38 -90t90 -38t90 38t38 90zM1536 256q0 -159 -112.5 -271.5t-271.5 -112.5t-271.5 112.5t-112.5 271.5t112.5 271.5t271.5 112.5t271.5 -112.5
-t112.5 -271.5zM1440 1344q0 -20 -13 -38l-1056 -1408q-19 -26 -51 -26h-160q-26 0 -45 19t-19 45q0 20 13 38l1056 1408q19 26 51 26h160q26 0 45 -19t19 -45zM768 1024q0 -159 -112.5 -271.5t-271.5 -112.5t-271.5 112.5t-112.5 271.5t112.5 271.5t271.5 112.5
-t271.5 -112.5t112.5 -271.5z" />
-    <glyph glyph-name="_621" unicode="&#xf296;" horiz-adv-x="1792" 
-d="M104 830l792 -1015l-868 630q-18 13 -25 34.5t0 42.5l101 308v0zM566 830h660l-330 -1015v0zM368 1442l198 -612h-462l198 612q8 23 33 23t33 -23zM1688 830l101 -308q7 -21 0 -42.5t-25 -34.5l-868 -630l792 1015v0zM1688 830h-462l198 612q8 23 33 23t33 -23z" />
-    <glyph glyph-name="_622" unicode="&#xf297;" horiz-adv-x="1792" 
-d="M384 704h160v224h-160v-224zM1221 372v92q-104 -36 -243 -38q-135 -1 -259.5 46.5t-220.5 122.5l1 -96q88 -80 212 -128.5t272 -47.5q129 0 238 49zM640 704h640v224h-640v-224zM1792 736q0 -187 -99 -352q89 -102 89 -229q0 -157 -129.5 -268t-313.5 -111
-q-122 0 -225 52.5t-161 140.5q-19 -1 -57 -1t-57 1q-58 -88 -161 -140.5t-225 -52.5q-184 0 -313.5 111t-129.5 268q0 127 89 229q-99 165 -99 352q0 209 120 385.5t326.5 279.5t449.5 103t449.5 -103t326.5 -279.5t120 -385.5z" />
-    <glyph glyph-name="_623" unicode="&#xf298;" 
-d="M515 625v-128h-252v128h252zM515 880v-127h-252v127h252zM1273 369v-128h-341v128h341zM1273 625v-128h-672v128h672zM1273 880v-127h-672v127h672zM1408 20v1240q0 8 -6 14t-14 6h-32l-378 -256l-210 171l-210 -171l-378 256h-32q-8 0 -14 -6t-6 -14v-1240q0 -8 6 -14
-t14 -6h1240q8 0 14 6t6 14zM553 1130l185 150h-406zM983 1130l221 150h-406zM1536 1260v-1240q0 -62 -43 -105t-105 -43h-1240q-62 0 -105 43t-43 105v1240q0 62 43 105t105 43h1240q62 0 105 -43t43 -105z" />
-    <glyph glyph-name="_624" unicode="&#xf299;" horiz-adv-x="1792" 
-d="M896 720q-104 196 -160 278q-139 202 -347 318q-34 19 -70 36q-89 40 -94 32t34 -38l39 -31q62 -43 112.5 -93.5t94.5 -116.5t70.5 -113t70.5 -131q9 -17 13 -25q44 -84 84 -153t98 -154t115.5 -150t131 -123.5t148.5 -90.5q153 -66 154 -60q1 3 -49 37q-53 36 -81 57
-q-77 58 -179 211t-185 310zM549 177q-76 60 -132.5 125t-98 143.5t-71 154.5t-58.5 186t-52 209t-60.5 252t-76.5 289q273 0 497.5 -36t379 -92t271 -144.5t185.5 -172.5t110 -198.5t56 -199.5t12.5 -198.5t-9.5 -173t-20 -143.5t-13 -107l323 -327h-104l-281 285
-q-22 -2 -91.5 -14t-121.5 -19t-138 -6t-160.5 17t-167.5 59t-179 111z" />
-    <glyph glyph-name="_625" unicode="&#xf29a;" horiz-adv-x="1792" 
-d="M1374 879q-6 26 -28.5 39.5t-48.5 7.5q-261 -62 -401 -62t-401 62q-26 6 -48.5 -7.5t-28.5 -39.5t7.5 -48.5t39.5 -28.5q194 -46 303 -58q-2 -158 -15.5 -269t-26.5 -155.5t-41 -115.5l-9 -21q-10 -25 1 -49t36 -34q9 -4 23 -4q44 0 60 41l8 20q54 139 71 259h42
-q17 -120 71 -259l8 -20q16 -41 60 -41q14 0 23 4q25 10 36 34t1 49l-9 21q-28 71 -41 115.5t-26.5 155.5t-15.5 269q109 12 303 58q26 6 39.5 28.5t7.5 48.5zM1024 1024q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5z
-M1600 640q0 -143 -55.5 -273.5t-150 -225t-225 -150t-273.5 -55.5t-273.5 55.5t-225 150t-150 225t-55.5 273.5t55.5 273.5t150 225t225 150t273.5 55.5t273.5 -55.5t225 -150t150 -225t55.5 -273.5zM896 1408q-156 0 -298 -61t-245 -164t-164 -245t-61 -298t61 -298
-t164 -245t245 -164t298 -61t298 61t245 164t164 245t61 298t-61 298t-164 245t-245 164t-298 61zM1792 640q0 -182 -71 -348t-191 -286t-286 -191t-348 -71t-348 71t-286 191t-191 286t-71 348t71 348t191 286t286 191t348 71t348 -71t286 -191t191 -286t71 -348z" />
-    <glyph glyph-name="_626" unicode="&#xf29b;" 
-d="M1438 723q34 -35 29 -82l-44 -551q-4 -42 -34.5 -70t-71.5 -28q-6 0 -9 1q-44 3 -72.5 36.5t-25.5 77.5l35 429l-143 -8q55 -113 55 -240q0 -216 -148 -372l-137 137q91 101 91 235q0 145 -102.5 248t-247.5 103q-134 0 -236 -92l-137 138q120 114 284 141l264 300
-l-149 87l-181 -161q-33 -30 -77 -27.5t-73 35.5t-26.5 77t34.5 73l239 213q26 23 60 26.5t64 -14.5l488 -283q36 -21 48 -68q17 -67 -26 -117l-205 -232l371 20q49 3 83 -32zM1240 1180q-74 0 -126 52t-52 126t52 126t126 52t126.5 -52t52.5 -126t-52.5 -126t-126.5 -52z
-M613 -62q106 0 196 61l139 -139q-146 -116 -335 -116q-148 0 -273.5 73t-198.5 198t-73 273q0 188 116 336l139 -139q-60 -88 -60 -197q0 -145 102.5 -247.5t247.5 -102.5z" />
-    <glyph glyph-name="_627" unicode="&#xf29c;" 
-d="M880 336v-160q0 -14 -9 -23t-23 -9h-160q-14 0 -23 9t-9 23v160q0 14 9 23t23 9h160q14 0 23 -9t9 -23zM1136 832q0 -50 -15 -90t-45.5 -69t-52 -44t-59.5 -36q-32 -18 -46.5 -28t-26 -24t-11.5 -29v-32q0 -14 -9 -23t-23 -9h-160q-14 0 -23 9t-9 23v68q0 35 10.5 64.5
-t24 47.5t39 35.5t41 25.5t44.5 21q53 25 75 43t22 49q0 42 -43.5 71.5t-95.5 29.5q-56 0 -95 -27q-29 -20 -80 -83q-9 -12 -25 -12q-11 0 -19 6l-108 82q-10 7 -12 20t5 23q122 192 349 192q129 0 238.5 -89.5t109.5 -214.5zM768 1280q-130 0 -248.5 -51t-204 -136.5
-t-136.5 -204t-51 -248.5t51 -248.5t136.5 -204t204 -136.5t248.5 -51t248.5 51t204 136.5t136.5 204t51 248.5t-51 248.5t-136.5 204t-204 136.5t-248.5 51zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5
-t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
-    <glyph glyph-name="_628" unicode="&#xf29d;" horiz-adv-x="1408" 
-d="M366 1225q-64 0 -110 45.5t-46 110.5q0 64 46 109.5t110 45.5t109.5 -45.5t45.5 -109.5q0 -65 -45.5 -110.5t-109.5 -45.5zM917 583q0 -50 -30 -67.5t-63.5 -6.5t-47.5 34l-367 438q-7 12 -14 15.5t-11 1.5l-3 -3q-7 -8 4 -21l122 -139l1 -354l-161 -457
-q-67 -192 -92 -234q-15 -26 -28 -32q-50 -26 -103 -1q-29 13 -41.5 43t-9.5 57q2 17 197 618l5 416l-85 -164l35 -222q4 -24 -1 -42t-14 -27.5t-19 -16t-17 -7.5l-7 -2q-19 -3 -34.5 3t-24 16t-14 22t-7.5 19.5t-2 9.5l-46 299l211 381q23 34 113 34q75 0 107 -40l424 -521
-q7 -5 14 -17l3 -3l-1 -1q7 -13 7 -29zM514 433q43 -113 88.5 -225t69.5 -168l24 -55q36 -93 42 -125q11 -70 -36 -97q-35 -22 -66 -16t-51 22t-29 35h-1q-6 16 -8 25l-124 351zM1338 -159q31 -49 31 -57q0 -5 -3 -7q-9 -5 -14.5 0.5t-15.5 26t-16 30.5q-114 172 -423 661
-q3 -1 7 1t7 4l3 2q11 9 11 17z" />
-    <glyph glyph-name="_629" unicode="&#xf29e;" horiz-adv-x="2304" 
-d="M504 542h171l-1 265zM1530 641q0 87 -50.5 140t-146.5 53h-54v-388h52q91 0 145 57t54 138zM956 1018l1 -756q0 -14 -9.5 -24t-23.5 -10h-216q-14 0 -23.5 10t-9.5 24v62h-291l-55 -81q-10 -15 -28 -15h-267q-21 0 -30.5 18t3.5 35l556 757q9 14 27 14h332q14 0 24 -10
-t10 -24zM1783 641q0 -193 -125.5 -303t-324.5 -110h-270q-14 0 -24 10t-10 24v756q0 14 10 24t24 10h268q200 0 326 -109t126 -302zM1939 640q0 -11 -0.5 -29t-8 -71.5t-21.5 -102t-44.5 -108t-73.5 -102.5h-51q38 45 66.5 104.5t41.5 112t21 98t9 72.5l1 27q0 8 -0.5 22.5
-t-7.5 60t-20 91.5t-41 111.5t-66 124.5h43q41 -47 72 -107t45.5 -111.5t23 -96t10.5 -70.5zM2123 640q0 -11 -0.5 -29t-8 -71.5t-21.5 -102t-45 -108t-74 -102.5h-51q38 45 66.5 104.5t41.5 112t21 98t9 72.5l1 27q0 8 -0.5 22.5t-7.5 60t-19.5 91.5t-40.5 111.5t-66 124.5
-h43q41 -47 72 -107t45.5 -111.5t23 -96t10.5 -70.5zM2304 640q0 -11 -0.5 -29t-8 -71.5t-21.5 -102t-44.5 -108t-73.5 -102.5h-51q38 45 66 104.5t41 112t21 98t9 72.5l1 27q0 8 -0.5 22.5t-7.5 60t-19.5 91.5t-40.5 111.5t-66 124.5h43q41 -47 72 -107t45.5 -111.5t23 -96
-t9.5 -70.5z" />
-    <glyph glyph-name="uniF2A0" unicode="&#xf2a0;" horiz-adv-x="1408" 
-d="M617 -153q0 11 -13 58t-31 107t-20 69q-1 4 -5 26.5t-8.5 36t-13.5 21.5q-15 14 -51 14q-23 0 -70 -5.5t-71 -5.5q-34 0 -47 11q-6 5 -11 15.5t-7.5 20t-6.5 24t-5 18.5q-37 128 -37 255t37 255q1 4 5 18.5t6.5 24t7.5 20t11 15.5q13 11 47 11q24 0 71 -5.5t70 -5.5
-q36 0 51 14q9 8 13.5 21.5t8.5 36t5 26.5q2 9 20 69t31 107t13 58q0 22 -43.5 52.5t-75.5 42.5q-20 8 -45 8q-34 0 -98 -18q-57 -17 -96.5 -40.5t-71 -66t-46 -70t-45.5 -94.5q-6 -12 -9 -19q-49 -107 -68 -216t-19 -244t19 -244t68 -216q56 -122 83 -161q63 -91 179 -127
-l6 -2q64 -18 98 -18q25 0 45 8q32 12 75.5 42.5t43.5 52.5zM776 760q-26 0 -45 19t-19 45.5t19 45.5q37 37 37 90q0 52 -37 91q-19 19 -19 45t19 45t45 19t45 -19q75 -75 75 -181t-75 -181q-21 -19 -45 -19zM957 579q-27 0 -45 19q-19 19 -19 45t19 45q112 114 112 272
-t-112 272q-19 19 -19 45t19 45t45 19t45 -19q150 -150 150 -362t-150 -362q-18 -19 -45 -19zM1138 398q-27 0 -45 19q-19 19 -19 45t19 45q90 91 138.5 208t48.5 245t-48.5 245t-138.5 208q-19 19 -19 45t19 45t45 19t45 -19q109 -109 167 -249t58 -294t-58 -294t-167 -249
-q-18 -19 -45 -19z" />
-    <glyph glyph-name="uniF2A1" unicode="&#xf2a1;" horiz-adv-x="2176" 
-d="M192 352q-66 0 -113 -47t-47 -113t47 -113t113 -47t113 47t47 113t-47 113t-113 47zM704 352q-66 0 -113 -47t-47 -113t47 -113t113 -47t113 47t47 113t-47 113t-113 47zM704 864q-66 0 -113 -47t-47 -113t47 -113t113 -47t113 47t47 113t-47 113t-113 47zM1472 352
-q-66 0 -113 -47t-47 -113t47 -113t113 -47t113 47t47 113t-47 113t-113 47zM1984 352q-66 0 -113 -47t-47 -113t47 -113t113 -47t113 47t47 113t-47 113t-113 47zM1472 864q-66 0 -113 -47t-47 -113t47 -113t113 -47t113 47t47 113t-47 113t-113 47zM1984 864
-q-66 0 -113 -47t-47 -113t47 -113t113 -47t113 47t47 113t-47 113t-113 47zM1984 1376q-66 0 -113 -47t-47 -113t47 -113t113 -47t113 47t47 113t-47 113t-113 47zM384 192q0 -80 -56 -136t-136 -56t-136 56t-56 136t56 136t136 56t136 -56t56 -136zM896 192q0 -80 -56 -136
-t-136 -56t-136 56t-56 136t56 136t136 56t136 -56t56 -136zM384 704q0 -80 -56 -136t-136 -56t-136 56t-56 136t56 136t136 56t136 -56t56 -136zM896 704q0 -80 -56 -136t-136 -56t-136 56t-56 136t56 136t136 56t136 -56t56 -136zM384 1216q0 -80 -56 -136t-136 -56
-t-136 56t-56 136t56 136t136 56t136 -56t56 -136zM1664 192q0 -80 -56 -136t-136 -56t-136 56t-56 136t56 136t136 56t136 -56t56 -136zM896 1216q0 -80 -56 -136t-136 -56t-136 56t-56 136t56 136t136 56t136 -56t56 -136zM2176 192q0 -80 -56 -136t-136 -56t-136 56
-t-56 136t56 136t136 56t136 -56t56 -136zM1664 704q0 -80 -56 -136t-136 -56t-136 56t-56 136t56 136t136 56t136 -56t56 -136zM2176 704q0 -80 -56 -136t-136 -56t-136 56t-56 136t56 136t136 56t136 -56t56 -136zM1664 1216q0 -80 -56 -136t-136 -56t-136 56t-56 136
-t56 136t136 56t136 -56t56 -136zM2176 1216q0 -80 -56 -136t-136 -56t-136 56t-56 136t56 136t136 56t136 -56t56 -136z" />
-    <glyph glyph-name="uniF2A2" unicode="&#xf2a2;" horiz-adv-x="1792" 
-d="M128 -192q0 -26 -19 -45t-45 -19t-45 19t-19 45t19 45t45 19t45 -19t19 -45zM320 0q0 -26 -19 -45t-45 -19t-45 19t-19 45t19 45t45 19t45 -19t19 -45zM365 365l256 -256l-90 -90l-256 256zM704 384q0 -26 -19 -45t-45 -19t-45 19t-19 45t19 45t45 19t45 -19t19 -45z
-M1411 704q0 -59 -11.5 -108.5t-37.5 -93.5t-44 -67.5t-53 -64.5q-31 -35 -45.5 -54t-33.5 -50t-26.5 -64t-7.5 -74q0 -159 -112.5 -271.5t-271.5 -112.5q-26 0 -45 19t-19 45t19 45t45 19q106 0 181 75t75 181q0 57 11.5 105.5t37 91t43.5 66.5t52 63q40 46 59.5 72
-t37.5 74.5t18 103.5q0 185 -131.5 316.5t-316.5 131.5t-316.5 -131.5t-131.5 -316.5q0 -26 -19 -45t-45 -19t-45 19t-19 45q0 117 45.5 223.5t123 184t184 123t223.5 45.5t223.5 -45.5t184 -123t123 -184t45.5 -223.5zM896 576q0 -26 -19 -45t-45 -19t-45 19t-19 45t19 45
-t45 19t45 -19t19 -45zM1184 704q0 -26 -19 -45t-45 -19t-45 19t-19 45q0 93 -65.5 158.5t-158.5 65.5q-92 0 -158 -65.5t-66 -158.5q0 -26 -19 -45t-45 -19t-45 19t-19 45q0 146 103 249t249 103t249 -103t103 -249zM1578 993q10 -25 -1 -49t-36 -34q-9 -4 -23 -4
-q-19 0 -35.5 11t-23.5 30q-68 178 -224 295q-21 16 -25 42t12 47q17 21 43 25t47 -12q183 -137 266 -351zM1788 1074q9 -25 -1.5 -49t-35.5 -34q-11 -4 -23 -4q-44 0 -60 41q-92 238 -297 393q-22 16 -25.5 42t12.5 47q16 22 42 25.5t47 -12.5q235 -175 341 -449z" />
-    <glyph glyph-name="uniF2A3" unicode="&#xf2a3;" horiz-adv-x="2304" 
-d="M1032 576q-59 2 -84 55q-17 34 -48 53.5t-68 19.5q-53 0 -90.5 -37.5t-37.5 -90.5q0 -56 36 -89l10 -8q34 -31 82 -31q37 0 68 19.5t48 53.5q25 53 84 55zM1600 704q0 56 -36 89l-10 8q-34 31 -82 31q-37 0 -68 -19.5t-48 -53.5q-25 -53 -84 -55q59 -2 84 -55
-q17 -34 48 -53.5t68 -19.5q53 0 90.5 37.5t37.5 90.5zM1174 925q-17 -35 -55 -48t-73 4q-62 31 -134 31q-51 0 -99 -17q3 0 9.5 0.5t9.5 0.5q92 0 170.5 -50t118.5 -133q17 -36 3.5 -73.5t-49.5 -54.5q-18 -9 -39 -9q21 0 39 -9q36 -17 49.5 -54.5t-3.5 -73.5
-q-40 -83 -118.5 -133t-170.5 -50h-6q-16 2 -44 4l-290 27l-239 -120q-14 -7 -29 -7q-40 0 -57 35l-160 320q-11 23 -4 47.5t29 37.5l209 119l148 267q17 155 91.5 291.5t195.5 236.5q31 25 70.5 21.5t64.5 -34.5t21.5 -70t-34.5 -65q-70 -59 -117 -128q123 84 267 101
-q40 5 71.5 -19t35.5 -64q5 -40 -19 -71.5t-64 -35.5q-84 -10 -159 -55q46 10 99 10q115 0 218 -50q36 -18 49 -55.5t-5 -73.5zM2137 1085l160 -320q11 -23 4 -47.5t-29 -37.5l-209 -119l-148 -267q-17 -155 -91.5 -291.5t-195.5 -236.5q-26 -22 -61 -22q-45 0 -74 35
-q-25 31 -21.5 70t34.5 65q70 59 117 128q-123 -84 -267 -101q-4 -1 -12 -1q-36 0 -63.5 24t-31.5 60q-5 40 19 71.5t64 35.5q84 10 159 55q-46 -10 -99 -10q-115 0 -218 50q-36 18 -49 55.5t5 73.5q17 35 55 48t73 -4q62 -31 134 -31q51 0 99 17q-3 0 -9.5 -0.5t-9.5 -0.5
-q-92 0 -170.5 50t-118.5 133q-17 36 -3.5 73.5t49.5 54.5q18 9 39 9q-21 0 -39 9q-36 17 -49.5 54.5t3.5 73.5q40 83 118.5 133t170.5 50h6h1q14 -2 42 -4l291 -27l239 120q14 7 29 7q40 0 57 -35z" />
-    <glyph glyph-name="uniF2A4" unicode="&#xf2a4;" horiz-adv-x="1792" 
-d="M1056 704q0 -26 19 -45t45 -19t45 19t19 45q0 146 -103 249t-249 103t-249 -103t-103 -249q0 -26 19 -45t45 -19t45 19t19 45q0 93 66 158.5t158 65.5t158 -65.5t66 -158.5zM835 1280q-117 0 -223.5 -45.5t-184 -123t-123 -184t-45.5 -223.5q0 -26 19 -45t45 -19t45 19
-t19 45q0 185 131.5 316.5t316.5 131.5t316.5 -131.5t131.5 -316.5q0 -55 -18 -103.5t-37.5 -74.5t-59.5 -72q-34 -39 -52 -63t-43.5 -66.5t-37 -91t-11.5 -105.5q0 -106 -75 -181t-181 -75q-26 0 -45 -19t-19 -45t19 -45t45 -19q159 0 271.5 112.5t112.5 271.5q0 41 7.5 74
-t26.5 64t33.5 50t45.5 54q35 41 53 64.5t44 67.5t37.5 93.5t11.5 108.5q0 117 -45.5 223.5t-123 184t-184 123t-223.5 45.5zM591 561l226 -226l-579 -579q-12 -12 -29 -12t-29 12l-168 168q-12 12 -12 29t12 29zM1612 1524l168 -168q12 -12 12 -29t-12 -30l-233 -233
-l-26 -25l-71 -71q-66 153 -195 258l91 91l207 207q13 12 30 12t29 -12z" />
-    <glyph glyph-name="uniF2A5" unicode="&#xf2a5;" 
-d="M866 1021q0 -27 -13 -94q-11 -50 -31.5 -150t-30.5 -150q-2 -11 -4.5 -12.5t-13.5 -2.5q-20 -2 -31 -2q-58 0 -84 49.5t-26 113.5q0 88 35 174t103 124q28 14 51 14q28 0 36.5 -16.5t8.5 -47.5zM1352 597q0 14 -39 75.5t-52 66.5q-21 8 -34 8q-91 0 -226 -77l-2 2
-q3 22 27.5 135t24.5 178q0 233 -242 233q-24 0 -68 -6q-94 -17 -168.5 -89.5t-111.5 -166.5t-37 -189q0 -146 80.5 -225t227.5 -79q25 0 25 -3t-1 -5q-4 -34 -26 -117q-14 -52 -51.5 -101t-82.5 -49q-42 0 -42 47q0 24 10.5 47.5t25 39.5t29.5 28.5t26 20t11 8.5q0 3 -7 10
-q-24 22 -58.5 36.5t-65.5 14.5q-35 0 -63.5 -34t-41 -75t-12.5 -75q0 -88 51.5 -142t138.5 -54q82 0 155 53t117.5 126t65.5 153q6 22 15.5 66.5t14.5 66.5q3 12 14 18q118 60 227 60q48 0 127 -18q1 -1 4 -1q5 0 9.5 4.5t4.5 8.5zM1536 1120v-960q0 -119 -84.5 -203.5
-t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
-    <glyph glyph-name="uniF2A6" unicode="&#xf2a6;" horiz-adv-x="1535" 
-d="M744 1231q0 24 -2 38.5t-8.5 30t-21 23t-37.5 7.5q-39 0 -78 -23q-105 -58 -159 -190.5t-54 -269.5q0 -44 8.5 -85.5t26.5 -80.5t52.5 -62.5t81.5 -23.5q4 0 18 -0.5t20 0t16 3t15 8.5t7 16q16 77 48 231.5t48 231.5q19 91 19 146zM1498 575q0 -7 -7.5 -13.5t-15.5 -6.5
-l-6 1q-22 3 -62 11t-72 12.5t-63 4.5q-167 0 -351 -93q-15 -8 -21 -27q-10 -36 -24.5 -105.5t-22.5 -100.5q-23 -91 -70 -179.5t-112.5 -164.5t-154.5 -123t-185 -47q-135 0 -214.5 83.5t-79.5 219.5q0 53 19.5 117t63 116.5t97.5 52.5q38 0 120 -33.5t83 -61.5
-q0 -1 -16.5 -12.5t-39.5 -31t-46 -44.5t-39 -61t-16 -74q0 -33 16.5 -53t48.5 -20q45 0 85 31.5t66.5 78t48 105.5t32.5 107t16 90v9q0 2 -3.5 3.5t-8.5 1.5h-10t-10 -0.5t-6 -0.5q-227 0 -352 122.5t-125 348.5q0 108 34.5 221t96 210t156 167.5t204.5 89.5q52 9 106 9
-q374 0 374 -360q0 -98 -38 -273t-43 -211l3 -3q101 57 182.5 88t167.5 31q22 0 53 -13q19 -7 80 -102.5t61 -116.5z" />
-    <glyph glyph-name="uniF2A7" unicode="&#xf2a7;" horiz-adv-x="1664" 
-d="M831 863q32 0 59 -18l222 -148q61 -40 110 -97l146 -170q40 -46 29 -106l-72 -413q-6 -32 -29.5 -53.5t-55.5 -25.5l-527 -56l-352 -32h-9q-39 0 -67.5 28t-28.5 68q0 37 27 64t65 32l260 32h-448q-41 0 -69.5 30t-26.5 71q2 39 32 65t69 26l442 1l-521 64q-41 5 -66 37
-t-19 73q6 35 34.5 57.5t65.5 22.5h10l481 -60l-351 94q-38 10 -62 41.5t-18 68.5q6 36 33 58.5t62 22.5q6 0 20 -2l448 -96l217 -37q1 0 3 -0.5t3 -0.5q23 0 30.5 23t-12.5 36l-186 125q-35 23 -42 63.5t18 73.5q27 38 76 38zM761 661l186 -125l-218 37l-5 2l-36 38
-l-238 262q-1 1 -2.5 3.5t-2.5 3.5q-24 31 -18.5 70t37.5 64q31 23 68 17.5t64 -33.5l142 -147q-2 -1 -5 -3.5t-4 -4.5q-32 -45 -23 -99t55 -85zM1648 1115l15 -266q4 -73 -11 -147l-48 -219q-12 -59 -67 -87l-106 -54q2 62 -39 109l-146 170q-53 61 -117 103l-222 148
-q-34 23 -76 23q-51 0 -88 -37l-235 312q-25 33 -18 73.5t41 63.5q33 22 71.5 14t62.5 -40l266 -352l-262 455q-21 35 -10.5 75t47.5 59q35 18 72.5 6t57.5 -46l241 -420l-136 337q-15 35 -4.5 74t44.5 56q37 19 76 6t56 -51l193 -415l101 -196q8 -15 23 -17.5t27 7.5t11 26
-l-12 224q-2 41 26 71t69 31q39 0 67 -28.5t30 -67.5z" />
-    <glyph glyph-name="uniF2A8" unicode="&#xf2a8;" horiz-adv-x="1792" 
-d="M335 180q-2 0 -6 2q-86 57 -168.5 145t-139.5 180q-21 30 -21 69q0 9 2 19t4 18t7 18t8.5 16t10.5 17t10 15t12 15.5t11 14.5q184 251 452 365q-110 198 -110 211q0 19 17 29q116 64 128 64q18 0 28 -16l124 -229q92 19 192 19q266 0 497.5 -137.5t378.5 -369.5
-q20 -31 20 -69t-20 -69q-91 -142 -218.5 -253.5t-278.5 -175.5q110 -198 110 -211q0 -20 -17 -29q-116 -64 -127 -64q-19 0 -29 16l-124 229l-64 119l-444 820l7 7q-58 -24 -99 -47q3 -5 127 -234t243 -449t119 -223q0 -7 -9 -9q-13 -3 -72 -3q-57 0 -60 7l-456 841
-q-39 -28 -82 -68q24 -43 214 -393.5t190 -354.5q0 -10 -11 -10q-14 0 -82.5 22t-72.5 28l-106 197l-224 413q-44 -53 -78 -106q2 -3 18 -25t23 -34l176 -327q0 -10 -10 -10zM1165 282l49 -91q273 111 450 385q-180 277 -459 389q67 -64 103 -148.5t36 -176.5
-q0 -106 -47 -200.5t-132 -157.5zM848 896q0 -20 14 -34t34 -14q86 0 147 -61t61 -147q0 -20 14 -34t34 -14t34 14t14 34q0 126 -89 215t-215 89q-20 0 -34 -14t-14 -34zM1214 961l-9 4l7 -7z" />
-    <glyph glyph-name="uniF2A9" unicode="&#xf2a9;" horiz-adv-x="1280" 
-d="M1050 430q0 -215 -147 -374q-148 -161 -378 -161q-232 0 -378 161q-147 159 -147 374q0 147 68 270.5t189 196.5t268 73q96 0 182 -31q-32 -62 -39 -126q-66 28 -143 28q-167 0 -280.5 -123t-113.5 -291q0 -170 112.5 -288.5t281.5 -118.5t281 118.5t112 288.5
-q0 89 -32 166q66 13 123 49q41 -98 41 -212zM846 619q0 -192 -79.5 -345t-238.5 -253l-14 -1q-29 0 -62 5q83 32 146.5 102.5t99.5 154.5t58.5 189t30 192.5t7.5 178.5q0 69 -3 103q55 -160 55 -326zM791 947v-2q-73 214 -206 440q88 -59 142.5 -186.5t63.5 -251.5z
-M1035 744q-83 0 -160 75q218 120 290 247q19 37 21 56q-42 -94 -139.5 -166.5t-204.5 -97.5q-35 54 -35 113q0 37 17 79t43 68q46 44 157 74q59 16 106 58.5t74 100.5q74 -105 74 -253q0 -109 -24 -170q-32 -77 -88.5 -130.5t-130.5 -53.5z" />
-    <glyph glyph-name="uniF2AA" unicode="&#xf2aa;" 
-d="M1050 495q0 78 -28 147q-41 -25 -85 -34q22 -50 22 -114q0 -117 -77 -198.5t-193 -81.5t-193.5 81.5t-77.5 198.5q0 115 78 199.5t193 84.5q53 0 98 -19q4 43 27 87q-60 21 -125 21q-154 0 -257.5 -108.5t-103.5 -263.5t103.5 -261t257.5 -106t257.5 106.5t103.5 260.5z
-M872 850q2 -24 2 -71q0 -63 -5 -123t-20.5 -132.5t-40.5 -130t-68.5 -106t-100.5 -70.5q21 -3 42 -3h10q219 139 219 411q0 116 -38 225zM872 850q-4 80 -44 171.5t-98 130.5q92 -156 142 -302zM1207 955q0 102 -51 174q-41 -86 -124 -109q-69 -19 -109 -53.5t-40 -99.5
-q0 -40 24 -77q74 17 140.5 67t95.5 115q-4 -52 -74.5 -111.5t-138.5 -97.5q52 -52 110 -52q51 0 90 37t60 90q17 42 17 117zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5
-t84.5 -203.5z" />
-    <glyph glyph-name="uniF2AB" unicode="&#xf2ab;" 
-d="M1279 388q0 22 -22 27q-67 15 -118 59t-80 108q-7 19 -7 25q0 15 19.5 26t43 17t43 20.5t19.5 36.5q0 19 -18.5 31.5t-38.5 12.5q-12 0 -32 -8t-31 -8q-4 0 -12 2q5 95 5 114q0 79 -17 114q-36 78 -103 121.5t-152 43.5q-199 0 -275 -165q-17 -35 -17 -114q0 -19 5 -114
-q-4 -2 -14 -2q-12 0 -32 7.5t-30 7.5q-21 0 -38.5 -12t-17.5 -32q0 -21 19.5 -35.5t43 -20.5t43 -17t19.5 -26q0 -6 -7 -25q-64 -138 -198 -167q-22 -5 -22 -27q0 -46 137 -68q2 -5 6 -26t11.5 -30.5t23.5 -9.5q12 0 37.5 4.5t39.5 4.5q35 0 67 -15t54 -32.5t57.5 -32.5
-t76.5 -15q43 0 79 15t57.5 32.5t53.5 32.5t67 15q14 0 39.5 -4t38.5 -4q16 0 23 10t11 30t6 25q137 22 137 68zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5
-t103 -385.5z" />
-    <glyph glyph-name="uniF2AC" unicode="&#xf2ac;" horiz-adv-x="1664" 
-d="M848 1408q134 1 240.5 -68.5t163.5 -192.5q27 -58 27 -179q0 -47 -9 -191q14 -7 28 -7q18 0 51 13.5t51 13.5q29 0 56 -18t27 -46q0 -32 -31.5 -54t-69 -31.5t-69 -29t-31.5 -47.5q0 -15 12 -43q37 -82 102.5 -150t144.5 -101q28 -12 80 -23q28 -6 28 -35
-q0 -70 -219 -103q-7 -11 -11 -39t-14 -46.5t-33 -18.5q-20 0 -62 6.5t-64 6.5q-37 0 -62 -5q-32 -5 -63 -22.5t-58 -38t-58 -40.5t-76 -33.5t-99 -13.5q-52 0 -96.5 13.5t-75 33.5t-57.5 40.5t-58 38t-62 22.5q-26 5 -63 5q-24 0 -65.5 -7.5t-58.5 -7.5q-25 0 -35 18.5
-t-14 47.5t-11 40q-219 33 -219 103q0 29 28 35q52 11 80 23q78 32 144.5 101t102.5 150q12 28 12 43q0 28 -31.5 47.5t-69.5 29.5t-69.5 31.5t-31.5 52.5q0 27 26 45.5t55 18.5q15 0 48 -13t53 -13q18 0 32 7q-9 142 -9 190q0 122 27 180q64 137 172 198t264 63z" />
-    <glyph glyph-name="uniF2AD" unicode="&#xf2ad;" 
-d="M1280 388q0 22 -22 27q-67 14 -118 58t-80 109q-7 14 -7 25q0 15 19.5 26t42.5 17t42.5 20.5t19.5 36.5q0 19 -18.5 31.5t-38.5 12.5q-11 0 -31 -8t-32 -8q-4 0 -12 2q5 63 5 115q0 78 -17 114q-36 78 -102.5 121.5t-152.5 43.5q-198 0 -275 -165q-18 -38 -18 -115
-q0 -38 6 -114q-10 -2 -15 -2q-11 0 -31.5 8t-30.5 8q-20 0 -37.5 -12.5t-17.5 -32.5q0 -21 19.5 -35.5t42.5 -20.5t42.5 -17t19.5 -26q0 -11 -7 -25q-64 -138 -198 -167q-22 -5 -22 -27q0 -47 138 -69q2 -5 6 -26t11 -30.5t23 -9.5q13 0 38.5 5t38.5 5q35 0 67.5 -15
-t54.5 -32.5t57.5 -32.5t76.5 -15q43 0 79 15t57.5 32.5t54 32.5t67.5 15q13 0 39 -4.5t39 -4.5q15 0 22.5 9.5t11.5 31t5 24.5q138 22 138 69zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960
-q119 0 203.5 -84.5t84.5 -203.5z" />
-    <glyph glyph-name="uniF2AE" unicode="&#xf2ae;" horiz-adv-x="2304" 
-d="M2304 1536q-69 -46 -125 -92t-89 -81t-59.5 -71.5t-37.5 -57.5t-22 -44.5t-14 -29.5q-10 -18 -35.5 -136.5t-48.5 -164.5q-15 -29 -50 -60.5t-67.5 -50.5t-72.5 -41t-48 -28q-47 -31 -151 -231q-341 14 -630 -158q-92 -53 -303 -179q47 16 86 31t55 22l15 7
-q71 27 163 64.5t133.5 53.5t108 34.5t142.5 31.5q186 31 465 -7q1 0 10 -3q11 -6 14 -17t-3 -22l-194 -345q-15 -29 -47 -22q-128 24 -354 24q-146 0 -402 -44.5t-392 -46.5q-82 -1 -149 13t-107 37t-61 40t-33 34l-1 1v2q0 6 6 6q138 0 371 55q192 366 374.5 524t383.5 158
-q5 0 14.5 -0.5t38 -5t55 -12t61.5 -24.5t63 -39.5t54 -59t40 -82.5l102 177q2 4 21 42.5t44.5 86.5t61 109.5t84 133.5t100.5 137q66 82 128 141.5t121.5 96.5t92.5 53.5t88 39.5z" />
-    <glyph glyph-name="uniF2B0" unicode="&#xf2b0;" 
-d="M1322 640q0 -45 -5 -76l-236 14l224 -78q-19 -73 -58 -141l-214 103l177 -158q-44 -61 -107 -108l-157 178l103 -215q-61 -37 -140 -59l-79 228l14 -240q-38 -6 -76 -6t-76 6l14 238l-78 -226q-74 19 -140 59l103 215l-157 -178q-59 43 -108 108l178 158l-214 -104
-q-39 69 -58 141l224 79l-237 -14q-5 42 -5 76q0 35 5 77l238 -14l-225 79q19 73 58 140l214 -104l-177 159q46 61 107 108l158 -178l-103 215q67 39 140 58l77 -224l-13 236q36 6 75 6q38 0 76 -6l-14 -237l78 225q74 -19 140 -59l-103 -214l158 178q61 -47 107 -108
-l-177 -159l213 104q37 -62 58 -141l-224 -78l237 14q5 -31 5 -77zM1352 640q0 160 -78.5 295.5t-213 214t-292.5 78.5q-119 0 -227 -46.5t-186.5 -125t-124.5 -187.5t-46 -229q0 -119 46 -228t124.5 -187.5t186.5 -125t227 -46.5q158 0 292.5 78.5t213 214t78.5 294.5z
-M1425 1023v-766l-657 -383l-657 383v766l657 383zM768 -183l708 412v823l-708 411l-708 -411v-823zM1536 1088v-896l-768 -448l-768 448v896l768 448z" />
-    <glyph glyph-name="uniF2B1" unicode="&#xf2b1;" horiz-adv-x="1664" 
-d="M339 1318h691l-26 -72h-665q-110 0 -188.5 -79t-78.5 -189v-771q0 -95 60.5 -169.5t153.5 -93.5q23 -5 98 -5v-72h-45q-140 0 -239.5 100t-99.5 240v771q0 140 99.5 240t239.5 100zM1190 1536h247l-482 -1294q-23 -61 -40.5 -103.5t-45 -98t-54 -93.5t-64.5 -78.5
-t-79.5 -65t-95.5 -41t-116 -18.5v195q163 26 220 182q20 52 20 105q0 54 -20 106l-285 733h228l187 -585zM1664 978v-1111h-795q37 55 45 73h678v1038q0 85 -49.5 155t-129.5 99l25 67q101 -34 163.5 -123.5t62.5 -197.5z" />
-    <glyph glyph-name="uniF2B2" unicode="&#xf2b2;" horiz-adv-x="1792" 
-d="M852 1227q0 -29 -17 -52.5t-45 -23.5t-45 23.5t-17 52.5t17 52.5t45 23.5t45 -23.5t17 -52.5zM688 -149v114q0 30 -20.5 51.5t-50.5 21.5t-50 -21.5t-20 -51.5v-114q0 -30 20.5 -52t49.5 -22q30 0 50.5 22t20.5 52zM860 -149v114q0 30 -20 51.5t-50 21.5t-50.5 -21.5
-t-20.5 -51.5v-114q0 -30 20.5 -52t50.5 -22q29 0 49.5 22t20.5 52zM1034 -149v114q0 30 -20.5 51.5t-50.5 21.5t-50.5 -21.5t-20.5 -51.5v-114q0 -30 20.5 -52t50.5 -22t50.5 22t20.5 52zM1208 -149v114q0 30 -20.5 51.5t-50.5 21.5t-50.5 -21.5t-20.5 -51.5v-114
-q0 -30 20.5 -52t50.5 -22t50.5 22t20.5 52zM1476 535q-84 -160 -232 -259.5t-323 -99.5q-123 0 -229.5 51.5t-178.5 137t-113 197.5t-41 232q0 88 21 174q-104 -175 -104 -390q0 -162 65 -312t185 -251q30 57 91 57q56 0 86 -50q32 50 87 50q56 0 86 -50q32 50 87 50t87 -50
-q30 50 86 50q28 0 52.5 -15.5t37.5 -40.5q112 94 177 231.5t73 287.5zM1326 564q0 75 -72 75q-17 0 -47 -6q-95 -19 -149 -19q-226 0 -226 243q0 86 30 204q-83 -127 -83 -275q0 -150 89 -260.5t235 -110.5q111 0 210 70q13 48 13 79zM884 1223q0 50 -32 89.5t-81 39.5
-t-81 -39.5t-32 -89.5q0 -51 31.5 -90.5t81.5 -39.5t81.5 39.5t31.5 90.5zM1513 884q0 96 -37.5 179t-113 137t-173.5 54q-77 0 -149 -35t-127 -94q-48 -159 -48 -268q0 -104 45.5 -157t147.5 -53q53 0 142 19q36 6 53 6q51 0 77.5 -28t26.5 -80q0 -26 -4 -46
-q75 68 117.5 165.5t42.5 200.5zM1792 667q0 -111 -33.5 -249.5t-93.5 -204.5q-58 -64 -195 -142.5t-228 -104.5l-4 -1v-114q0 -43 -29.5 -75t-72.5 -32q-56 0 -86 50q-32 -50 -87 -50t-87 50q-30 -50 -86 -50q-55 0 -87 50q-30 -50 -86 -50q-47 0 -75 33.5t-28 81.5
-q-90 -68 -198 -68q-118 0 -211 80q54 1 106 20q-113 31 -182 127q32 -7 71 -7q89 0 164 46q-192 192 -240 306q-24 56 -24 160q0 57 9 125.5t31.5 146.5t55 141t86.5 105t120 42q59 0 81 -52q19 29 42 54q2 3 12 13t13 16q10 15 23 38t25 42t28 39q87 111 211.5 177
-t260.5 66q35 0 62 -4q59 64 146 64q83 0 140 -57q5 -5 5 -12q0 -5 -6 -13.5t-12.5 -16t-16 -17l-10.5 -10.5q17 -6 36 -18t19 -24q0 -6 -16 -25q157 -138 197 -378q25 30 60 30q45 0 100 -49q90 -80 90 -279z" />
-    <glyph glyph-name="uniF2B3" unicode="&#xf2b3;" 
-d="M917 631q0 33 -6 64h-362v-132h217q-12 -76 -74.5 -120.5t-142.5 -44.5q-99 0 -169 71.5t-70 170.5t70 170.5t169 71.5q93 0 153 -59l104 101q-108 100 -257 100q-160 0 -272 -112.5t-112 -271.5t112 -271.5t272 -112.5q165 0 266.5 105t101.5 270zM1262 585h109v110
-h-109v110h-110v-110h-110v-110h110v-110h110v110zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
-    <glyph glyph-name="uniF2B4" unicode="&#xf2b4;" 
-d="M1536 1024v-839q0 -48 -49 -62q-174 -52 -338 -52q-73 0 -215.5 29.5t-227.5 29.5q-164 0 -370 -48v-338h-160v1368q-63 25 -101 81t-38 124q0 91 64 155t155 64t155 -64t64 -155q0 -68 -38 -124t-101 -81v-68q190 44 343 44q99 0 198 -15q14 -2 111.5 -22.5t149.5 -20.5
-q77 0 165 18q11 2 80 21t89 19q26 0 45 -19t19 -45z" />
-    <glyph glyph-name="uniF2B5" unicode="&#xf2b5;" horiz-adv-x="2304" 
-d="M192 384q40 0 56 32t0 64t-56 32t-56 -32t0 -64t56 -32zM1665 442q-10 13 -38.5 50t-41.5 54t-38 49t-42.5 53t-40.5 47t-45 49l-125 -140q-83 -94 -208.5 -92t-205.5 98q-57 69 -56.5 158t58.5 157l177 206q-22 11 -51 16.5t-47.5 6t-56.5 -0.5t-49 -1q-92 0 -158 -66
-l-158 -158h-155v-544q5 0 21 0.5t22 0t19.5 -2t20.5 -4.5t17.5 -8.5t18.5 -13.5l297 -292q115 -111 227 -111q78 0 125 47q57 -20 112.5 8t72.5 85q74 -6 127 44q20 18 36 45.5t14 50.5q10 -10 43 -10q43 0 77 21t49.5 53t12 71.5t-30.5 73.5zM1824 384h96v512h-93l-157 180
-q-66 76 -169 76h-167q-89 0 -146 -67l-209 -243q-28 -33 -28 -75t27 -75q43 -51 110 -52t111 49l193 218q25 23 53.5 21.5t47 -27t8.5 -56.5q16 -19 56 -63t60 -68q29 -36 82.5 -105.5t64.5 -84.5q52 -66 60 -140zM2112 384q40 0 56 32t0 64t-56 32t-56 -32t0 -64t56 -32z
-M2304 960v-640q0 -26 -19 -45t-45 -19h-434q-27 -65 -82 -106.5t-125 -51.5q-33 -48 -80.5 -81.5t-102.5 -45.5q-42 -53 -104.5 -81.5t-128.5 -24.5q-60 -34 -126 -39.5t-127.5 14t-117 53.5t-103.5 81l-287 282h-358q-26 0 -45 19t-19 45v672q0 26 19 45t45 19h421
-q14 14 47 48t47.5 48t44 40t50.5 37.5t51 25.5t62 19.5t68 5.5h117q99 0 181 -56q82 56 181 56h167q35 0 67 -6t56.5 -14.5t51.5 -26.5t44.5 -31t43 -39.5t39 -42t41 -48t41.5 -48.5h355q26 0 45 -19t19 -45z" />
-    <glyph glyph-name="uniF2B6" unicode="&#xf2b6;" horiz-adv-x="1792" 
-d="M1792 882v-978q0 -66 -47 -113t-113 -47h-1472q-66 0 -113 47t-47 113v978q0 15 11 24q8 7 39 34.5t41.5 36t45.5 37.5t70 55.5t96 73t143.5 107t192.5 140.5q5 4 52.5 40t71.5 52.5t64 35t69 18.5t69 -18.5t65 -35.5t71 -52t52 -40q110 -80 192.5 -140.5t143.5 -107
-t96 -73t70 -55.5t45.5 -37.5t41.5 -36t39 -34.5q11 -9 11 -24zM1228 297q263 191 345 252q11 8 12.5 20.5t-6.5 23.5l-38 52q-8 11 -21 12.5t-24 -6.5q-231 -169 -343 -250q-5 -3 -52 -39t-71.5 -52.5t-64.5 -35t-69 -18.5t-69 18.5t-64.5 35t-71.5 52.5t-52 39
-q-186 134 -343 250q-11 8 -24 6.5t-21 -12.5l-38 -52q-8 -11 -6.5 -23.5t12.5 -20.5q82 -61 345 -252q10 -8 50 -38t65 -47t64 -39.5t77.5 -33.5t75.5 -11t75.5 11t79 34.5t64.5 39.5t65 47.5t48 36.5z" />
-    <glyph glyph-name="uniF2B7" unicode="&#xf2b7;" horiz-adv-x="1792" 
-d="M1474 623l39 -51q8 -11 6.5 -23.5t-11.5 -20.5q-43 -34 -126.5 -98.5t-146.5 -113t-67 -51.5q-39 -32 -60 -48t-60.5 -41t-76.5 -36.5t-74 -11.5h-1h-1q-37 0 -74 11.5t-76 36.5t-61 41.5t-60 47.5q-5 4 -65 50.5t-143.5 111t-122.5 94.5q-11 8 -12.5 20.5t6.5 23.5
-l37 52q8 11 21.5 13t24.5 -7q94 -73 306 -236q5 -4 43.5 -35t60.5 -46.5t56.5 -32.5t58.5 -17h1h1q24 0 58.5 17t56.5 32.5t60.5 46.5t43.5 35q258 198 313 242q11 8 24 6.5t21 -12.5zM1664 -96v928q-90 83 -159 139q-91 74 -389 304q-3 2 -43 35t-61 48t-56 32.5t-59 17.5
-h-1h-1q-24 0 -59 -17.5t-56 -32.5t-61 -48t-43 -35q-215 -166 -315.5 -245.5t-129.5 -104t-82 -74.5q-14 -12 -21 -19v-928q0 -13 9.5 -22.5t22.5 -9.5h1472q13 0 22.5 9.5t9.5 22.5zM1792 832v-928q0 -66 -47 -113t-113 -47h-1472q-66 0 -113 47t-47 113v928q0 56 41 94
-q123 114 350 290.5t233 181.5q36 30 59 47.5t61.5 42t76 36.5t74.5 12h1h1q37 0 74.5 -12t76 -36.5t61.5 -42t59 -47.5q43 -36 156 -122t226 -177t201 -173q41 -38 41 -94z" />
-    <glyph glyph-name="uniF2B8" unicode="&#xf2b8;" 
-d="M330 1l202 -214l-34 236l-216 213zM556 -225l274 218l-11 245l-300 -215zM245 413l227 -213l-48 327l-245 204zM495 189l317 214l-14 324l-352 -200zM843 178l95 -80l-2 239l-103 79q0 -1 1 -8.5t0 -12t-5 -7.5l-78 -52l85 -70q7 -6 7 -88zM138 930l256 -200l-68 465
-l-279 173zM1173 267l15 234l-230 -164l2 -240zM417 722l373 194l-19 441l-423 -163zM1270 357l20 233l-226 142l-2 -105l144 -95q6 -4 4 -9l-7 -119zM1461 496l30 222l-179 -128l-20 -228zM1273 329l-71 49l-8 -117q0 -5 -4 -8l-234 -187q-7 -5 -14 0l-98 83l7 -161
-q0 -5 -4 -8l-293 -234q-4 -2 -6 -2q-8 2 -8 3l-228 242q-4 4 -59 277q-2 7 5 11l61 37q-94 86 -95 92l-72 351q-2 7 6 12l94 45q-133 100 -135 108l-96 466q-2 10 7 13l433 135q5 0 8 -1l317 -153q6 -4 6 -9l20 -463q0 -7 -6 -10l-118 -61l126 -85q5 -2 5 -8l5 -123l121 74
-q5 4 11 0l84 -56l3 110q0 6 5 9l206 126q6 3 11 0l245 -135q4 -4 5 -7t-6.5 -60t-17.5 -124.5t-10 -70.5q0 -5 -4 -7l-191 -153q-6 -5 -13 0z" />
-    <glyph glyph-name="uniF2B9" unicode="&#xf2b9;" horiz-adv-x="1664" 
-d="M1201 298q0 57 -5.5 107t-21 100.5t-39.5 86t-64 58t-91 22.5q-6 -4 -33.5 -20.5t-42.5 -24.5t-40.5 -20t-49 -17t-46.5 -5t-46.5 5t-49 17t-40.5 20t-42.5 24.5t-33.5 20.5q-51 0 -91 -22.5t-64 -58t-39.5 -86t-21 -100.5t-5.5 -107q0 -73 42 -121.5t103 -48.5h576
-q61 0 103 48.5t42 121.5zM1028 892q0 108 -76.5 184t-183.5 76t-183.5 -76t-76.5 -184q0 -107 76.5 -183t183.5 -76t183.5 76t76.5 183zM1664 352v-192q0 -14 -9 -23t-23 -9h-96v-224q0 -66 -47 -113t-113 -47h-1216q-66 0 -113 47t-47 113v1472q0 66 47 113t113 47h1216
-q66 0 113 -47t47 -113v-224h96q14 0 23 -9t9 -23v-192q0 -14 -9 -23t-23 -9h-96v-128h96q14 0 23 -9t9 -23v-192q0 -14 -9 -23t-23 -9h-96v-128h96q14 0 23 -9t9 -23z" />
-    <glyph glyph-name="uniF2BA" unicode="&#xf2ba;" horiz-adv-x="1664" 
-d="M1028 892q0 -107 -76.5 -183t-183.5 -76t-183.5 76t-76.5 183q0 108 76.5 184t183.5 76t183.5 -76t76.5 -184zM980 672q46 0 82.5 -17t60 -47.5t39.5 -67t24 -81t11.5 -82.5t3.5 -79q0 -67 -39.5 -118.5t-105.5 -51.5h-576q-66 0 -105.5 51.5t-39.5 118.5q0 48 4.5 93.5
-t18.5 98.5t36.5 91.5t63 64.5t93.5 26h5q7 -4 32 -19.5t35.5 -21t33 -17t37 -16t35 -9t39.5 -4.5t39.5 4.5t35 9t37 16t33 17t35.5 21t32 19.5zM1664 928q0 -13 -9.5 -22.5t-22.5 -9.5h-96v-128h96q13 0 22.5 -9.5t9.5 -22.5v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-96v-128h96
-q13 0 22.5 -9.5t9.5 -22.5v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-96v-224q0 -66 -47 -113t-113 -47h-1216q-66 0 -113 47t-47 113v1472q0 66 47 113t113 47h1216q66 0 113 -47t47 -113v-224h96q13 0 22.5 -9.5t9.5 -22.5v-192zM1408 -96v1472q0 13 -9.5 22.5t-22.5 9.5h-1216
-q-13 0 -22.5 -9.5t-9.5 -22.5v-1472q0 -13 9.5 -22.5t22.5 -9.5h1216q13 0 22.5 9.5t9.5 22.5z" />
-    <glyph glyph-name="uniF2BB" unicode="&#xf2bb;" horiz-adv-x="2048" 
-d="M1024 405q0 64 -9 117.5t-29.5 103t-60.5 78t-97 28.5q-6 -4 -30 -18t-37.5 -21.5t-35.5 -17.5t-43 -14.5t-42 -4.5t-42 4.5t-43 14.5t-35.5 17.5t-37.5 21.5t-30 18q-57 0 -97 -28.5t-60.5 -78t-29.5 -103t-9 -117.5t37 -106.5t91 -42.5h512q54 0 91 42.5t37 106.5z
-M867 925q0 94 -66.5 160.5t-160.5 66.5t-160.5 -66.5t-66.5 -160.5t66.5 -160.5t160.5 -66.5t160.5 66.5t66.5 160.5zM1792 416v64q0 14 -9 23t-23 9h-576q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h576q14 0 23 9t9 23zM1792 676v56q0 15 -10.5 25.5t-25.5 10.5h-568
-q-15 0 -25.5 -10.5t-10.5 -25.5v-56q0 -15 10.5 -25.5t25.5 -10.5h568q15 0 25.5 10.5t10.5 25.5zM1792 928v64q0 14 -9 23t-23 9h-576q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h576q14 0 23 9t9 23zM2048 1248v-1216q0 -66 -47 -113t-113 -47h-352v96q0 14 -9 23t-23 9
-h-64q-14 0 -23 -9t-9 -23v-96h-768v96q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-96h-352q-66 0 -113 47t-47 113v1216q0 66 47 113t113 47h1728q66 0 113 -47t47 -113z" />
-    <glyph glyph-name="uniF2BC" unicode="&#xf2bc;" horiz-adv-x="2048" 
-d="M1024 405q0 -64 -37 -106.5t-91 -42.5h-512q-54 0 -91 42.5t-37 106.5t9 117.5t29.5 103t60.5 78t97 28.5q6 -4 30 -18t37.5 -21.5t35.5 -17.5t43 -14.5t42 -4.5t42 4.5t43 14.5t35.5 17.5t37.5 21.5t30 18q57 0 97 -28.5t60.5 -78t29.5 -103t9 -117.5zM867 925
-q0 -94 -66.5 -160.5t-160.5 -66.5t-160.5 66.5t-66.5 160.5t66.5 160.5t160.5 66.5t160.5 -66.5t66.5 -160.5zM1792 480v-64q0 -14 -9 -23t-23 -9h-576q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h576q14 0 23 -9t9 -23zM1792 732v-56q0 -15 -10.5 -25.5t-25.5 -10.5h-568
-q-15 0 -25.5 10.5t-10.5 25.5v56q0 15 10.5 25.5t25.5 10.5h568q15 0 25.5 -10.5t10.5 -25.5zM1792 992v-64q0 -14 -9 -23t-23 -9h-576q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h576q14 0 23 -9t9 -23zM1920 32v1216q0 13 -9.5 22.5t-22.5 9.5h-1728q-13 0 -22.5 -9.5
-t-9.5 -22.5v-1216q0 -13 9.5 -22.5t22.5 -9.5h352v96q0 14 9 23t23 9h64q14 0 23 -9t9 -23v-96h768v96q0 14 9 23t23 9h64q14 0 23 -9t9 -23v-96h352q13 0 22.5 9.5t9.5 22.5zM2048 1248v-1216q0 -66 -47 -113t-113 -47h-1728q-66 0 -113 47t-47 113v1216q0 66 47 113
-t113 47h1728q66 0 113 -47t47 -113z" />
-    <glyph glyph-name="uniF2BD" unicode="&#xf2bd;" horiz-adv-x="1792" 
-d="M1523 197q-22 155 -87.5 257.5t-184.5 118.5q-67 -74 -159.5 -115.5t-195.5 -41.5t-195.5 41.5t-159.5 115.5q-119 -16 -184.5 -118.5t-87.5 -257.5q106 -150 271 -237.5t356 -87.5t356 87.5t271 237.5zM1280 896q0 159 -112.5 271.5t-271.5 112.5t-271.5 -112.5
-t-112.5 -271.5t112.5 -271.5t271.5 -112.5t271.5 112.5t112.5 271.5zM1792 640q0 -182 -71 -347.5t-190.5 -286t-285.5 -191.5t-349 -71q-182 0 -348 71t-286 191t-191 286t-71 348t71 348t191 286t286 191t348 71t348 -71t286 -191t191 -286t71 -348z" />
-    <glyph glyph-name="uniF2BE" unicode="&#xf2be;" horiz-adv-x="1792" 
-d="M896 1536q182 0 348 -71t286 -191t191 -286t71 -348q0 -181 -70.5 -347t-190.5 -286t-286 -191.5t-349 -71.5t-349 71t-285.5 191.5t-190.5 286t-71 347.5t71 348t191 286t286 191t348 71zM1515 185q149 205 149 455q0 156 -61 298t-164 245t-245 164t-298 61t-298 -61
-t-245 -164t-164 -245t-61 -298q0 -250 149 -455q66 327 306 327q131 -128 313 -128t313 128q240 0 306 -327zM1280 832q0 159 -112.5 271.5t-271.5 112.5t-271.5 -112.5t-112.5 -271.5t112.5 -271.5t271.5 -112.5t271.5 112.5t112.5 271.5z" />
-    <glyph glyph-name="uniF2C0" unicode="&#xf2c0;" 
-d="M1201 752q47 -14 89.5 -38t89 -73t79.5 -115.5t55 -172t22 -236.5q0 -154 -100 -263.5t-241 -109.5h-854q-141 0 -241 109.5t-100 263.5q0 131 22 236.5t55 172t79.5 115.5t89 73t89.5 38q-79 125 -79 272q0 104 40.5 198.5t109.5 163.5t163.5 109.5t198.5 40.5
-t198.5 -40.5t163.5 -109.5t109.5 -163.5t40.5 -198.5q0 -147 -79 -272zM768 1408q-159 0 -271.5 -112.5t-112.5 -271.5t112.5 -271.5t271.5 -112.5t271.5 112.5t112.5 271.5t-112.5 271.5t-271.5 112.5zM1195 -128q88 0 150.5 71.5t62.5 173.5q0 239 -78.5 377t-225.5 145
-q-145 -127 -336 -127t-336 127q-147 -7 -225.5 -145t-78.5 -377q0 -102 62.5 -173.5t150.5 -71.5h854z" />
-    <glyph glyph-name="uniF2C1" unicode="&#xf2c1;" horiz-adv-x="1280" 
-d="M1024 278q0 -64 -37 -107t-91 -43h-512q-54 0 -91 43t-37 107t9 118t29.5 104t61 78.5t96.5 28.5q80 -75 188 -75t188 75q56 0 96.5 -28.5t61 -78.5t29.5 -104t9 -118zM870 797q0 -94 -67.5 -160.5t-162.5 -66.5t-162.5 66.5t-67.5 160.5t67.5 160.5t162.5 66.5
-t162.5 -66.5t67.5 -160.5zM1152 -96v1376h-1024v-1376q0 -13 9.5 -22.5t22.5 -9.5h960q13 0 22.5 9.5t9.5 22.5zM1280 1376v-1472q0 -66 -47 -113t-113 -47h-960q-66 0 -113 47t-47 113v1472q0 66 47 113t113 47h352v-96q0 -14 9 -23t23 -9h192q14 0 23 9t9 23v96h352
-q66 0 113 -47t47 -113z" />
-    <glyph glyph-name="uniF2C2" unicode="&#xf2c2;" horiz-adv-x="2048" 
-d="M896 324q0 54 -7.5 100.5t-24.5 90t-51 68.5t-81 25q-64 -64 -156 -64t-156 64q-47 0 -81 -25t-51 -68.5t-24.5 -90t-7.5 -100.5q0 -55 31.5 -93.5t75.5 -38.5h426q44 0 75.5 38.5t31.5 93.5zM768 768q0 80 -56 136t-136 56t-136 -56t-56 -136t56 -136t136 -56t136 56
-t56 136zM1792 288v64q0 14 -9 23t-23 9h-704q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h704q14 0 23 9t9 23zM1408 544v64q0 14 -9 23t-23 9h-320q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h320q14 0 23 9t9 23zM1792 544v64q0 14 -9 23t-23 9h-192q-14 0 -23 -9t-9 -23
-v-64q0 -14 9 -23t23 -9h192q14 0 23 9t9 23zM1792 800v64q0 14 -9 23t-23 9h-704q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h704q14 0 23 9t9 23zM128 1152h1792v96q0 14 -9 23t-23 9h-1728q-14 0 -23 -9t-9 -23v-96zM2048 1248v-1216q0 -66 -47 -113t-113 -47h-1728
-q-66 0 -113 47t-47 113v1216q0 66 47 113t113 47h1728q66 0 113 -47t47 -113z" />
-    <glyph glyph-name="uniF2C3" unicode="&#xf2c3;" horiz-adv-x="2048" 
-d="M896 324q0 -55 -31.5 -93.5t-75.5 -38.5h-426q-44 0 -75.5 38.5t-31.5 93.5q0 54 7.5 100.5t24.5 90t51 68.5t81 25q64 -64 156 -64t156 64q47 0 81 -25t51 -68.5t24.5 -90t7.5 -100.5zM768 768q0 -80 -56 -136t-136 -56t-136 56t-56 136t56 136t136 56t136 -56t56 -136z
-M1792 352v-64q0 -14 -9 -23t-23 -9h-704q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h704q14 0 23 -9t9 -23zM1408 608v-64q0 -14 -9 -23t-23 -9h-320q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h320q14 0 23 -9t9 -23zM1792 608v-64q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v64
-q0 14 9 23t23 9h192q14 0 23 -9t9 -23zM1792 864v-64q0 -14 -9 -23t-23 -9h-704q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h704q14 0 23 -9t9 -23zM1920 32v1120h-1792v-1120q0 -13 9.5 -22.5t22.5 -9.5h1728q13 0 22.5 9.5t9.5 22.5zM2048 1248v-1216q0 -66 -47 -113t-113 -47
-h-1728q-66 0 -113 47t-47 113v1216q0 66 47 113t113 47h1728q66 0 113 -47t47 -113z" />
-    <glyph glyph-name="uniF2C4" unicode="&#xf2c4;" horiz-adv-x="1792" 
-d="M1255 749q0 318 -105 474.5t-330 156.5q-222 0 -326 -157t-104 -474q0 -316 104 -471.5t326 -155.5q74 0 131 17q-22 43 -39 73t-44 65t-53.5 56.5t-63 36t-77.5 14.5q-46 0 -79 -16l-49 97q105 91 276 91q132 0 215.5 -54t150.5 -155q67 149 67 402zM1645 117h117
-q3 -27 -2 -67t-26.5 -95t-58 -100.5t-107 -78t-162.5 -32.5q-71 0 -130.5 19t-105.5 56t-79 78t-66 96q-97 -27 -205 -27q-150 0 -292.5 58t-253 158.5t-178 249t-67.5 317.5q0 170 67.5 319.5t178.5 250.5t253.5 159t291.5 58q121 0 238.5 -36t217 -106t176 -164.5
-t119.5 -219t43 -261.5q0 -190 -80.5 -347.5t-218.5 -264.5q47 -70 93.5 -106.5t104.5 -36.5q61 0 94 37.5t38 85.5z" />
-    <glyph glyph-name="uniF2C5" unicode="&#xf2c5;" horiz-adv-x="2304" 
-d="M453 -101q0 -21 -16 -37.5t-37 -16.5q-1 0 -13 3q-63 15 -162 140q-225 284 -225 676q0 341 213 614q39 51 95 103.5t94 52.5q19 0 35 -13.5t16 -32.5q0 -27 -63 -90q-98 -102 -147 -184q-119 -199 -119 -449q0 -281 123 -491q50 -85 136 -173q2 -3 14.5 -16t19.5 -21
-t17 -20.5t14.5 -23.5t4.5 -21zM1796 33q0 -29 -17.5 -48.5t-46.5 -19.5h-1081q-26 0 -45 19t-19 45q0 29 17.5 48.5t46.5 19.5h1081q26 0 45 -19t19 -45zM1581 644q0 -134 -67 -233q-25 -38 -69.5 -78.5t-83.5 -60.5q-16 -10 -27 -10q-7 0 -15 6t-8 12q0 9 19 30t42 46
-t42 67.5t19 88.5q0 76 -35 130q-29 42 -46 42q-3 0 -3 -5q0 -12 7.5 -35.5t7.5 -36.5q0 -22 -21.5 -35t-44.5 -13q-66 0 -66 76q0 15 1.5 44t1.5 44q0 25 -10 46q-13 25 -42 53.5t-51 28.5q-5 0 -7 -0.5t-3.5 -2.5t-1.5 -6q0 -2 16 -26t16 -54q0 -37 -19 -68t-46 -54
-t-53.5 -46t-45.5 -54t-19 -68q0 -98 42 -160q29 -43 79 -63q16 -5 17 -10q1 -2 1 -5q0 -16 -18 -16q-6 0 -33 11q-119 43 -195 139.5t-76 218.5q0 55 24.5 115.5t60 115t70.5 108.5t59.5 113.5t24.5 111.5q0 53 -25 94q-29 48 -56 64q-19 9 -19 21q0 20 41 20q50 0 110 -29
-q41 -19 71 -44.5t49.5 -51t33.5 -62.5t22 -69t16 -80q0 -1 3 -17.5t4.5 -25t5.5 -25t9 -27t11 -21.5t14.5 -16.5t18.5 -5.5q23 0 37 14t14 37q0 25 -20 67t-20 52t10 10q27 0 93 -70q72 -76 102.5 -156t30.5 -186zM2304 615q0 -274 -138 -503q-19 -32 -48 -72t-68 -86.5
-t-81 -77t-74 -30.5q-16 0 -31 15.5t-15 31.5q0 15 29 50.5t68.5 77t48.5 52.5q183 230 183 531q0 131 -20.5 235t-72.5 211q-58 119 -163 228q-2 3 -13 13.5t-16.5 16.5t-15 17.5t-15 20t-9.5 18.5t-4 19q0 19 16 35.5t35 16.5q70 0 196 -169q98 -131 146 -273t60 -314
-q2 -42 2 -64z" />
-    <glyph glyph-name="uniF2C6" unicode="&#xf2c6;" horiz-adv-x="1792" 
-d="M1189 229l147 693q9 44 -10.5 63t-51.5 7l-864 -333q-29 -11 -39.5 -25t-2.5 -26.5t32 -19.5l221 -69l513 323q21 14 32 6q7 -5 -4 -15l-415 -375v0v0l-16 -228q23 0 45 22l108 104l224 -165q64 -36 81 38zM1792 640q0 -182 -71 -348t-191 -286t-286 -191t-348 -71
-t-348 71t-286 191t-191 286t-71 348t71 348t191 286t286 191t348 71t348 -71t286 -191t191 -286t71 -348z" />
-    <glyph glyph-name="uniF2C7" unicode="&#xf2c7;" horiz-adv-x="1024" 
-d="M640 192q0 -80 -56 -136t-136 -56t-136 56t-56 136q0 60 35 110t93 71v907h128v-907q58 -21 93 -71t35 -110zM768 192q0 77 -34 144t-94 112v768q0 80 -56 136t-136 56t-136 -56t-56 -136v-768q-60 -45 -94 -112t-34 -144q0 -133 93.5 -226.5t226.5 -93.5t226.5 93.5
-t93.5 226.5zM896 192q0 -185 -131.5 -316.5t-316.5 -131.5t-316.5 131.5t-131.5 316.5q0 182 128 313v711q0 133 93.5 226.5t226.5 93.5t226.5 -93.5t93.5 -226.5v-711q128 -131 128 -313zM1024 768v-128h-192v128h192zM1024 1024v-128h-192v128h192zM1024 1280v-128h-192
-v128h192z" />
-    <glyph glyph-name="uniF2C8" unicode="&#xf2c8;" horiz-adv-x="1024" 
-d="M640 192q0 -80 -56 -136t-136 -56t-136 56t-56 136q0 60 35 110t93 71v651h128v-651q58 -21 93 -71t35 -110zM768 192q0 77 -34 144t-94 112v768q0 80 -56 136t-136 56t-136 -56t-56 -136v-768q-60 -45 -94 -112t-34 -144q0 -133 93.5 -226.5t226.5 -93.5t226.5 93.5
-t93.5 226.5zM896 192q0 -185 -131.5 -316.5t-316.5 -131.5t-316.5 131.5t-131.5 316.5q0 182 128 313v711q0 133 93.5 226.5t226.5 93.5t226.5 -93.5t93.5 -226.5v-711q128 -131 128 -313zM1024 768v-128h-192v128h192zM1024 1024v-128h-192v128h192zM1024 1280v-128h-192
-v128h192z" />
-    <glyph glyph-name="uniF2C9" unicode="&#xf2c9;" horiz-adv-x="1024" 
-d="M640 192q0 -80 -56 -136t-136 -56t-136 56t-56 136q0 60 35 110t93 71v395h128v-395q58 -21 93 -71t35 -110zM768 192q0 77 -34 144t-94 112v768q0 80 -56 136t-136 56t-136 -56t-56 -136v-768q-60 -45 -94 -112t-34 -144q0 -133 93.5 -226.5t226.5 -93.5t226.5 93.5
-t93.5 226.5zM896 192q0 -185 -131.5 -316.5t-316.5 -131.5t-316.5 131.5t-131.5 316.5q0 182 128 313v711q0 133 93.5 226.5t226.5 93.5t226.5 -93.5t93.5 -226.5v-711q128 -131 128 -313zM1024 768v-128h-192v128h192zM1024 1024v-128h-192v128h192zM1024 1280v-128h-192
-v128h192z" />
-    <glyph glyph-name="uniF2CA" unicode="&#xf2ca;" horiz-adv-x="1024" 
-d="M640 192q0 -80 -56 -136t-136 -56t-136 56t-56 136q0 60 35 110t93 71v139h128v-139q58 -21 93 -71t35 -110zM768 192q0 77 -34 144t-94 112v768q0 80 -56 136t-136 56t-136 -56t-56 -136v-768q-60 -45 -94 -112t-34 -144q0 -133 93.5 -226.5t226.5 -93.5t226.5 93.5
-t93.5 226.5zM896 192q0 -185 -131.5 -316.5t-316.5 -131.5t-316.5 131.5t-131.5 316.5q0 182 128 313v711q0 133 93.5 226.5t226.5 93.5t226.5 -93.5t93.5 -226.5v-711q128 -131 128 -313zM1024 768v-128h-192v128h192zM1024 1024v-128h-192v128h192zM1024 1280v-128h-192
-v128h192z" />
-    <glyph glyph-name="uniF2CB" unicode="&#xf2cb;" horiz-adv-x="1024" 
-d="M640 192q0 -80 -56 -136t-136 -56t-136 56t-56 136q0 79 56 135.5t136 56.5t136 -56.5t56 -135.5zM768 192q0 77 -34 144t-94 112v768q0 80 -56 136t-136 56t-136 -56t-56 -136v-768q-60 -45 -94 -112t-34 -144q0 -133 93.5 -226.5t226.5 -93.5t226.5 93.5t93.5 226.5z
-M896 192q0 -185 -131.5 -316.5t-316.5 -131.5t-316.5 131.5t-131.5 316.5q0 182 128 313v711q0 133 93.5 226.5t226.5 93.5t226.5 -93.5t93.5 -226.5v-711q128 -131 128 -313zM1024 768v-128h-192v128h192zM1024 1024v-128h-192v128h192zM1024 1280v-128h-192v128h192z" />
-    <glyph glyph-name="uniF2CC" unicode="&#xf2cc;" horiz-adv-x="1920" 
-d="M1433 1287q10 -10 10 -23t-10 -23l-626 -626q-10 -10 -23 -10t-23 10l-82 82q-10 10 -10 23t10 23l44 44q-72 91 -81.5 207t46.5 215q-74 71 -176 71q-106 0 -181 -75t-75 -181v-1280h-256v1280q0 104 40.5 198.5t109.5 163.5t163.5 109.5t198.5 40.5q106 0 201 -41
-t166 -115q94 39 197 24.5t185 -79.5l44 44q10 10 23 10t23 -10zM1344 1024q26 0 45 -19t19 -45t-19 -45t-45 -19t-45 19t-19 45t19 45t45 19zM1600 896q-26 0 -45 19t-19 45t19 45t45 19t45 -19t19 -45t-19 -45t-45 -19zM1856 1024q26 0 45 -19t19 -45t-19 -45t-45 -19
-t-45 19t-19 45t19 45t45 19zM1216 896q26 0 45 -19t19 -45t-19 -45t-45 -19t-45 19t-19 45t19 45t45 19zM1408 832q0 26 19 45t45 19t45 -19t19 -45t-19 -45t-45 -19t-45 19t-19 45zM1728 896q26 0 45 -19t19 -45t-19 -45t-45 -19t-45 19t-19 45t19 45t45 19zM1088 768
-q26 0 45 -19t19 -45t-19 -45t-45 -19t-45 19t-19 45t19 45t45 19zM1344 640q-26 0 -45 19t-19 45t19 45t45 19t45 -19t19 -45t-19 -45t-45 -19zM1600 768q26 0 45 -19t19 -45t-19 -45t-45 -19t-45 19t-19 45t19 45t45 19zM1216 512q-26 0 -45 19t-19 45t19 45t45 19t45 -19
-t19 -45t-19 -45t-45 -19zM1472 640q26 0 45 -19t19 -45t-19 -45t-45 -19t-45 19t-19 45t19 45t45 19zM1088 512q26 0 45 -19t19 -45t-19 -45t-45 -19t-45 19t-19 45t19 45t45 19zM1344 512q26 0 45 -19t19 -45t-19 -45t-45 -19t-45 19t-19 45t19 45t45 19zM1216 384
-q26 0 45 -19t19 -45t-19 -45t-45 -19t-45 19t-19 45t19 45t45 19zM1088 256q26 0 45 -19t19 -45t-19 -45t-45 -19t-45 19t-19 45t19 45t45 19z" />
-    <glyph glyph-name="uniF2CD" unicode="&#xf2cd;" horiz-adv-x="1792" 
-d="M1664 448v-192q0 -169 -128 -286v-194q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v118q-63 -22 -128 -22h-768q-65 0 -128 22v-110q0 -17 -9.5 -28.5t-22.5 -11.5h-64q-13 0 -22.5 11.5t-9.5 28.5v186q-128 117 -128 286v192h1536zM704 864q0 -14 -9 -23t-23 -9t-23 9
-t-9 23t9 23t23 9t23 -9t9 -23zM768 928q0 -14 -9 -23t-23 -9t-23 9t-9 23t9 23t23 9t23 -9t9 -23zM704 992q0 -14 -9 -23t-23 -9t-23 9t-9 23t9 23t23 9t23 -9t9 -23zM832 992q0 -14 -9 -23t-23 -9t-23 9t-9 23t9 23t23 9t23 -9t9 -23zM768 1056q0 -14 -9 -23t-23 -9t-23 9
-t-9 23t9 23t23 9t23 -9t9 -23zM704 1120q0 -14 -9 -23t-23 -9t-23 9t-9 23t9 23t23 9t23 -9t9 -23zM1792 608v-64q0 -14 -9 -23t-23 -9h-1728q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h96v640q0 106 75 181t181 75q108 0 184 -78q46 19 98 12t93 -39l22 22q11 11 22 0l42 -42
-q11 -11 0 -22l-314 -314q-11 -11 -22 0l-42 42q-11 11 0 22l22 22q-36 46 -40.5 104t23.5 108q-37 35 -88 35q-53 0 -90.5 -37.5t-37.5 -90.5v-640h1504q14 0 23 -9t9 -23zM896 1056q0 -14 -9 -23t-23 -9t-23 9t-9 23t9 23t23 9t23 -9t9 -23zM832 1120q0 -14 -9 -23t-23 -9
-t-23 9t-9 23t9 23t23 9t23 -9t9 -23zM768 1184q0 -14 -9 -23t-23 -9t-23 9t-9 23t9 23t23 9t23 -9t9 -23zM960 1120q0 -14 -9 -23t-23 -9t-23 9t-9 23t9 23t23 9t23 -9t9 -23zM896 1184q0 -14 -9 -23t-23 -9t-23 9t-9 23t9 23t23 9t23 -9t9 -23zM832 1248q0 -14 -9 -23
-t-23 -9t-23 9t-9 23t9 23t23 9t23 -9t9 -23zM1024 1184q0 -14 -9 -23t-23 -9t-23 9t-9 23t9 23t23 9t23 -9t9 -23zM960 1248q0 -14 -9 -23t-23 -9t-23 9t-9 23t9 23t23 9t23 -9t9 -23zM1088 1248q0 -14 -9 -23t-23 -9t-23 9t-9 23t9 23t23 9t23 -9t9 -23z" />
-    <glyph glyph-name="uniF2CE" unicode="&#xf2ce;" 
-d="M994 344q0 -86 -17 -197q-31 -215 -55 -313q-22 -90 -152 -90t-152 90q-24 98 -55 313q-17 110 -17 197q0 168 224 168t224 -168zM1536 768q0 -240 -134 -434t-350 -280q-8 -3 -15 3t-6 15q7 48 10 66q4 32 6 47q1 9 9 12q159 81 255.5 234t96.5 337q0 180 -91 330.5
-t-247 234.5t-337 74q-124 -7 -237 -61t-193.5 -140.5t-128 -202t-46.5 -240.5q1 -184 99 -336.5t257 -231.5q7 -3 9 -12q3 -21 6 -45q1 -9 5 -32.5t6 -35.5q1 -9 -6.5 -15t-15.5 -2q-148 58 -261 169.5t-173.5 264t-52.5 319.5q7 143 66 273.5t154.5 227t225 157.5t272.5 70
-q164 10 315.5 -46.5t261 -160.5t175 -250.5t65.5 -308.5zM994 800q0 -93 -65.5 -158.5t-158.5 -65.5t-158.5 65.5t-65.5 158.5t65.5 158.5t158.5 65.5t158.5 -65.5t65.5 -158.5zM1282 768q0 -122 -53.5 -228.5t-146.5 -177.5q-8 -6 -16 -2t-10 14q-6 52 -29 92q-7 10 3 20
-q58 54 91 127t33 155q0 111 -58.5 204t-157.5 141.5t-212 36.5q-133 -15 -229 -113t-109 -231q-10 -92 23.5 -176t98.5 -144q10 -10 3 -20q-24 -41 -29 -93q-2 -9 -10 -13t-16 2q-95 74 -148.5 183t-51.5 234q3 131 69 244t177 181.5t241 74.5q144 7 268 -60t196.5 -187.5
-t72.5 -263.5z" />
-    <glyph glyph-name="uniF2D0" unicode="&#xf2d0;" horiz-adv-x="1792" 
-d="M256 128h1280v768h-1280v-768zM1792 1248v-1216q0 -66 -47 -113t-113 -47h-1472q-66 0 -113 47t-47 113v1216q0 66 47 113t113 47h1472q66 0 113 -47t47 -113z" />
-    <glyph glyph-name="uniF2D1" unicode="&#xf2d1;" horiz-adv-x="1792" 
-d="M1792 224v-192q0 -66 -47 -113t-113 -47h-1472q-66 0 -113 47t-47 113v192q0 66 47 113t113 47h1472q66 0 113 -47t47 -113z" />
-    <glyph glyph-name="uniF2D2" unicode="&#xf2d2;" horiz-adv-x="2048" 
-d="M256 0h768v512h-768v-512zM1280 512h512v768h-768v-256h96q66 0 113 -47t47 -113v-352zM2048 1376v-960q0 -66 -47 -113t-113 -47h-608v-352q0 -66 -47 -113t-113 -47h-960q-66 0 -113 47t-47 113v960q0 66 47 113t113 47h608v352q0 66 47 113t113 47h960q66 0 113 -47
-t47 -113z" />
-    <glyph glyph-name="uniF2D3" unicode="&#xf2d3;" horiz-adv-x="1792" 
-d="M1175 215l146 146q10 10 10 23t-10 23l-233 233l233 233q10 10 10 23t-10 23l-146 146q-10 10 -23 10t-23 -10l-233 -233l-233 233q-10 10 -23 10t-23 -10l-146 -146q-10 -10 -10 -23t10 -23l233 -233l-233 -233q-10 -10 -10 -23t10 -23l146 -146q10 -10 23 -10t23 10
-l233 233l233 -233q10 -10 23 -10t23 10zM1792 1248v-1216q0 -66 -47 -113t-113 -47h-1472q-66 0 -113 47t-47 113v1216q0 66 47 113t113 47h1472q66 0 113 -47t47 -113z" />
-    <glyph glyph-name="uniF2D4" unicode="&#xf2d4;" horiz-adv-x="1792" 
-d="M1257 425l-146 -146q-10 -10 -23 -10t-23 10l-169 169l-169 -169q-10 -10 -23 -10t-23 10l-146 146q-10 10 -10 23t10 23l169 169l-169 169q-10 10 -10 23t10 23l146 146q10 10 23 10t23 -10l169 -169l169 169q10 10 23 10t23 -10l146 -146q10 -10 10 -23t-10 -23
-l-169 -169l169 -169q10 -10 10 -23t-10 -23zM256 128h1280v1024h-1280v-1024zM1792 1248v-1216q0 -66 -47 -113t-113 -47h-1472q-66 0 -113 47t-47 113v1216q0 66 47 113t113 47h1472q66 0 113 -47t47 -113z" />
-    <glyph glyph-name="uniF2D5" unicode="&#xf2d5;" horiz-adv-x="1792" 
-d="M1070 358l306 564h-654l-306 -564h654zM1792 640q0 -182 -71 -348t-191 -286t-286 -191t-348 -71t-348 71t-286 191t-191 286t-71 348t71 348t191 286t286 191t348 71t348 -71t286 -191t191 -286t71 -348z" />
-    <glyph glyph-name="uniF2D6" unicode="&#xf2d6;" horiz-adv-x="1794" 
-d="M1291 1060q-15 17 -35 8.5t-26 -28.5t5 -38q14 -17 40 -14.5t34 20.5t-18 52zM895 814q-8 -8 -19.5 -8t-18.5 8q-8 8 -8 19t8 18q7 8 18.5 8t19.5 -8q7 -7 7 -18t-7 -19zM1060 740l-35 -35q-12 -13 -29.5 -13t-30.5 13l-38 38q-12 13 -12 30t12 30l35 35q12 12 29.5 12
-t30.5 -12l38 -39q12 -12 12 -29.5t-12 -29.5zM951 870q-7 -8 -18.5 -8t-19.5 8q-7 8 -7 19t7 19q8 8 19 8t19 -8t8 -19t-8 -19zM1354 968q-34 -64 -107.5 -85.5t-127.5 16.5q-38 28 -61 66.5t-21 87.5t39 92t75.5 53t70.5 -5t70 -51q2 -2 13 -12.5t14.5 -13.5t13 -13.5
-t12.5 -15.5t10 -15.5t8.5 -18t4 -18.5t1 -21t-5 -22t-9.5 -24zM1555 486q3 20 -8.5 34.5t-27.5 21.5t-33 17t-23 20q-40 71 -84 98.5t-113 11.5q19 13 40 18.5t33 4.5l12 -1q2 45 -34 90q6 20 6.5 40.5t-2.5 30.5l-3 10q43 24 71 65t34 91q10 84 -43 150.5t-137 76.5
-q-60 7 -114 -18.5t-82 -74.5q-30 -51 -33.5 -101t14.5 -87t43.5 -64t56.5 -42q-45 4 -88 36t-57 88q-28 108 32 222q-16 21 -29 32q-50 0 -89 -19q19 24 42 37t36 14l13 1q0 50 -13 78q-10 21 -32.5 28.5t-47 -3.5t-37.5 -40q2 4 4 7q-7 -28 -6.5 -75.5t19 -117t48.5 -122.5
-q-25 -14 -47 -36q-35 -16 -85.5 -70.5t-84.5 -101.5l-33 -46q-90 -34 -181 -125.5t-75 -162.5q1 -16 11 -27q-15 -12 -30 -30q-21 -25 -21 -54t21.5 -40t63.5 6q41 19 77 49.5t55 60.5q-2 2 -6.5 5t-20.5 7.5t-33 3.5q23 5 51 12.5t40 10t27.5 6t26 4t23.5 0.5q14 -7 22 34
-q7 37 7 90q0 102 -40 150q106 -103 101 -219q-1 -29 -15 -50t-27 -27l-13 -6q-4 -7 -19 -32t-26 -45.5t-26.5 -52t-25 -61t-17 -63t-6.5 -66.5t10 -63q-35 54 -37 80q-22 -24 -34.5 -39t-33.5 -42t-30.5 -46t-16.5 -41t-0.5 -38t25.5 -27q45 -25 144 64t190.5 221.5
-t122.5 228.5q86 52 145 115.5t86 119.5q47 -93 154 -178q104 -83 167 -80q39 2 46 43zM1794 640q0 -182 -71 -348t-191 -286t-286.5 -191t-348.5 -71t-348.5 71t-286.5 191t-191 286t-71 348t71 348t191 286t286.5 191t348.5 71t348.5 -71t286.5 -191t191 -286t71 -348z" />
-    <glyph glyph-name="uniF2D7" unicode="&#xf2d7;" 
-d="M518 1353v-655q103 -1 191.5 1.5t125.5 5.5l37 3q68 2 90.5 24.5t39.5 94.5l33 142h103l-14 -322l7 -319h-103l-29 127q-15 68 -45 93t-84 26q-87 8 -352 8v-556q0 -78 43.5 -115.5t133.5 -37.5h357q35 0 59.5 2t55 7.5t54 18t48.5 32t46 50.5t39 73l93 216h89
-q-6 -37 -31.5 -252t-30.5 -276q-146 5 -263.5 8t-162.5 4h-44h-628l-376 -12v102l127 25q67 13 91.5 37t25.5 79l8 643q3 402 -8 645q-2 61 -25.5 84t-91.5 36l-127 24v102l376 -12h702q139 0 374 27q-6 -68 -14 -194.5t-12 -219.5l-5 -92h-93l-32 124q-31 121 -74 179.5
-t-113 58.5h-548q-28 0 -35.5 -8.5t-7.5 -30.5z" />
-    <glyph glyph-name="uniF2D8" unicode="&#xf2d8;" 
-d="M922 739v-182q0 -4 0.5 -15t0 -15l-1.5 -12t-3.5 -11.5t-6.5 -7.5t-11 -5.5t-16 -1.5v309q9 0 16 -1t11 -5t6.5 -5.5t3.5 -9.5t1 -10.5v-13.5v-14zM1238 643v-121q0 -1 0.5 -12.5t0 -15.5t-2.5 -11.5t-7.5 -10.5t-13.5 -3q-9 0 -14 9q-4 10 -4 165v7v8.5v9t1.5 8.5l3.5 7
-t5 5.5t8 1.5q6 0 10 -1.5t6.5 -4.5t4 -6t2 -8.5t0.5 -8v-9.5v-9zM180 407h122v472h-122v-472zM614 407h106v472h-159l-28 -221q-20 148 -32 221h-158v-472h107v312l45 -312h76l43 319v-319zM1039 712q0 67 -5 90q-3 16 -11 28.5t-17 20.5t-25 14t-26.5 8.5t-31 4t-29 1.5
-h-29.5h-12h-91v-472h56q169 -1 197 24.5t25 180.5q-1 62 -1 100zM1356 515v133q0 29 -2 45t-9.5 33.5t-24.5 25t-46 7.5q-46 0 -77 -34v154h-117v-472h110l7 30q30 -36 77 -36q50 0 66 30.5t16 83.5zM1536 1248v-1216q0 -66 -47 -113t-113 -47h-1216q-66 0 -113 47t-47 113
-v1216q0 66 47 113t113 47h1216q66 0 113 -47t47 -113z" />
-    <glyph glyph-name="uniF2D9" unicode="&#xf2d9;" horiz-adv-x="2176" 
-d="M1143 -197q-6 1 -11 4q-13 8 -36 23t-86 65t-116.5 104.5t-112 140t-89.5 172.5q-17 3 -175 37q66 -213 235 -362t391 -184zM502 409l168 -28q-25 76 -41 167.5t-19 145.5l-4 53q-84 -82 -121 -224q5 -65 17 -114zM612 1018q-43 -64 -77 -148q44 46 74 68zM2049 584
-q0 161 -62 307t-167.5 252t-250.5 168.5t-304 62.5q-147 0 -281 -52.5t-240 -148.5q-30 -58 -45 -160q60 51 143 83.5t158.5 43t143 13.5t108.5 -1l40 -3q33 -1 53 -15.5t24.5 -33t6.5 -37t-1 -28.5q-126 11 -227.5 0.5t-183 -43.5t-142.5 -71.5t-131 -98.5
-q4 -36 11.5 -92.5t35.5 -178t62 -179.5q123 -6 247.5 14.5t214.5 53.5t162.5 67t109.5 59l37 24q22 16 39.5 20.5t30.5 -5t17 -34.5q14 -97 -39 -121q-208 -97 -467 -134q-135 -20 -317 -16q41 -96 110 -176.5t137 -127t130.5 -79t101.5 -43.5l39 -12q143 -23 263 15
-q195 99 314 289t119 418zM2123 621q-14 -135 -40 -212q-70 -208 -181.5 -346.5t-318.5 -253.5q-48 -33 -82 -44q-72 -26 -163 -16q-36 -3 -73 -3q-283 0 -504.5 173t-295.5 442q-1 0 -4 0.5t-5 0.5q-6 -50 2.5 -112.5t26 -115t36 -98t31.5 -71.5l14 -26q8 -12 54 -82
-q-71 38 -124.5 106.5t-78.5 140t-39.5 137t-17.5 107.5l-2 42q-5 2 -33.5 12.5t-48.5 18t-53 20.5t-57.5 25t-50 25.5t-42.5 27t-25 25.5q19 -10 50.5 -25.5t113 -45.5t145.5 -38l2 32q11 149 94 290q41 202 176 365q28 115 81 214q15 28 32 45t49 32q158 74 303.5 104
-t302 11t306.5 -97q220 -115 333 -336t87 -474z" />
-    <glyph glyph-name="uniF2DA" unicode="&#xf2da;" horiz-adv-x="1792" 
-d="M1341 752q29 44 -6.5 129.5t-121.5 142.5q-58 39 -125.5 53.5t-118 4.5t-68.5 -37q-12 -23 -4.5 -28t42.5 -10q23 -3 38.5 -5t44.5 -9.5t56 -17.5q36 -13 67.5 -31.5t53 -37t40 -38.5t30.5 -38t22 -34.5t16.5 -28.5t12 -18.5t10.5 -6t11 9.5zM1704 178
-q-52 -127 -148.5 -220t-214.5 -141.5t-253 -60.5t-266 13.5t-251 91t-210 161.5t-141.5 235.5t-46.5 303.5q1 41 8.5 84.5t12.5 64t24 80.5t23 73q-51 -208 1 -397t173 -318t291 -206t346 -83t349 74.5t289 244.5q20 27 18 14q0 -4 -4 -14zM1465 627q0 -104 -40.5 -199
-t-108.5 -164t-162 -109.5t-198 -40.5t-198 40.5t-162 109.5t-108.5 164t-40.5 199t40.5 199t108.5 164t162 109.5t198 40.5t198 -40.5t162 -109.5t108.5 -164t40.5 -199zM1752 915q-65 147 -180.5 251t-253 153.5t-292 53.5t-301 -36.5t-275.5 -129t-220 -211.5t-131 -297
-t-10 -373q-49 161 -51.5 311.5t35.5 272.5t109 227t165.5 180.5t207 126t232 71t242.5 9t236 -54t216 -124.5t178 -197q33 -50 62 -121t31 -112zM1690 573q12 244 -136.5 416t-396.5 240q-8 0 -10 5t24 8q125 -4 230 -50t173 -120t116 -168.5t58.5 -199t-1 -208
-t-61.5 -197.5t-122.5 -167t-185 -117.5t-248.5 -46.5q108 30 201.5 80t174 123t129.5 176.5t55 225.5z" />
-    <glyph glyph-name="uniF2DB" unicode="&#xf2db;" 
-d="M192 256v-128h-112q-16 0 -16 16v16h-48q-16 0 -16 16v32q0 16 16 16h48v16q0 16 16 16h112zM192 512v-128h-112q-16 0 -16 16v16h-48q-16 0 -16 16v32q0 16 16 16h48v16q0 16 16 16h112zM192 768v-128h-112q-16 0 -16 16v16h-48q-16 0 -16 16v32q0 16 16 16h48v16
-q0 16 16 16h112zM192 1024v-128h-112q-16 0 -16 16v16h-48q-16 0 -16 16v32q0 16 16 16h48v16q0 16 16 16h112zM192 1280v-128h-112q-16 0 -16 16v16h-48q-16 0 -16 16v32q0 16 16 16h48v16q0 16 16 16h112zM1280 1440v-1472q0 -40 -28 -68t-68 -28h-832q-40 0 -68 28
-t-28 68v1472q0 40 28 68t68 28h832q40 0 68 -28t28 -68zM1536 208v-32q0 -16 -16 -16h-48v-16q0 -16 -16 -16h-112v128h112q16 0 16 -16v-16h48q16 0 16 -16zM1536 464v-32q0 -16 -16 -16h-48v-16q0 -16 -16 -16h-112v128h112q16 0 16 -16v-16h48q16 0 16 -16zM1536 720v-32
-q0 -16 -16 -16h-48v-16q0 -16 -16 -16h-112v128h112q16 0 16 -16v-16h48q16 0 16 -16zM1536 976v-32q0 -16 -16 -16h-48v-16q0 -16 -16 -16h-112v128h112q16 0 16 -16v-16h48q16 0 16 -16zM1536 1232v-32q0 -16 -16 -16h-48v-16q0 -16 -16 -16h-112v128h112q16 0 16 -16v-16
-h48q16 0 16 -16z" />
-    <glyph glyph-name="uniF2DC" unicode="&#xf2dc;" horiz-adv-x="1664" 
-d="M1566 419l-167 -33l186 -107q23 -13 29.5 -38.5t-6.5 -48.5q-14 -23 -39 -29.5t-48 6.5l-186 106l55 -160q13 -38 -12 -63.5t-60.5 -20.5t-48.5 42l-102 300l-271 156v-313l208 -238q16 -18 17 -39t-11 -36.5t-28.5 -25t-37 -5.5t-36.5 22l-112 128v-214q0 -26 -19 -45
-t-45 -19t-45 19t-19 45v214l-112 -128q-16 -18 -36.5 -22t-37 5.5t-28.5 25t-11 36.5t17 39l208 238v313l-271 -156l-102 -300q-13 -37 -48.5 -42t-60.5 20.5t-12 63.5l55 160l-186 -106q-23 -13 -48 -6.5t-39 29.5q-13 23 -6.5 48.5t29.5 38.5l186 107l-167 33
-q-29 6 -42 29t-8.5 46.5t25.5 40t50 10.5l310 -62l271 157l-271 157l-310 -62q-4 -1 -13 -1q-27 0 -44 18t-19 40t11 43t40 26l167 33l-186 107q-23 13 -29.5 38.5t6.5 48.5t39 30t48 -7l186 -106l-55 160q-13 38 12 63.5t60.5 20.5t48.5 -42l102 -300l271 -156v313
-l-208 238q-16 18 -17 39t11 36.5t28.5 25t37 5.5t36.5 -22l112 -128v214q0 26 19 45t45 19t45 -19t19 -45v-214l112 128q16 18 36.5 22t37 -5.5t28.5 -25t11 -36.5t-17 -39l-208 -238v-313l271 156l102 300q13 37 48.5 42t60.5 -20.5t12 -63.5l-55 -160l186 106
-q23 13 48 6.5t39 -29.5q13 -23 6.5 -48.5t-29.5 -38.5l-186 -107l167 -33q27 -5 40 -26t11 -43t-19 -40t-44 -18q-9 0 -13 1l-310 62l-271 -157l271 -157l310 62q29 6 50 -10.5t25.5 -40t-8.5 -46.5t-42 -29z" />
-    <glyph glyph-name="uniF2DD" unicode="&#xf2dd;" horiz-adv-x="1792" 
-d="M1473 607q7 118 -33 226.5t-113 189t-177 131t-221 57.5q-116 7 -225.5 -32t-192 -110.5t-135 -175t-59.5 -220.5q-7 -118 33 -226.5t113 -189t177.5 -131t221.5 -57.5q155 -9 293 59t224 195.5t94 283.5zM1792 1536l-349 -348q120 -117 180.5 -272t50.5 -321
-q-11 -183 -102 -339t-241 -255.5t-332 -124.5l-999 -132l347 347q-120 116 -180.5 271.5t-50.5 321.5q11 184 102 340t241.5 255.5t332.5 124.5q167 22 500 66t500 66z" />
-    <glyph glyph-name="uniF2DE" unicode="&#xf2de;" horiz-adv-x="1792" 
-d="M948 508l163 -329h-51l-175 350l-171 -350h-49l179 374l-78 33l21 49l240 -102l-21 -50zM563 1100l304 -130l-130 -304l-304 130zM907 915l240 -103l-103 -239l-239 102zM1188 765l191 -81l-82 -190l-190 81zM1680 640q0 159 -62 304t-167.5 250.5t-250.5 167.5t-304 62
-t-304 -62t-250.5 -167.5t-167.5 -250.5t-62 -304t62 -304t167.5 -250.5t250.5 -167.5t304 -62t304 62t250.5 167.5t167.5 250.5t62 304zM1792 640q0 -182 -71 -348t-191 -286t-286 -191t-348 -71t-348 71t-286 191t-191 286t-71 348t71 348t191 286t286 191t348 71t348 -71
-t286 -191t191 -286t71 -348z" />
-    <glyph glyph-name="uniF2E0" unicode="&#xf2e0;" horiz-adv-x="1920" 
-d="M1334 302q-4 24 -27.5 34t-49.5 10.5t-48.5 12.5t-25.5 38q-5 47 33 139.5t75 181t32 127.5q-14 101 -117 103q-45 1 -75 -16l-3 -2l-5 -2.5t-4.5 -2t-5 -2t-5 -0.5t-6 1.5t-6 3.5t-6.5 5q-3 2 -9 8.5t-9 9t-8.5 7.5t-9.5 7.5t-9.5 5.5t-11 4.5t-11.5 2.5q-30 5 -48 -3
-t-45 -31q-1 -1 -9 -8.5t-12.5 -11t-15 -10t-16.5 -5.5t-17 3q-54 27 -84 40q-41 18 -94 -5t-76 -65q-16 -28 -41 -98.5t-43.5 -132.5t-40 -134t-21.5 -73q-22 -69 18.5 -119t110.5 -46q30 2 50.5 15t38.5 46q7 13 79 199.5t77 194.5q6 11 21.5 18t29.5 0q27 -15 21 -53
-q-2 -18 -51 -139.5t-50 -132.5q-6 -38 19.5 -56.5t60.5 -7t55 49.5q4 8 45.5 92t81.5 163.5t46 88.5q20 29 41 28q29 0 25 -38q-2 -16 -65.5 -147.5t-70.5 -159.5q-12 -53 13 -103t74 -74q17 -9 51 -15.5t71.5 -8t62.5 14t20 48.5zM383 86q3 -15 -5 -27.5t-23 -15.5
-q-14 -3 -26.5 5t-15.5 23q-3 14 5 27t22 16t27 -5t16 -23zM953 -177q12 -17 8.5 -37.5t-20.5 -32.5t-37.5 -8t-32.5 21q-11 17 -7.5 37.5t20.5 32.5t37.5 8t31.5 -21zM177 635q-18 -27 -49.5 -33t-57.5 13q-26 18 -32 50t12 58q18 27 49.5 33t57.5 -12q26 -19 32 -50.5
-t-12 -58.5zM1467 -42q19 -28 13 -61.5t-34 -52.5t-60.5 -13t-51.5 34t-13 61t33 53q28 19 60.5 13t52.5 -34zM1579 562q69 -113 42.5 -244.5t-134.5 -207.5q-90 -63 -199 -60q-20 -80 -84.5 -127t-143.5 -44.5t-140 57.5q-12 -9 -13 -10q-103 -71 -225 -48.5t-193 126.5
-q-50 73 -53 164q-83 14 -142.5 70.5t-80.5 128t-2 152t81 138.5q-36 60 -38 128t24.5 125t79.5 98.5t121 50.5q32 85 99 148t146.5 91.5t168 17t159.5 -66.5q72 21 140 17.5t128.5 -36t104.5 -80t67.5 -115t17.5 -140.5q52 -16 87 -57t45.5 -89t-5.5 -99.5t-58 -87.5z
-M455 1222q14 -20 9.5 -44.5t-24.5 -38.5q-19 -14 -43.5 -9.5t-37.5 24.5q-14 20 -9.5 44.5t24.5 38.5q19 14 43.5 9.5t37.5 -24.5zM614 1503q4 -16 -5 -30.5t-26 -18.5t-31 5.5t-18 26.5q-3 17 6.5 31t25.5 18q17 4 31 -5.5t17 -26.5zM1800 555q4 -20 -6.5 -37t-30.5 -21
-q-19 -4 -36 6.5t-21 30.5t6.5 37t30.5 22q20 4 36.5 -7.5t20.5 -30.5zM1136 1448q16 -27 8.5 -58.5t-35.5 -47.5q-27 -16 -57.5 -8.5t-46.5 34.5q-16 28 -8.5 59t34.5 48t58 9t47 -36zM1882 792q4 -15 -4 -27.5t-23 -16.5q-15 -3 -27.5 5.5t-15.5 22.5q-3 15 5 28t23 16
-q14 3 26.5 -5t15.5 -23zM1691 1033q15 -22 10.5 -49t-26.5 -43q-22 -15 -49 -10t-42 27t-10 49t27 43t48.5 11t41.5 -28z" />
-    <glyph glyph-name="uniF2E1" unicode="&#xf2e1;" horiz-adv-x="1792" 
- />
-    <glyph glyph-name="uniF2E2" unicode="&#xf2e2;" horiz-adv-x="1792" 
- />
-    <glyph glyph-name="uniF2E3" unicode="&#xf2e3;" horiz-adv-x="1792" 
- />
-    <glyph glyph-name="uniF2E4" unicode="&#xf2e4;" horiz-adv-x="1792" 
- />
-    <glyph glyph-name="uniF2E5" unicode="&#xf2e5;" horiz-adv-x="1792" 
- />
-    <glyph glyph-name="uniF2E6" unicode="&#xf2e6;" horiz-adv-x="1792" 
- />
-    <glyph glyph-name="uniF2E7" unicode="&#xf2e7;" horiz-adv-x="1792" 
- />
-    <glyph glyph-name="_698" unicode="&#xf2e8;" horiz-adv-x="1792" 
- />
-    <glyph glyph-name="uniF2E9" unicode="&#xf2e9;" horiz-adv-x="1792" 
- />
-    <glyph glyph-name="uniF2EA" unicode="&#xf2ea;" horiz-adv-x="1792" 
- />
-    <glyph glyph-name="uniF2EB" unicode="&#xf2eb;" horiz-adv-x="1792" 
- />
-    <glyph glyph-name="uniF2EC" unicode="&#xf2ec;" horiz-adv-x="1792" 
- />
-    <glyph glyph-name="uniF2ED" unicode="&#xf2ed;" horiz-adv-x="1792" 
- />
-    <glyph glyph-name="uniF2EE" unicode="&#xf2ee;" horiz-adv-x="1792" 
- />
-    <glyph glyph-name="lessequal" unicode="&#xf500;" horiz-adv-x="1792" 
- />
-  </font>
-</defs></svg>
diff --git a/docs/_build/html/_static/css/fonts/fontawesome-webfont.ttf b/docs/_build/html/_static/css/fonts/fontawesome-webfont.ttf
deleted file mode 100644
index 35acda2f..00000000
Binary files a/docs/_build/html/_static/css/fonts/fontawesome-webfont.ttf and /dev/null differ
diff --git a/docs/_build/html/_static/css/fonts/fontawesome-webfont.woff b/docs/_build/html/_static/css/fonts/fontawesome-webfont.woff
deleted file mode 100644
index 400014a4..00000000
Binary files a/docs/_build/html/_static/css/fonts/fontawesome-webfont.woff and /dev/null differ
diff --git a/docs/_build/html/_static/css/fonts/fontawesome-webfont.woff2 b/docs/_build/html/_static/css/fonts/fontawesome-webfont.woff2
deleted file mode 100644
index 4d13fc60..00000000
Binary files a/docs/_build/html/_static/css/fonts/fontawesome-webfont.woff2 and /dev/null differ
diff --git a/docs/_build/html/_static/css/fonts/lato-bold-italic.woff b/docs/_build/html/_static/css/fonts/lato-bold-italic.woff
deleted file mode 100644
index 88ad05b9..00000000
Binary files a/docs/_build/html/_static/css/fonts/lato-bold-italic.woff and /dev/null differ
diff --git a/docs/_build/html/_static/css/fonts/lato-bold-italic.woff2 b/docs/_build/html/_static/css/fonts/lato-bold-italic.woff2
deleted file mode 100644
index c4e3d804..00000000
Binary files a/docs/_build/html/_static/css/fonts/lato-bold-italic.woff2 and /dev/null differ
diff --git a/docs/_build/html/_static/css/fonts/lato-bold.woff b/docs/_build/html/_static/css/fonts/lato-bold.woff
deleted file mode 100644
index c6dff51f..00000000
Binary files a/docs/_build/html/_static/css/fonts/lato-bold.woff and /dev/null differ
diff --git a/docs/_build/html/_static/css/fonts/lato-bold.woff2 b/docs/_build/html/_static/css/fonts/lato-bold.woff2
deleted file mode 100644
index bb195043..00000000
Binary files a/docs/_build/html/_static/css/fonts/lato-bold.woff2 and /dev/null differ
diff --git a/docs/_build/html/_static/css/fonts/lato-normal-italic.woff b/docs/_build/html/_static/css/fonts/lato-normal-italic.woff
deleted file mode 100644
index 76114bc0..00000000
Binary files a/docs/_build/html/_static/css/fonts/lato-normal-italic.woff and /dev/null differ
diff --git a/docs/_build/html/_static/css/fonts/lato-normal-italic.woff2 b/docs/_build/html/_static/css/fonts/lato-normal-italic.woff2
deleted file mode 100644
index 3404f37e..00000000
Binary files a/docs/_build/html/_static/css/fonts/lato-normal-italic.woff2 and /dev/null differ
diff --git a/docs/_build/html/_static/css/fonts/lato-normal.woff b/docs/_build/html/_static/css/fonts/lato-normal.woff
deleted file mode 100644
index ae1307ff..00000000
Binary files a/docs/_build/html/_static/css/fonts/lato-normal.woff and /dev/null differ
diff --git a/docs/_build/html/_static/css/fonts/lato-normal.woff2 b/docs/_build/html/_static/css/fonts/lato-normal.woff2
deleted file mode 100644
index 3bf98433..00000000
Binary files a/docs/_build/html/_static/css/fonts/lato-normal.woff2 and /dev/null differ
diff --git a/docs/_build/html/_static/css/theme.css b/docs/_build/html/_static/css/theme.css
deleted file mode 100644
index 8cd4f101..00000000
--- a/docs/_build/html/_static/css/theme.css
+++ /dev/null
@@ -1,4 +0,0 @@
-html{box-sizing:border-box}*,:after,:before{box-sizing:inherit}article,aside,details,figcaption,figure,footer,header,hgroup,nav,section{display:block}audio,canvas,video{display:inline-block;*display:inline;*zoom:1}[hidden],audio:not([controls]){display:none}*{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}html{font-size:100%;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}body{margin:0}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:700}blockquote{margin:0}dfn{font-style:italic}ins{background:#ff9;text-decoration:none}ins,mark{color:#000}mark{background:#ff0;font-style:italic;font-weight:700}.rst-content code,.rst-content tt,code,kbd,pre,samp{font-family:monospace,serif;_font-family:courier new,monospace;font-size:1em}pre{white-space:pre}q{quotes:none}q:after,q:before{content:"";content:none}small{font-size:85%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}dl,ol,ul{margin:0;padding:0;list-style:none;list-style-image:none}li{list-style:none}dd{margin:0}img{border:0;-ms-interpolation-mode:bicubic;vertical-align:middle;max-width:100%}svg:not(:root){overflow:hidden}figure,form{margin:0}label{cursor:pointer}button,input,select,textarea{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle}button,input{line-height:normal}button,input[type=button],input[type=reset],input[type=submit]{cursor:pointer;-webkit-appearance:button;*overflow:visible}button[disabled],input[disabled]{cursor:default}input[type=search]{-webkit-appearance:textfield;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box}textarea{resize:vertical}table{border-collapse:collapse;border-spacing:0}td{vertical-align:top}.chromeframe{margin:.2em 0;background:#ccc;color:#000;padding:.2em 0}.ir{display:block;border:0;text-indent:-999em;overflow:hidden;background-color:transparent;background-repeat:no-repeat;text-align:left;direction:ltr;*line-height:0}.ir br{display:none}.hidden{display:none!important;visibility:hidden}.visuallyhidden{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.visuallyhidden.focusable:active,.visuallyhidden.focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}.invisible{visibility:hidden}.relative{position:relative}big,small{font-size:100%}@media print{body,html,section{background:none!important}*{box-shadow:none!important;text-shadow:none!important;filter:none!important;-ms-filter:none!important}a,a:visited{text-decoration:underline}.ir a:after,a[href^="#"]:after,a[href^="javascript:"]:after{content:""}blockquote,pre{page-break-inside:avoid}thead{display:table-header-group}img,tr{page-break-inside:avoid}img{max-width:100%!important}@page{margin:.5cm}.rst-content .toctree-wrapper>p.caption,h2,h3,p{orphans:3;widows:3}.rst-content .toctree-wrapper>p.caption,h2,h3{page-break-after:avoid}}.btn,.fa:before,.icon:before,.rst-content .admonition,.rst-content .admonition-title:before,.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .code-block-caption .headerlink:before,.rst-content .danger,.rst-content .error,.rst-content .hint,.rst-content .important,.rst-content .note,.rst-content .seealso,.rst-content .tip,.rst-content .warning,.rst-content code.download span:first-child:before,.rst-content dl dt .headerlink:before,.rst-content h1 .headerlink:before,.rst-content h2 .headerlink:before,.rst-content h3 .headerlink:before,.rst-content h4 .headerlink:before,.rst-content h5 .headerlink:before,.rst-content h6 .headerlink:before,.rst-content p.caption .headerlink:before,.rst-content table>caption .headerlink:before,.rst-content tt.download span:first-child:before,.wy-alert,.wy-dropdown .caret:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before,.wy-menu-vertical li.current>a,.wy-menu-vertical li.current>a span.toctree-expand:before,.wy-menu-vertical li.on a,.wy-menu-vertical li.on a span.toctree-expand:before,.wy-menu-vertical li span.toctree-expand:before,.wy-nav-top a,.wy-side-nav-search .wy-dropdown>a,.wy-side-nav-search>a,input[type=color],input[type=date],input[type=datetime-local],input[type=datetime],input[type=email],input[type=month],input[type=number],input[type=password],input[type=search],input[type=tel],input[type=text],input[type=time],input[type=url],input[type=week],select,textarea{-webkit-font-smoothing:antialiased}.clearfix{*zoom:1}.clearfix:after,.clearfix:before{display:table;content:""}.clearfix:after{clear:both}/*!
- *  Font Awesome 4.7.0 by @davegandy - http://fontawesome.io - @fontawesome
- *  License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License)
- */@font-face{font-family:FontAwesome;src:url(fonts/fontawesome-webfont.eot?674f50d287a8c48dc19ba404d20fe713);src:url(fonts/fontawesome-webfont.eot?674f50d287a8c48dc19ba404d20fe713?#iefix&v=4.7.0) format("embedded-opentype"),url(fonts/fontawesome-webfont.woff2?af7ae505a9eed503f8b8e6982036873e) format("woff2"),url(fonts/fontawesome-webfont.woff?fee66e712a8a08eef5805a46892932ad) format("woff"),url(fonts/fontawesome-webfont.ttf?b06871f281fee6b241d60582ae9369b9) format("truetype"),url(fonts/fontawesome-webfont.svg?912ec66d7572ff821749319396470bde#fontawesomeregular) format("svg");font-weight:400;font-style:normal}.fa,.icon,.rst-content .admonition-title,.rst-content .code-block-caption .headerlink,.rst-content code.download span:first-child,.rst-content dl dt .headerlink,.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content p.caption .headerlink,.rst-content table>caption .headerlink,.rst-content tt.download span:first-child,.wy-menu-vertical li.current>a span.toctree-expand,.wy-menu-vertical li.on a span.toctree-expand,.wy-menu-vertical li span.toctree-expand{display:inline-block;font:normal normal normal 14px/1 FontAwesome;font-size:inherit;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.fa-lg{font-size:1.33333em;line-height:.75em;vertical-align:-15%}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-fw{width:1.28571em;text-align:center}.fa-ul{padding-left:0;margin-left:2.14286em;list-style-type:none}.fa-ul>li{position:relative}.fa-li{position:absolute;left:-2.14286em;width:2.14286em;top:.14286em;text-align:center}.fa-li.fa-lg{left:-1.85714em}.fa-border{padding:.2em .25em .15em;border:.08em solid #eee;border-radius:.1em}.fa-pull-left{float:left}.fa-pull-right{float:right}.fa-pull-left.icon,.fa.fa-pull-left,.rst-content .code-block-caption .fa-pull-left.headerlink,.rst-content .fa-pull-left.admonition-title,.rst-content code.download span.fa-pull-left:first-child,.rst-content dl dt .fa-pull-left.headerlink,.rst-content h1 .fa-pull-left.headerlink,.rst-content h2 .fa-pull-left.headerlink,.rst-content h3 .fa-pull-left.headerlink,.rst-content h4 .fa-pull-left.headerlink,.rst-content h5 .fa-pull-left.headerlink,.rst-content h6 .fa-pull-left.headerlink,.rst-content p.caption .fa-pull-left.headerlink,.rst-content table>caption .fa-pull-left.headerlink,.rst-content tt.download span.fa-pull-left:first-child,.wy-menu-vertical li.current>a span.fa-pull-left.toctree-expand,.wy-menu-vertical li.on a span.fa-pull-left.toctree-expand,.wy-menu-vertical li span.fa-pull-left.toctree-expand{margin-right:.3em}.fa-pull-right.icon,.fa.fa-pull-right,.rst-content .code-block-caption .fa-pull-right.headerlink,.rst-content .fa-pull-right.admonition-title,.rst-content code.download span.fa-pull-right:first-child,.rst-content dl dt .fa-pull-right.headerlink,.rst-content h1 .fa-pull-right.headerlink,.rst-content h2 .fa-pull-right.headerlink,.rst-content h3 .fa-pull-right.headerlink,.rst-content h4 .fa-pull-right.headerlink,.rst-content h5 .fa-pull-right.headerlink,.rst-content h6 .fa-pull-right.headerlink,.rst-content p.caption .fa-pull-right.headerlink,.rst-content table>caption .fa-pull-right.headerlink,.rst-content tt.download span.fa-pull-right:first-child,.wy-menu-vertical li.current>a span.fa-pull-right.toctree-expand,.wy-menu-vertical li.on a span.fa-pull-right.toctree-expand,.wy-menu-vertical li span.fa-pull-right.toctree-expand{margin-left:.3em}.pull-right{float:right}.pull-left{float:left}.fa.pull-left,.pull-left.icon,.rst-content .code-block-caption .pull-left.headerlink,.rst-content .pull-left.admonition-title,.rst-content code.download span.pull-left:first-child,.rst-content dl dt .pull-left.headerlink,.rst-content h1 .pull-left.headerlink,.rst-content h2 .pull-left.headerlink,.rst-content h3 .pull-left.headerlink,.rst-content h4 .pull-left.headerlink,.rst-content h5 .pull-left.headerlink,.rst-content h6 .pull-left.headerlink,.rst-content p.caption .pull-left.headerlink,.rst-content table>caption .pull-left.headerlink,.rst-content tt.download span.pull-left:first-child,.wy-menu-vertical li.current>a span.pull-left.toctree-expand,.wy-menu-vertical li.on a span.pull-left.toctree-expand,.wy-menu-vertical li span.pull-left.toctree-expand{margin-right:.3em}.fa.pull-right,.pull-right.icon,.rst-content .code-block-caption .pull-right.headerlink,.rst-content .pull-right.admonition-title,.rst-content code.download span.pull-right:first-child,.rst-content dl dt .pull-right.headerlink,.rst-content h1 .pull-right.headerlink,.rst-content h2 .pull-right.headerlink,.rst-content h3 .pull-right.headerlink,.rst-content h4 .pull-right.headerlink,.rst-content h5 .pull-right.headerlink,.rst-content h6 .pull-right.headerlink,.rst-content p.caption .pull-right.headerlink,.rst-content table>caption .pull-right.headerlink,.rst-content tt.download span.pull-right:first-child,.wy-menu-vertical li.current>a span.pull-right.toctree-expand,.wy-menu-vertical li.on a span.pull-right.toctree-expand,.wy-menu-vertical li span.pull-right.toctree-expand{margin-left:.3em}.fa-spin{-webkit-animation:fa-spin 2s linear infinite;animation:fa-spin 2s linear infinite}.fa-pulse{-webkit-animation:fa-spin 1s steps(8) infinite;animation:fa-spin 1s steps(8) infinite}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.fa-rotate-90{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=1)";-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2)";-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=3)";-webkit-transform:rotate(270deg);-ms-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)";-webkit-transform:scaleX(-1);-ms-transform:scaleX(-1);transform:scaleX(-1)}.fa-flip-vertical{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)";-webkit-transform:scaleY(-1);-ms-transform:scaleY(-1);transform:scaleY(-1)}:root .fa-flip-horizontal,:root .fa-flip-vertical,:root .fa-rotate-90,:root .fa-rotate-180,:root .fa-rotate-270{filter:none}.fa-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:middle}.fa-stack-1x,.fa-stack-2x{position:absolute;left:0;width:100%;text-align:center}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-glass:before{content:""}.fa-music:before{content:""}.fa-search:before,.icon-search:before{content:""}.fa-envelope-o:before{content:""}.fa-heart:before{content:""}.fa-star:before{content:""}.fa-star-o:before{content:""}.fa-user:before{content:""}.fa-film:before{content:""}.fa-th-large:before{content:""}.fa-th:before{content:""}.fa-th-list:before{content:""}.fa-check:before{content:""}.fa-close:before,.fa-remove:before,.fa-times:before{content:""}.fa-search-plus:before{content:""}.fa-search-minus:before{content:""}.fa-power-off:before{content:""}.fa-signal:before{content:""}.fa-cog:before,.fa-gear:before{content:""}.fa-trash-o:before{content:""}.fa-home:before,.icon-home:before{content:""}.fa-file-o:before{content:""}.fa-clock-o:before{content:""}.fa-road:before{content:""}.fa-download:before,.rst-content code.download span:first-child:before,.rst-content tt.download span:first-child:before{content:""}.fa-arrow-circle-o-down:before{content:""}.fa-arrow-circle-o-up:before{content:""}.fa-inbox:before{content:""}.fa-play-circle-o:before{content:""}.fa-repeat:before,.fa-rotate-right:before{content:""}.fa-refresh:before{content:""}.fa-list-alt:before{content:""}.fa-lock:before{content:""}.fa-flag:before{content:""}.fa-headphones:before{content:""}.fa-volume-off:before{content:""}.fa-volume-down:before{content:""}.fa-volume-up:before{content:""}.fa-qrcode:before{content:""}.fa-barcode:before{content:""}.fa-tag:before{content:""}.fa-tags:before{content:""}.fa-book:before,.icon-book:before{content:""}.fa-bookmark:before{content:""}.fa-print:before{content:""}.fa-camera:before{content:""}.fa-font:before{content:""}.fa-bold:before{content:""}.fa-italic:before{content:""}.fa-text-height:before{content:""}.fa-text-width:before{content:""}.fa-align-left:before{content:""}.fa-align-center:before{content:""}.fa-align-right:before{content:""}.fa-align-justify:before{content:""}.fa-list:before{content:""}.fa-dedent:before,.fa-outdent:before{content:""}.fa-indent:before{content:""}.fa-video-camera:before{content:""}.fa-image:before,.fa-photo:before,.fa-picture-o:before{content:""}.fa-pencil:before{content:""}.fa-map-marker:before{content:""}.fa-adjust:before{content:""}.fa-tint:before{content:""}.fa-edit:before,.fa-pencil-square-o:before{content:""}.fa-share-square-o:before{content:""}.fa-check-square-o:before{content:""}.fa-arrows:before{content:""}.fa-step-backward:before{content:""}.fa-fast-backward:before{content:""}.fa-backward:before{content:""}.fa-play:before{content:""}.fa-pause:before{content:""}.fa-stop:before{content:""}.fa-forward:before{content:""}.fa-fast-forward:before{content:""}.fa-step-forward:before{content:""}.fa-eject:before{content:""}.fa-chevron-left:before{content:""}.fa-chevron-right:before{content:""}.fa-plus-circle:before{content:""}.fa-minus-circle:before{content:""}.fa-times-circle:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before{content:""}.fa-check-circle:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before{content:""}.fa-question-circle:before{content:""}.fa-info-circle:before{content:""}.fa-crosshairs:before{content:""}.fa-times-circle-o:before{content:""}.fa-check-circle-o:before{content:""}.fa-ban:before{content:""}.fa-arrow-left:before{content:""}.fa-arrow-right:before{content:""}.fa-arrow-up:before{content:""}.fa-arrow-down:before{content:""}.fa-mail-forward:before,.fa-share:before{content:""}.fa-expand:before{content:""}.fa-compress:before{content:""}.fa-plus:before{content:""}.fa-minus:before{content:""}.fa-asterisk:before{content:""}.fa-exclamation-circle:before,.rst-content .admonition-title:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before{content:""}.fa-gift:before{content:""}.fa-leaf:before{content:""}.fa-fire:before,.icon-fire:before{content:""}.fa-eye:before{content:""}.fa-eye-slash:before{content:""}.fa-exclamation-triangle:before,.fa-warning:before{content:""}.fa-plane:before{content:""}.fa-calendar:before{content:""}.fa-random:before{content:""}.fa-comment:before{content:""}.fa-magnet:before{content:""}.fa-chevron-up:before{content:""}.fa-chevron-down:before{content:""}.fa-retweet:before{content:""}.fa-shopping-cart:before{content:""}.fa-folder:before{content:""}.fa-folder-open:before{content:""}.fa-arrows-v:before{content:""}.fa-arrows-h:before{content:""}.fa-bar-chart-o:before,.fa-bar-chart:before{content:""}.fa-twitter-square:before{content:""}.fa-facebook-square:before{content:""}.fa-camera-retro:before{content:""}.fa-key:before{content:""}.fa-cogs:before,.fa-gears:before{content:""}.fa-comments:before{content:""}.fa-thumbs-o-up:before{content:""}.fa-thumbs-o-down:before{content:""}.fa-star-half:before{content:""}.fa-heart-o:before{content:""}.fa-sign-out:before{content:""}.fa-linkedin-square:before{content:""}.fa-thumb-tack:before{content:""}.fa-external-link:before{content:""}.fa-sign-in:before{content:""}.fa-trophy:before{content:""}.fa-github-square:before{content:""}.fa-upload:before{content:""}.fa-lemon-o:before{content:""}.fa-phone:before{content:""}.fa-square-o:before{content:""}.fa-bookmark-o:before{content:""}.fa-phone-square:before{content:""}.fa-twitter:before{content:""}.fa-facebook-f:before,.fa-facebook:before{content:""}.fa-github:before,.icon-github:before{content:""}.fa-unlock:before{content:""}.fa-credit-card:before{content:""}.fa-feed:before,.fa-rss:before{content:""}.fa-hdd-o:before{content:""}.fa-bullhorn:before{content:""}.fa-bell:before{content:""}.fa-certificate:before{content:""}.fa-hand-o-right:before{content:""}.fa-hand-o-left:before{content:""}.fa-hand-o-up:before{content:""}.fa-hand-o-down:before{content:""}.fa-arrow-circle-left:before,.icon-circle-arrow-left:before{content:""}.fa-arrow-circle-right:before,.icon-circle-arrow-right:before{content:""}.fa-arrow-circle-up:before{content:""}.fa-arrow-circle-down:before{content:""}.fa-globe:before{content:""}.fa-wrench:before{content:""}.fa-tasks:before{content:""}.fa-filter:before{content:""}.fa-briefcase:before{content:""}.fa-arrows-alt:before{content:""}.fa-group:before,.fa-users:before{content:""}.fa-chain:before,.fa-link:before,.icon-link:before{content:""}.fa-cloud:before{content:""}.fa-flask:before{content:""}.fa-cut:before,.fa-scissors:before{content:""}.fa-copy:before,.fa-files-o:before{content:""}.fa-paperclip:before{content:""}.fa-floppy-o:before,.fa-save:before{content:""}.fa-square:before{content:""}.fa-bars:before,.fa-navicon:before,.fa-reorder:before{content:""}.fa-list-ul:before{content:""}.fa-list-ol:before{content:""}.fa-strikethrough:before{content:""}.fa-underline:before{content:""}.fa-table:before{content:""}.fa-magic:before{content:""}.fa-truck:before{content:""}.fa-pinterest:before{content:""}.fa-pinterest-square:before{content:""}.fa-google-plus-square:before{content:""}.fa-google-plus:before{content:""}.fa-money:before{content:""}.fa-caret-down:before,.icon-caret-down:before,.wy-dropdown .caret:before{content:""}.fa-caret-up:before{content:""}.fa-caret-left:before{content:""}.fa-caret-right:before{content:""}.fa-columns:before{content:""}.fa-sort:before,.fa-unsorted:before{content:""}.fa-sort-desc:before,.fa-sort-down:before{content:""}.fa-sort-asc:before,.fa-sort-up:before{content:""}.fa-envelope:before{content:""}.fa-linkedin:before{content:""}.fa-rotate-left:before,.fa-undo:before{content:""}.fa-gavel:before,.fa-legal:before{content:""}.fa-dashboard:before,.fa-tachometer:before{content:""}.fa-comment-o:before{content:""}.fa-comments-o:before{content:""}.fa-bolt:before,.fa-flash:before{content:""}.fa-sitemap:before{content:""}.fa-umbrella:before{content:""}.fa-clipboard:before,.fa-paste:before{content:""}.fa-lightbulb-o:before{content:""}.fa-exchange:before{content:""}.fa-cloud-download:before{content:""}.fa-cloud-upload:before{content:""}.fa-user-md:before{content:""}.fa-stethoscope:before{content:""}.fa-suitcase:before{content:""}.fa-bell-o:before{content:""}.fa-coffee:before{content:""}.fa-cutlery:before{content:""}.fa-file-text-o:before{content:""}.fa-building-o:before{content:""}.fa-hospital-o:before{content:""}.fa-ambulance:before{content:""}.fa-medkit:before{content:""}.fa-fighter-jet:before{content:""}.fa-beer:before{content:""}.fa-h-square:before{content:""}.fa-plus-square:before{content:""}.fa-angle-double-left:before{content:""}.fa-angle-double-right:before{content:""}.fa-angle-double-up:before{content:""}.fa-angle-double-down:before{content:""}.fa-angle-left:before{content:""}.fa-angle-right:before{content:""}.fa-angle-up:before{content:""}.fa-angle-down:before{content:""}.fa-desktop:before{content:""}.fa-laptop:before{content:""}.fa-tablet:before{content:""}.fa-mobile-phone:before,.fa-mobile:before{content:""}.fa-circle-o:before{content:""}.fa-quote-left:before{content:""}.fa-quote-right:before{content:""}.fa-spinner:before{content:""}.fa-circle:before{content:""}.fa-mail-reply:before,.fa-reply:before{content:""}.fa-github-alt:before{content:""}.fa-folder-o:before{content:""}.fa-folder-open-o:before{content:""}.fa-smile-o:before{content:""}.fa-frown-o:before{content:""}.fa-meh-o:before{content:""}.fa-gamepad:before{content:""}.fa-keyboard-o:before{content:""}.fa-flag-o:before{content:""}.fa-flag-checkered:before{content:""}.fa-terminal:before{content:""}.fa-code:before{content:""}.fa-mail-reply-all:before,.fa-reply-all:before{content:""}.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:""}.fa-location-arrow:before{content:""}.fa-crop:before{content:""}.fa-code-fork:before{content:""}.fa-chain-broken:before,.fa-unlink:before{content:""}.fa-question:before{content:""}.fa-info:before{content:""}.fa-exclamation:before{content:""}.fa-superscript:before{content:""}.fa-subscript:before{content:""}.fa-eraser:before{content:""}.fa-puzzle-piece:before{content:""}.fa-microphone:before{content:""}.fa-microphone-slash:before{content:""}.fa-shield:before{content:""}.fa-calendar-o:before{content:""}.fa-fire-extinguisher:before{content:""}.fa-rocket:before{content:""}.fa-maxcdn:before{content:""}.fa-chevron-circle-left:before{content:""}.fa-chevron-circle-right:before{content:""}.fa-chevron-circle-up:before{content:""}.fa-chevron-circle-down:before{content:""}.fa-html5:before{content:""}.fa-css3:before{content:""}.fa-anchor:before{content:""}.fa-unlock-alt:before{content:""}.fa-bullseye:before{content:""}.fa-ellipsis-h:before{content:""}.fa-ellipsis-v:before{content:""}.fa-rss-square:before{content:""}.fa-play-circle:before{content:""}.fa-ticket:before{content:""}.fa-minus-square:before{content:""}.fa-minus-square-o:before,.wy-menu-vertical li.current>a span.toctree-expand:before,.wy-menu-vertical li.on a span.toctree-expand:before{content:""}.fa-level-up:before{content:""}.fa-level-down:before{content:""}.fa-check-square:before{content:""}.fa-pencil-square:before{content:""}.fa-external-link-square:before{content:""}.fa-share-square:before{content:""}.fa-compass:before{content:""}.fa-caret-square-o-down:before,.fa-toggle-down:before{content:""}.fa-caret-square-o-up:before,.fa-toggle-up:before{content:""}.fa-caret-square-o-right:before,.fa-toggle-right:before{content:""}.fa-eur:before,.fa-euro:before{content:""}.fa-gbp:before{content:""}.fa-dollar:before,.fa-usd:before{content:""}.fa-inr:before,.fa-rupee:before{content:""}.fa-cny:before,.fa-jpy:before,.fa-rmb:before,.fa-yen:before{content:""}.fa-rouble:before,.fa-rub:before,.fa-ruble:before{content:""}.fa-krw:before,.fa-won:before{content:""}.fa-bitcoin:before,.fa-btc:before{content:""}.fa-file:before{content:""}.fa-file-text:before{content:""}.fa-sort-alpha-asc:before{content:""}.fa-sort-alpha-desc:before{content:""}.fa-sort-amount-asc:before{content:""}.fa-sort-amount-desc:before{content:""}.fa-sort-numeric-asc:before{content:""}.fa-sort-numeric-desc:before{content:""}.fa-thumbs-up:before{content:""}.fa-thumbs-down:before{content:""}.fa-youtube-square:before{content:""}.fa-youtube:before{content:""}.fa-xing:before{content:""}.fa-xing-square:before{content:""}.fa-youtube-play:before{content:""}.fa-dropbox:before{content:""}.fa-stack-overflow:before{content:""}.fa-instagram:before{content:""}.fa-flickr:before{content:""}.fa-adn:before{content:""}.fa-bitbucket:before,.icon-bitbucket:before{content:""}.fa-bitbucket-square:before{content:""}.fa-tumblr:before{content:""}.fa-tumblr-square:before{content:""}.fa-long-arrow-down:before{content:""}.fa-long-arrow-up:before{content:""}.fa-long-arrow-left:before{content:""}.fa-long-arrow-right:before{content:""}.fa-apple:before{content:""}.fa-windows:before{content:""}.fa-android:before{content:""}.fa-linux:before{content:""}.fa-dribbble:before{content:""}.fa-skype:before{content:""}.fa-foursquare:before{content:""}.fa-trello:before{content:""}.fa-female:before{content:""}.fa-male:before{content:""}.fa-gittip:before,.fa-gratipay:before{content:""}.fa-sun-o:before{content:""}.fa-moon-o:before{content:""}.fa-archive:before{content:""}.fa-bug:before{content:""}.fa-vk:before{content:""}.fa-weibo:before{content:""}.fa-renren:before{content:""}.fa-pagelines:before{content:""}.fa-stack-exchange:before{content:""}.fa-arrow-circle-o-right:before{content:""}.fa-arrow-circle-o-left:before{content:""}.fa-caret-square-o-left:before,.fa-toggle-left:before{content:""}.fa-dot-circle-o:before{content:""}.fa-wheelchair:before{content:""}.fa-vimeo-square:before{content:""}.fa-try:before,.fa-turkish-lira:before{content:""}.fa-plus-square-o:before,.wy-menu-vertical li span.toctree-expand:before{content:""}.fa-space-shuttle:before{content:""}.fa-slack:before{content:""}.fa-envelope-square:before{content:""}.fa-wordpress:before{content:""}.fa-openid:before{content:""}.fa-bank:before,.fa-institution:before,.fa-university:before{content:""}.fa-graduation-cap:before,.fa-mortar-board:before{content:""}.fa-yahoo:before{content:""}.fa-google:before{content:""}.fa-reddit:before{content:""}.fa-reddit-square:before{content:""}.fa-stumbleupon-circle:before{content:""}.fa-stumbleupon:before{content:""}.fa-delicious:before{content:""}.fa-digg:before{content:""}.fa-pied-piper-pp:before{content:""}.fa-pied-piper-alt:before{content:""}.fa-drupal:before{content:""}.fa-joomla:before{content:""}.fa-language:before{content:""}.fa-fax:before{content:""}.fa-building:before{content:""}.fa-child:before{content:""}.fa-paw:before{content:""}.fa-spoon:before{content:""}.fa-cube:before{content:""}.fa-cubes:before{content:""}.fa-behance:before{content:""}.fa-behance-square:before{content:""}.fa-steam:before{content:""}.fa-steam-square:before{content:""}.fa-recycle:before{content:""}.fa-automobile:before,.fa-car:before{content:""}.fa-cab:before,.fa-taxi:before{content:""}.fa-tree:before{content:""}.fa-spotify:before{content:""}.fa-deviantart:before{content:""}.fa-soundcloud:before{content:""}.fa-database:before{content:""}.fa-file-pdf-o:before{content:""}.fa-file-word-o:before{content:""}.fa-file-excel-o:before{content:""}.fa-file-powerpoint-o:before{content:""}.fa-file-image-o:before,.fa-file-photo-o:before,.fa-file-picture-o:before{content:""}.fa-file-archive-o:before,.fa-file-zip-o:before{content:""}.fa-file-audio-o:before,.fa-file-sound-o:before{content:""}.fa-file-movie-o:before,.fa-file-video-o:before{content:""}.fa-file-code-o:before{content:""}.fa-vine:before{content:""}.fa-codepen:before{content:""}.fa-jsfiddle:before{content:""}.fa-life-bouy:before,.fa-life-buoy:before,.fa-life-ring:before,.fa-life-saver:before,.fa-support:before{content:""}.fa-circle-o-notch:before{content:""}.fa-ra:before,.fa-rebel:before,.fa-resistance:before{content:""}.fa-empire:before,.fa-ge:before{content:""}.fa-git-square:before{content:""}.fa-git:before{content:""}.fa-hacker-news:before,.fa-y-combinator-square:before,.fa-yc-square:before{content:""}.fa-tencent-weibo:before{content:""}.fa-qq:before{content:""}.fa-wechat:before,.fa-weixin:before{content:""}.fa-paper-plane:before,.fa-send:before{content:""}.fa-paper-plane-o:before,.fa-send-o:before{content:""}.fa-history:before{content:""}.fa-circle-thin:before{content:""}.fa-header:before{content:""}.fa-paragraph:before{content:""}.fa-sliders:before{content:""}.fa-share-alt:before{content:""}.fa-share-alt-square:before{content:""}.fa-bomb:before{content:""}.fa-futbol-o:before,.fa-soccer-ball-o:before{content:""}.fa-tty:before{content:""}.fa-binoculars:before{content:""}.fa-plug:before{content:""}.fa-slideshare:before{content:""}.fa-twitch:before{content:""}.fa-yelp:before{content:""}.fa-newspaper-o:before{content:""}.fa-wifi:before{content:""}.fa-calculator:before{content:""}.fa-paypal:before{content:""}.fa-google-wallet:before{content:""}.fa-cc-visa:before{content:""}.fa-cc-mastercard:before{content:""}.fa-cc-discover:before{content:""}.fa-cc-amex:before{content:""}.fa-cc-paypal:before{content:""}.fa-cc-stripe:before{content:""}.fa-bell-slash:before{content:""}.fa-bell-slash-o:before{content:""}.fa-trash:before{content:""}.fa-copyright:before{content:""}.fa-at:before{content:""}.fa-eyedropper:before{content:""}.fa-paint-brush:before{content:""}.fa-birthday-cake:before{content:""}.fa-area-chart:before{content:""}.fa-pie-chart:before{content:""}.fa-line-chart:before{content:""}.fa-lastfm:before{content:""}.fa-lastfm-square:before{content:""}.fa-toggle-off:before{content:""}.fa-toggle-on:before{content:""}.fa-bicycle:before{content:""}.fa-bus:before{content:""}.fa-ioxhost:before{content:""}.fa-angellist:before{content:""}.fa-cc:before{content:""}.fa-ils:before,.fa-shekel:before,.fa-sheqel:before{content:""}.fa-meanpath:before{content:""}.fa-buysellads:before{content:""}.fa-connectdevelop:before{content:""}.fa-dashcube:before{content:""}.fa-forumbee:before{content:""}.fa-leanpub:before{content:""}.fa-sellsy:before{content:""}.fa-shirtsinbulk:before{content:""}.fa-simplybuilt:before{content:""}.fa-skyatlas:before{content:""}.fa-cart-plus:before{content:""}.fa-cart-arrow-down:before{content:""}.fa-diamond:before{content:""}.fa-ship:before{content:""}.fa-user-secret:before{content:""}.fa-motorcycle:before{content:""}.fa-street-view:before{content:""}.fa-heartbeat:before{content:""}.fa-venus:before{content:""}.fa-mars:before{content:""}.fa-mercury:before{content:""}.fa-intersex:before,.fa-transgender:before{content:""}.fa-transgender-alt:before{content:""}.fa-venus-double:before{content:""}.fa-mars-double:before{content:""}.fa-venus-mars:before{content:""}.fa-mars-stroke:before{content:""}.fa-mars-stroke-v:before{content:""}.fa-mars-stroke-h:before{content:""}.fa-neuter:before{content:""}.fa-genderless:before{content:""}.fa-facebook-official:before{content:""}.fa-pinterest-p:before{content:""}.fa-whatsapp:before{content:""}.fa-server:before{content:""}.fa-user-plus:before{content:""}.fa-user-times:before{content:""}.fa-bed:before,.fa-hotel:before{content:""}.fa-viacoin:before{content:""}.fa-train:before{content:""}.fa-subway:before{content:""}.fa-medium:before{content:""}.fa-y-combinator:before,.fa-yc:before{content:""}.fa-optin-monster:before{content:""}.fa-opencart:before{content:""}.fa-expeditedssl:before{content:""}.fa-battery-4:before,.fa-battery-full:before,.fa-battery:before{content:""}.fa-battery-3:before,.fa-battery-three-quarters:before{content:""}.fa-battery-2:before,.fa-battery-half:before{content:""}.fa-battery-1:before,.fa-battery-quarter:before{content:""}.fa-battery-0:before,.fa-battery-empty:before{content:""}.fa-mouse-pointer:before{content:""}.fa-i-cursor:before{content:""}.fa-object-group:before{content:""}.fa-object-ungroup:before{content:""}.fa-sticky-note:before{content:""}.fa-sticky-note-o:before{content:""}.fa-cc-jcb:before{content:""}.fa-cc-diners-club:before{content:""}.fa-clone:before{content:""}.fa-balance-scale:before{content:""}.fa-hourglass-o:before{content:""}.fa-hourglass-1:before,.fa-hourglass-start:before{content:""}.fa-hourglass-2:before,.fa-hourglass-half:before{content:""}.fa-hourglass-3:before,.fa-hourglass-end:before{content:""}.fa-hourglass:before{content:""}.fa-hand-grab-o:before,.fa-hand-rock-o:before{content:""}.fa-hand-paper-o:before,.fa-hand-stop-o:before{content:""}.fa-hand-scissors-o:before{content:""}.fa-hand-lizard-o:before{content:""}.fa-hand-spock-o:before{content:""}.fa-hand-pointer-o:before{content:""}.fa-hand-peace-o:before{content:""}.fa-trademark:before{content:""}.fa-registered:before{content:""}.fa-creative-commons:before{content:""}.fa-gg:before{content:""}.fa-gg-circle:before{content:""}.fa-tripadvisor:before{content:""}.fa-odnoklassniki:before{content:""}.fa-odnoklassniki-square:before{content:""}.fa-get-pocket:before{content:""}.fa-wikipedia-w:before{content:""}.fa-safari:before{content:""}.fa-chrome:before{content:""}.fa-firefox:before{content:""}.fa-opera:before{content:""}.fa-internet-explorer:before{content:""}.fa-television:before,.fa-tv:before{content:""}.fa-contao:before{content:""}.fa-500px:before{content:""}.fa-amazon:before{content:""}.fa-calendar-plus-o:before{content:""}.fa-calendar-minus-o:before{content:""}.fa-calendar-times-o:before{content:""}.fa-calendar-check-o:before{content:""}.fa-industry:before{content:""}.fa-map-pin:before{content:""}.fa-map-signs:before{content:""}.fa-map-o:before{content:""}.fa-map:before{content:""}.fa-commenting:before{content:""}.fa-commenting-o:before{content:""}.fa-houzz:before{content:""}.fa-vimeo:before{content:""}.fa-black-tie:before{content:""}.fa-fonticons:before{content:""}.fa-reddit-alien:before{content:""}.fa-edge:before{content:""}.fa-credit-card-alt:before{content:""}.fa-codiepie:before{content:""}.fa-modx:before{content:""}.fa-fort-awesome:before{content:""}.fa-usb:before{content:""}.fa-product-hunt:before{content:""}.fa-mixcloud:before{content:""}.fa-scribd:before{content:""}.fa-pause-circle:before{content:""}.fa-pause-circle-o:before{content:""}.fa-stop-circle:before{content:""}.fa-stop-circle-o:before{content:""}.fa-shopping-bag:before{content:""}.fa-shopping-basket:before{content:""}.fa-hashtag:before{content:""}.fa-bluetooth:before{content:""}.fa-bluetooth-b:before{content:""}.fa-percent:before{content:""}.fa-gitlab:before,.icon-gitlab:before{content:""}.fa-wpbeginner:before{content:""}.fa-wpforms:before{content:""}.fa-envira:before{content:""}.fa-universal-access:before{content:""}.fa-wheelchair-alt:before{content:""}.fa-question-circle-o:before{content:""}.fa-blind:before{content:""}.fa-audio-description:before{content:""}.fa-volume-control-phone:before{content:""}.fa-braille:before{content:""}.fa-assistive-listening-systems:before{content:""}.fa-american-sign-language-interpreting:before,.fa-asl-interpreting:before{content:""}.fa-deaf:before,.fa-deafness:before,.fa-hard-of-hearing:before{content:""}.fa-glide:before{content:""}.fa-glide-g:before{content:""}.fa-sign-language:before,.fa-signing:before{content:""}.fa-low-vision:before{content:""}.fa-viadeo:before{content:""}.fa-viadeo-square:before{content:""}.fa-snapchat:before{content:""}.fa-snapchat-ghost:before{content:""}.fa-snapchat-square:before{content:""}.fa-pied-piper:before{content:""}.fa-first-order:before{content:""}.fa-yoast:before{content:""}.fa-themeisle:before{content:""}.fa-google-plus-circle:before,.fa-google-plus-official:before{content:""}.fa-fa:before,.fa-font-awesome:before{content:""}.fa-handshake-o:before{content:""}.fa-envelope-open:before{content:""}.fa-envelope-open-o:before{content:""}.fa-linode:before{content:""}.fa-address-book:before{content:""}.fa-address-book-o:before{content:""}.fa-address-card:before,.fa-vcard:before{content:""}.fa-address-card-o:before,.fa-vcard-o:before{content:""}.fa-user-circle:before{content:""}.fa-user-circle-o:before{content:""}.fa-user-o:before{content:""}.fa-id-badge:before{content:""}.fa-drivers-license:before,.fa-id-card:before{content:""}.fa-drivers-license-o:before,.fa-id-card-o:before{content:""}.fa-quora:before{content:""}.fa-free-code-camp:before{content:""}.fa-telegram:before{content:""}.fa-thermometer-4:before,.fa-thermometer-full:before,.fa-thermometer:before{content:""}.fa-thermometer-3:before,.fa-thermometer-three-quarters:before{content:""}.fa-thermometer-2:before,.fa-thermometer-half:before{content:""}.fa-thermometer-1:before,.fa-thermometer-quarter:before{content:""}.fa-thermometer-0:before,.fa-thermometer-empty:before{content:""}.fa-shower:before{content:""}.fa-bath:before,.fa-bathtub:before,.fa-s15:before{content:""}.fa-podcast:before{content:""}.fa-window-maximize:before{content:""}.fa-window-minimize:before{content:""}.fa-window-restore:before{content:""}.fa-times-rectangle:before,.fa-window-close:before{content:""}.fa-times-rectangle-o:before,.fa-window-close-o:before{content:""}.fa-bandcamp:before{content:""}.fa-grav:before{content:""}.fa-etsy:before{content:""}.fa-imdb:before{content:""}.fa-ravelry:before{content:""}.fa-eercast:before{content:""}.fa-microchip:before{content:""}.fa-snowflake-o:before{content:""}.fa-superpowers:before{content:""}.fa-wpexplorer:before{content:""}.fa-meetup:before{content:""}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto}.fa,.icon,.rst-content .admonition-title,.rst-content .code-block-caption .headerlink,.rst-content code.download span:first-child,.rst-content dl dt .headerlink,.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content p.caption .headerlink,.rst-content table>caption .headerlink,.rst-content tt.download span:first-child,.wy-dropdown .caret,.wy-inline-validate.wy-inline-validate-danger .wy-input-context,.wy-inline-validate.wy-inline-validate-info .wy-input-context,.wy-inline-validate.wy-inline-validate-success .wy-input-context,.wy-inline-validate.wy-inline-validate-warning .wy-input-context,.wy-menu-vertical li.current>a span.toctree-expand,.wy-menu-vertical li.on a span.toctree-expand,.wy-menu-vertical li span.toctree-expand{font-family:inherit}.fa:before,.icon:before,.rst-content .admonition-title:before,.rst-content .code-block-caption .headerlink:before,.rst-content code.download span:first-child:before,.rst-content dl dt .headerlink:before,.rst-content h1 .headerlink:before,.rst-content h2 .headerlink:before,.rst-content h3 .headerlink:before,.rst-content h4 .headerlink:before,.rst-content h5 .headerlink:before,.rst-content h6 .headerlink:before,.rst-content p.caption .headerlink:before,.rst-content table>caption .headerlink:before,.rst-content tt.download span:first-child:before,.wy-dropdown .caret:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before,.wy-menu-vertical li.current>a span.toctree-expand:before,.wy-menu-vertical li.on a span.toctree-expand:before,.wy-menu-vertical li span.toctree-expand:before{font-family:FontAwesome;display:inline-block;font-style:normal;font-weight:400;line-height:1;text-decoration:inherit}.rst-content .code-block-caption a .headerlink,.rst-content a .admonition-title,.rst-content code.download a span:first-child,.rst-content dl dt a .headerlink,.rst-content h1 a .headerlink,.rst-content h2 a .headerlink,.rst-content h3 a .headerlink,.rst-content h4 a .headerlink,.rst-content h5 a .headerlink,.rst-content h6 a .headerlink,.rst-content p.caption a .headerlink,.rst-content table>caption a .headerlink,.rst-content tt.download a span:first-child,.wy-menu-vertical li.current>a span.toctree-expand,.wy-menu-vertical li.on a span.toctree-expand,.wy-menu-vertical li a span.toctree-expand,a .fa,a .icon,a .rst-content .admonition-title,a .rst-content .code-block-caption .headerlink,a .rst-content code.download span:first-child,a .rst-content dl dt .headerlink,a .rst-content h1 .headerlink,a .rst-content h2 .headerlink,a .rst-content h3 .headerlink,a .rst-content h4 .headerlink,a .rst-content h5 .headerlink,a .rst-content h6 .headerlink,a .rst-content p.caption .headerlink,a .rst-content table>caption .headerlink,a .rst-content tt.download span:first-child,a .wy-menu-vertical li span.toctree-expand{display:inline-block;text-decoration:inherit}.btn .fa,.btn .icon,.btn .rst-content .admonition-title,.btn .rst-content .code-block-caption .headerlink,.btn .rst-content code.download span:first-child,.btn .rst-content dl dt .headerlink,.btn .rst-content h1 .headerlink,.btn .rst-content h2 .headerlink,.btn .rst-content h3 .headerlink,.btn .rst-content h4 .headerlink,.btn .rst-content h5 .headerlink,.btn .rst-content h6 .headerlink,.btn .rst-content p.caption .headerlink,.btn .rst-content table>caption .headerlink,.btn .rst-content tt.download span:first-child,.btn .wy-menu-vertical li.current>a span.toctree-expand,.btn .wy-menu-vertical li.on a span.toctree-expand,.btn .wy-menu-vertical li span.toctree-expand,.nav .fa,.nav .icon,.nav .rst-content .admonition-title,.nav .rst-content .code-block-caption .headerlink,.nav .rst-content code.download span:first-child,.nav .rst-content dl dt .headerlink,.nav .rst-content h1 .headerlink,.nav .rst-content h2 .headerlink,.nav .rst-content h3 .headerlink,.nav .rst-content h4 .headerlink,.nav .rst-content h5 .headerlink,.nav .rst-content h6 .headerlink,.nav .rst-content p.caption .headerlink,.nav .rst-content table>caption .headerlink,.nav .rst-content tt.download span:first-child,.nav .wy-menu-vertical li.current>a span.toctree-expand,.nav .wy-menu-vertical li.on a span.toctree-expand,.nav .wy-menu-vertical li span.toctree-expand,.rst-content .btn .admonition-title,.rst-content .code-block-caption .btn .headerlink,.rst-content .code-block-caption .nav .headerlink,.rst-content .nav .admonition-title,.rst-content code.download .btn span:first-child,.rst-content code.download .nav span:first-child,.rst-content dl dt .btn .headerlink,.rst-content dl dt .nav .headerlink,.rst-content h1 .btn .headerlink,.rst-content h1 .nav .headerlink,.rst-content h2 .btn .headerlink,.rst-content h2 .nav .headerlink,.rst-content h3 .btn .headerlink,.rst-content h3 .nav .headerlink,.rst-content h4 .btn .headerlink,.rst-content h4 .nav .headerlink,.rst-content h5 .btn .headerlink,.rst-content h5 .nav .headerlink,.rst-content h6 .btn .headerlink,.rst-content h6 .nav .headerlink,.rst-content p.caption .btn .headerlink,.rst-content p.caption .nav .headerlink,.rst-content table>caption .btn .headerlink,.rst-content table>caption .nav .headerlink,.rst-content tt.download .btn span:first-child,.rst-content tt.download .nav span:first-child,.wy-menu-vertical li .btn span.toctree-expand,.wy-menu-vertical li.current>a .btn span.toctree-expand,.wy-menu-vertical li.current>a .nav span.toctree-expand,.wy-menu-vertical li .nav span.toctree-expand,.wy-menu-vertical li.on a .btn span.toctree-expand,.wy-menu-vertical li.on a .nav span.toctree-expand{display:inline}.btn .fa-large.icon,.btn .fa.fa-large,.btn .rst-content .code-block-caption .fa-large.headerlink,.btn .rst-content .fa-large.admonition-title,.btn .rst-content code.download span.fa-large:first-child,.btn .rst-content dl dt .fa-large.headerlink,.btn .rst-content h1 .fa-large.headerlink,.btn .rst-content h2 .fa-large.headerlink,.btn .rst-content h3 .fa-large.headerlink,.btn .rst-content h4 .fa-large.headerlink,.btn .rst-content h5 .fa-large.headerlink,.btn .rst-content h6 .fa-large.headerlink,.btn .rst-content p.caption .fa-large.headerlink,.btn .rst-content table>caption .fa-large.headerlink,.btn .rst-content tt.download span.fa-large:first-child,.btn .wy-menu-vertical li span.fa-large.toctree-expand,.nav .fa-large.icon,.nav .fa.fa-large,.nav .rst-content .code-block-caption .fa-large.headerlink,.nav .rst-content .fa-large.admonition-title,.nav .rst-content code.download span.fa-large:first-child,.nav .rst-content dl dt .fa-large.headerlink,.nav .rst-content h1 .fa-large.headerlink,.nav .rst-content h2 .fa-large.headerlink,.nav .rst-content h3 .fa-large.headerlink,.nav .rst-content h4 .fa-large.headerlink,.nav .rst-content h5 .fa-large.headerlink,.nav .rst-content h6 .fa-large.headerlink,.nav .rst-content p.caption .fa-large.headerlink,.nav .rst-content table>caption .fa-large.headerlink,.nav .rst-content tt.download span.fa-large:first-child,.nav .wy-menu-vertical li span.fa-large.toctree-expand,.rst-content .btn .fa-large.admonition-title,.rst-content .code-block-caption .btn .fa-large.headerlink,.rst-content .code-block-caption .nav .fa-large.headerlink,.rst-content .nav .fa-large.admonition-title,.rst-content code.download .btn span.fa-large:first-child,.rst-content code.download .nav span.fa-large:first-child,.rst-content dl dt .btn .fa-large.headerlink,.rst-content dl dt .nav .fa-large.headerlink,.rst-content h1 .btn .fa-large.headerlink,.rst-content h1 .nav .fa-large.headerlink,.rst-content h2 .btn .fa-large.headerlink,.rst-content h2 .nav .fa-large.headerlink,.rst-content h3 .btn .fa-large.headerlink,.rst-content h3 .nav .fa-large.headerlink,.rst-content h4 .btn .fa-large.headerlink,.rst-content h4 .nav .fa-large.headerlink,.rst-content h5 .btn .fa-large.headerlink,.rst-content h5 .nav .fa-large.headerlink,.rst-content h6 .btn .fa-large.headerlink,.rst-content h6 .nav .fa-large.headerlink,.rst-content p.caption .btn .fa-large.headerlink,.rst-content p.caption .nav .fa-large.headerlink,.rst-content table>caption .btn .fa-large.headerlink,.rst-content table>caption .nav .fa-large.headerlink,.rst-content tt.download .btn span.fa-large:first-child,.rst-content tt.download .nav span.fa-large:first-child,.wy-menu-vertical li .btn span.fa-large.toctree-expand,.wy-menu-vertical li .nav span.fa-large.toctree-expand{line-height:.9em}.btn .fa-spin.icon,.btn .fa.fa-spin,.btn .rst-content .code-block-caption .fa-spin.headerlink,.btn .rst-content .fa-spin.admonition-title,.btn .rst-content code.download span.fa-spin:first-child,.btn .rst-content dl dt .fa-spin.headerlink,.btn .rst-content h1 .fa-spin.headerlink,.btn .rst-content h2 .fa-spin.headerlink,.btn .rst-content h3 .fa-spin.headerlink,.btn .rst-content h4 .fa-spin.headerlink,.btn .rst-content h5 .fa-spin.headerlink,.btn .rst-content h6 .fa-spin.headerlink,.btn .rst-content p.caption .fa-spin.headerlink,.btn .rst-content table>caption .fa-spin.headerlink,.btn .rst-content tt.download span.fa-spin:first-child,.btn .wy-menu-vertical li span.fa-spin.toctree-expand,.nav .fa-spin.icon,.nav .fa.fa-spin,.nav .rst-content .code-block-caption .fa-spin.headerlink,.nav .rst-content .fa-spin.admonition-title,.nav .rst-content code.download span.fa-spin:first-child,.nav .rst-content dl dt .fa-spin.headerlink,.nav .rst-content h1 .fa-spin.headerlink,.nav .rst-content h2 .fa-spin.headerlink,.nav .rst-content h3 .fa-spin.headerlink,.nav .rst-content h4 .fa-spin.headerlink,.nav .rst-content h5 .fa-spin.headerlink,.nav .rst-content h6 .fa-spin.headerlink,.nav .rst-content p.caption .fa-spin.headerlink,.nav .rst-content table>caption .fa-spin.headerlink,.nav .rst-content tt.download span.fa-spin:first-child,.nav .wy-menu-vertical li span.fa-spin.toctree-expand,.rst-content .btn .fa-spin.admonition-title,.rst-content .code-block-caption .btn .fa-spin.headerlink,.rst-content .code-block-caption .nav .fa-spin.headerlink,.rst-content .nav .fa-spin.admonition-title,.rst-content code.download .btn span.fa-spin:first-child,.rst-content code.download .nav span.fa-spin:first-child,.rst-content dl dt .btn .fa-spin.headerlink,.rst-content dl dt .nav .fa-spin.headerlink,.rst-content h1 .btn .fa-spin.headerlink,.rst-content h1 .nav .fa-spin.headerlink,.rst-content h2 .btn .fa-spin.headerlink,.rst-content h2 .nav .fa-spin.headerlink,.rst-content h3 .btn .fa-spin.headerlink,.rst-content h3 .nav .fa-spin.headerlink,.rst-content h4 .btn .fa-spin.headerlink,.rst-content h4 .nav .fa-spin.headerlink,.rst-content h5 .btn .fa-spin.headerlink,.rst-content h5 .nav .fa-spin.headerlink,.rst-content h6 .btn .fa-spin.headerlink,.rst-content h6 .nav .fa-spin.headerlink,.rst-content p.caption .btn .fa-spin.headerlink,.rst-content p.caption .nav .fa-spin.headerlink,.rst-content table>caption .btn .fa-spin.headerlink,.rst-content table>caption .nav .fa-spin.headerlink,.rst-content tt.download .btn span.fa-spin:first-child,.rst-content tt.download .nav span.fa-spin:first-child,.wy-menu-vertical li .btn span.fa-spin.toctree-expand,.wy-menu-vertical li .nav span.fa-spin.toctree-expand{display:inline-block}.btn.fa:before,.btn.icon:before,.rst-content .btn.admonition-title:before,.rst-content .code-block-caption .btn.headerlink:before,.rst-content code.download span.btn:first-child:before,.rst-content dl dt .btn.headerlink:before,.rst-content h1 .btn.headerlink:before,.rst-content h2 .btn.headerlink:before,.rst-content h3 .btn.headerlink:before,.rst-content h4 .btn.headerlink:before,.rst-content h5 .btn.headerlink:before,.rst-content h6 .btn.headerlink:before,.rst-content p.caption .btn.headerlink:before,.rst-content table>caption .btn.headerlink:before,.rst-content tt.download span.btn:first-child:before,.wy-menu-vertical li span.btn.toctree-expand:before{opacity:.5;-webkit-transition:opacity .05s ease-in;-moz-transition:opacity .05s ease-in;transition:opacity .05s ease-in}.btn.fa:hover:before,.btn.icon:hover:before,.rst-content .btn.admonition-title:hover:before,.rst-content .code-block-caption .btn.headerlink:hover:before,.rst-content code.download span.btn:first-child:hover:before,.rst-content dl dt .btn.headerlink:hover:before,.rst-content h1 .btn.headerlink:hover:before,.rst-content h2 .btn.headerlink:hover:before,.rst-content h3 .btn.headerlink:hover:before,.rst-content h4 .btn.headerlink:hover:before,.rst-content h5 .btn.headerlink:hover:before,.rst-content h6 .btn.headerlink:hover:before,.rst-content p.caption .btn.headerlink:hover:before,.rst-content table>caption .btn.headerlink:hover:before,.rst-content tt.download span.btn:first-child:hover:before,.wy-menu-vertical li span.btn.toctree-expand:hover:before{opacity:1}.btn-mini .fa:before,.btn-mini .icon:before,.btn-mini .rst-content .admonition-title:before,.btn-mini .rst-content .code-block-caption .headerlink:before,.btn-mini .rst-content code.download span:first-child:before,.btn-mini .rst-content dl dt .headerlink:before,.btn-mini .rst-content h1 .headerlink:before,.btn-mini .rst-content h2 .headerlink:before,.btn-mini .rst-content h3 .headerlink:before,.btn-mini .rst-content h4 .headerlink:before,.btn-mini .rst-content h5 .headerlink:before,.btn-mini .rst-content h6 .headerlink:before,.btn-mini .rst-content p.caption .headerlink:before,.btn-mini .rst-content table>caption .headerlink:before,.btn-mini .rst-content tt.download span:first-child:before,.btn-mini .wy-menu-vertical li span.toctree-expand:before,.rst-content .btn-mini .admonition-title:before,.rst-content .code-block-caption .btn-mini .headerlink:before,.rst-content code.download .btn-mini span:first-child:before,.rst-content dl dt .btn-mini .headerlink:before,.rst-content h1 .btn-mini .headerlink:before,.rst-content h2 .btn-mini .headerlink:before,.rst-content h3 .btn-mini .headerlink:before,.rst-content h4 .btn-mini .headerlink:before,.rst-content h5 .btn-mini .headerlink:before,.rst-content h6 .btn-mini .headerlink:before,.rst-content p.caption .btn-mini .headerlink:before,.rst-content table>caption .btn-mini .headerlink:before,.rst-content tt.download .btn-mini span:first-child:before,.wy-menu-vertical li .btn-mini span.toctree-expand:before{font-size:14px;vertical-align:-15%}.rst-content .admonition,.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .danger,.rst-content .error,.rst-content .hint,.rst-content .important,.rst-content .note,.rst-content .seealso,.rst-content .tip,.rst-content .warning,.wy-alert{padding:12px;line-height:24px;margin-bottom:24px;background:#e7f2fa}.rst-content .admonition-title,.wy-alert-title{font-weight:700;display:block;color:#fff;background:#6ab0de;padding:6px 12px;margin:-12px -12px 12px}.rst-content .danger,.rst-content .error,.rst-content .wy-alert-danger.admonition,.rst-content .wy-alert-danger.admonition-todo,.rst-content .wy-alert-danger.attention,.rst-content .wy-alert-danger.caution,.rst-content .wy-alert-danger.hint,.rst-content .wy-alert-danger.important,.rst-content .wy-alert-danger.note,.rst-content .wy-alert-danger.seealso,.rst-content .wy-alert-danger.tip,.rst-content .wy-alert-danger.warning,.wy-alert.wy-alert-danger{background:#fdf3f2}.rst-content .danger .admonition-title,.rst-content .danger .wy-alert-title,.rst-content .error .admonition-title,.rst-content .error .wy-alert-title,.rst-content .wy-alert-danger.admonition-todo .admonition-title,.rst-content .wy-alert-danger.admonition-todo .wy-alert-title,.rst-content .wy-alert-danger.admonition .admonition-title,.rst-content .wy-alert-danger.admonition .wy-alert-title,.rst-content .wy-alert-danger.attention .admonition-title,.rst-content .wy-alert-danger.attention .wy-alert-title,.rst-content .wy-alert-danger.caution .admonition-title,.rst-content .wy-alert-danger.caution .wy-alert-title,.rst-content .wy-alert-danger.hint .admonition-title,.rst-content .wy-alert-danger.hint .wy-alert-title,.rst-content .wy-alert-danger.important .admonition-title,.rst-content .wy-alert-danger.important .wy-alert-title,.rst-content .wy-alert-danger.note .admonition-title,.rst-content .wy-alert-danger.note .wy-alert-title,.rst-content .wy-alert-danger.seealso .admonition-title,.rst-content .wy-alert-danger.seealso .wy-alert-title,.rst-content .wy-alert-danger.tip .admonition-title,.rst-content .wy-alert-danger.tip .wy-alert-title,.rst-content .wy-alert-danger.warning .admonition-title,.rst-content .wy-alert-danger.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-danger .admonition-title,.wy-alert.wy-alert-danger .rst-content .admonition-title,.wy-alert.wy-alert-danger .wy-alert-title{background:#f29f97}.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .warning,.rst-content .wy-alert-warning.admonition,.rst-content .wy-alert-warning.danger,.rst-content .wy-alert-warning.error,.rst-content .wy-alert-warning.hint,.rst-content .wy-alert-warning.important,.rst-content .wy-alert-warning.note,.rst-content .wy-alert-warning.seealso,.rst-content .wy-alert-warning.tip,.wy-alert.wy-alert-warning{background:#ffedcc}.rst-content .admonition-todo .admonition-title,.rst-content .admonition-todo .wy-alert-title,.rst-content .attention .admonition-title,.rst-content .attention .wy-alert-title,.rst-content .caution .admonition-title,.rst-content .caution .wy-alert-title,.rst-content .warning .admonition-title,.rst-content .warning .wy-alert-title,.rst-content .wy-alert-warning.admonition .admonition-title,.rst-content .wy-alert-warning.admonition .wy-alert-title,.rst-content .wy-alert-warning.danger .admonition-title,.rst-content .wy-alert-warning.danger .wy-alert-title,.rst-content .wy-alert-warning.error .admonition-title,.rst-content .wy-alert-warning.error .wy-alert-title,.rst-content .wy-alert-warning.hint .admonition-title,.rst-content .wy-alert-warning.hint .wy-alert-title,.rst-content .wy-alert-warning.important .admonition-title,.rst-content .wy-alert-warning.important .wy-alert-title,.rst-content .wy-alert-warning.note .admonition-title,.rst-content .wy-alert-warning.note .wy-alert-title,.rst-content .wy-alert-warning.seealso .admonition-title,.rst-content .wy-alert-warning.seealso .wy-alert-title,.rst-content .wy-alert-warning.tip .admonition-title,.rst-content .wy-alert-warning.tip .wy-alert-title,.rst-content .wy-alert.wy-alert-warning .admonition-title,.wy-alert.wy-alert-warning .rst-content .admonition-title,.wy-alert.wy-alert-warning .wy-alert-title{background:#f0b37e}.rst-content .note,.rst-content .seealso,.rst-content .wy-alert-info.admonition,.rst-content .wy-alert-info.admonition-todo,.rst-content .wy-alert-info.attention,.rst-content .wy-alert-info.caution,.rst-content .wy-alert-info.danger,.rst-content .wy-alert-info.error,.rst-content .wy-alert-info.hint,.rst-content .wy-alert-info.important,.rst-content .wy-alert-info.tip,.rst-content .wy-alert-info.warning,.wy-alert.wy-alert-info{background:#e7f2fa}.rst-content .note .admonition-title,.rst-content .note .wy-alert-title,.rst-content .seealso .admonition-title,.rst-content .seealso .wy-alert-title,.rst-content .wy-alert-info.admonition-todo .admonition-title,.rst-content .wy-alert-info.admonition-todo .wy-alert-title,.rst-content .wy-alert-info.admonition .admonition-title,.rst-content .wy-alert-info.admonition .wy-alert-title,.rst-content .wy-alert-info.attention .admonition-title,.rst-content .wy-alert-info.attention .wy-alert-title,.rst-content .wy-alert-info.caution .admonition-title,.rst-content .wy-alert-info.caution .wy-alert-title,.rst-content .wy-alert-info.danger .admonition-title,.rst-content .wy-alert-info.danger .wy-alert-title,.rst-content .wy-alert-info.error .admonition-title,.rst-content .wy-alert-info.error .wy-alert-title,.rst-content .wy-alert-info.hint .admonition-title,.rst-content .wy-alert-info.hint .wy-alert-title,.rst-content .wy-alert-info.important .admonition-title,.rst-content .wy-alert-info.important .wy-alert-title,.rst-content .wy-alert-info.tip .admonition-title,.rst-content .wy-alert-info.tip .wy-alert-title,.rst-content .wy-alert-info.warning .admonition-title,.rst-content .wy-alert-info.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-info .admonition-title,.wy-alert.wy-alert-info .rst-content .admonition-title,.wy-alert.wy-alert-info .wy-alert-title{background:#6ab0de}.rst-content .hint,.rst-content .important,.rst-content .tip,.rst-content .wy-alert-success.admonition,.rst-content .wy-alert-success.admonition-todo,.rst-content .wy-alert-success.attention,.rst-content .wy-alert-success.caution,.rst-content .wy-alert-success.danger,.rst-content .wy-alert-success.error,.rst-content .wy-alert-success.note,.rst-content .wy-alert-success.seealso,.rst-content .wy-alert-success.warning,.wy-alert.wy-alert-success{background:#dbfaf4}.rst-content .hint .admonition-title,.rst-content .hint .wy-alert-title,.rst-content .important .admonition-title,.rst-content .important .wy-alert-title,.rst-content .tip .admonition-title,.rst-content .tip .wy-alert-title,.rst-content .wy-alert-success.admonition-todo .admonition-title,.rst-content .wy-alert-success.admonition-todo .wy-alert-title,.rst-content .wy-alert-success.admonition .admonition-title,.rst-content .wy-alert-success.admonition .wy-alert-title,.rst-content .wy-alert-success.attention .admonition-title,.rst-content .wy-alert-success.attention .wy-alert-title,.rst-content .wy-alert-success.caution .admonition-title,.rst-content .wy-alert-success.caution .wy-alert-title,.rst-content .wy-alert-success.danger .admonition-title,.rst-content .wy-alert-success.danger .wy-alert-title,.rst-content .wy-alert-success.error .admonition-title,.rst-content .wy-alert-success.error .wy-alert-title,.rst-content .wy-alert-success.note .admonition-title,.rst-content .wy-alert-success.note .wy-alert-title,.rst-content .wy-alert-success.seealso .admonition-title,.rst-content .wy-alert-success.seealso .wy-alert-title,.rst-content .wy-alert-success.warning .admonition-title,.rst-content .wy-alert-success.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-success .admonition-title,.wy-alert.wy-alert-success .rst-content .admonition-title,.wy-alert.wy-alert-success .wy-alert-title{background:#1abc9c}.rst-content .wy-alert-neutral.admonition,.rst-content .wy-alert-neutral.admonition-todo,.rst-content .wy-alert-neutral.attention,.rst-content .wy-alert-neutral.caution,.rst-content .wy-alert-neutral.danger,.rst-content .wy-alert-neutral.error,.rst-content .wy-alert-neutral.hint,.rst-content .wy-alert-neutral.important,.rst-content .wy-alert-neutral.note,.rst-content .wy-alert-neutral.seealso,.rst-content .wy-alert-neutral.tip,.rst-content .wy-alert-neutral.warning,.wy-alert.wy-alert-neutral{background:#f3f6f6}.rst-content .wy-alert-neutral.admonition-todo .admonition-title,.rst-content .wy-alert-neutral.admonition-todo .wy-alert-title,.rst-content .wy-alert-neutral.admonition .admonition-title,.rst-content .wy-alert-neutral.admonition .wy-alert-title,.rst-content .wy-alert-neutral.attention .admonition-title,.rst-content .wy-alert-neutral.attention .wy-alert-title,.rst-content .wy-alert-neutral.caution .admonition-title,.rst-content .wy-alert-neutral.caution .wy-alert-title,.rst-content .wy-alert-neutral.danger .admonition-title,.rst-content .wy-alert-neutral.danger .wy-alert-title,.rst-content .wy-alert-neutral.error .admonition-title,.rst-content .wy-alert-neutral.error .wy-alert-title,.rst-content .wy-alert-neutral.hint .admonition-title,.rst-content .wy-alert-neutral.hint .wy-alert-title,.rst-content .wy-alert-neutral.important .admonition-title,.rst-content .wy-alert-neutral.important .wy-alert-title,.rst-content .wy-alert-neutral.note .admonition-title,.rst-content .wy-alert-neutral.note .wy-alert-title,.rst-content .wy-alert-neutral.seealso .admonition-title,.rst-content .wy-alert-neutral.seealso .wy-alert-title,.rst-content .wy-alert-neutral.tip .admonition-title,.rst-content .wy-alert-neutral.tip .wy-alert-title,.rst-content .wy-alert-neutral.warning .admonition-title,.rst-content .wy-alert-neutral.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-neutral .admonition-title,.wy-alert.wy-alert-neutral .rst-content .admonition-title,.wy-alert.wy-alert-neutral .wy-alert-title{color:#404040;background:#e1e4e5}.rst-content .wy-alert-neutral.admonition-todo a,.rst-content .wy-alert-neutral.admonition a,.rst-content .wy-alert-neutral.attention a,.rst-content .wy-alert-neutral.caution a,.rst-content .wy-alert-neutral.danger a,.rst-content .wy-alert-neutral.error a,.rst-content .wy-alert-neutral.hint a,.rst-content .wy-alert-neutral.important a,.rst-content .wy-alert-neutral.note a,.rst-content .wy-alert-neutral.seealso a,.rst-content .wy-alert-neutral.tip a,.rst-content .wy-alert-neutral.warning a,.wy-alert.wy-alert-neutral a{color:#2980b9}.rst-content .admonition-todo p:last-child,.rst-content .admonition p:last-child,.rst-content .attention p:last-child,.rst-content .caution p:last-child,.rst-content .danger p:last-child,.rst-content .error p:last-child,.rst-content .hint p:last-child,.rst-content .important p:last-child,.rst-content .note p:last-child,.rst-content .seealso p:last-child,.rst-content .tip p:last-child,.rst-content .warning p:last-child,.wy-alert p:last-child{margin-bottom:0}.wy-tray-container{position:fixed;bottom:0;left:0;z-index:600}.wy-tray-container li{display:block;width:300px;background:transparent;color:#fff;text-align:center;box-shadow:0 5px 5px 0 rgba(0,0,0,.1);padding:0 24px;min-width:20%;opacity:0;height:0;line-height:56px;overflow:hidden;-webkit-transition:all .3s ease-in;-moz-transition:all .3s ease-in;transition:all .3s ease-in}.wy-tray-container li.wy-tray-item-success{background:#27ae60}.wy-tray-container li.wy-tray-item-info{background:#2980b9}.wy-tray-container li.wy-tray-item-warning{background:#e67e22}.wy-tray-container li.wy-tray-item-danger{background:#e74c3c}.wy-tray-container li.on{opacity:1;height:56px}@media screen and (max-width:768px){.wy-tray-container{bottom:auto;top:0;width:100%}.wy-tray-container li{width:100%}}button{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle;cursor:pointer;line-height:normal;-webkit-appearance:button;*overflow:visible}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}button[disabled]{cursor:default}.btn{display:inline-block;border-radius:2px;line-height:normal;white-space:nowrap;text-align:center;cursor:pointer;font-size:100%;padding:6px 12px 8px;color:#fff;border:1px solid rgba(0,0,0,.1);background-color:#27ae60;text-decoration:none;font-weight:400;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;box-shadow:inset 0 1px 2px -1px hsla(0,0%,100%,.5),inset 0 -2px 0 0 rgba(0,0,0,.1);outline-none:false;vertical-align:middle;*display:inline;zoom:1;-webkit-user-drag:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-transition:all .1s linear;-moz-transition:all .1s linear;transition:all .1s linear}.btn-hover{background:#2e8ece;color:#fff}.btn:hover{background:#2cc36b;color:#fff}.btn:focus{background:#2cc36b;outline:0}.btn:active{box-shadow:inset 0 -1px 0 0 rgba(0,0,0,.05),inset 0 2px 0 0 rgba(0,0,0,.1);padding:8px 12px 6px}.btn:visited{color:#fff}.btn-disabled,.btn-disabled:active,.btn-disabled:focus,.btn-disabled:hover,.btn:disabled{background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);filter:alpha(opacity=40);opacity:.4;cursor:not-allowed;box-shadow:none}.btn::-moz-focus-inner{padding:0;border:0}.btn-small{font-size:80%}.btn-info{background-color:#2980b9!important}.btn-info:hover{background-color:#2e8ece!important}.btn-neutral{background-color:#f3f6f6!important;color:#404040!important}.btn-neutral:hover{background-color:#e5ebeb!important;color:#404040}.btn-neutral:visited{color:#404040!important}.btn-success{background-color:#27ae60!important}.btn-success:hover{background-color:#295!important}.btn-danger{background-color:#e74c3c!important}.btn-danger:hover{background-color:#ea6153!important}.btn-warning{background-color:#e67e22!important}.btn-warning:hover{background-color:#e98b39!important}.btn-invert{background-color:#222}.btn-invert:hover{background-color:#2f2f2f!important}.btn-link{background-color:transparent!important;color:#2980b9;box-shadow:none;border-color:transparent!important}.btn-link:active,.btn-link:hover{background-color:transparent!important;color:#409ad5!important;box-shadow:none}.btn-link:visited{color:#9b59b6}.wy-btn-group .btn,.wy-control .btn{vertical-align:middle}.wy-btn-group{margin-bottom:24px;*zoom:1}.wy-btn-group:after,.wy-btn-group:before{display:table;content:""}.wy-btn-group:after{clear:both}.wy-dropdown{position:relative;display:inline-block}.wy-dropdown-active .wy-dropdown-menu{display:block}.wy-dropdown-menu{position:absolute;left:0;display:none;float:left;top:100%;min-width:100%;background:#fcfcfc;z-index:100;border:1px solid #cfd7dd;box-shadow:0 2px 2px 0 rgba(0,0,0,.1);padding:12px}.wy-dropdown-menu>dd>a{display:block;clear:both;color:#404040;white-space:nowrap;font-size:90%;padding:0 12px;cursor:pointer}.wy-dropdown-menu>dd>a:hover{background:#2980b9;color:#fff}.wy-dropdown-menu>dd.divider{border-top:1px solid #cfd7dd;margin:6px 0}.wy-dropdown-menu>dd.search{padding-bottom:12px}.wy-dropdown-menu>dd.search input[type=search]{width:100%}.wy-dropdown-menu>dd.call-to-action{background:#e3e3e3;text-transform:uppercase;font-weight:500;font-size:80%}.wy-dropdown-menu>dd.call-to-action:hover{background:#e3e3e3}.wy-dropdown-menu>dd.call-to-action .btn{color:#fff}.wy-dropdown.wy-dropdown-up .wy-dropdown-menu{bottom:100%;top:auto;left:auto;right:0}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu{background:#fcfcfc;margin-top:2px}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu a{padding:6px 12px}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu a:hover{background:#2980b9;color:#fff}.wy-dropdown.wy-dropdown-left .wy-dropdown-menu{right:0;left:auto;text-align:right}.wy-dropdown-arrow:before{content:" ";border-bottom:5px solid #f5f5f5;border-left:5px solid transparent;border-right:5px solid transparent;position:absolute;display:block;top:-4px;left:50%;margin-left:-3px}.wy-dropdown-arrow.wy-dropdown-arrow-left:before{left:11px}.wy-form-stacked select{display:block}.wy-form-aligned .wy-help-inline,.wy-form-aligned input,.wy-form-aligned label,.wy-form-aligned select,.wy-form-aligned textarea{display:inline-block;*display:inline;*zoom:1;vertical-align:middle}.wy-form-aligned .wy-control-group>label{display:inline-block;vertical-align:middle;width:10em;margin:6px 12px 0 0;float:left}.wy-form-aligned .wy-control{float:left}.wy-form-aligned .wy-control label{display:block}.wy-form-aligned .wy-control select{margin-top:6px}fieldset{margin:0}fieldset,legend{border:0;padding:0}legend{width:100%;white-space:normal;margin-bottom:24px;font-size:150%;*margin-left:-7px}label,legend{display:block}label{margin:0 0 .3125em;color:#333;font-size:90%}input,select,textarea{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle}.wy-control-group{margin-bottom:24px;max-width:1200px;margin-left:auto;margin-right:auto;*zoom:1}.wy-control-group:after,.wy-control-group:before{display:table;content:""}.wy-control-group:after{clear:both}.wy-control-group.wy-control-group-required>label:after{content:" *";color:#e74c3c}.wy-control-group .wy-form-full,.wy-control-group .wy-form-halves,.wy-control-group .wy-form-thirds{padding-bottom:12px}.wy-control-group .wy-form-full input[type=color],.wy-control-group .wy-form-full input[type=date],.wy-control-group .wy-form-full input[type=datetime-local],.wy-control-group .wy-form-full input[type=datetime],.wy-control-group .wy-form-full input[type=email],.wy-control-group .wy-form-full input[type=month],.wy-control-group .wy-form-full input[type=number],.wy-control-group .wy-form-full input[type=password],.wy-control-group .wy-form-full input[type=search],.wy-control-group .wy-form-full input[type=tel],.wy-control-group .wy-form-full input[type=text],.wy-control-group .wy-form-full input[type=time],.wy-control-group .wy-form-full input[type=url],.wy-control-group .wy-form-full input[type=week],.wy-control-group .wy-form-full select,.wy-control-group .wy-form-halves input[type=color],.wy-control-group .wy-form-halves input[type=date],.wy-control-group .wy-form-halves input[type=datetime-local],.wy-control-group .wy-form-halves input[type=datetime],.wy-control-group .wy-form-halves input[type=email],.wy-control-group .wy-form-halves input[type=month],.wy-control-group .wy-form-halves input[type=number],.wy-control-group .wy-form-halves input[type=password],.wy-control-group .wy-form-halves input[type=search],.wy-control-group .wy-form-halves input[type=tel],.wy-control-group .wy-form-halves input[type=text],.wy-control-group .wy-form-halves input[type=time],.wy-control-group .wy-form-halves input[type=url],.wy-control-group .wy-form-halves input[type=week],.wy-control-group .wy-form-halves select,.wy-control-group .wy-form-thirds input[type=color],.wy-control-group .wy-form-thirds input[type=date],.wy-control-group .wy-form-thirds input[type=datetime-local],.wy-control-group .wy-form-thirds input[type=datetime],.wy-control-group .wy-form-thirds input[type=email],.wy-control-group .wy-form-thirds input[type=month],.wy-control-group .wy-form-thirds input[type=number],.wy-control-group .wy-form-thirds input[type=password],.wy-control-group .wy-form-thirds input[type=search],.wy-control-group .wy-form-thirds input[type=tel],.wy-control-group .wy-form-thirds input[type=text],.wy-control-group .wy-form-thirds input[type=time],.wy-control-group .wy-form-thirds input[type=url],.wy-control-group .wy-form-thirds input[type=week],.wy-control-group .wy-form-thirds select{width:100%}.wy-control-group .wy-form-full{float:left;display:block;width:100%;margin-right:0}.wy-control-group .wy-form-full:last-child{margin-right:0}.wy-control-group .wy-form-halves{float:left;display:block;margin-right:2.35765%;width:48.82117%}.wy-control-group .wy-form-halves:last-child,.wy-control-group .wy-form-halves:nth-of-type(2n){margin-right:0}.wy-control-group .wy-form-halves:nth-of-type(odd){clear:left}.wy-control-group .wy-form-thirds{float:left;display:block;margin-right:2.35765%;width:31.76157%}.wy-control-group .wy-form-thirds:last-child,.wy-control-group .wy-form-thirds:nth-of-type(3n){margin-right:0}.wy-control-group .wy-form-thirds:nth-of-type(3n+1){clear:left}.wy-control-group.wy-control-group-no-input .wy-control,.wy-control-no-input{margin:6px 0 0;font-size:90%}.wy-control-no-input{display:inline-block}.wy-control-group.fluid-input input[type=color],.wy-control-group.fluid-input input[type=date],.wy-control-group.fluid-input input[type=datetime-local],.wy-control-group.fluid-input input[type=datetime],.wy-control-group.fluid-input input[type=email],.wy-control-group.fluid-input input[type=month],.wy-control-group.fluid-input input[type=number],.wy-control-group.fluid-input input[type=password],.wy-control-group.fluid-input input[type=search],.wy-control-group.fluid-input input[type=tel],.wy-control-group.fluid-input input[type=text],.wy-control-group.fluid-input input[type=time],.wy-control-group.fluid-input input[type=url],.wy-control-group.fluid-input input[type=week]{width:100%}.wy-form-message-inline{padding-left:.3em;color:#666;font-size:90%}.wy-form-message{display:block;color:#999;font-size:70%;margin-top:.3125em;font-style:italic}.wy-form-message p{font-size:inherit;font-style:italic;margin-bottom:6px}.wy-form-message p:last-child{margin-bottom:0}input{line-height:normal}input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;*overflow:visible}input[type=color],input[type=date],input[type=datetime-local],input[type=datetime],input[type=email],input[type=month],input[type=number],input[type=password],input[type=search],input[type=tel],input[type=text],input[type=time],input[type=url],input[type=week]{-webkit-appearance:none;padding:6px;display:inline-block;border:1px solid #ccc;font-size:80%;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;box-shadow:inset 0 1px 3px #ddd;border-radius:0;-webkit-transition:border .3s linear;-moz-transition:border .3s linear;transition:border .3s linear}input[type=datetime-local]{padding:.34375em .625em}input[disabled]{cursor:default}input[type=checkbox],input[type=radio]{padding:0;margin-right:.3125em;*height:13px;*width:13px}input[type=checkbox],input[type=radio],input[type=search]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}input[type=color]:focus,input[type=date]:focus,input[type=datetime-local]:focus,input[type=datetime]:focus,input[type=email]:focus,input[type=month]:focus,input[type=number]:focus,input[type=password]:focus,input[type=search]:focus,input[type=tel]:focus,input[type=text]:focus,input[type=time]:focus,input[type=url]:focus,input[type=week]:focus{outline:0;outline:thin dotted\9;border-color:#333}input.no-focus:focus{border-color:#ccc!important}input[type=checkbox]:focus,input[type=file]:focus,input[type=radio]:focus{outline:thin dotted #333;outline:1px auto #129fea}input[type=color][disabled],input[type=date][disabled],input[type=datetime-local][disabled],input[type=datetime][disabled],input[type=email][disabled],input[type=month][disabled],input[type=number][disabled],input[type=password][disabled],input[type=search][disabled],input[type=tel][disabled],input[type=text][disabled],input[type=time][disabled],input[type=url][disabled],input[type=week][disabled]{cursor:not-allowed;background-color:#fafafa}input:focus:invalid,select:focus:invalid,textarea:focus:invalid{color:#e74c3c;border:1px solid #e74c3c}input:focus:invalid:focus,select:focus:invalid:focus,textarea:focus:invalid:focus{border-color:#e74c3c}input[type=checkbox]:focus:invalid:focus,input[type=file]:focus:invalid:focus,input[type=radio]:focus:invalid:focus{outline-color:#e74c3c}input.wy-input-large{padding:12px;font-size:100%}textarea{overflow:auto;vertical-align:top;width:100%;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif}select,textarea{padding:.5em .625em;display:inline-block;border:1px solid #ccc;font-size:80%;box-shadow:inset 0 1px 3px #ddd;-webkit-transition:border .3s linear;-moz-transition:border .3s linear;transition:border .3s linear}select{border:1px solid #ccc;background-color:#fff}select[multiple]{height:auto}select:focus,textarea:focus{outline:0}input[readonly],select[disabled],select[readonly],textarea[disabled],textarea[readonly]{cursor:not-allowed;background-color:#fafafa}input[type=checkbox][disabled],input[type=radio][disabled]{cursor:not-allowed}.wy-checkbox,.wy-radio{margin:6px 0;color:#404040;display:block}.wy-checkbox input,.wy-radio input{vertical-align:baseline}.wy-form-message-inline{display:inline-block;*display:inline;*zoom:1;vertical-align:middle}.wy-input-prefix,.wy-input-suffix{white-space:nowrap;padding:6px}.wy-input-prefix .wy-input-context,.wy-input-suffix .wy-input-context{line-height:27px;padding:0 8px;display:inline-block;font-size:80%;background-color:#f3f6f6;border:1px solid #ccc;color:#999}.wy-input-suffix .wy-input-context{border-left:0}.wy-input-prefix .wy-input-context{border-right:0}.wy-switch{position:relative;display:block;height:24px;margin-top:12px;cursor:pointer}.wy-switch:before{left:0;top:0;width:36px;height:12px;background:#ccc}.wy-switch:after,.wy-switch:before{position:absolute;content:"";display:block;border-radius:4px;-webkit-transition:all .2s ease-in-out;-moz-transition:all .2s ease-in-out;transition:all .2s ease-in-out}.wy-switch:after{width:18px;height:18px;background:#999;left:-3px;top:-3px}.wy-switch span{position:absolute;left:48px;display:block;font-size:12px;color:#ccc;line-height:1}.wy-switch.active:before{background:#1e8449}.wy-switch.active:after{left:24px;background:#27ae60}.wy-switch.disabled{cursor:not-allowed;opacity:.8}.wy-control-group.wy-control-group-error .wy-form-message,.wy-control-group.wy-control-group-error>label{color:#e74c3c}.wy-control-group.wy-control-group-error input[type=color],.wy-control-group.wy-control-group-error input[type=date],.wy-control-group.wy-control-group-error input[type=datetime-local],.wy-control-group.wy-control-group-error input[type=datetime],.wy-control-group.wy-control-group-error input[type=email],.wy-control-group.wy-control-group-error input[type=month],.wy-control-group.wy-control-group-error input[type=number],.wy-control-group.wy-control-group-error input[type=password],.wy-control-group.wy-control-group-error input[type=search],.wy-control-group.wy-control-group-error input[type=tel],.wy-control-group.wy-control-group-error input[type=text],.wy-control-group.wy-control-group-error input[type=time],.wy-control-group.wy-control-group-error input[type=url],.wy-control-group.wy-control-group-error input[type=week],.wy-control-group.wy-control-group-error textarea{border:1px solid #e74c3c}.wy-inline-validate{white-space:nowrap}.wy-inline-validate .wy-input-context{padding:.5em .625em;display:inline-block;font-size:80%}.wy-inline-validate.wy-inline-validate-success .wy-input-context{color:#27ae60}.wy-inline-validate.wy-inline-validate-danger .wy-input-context{color:#e74c3c}.wy-inline-validate.wy-inline-validate-warning .wy-input-context{color:#e67e22}.wy-inline-validate.wy-inline-validate-info .wy-input-context{color:#2980b9}.rotate-90{-webkit-transform:rotate(90deg);-moz-transform:rotate(90deg);-ms-transform:rotate(90deg);-o-transform:rotate(90deg);transform:rotate(90deg)}.rotate-180{-webkit-transform:rotate(180deg);-moz-transform:rotate(180deg);-ms-transform:rotate(180deg);-o-transform:rotate(180deg);transform:rotate(180deg)}.rotate-270{-webkit-transform:rotate(270deg);-moz-transform:rotate(270deg);-ms-transform:rotate(270deg);-o-transform:rotate(270deg);transform:rotate(270deg)}.mirror{-webkit-transform:scaleX(-1);-moz-transform:scaleX(-1);-ms-transform:scaleX(-1);-o-transform:scaleX(-1);transform:scaleX(-1)}.mirror.rotate-90{-webkit-transform:scaleX(-1) rotate(90deg);-moz-transform:scaleX(-1) rotate(90deg);-ms-transform:scaleX(-1) rotate(90deg);-o-transform:scaleX(-1) rotate(90deg);transform:scaleX(-1) rotate(90deg)}.mirror.rotate-180{-webkit-transform:scaleX(-1) rotate(180deg);-moz-transform:scaleX(-1) rotate(180deg);-ms-transform:scaleX(-1) rotate(180deg);-o-transform:scaleX(-1) rotate(180deg);transform:scaleX(-1) rotate(180deg)}.mirror.rotate-270{-webkit-transform:scaleX(-1) rotate(270deg);-moz-transform:scaleX(-1) rotate(270deg);-ms-transform:scaleX(-1) rotate(270deg);-o-transform:scaleX(-1) rotate(270deg);transform:scaleX(-1) rotate(270deg)}@media only screen and (max-width:480px){.wy-form button[type=submit]{margin:.7em 0 0}.wy-form input[type=color],.wy-form input[type=date],.wy-form input[type=datetime-local],.wy-form input[type=datetime],.wy-form input[type=email],.wy-form input[type=month],.wy-form input[type=number],.wy-form input[type=password],.wy-form input[type=search],.wy-form input[type=tel],.wy-form input[type=text],.wy-form input[type=time],.wy-form input[type=url],.wy-form input[type=week],.wy-form label{margin-bottom:.3em;display:block}.wy-form input[type=color],.wy-form input[type=date],.wy-form input[type=datetime-local],.wy-form input[type=datetime],.wy-form input[type=email],.wy-form input[type=month],.wy-form input[type=number],.wy-form input[type=password],.wy-form input[type=search],.wy-form input[type=tel],.wy-form input[type=time],.wy-form input[type=url],.wy-form input[type=week]{margin-bottom:0}.wy-form-aligned .wy-control-group label{margin-bottom:.3em;text-align:left;display:block;width:100%}.wy-form-aligned .wy-control{margin:1.5em 0 0}.wy-form-message,.wy-form-message-inline,.wy-form .wy-help-inline{display:block;font-size:80%;padding:6px 0}}@media screen and (max-width:768px){.tablet-hide{display:none}}@media screen and (max-width:480px){.mobile-hide{display:none}}.float-left{float:left}.float-right{float:right}.full-width{width:100%}.rst-content table.docutils,.rst-content table.field-list,.wy-table{border-collapse:collapse;border-spacing:0;empty-cells:show;margin-bottom:24px}.rst-content table.docutils caption,.rst-content table.field-list caption,.wy-table caption{color:#000;font:italic 85%/1 arial,sans-serif;padding:1em 0;text-align:center}.rst-content table.docutils td,.rst-content table.docutils th,.rst-content table.field-list td,.rst-content table.field-list th,.wy-table td,.wy-table th{font-size:90%;margin:0;overflow:visible;padding:8px 16px}.rst-content table.docutils td:first-child,.rst-content table.docutils th:first-child,.rst-content table.field-list td:first-child,.rst-content table.field-list th:first-child,.wy-table td:first-child,.wy-table th:first-child{border-left-width:0}.rst-content table.docutils thead,.rst-content table.field-list thead,.wy-table thead{color:#000;text-align:left;vertical-align:bottom;white-space:nowrap}.rst-content table.docutils thead th,.rst-content table.field-list thead th,.wy-table thead th{font-weight:700;border-bottom:2px solid #e1e4e5}.rst-content table.docutils td,.rst-content table.field-list td,.wy-table td{background-color:transparent;vertical-align:middle}.rst-content table.docutils td p,.rst-content table.field-list td p,.wy-table td p{line-height:18px}.rst-content table.docutils td p:last-child,.rst-content table.field-list td p:last-child,.wy-table td p:last-child{margin-bottom:0}.rst-content table.docutils .wy-table-cell-min,.rst-content table.field-list .wy-table-cell-min,.wy-table .wy-table-cell-min{width:1%;padding-right:0}.rst-content table.docutils .wy-table-cell-min input[type=checkbox],.rst-content table.field-list .wy-table-cell-min input[type=checkbox],.wy-table .wy-table-cell-min input[type=checkbox]{margin:0}.wy-table-secondary{color:grey;font-size:90%}.wy-table-tertiary{color:grey;font-size:80%}.rst-content table.docutils:not(.field-list) tr:nth-child(2n-1) td,.wy-table-backed,.wy-table-odd td,.wy-table-striped tr:nth-child(2n-1) td{background-color:#f3f6f6}.rst-content table.docutils,.wy-table-bordered-all{border:1px solid #e1e4e5}.rst-content table.docutils td,.wy-table-bordered-all td{border-bottom:1px solid #e1e4e5;border-left:1px solid #e1e4e5}.rst-content table.docutils tbody>tr:last-child td,.wy-table-bordered-all tbody>tr:last-child td{border-bottom-width:0}.wy-table-bordered{border:1px solid #e1e4e5}.wy-table-bordered-rows td{border-bottom:1px solid #e1e4e5}.wy-table-bordered-rows tbody>tr:last-child td{border-bottom-width:0}.wy-table-horizontal td,.wy-table-horizontal th{border-width:0 0 1px;border-bottom:1px solid #e1e4e5}.wy-table-horizontal tbody>tr:last-child td{border-bottom-width:0}.wy-table-responsive{margin-bottom:24px;max-width:100%;overflow:auto}.wy-table-responsive table{margin-bottom:0!important}.wy-table-responsive table td,.wy-table-responsive table th{white-space:nowrap}a{color:#2980b9;text-decoration:none;cursor:pointer}a:hover{color:#3091d1}a:visited{color:#9b59b6}html{height:100%}body,html{overflow-x:hidden}body{font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;font-weight:400;color:#404040;min-height:100%;background:#edf0f2}.wy-text-left{text-align:left}.wy-text-center{text-align:center}.wy-text-right{text-align:right}.wy-text-large{font-size:120%}.wy-text-normal{font-size:100%}.wy-text-small,small{font-size:80%}.wy-text-strike{text-decoration:line-through}.wy-text-warning{color:#e67e22!important}a.wy-text-warning:hover{color:#eb9950!important}.wy-text-info{color:#2980b9!important}a.wy-text-info:hover{color:#409ad5!important}.wy-text-success{color:#27ae60!important}a.wy-text-success:hover{color:#36d278!important}.wy-text-danger{color:#e74c3c!important}a.wy-text-danger:hover{color:#ed7669!important}.wy-text-neutral{color:#404040!important}a.wy-text-neutral:hover{color:#595959!important}.rst-content .toctree-wrapper>p.caption,h1,h2,h3,h4,h5,h6,legend{margin-top:0;font-weight:700;font-family:Roboto Slab,ff-tisa-web-pro,Georgia,Arial,sans-serif}p{line-height:24px;font-size:16px;margin:0 0 24px}h1{font-size:175%}.rst-content .toctree-wrapper>p.caption,h2{font-size:150%}h3{font-size:125%}h4{font-size:115%}h5{font-size:110%}h6{font-size:100%}hr{display:block;height:1px;border:0;border-top:1px solid #e1e4e5;margin:24px 0;padding:0}.rst-content code,.rst-content tt,code{white-space:nowrap;max-width:100%;background:#fff;border:1px solid #e1e4e5;font-size:75%;padding:0 5px;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;color:#e74c3c;overflow-x:auto}.rst-content tt.code-large,code.code-large{font-size:90%}.rst-content .section ul,.rst-content .toctree-wrapper ul,.wy-plain-list-disc,article ul{list-style:disc;line-height:24px;margin-bottom:24px}.rst-content .section ul li,.rst-content .toctree-wrapper ul li,.wy-plain-list-disc li,article ul li{list-style:disc;margin-left:24px}.rst-content .section ul li p:last-child,.rst-content .section ul li ul,.rst-content .toctree-wrapper ul li p:last-child,.rst-content .toctree-wrapper ul li ul,.wy-plain-list-disc li p:last-child,.wy-plain-list-disc li ul,article ul li p:last-child,article ul li ul{margin-bottom:0}.rst-content .section ul li li,.rst-content .toctree-wrapper ul li li,.wy-plain-list-disc li li,article ul li li{list-style:circle}.rst-content .section ul li li li,.rst-content .toctree-wrapper ul li li li,.wy-plain-list-disc li li li,article ul li li li{list-style:square}.rst-content .section ul li ol li,.rst-content .toctree-wrapper ul li ol li,.wy-plain-list-disc li ol li,article ul li ol li{list-style:decimal}.rst-content .section ol,.rst-content ol.arabic,.wy-plain-list-decimal,article ol{list-style:decimal;line-height:24px;margin-bottom:24px}.rst-content .section ol li,.rst-content ol.arabic li,.wy-plain-list-decimal li,article ol li{list-style:decimal;margin-left:24px}.rst-content .section ol li p:last-child,.rst-content .section ol li ul,.rst-content ol.arabic li p:last-child,.rst-content ol.arabic li ul,.wy-plain-list-decimal li p:last-child,.wy-plain-list-decimal li ul,article ol li p:last-child,article ol li ul{margin-bottom:0}.rst-content .section ol li ul li,.rst-content ol.arabic li ul li,.wy-plain-list-decimal li ul li,article ol li ul li{list-style:disc}.wy-breadcrumbs{*zoom:1}.wy-breadcrumbs:after,.wy-breadcrumbs:before{display:table;content:""}.wy-breadcrumbs:after{clear:both}.wy-breadcrumbs li{display:inline-block}.wy-breadcrumbs li.wy-breadcrumbs-aside{float:right}.wy-breadcrumbs li a{display:inline-block;padding:5px}.wy-breadcrumbs li a:first-child{padding-left:0}.rst-content .wy-breadcrumbs li tt,.wy-breadcrumbs li .rst-content tt,.wy-breadcrumbs li code{padding:5px;border:none;background:none}.rst-content .wy-breadcrumbs li tt.literal,.wy-breadcrumbs li .rst-content tt.literal,.wy-breadcrumbs li code.literal{color:#404040}.wy-breadcrumbs-extra{margin-bottom:0;color:#b3b3b3;font-size:80%;display:inline-block}@media screen and (max-width:480px){.wy-breadcrumbs-extra,.wy-breadcrumbs li.wy-breadcrumbs-aside{display:none}}@media print{.wy-breadcrumbs li.wy-breadcrumbs-aside{display:none}}html{font-size:16px}.wy-affix{position:fixed;top:1.618em}.wy-menu a:hover{text-decoration:none}.wy-menu-horiz{*zoom:1}.wy-menu-horiz:after,.wy-menu-horiz:before{display:table;content:""}.wy-menu-horiz:after{clear:both}.wy-menu-horiz li,.wy-menu-horiz ul{display:inline-block}.wy-menu-horiz li:hover{background:hsla(0,0%,100%,.1)}.wy-menu-horiz li.divide-left{border-left:1px solid #404040}.wy-menu-horiz li.divide-right{border-right:1px solid #404040}.wy-menu-horiz a{height:32px;display:inline-block;line-height:32px;padding:0 16px}.wy-menu-vertical{width:300px}.wy-menu-vertical header,.wy-menu-vertical p.caption{color:#55a5d9;height:32px;line-height:32px;padding:0 1.618em;margin:12px 0 0;display:block;font-weight:700;text-transform:uppercase;font-size:85%;white-space:nowrap}.wy-menu-vertical ul{margin-bottom:0}.wy-menu-vertical li.divide-top{border-top:1px solid #404040}.wy-menu-vertical li.divide-bottom{border-bottom:1px solid #404040}.wy-menu-vertical li.current{background:#e3e3e3}.wy-menu-vertical li.current a{color:grey;border-right:1px solid #c9c9c9;padding:.4045em 2.427em}.wy-menu-vertical li.current a:hover{background:#d6d6d6}.rst-content .wy-menu-vertical li tt,.wy-menu-vertical li .rst-content tt,.wy-menu-vertical li code{border:none;background:inherit;color:inherit;padding-left:0;padding-right:0}.wy-menu-vertical li span.toctree-expand{display:block;float:left;margin-left:-1.2em;font-size:.8em;line-height:1.6em;color:#4d4d4d}.wy-menu-vertical li.current>a,.wy-menu-vertical li.on a{color:#404040;font-weight:700;position:relative;background:#fcfcfc;border:none;padding:.4045em 1.618em}.wy-menu-vertical li.current>a:hover,.wy-menu-vertical li.on a:hover{background:#fcfcfc}.wy-menu-vertical li.current>a:hover span.toctree-expand,.wy-menu-vertical li.on a:hover span.toctree-expand{color:grey}.wy-menu-vertical li.current>a span.toctree-expand,.wy-menu-vertical li.on a span.toctree-expand{display:block;font-size:.8em;line-height:1.6em;color:#333}.wy-menu-vertical li.toctree-l1.current>a{border-bottom:1px solid #c9c9c9;border-top:1px solid #c9c9c9}.wy-menu-vertical .toctree-l1.current .toctree-l2>ul,.wy-menu-vertical .toctree-l2.current .toctree-l3>ul,.wy-menu-vertical .toctree-l3.current .toctree-l4>ul,.wy-menu-vertical .toctree-l4.current .toctree-l5>ul,.wy-menu-vertical .toctree-l5.current .toctree-l6>ul,.wy-menu-vertical .toctree-l6.current .toctree-l7>ul,.wy-menu-vertical .toctree-l7.current .toctree-l8>ul,.wy-menu-vertical .toctree-l8.current .toctree-l9>ul,.wy-menu-vertical .toctree-l9.current .toctree-l10>ul,.wy-menu-vertical .toctree-l10.current .toctree-l11>ul{display:none}.wy-menu-vertical .toctree-l1.current .current.toctree-l2>ul,.wy-menu-vertical .toctree-l2.current .current.toctree-l3>ul,.wy-menu-vertical .toctree-l3.current .current.toctree-l4>ul,.wy-menu-vertical .toctree-l4.current .current.toctree-l5>ul,.wy-menu-vertical .toctree-l5.current .current.toctree-l6>ul,.wy-menu-vertical .toctree-l6.current .current.toctree-l7>ul,.wy-menu-vertical .toctree-l7.current .current.toctree-l8>ul,.wy-menu-vertical .toctree-l8.current .current.toctree-l9>ul,.wy-menu-vertical .toctree-l9.current .current.toctree-l10>ul,.wy-menu-vertical .toctree-l10.current .current.toctree-l11>ul{display:block}.wy-menu-vertical li.toctree-l3,.wy-menu-vertical li.toctree-l4{font-size:.9em}.wy-menu-vertical li.toctree-l2 a,.wy-menu-vertical li.toctree-l3 a,.wy-menu-vertical li.toctree-l4 a,.wy-menu-vertical li.toctree-l5 a,.wy-menu-vertical li.toctree-l6 a,.wy-menu-vertical li.toctree-l7 a,.wy-menu-vertical li.toctree-l8 a,.wy-menu-vertical li.toctree-l9 a,.wy-menu-vertical li.toctree-l10 a{color:#404040}.wy-menu-vertical li.toctree-l2 a:hover span.toctree-expand,.wy-menu-vertical li.toctree-l3 a:hover span.toctree-expand,.wy-menu-vertical li.toctree-l4 a:hover span.toctree-expand,.wy-menu-vertical li.toctree-l5 a:hover span.toctree-expand,.wy-menu-vertical li.toctree-l6 a:hover span.toctree-expand,.wy-menu-vertical li.toctree-l7 a:hover span.toctree-expand,.wy-menu-vertical li.toctree-l8 a:hover span.toctree-expand,.wy-menu-vertical li.toctree-l9 a:hover span.toctree-expand,.wy-menu-vertical li.toctree-l10 a:hover span.toctree-expand{color:grey}.wy-menu-vertical li.toctree-l2.current li.toctree-l3>a,.wy-menu-vertical li.toctree-l3.current li.toctree-l4>a,.wy-menu-vertical li.toctree-l4.current li.toctree-l5>a,.wy-menu-vertical li.toctree-l5.current li.toctree-l6>a,.wy-menu-vertical li.toctree-l6.current li.toctree-l7>a,.wy-menu-vertical li.toctree-l7.current li.toctree-l8>a,.wy-menu-vertical li.toctree-l8.current li.toctree-l9>a,.wy-menu-vertical li.toctree-l9.current li.toctree-l10>a,.wy-menu-vertical li.toctree-l10.current li.toctree-l11>a{display:block}.wy-menu-vertical li.toctree-l2.current>a{padding:.4045em 2.427em}.wy-menu-vertical li.toctree-l2.current li.toctree-l3>a,.wy-menu-vertical li.toctree-l3.current>a{padding:.4045em 4.045em}.wy-menu-vertical li.toctree-l3.current li.toctree-l4>a,.wy-menu-vertical li.toctree-l4.current>a{padding:.4045em 5.663em}.wy-menu-vertical li.toctree-l4.current li.toctree-l5>a,.wy-menu-vertical li.toctree-l5.current>a{padding:.4045em 7.281em}.wy-menu-vertical li.toctree-l5.current li.toctree-l6>a,.wy-menu-vertical li.toctree-l6.current>a{padding:.4045em 8.899em}.wy-menu-vertical li.toctree-l6.current li.toctree-l7>a,.wy-menu-vertical li.toctree-l7.current>a{padding:.4045em 10.517em}.wy-menu-vertical li.toctree-l7.current li.toctree-l8>a,.wy-menu-vertical li.toctree-l8.current>a{padding:.4045em 12.135em}.wy-menu-vertical li.toctree-l8.current li.toctree-l9>a,.wy-menu-vertical li.toctree-l9.current>a{padding:.4045em 13.753em}.wy-menu-vertical li.toctree-l9.current li.toctree-l10>a,.wy-menu-vertical li.toctree-l10.current>a{padding:.4045em 15.371em}.wy-menu-vertical li.toctree-l10.current li.toctree-l11>a{padding:.4045em 16.989em}.wy-menu-vertical li.toctree-l2.current>a,.wy-menu-vertical li.toctree-l2.current li.toctree-l3>a{background:#c9c9c9}.wy-menu-vertical li.toctree-l2 span.toctree-expand{color:#a3a3a3}.wy-menu-vertical li.toctree-l3.current>a,.wy-menu-vertical li.toctree-l3.current li.toctree-l4>a{background:#bdbdbd}.wy-menu-vertical li.toctree-l3 span.toctree-expand{color:#969696}.wy-menu-vertical li.current ul{display:block}.wy-menu-vertical li ul{margin-bottom:0;display:none}.wy-menu-vertical li ul li a{margin-bottom:0;color:#d9d9d9;font-weight:400}.wy-menu-vertical a{line-height:18px;padding:.4045em 1.618em;display:block;position:relative;font-size:90%;color:#d9d9d9}.wy-menu-vertical a:hover{background-color:#4e4a4a;cursor:pointer}.wy-menu-vertical a:hover span.toctree-expand{color:#d9d9d9}.wy-menu-vertical a:active{background-color:#2980b9;cursor:pointer;color:#fff}.wy-menu-vertical a:active span.toctree-expand{color:#fff}.wy-side-nav-search{display:block;width:300px;padding:.809em;margin-bottom:.809em;z-index:200;background-color:#2980b9;text-align:center;color:#fcfcfc}.wy-side-nav-search input[type=text]{width:100%;border-radius:50px;padding:6px 12px;border-color:#2472a4}.wy-side-nav-search img{display:block;margin:auto auto .809em;height:45px;width:45px;background-color:#2980b9;padding:5px;border-radius:100%}.wy-side-nav-search .wy-dropdown>a,.wy-side-nav-search>a{color:#fcfcfc;font-size:100%;font-weight:700;display:inline-block;padding:4px 6px;margin-bottom:.809em}.wy-side-nav-search .wy-dropdown>a:hover,.wy-side-nav-search>a:hover{background:hsla(0,0%,100%,.1)}.wy-side-nav-search .wy-dropdown>a img.logo,.wy-side-nav-search>a img.logo{display:block;margin:0 auto;height:auto;width:auto;border-radius:0;max-width:100%;background:transparent}.wy-side-nav-search .wy-dropdown>a.icon img.logo,.wy-side-nav-search>a.icon img.logo{margin-top:.85em}.wy-side-nav-search>div.version{margin-top:-.4045em;margin-bottom:.809em;font-weight:400;color:hsla(0,0%,100%,.3)}.wy-nav .wy-menu-vertical header{color:#2980b9}.wy-nav .wy-menu-vertical a{color:#b3b3b3}.wy-nav .wy-menu-vertical a:hover{background-color:#2980b9;color:#fff}[data-menu-wrap]{-webkit-transition:all .2s ease-in;-moz-transition:all .2s ease-in;transition:all .2s ease-in;position:absolute;opacity:1;width:100%;opacity:0}[data-menu-wrap].move-center{left:0;right:auto;opacity:1}[data-menu-wrap].move-left{right:auto;left:-100%;opacity:0}[data-menu-wrap].move-right{right:-100%;left:auto;opacity:0}.wy-body-for-nav{background:#fcfcfc}.wy-grid-for-nav{position:absolute;width:100%;height:100%}.wy-nav-side{position:fixed;top:0;bottom:0;left:0;padding-bottom:2em;width:300px;overflow-x:hidden;overflow-y:hidden;min-height:100%;color:#9b9b9b;background:#343131;z-index:200}.wy-side-scroll{width:320px;position:relative;overflow-x:hidden;overflow-y:scroll;height:100%}.wy-nav-top{display:none;background:#2980b9;color:#fff;padding:.4045em .809em;position:relative;line-height:50px;text-align:center;font-size:100%;*zoom:1}.wy-nav-top:after,.wy-nav-top:before{display:table;content:""}.wy-nav-top:after{clear:both}.wy-nav-top a{color:#fff;font-weight:700}.wy-nav-top img{margin-right:12px;height:45px;width:45px;background-color:#2980b9;padding:5px;border-radius:100%}.wy-nav-top i{font-size:30px;float:left;cursor:pointer;padding-top:inherit}.wy-nav-content-wrap{margin-left:300px;background:#fcfcfc;min-height:100%}.wy-nav-content{padding:1.618em 3.236em;height:100%;max-width:800px;margin:auto}.wy-body-mask{position:fixed;width:100%;height:100%;background:rgba(0,0,0,.2);display:none;z-index:499}.wy-body-mask.on{display:block}footer{color:grey}footer p{margin-bottom:12px}.rst-content footer span.commit tt,footer span.commit .rst-content tt,footer span.commit code{padding:0;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;font-size:1em;background:none;border:none;color:grey}.rst-footer-buttons{*zoom:1}.rst-footer-buttons:after,.rst-footer-buttons:before{width:100%;display:table;content:""}.rst-footer-buttons:after{clear:both}.rst-breadcrumbs-buttons{margin-top:12px;*zoom:1}.rst-breadcrumbs-buttons:after,.rst-breadcrumbs-buttons:before{display:table;content:""}.rst-breadcrumbs-buttons:after{clear:both}#search-results .search li{margin-bottom:24px;border-bottom:1px solid #e1e4e5;padding-bottom:24px}#search-results .search li:first-child{border-top:1px solid #e1e4e5;padding-top:24px}#search-results .search li a{font-size:120%;margin-bottom:12px;display:inline-block}#search-results .context{color:grey;font-size:90%}.genindextable li>ul{margin-left:24px}@media screen and (max-width:768px){.wy-body-for-nav{background:#fcfcfc}.wy-nav-top{display:block}.wy-nav-side{left:-300px}.wy-nav-side.shift{width:85%;left:0}.wy-menu.wy-menu-vertical,.wy-side-nav-search,.wy-side-scroll{width:auto}.wy-nav-content-wrap{margin-left:0}.wy-nav-content-wrap .wy-nav-content{padding:1.618em}.wy-nav-content-wrap.shift{position:fixed;min-width:100%;left:85%;top:0;height:100%;overflow:hidden}}@media screen and (min-width:1100px){.wy-nav-content-wrap{background:rgba(0,0,0,.05)}.wy-nav-content{margin:0;background:#fcfcfc}}@media print{.rst-versions,.wy-nav-side,footer{display:none}.wy-nav-content-wrap{margin-left:0}}.rst-versions{position:fixed;bottom:0;left:0;width:300px;color:#fcfcfc;background:#1f1d1d;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;z-index:400}.rst-versions a{color:#2980b9;text-decoration:none}.rst-versions .rst-badge-small{display:none}.rst-versions .rst-current-version{padding:12px;background-color:#272525;display:block;text-align:right;font-size:90%;cursor:pointer;color:#27ae60;*zoom:1}.rst-versions .rst-current-version:after,.rst-versions .rst-current-version:before{display:table;content:""}.rst-versions .rst-current-version:after{clear:both}.rst-content .code-block-caption .rst-versions .rst-current-version .headerlink,.rst-content .rst-versions .rst-current-version .admonition-title,.rst-content code.download .rst-versions .rst-current-version span:first-child,.rst-content dl dt .rst-versions .rst-current-version .headerlink,.rst-content h1 .rst-versions .rst-current-version .headerlink,.rst-content h2 .rst-versions .rst-current-version .headerlink,.rst-content h3 .rst-versions .rst-current-version .headerlink,.rst-content h4 .rst-versions .rst-current-version .headerlink,.rst-content h5 .rst-versions .rst-current-version .headerlink,.rst-content h6 .rst-versions .rst-current-version .headerlink,.rst-content p.caption .rst-versions .rst-current-version .headerlink,.rst-content table>caption .rst-versions .rst-current-version .headerlink,.rst-content tt.download .rst-versions .rst-current-version span:first-child,.rst-versions .rst-current-version .fa,.rst-versions .rst-current-version .icon,.rst-versions .rst-current-version .rst-content .admonition-title,.rst-versions .rst-current-version .rst-content .code-block-caption .headerlink,.rst-versions .rst-current-version .rst-content code.download span:first-child,.rst-versions .rst-current-version .rst-content dl dt .headerlink,.rst-versions .rst-current-version .rst-content h1 .headerlink,.rst-versions .rst-current-version .rst-content h2 .headerlink,.rst-versions .rst-current-version .rst-content h3 .headerlink,.rst-versions .rst-current-version .rst-content h4 .headerlink,.rst-versions .rst-current-version .rst-content h5 .headerlink,.rst-versions .rst-current-version .rst-content h6 .headerlink,.rst-versions .rst-current-version .rst-content p.caption .headerlink,.rst-versions .rst-current-version .rst-content table>caption .headerlink,.rst-versions .rst-current-version .rst-content tt.download span:first-child,.rst-versions .rst-current-version .wy-menu-vertical li span.toctree-expand,.wy-menu-vertical li .rst-versions .rst-current-version span.toctree-expand{color:#fcfcfc}.rst-versions .rst-current-version .fa-book,.rst-versions .rst-current-version .icon-book{float:left}.rst-versions .rst-current-version.rst-out-of-date{background-color:#e74c3c;color:#fff}.rst-versions .rst-current-version.rst-active-old-version{background-color:#f1c40f;color:#000}.rst-versions.shift-up{height:auto;max-height:100%;overflow-y:scroll}.rst-versions.shift-up .rst-other-versions{display:block}.rst-versions .rst-other-versions{font-size:90%;padding:12px;color:grey;display:none}.rst-versions .rst-other-versions hr{display:block;height:1px;border:0;margin:20px 0;padding:0;border-top:1px solid #413d3d}.rst-versions .rst-other-versions dd{display:inline-block;margin:0}.rst-versions .rst-other-versions dd a{display:inline-block;padding:6px;color:#fcfcfc}.rst-versions.rst-badge{width:auto;bottom:20px;right:20px;left:auto;border:none;max-width:300px;max-height:90%}.rst-versions.rst-badge .fa-book,.rst-versions.rst-badge .icon-book{float:none;line-height:30px}.rst-versions.rst-badge.shift-up .rst-current-version{text-align:right}.rst-versions.rst-badge.shift-up .rst-current-version .fa-book,.rst-versions.rst-badge.shift-up .rst-current-version .icon-book{float:left}.rst-versions.rst-badge>.rst-current-version{width:auto;height:30px;line-height:30px;padding:0 6px;display:block;text-align:center}@media screen and (max-width:768px){.rst-versions{width:85%;display:none}.rst-versions.shift{display:block}}.rst-content img{max-width:100%;height:auto}.rst-content div.figure{margin-bottom:24px}.rst-content div.figure p.caption{font-style:italic}.rst-content div.figure p:last-child.caption{margin-bottom:0}.rst-content div.figure.align-center{text-align:center}.rst-content .section>a>img,.rst-content .section>img{margin-bottom:24px}.rst-content abbr[title]{text-decoration:none}.rst-content.style-external-links a.reference.external:after{font-family:FontAwesome;content:"\f08e";color:#b3b3b3;vertical-align:super;font-size:60%;margin:0 .2em}.rst-content blockquote{margin-left:24px;line-height:24px;margin-bottom:24px}.rst-content pre.literal-block{white-space:pre;margin:0;padding:12px;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;display:block;overflow:auto}.rst-content div[class^=highlight],.rst-content pre.literal-block{border:1px solid #e1e4e5;overflow-x:auto;margin:1px 0 24px}.rst-content div[class^=highlight] div[class^=highlight],.rst-content pre.literal-block div[class^=highlight]{padding:0;border:none;margin:0}.rst-content div[class^=highlight] td.code{width:100%}.rst-content .linenodiv pre{border-right:1px solid #e6e9ea;margin:0;padding:12px;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;user-select:none;pointer-events:none}.rst-content div[class^=highlight] pre{white-space:pre;margin:0;padding:12px;display:block;overflow:auto}.rst-content div[class^=highlight] pre .hll{display:block;margin:0 -12px;padding:0 12px}.rst-content .linenodiv pre,.rst-content div[class^=highlight] pre,.rst-content pre.literal-block{font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;font-size:12px;line-height:1.4}.rst-content div.highlight .gp{user-select:none;pointer-events:none}.rst-content .code-block-caption{font-style:italic;font-size:85%;line-height:1;padding:1em 0;text-align:center}@media print{.rst-content .codeblock,.rst-content div[class^=highlight],.rst-content div[class^=highlight] pre{white-space:pre-wrap}}.rst-content .admonition,.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .danger,.rst-content .error,.rst-content .hint,.rst-content .important,.rst-content .note,.rst-content .seealso,.rst-content .tip,.rst-content .warning{clear:both}.rst-content .admonition-todo .last,.rst-content .admonition-todo>:last-child,.rst-content .admonition .last,.rst-content .admonition>:last-child,.rst-content .attention .last,.rst-content .attention>:last-child,.rst-content .caution .last,.rst-content .caution>:last-child,.rst-content .danger .last,.rst-content .danger>:last-child,.rst-content .error .last,.rst-content .error>:last-child,.rst-content .hint .last,.rst-content .hint>:last-child,.rst-content .important .last,.rst-content .important>:last-child,.rst-content .note .last,.rst-content .note>:last-child,.rst-content .seealso .last,.rst-content .seealso>:last-child,.rst-content .tip .last,.rst-content .tip>:last-child,.rst-content .warning .last,.rst-content .warning>:last-child{margin-bottom:0}.rst-content .admonition-title:before{margin-right:4px}.rst-content .admonition table{border-color:rgba(0,0,0,.1)}.rst-content .admonition table td,.rst-content .admonition table th{background:transparent!important;border-color:rgba(0,0,0,.1)!important}.rst-content .section ol.loweralpha,.rst-content .section ol.loweralpha>li{list-style:lower-alpha}.rst-content .section ol.upperalpha,.rst-content .section ol.upperalpha>li{list-style:upper-alpha}.rst-content .section ol li>*,.rst-content .section ul li>*{margin-top:12px;margin-bottom:12px}.rst-content .section ol li>:first-child,.rst-content .section ul li>:first-child{margin-top:0}.rst-content .section ol li>p,.rst-content .section ol li>p:last-child,.rst-content .section ul li>p,.rst-content .section ul li>p:last-child{margin-bottom:12px}.rst-content .section ol li>p:only-child,.rst-content .section ol li>p:only-child:last-child,.rst-content .section ul li>p:only-child,.rst-content .section ul li>p:only-child:last-child{margin-bottom:0}.rst-content .section ol li>ol,.rst-content .section ol li>ul,.rst-content .section ul li>ol,.rst-content .section ul li>ul{margin-bottom:12px}.rst-content .section ol.simple li>*,.rst-content .section ol.simple li ol,.rst-content .section ol.simple li ul,.rst-content .section ul.simple li>*,.rst-content .section ul.simple li ol,.rst-content .section ul.simple li ul{margin-top:0;margin-bottom:0}.rst-content .line-block{margin-left:0;margin-bottom:24px;line-height:24px}.rst-content .line-block .line-block{margin-left:24px;margin-bottom:0}.rst-content .topic-title{font-weight:700;margin-bottom:12px}.rst-content .toc-backref{color:#404040}.rst-content .align-right{float:right;margin:0 0 24px 24px}.rst-content .align-left{float:left;margin:0 24px 24px 0}.rst-content .align-center{margin:auto}.rst-content .align-center:not(table){display:block}.rst-content .code-block-caption .headerlink,.rst-content .toctree-wrapper>p.caption .headerlink,.rst-content dl dt .headerlink,.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content p.caption .headerlink,.rst-content table>caption .headerlink{visibility:hidden;font-size:14px}.rst-content .code-block-caption .headerlink:after,.rst-content .toctree-wrapper>p.caption .headerlink:after,.rst-content dl dt .headerlink:after,.rst-content h1 .headerlink:after,.rst-content h2 .headerlink:after,.rst-content h3 .headerlink:after,.rst-content h4 .headerlink:after,.rst-content h5 .headerlink:after,.rst-content h6 .headerlink:after,.rst-content p.caption .headerlink:after,.rst-content table>caption .headerlink:after{content:"\f0c1";font-family:FontAwesome}.rst-content .code-block-caption:hover .headerlink:after,.rst-content .toctree-wrapper>p.caption:hover .headerlink:after,.rst-content dl dt:hover .headerlink:after,.rst-content h1:hover .headerlink:after,.rst-content h2:hover .headerlink:after,.rst-content h3:hover .headerlink:after,.rst-content h4:hover .headerlink:after,.rst-content h5:hover .headerlink:after,.rst-content h6:hover .headerlink:after,.rst-content p.caption:hover .headerlink:after,.rst-content table>caption:hover .headerlink:after{visibility:visible}.rst-content table>caption .headerlink:after{font-size:12px}.rst-content .centered{text-align:center}.rst-content .sidebar{float:right;width:40%;display:block;margin:0 0 24px 24px;padding:24px;background:#f3f6f6;border:1px solid #e1e4e5}.rst-content .sidebar dl,.rst-content .sidebar p,.rst-content .sidebar ul{font-size:90%}.rst-content .sidebar .last,.rst-content .sidebar>:last-child{margin-bottom:0}.rst-content .sidebar .sidebar-title{display:block;font-family:Roboto Slab,ff-tisa-web-pro,Georgia,Arial,sans-serif;font-weight:700;background:#e1e4e5;padding:6px 12px;margin:-24px -24px 24px;font-size:100%}.rst-content .highlighted{background:#f1c40f;box-shadow:0 0 0 2px #f1c40f;display:inline;font-weight:700}.rst-content .citation-reference,.rst-content .footnote-reference{vertical-align:baseline;position:relative;top:-.4em;line-height:0;font-size:90%}.rst-content .hlist{width:100%}html.writer-html4 .rst-content table.docutils.citation,html.writer-html4 .rst-content table.docutils.footnote{background:none;border:none}html.writer-html4 .rst-content table.docutils.citation td,html.writer-html4 .rst-content table.docutils.citation tr,html.writer-html4 .rst-content table.docutils.footnote td,html.writer-html4 .rst-content table.docutils.footnote tr{border:none;background-color:transparent!important;white-space:normal}html.writer-html4 .rst-content table.docutils.citation td.label,html.writer-html4 .rst-content table.docutils.footnote td.label{padding-left:0;padding-right:0;vertical-align:top}html.writer-html5 .rst-content dl dt span.classifier:before{content:" : "}html.writer-html5 .rst-content dl.field-list,html.writer-html5 .rst-content dl.footnote{display:grid;grid-template-columns:max-content auto}html.writer-html5 .rst-content dl.field-list>dt,html.writer-html5 .rst-content dl.footnote>dt{padding-left:1rem}html.writer-html5 .rst-content dl.field-list>dt:after,html.writer-html5 .rst-content dl.footnote>dt:after{content:":"}html.writer-html5 .rst-content dl.field-list>dd,html.writer-html5 .rst-content dl.field-list>dt,html.writer-html5 .rst-content dl.footnote>dd,html.writer-html5 .rst-content dl.footnote>dt{margin-bottom:0}html.writer-html5 .rst-content dl.footnote{font-size:.9rem}html.writer-html5 .rst-content dl.footnote>dt{margin:0 .5rem .5rem 0;line-height:1.2rem;word-break:break-all;font-weight:400}html.writer-html5 .rst-content dl.footnote>dt>span.brackets{margin-right:.5rem}html.writer-html5 .rst-content dl.footnote>dt>span.brackets:before{content:"["}html.writer-html5 .rst-content dl.footnote>dt>span.brackets:after{content:"]"}html.writer-html5 .rst-content dl.footnote>dt>span.fn-backref{font-style:italic}html.writer-html5 .rst-content dl.footnote>dd{margin:0 0 .5rem;line-height:1.2rem}html.writer-html5 .rst-content dl.footnote>dd p,html.writer-html5 .rst-content dl.option-list kbd{font-size:.9rem}.rst-content table.docutils.footnote,html.writer-html4 .rst-content table.docutils.citation,html.writer-html5 .rst-content dl.footnote{color:grey}.rst-content table.docutils.footnote code,.rst-content table.docutils.footnote tt,html.writer-html4 .rst-content table.docutils.citation code,html.writer-html4 .rst-content table.docutils.citation tt,html.writer-html5 .rst-content dl.footnote code,html.writer-html5 .rst-content dl.footnote tt{color:#555}.rst-content .wy-table-responsive.citation,.rst-content .wy-table-responsive.footnote{margin-bottom:0}.rst-content .wy-table-responsive.citation+:not(.citation),.rst-content .wy-table-responsive.footnote+:not(.footnote){margin-top:24px}.rst-content .wy-table-responsive.citation:last-child,.rst-content .wy-table-responsive.footnote:last-child{margin-bottom:24px}.rst-content table.docutils th{border-color:#e1e4e5}html.writer-html5 .rst-content table.docutils th{border:1px solid #e1e4e5}html.writer-html5 .rst-content table.docutils td>p,html.writer-html5 .rst-content table.docutils th>p{line-height:1rem;margin-bottom:0;font-size:.9rem}.rst-content table.docutils td .last,.rst-content table.docutils td .last>:last-child{margin-bottom:0}.rst-content table.field-list,.rst-content table.field-list td{border:none}.rst-content table.field-list td p{font-size:inherit;line-height:inherit}.rst-content table.field-list td>strong{display:inline-block}.rst-content table.field-list .field-name{padding-right:10px;text-align:left;white-space:nowrap}.rst-content table.field-list .field-body{text-align:left}.rst-content code,.rst-content tt{color:#000;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;padding:2px 5px}.rst-content code big,.rst-content code em,.rst-content tt big,.rst-content tt em{font-size:100%!important;line-height:normal}.rst-content code.literal,.rst-content tt.literal{color:#e74c3c}.rst-content code.xref,.rst-content tt.xref,a .rst-content code,a .rst-content tt{font-weight:700;color:#404040}.rst-content kbd,.rst-content pre,.rst-content samp{font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace}.rst-content a code,.rst-content a tt{color:#2980b9}.rst-content dl{margin-bottom:24px}.rst-content dl dt{font-weight:700;margin-bottom:12px}.rst-content dl ol,.rst-content dl p,.rst-content dl table,.rst-content dl ul{margin-bottom:12px}.rst-content dl dd{margin:0 0 12px 24px;line-height:24px}html.writer-html4 .rst-content dl:not(.docutils),html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple){margin-bottom:24px}html.writer-html4 .rst-content dl:not(.docutils)>dt,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple)>dt{display:table;margin:6px 0;font-size:90%;line-height:normal;background:#e7f2fa;color:#2980b9;border-top:3px solid #6ab0de;padding:6px;position:relative}html.writer-html4 .rst-content dl:not(.docutils)>dt:before,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple)>dt:before{color:#6ab0de}html.writer-html4 .rst-content dl:not(.docutils)>dt .headerlink,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple)>dt .headerlink{color:#404040;font-size:100%!important}html.writer-html4 .rst-content dl:not(.docutils) dl:not(.field-list)>dt,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) dl:not(.field-list)>dt{margin-bottom:6px;border:none;border-left:3px solid #ccc;background:#f0f0f0;color:#555}html.writer-html4 .rst-content dl:not(.docutils) dl:not(.field-list)>dt .headerlink,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) dl:not(.field-list)>dt .headerlink{color:#404040;font-size:100%!important}html.writer-html4 .rst-content dl:not(.docutils)>dt:first-child,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple)>dt:first-child{margin-top:0}html.writer-html4 .rst-content dl:not(.docutils) code,html.writer-html4 .rst-content dl:not(.docutils) tt,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) code,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) tt{font-weight:700}html.writer-html4 .rst-content dl:not(.docutils) code.descclassname,html.writer-html4 .rst-content dl:not(.docutils) code.descname,html.writer-html4 .rst-content dl:not(.docutils) tt.descclassname,html.writer-html4 .rst-content dl:not(.docutils) tt.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) code.descclassname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) code.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) tt.descclassname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) tt.descname{background-color:transparent;border:none;padding:0;font-size:100%!important}html.writer-html4 .rst-content dl:not(.docutils) code.descname,html.writer-html4 .rst-content dl:not(.docutils) tt.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) code.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) tt.descname{font-weight:700}html.writer-html4 .rst-content dl:not(.docutils) .optional,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) .optional{display:inline-block;padding:0 4px;color:#000;font-weight:700}html.writer-html4 .rst-content dl:not(.docutils) .property,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) .property{display:inline-block;padding-right:8px}.rst-content .viewcode-back,.rst-content .viewcode-link{display:inline-block;color:#27ae60;font-size:80%;padding-left:24px}.rst-content .viewcode-back{display:block;float:right}.rst-content p.rubric{margin-bottom:12px;font-weight:700}.rst-content code.download,.rst-content tt.download{background:inherit;padding:inherit;font-weight:400;font-family:inherit;font-size:inherit;color:inherit;border:inherit;white-space:inherit}.rst-content code.download span:first-child,.rst-content tt.download span:first-child{-webkit-font-smoothing:subpixel-antialiased}.rst-content code.download span:first-child:before,.rst-content tt.download span:first-child:before{margin-right:4px}.rst-content .guilabel{border:1px solid #7fbbe3;background:#e7f2fa;font-size:80%;font-weight:700;border-radius:4px;padding:2.4px 6px;margin:auto 2px}.rst-content .versionmodified{font-style:italic}@media screen and (max-width:480px){.rst-content .sidebar{width:100%}}span[id*=MathJax-Span]{color:#404040}.math{text-align:center}@font-face{font-family:Lato;src:url(fonts/lato-normal.woff2?bd03a2cc277bbbc338d464e679fe9942) format("woff2"),url(fonts/lato-normal.woff?27bd77b9162d388cb8d4c4217c7c5e2a) format("woff");font-weight:400;font-style:normal;font-display:block}@font-face{font-family:Lato;src:url(fonts/lato-bold.woff2?cccb897485813c7c256901dbca54ecf2) format("woff2"),url(fonts/lato-bold.woff?d878b6c29b10beca227e9eef4246111b) format("woff");font-weight:700;font-style:normal;font-display:block}@font-face{font-family:Lato;src:url(fonts/lato-bold-italic.woff2?0b6bb6725576b072c5d0b02ecdd1900d) format("woff2"),url(fonts/lato-bold-italic.woff?9c7e4e9eb485b4a121c760e61bc3707c) format("woff");font-weight:700;font-style:italic;font-display:block}@font-face{font-family:Lato;src:url(fonts/lato-normal-italic.woff2?4eb103b4d12be57cb1d040ed5e162e9d) format("woff2"),url(fonts/lato-normal-italic.woff?f28f2d6482446544ef1ea1ccc6dd5892) format("woff");font-weight:400;font-style:italic;font-display:block}@font-face{font-family:Roboto Slab;font-style:normal;font-weight:400;src:url(fonts/Roboto-Slab-Regular.woff2?7abf5b8d04d26a2cafea937019bca958) format("woff2"),url(fonts/Roboto-Slab-Regular.woff?c1be9284088d487c5e3ff0a10a92e58c) format("woff");font-display:block}@font-face{font-family:Roboto Slab;font-style:normal;font-weight:700;src:url(fonts/Roboto-Slab-Bold.woff2?9984f4a9bda09be08e83f2506954adbe) format("woff2"),url(fonts/Roboto-Slab-Bold.woff?bed5564a116b05148e3b3bea6fb1162a) format("woff");font-display:block}
\ No newline at end of file
diff --git a/docs/_build/html/_static/custom.css b/docs/_build/html/_static/custom.css
deleted file mode 100644
index 2a924f1d..00000000
--- a/docs/_build/html/_static/custom.css
+++ /dev/null
@@ -1 +0,0 @@
-/* This file intentionally left blank. */
diff --git a/docs/_build/html/_static/doctools.js b/docs/_build/html/_static/doctools.js
deleted file mode 100644
index 61ac9d26..00000000
--- a/docs/_build/html/_static/doctools.js
+++ /dev/null
@@ -1,321 +0,0 @@
-/*
- * doctools.js
- * ~~~~~~~~~~~
- *
- * Sphinx JavaScript utilities for all documentation.
- *
- * :copyright: Copyright 2007-2021 by the Sphinx team, see AUTHORS.
- * :license: BSD, see LICENSE for details.
- *
- */
-
-/**
- * select a different prefix for underscore
- */
-$u = _.noConflict();
-
-/**
- * make the code below compatible with browsers without
- * an installed firebug like debugger
-if (!window.console || !console.firebug) {
-  var names = ["log", "debug", "info", "warn", "error", "assert", "dir",
-    "dirxml", "group", "groupEnd", "time", "timeEnd", "count", "trace",
-    "profile", "profileEnd"];
-  window.console = {};
-  for (var i = 0; i < names.length; ++i)
-    window.console[names[i]] = function() {};
-}
- */
-
-/**
- * small helper function to urldecode strings
- *
- * See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/decodeURIComponent#Decoding_query_parameters_from_a_URL
- */
-jQuery.urldecode = function(x) {
-  if (!x) {
-    return x
-  }
-  return decodeURIComponent(x.replace(/\+/g, ' '));
-};
-
-/**
- * small helper function to urlencode strings
- */
-jQuery.urlencode = encodeURIComponent;
-
-/**
- * This function returns the parsed url parameters of the
- * current request. Multiple values per key are supported,
- * it will always return arrays of strings for the value parts.
- */
-jQuery.getQueryParameters = function(s) {
-  if (typeof s === 'undefined')
-    s = document.location.search;
-  var parts = s.substr(s.indexOf('?') + 1).split('&');
-  var result = {};
-  for (var i = 0; i < parts.length; i++) {
-    var tmp = parts[i].split('=', 2);
-    var key = jQuery.urldecode(tmp[0]);
-    var value = jQuery.urldecode(tmp[1]);
-    if (key in result)
-      result[key].push(value);
-    else
-      result[key] = [value];
-  }
-  return result;
-};
-
-/**
- * highlight a given string on a jquery object by wrapping it in
- * span elements with the given class name.
- */
-jQuery.fn.highlightText = function(text, className) {
-  function highlight(node, addItems) {
-    if (node.nodeType === 3) {
-      var val = node.nodeValue;
-      var pos = val.toLowerCase().indexOf(text);
-      if (pos >= 0 &&
-          !jQuery(node.parentNode).hasClass(className) &&
-          !jQuery(node.parentNode).hasClass("nohighlight")) {
-        var span;
-        var isInSVG = jQuery(node).closest("body, svg, foreignObject").is("svg");
-        if (isInSVG) {
-          span = document.createElementNS("http://www.w3.org/2000/svg", "tspan");
-        } else {
-          span = document.createElement("span");
-          span.className = className;
-        }
-        span.appendChild(document.createTextNode(val.substr(pos, text.length)));
-        node.parentNode.insertBefore(span, node.parentNode.insertBefore(
-          document.createTextNode(val.substr(pos + text.length)),
-          node.nextSibling));
-        node.nodeValue = val.substr(0, pos);
-        if (isInSVG) {
-          var rect = document.createElementNS("http://www.w3.org/2000/svg", "rect");
-          var bbox = node.parentElement.getBBox();
-          rect.x.baseVal.value = bbox.x;
-          rect.y.baseVal.value = bbox.y;
-          rect.width.baseVal.value = bbox.width;
-          rect.height.baseVal.value = bbox.height;
-          rect.setAttribute('class', className);
-          addItems.push({
-              "parent": node.parentNode,
-              "target": rect});
-        }
-      }
-    }
-    else if (!jQuery(node).is("button, select, textarea")) {
-      jQuery.each(node.childNodes, function() {
-        highlight(this, addItems);
-      });
-    }
-  }
-  var addItems = [];
-  var result = this.each(function() {
-    highlight(this, addItems);
-  });
-  for (var i = 0; i < addItems.length; ++i) {
-    jQuery(addItems[i].parent).before(addItems[i].target);
-  }
-  return result;
-};
-
-/*
- * backward compatibility for jQuery.browser
- * This will be supported until firefox bug is fixed.
- */
-if (!jQuery.browser) {
-  jQuery.uaMatch = function(ua) {
-    ua = ua.toLowerCase();
-
-    var match = /(chrome)[ \/]([\w.]+)/.exec(ua) ||
-      /(webkit)[ \/]([\w.]+)/.exec(ua) ||
-      /(opera)(?:.*version|)[ \/]([\w.]+)/.exec(ua) ||
-      /(msie) ([\w.]+)/.exec(ua) ||
-      ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec(ua) ||
-      [];
-
-    return {
-      browser: match[ 1 ] || "",
-      version: match[ 2 ] || "0"
-    };
-  };
-  jQuery.browser = {};
-  jQuery.browser[jQuery.uaMatch(navigator.userAgent).browser] = true;
-}
-
-/**
- * Small JavaScript module for the documentation.
- */
-var Documentation = {
-
-  init : function() {
-    this.fixFirefoxAnchorBug();
-    this.highlightSearchWords();
-    this.initIndexTable();
-    if (DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS) {
-      this.initOnKeyListeners();
-    }
-  },
-
-  /**
-   * i18n support
-   */
-  TRANSLATIONS : {},
-  PLURAL_EXPR : function(n) { return n === 1 ? 0 : 1; },
-  LOCALE : 'unknown',
-
-  // gettext and ngettext don't access this so that the functions
-  // can safely bound to a different name (_ = Documentation.gettext)
-  gettext : function(string) {
-    var translated = Documentation.TRANSLATIONS[string];
-    if (typeof translated === 'undefined')
-      return string;
-    return (typeof translated === 'string') ? translated : translated[0];
-  },
-
-  ngettext : function(singular, plural, n) {
-    var translated = Documentation.TRANSLATIONS[singular];
-    if (typeof translated === 'undefined')
-      return (n == 1) ? singular : plural;
-    return translated[Documentation.PLURALEXPR(n)];
-  },
-
-  addTranslations : function(catalog) {
-    for (var key in catalog.messages)
-      this.TRANSLATIONS[key] = catalog.messages[key];
-    this.PLURAL_EXPR = new Function('n', 'return +(' + catalog.plural_expr + ')');
-    this.LOCALE = catalog.locale;
-  },
-
-  /**
-   * add context elements like header anchor links
-   */
-  addContextElements : function() {
-    $('div[id] > :header:first').each(function() {
-      $('<a class="headerlink">\u00B6</a>').
-      attr('href', '#' + this.id).
-      attr('title', _('Permalink to this headline')).
-      appendTo(this);
-    });
-    $('dt[id]').each(function() {
-      $('<a class="headerlink">\u00B6</a>').
-      attr('href', '#' + this.id).
-      attr('title', _('Permalink to this definition')).
-      appendTo(this);
-    });
-  },
-
-  /**
-   * workaround a firefox stupidity
-   * see: https://bugzilla.mozilla.org/show_bug.cgi?id=645075
-   */
-  fixFirefoxAnchorBug : function() {
-    if (document.location.hash && $.browser.mozilla)
-      window.setTimeout(function() {
-        document.location.href += '';
-      }, 10);
-  },
-
-  /**
-   * highlight the search words provided in the url in the text
-   */
-  highlightSearchWords : function() {
-    var params = $.getQueryParameters();
-    var terms = (params.highlight) ? params.highlight[0].split(/\s+/) : [];
-    if (terms.length) {
-      var body = $('div.body');
-      if (!body.length) {
-        body = $('body');
-      }
-      window.setTimeout(function() {
-        $.each(terms, function() {
-          body.highlightText(this.toLowerCase(), 'highlighted');
-        });
-      }, 10);
-      $('<p class="highlight-link"><a href="javascript:Documentation.' +
-        'hideSearchWords()">' + _('Hide Search Matches') + '</a></p>')
-          .appendTo($('#searchbox'));
-    }
-  },
-
-  /**
-   * init the domain index toggle buttons
-   */
-  initIndexTable : function() {
-    var togglers = $('img.toggler').click(function() {
-      var src = $(this).attr('src');
-      var idnum = $(this).attr('id').substr(7);
-      $('tr.cg-' + idnum).toggle();
-      if (src.substr(-9) === 'minus.png')
-        $(this).attr('src', src.substr(0, src.length-9) + 'plus.png');
-      else
-        $(this).attr('src', src.substr(0, src.length-8) + 'minus.png');
-    }).css('display', '');
-    if (DOCUMENTATION_OPTIONS.COLLAPSE_INDEX) {
-        togglers.click();
-    }
-  },
-
-  /**
-   * helper function to hide the search marks again
-   */
-  hideSearchWords : function() {
-    $('#searchbox .highlight-link').fadeOut(300);
-    $('span.highlighted').removeClass('highlighted');
-  },
-
-  /**
-   * make the url absolute
-   */
-  makeURL : function(relativeURL) {
-    return DOCUMENTATION_OPTIONS.URL_ROOT + '/' + relativeURL;
-  },
-
-  /**
-   * get the current relative url
-   */
-  getCurrentURL : function() {
-    var path = document.location.pathname;
-    var parts = path.split(/\//);
-    $.each(DOCUMENTATION_OPTIONS.URL_ROOT.split(/\//), function() {
-      if (this === '..')
-        parts.pop();
-    });
-    var url = parts.join('/');
-    return path.substring(url.lastIndexOf('/') + 1, path.length - 1);
-  },
-
-  initOnKeyListeners: function() {
-    $(document).keydown(function(event) {
-      var activeElementType = document.activeElement.tagName;
-      // don't navigate when in search box, textarea, dropdown or button
-      if (activeElementType !== 'TEXTAREA' && activeElementType !== 'INPUT' && activeElementType !== 'SELECT'
-          && activeElementType !== 'BUTTON' && !event.altKey && !event.ctrlKey && !event.metaKey
-          && !event.shiftKey) {
-        switch (event.keyCode) {
-          case 37: // left
-            var prevHref = $('link[rel="prev"]').prop('href');
-            if (prevHref) {
-              window.location.href = prevHref;
-              return false;
-            }
-          case 39: // right
-            var nextHref = $('link[rel="next"]').prop('href');
-            if (nextHref) {
-              window.location.href = nextHref;
-              return false;
-            }
-        }
-      }
-    });
-  }
-};
-
-// quick alias for translations
-_ = Documentation.gettext;
-
-$(document).ready(function() {
-  Documentation.init();
-});
diff --git a/docs/_build/html/_static/documentation_options.js b/docs/_build/html/_static/documentation_options.js
deleted file mode 100644
index 013a92a7..00000000
--- a/docs/_build/html/_static/documentation_options.js
+++ /dev/null
@@ -1,12 +0,0 @@
-var DOCUMENTATION_OPTIONS = {
-    URL_ROOT: document.getElementById("documentation_options").getAttribute('data-url_root'),
-    VERSION: '1.7.5',
-    LANGUAGE: 'None',
-    COLLAPSE_INDEX: false,
-    BUILDER: 'html',
-    FILE_SUFFIX: '.html',
-    LINK_SUFFIX: '.html',
-    HAS_SOURCE: true,
-    SOURCELINK_SUFFIX: '.txt',
-    NAVIGATION_WITH_KEYS: false
-};
\ No newline at end of file
diff --git a/docs/_build/html/_static/file.png b/docs/_build/html/_static/file.png
deleted file mode 100644
index a858a410..00000000
Binary files a/docs/_build/html/_static/file.png and /dev/null differ
diff --git a/docs/_build/html/_static/fonts/Inconsolata-Bold.ttf b/docs/_build/html/_static/fonts/Inconsolata-Bold.ttf
deleted file mode 100644
index 809c1f58..00000000
Binary files a/docs/_build/html/_static/fonts/Inconsolata-Bold.ttf and /dev/null differ
diff --git a/docs/_build/html/_static/fonts/Inconsolata-Regular.ttf b/docs/_build/html/_static/fonts/Inconsolata-Regular.ttf
deleted file mode 100644
index fc981ce7..00000000
Binary files a/docs/_build/html/_static/fonts/Inconsolata-Regular.ttf and /dev/null differ
diff --git a/docs/_build/html/_static/fonts/Inconsolata.ttf b/docs/_build/html/_static/fonts/Inconsolata.ttf
deleted file mode 100644
index 4b8a36d2..00000000
Binary files a/docs/_build/html/_static/fonts/Inconsolata.ttf and /dev/null differ
diff --git a/docs/_build/html/_static/fonts/Lato-Bold.ttf b/docs/_build/html/_static/fonts/Lato-Bold.ttf
deleted file mode 100644
index 1d23c706..00000000
Binary files a/docs/_build/html/_static/fonts/Lato-Bold.ttf and /dev/null differ
diff --git a/docs/_build/html/_static/fonts/Lato-Regular.ttf b/docs/_build/html/_static/fonts/Lato-Regular.ttf
deleted file mode 100644
index 0f3d0f83..00000000
Binary files a/docs/_build/html/_static/fonts/Lato-Regular.ttf and /dev/null differ
diff --git a/docs/_build/html/_static/fonts/Lato/lato-bold.eot b/docs/_build/html/_static/fonts/Lato/lato-bold.eot
deleted file mode 100644
index 3361183a..00000000
Binary files a/docs/_build/html/_static/fonts/Lato/lato-bold.eot and /dev/null differ
diff --git a/docs/_build/html/_static/fonts/Lato/lato-bold.ttf b/docs/_build/html/_static/fonts/Lato/lato-bold.ttf
deleted file mode 100644
index 29f691d5..00000000
Binary files a/docs/_build/html/_static/fonts/Lato/lato-bold.ttf and /dev/null differ
diff --git a/docs/_build/html/_static/fonts/Lato/lato-bold.woff b/docs/_build/html/_static/fonts/Lato/lato-bold.woff
deleted file mode 100644
index c6dff51f..00000000
Binary files a/docs/_build/html/_static/fonts/Lato/lato-bold.woff and /dev/null differ
diff --git a/docs/_build/html/_static/fonts/Lato/lato-bold.woff2 b/docs/_build/html/_static/fonts/Lato/lato-bold.woff2
deleted file mode 100644
index bb195043..00000000
Binary files a/docs/_build/html/_static/fonts/Lato/lato-bold.woff2 and /dev/null differ
diff --git a/docs/_build/html/_static/fonts/Lato/lato-bolditalic.eot b/docs/_build/html/_static/fonts/Lato/lato-bolditalic.eot
deleted file mode 100644
index 3d415493..00000000
Binary files a/docs/_build/html/_static/fonts/Lato/lato-bolditalic.eot and /dev/null differ
diff --git a/docs/_build/html/_static/fonts/Lato/lato-bolditalic.ttf b/docs/_build/html/_static/fonts/Lato/lato-bolditalic.ttf
deleted file mode 100644
index f402040b..00000000
Binary files a/docs/_build/html/_static/fonts/Lato/lato-bolditalic.ttf and /dev/null differ
diff --git a/docs/_build/html/_static/fonts/Lato/lato-bolditalic.woff b/docs/_build/html/_static/fonts/Lato/lato-bolditalic.woff
deleted file mode 100644
index 88ad05b9..00000000
Binary files a/docs/_build/html/_static/fonts/Lato/lato-bolditalic.woff and /dev/null differ
diff --git a/docs/_build/html/_static/fonts/Lato/lato-bolditalic.woff2 b/docs/_build/html/_static/fonts/Lato/lato-bolditalic.woff2
deleted file mode 100644
index c4e3d804..00000000
Binary files a/docs/_build/html/_static/fonts/Lato/lato-bolditalic.woff2 and /dev/null differ
diff --git a/docs/_build/html/_static/fonts/Lato/lato-italic.eot b/docs/_build/html/_static/fonts/Lato/lato-italic.eot
deleted file mode 100644
index 3f826421..00000000
Binary files a/docs/_build/html/_static/fonts/Lato/lato-italic.eot and /dev/null differ
diff --git a/docs/_build/html/_static/fonts/Lato/lato-italic.ttf b/docs/_build/html/_static/fonts/Lato/lato-italic.ttf
deleted file mode 100644
index b4bfc9b2..00000000
Binary files a/docs/_build/html/_static/fonts/Lato/lato-italic.ttf and /dev/null differ
diff --git a/docs/_build/html/_static/fonts/Lato/lato-italic.woff b/docs/_build/html/_static/fonts/Lato/lato-italic.woff
deleted file mode 100644
index 76114bc0..00000000
Binary files a/docs/_build/html/_static/fonts/Lato/lato-italic.woff and /dev/null differ
diff --git a/docs/_build/html/_static/fonts/Lato/lato-italic.woff2 b/docs/_build/html/_static/fonts/Lato/lato-italic.woff2
deleted file mode 100644
index 3404f37e..00000000
Binary files a/docs/_build/html/_static/fonts/Lato/lato-italic.woff2 and /dev/null differ
diff --git a/docs/_build/html/_static/fonts/Lato/lato-regular.eot b/docs/_build/html/_static/fonts/Lato/lato-regular.eot
deleted file mode 100644
index 11e3f2a5..00000000
Binary files a/docs/_build/html/_static/fonts/Lato/lato-regular.eot and /dev/null differ
diff --git a/docs/_build/html/_static/fonts/Lato/lato-regular.ttf b/docs/_build/html/_static/fonts/Lato/lato-regular.ttf
deleted file mode 100644
index 74decd9e..00000000
Binary files a/docs/_build/html/_static/fonts/Lato/lato-regular.ttf and /dev/null differ
diff --git a/docs/_build/html/_static/fonts/Lato/lato-regular.woff b/docs/_build/html/_static/fonts/Lato/lato-regular.woff
deleted file mode 100644
index ae1307ff..00000000
Binary files a/docs/_build/html/_static/fonts/Lato/lato-regular.woff and /dev/null differ
diff --git a/docs/_build/html/_static/fonts/Lato/lato-regular.woff2 b/docs/_build/html/_static/fonts/Lato/lato-regular.woff2
deleted file mode 100644
index 3bf98433..00000000
Binary files a/docs/_build/html/_static/fonts/Lato/lato-regular.woff2 and /dev/null differ
diff --git a/docs/_build/html/_static/fonts/RobotoSlab-Bold.ttf b/docs/_build/html/_static/fonts/RobotoSlab-Bold.ttf
deleted file mode 100644
index df5d1df2..00000000
Binary files a/docs/_build/html/_static/fonts/RobotoSlab-Bold.ttf and /dev/null differ
diff --git a/docs/_build/html/_static/fonts/RobotoSlab-Regular.ttf b/docs/_build/html/_static/fonts/RobotoSlab-Regular.ttf
deleted file mode 100644
index eb52a790..00000000
Binary files a/docs/_build/html/_static/fonts/RobotoSlab-Regular.ttf and /dev/null differ
diff --git a/docs/_build/html/_static/fonts/RobotoSlab/roboto-slab-v7-bold.eot b/docs/_build/html/_static/fonts/RobotoSlab/roboto-slab-v7-bold.eot
deleted file mode 100644
index 79dc8efe..00000000
Binary files a/docs/_build/html/_static/fonts/RobotoSlab/roboto-slab-v7-bold.eot and /dev/null differ
diff --git a/docs/_build/html/_static/fonts/RobotoSlab/roboto-slab-v7-bold.ttf b/docs/_build/html/_static/fonts/RobotoSlab/roboto-slab-v7-bold.ttf
deleted file mode 100644
index df5d1df2..00000000
Binary files a/docs/_build/html/_static/fonts/RobotoSlab/roboto-slab-v7-bold.ttf and /dev/null differ
diff --git a/docs/_build/html/_static/fonts/RobotoSlab/roboto-slab-v7-bold.woff b/docs/_build/html/_static/fonts/RobotoSlab/roboto-slab-v7-bold.woff
deleted file mode 100644
index 6cb60000..00000000
Binary files a/docs/_build/html/_static/fonts/RobotoSlab/roboto-slab-v7-bold.woff and /dev/null differ
diff --git a/docs/_build/html/_static/fonts/RobotoSlab/roboto-slab-v7-bold.woff2 b/docs/_build/html/_static/fonts/RobotoSlab/roboto-slab-v7-bold.woff2
deleted file mode 100644
index 7059e231..00000000
Binary files a/docs/_build/html/_static/fonts/RobotoSlab/roboto-slab-v7-bold.woff2 and /dev/null differ
diff --git a/docs/_build/html/_static/fonts/RobotoSlab/roboto-slab-v7-regular.eot b/docs/_build/html/_static/fonts/RobotoSlab/roboto-slab-v7-regular.eot
deleted file mode 100644
index 2f7ca78a..00000000
Binary files a/docs/_build/html/_static/fonts/RobotoSlab/roboto-slab-v7-regular.eot and /dev/null differ
diff --git a/docs/_build/html/_static/fonts/RobotoSlab/roboto-slab-v7-regular.ttf b/docs/_build/html/_static/fonts/RobotoSlab/roboto-slab-v7-regular.ttf
deleted file mode 100644
index eb52a790..00000000
Binary files a/docs/_build/html/_static/fonts/RobotoSlab/roboto-slab-v7-regular.ttf and /dev/null differ
diff --git a/docs/_build/html/_static/fonts/RobotoSlab/roboto-slab-v7-regular.woff b/docs/_build/html/_static/fonts/RobotoSlab/roboto-slab-v7-regular.woff
deleted file mode 100644
index f815f63f..00000000
Binary files a/docs/_build/html/_static/fonts/RobotoSlab/roboto-slab-v7-regular.woff and /dev/null differ
diff --git a/docs/_build/html/_static/fonts/RobotoSlab/roboto-slab-v7-regular.woff2 b/docs/_build/html/_static/fonts/RobotoSlab/roboto-slab-v7-regular.woff2
deleted file mode 100644
index f2c76e5b..00000000
Binary files a/docs/_build/html/_static/fonts/RobotoSlab/roboto-slab-v7-regular.woff2 and /dev/null differ
diff --git a/docs/_build/html/_static/fonts/fontawesome-webfont.eot b/docs/_build/html/_static/fonts/fontawesome-webfont.eot
deleted file mode 100644
index e9f60ca9..00000000
Binary files a/docs/_build/html/_static/fonts/fontawesome-webfont.eot and /dev/null differ
diff --git a/docs/_build/html/_static/fonts/fontawesome-webfont.svg b/docs/_build/html/_static/fonts/fontawesome-webfont.svg
deleted file mode 100644
index 855c845e..00000000
--- a/docs/_build/html/_static/fonts/fontawesome-webfont.svg
+++ /dev/null
@@ -1,2671 +0,0 @@
-<?xml version="1.0" standalone="no"?>
-<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" >
-<svg>
-<metadata>
-Created by FontForge 20120731 at Mon Oct 24 17:37:40 2016
- By ,,,
-Copyright Dave Gandy 2016. All rights reserved.
-</metadata>
-<defs>
-<font id="FontAwesome" horiz-adv-x="1536" >
-  <font-face 
-    font-family="FontAwesome"
-    font-weight="400"
-    font-stretch="normal"
-    units-per-em="1792"
-    panose-1="0 0 0 0 0 0 0 0 0 0"
-    ascent="1536"
-    descent="-256"
-    bbox="-1.02083 -256.962 2304.6 1537.02"
-    underline-thickness="0"
-    underline-position="0"
-    unicode-range="U+0020-F500"
-  />
-<missing-glyph horiz-adv-x="896" 
-d="M224 112h448v1312h-448v-1312zM112 0v1536h672v-1536h-672z" />
-    <glyph glyph-name=".notdef" horiz-adv-x="896" 
-d="M224 112h448v1312h-448v-1312zM112 0v1536h672v-1536h-672z" />
-    <glyph glyph-name=".null" horiz-adv-x="0" 
- />
-    <glyph glyph-name="nonmarkingreturn" horiz-adv-x="597" 
- />
-    <glyph glyph-name="space" unicode=" " horiz-adv-x="448" 
- />
-    <glyph glyph-name="dieresis" unicode="&#xa8;" horiz-adv-x="1792" 
- />
-    <glyph glyph-name="copyright" unicode="&#xa9;" horiz-adv-x="1792" 
- />
-    <glyph glyph-name="registered" unicode="&#xae;" horiz-adv-x="1792" 
- />
-    <glyph glyph-name="acute" unicode="&#xb4;" horiz-adv-x="1792" 
- />
-    <glyph glyph-name="AE" unicode="&#xc6;" horiz-adv-x="1792" 
- />
-    <glyph glyph-name="Oslash" unicode="&#xd8;" horiz-adv-x="1792" 
- />
-    <glyph glyph-name="trademark" unicode="&#x2122;" horiz-adv-x="1792" 
- />
-    <glyph glyph-name="infinity" unicode="&#x221e;" horiz-adv-x="1792" 
- />
-    <glyph glyph-name="notequal" unicode="&#x2260;" horiz-adv-x="1792" 
- />
-    <glyph glyph-name="glass" unicode="&#xf000;" horiz-adv-x="1792" 
-d="M1699 1350q0 -35 -43 -78l-632 -632v-768h320q26 0 45 -19t19 -45t-19 -45t-45 -19h-896q-26 0 -45 19t-19 45t19 45t45 19h320v768l-632 632q-43 43 -43 78q0 23 18 36.5t38 17.5t43 4h1408q23 0 43 -4t38 -17.5t18 -36.5z" />
-    <glyph glyph-name="music" unicode="&#xf001;" 
-d="M1536 1312v-1120q0 -50 -34 -89t-86 -60.5t-103.5 -32t-96.5 -10.5t-96.5 10.5t-103.5 32t-86 60.5t-34 89t34 89t86 60.5t103.5 32t96.5 10.5q105 0 192 -39v537l-768 -237v-709q0 -50 -34 -89t-86 -60.5t-103.5 -32t-96.5 -10.5t-96.5 10.5t-103.5 32t-86 60.5t-34 89
-t34 89t86 60.5t103.5 32t96.5 10.5q105 0 192 -39v967q0 31 19 56.5t49 35.5l832 256q12 4 28 4q40 0 68 -28t28 -68z" />
-    <glyph glyph-name="search" unicode="&#xf002;" horiz-adv-x="1664" 
-d="M1152 704q0 185 -131.5 316.5t-316.5 131.5t-316.5 -131.5t-131.5 -316.5t131.5 -316.5t316.5 -131.5t316.5 131.5t131.5 316.5zM1664 -128q0 -52 -38 -90t-90 -38q-54 0 -90 38l-343 342q-179 -124 -399 -124q-143 0 -273.5 55.5t-225 150t-150 225t-55.5 273.5
-t55.5 273.5t150 225t225 150t273.5 55.5t273.5 -55.5t225 -150t150 -225t55.5 -273.5q0 -220 -124 -399l343 -343q37 -37 37 -90z" />
-    <glyph glyph-name="envelope" unicode="&#xf003;" horiz-adv-x="1792" 
-d="M1664 32v768q-32 -36 -69 -66q-268 -206 -426 -338q-51 -43 -83 -67t-86.5 -48.5t-102.5 -24.5h-1h-1q-48 0 -102.5 24.5t-86.5 48.5t-83 67q-158 132 -426 338q-37 30 -69 66v-768q0 -13 9.5 -22.5t22.5 -9.5h1472q13 0 22.5 9.5t9.5 22.5zM1664 1083v11v13.5t-0.5 13
-t-3 12.5t-5.5 9t-9 7.5t-14 2.5h-1472q-13 0 -22.5 -9.5t-9.5 -22.5q0 -168 147 -284q193 -152 401 -317q6 -5 35 -29.5t46 -37.5t44.5 -31.5t50.5 -27.5t43 -9h1h1q20 0 43 9t50.5 27.5t44.5 31.5t46 37.5t35 29.5q208 165 401 317q54 43 100.5 115.5t46.5 131.5z
-M1792 1120v-1088q0 -66 -47 -113t-113 -47h-1472q-66 0 -113 47t-47 113v1088q0 66 47 113t113 47h1472q66 0 113 -47t47 -113z" />
-    <glyph glyph-name="heart" unicode="&#xf004;" horiz-adv-x="1792" 
-d="M896 -128q-26 0 -44 18l-624 602q-10 8 -27.5 26t-55.5 65.5t-68 97.5t-53.5 121t-23.5 138q0 220 127 344t351 124q62 0 126.5 -21.5t120 -58t95.5 -68.5t76 -68q36 36 76 68t95.5 68.5t120 58t126.5 21.5q224 0 351 -124t127 -344q0 -221 -229 -450l-623 -600
-q-18 -18 -44 -18z" />
-    <glyph glyph-name="star" unicode="&#xf005;" horiz-adv-x="1664" 
-d="M1664 889q0 -22 -26 -48l-363 -354l86 -500q1 -7 1 -20q0 -21 -10.5 -35.5t-30.5 -14.5q-19 0 -40 12l-449 236l-449 -236q-22 -12 -40 -12q-21 0 -31.5 14.5t-10.5 35.5q0 6 2 20l86 500l-364 354q-25 27 -25 48q0 37 56 46l502 73l225 455q19 41 49 41t49 -41l225 -455
-l502 -73q56 -9 56 -46z" />
-    <glyph glyph-name="star_empty" unicode="&#xf006;" horiz-adv-x="1664" 
-d="M1137 532l306 297l-422 62l-189 382l-189 -382l-422 -62l306 -297l-73 -421l378 199l377 -199zM1664 889q0 -22 -26 -48l-363 -354l86 -500q1 -7 1 -20q0 -50 -41 -50q-19 0 -40 12l-449 236l-449 -236q-22 -12 -40 -12q-21 0 -31.5 14.5t-10.5 35.5q0 6 2 20l86 500
-l-364 354q-25 27 -25 48q0 37 56 46l502 73l225 455q19 41 49 41t49 -41l225 -455l502 -73q56 -9 56 -46z" />
-    <glyph glyph-name="user" unicode="&#xf007;" horiz-adv-x="1280" 
-d="M1280 137q0 -109 -62.5 -187t-150.5 -78h-854q-88 0 -150.5 78t-62.5 187q0 85 8.5 160.5t31.5 152t58.5 131t94 89t134.5 34.5q131 -128 313 -128t313 128q76 0 134.5 -34.5t94 -89t58.5 -131t31.5 -152t8.5 -160.5zM1024 1024q0 -159 -112.5 -271.5t-271.5 -112.5
-t-271.5 112.5t-112.5 271.5t112.5 271.5t271.5 112.5t271.5 -112.5t112.5 -271.5z" />
-    <glyph glyph-name="film" unicode="&#xf008;" horiz-adv-x="1920" 
-d="M384 -64v128q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45t45 -19h128q26 0 45 19t19 45zM384 320v128q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45t45 -19h128q26 0 45 19t19 45zM384 704v128q0 26 -19 45t-45 19h-128
-q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45t45 -19h128q26 0 45 19t19 45zM1408 -64v512q0 26 -19 45t-45 19h-768q-26 0 -45 -19t-19 -45v-512q0 -26 19 -45t45 -19h768q26 0 45 19t19 45zM384 1088v128q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45
-t45 -19h128q26 0 45 19t19 45zM1792 -64v128q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45t45 -19h128q26 0 45 19t19 45zM1408 704v512q0 26 -19 45t-45 19h-768q-26 0 -45 -19t-19 -45v-512q0 -26 19 -45t45 -19h768q26 0 45 19t19 45zM1792 320v128
-q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45t45 -19h128q26 0 45 19t19 45zM1792 704v128q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45t45 -19h128q26 0 45 19t19 45zM1792 1088v128q0 26 -19 45t-45 19h-128q-26 0 -45 -19
-t-19 -45v-128q0 -26 19 -45t45 -19h128q26 0 45 19t19 45zM1920 1248v-1344q0 -66 -47 -113t-113 -47h-1600q-66 0 -113 47t-47 113v1344q0 66 47 113t113 47h1600q66 0 113 -47t47 -113z" />
-    <glyph glyph-name="th_large" unicode="&#xf009;" horiz-adv-x="1664" 
-d="M768 512v-384q0 -52 -38 -90t-90 -38h-512q-52 0 -90 38t-38 90v384q0 52 38 90t90 38h512q52 0 90 -38t38 -90zM768 1280v-384q0 -52 -38 -90t-90 -38h-512q-52 0 -90 38t-38 90v384q0 52 38 90t90 38h512q52 0 90 -38t38 -90zM1664 512v-384q0 -52 -38 -90t-90 -38
-h-512q-52 0 -90 38t-38 90v384q0 52 38 90t90 38h512q52 0 90 -38t38 -90zM1664 1280v-384q0 -52 -38 -90t-90 -38h-512q-52 0 -90 38t-38 90v384q0 52 38 90t90 38h512q52 0 90 -38t38 -90z" />
-    <glyph glyph-name="th" unicode="&#xf00a;" horiz-adv-x="1792" 
-d="M512 288v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68zM512 800v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68zM1152 288v-192q0 -40 -28 -68t-68 -28h-320
-q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68zM512 1312v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68zM1152 800v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v192q0 40 28 68t68 28
-h320q40 0 68 -28t28 -68zM1792 288v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68zM1152 1312v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68zM1792 800v-192
-q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68zM1792 1312v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68z" />
-    <glyph glyph-name="th_list" unicode="&#xf00b;" horiz-adv-x="1792" 
-d="M512 288v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68zM512 800v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68zM1792 288v-192q0 -40 -28 -68t-68 -28h-960
-q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h960q40 0 68 -28t28 -68zM512 1312v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68zM1792 800v-192q0 -40 -28 -68t-68 -28h-960q-40 0 -68 28t-28 68v192q0 40 28 68t68 28
-h960q40 0 68 -28t28 -68zM1792 1312v-192q0 -40 -28 -68t-68 -28h-960q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h960q40 0 68 -28t28 -68z" />
-    <glyph glyph-name="ok" unicode="&#xf00c;" horiz-adv-x="1792" 
-d="M1671 970q0 -40 -28 -68l-724 -724l-136 -136q-28 -28 -68 -28t-68 28l-136 136l-362 362q-28 28 -28 68t28 68l136 136q28 28 68 28t68 -28l294 -295l656 657q28 28 68 28t68 -28l136 -136q28 -28 28 -68z" />
-    <glyph glyph-name="remove" unicode="&#xf00d;" horiz-adv-x="1408" 
-d="M1298 214q0 -40 -28 -68l-136 -136q-28 -28 -68 -28t-68 28l-294 294l-294 -294q-28 -28 -68 -28t-68 28l-136 136q-28 28 -28 68t28 68l294 294l-294 294q-28 28 -28 68t28 68l136 136q28 28 68 28t68 -28l294 -294l294 294q28 28 68 28t68 -28l136 -136q28 -28 28 -68
-t-28 -68l-294 -294l294 -294q28 -28 28 -68z" />
-    <glyph glyph-name="zoom_in" unicode="&#xf00e;" horiz-adv-x="1664" 
-d="M1024 736v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-224v-224q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v224h-224q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h224v224q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5v-224h224
-q13 0 22.5 -9.5t9.5 -22.5zM1152 704q0 185 -131.5 316.5t-316.5 131.5t-316.5 -131.5t-131.5 -316.5t131.5 -316.5t316.5 -131.5t316.5 131.5t131.5 316.5zM1664 -128q0 -53 -37.5 -90.5t-90.5 -37.5q-54 0 -90 38l-343 342q-179 -124 -399 -124q-143 0 -273.5 55.5
-t-225 150t-150 225t-55.5 273.5t55.5 273.5t150 225t225 150t273.5 55.5t273.5 -55.5t225 -150t150 -225t55.5 -273.5q0 -220 -124 -399l343 -343q37 -37 37 -90z" />
-    <glyph glyph-name="zoom_out" unicode="&#xf010;" horiz-adv-x="1664" 
-d="M1024 736v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-576q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h576q13 0 22.5 -9.5t9.5 -22.5zM1152 704q0 185 -131.5 316.5t-316.5 131.5t-316.5 -131.5t-131.5 -316.5t131.5 -316.5t316.5 -131.5t316.5 131.5t131.5 316.5z
-M1664 -128q0 -53 -37.5 -90.5t-90.5 -37.5q-54 0 -90 38l-343 342q-179 -124 -399 -124q-143 0 -273.5 55.5t-225 150t-150 225t-55.5 273.5t55.5 273.5t150 225t225 150t273.5 55.5t273.5 -55.5t225 -150t150 -225t55.5 -273.5q0 -220 -124 -399l343 -343q37 -37 37 -90z
-" />
-    <glyph glyph-name="off" unicode="&#xf011;" 
-d="M1536 640q0 -156 -61 -298t-164 -245t-245 -164t-298 -61t-298 61t-245 164t-164 245t-61 298q0 182 80.5 343t226.5 270q43 32 95.5 25t83.5 -50q32 -42 24.5 -94.5t-49.5 -84.5q-98 -74 -151.5 -181t-53.5 -228q0 -104 40.5 -198.5t109.5 -163.5t163.5 -109.5
-t198.5 -40.5t198.5 40.5t163.5 109.5t109.5 163.5t40.5 198.5q0 121 -53.5 228t-151.5 181q-42 32 -49.5 84.5t24.5 94.5q31 43 84 50t95 -25q146 -109 226.5 -270t80.5 -343zM896 1408v-640q0 -52 -38 -90t-90 -38t-90 38t-38 90v640q0 52 38 90t90 38t90 -38t38 -90z" />
-    <glyph glyph-name="signal" unicode="&#xf012;" horiz-adv-x="1792" 
-d="M256 96v-192q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h192q14 0 23 -9t9 -23zM640 224v-320q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v320q0 14 9 23t23 9h192q14 0 23 -9t9 -23zM1024 480v-576q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23
-v576q0 14 9 23t23 9h192q14 0 23 -9t9 -23zM1408 864v-960q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v960q0 14 9 23t23 9h192q14 0 23 -9t9 -23zM1792 1376v-1472q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v1472q0 14 9 23t23 9h192q14 0 23 -9t9 -23z" />
-    <glyph glyph-name="cog" unicode="&#xf013;" 
-d="M1024 640q0 106 -75 181t-181 75t-181 -75t-75 -181t75 -181t181 -75t181 75t75 181zM1536 749v-222q0 -12 -8 -23t-20 -13l-185 -28q-19 -54 -39 -91q35 -50 107 -138q10 -12 10 -25t-9 -23q-27 -37 -99 -108t-94 -71q-12 0 -26 9l-138 108q-44 -23 -91 -38
-q-16 -136 -29 -186q-7 -28 -36 -28h-222q-14 0 -24.5 8.5t-11.5 21.5l-28 184q-49 16 -90 37l-141 -107q-10 -9 -25 -9q-14 0 -25 11q-126 114 -165 168q-7 10 -7 23q0 12 8 23q15 21 51 66.5t54 70.5q-27 50 -41 99l-183 27q-13 2 -21 12.5t-8 23.5v222q0 12 8 23t19 13
-l186 28q14 46 39 92q-40 57 -107 138q-10 12 -10 24q0 10 9 23q26 36 98.5 107.5t94.5 71.5q13 0 26 -10l138 -107q44 23 91 38q16 136 29 186q7 28 36 28h222q14 0 24.5 -8.5t11.5 -21.5l28 -184q49 -16 90 -37l142 107q9 9 24 9q13 0 25 -10q129 -119 165 -170q7 -8 7 -22
-q0 -12 -8 -23q-15 -21 -51 -66.5t-54 -70.5q26 -50 41 -98l183 -28q13 -2 21 -12.5t8 -23.5z" />
-    <glyph glyph-name="trash" unicode="&#xf014;" horiz-adv-x="1408" 
-d="M512 800v-576q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v576q0 14 9 23t23 9h64q14 0 23 -9t9 -23zM768 800v-576q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v576q0 14 9 23t23 9h64q14 0 23 -9t9 -23zM1024 800v-576q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v576
-q0 14 9 23t23 9h64q14 0 23 -9t9 -23zM1152 76v948h-896v-948q0 -22 7 -40.5t14.5 -27t10.5 -8.5h832q3 0 10.5 8.5t14.5 27t7 40.5zM480 1152h448l-48 117q-7 9 -17 11h-317q-10 -2 -17 -11zM1408 1120v-64q0 -14 -9 -23t-23 -9h-96v-948q0 -83 -47 -143.5t-113 -60.5h-832
-q-66 0 -113 58.5t-47 141.5v952h-96q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h309l70 167q15 37 54 63t79 26h320q40 0 79 -26t54 -63l70 -167h309q14 0 23 -9t9 -23z" />
-    <glyph glyph-name="home" unicode="&#xf015;" horiz-adv-x="1664" 
-d="M1408 544v-480q0 -26 -19 -45t-45 -19h-384v384h-256v-384h-384q-26 0 -45 19t-19 45v480q0 1 0.5 3t0.5 3l575 474l575 -474q1 -2 1 -6zM1631 613l-62 -74q-8 -9 -21 -11h-3q-13 0 -21 7l-692 577l-692 -577q-12 -8 -24 -7q-13 2 -21 11l-62 74q-8 10 -7 23.5t11 21.5
-l719 599q32 26 76 26t76 -26l244 -204v195q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-408l219 -182q10 -8 11 -21.5t-7 -23.5z" />
-    <glyph glyph-name="file_alt" unicode="&#xf016;" 
-d="M1468 1156q28 -28 48 -76t20 -88v-1152q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68v1600q0 40 28 68t68 28h896q40 0 88 -20t76 -48zM1024 1400v-376h376q-10 29 -22 41l-313 313q-12 12 -41 22zM1408 -128v1024h-416q-40 0 -68 28t-28 68v416h-768v-1536h1280z
-" />
-    <glyph glyph-name="time" unicode="&#xf017;" 
-d="M896 992v-448q0 -14 -9 -23t-23 -9h-320q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h224v352q0 14 9 23t23 9h64q14 0 23 -9t9 -23zM1312 640q0 148 -73 273t-198 198t-273 73t-273 -73t-198 -198t-73 -273t73 -273t198 -198t273 -73t273 73t198 198t73 273zM1536 640
-q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
-    <glyph glyph-name="road" unicode="&#xf018;" horiz-adv-x="1920" 
-d="M1111 540v4l-24 320q-1 13 -11 22.5t-23 9.5h-186q-13 0 -23 -9.5t-11 -22.5l-24 -320v-4q-1 -12 8 -20t21 -8h244q12 0 21 8t8 20zM1870 73q0 -73 -46 -73h-704q13 0 22 9.5t8 22.5l-20 256q-1 13 -11 22.5t-23 9.5h-272q-13 0 -23 -9.5t-11 -22.5l-20 -256
-q-1 -13 8 -22.5t22 -9.5h-704q-46 0 -46 73q0 54 26 116l417 1044q8 19 26 33t38 14h339q-13 0 -23 -9.5t-11 -22.5l-15 -192q-1 -14 8 -23t22 -9h166q13 0 22 9t8 23l-15 192q-1 13 -11 22.5t-23 9.5h339q20 0 38 -14t26 -33l417 -1044q26 -62 26 -116z" />
-    <glyph glyph-name="download_alt" unicode="&#xf019;" horiz-adv-x="1664" 
-d="M1280 192q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1536 192q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1664 416v-320q0 -40 -28 -68t-68 -28h-1472q-40 0 -68 28t-28 68v320q0 40 28 68t68 28h465l135 -136
-q58 -56 136 -56t136 56l136 136h464q40 0 68 -28t28 -68zM1339 985q17 -41 -14 -70l-448 -448q-18 -19 -45 -19t-45 19l-448 448q-31 29 -14 70q17 39 59 39h256v448q0 26 19 45t45 19h256q26 0 45 -19t19 -45v-448h256q42 0 59 -39z" />
-    <glyph glyph-name="download" unicode="&#xf01a;" 
-d="M1120 608q0 -12 -10 -24l-319 -319q-11 -9 -23 -9t-23 9l-320 320q-15 16 -7 35q8 20 30 20h192v352q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-352h192q14 0 23 -9t9 -23zM768 1184q-148 0 -273 -73t-198 -198t-73 -273t73 -273t198 -198t273 -73t273 73t198 198t73 273
-t-73 273t-198 198t-273 73zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
-    <glyph glyph-name="upload" unicode="&#xf01b;" 
-d="M1118 660q-8 -20 -30 -20h-192v-352q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v352h-192q-14 0 -23 9t-9 23q0 12 10 24l319 319q11 9 23 9t23 -9l320 -320q15 -16 7 -35zM768 1184q-148 0 -273 -73t-198 -198t-73 -273t73 -273t198 -198t273 -73t273 73t198 198
-t73 273t-73 273t-198 198t-273 73zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
-    <glyph glyph-name="inbox" unicode="&#xf01c;" 
-d="M1023 576h316q-1 3 -2.5 8.5t-2.5 7.5l-212 496h-708l-212 -496q-1 -3 -2.5 -8.5t-2.5 -7.5h316l95 -192h320zM1536 546v-482q0 -26 -19 -45t-45 -19h-1408q-26 0 -45 19t-19 45v482q0 62 25 123l238 552q10 25 36.5 42t52.5 17h832q26 0 52.5 -17t36.5 -42l238 -552
-q25 -61 25 -123z" />
-    <glyph glyph-name="play_circle" unicode="&#xf01d;" 
-d="M1184 640q0 -37 -32 -55l-544 -320q-15 -9 -32 -9q-16 0 -32 8q-32 19 -32 56v640q0 37 32 56q33 18 64 -1l544 -320q32 -18 32 -55zM1312 640q0 148 -73 273t-198 198t-273 73t-273 -73t-198 -198t-73 -273t73 -273t198 -198t273 -73t273 73t198 198t73 273zM1536 640
-q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
-    <glyph glyph-name="repeat" unicode="&#xf01e;" 
-d="M1536 1280v-448q0 -26 -19 -45t-45 -19h-448q-42 0 -59 40q-17 39 14 69l138 138q-148 137 -349 137q-104 0 -198.5 -40.5t-163.5 -109.5t-109.5 -163.5t-40.5 -198.5t40.5 -198.5t109.5 -163.5t163.5 -109.5t198.5 -40.5q119 0 225 52t179 147q7 10 23 12q15 0 25 -9
-l137 -138q9 -8 9.5 -20.5t-7.5 -22.5q-109 -132 -264 -204.5t-327 -72.5q-156 0 -298 61t-245 164t-164 245t-61 298t61 298t164 245t245 164t298 61q147 0 284.5 -55.5t244.5 -156.5l130 129q29 31 70 14q39 -17 39 -59z" />
-    <glyph glyph-name="refresh" unicode="&#xf021;" 
-d="M1511 480q0 -5 -1 -7q-64 -268 -268 -434.5t-478 -166.5q-146 0 -282.5 55t-243.5 157l-129 -129q-19 -19 -45 -19t-45 19t-19 45v448q0 26 19 45t45 19h448q26 0 45 -19t19 -45t-19 -45l-137 -137q71 -66 161 -102t187 -36q134 0 250 65t186 179q11 17 53 117
-q8 23 30 23h192q13 0 22.5 -9.5t9.5 -22.5zM1536 1280v-448q0 -26 -19 -45t-45 -19h-448q-26 0 -45 19t-19 45t19 45l138 138q-148 137 -349 137q-134 0 -250 -65t-186 -179q-11 -17 -53 -117q-8 -23 -30 -23h-199q-13 0 -22.5 9.5t-9.5 22.5v7q65 268 270 434.5t480 166.5
-q146 0 284 -55.5t245 -156.5l130 129q19 19 45 19t45 -19t19 -45z" />
-    <glyph glyph-name="list_alt" unicode="&#xf022;" horiz-adv-x="1792" 
-d="M384 352v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM384 608v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z
-M384 864v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM1536 352v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-960q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h960q13 0 22.5 -9.5t9.5 -22.5z
-M1536 608v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-960q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h960q13 0 22.5 -9.5t9.5 -22.5zM1536 864v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-960q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h960q13 0 22.5 -9.5
-t9.5 -22.5zM1664 160v832q0 13 -9.5 22.5t-22.5 9.5h-1472q-13 0 -22.5 -9.5t-9.5 -22.5v-832q0 -13 9.5 -22.5t22.5 -9.5h1472q13 0 22.5 9.5t9.5 22.5zM1792 1248v-1088q0 -66 -47 -113t-113 -47h-1472q-66 0 -113 47t-47 113v1088q0 66 47 113t113 47h1472q66 0 113 -47
-t47 -113z" />
-    <glyph glyph-name="lock" unicode="&#xf023;" horiz-adv-x="1152" 
-d="M320 768h512v192q0 106 -75 181t-181 75t-181 -75t-75 -181v-192zM1152 672v-576q0 -40 -28 -68t-68 -28h-960q-40 0 -68 28t-28 68v576q0 40 28 68t68 28h32v192q0 184 132 316t316 132t316 -132t132 -316v-192h32q40 0 68 -28t28 -68z" />
-    <glyph glyph-name="flag" unicode="&#xf024;" horiz-adv-x="1792" 
-d="M320 1280q0 -72 -64 -110v-1266q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v1266q-64 38 -64 110q0 53 37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1792 1216v-763q0 -25 -12.5 -38.5t-39.5 -27.5q-215 -116 -369 -116q-61 0 -123.5 22t-108.5 48
-t-115.5 48t-142.5 22q-192 0 -464 -146q-17 -9 -33 -9q-26 0 -45 19t-19 45v742q0 32 31 55q21 14 79 43q236 120 421 120q107 0 200 -29t219 -88q38 -19 88 -19q54 0 117.5 21t110 47t88 47t54.5 21q26 0 45 -19t19 -45z" />
-    <glyph glyph-name="headphones" unicode="&#xf025;" horiz-adv-x="1664" 
-d="M1664 650q0 -166 -60 -314l-20 -49l-185 -33q-22 -83 -90.5 -136.5t-156.5 -53.5v-32q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v576q0 14 9 23t23 9h64q14 0 23 -9t9 -23v-32q71 0 130 -35.5t93 -95.5l68 12q29 95 29 193q0 148 -88 279t-236.5 209t-315.5 78
-t-315.5 -78t-236.5 -209t-88 -279q0 -98 29 -193l68 -12q34 60 93 95.5t130 35.5v32q0 14 9 23t23 9h64q14 0 23 -9t9 -23v-576q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v32q-88 0 -156.5 53.5t-90.5 136.5l-185 33l-20 49q-60 148 -60 314q0 151 67 291t179 242.5
-t266 163.5t320 61t320 -61t266 -163.5t179 -242.5t67 -291z" />
-    <glyph glyph-name="volume_off" unicode="&#xf026;" horiz-adv-x="768" 
-d="M768 1184v-1088q0 -26 -19 -45t-45 -19t-45 19l-333 333h-262q-26 0 -45 19t-19 45v384q0 26 19 45t45 19h262l333 333q19 19 45 19t45 -19t19 -45z" />
-    <glyph glyph-name="volume_down" unicode="&#xf027;" horiz-adv-x="1152" 
-d="M768 1184v-1088q0 -26 -19 -45t-45 -19t-45 19l-333 333h-262q-26 0 -45 19t-19 45v384q0 26 19 45t45 19h262l333 333q19 19 45 19t45 -19t19 -45zM1152 640q0 -76 -42.5 -141.5t-112.5 -93.5q-10 -5 -25 -5q-26 0 -45 18.5t-19 45.5q0 21 12 35.5t29 25t34 23t29 36
-t12 56.5t-12 56.5t-29 36t-34 23t-29 25t-12 35.5q0 27 19 45.5t45 18.5q15 0 25 -5q70 -27 112.5 -93t42.5 -142z" />
-    <glyph glyph-name="volume_up" unicode="&#xf028;" horiz-adv-x="1664" 
-d="M768 1184v-1088q0 -26 -19 -45t-45 -19t-45 19l-333 333h-262q-26 0 -45 19t-19 45v384q0 26 19 45t45 19h262l333 333q19 19 45 19t45 -19t19 -45zM1152 640q0 -76 -42.5 -141.5t-112.5 -93.5q-10 -5 -25 -5q-26 0 -45 18.5t-19 45.5q0 21 12 35.5t29 25t34 23t29 36
-t12 56.5t-12 56.5t-29 36t-34 23t-29 25t-12 35.5q0 27 19 45.5t45 18.5q15 0 25 -5q70 -27 112.5 -93t42.5 -142zM1408 640q0 -153 -85 -282.5t-225 -188.5q-13 -5 -25 -5q-27 0 -46 19t-19 45q0 39 39 59q56 29 76 44q74 54 115.5 135.5t41.5 173.5t-41.5 173.5
-t-115.5 135.5q-20 15 -76 44q-39 20 -39 59q0 26 19 45t45 19q13 0 26 -5q140 -59 225 -188.5t85 -282.5zM1664 640q0 -230 -127 -422.5t-338 -283.5q-13 -5 -26 -5q-26 0 -45 19t-19 45q0 36 39 59q7 4 22.5 10.5t22.5 10.5q46 25 82 51q123 91 192 227t69 289t-69 289
-t-192 227q-36 26 -82 51q-7 4 -22.5 10.5t-22.5 10.5q-39 23 -39 59q0 26 19 45t45 19q13 0 26 -5q211 -91 338 -283.5t127 -422.5z" />
-    <glyph glyph-name="qrcode" unicode="&#xf029;" horiz-adv-x="1408" 
-d="M384 384v-128h-128v128h128zM384 1152v-128h-128v128h128zM1152 1152v-128h-128v128h128zM128 129h384v383h-384v-383zM128 896h384v384h-384v-384zM896 896h384v384h-384v-384zM640 640v-640h-640v640h640zM1152 128v-128h-128v128h128zM1408 128v-128h-128v128h128z
-M1408 640v-384h-384v128h-128v-384h-128v640h384v-128h128v128h128zM640 1408v-640h-640v640h640zM1408 1408v-640h-640v640h640z" />
-    <glyph glyph-name="barcode" unicode="&#xf02a;" horiz-adv-x="1792" 
-d="M63 0h-63v1408h63v-1408zM126 1h-32v1407h32v-1407zM220 1h-31v1407h31v-1407zM377 1h-31v1407h31v-1407zM534 1h-62v1407h62v-1407zM660 1h-31v1407h31v-1407zM723 1h-31v1407h31v-1407zM786 1h-31v1407h31v-1407zM943 1h-63v1407h63v-1407zM1100 1h-63v1407h63v-1407z
-M1226 1h-63v1407h63v-1407zM1352 1h-63v1407h63v-1407zM1446 1h-63v1407h63v-1407zM1635 1h-94v1407h94v-1407zM1698 1h-32v1407h32v-1407zM1792 0h-63v1408h63v-1408z" />
-    <glyph glyph-name="tag" unicode="&#xf02b;" 
-d="M448 1088q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1515 512q0 -53 -37 -90l-491 -492q-39 -37 -91 -37q-53 0 -90 37l-715 716q-38 37 -64.5 101t-26.5 117v416q0 52 38 90t90 38h416q53 0 117 -26.5t102 -64.5
-l715 -714q37 -39 37 -91z" />
-    <glyph glyph-name="tags" unicode="&#xf02c;" horiz-adv-x="1920" 
-d="M448 1088q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1515 512q0 -53 -37 -90l-491 -492q-39 -37 -91 -37q-53 0 -90 37l-715 716q-38 37 -64.5 101t-26.5 117v416q0 52 38 90t90 38h416q53 0 117 -26.5t102 -64.5
-l715 -714q37 -39 37 -91zM1899 512q0 -53 -37 -90l-491 -492q-39 -37 -91 -37q-36 0 -59 14t-53 45l470 470q37 37 37 90q0 52 -37 91l-715 714q-38 38 -102 64.5t-117 26.5h224q53 0 117 -26.5t102 -64.5l715 -714q37 -39 37 -91z" />
-    <glyph glyph-name="book" unicode="&#xf02d;" horiz-adv-x="1664" 
-d="M1639 1058q40 -57 18 -129l-275 -906q-19 -64 -76.5 -107.5t-122.5 -43.5h-923q-77 0 -148.5 53.5t-99.5 131.5q-24 67 -2 127q0 4 3 27t4 37q1 8 -3 21.5t-3 19.5q2 11 8 21t16.5 23.5t16.5 23.5q23 38 45 91.5t30 91.5q3 10 0.5 30t-0.5 28q3 11 17 28t17 23
-q21 36 42 92t25 90q1 9 -2.5 32t0.5 28q4 13 22 30.5t22 22.5q19 26 42.5 84.5t27.5 96.5q1 8 -3 25.5t-2 26.5q2 8 9 18t18 23t17 21q8 12 16.5 30.5t15 35t16 36t19.5 32t26.5 23.5t36 11.5t47.5 -5.5l-1 -3q38 9 51 9h761q74 0 114 -56t18 -130l-274 -906
-q-36 -119 -71.5 -153.5t-128.5 -34.5h-869q-27 0 -38 -15q-11 -16 -1 -43q24 -70 144 -70h923q29 0 56 15.5t35 41.5l300 987q7 22 5 57q38 -15 59 -43zM575 1056q-4 -13 2 -22.5t20 -9.5h608q13 0 25.5 9.5t16.5 22.5l21 64q4 13 -2 22.5t-20 9.5h-608q-13 0 -25.5 -9.5
-t-16.5 -22.5zM492 800q-4 -13 2 -22.5t20 -9.5h608q13 0 25.5 9.5t16.5 22.5l21 64q4 13 -2 22.5t-20 9.5h-608q-13 0 -25.5 -9.5t-16.5 -22.5z" />
-    <glyph glyph-name="bookmark" unicode="&#xf02e;" horiz-adv-x="1280" 
-d="M1164 1408q23 0 44 -9q33 -13 52.5 -41t19.5 -62v-1289q0 -34 -19.5 -62t-52.5 -41q-19 -8 -44 -8q-48 0 -83 32l-441 424l-441 -424q-36 -33 -83 -33q-23 0 -44 9q-33 13 -52.5 41t-19.5 62v1289q0 34 19.5 62t52.5 41q21 9 44 9h1048z" />
-    <glyph glyph-name="print" unicode="&#xf02f;" horiz-adv-x="1664" 
-d="M384 0h896v256h-896v-256zM384 640h896v384h-160q-40 0 -68 28t-28 68v160h-640v-640zM1536 576q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1664 576v-416q0 -13 -9.5 -22.5t-22.5 -9.5h-224v-160q0 -40 -28 -68t-68 -28h-960q-40 0 -68 28t-28 68
-v160h-224q-13 0 -22.5 9.5t-9.5 22.5v416q0 79 56.5 135.5t135.5 56.5h64v544q0 40 28 68t68 28h672q40 0 88 -20t76 -48l152 -152q28 -28 48 -76t20 -88v-256h64q79 0 135.5 -56.5t56.5 -135.5z" />
-    <glyph glyph-name="camera" unicode="&#xf030;" horiz-adv-x="1920" 
-d="M960 864q119 0 203.5 -84.5t84.5 -203.5t-84.5 -203.5t-203.5 -84.5t-203.5 84.5t-84.5 203.5t84.5 203.5t203.5 84.5zM1664 1280q106 0 181 -75t75 -181v-896q0 -106 -75 -181t-181 -75h-1408q-106 0 -181 75t-75 181v896q0 106 75 181t181 75h224l51 136
-q19 49 69.5 84.5t103.5 35.5h512q53 0 103.5 -35.5t69.5 -84.5l51 -136h224zM960 128q185 0 316.5 131.5t131.5 316.5t-131.5 316.5t-316.5 131.5t-316.5 -131.5t-131.5 -316.5t131.5 -316.5t316.5 -131.5z" />
-    <glyph glyph-name="font" unicode="&#xf031;" horiz-adv-x="1664" 
-d="M725 977l-170 -450q33 0 136.5 -2t160.5 -2q19 0 57 2q-87 253 -184 452zM0 -128l2 79q23 7 56 12.5t57 10.5t49.5 14.5t44.5 29t31 50.5l237 616l280 724h75h53q8 -14 11 -21l205 -480q33 -78 106 -257.5t114 -274.5q15 -34 58 -144.5t72 -168.5q20 -45 35 -57
-q19 -15 88 -29.5t84 -20.5q6 -38 6 -57q0 -5 -0.5 -13.5t-0.5 -12.5q-63 0 -190 8t-191 8q-76 0 -215 -7t-178 -8q0 43 4 78l131 28q1 0 12.5 2.5t15.5 3.5t14.5 4.5t15 6.5t11 8t9 11t2.5 14q0 16 -31 96.5t-72 177.5t-42 100l-450 2q-26 -58 -76.5 -195.5t-50.5 -162.5
-q0 -22 14 -37.5t43.5 -24.5t48.5 -13.5t57 -8.5t41 -4q1 -19 1 -58q0 -9 -2 -27q-58 0 -174.5 10t-174.5 10q-8 0 -26.5 -4t-21.5 -4q-80 -14 -188 -14z" />
-    <glyph glyph-name="bold" unicode="&#xf032;" horiz-adv-x="1408" 
-d="M555 15q74 -32 140 -32q376 0 376 335q0 114 -41 180q-27 44 -61.5 74t-67.5 46.5t-80.5 25t-84 10.5t-94.5 2q-73 0 -101 -10q0 -53 -0.5 -159t-0.5 -158q0 -8 -1 -67.5t-0.5 -96.5t4.5 -83.5t12 -66.5zM541 761q42 -7 109 -7q82 0 143 13t110 44.5t74.5 89.5t25.5 142
-q0 70 -29 122.5t-79 82t-108 43.5t-124 14q-50 0 -130 -13q0 -50 4 -151t4 -152q0 -27 -0.5 -80t-0.5 -79q0 -46 1 -69zM0 -128l2 94q15 4 85 16t106 27q7 12 12.5 27t8.5 33.5t5.5 32.5t3 37.5t0.5 34v35.5v30q0 982 -22 1025q-4 8 -22 14.5t-44.5 11t-49.5 7t-48.5 4.5
-t-30.5 3l-4 83q98 2 340 11.5t373 9.5q23 0 68 -0.5t68 -0.5q70 0 136.5 -13t128.5 -42t108 -71t74 -104.5t28 -137.5q0 -52 -16.5 -95.5t-39 -72t-64.5 -57.5t-73 -45t-84 -40q154 -35 256.5 -134t102.5 -248q0 -100 -35 -179.5t-93.5 -130.5t-138 -85.5t-163.5 -48.5
-t-176 -14q-44 0 -132 3t-132 3q-106 0 -307 -11t-231 -12z" />
-    <glyph glyph-name="italic" unicode="&#xf033;" horiz-adv-x="1024" 
-d="M0 -126l17 85q22 7 61.5 16.5t72 19t59.5 23.5q28 35 41 101q1 7 62 289t114 543.5t52 296.5v25q-24 13 -54.5 18.5t-69.5 8t-58 5.5l19 103q33 -2 120 -6.5t149.5 -7t120.5 -2.5q48 0 98.5 2.5t121 7t98.5 6.5q-5 -39 -19 -89q-30 -10 -101.5 -28.5t-108.5 -33.5
-q-8 -19 -14 -42.5t-9 -40t-7.5 -45.5t-6.5 -42q-27 -148 -87.5 -419.5t-77.5 -355.5q-2 -9 -13 -58t-20 -90t-16 -83.5t-6 -57.5l1 -18q17 -4 185 -31q-3 -44 -16 -99q-11 0 -32.5 -1.5t-32.5 -1.5q-29 0 -87 10t-86 10q-138 2 -206 2q-51 0 -143 -9t-121 -11z" />
-    <glyph glyph-name="text_height" unicode="&#xf034;" horiz-adv-x="1792" 
-d="M1744 128q33 0 42 -18.5t-11 -44.5l-126 -162q-20 -26 -49 -26t-49 26l-126 162q-20 26 -11 44.5t42 18.5h80v1024h-80q-33 0 -42 18.5t11 44.5l126 162q20 26 49 26t49 -26l126 -162q20 -26 11 -44.5t-42 -18.5h-80v-1024h80zM81 1407l54 -27q12 -5 211 -5q44 0 132 2
-t132 2q36 0 107.5 -0.5t107.5 -0.5h293q6 0 21 -0.5t20.5 0t16 3t17.5 9t15 17.5l42 1q4 0 14 -0.5t14 -0.5q2 -112 2 -336q0 -80 -5 -109q-39 -14 -68 -18q-25 44 -54 128q-3 9 -11 48t-14.5 73.5t-7.5 35.5q-6 8 -12 12.5t-15.5 6t-13 2.5t-18 0.5t-16.5 -0.5
-q-17 0 -66.5 0.5t-74.5 0.5t-64 -2t-71 -6q-9 -81 -8 -136q0 -94 2 -388t2 -455q0 -16 -2.5 -71.5t0 -91.5t12.5 -69q40 -21 124 -42.5t120 -37.5q5 -40 5 -50q0 -14 -3 -29l-34 -1q-76 -2 -218 8t-207 10q-50 0 -151 -9t-152 -9q-3 51 -3 52v9q17 27 61.5 43t98.5 29t78 27
-q19 42 19 383q0 101 -3 303t-3 303v117q0 2 0.5 15.5t0.5 25t-1 25.5t-3 24t-5 14q-11 12 -162 12q-33 0 -93 -12t-80 -26q-19 -13 -34 -72.5t-31.5 -111t-42.5 -53.5q-42 26 -56 44v383z" />
-    <glyph glyph-name="text_width" unicode="&#xf035;" 
-d="M81 1407l54 -27q12 -5 211 -5q44 0 132 2t132 2q70 0 246.5 1t304.5 0.5t247 -4.5q33 -1 56 31l42 1q4 0 14 -0.5t14 -0.5q2 -112 2 -336q0 -80 -5 -109q-39 -14 -68 -18q-25 44 -54 128q-3 9 -11 47.5t-15 73.5t-7 36q-10 13 -27 19q-5 2 -66 2q-30 0 -93 1t-103 1
-t-94 -2t-96 -7q-9 -81 -8 -136l1 -152v52q0 -55 1 -154t1.5 -180t0.5 -153q0 -16 -2.5 -71.5t0 -91.5t12.5 -69q40 -21 124 -42.5t120 -37.5q5 -40 5 -50q0 -14 -3 -29l-34 -1q-76 -2 -218 8t-207 10q-50 0 -151 -9t-152 -9q-3 51 -3 52v9q17 27 61.5 43t98.5 29t78 27
-q7 16 11.5 74t6 145.5t1.5 155t-0.5 153.5t-0.5 89q0 7 -2.5 21.5t-2.5 22.5q0 7 0.5 44t1 73t0 76.5t-3 67.5t-6.5 32q-11 12 -162 12q-41 0 -163 -13.5t-138 -24.5q-19 -12 -34 -71.5t-31.5 -111.5t-42.5 -54q-42 26 -56 44v383zM1310 125q12 0 42 -19.5t57.5 -41.5
-t59.5 -49t36 -30q26 -21 26 -49t-26 -49q-4 -3 -36 -30t-59.5 -49t-57.5 -41.5t-42 -19.5q-13 0 -20.5 10.5t-10 28.5t-2.5 33.5t1.5 33t1.5 19.5h-1024q0 -2 1.5 -19.5t1.5 -33t-2.5 -33.5t-10 -28.5t-20.5 -10.5q-12 0 -42 19.5t-57.5 41.5t-59.5 49t-36 30q-26 21 -26 49
-t26 49q4 3 36 30t59.5 49t57.5 41.5t42 19.5q13 0 20.5 -10.5t10 -28.5t2.5 -33.5t-1.5 -33t-1.5 -19.5h1024q0 2 -1.5 19.5t-1.5 33t2.5 33.5t10 28.5t20.5 10.5z" />
-    <glyph glyph-name="align_left" unicode="&#xf036;" horiz-adv-x="1792" 
-d="M1792 192v-128q0 -26 -19 -45t-45 -19h-1664q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1664q26 0 45 -19t19 -45zM1408 576v-128q0 -26 -19 -45t-45 -19h-1280q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1280q26 0 45 -19t19 -45zM1664 960v-128q0 -26 -19 -45
-t-45 -19h-1536q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1536q26 0 45 -19t19 -45zM1280 1344v-128q0 -26 -19 -45t-45 -19h-1152q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1152q26 0 45 -19t19 -45z" />
-    <glyph glyph-name="align_center" unicode="&#xf037;" horiz-adv-x="1792" 
-d="M1792 192v-128q0 -26 -19 -45t-45 -19h-1664q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1664q26 0 45 -19t19 -45zM1408 576v-128q0 -26 -19 -45t-45 -19h-896q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h896q26 0 45 -19t19 -45zM1664 960v-128q0 -26 -19 -45t-45 -19
-h-1408q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1408q26 0 45 -19t19 -45zM1280 1344v-128q0 -26 -19 -45t-45 -19h-640q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h640q26 0 45 -19t19 -45z" />
-    <glyph glyph-name="align_right" unicode="&#xf038;" horiz-adv-x="1792" 
-d="M1792 192v-128q0 -26 -19 -45t-45 -19h-1664q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1664q26 0 45 -19t19 -45zM1792 576v-128q0 -26 -19 -45t-45 -19h-1280q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1280q26 0 45 -19t19 -45zM1792 960v-128q0 -26 -19 -45
-t-45 -19h-1536q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1536q26 0 45 -19t19 -45zM1792 1344v-128q0 -26 -19 -45t-45 -19h-1152q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1152q26 0 45 -19t19 -45z" />
-    <glyph glyph-name="align_justify" unicode="&#xf039;" horiz-adv-x="1792" 
-d="M1792 192v-128q0 -26 -19 -45t-45 -19h-1664q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1664q26 0 45 -19t19 -45zM1792 576v-128q0 -26 -19 -45t-45 -19h-1664q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1664q26 0 45 -19t19 -45zM1792 960v-128q0 -26 -19 -45
-t-45 -19h-1664q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1664q26 0 45 -19t19 -45zM1792 1344v-128q0 -26 -19 -45t-45 -19h-1664q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1664q26 0 45 -19t19 -45z" />
-    <glyph glyph-name="list" unicode="&#xf03a;" horiz-adv-x="1792" 
-d="M256 224v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-192q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h192q13 0 22.5 -9.5t9.5 -22.5zM256 608v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-192q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h192q13 0 22.5 -9.5
-t9.5 -22.5zM256 992v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-192q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h192q13 0 22.5 -9.5t9.5 -22.5zM1792 224v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1344q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1344
-q13 0 22.5 -9.5t9.5 -22.5zM256 1376v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-192q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h192q13 0 22.5 -9.5t9.5 -22.5zM1792 608v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1344q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5
-t22.5 9.5h1344q13 0 22.5 -9.5t9.5 -22.5zM1792 992v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1344q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1344q13 0 22.5 -9.5t9.5 -22.5zM1792 1376v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1344q-13 0 -22.5 9.5t-9.5 22.5v192
-q0 13 9.5 22.5t22.5 9.5h1344q13 0 22.5 -9.5t9.5 -22.5z" />
-    <glyph glyph-name="indent_left" unicode="&#xf03b;" horiz-adv-x="1792" 
-d="M384 992v-576q0 -13 -9.5 -22.5t-22.5 -9.5q-14 0 -23 9l-288 288q-9 9 -9 23t9 23l288 288q9 9 23 9q13 0 22.5 -9.5t9.5 -22.5zM1792 224v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1728q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1728q13 0 22.5 -9.5
-t9.5 -22.5zM1792 608v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1088q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1088q13 0 22.5 -9.5t9.5 -22.5zM1792 992v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1088q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1088
-q13 0 22.5 -9.5t9.5 -22.5zM1792 1376v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1728q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1728q13 0 22.5 -9.5t9.5 -22.5z" />
-    <glyph glyph-name="indent_right" unicode="&#xf03c;" horiz-adv-x="1792" 
-d="M352 704q0 -14 -9 -23l-288 -288q-9 -9 -23 -9q-13 0 -22.5 9.5t-9.5 22.5v576q0 13 9.5 22.5t22.5 9.5q14 0 23 -9l288 -288q9 -9 9 -23zM1792 224v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1728q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1728q13 0 22.5 -9.5
-t9.5 -22.5zM1792 608v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1088q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1088q13 0 22.5 -9.5t9.5 -22.5zM1792 992v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1088q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1088
-q13 0 22.5 -9.5t9.5 -22.5zM1792 1376v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1728q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1728q13 0 22.5 -9.5t9.5 -22.5z" />
-    <glyph glyph-name="facetime_video" unicode="&#xf03d;" horiz-adv-x="1792" 
-d="M1792 1184v-1088q0 -42 -39 -59q-13 -5 -25 -5q-27 0 -45 19l-403 403v-166q0 -119 -84.5 -203.5t-203.5 -84.5h-704q-119 0 -203.5 84.5t-84.5 203.5v704q0 119 84.5 203.5t203.5 84.5h704q119 0 203.5 -84.5t84.5 -203.5v-165l403 402q18 19 45 19q12 0 25 -5
-q39 -17 39 -59z" />
-    <glyph glyph-name="picture" unicode="&#xf03e;" horiz-adv-x="1920" 
-d="M640 960q0 -80 -56 -136t-136 -56t-136 56t-56 136t56 136t136 56t136 -56t56 -136zM1664 576v-448h-1408v192l320 320l160 -160l512 512zM1760 1280h-1600q-13 0 -22.5 -9.5t-9.5 -22.5v-1216q0 -13 9.5 -22.5t22.5 -9.5h1600q13 0 22.5 9.5t9.5 22.5v1216
-q0 13 -9.5 22.5t-22.5 9.5zM1920 1248v-1216q0 -66 -47 -113t-113 -47h-1600q-66 0 -113 47t-47 113v1216q0 66 47 113t113 47h1600q66 0 113 -47t47 -113z" />
-    <glyph glyph-name="pencil" unicode="&#xf040;" 
-d="M363 0l91 91l-235 235l-91 -91v-107h128v-128h107zM886 928q0 22 -22 22q-10 0 -17 -7l-542 -542q-7 -7 -7 -17q0 -22 22 -22q10 0 17 7l542 542q7 7 7 17zM832 1120l416 -416l-832 -832h-416v416zM1515 1024q0 -53 -37 -90l-166 -166l-416 416l166 165q36 38 90 38
-q53 0 91 -38l235 -234q37 -39 37 -91z" />
-    <glyph glyph-name="map_marker" unicode="&#xf041;" horiz-adv-x="1024" 
-d="M768 896q0 106 -75 181t-181 75t-181 -75t-75 -181t75 -181t181 -75t181 75t75 181zM1024 896q0 -109 -33 -179l-364 -774q-16 -33 -47.5 -52t-67.5 -19t-67.5 19t-46.5 52l-365 774q-33 70 -33 179q0 212 150 362t362 150t362 -150t150 -362z" />
-    <glyph glyph-name="adjust" unicode="&#xf042;" 
-d="M768 96v1088q-148 0 -273 -73t-198 -198t-73 -273t73 -273t198 -198t273 -73zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
-    <glyph glyph-name="tint" unicode="&#xf043;" horiz-adv-x="1024" 
-d="M512 384q0 36 -20 69q-1 1 -15.5 22.5t-25.5 38t-25 44t-21 50.5q-4 16 -21 16t-21 -16q-7 -23 -21 -50.5t-25 -44t-25.5 -38t-15.5 -22.5q-20 -33 -20 -69q0 -53 37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1024 512q0 -212 -150 -362t-362 -150t-362 150t-150 362
-q0 145 81 275q6 9 62.5 90.5t101 151t99.5 178t83 201.5q9 30 34 47t51 17t51.5 -17t33.5 -47q28 -93 83 -201.5t99.5 -178t101 -151t62.5 -90.5q81 -127 81 -275z" />
-    <glyph glyph-name="edit" unicode="&#xf044;" horiz-adv-x="1792" 
-d="M888 352l116 116l-152 152l-116 -116v-56h96v-96h56zM1328 1072q-16 16 -33 -1l-350 -350q-17 -17 -1 -33t33 1l350 350q17 17 1 33zM1408 478v-190q0 -119 -84.5 -203.5t-203.5 -84.5h-832q-119 0 -203.5 84.5t-84.5 203.5v832q0 119 84.5 203.5t203.5 84.5h832
-q63 0 117 -25q15 -7 18 -23q3 -17 -9 -29l-49 -49q-14 -14 -32 -8q-23 6 -45 6h-832q-66 0 -113 -47t-47 -113v-832q0 -66 47 -113t113 -47h832q66 0 113 47t47 113v126q0 13 9 22l64 64q15 15 35 7t20 -29zM1312 1216l288 -288l-672 -672h-288v288zM1756 1084l-92 -92
-l-288 288l92 92q28 28 68 28t68 -28l152 -152q28 -28 28 -68t-28 -68z" />
-    <glyph glyph-name="share" unicode="&#xf045;" horiz-adv-x="1664" 
-d="M1408 547v-259q0 -119 -84.5 -203.5t-203.5 -84.5h-832q-119 0 -203.5 84.5t-84.5 203.5v832q0 119 84.5 203.5t203.5 84.5h255v0q13 0 22.5 -9.5t9.5 -22.5q0 -27 -26 -32q-77 -26 -133 -60q-10 -4 -16 -4h-112q-66 0 -113 -47t-47 -113v-832q0 -66 47 -113t113 -47h832
-q66 0 113 47t47 113v214q0 19 18 29q28 13 54 37q16 16 35 8q21 -9 21 -29zM1645 1043l-384 -384q-18 -19 -45 -19q-12 0 -25 5q-39 17 -39 59v192h-160q-323 0 -438 -131q-119 -137 -74 -473q3 -23 -20 -34q-8 -2 -12 -2q-16 0 -26 13q-10 14 -21 31t-39.5 68.5t-49.5 99.5
-t-38.5 114t-17.5 122q0 49 3.5 91t14 90t28 88t47 81.5t68.5 74t94.5 61.5t124.5 48.5t159.5 30.5t196.5 11h160v192q0 42 39 59q13 5 25 5q26 0 45 -19l384 -384q19 -19 19 -45t-19 -45z" />
-    <glyph glyph-name="check" unicode="&#xf046;" horiz-adv-x="1664" 
-d="M1408 606v-318q0 -119 -84.5 -203.5t-203.5 -84.5h-832q-119 0 -203.5 84.5t-84.5 203.5v832q0 119 84.5 203.5t203.5 84.5h832q63 0 117 -25q15 -7 18 -23q3 -17 -9 -29l-49 -49q-10 -10 -23 -10q-3 0 -9 2q-23 6 -45 6h-832q-66 0 -113 -47t-47 -113v-832
-q0 -66 47 -113t113 -47h832q66 0 113 47t47 113v254q0 13 9 22l64 64q10 10 23 10q6 0 12 -3q20 -8 20 -29zM1639 1095l-814 -814q-24 -24 -57 -24t-57 24l-430 430q-24 24 -24 57t24 57l110 110q24 24 57 24t57 -24l263 -263l647 647q24 24 57 24t57 -24l110 -110
-q24 -24 24 -57t-24 -57z" />
-    <glyph glyph-name="move" unicode="&#xf047;" horiz-adv-x="1792" 
-d="M1792 640q0 -26 -19 -45l-256 -256q-19 -19 -45 -19t-45 19t-19 45v128h-384v-384h128q26 0 45 -19t19 -45t-19 -45l-256 -256q-19 -19 -45 -19t-45 19l-256 256q-19 19 -19 45t19 45t45 19h128v384h-384v-128q0 -26 -19 -45t-45 -19t-45 19l-256 256q-19 19 -19 45
-t19 45l256 256q19 19 45 19t45 -19t19 -45v-128h384v384h-128q-26 0 -45 19t-19 45t19 45l256 256q19 19 45 19t45 -19l256 -256q19 -19 19 -45t-19 -45t-45 -19h-128v-384h384v128q0 26 19 45t45 19t45 -19l256 -256q19 -19 19 -45z" />
-    <glyph glyph-name="step_backward" unicode="&#xf048;" horiz-adv-x="1024" 
-d="M979 1395q19 19 32 13t13 -32v-1472q0 -26 -13 -32t-32 13l-710 710q-9 9 -13 19v-678q0 -26 -19 -45t-45 -19h-128q-26 0 -45 19t-19 45v1408q0 26 19 45t45 19h128q26 0 45 -19t19 -45v-678q4 10 13 19z" />
-    <glyph glyph-name="fast_backward" unicode="&#xf049;" horiz-adv-x="1792" 
-d="M1747 1395q19 19 32 13t13 -32v-1472q0 -26 -13 -32t-32 13l-710 710q-9 9 -13 19v-710q0 -26 -13 -32t-32 13l-710 710q-9 9 -13 19v-678q0 -26 -19 -45t-45 -19h-128q-26 0 -45 19t-19 45v1408q0 26 19 45t45 19h128q26 0 45 -19t19 -45v-678q4 10 13 19l710 710
-q19 19 32 13t13 -32v-710q4 10 13 19z" />
-    <glyph glyph-name="backward" unicode="&#xf04a;" horiz-adv-x="1664" 
-d="M1619 1395q19 19 32 13t13 -32v-1472q0 -26 -13 -32t-32 13l-710 710q-9 9 -13 19v-710q0 -26 -13 -32t-32 13l-710 710q-19 19 -19 45t19 45l710 710q19 19 32 13t13 -32v-710q4 10 13 19z" />
-    <glyph glyph-name="play" unicode="&#xf04b;" horiz-adv-x="1408" 
-d="M1384 609l-1328 -738q-23 -13 -39.5 -3t-16.5 36v1472q0 26 16.5 36t39.5 -3l1328 -738q23 -13 23 -31t-23 -31z" />
-    <glyph glyph-name="pause" unicode="&#xf04c;" 
-d="M1536 1344v-1408q0 -26 -19 -45t-45 -19h-512q-26 0 -45 19t-19 45v1408q0 26 19 45t45 19h512q26 0 45 -19t19 -45zM640 1344v-1408q0 -26 -19 -45t-45 -19h-512q-26 0 -45 19t-19 45v1408q0 26 19 45t45 19h512q26 0 45 -19t19 -45z" />
-    <glyph glyph-name="stop" unicode="&#xf04d;" 
-d="M1536 1344v-1408q0 -26 -19 -45t-45 -19h-1408q-26 0 -45 19t-19 45v1408q0 26 19 45t45 19h1408q26 0 45 -19t19 -45z" />
-    <glyph glyph-name="forward" unicode="&#xf04e;" horiz-adv-x="1664" 
-d="M45 -115q-19 -19 -32 -13t-13 32v1472q0 26 13 32t32 -13l710 -710q9 -9 13 -19v710q0 26 13 32t32 -13l710 -710q19 -19 19 -45t-19 -45l-710 -710q-19 -19 -32 -13t-13 32v710q-4 -10 -13 -19z" />
-    <glyph glyph-name="fast_forward" unicode="&#xf050;" horiz-adv-x="1792" 
-d="M45 -115q-19 -19 -32 -13t-13 32v1472q0 26 13 32t32 -13l710 -710q9 -9 13 -19v710q0 26 13 32t32 -13l710 -710q9 -9 13 -19v678q0 26 19 45t45 19h128q26 0 45 -19t19 -45v-1408q0 -26 -19 -45t-45 -19h-128q-26 0 -45 19t-19 45v678q-4 -10 -13 -19l-710 -710
-q-19 -19 -32 -13t-13 32v710q-4 -10 -13 -19z" />
-    <glyph glyph-name="step_forward" unicode="&#xf051;" horiz-adv-x="1024" 
-d="M45 -115q-19 -19 -32 -13t-13 32v1472q0 26 13 32t32 -13l710 -710q9 -9 13 -19v678q0 26 19 45t45 19h128q26 0 45 -19t19 -45v-1408q0 -26 -19 -45t-45 -19h-128q-26 0 -45 19t-19 45v678q-4 -10 -13 -19z" />
-    <glyph glyph-name="eject" unicode="&#xf052;" horiz-adv-x="1538" 
-d="M14 557l710 710q19 19 45 19t45 -19l710 -710q19 -19 13 -32t-32 -13h-1472q-26 0 -32 13t13 32zM1473 0h-1408q-26 0 -45 19t-19 45v256q0 26 19 45t45 19h1408q26 0 45 -19t19 -45v-256q0 -26 -19 -45t-45 -19z" />
-    <glyph glyph-name="chevron_left" unicode="&#xf053;" horiz-adv-x="1280" 
-d="M1171 1235l-531 -531l531 -531q19 -19 19 -45t-19 -45l-166 -166q-19 -19 -45 -19t-45 19l-742 742q-19 19 -19 45t19 45l742 742q19 19 45 19t45 -19l166 -166q19 -19 19 -45t-19 -45z" />
-    <glyph glyph-name="chevron_right" unicode="&#xf054;" horiz-adv-x="1280" 
-d="M1107 659l-742 -742q-19 -19 -45 -19t-45 19l-166 166q-19 19 -19 45t19 45l531 531l-531 531q-19 19 -19 45t19 45l166 166q19 19 45 19t45 -19l742 -742q19 -19 19 -45t-19 -45z" />
-    <glyph glyph-name="plus_sign" unicode="&#xf055;" 
-d="M1216 576v128q0 26 -19 45t-45 19h-256v256q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-256h-256q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45t45 -19h256v-256q0 -26 19 -45t45 -19h128q26 0 45 19t19 45v256h256q26 0 45 19t19 45zM1536 640q0 -209 -103 -385.5
-t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
-    <glyph glyph-name="minus_sign" unicode="&#xf056;" 
-d="M1216 576v128q0 26 -19 45t-45 19h-768q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45t45 -19h768q26 0 45 19t19 45zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5
-t103 -385.5z" />
-    <glyph glyph-name="remove_sign" unicode="&#xf057;" 
-d="M1149 414q0 26 -19 45l-181 181l181 181q19 19 19 45q0 27 -19 46l-90 90q-19 19 -46 19q-26 0 -45 -19l-181 -181l-181 181q-19 19 -45 19q-27 0 -46 -19l-90 -90q-19 -19 -19 -46q0 -26 19 -45l181 -181l-181 -181q-19 -19 -19 -45q0 -27 19 -46l90 -90q19 -19 46 -19
-q26 0 45 19l181 181l181 -181q19 -19 45 -19q27 0 46 19l90 90q19 19 19 46zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
-    <glyph glyph-name="ok_sign" unicode="&#xf058;" 
-d="M1284 802q0 28 -18 46l-91 90q-19 19 -45 19t-45 -19l-408 -407l-226 226q-19 19 -45 19t-45 -19l-91 -90q-18 -18 -18 -46q0 -27 18 -45l362 -362q19 -19 45 -19q27 0 46 19l543 543q18 18 18 45zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103
-t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
-    <glyph glyph-name="question_sign" unicode="&#xf059;" 
-d="M896 160v192q0 14 -9 23t-23 9h-192q-14 0 -23 -9t-9 -23v-192q0 -14 9 -23t23 -9h192q14 0 23 9t9 23zM1152 832q0 88 -55.5 163t-138.5 116t-170 41q-243 0 -371 -213q-15 -24 8 -42l132 -100q7 -6 19 -6q16 0 25 12q53 68 86 92q34 24 86 24q48 0 85.5 -26t37.5 -59
-q0 -38 -20 -61t-68 -45q-63 -28 -115.5 -86.5t-52.5 -125.5v-36q0 -14 9 -23t23 -9h192q14 0 23 9t9 23q0 19 21.5 49.5t54.5 49.5q32 18 49 28.5t46 35t44.5 48t28 60.5t12.5 81zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5
-t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
-    <glyph glyph-name="info_sign" unicode="&#xf05a;" 
-d="M1024 160v160q0 14 -9 23t-23 9h-96v512q0 14 -9 23t-23 9h-320q-14 0 -23 -9t-9 -23v-160q0 -14 9 -23t23 -9h96v-320h-96q-14 0 -23 -9t-9 -23v-160q0 -14 9 -23t23 -9h448q14 0 23 9t9 23zM896 1056v160q0 14 -9 23t-23 9h-192q-14 0 -23 -9t-9 -23v-160q0 -14 9 -23
-t23 -9h192q14 0 23 9t9 23zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
-    <glyph glyph-name="screenshot" unicode="&#xf05b;" 
-d="M1197 512h-109q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h109q-32 108 -112.5 188.5t-188.5 112.5v-109q0 -26 -19 -45t-45 -19h-128q-26 0 -45 19t-19 45v109q-108 -32 -188.5 -112.5t-112.5 -188.5h109q26 0 45 -19t19 -45v-128q0 -26 -19 -45t-45 -19h-109
-q32 -108 112.5 -188.5t188.5 -112.5v109q0 26 19 45t45 19h128q26 0 45 -19t19 -45v-109q108 32 188.5 112.5t112.5 188.5zM1536 704v-128q0 -26 -19 -45t-45 -19h-143q-37 -161 -154.5 -278.5t-278.5 -154.5v-143q0 -26 -19 -45t-45 -19h-128q-26 0 -45 19t-19 45v143
-q-161 37 -278.5 154.5t-154.5 278.5h-143q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h143q37 161 154.5 278.5t278.5 154.5v143q0 26 19 45t45 19h128q26 0 45 -19t19 -45v-143q161 -37 278.5 -154.5t154.5 -278.5h143q26 0 45 -19t19 -45z" />
-    <glyph glyph-name="remove_circle" unicode="&#xf05c;" 
-d="M1097 457l-146 -146q-10 -10 -23 -10t-23 10l-137 137l-137 -137q-10 -10 -23 -10t-23 10l-146 146q-10 10 -10 23t10 23l137 137l-137 137q-10 10 -10 23t10 23l146 146q10 10 23 10t23 -10l137 -137l137 137q10 10 23 10t23 -10l146 -146q10 -10 10 -23t-10 -23
-l-137 -137l137 -137q10 -10 10 -23t-10 -23zM1312 640q0 148 -73 273t-198 198t-273 73t-273 -73t-198 -198t-73 -273t73 -273t198 -198t273 -73t273 73t198 198t73 273zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5
-t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
-    <glyph glyph-name="ok_circle" unicode="&#xf05d;" 
-d="M1171 723l-422 -422q-19 -19 -45 -19t-45 19l-294 294q-19 19 -19 45t19 45l102 102q19 19 45 19t45 -19l147 -147l275 275q19 19 45 19t45 -19l102 -102q19 -19 19 -45t-19 -45zM1312 640q0 148 -73 273t-198 198t-273 73t-273 -73t-198 -198t-73 -273t73 -273t198 -198
-t273 -73t273 73t198 198t73 273zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
-    <glyph glyph-name="ban_circle" unicode="&#xf05e;" 
-d="M1312 643q0 161 -87 295l-754 -753q137 -89 297 -89q111 0 211.5 43.5t173.5 116.5t116 174.5t43 212.5zM313 344l755 754q-135 91 -300 91q-148 0 -273 -73t-198 -199t-73 -274q0 -162 89 -299zM1536 643q0 -157 -61 -300t-163.5 -246t-245 -164t-298.5 -61t-298.5 61
-t-245 164t-163.5 246t-61 300t61 299.5t163.5 245.5t245 164t298.5 61t298.5 -61t245 -164t163.5 -245.5t61 -299.5z" />
-    <glyph glyph-name="arrow_left" unicode="&#xf060;" 
-d="M1536 640v-128q0 -53 -32.5 -90.5t-84.5 -37.5h-704l293 -294q38 -36 38 -90t-38 -90l-75 -76q-37 -37 -90 -37q-52 0 -91 37l-651 652q-37 37 -37 90q0 52 37 91l651 650q38 38 91 38q52 0 90 -38l75 -74q38 -38 38 -91t-38 -91l-293 -293h704q52 0 84.5 -37.5
-t32.5 -90.5z" />
-    <glyph glyph-name="arrow_right" unicode="&#xf061;" 
-d="M1472 576q0 -54 -37 -91l-651 -651q-39 -37 -91 -37q-51 0 -90 37l-75 75q-38 38 -38 91t38 91l293 293h-704q-52 0 -84.5 37.5t-32.5 90.5v128q0 53 32.5 90.5t84.5 37.5h704l-293 294q-38 36 -38 90t38 90l75 75q38 38 90 38q53 0 91 -38l651 -651q37 -35 37 -90z" />
-    <glyph glyph-name="arrow_up" unicode="&#xf062;" horiz-adv-x="1664" 
-d="M1611 565q0 -51 -37 -90l-75 -75q-38 -38 -91 -38q-54 0 -90 38l-294 293v-704q0 -52 -37.5 -84.5t-90.5 -32.5h-128q-53 0 -90.5 32.5t-37.5 84.5v704l-294 -293q-36 -38 -90 -38t-90 38l-75 75q-38 38 -38 90q0 53 38 91l651 651q35 37 90 37q54 0 91 -37l651 -651
-q37 -39 37 -91z" />
-    <glyph glyph-name="arrow_down" unicode="&#xf063;" horiz-adv-x="1664" 
-d="M1611 704q0 -53 -37 -90l-651 -652q-39 -37 -91 -37q-53 0 -90 37l-651 652q-38 36 -38 90q0 53 38 91l74 75q39 37 91 37q53 0 90 -37l294 -294v704q0 52 38 90t90 38h128q52 0 90 -38t38 -90v-704l294 294q37 37 90 37q52 0 91 -37l75 -75q37 -39 37 -91z" />
-    <glyph glyph-name="share_alt" unicode="&#xf064;" horiz-adv-x="1792" 
-d="M1792 896q0 -26 -19 -45l-512 -512q-19 -19 -45 -19t-45 19t-19 45v256h-224q-98 0 -175.5 -6t-154 -21.5t-133 -42.5t-105.5 -69.5t-80 -101t-48.5 -138.5t-17.5 -181q0 -55 5 -123q0 -6 2.5 -23.5t2.5 -26.5q0 -15 -8.5 -25t-23.5 -10q-16 0 -28 17q-7 9 -13 22
-t-13.5 30t-10.5 24q-127 285 -127 451q0 199 53 333q162 403 875 403h224v256q0 26 19 45t45 19t45 -19l512 -512q19 -19 19 -45z" />
-    <glyph glyph-name="resize_full" unicode="&#xf065;" 
-d="M755 480q0 -13 -10 -23l-332 -332l144 -144q19 -19 19 -45t-19 -45t-45 -19h-448q-26 0 -45 19t-19 45v448q0 26 19 45t45 19t45 -19l144 -144l332 332q10 10 23 10t23 -10l114 -114q10 -10 10 -23zM1536 1344v-448q0 -26 -19 -45t-45 -19t-45 19l-144 144l-332 -332
-q-10 -10 -23 -10t-23 10l-114 114q-10 10 -10 23t10 23l332 332l-144 144q-19 19 -19 45t19 45t45 19h448q26 0 45 -19t19 -45z" />
-    <glyph glyph-name="resize_small" unicode="&#xf066;" 
-d="M768 576v-448q0 -26 -19 -45t-45 -19t-45 19l-144 144l-332 -332q-10 -10 -23 -10t-23 10l-114 114q-10 10 -10 23t10 23l332 332l-144 144q-19 19 -19 45t19 45t45 19h448q26 0 45 -19t19 -45zM1523 1248q0 -13 -10 -23l-332 -332l144 -144q19 -19 19 -45t-19 -45
-t-45 -19h-448q-26 0 -45 19t-19 45v448q0 26 19 45t45 19t45 -19l144 -144l332 332q10 10 23 10t23 -10l114 -114q10 -10 10 -23z" />
-    <glyph glyph-name="plus" unicode="&#xf067;" horiz-adv-x="1408" 
-d="M1408 800v-192q0 -40 -28 -68t-68 -28h-416v-416q0 -40 -28 -68t-68 -28h-192q-40 0 -68 28t-28 68v416h-416q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h416v416q0 40 28 68t68 28h192q40 0 68 -28t28 -68v-416h416q40 0 68 -28t28 -68z" />
-    <glyph glyph-name="minus" unicode="&#xf068;" horiz-adv-x="1408" 
-d="M1408 800v-192q0 -40 -28 -68t-68 -28h-1216q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h1216q40 0 68 -28t28 -68z" />
-    <glyph glyph-name="asterisk" unicode="&#xf069;" horiz-adv-x="1664" 
-d="M1482 486q46 -26 59.5 -77.5t-12.5 -97.5l-64 -110q-26 -46 -77.5 -59.5t-97.5 12.5l-266 153v-307q0 -52 -38 -90t-90 -38h-128q-52 0 -90 38t-38 90v307l-266 -153q-46 -26 -97.5 -12.5t-77.5 59.5l-64 110q-26 46 -12.5 97.5t59.5 77.5l266 154l-266 154
-q-46 26 -59.5 77.5t12.5 97.5l64 110q26 46 77.5 59.5t97.5 -12.5l266 -153v307q0 52 38 90t90 38h128q52 0 90 -38t38 -90v-307l266 153q46 26 97.5 12.5t77.5 -59.5l64 -110q26 -46 12.5 -97.5t-59.5 -77.5l-266 -154z" />
-    <glyph glyph-name="exclamation_sign" unicode="&#xf06a;" 
-d="M768 1408q209 0 385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103zM896 161v190q0 14 -9 23.5t-22 9.5h-192q-13 0 -23 -10t-10 -23v-190q0 -13 10 -23t23 -10h192
-q13 0 22 9.5t9 23.5zM894 505l18 621q0 12 -10 18q-10 8 -24 8h-220q-14 0 -24 -8q-10 -6 -10 -18l17 -621q0 -10 10 -17.5t24 -7.5h185q14 0 23.5 7.5t10.5 17.5z" />
-    <glyph glyph-name="gift" unicode="&#xf06b;" 
-d="M928 180v56v468v192h-320v-192v-468v-56q0 -25 18 -38.5t46 -13.5h192q28 0 46 13.5t18 38.5zM472 1024h195l-126 161q-26 31 -69 31q-40 0 -68 -28t-28 -68t28 -68t68 -28zM1160 1120q0 40 -28 68t-68 28q-43 0 -69 -31l-125 -161h194q40 0 68 28t28 68zM1536 864v-320
-q0 -14 -9 -23t-23 -9h-96v-416q0 -40 -28 -68t-68 -28h-1088q-40 0 -68 28t-28 68v416h-96q-14 0 -23 9t-9 23v320q0 14 9 23t23 9h440q-93 0 -158.5 65.5t-65.5 158.5t65.5 158.5t158.5 65.5q107 0 168 -77l128 -165l128 165q61 77 168 77q93 0 158.5 -65.5t65.5 -158.5
-t-65.5 -158.5t-158.5 -65.5h440q14 0 23 -9t9 -23z" />
-    <glyph glyph-name="leaf" unicode="&#xf06c;" horiz-adv-x="1792" 
-d="M1280 832q0 26 -19 45t-45 19q-172 0 -318 -49.5t-259.5 -134t-235.5 -219.5q-19 -21 -19 -45q0 -26 19 -45t45 -19q24 0 45 19q27 24 74 71t67 66q137 124 268.5 176t313.5 52q26 0 45 19t19 45zM1792 1030q0 -95 -20 -193q-46 -224 -184.5 -383t-357.5 -268
-q-214 -108 -438 -108q-148 0 -286 47q-15 5 -88 42t-96 37q-16 0 -39.5 -32t-45 -70t-52.5 -70t-60 -32q-43 0 -63.5 17.5t-45.5 59.5q-2 4 -6 11t-5.5 10t-3 9.5t-1.5 13.5q0 35 31 73.5t68 65.5t68 56t31 48q0 4 -14 38t-16 44q-9 51 -9 104q0 115 43.5 220t119 184.5
-t170.5 139t204 95.5q55 18 145 25.5t179.5 9t178.5 6t163.5 24t113.5 56.5l29.5 29.5t29.5 28t27 20t36.5 16t43.5 4.5q39 0 70.5 -46t47.5 -112t24 -124t8 -96z" />
-    <glyph glyph-name="fire" unicode="&#xf06d;" horiz-adv-x="1408" 
-d="M1408 -160v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-1344q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h1344q13 0 22.5 -9.5t9.5 -22.5zM1152 896q0 -78 -24.5 -144t-64 -112.5t-87.5 -88t-96 -77.5t-87.5 -72t-64 -81.5t-24.5 -96.5q0 -96 67 -224l-4 1l1 -1
-q-90 41 -160 83t-138.5 100t-113.5 122.5t-72.5 150.5t-27.5 184q0 78 24.5 144t64 112.5t87.5 88t96 77.5t87.5 72t64 81.5t24.5 96.5q0 94 -66 224l3 -1l-1 1q90 -41 160 -83t138.5 -100t113.5 -122.5t72.5 -150.5t27.5 -184z" />
-    <glyph glyph-name="eye_open" unicode="&#xf06e;" horiz-adv-x="1792" 
-d="M1664 576q-152 236 -381 353q61 -104 61 -225q0 -185 -131.5 -316.5t-316.5 -131.5t-316.5 131.5t-131.5 316.5q0 121 61 225q-229 -117 -381 -353q133 -205 333.5 -326.5t434.5 -121.5t434.5 121.5t333.5 326.5zM944 960q0 20 -14 34t-34 14q-125 0 -214.5 -89.5
-t-89.5 -214.5q0 -20 14 -34t34 -14t34 14t14 34q0 86 61 147t147 61q20 0 34 14t14 34zM1792 576q0 -34 -20 -69q-140 -230 -376.5 -368.5t-499.5 -138.5t-499.5 139t-376.5 368q-20 35 -20 69t20 69q140 229 376.5 368t499.5 139t499.5 -139t376.5 -368q20 -35 20 -69z" />
-    <glyph glyph-name="eye_close" unicode="&#xf070;" horiz-adv-x="1792" 
-d="M555 201l78 141q-87 63 -136 159t-49 203q0 121 61 225q-229 -117 -381 -353q167 -258 427 -375zM944 960q0 20 -14 34t-34 14q-125 0 -214.5 -89.5t-89.5 -214.5q0 -20 14 -34t34 -14t34 14t14 34q0 86 61 147t147 61q20 0 34 14t14 34zM1307 1151q0 -7 -1 -9
-q-106 -189 -316 -567t-315 -566l-49 -89q-10 -16 -28 -16q-12 0 -134 70q-16 10 -16 28q0 12 44 87q-143 65 -263.5 173t-208.5 245q-20 31 -20 69t20 69q153 235 380 371t496 136q89 0 180 -17l54 97q10 16 28 16q5 0 18 -6t31 -15.5t33 -18.5t31.5 -18.5t19.5 -11.5
-q16 -10 16 -27zM1344 704q0 -139 -79 -253.5t-209 -164.5l280 502q8 -45 8 -84zM1792 576q0 -35 -20 -69q-39 -64 -109 -145q-150 -172 -347.5 -267t-419.5 -95l74 132q212 18 392.5 137t301.5 307q-115 179 -282 294l63 112q95 -64 182.5 -153t144.5 -184q20 -34 20 -69z
-" />
-    <glyph glyph-name="warning_sign" unicode="&#xf071;" horiz-adv-x="1792" 
-d="M1024 161v190q0 14 -9.5 23.5t-22.5 9.5h-192q-13 0 -22.5 -9.5t-9.5 -23.5v-190q0 -14 9.5 -23.5t22.5 -9.5h192q13 0 22.5 9.5t9.5 23.5zM1022 535l18 459q0 12 -10 19q-13 11 -24 11h-220q-11 0 -24 -11q-10 -7 -10 -21l17 -457q0 -10 10 -16.5t24 -6.5h185
-q14 0 23.5 6.5t10.5 16.5zM1008 1469l768 -1408q35 -63 -2 -126q-17 -29 -46.5 -46t-63.5 -17h-1536q-34 0 -63.5 17t-46.5 46q-37 63 -2 126l768 1408q17 31 47 49t65 18t65 -18t47 -49z" />
-    <glyph glyph-name="plane" unicode="&#xf072;" horiz-adv-x="1408" 
-d="M1376 1376q44 -52 12 -148t-108 -172l-161 -161l160 -696q5 -19 -12 -33l-128 -96q-7 -6 -19 -6q-4 0 -7 1q-15 3 -21 16l-279 508l-259 -259l53 -194q5 -17 -8 -31l-96 -96q-9 -9 -23 -9h-2q-15 2 -24 13l-189 252l-252 189q-11 7 -13 23q-1 13 9 25l96 97q9 9 23 9
-q6 0 8 -1l194 -53l259 259l-508 279q-14 8 -17 24q-2 16 9 27l128 128q14 13 30 8l665 -159l160 160q76 76 172 108t148 -12z" />
-    <glyph glyph-name="calendar" unicode="&#xf073;" horiz-adv-x="1664" 
-d="M128 -128h288v288h-288v-288zM480 -128h320v288h-320v-288zM128 224h288v320h-288v-320zM480 224h320v320h-320v-320zM128 608h288v288h-288v-288zM864 -128h320v288h-320v-288zM480 608h320v288h-320v-288zM1248 -128h288v288h-288v-288zM864 224h320v320h-320v-320z
-M512 1088v288q0 13 -9.5 22.5t-22.5 9.5h-64q-13 0 -22.5 -9.5t-9.5 -22.5v-288q0 -13 9.5 -22.5t22.5 -9.5h64q13 0 22.5 9.5t9.5 22.5zM1248 224h288v320h-288v-320zM864 608h320v288h-320v-288zM1248 608h288v288h-288v-288zM1280 1088v288q0 13 -9.5 22.5t-22.5 9.5h-64
-q-13 0 -22.5 -9.5t-9.5 -22.5v-288q0 -13 9.5 -22.5t22.5 -9.5h64q13 0 22.5 9.5t9.5 22.5zM1664 1152v-1280q0 -52 -38 -90t-90 -38h-1408q-52 0 -90 38t-38 90v1280q0 52 38 90t90 38h128v96q0 66 47 113t113 47h64q66 0 113 -47t47 -113v-96h384v96q0 66 47 113t113 47
-h64q66 0 113 -47t47 -113v-96h128q52 0 90 -38t38 -90z" />
-    <glyph glyph-name="random" unicode="&#xf074;" horiz-adv-x="1792" 
-d="M666 1055q-60 -92 -137 -273q-22 45 -37 72.5t-40.5 63.5t-51 56.5t-63 35t-81.5 14.5h-224q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h224q250 0 410 -225zM1792 256q0 -14 -9 -23l-320 -320q-9 -9 -23 -9q-13 0 -22.5 9.5t-9.5 22.5v192q-32 0 -85 -0.5t-81 -1t-73 1
-t-71 5t-64 10.5t-63 18.5t-58 28.5t-59 40t-55 53.5t-56 69.5q59 93 136 273q22 -45 37 -72.5t40.5 -63.5t51 -56.5t63 -35t81.5 -14.5h256v192q0 14 9 23t23 9q12 0 24 -10l319 -319q9 -9 9 -23zM1792 1152q0 -14 -9 -23l-320 -320q-9 -9 -23 -9q-13 0 -22.5 9.5t-9.5 22.5
-v192h-256q-48 0 -87 -15t-69 -45t-51 -61.5t-45 -77.5q-32 -62 -78 -171q-29 -66 -49.5 -111t-54 -105t-64 -100t-74 -83t-90 -68.5t-106.5 -42t-128 -16.5h-224q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h224q48 0 87 15t69 45t51 61.5t45 77.5q32 62 78 171q29 66 49.5 111
-t54 105t64 100t74 83t90 68.5t106.5 42t128 16.5h256v192q0 14 9 23t23 9q12 0 24 -10l319 -319q9 -9 9 -23z" />
-    <glyph glyph-name="comment" unicode="&#xf075;" horiz-adv-x="1792" 
-d="M1792 640q0 -174 -120 -321.5t-326 -233t-450 -85.5q-70 0 -145 8q-198 -175 -460 -242q-49 -14 -114 -22q-17 -2 -30.5 9t-17.5 29v1q-3 4 -0.5 12t2 10t4.5 9.5l6 9t7 8.5t8 9q7 8 31 34.5t34.5 38t31 39.5t32.5 51t27 59t26 76q-157 89 -247.5 220t-90.5 281
-q0 130 71 248.5t191 204.5t286 136.5t348 50.5q244 0 450 -85.5t326 -233t120 -321.5z" />
-    <glyph glyph-name="magnet" unicode="&#xf076;" 
-d="M1536 704v-128q0 -201 -98.5 -362t-274 -251.5t-395.5 -90.5t-395.5 90.5t-274 251.5t-98.5 362v128q0 26 19 45t45 19h384q26 0 45 -19t19 -45v-128q0 -52 23.5 -90t53.5 -57t71 -30t64 -13t44 -2t44 2t64 13t71 30t53.5 57t23.5 90v128q0 26 19 45t45 19h384
-q26 0 45 -19t19 -45zM512 1344v-384q0 -26 -19 -45t-45 -19h-384q-26 0 -45 19t-19 45v384q0 26 19 45t45 19h384q26 0 45 -19t19 -45zM1536 1344v-384q0 -26 -19 -45t-45 -19h-384q-26 0 -45 19t-19 45v384q0 26 19 45t45 19h384q26 0 45 -19t19 -45z" />
-    <glyph glyph-name="chevron_up" unicode="&#xf077;" horiz-adv-x="1792" 
-d="M1683 205l-166 -165q-19 -19 -45 -19t-45 19l-531 531l-531 -531q-19 -19 -45 -19t-45 19l-166 165q-19 19 -19 45.5t19 45.5l742 741q19 19 45 19t45 -19l742 -741q19 -19 19 -45.5t-19 -45.5z" />
-    <glyph glyph-name="chevron_down" unicode="&#xf078;" horiz-adv-x="1792" 
-d="M1683 728l-742 -741q-19 -19 -45 -19t-45 19l-742 741q-19 19 -19 45.5t19 45.5l166 165q19 19 45 19t45 -19l531 -531l531 531q19 19 45 19t45 -19l166 -165q19 -19 19 -45.5t-19 -45.5z" />
-    <glyph glyph-name="retweet" unicode="&#xf079;" horiz-adv-x="1920" 
-d="M1280 32q0 -13 -9.5 -22.5t-22.5 -9.5h-960q-8 0 -13.5 2t-9 7t-5.5 8t-3 11.5t-1 11.5v13v11v160v416h-192q-26 0 -45 19t-19 45q0 24 15 41l320 384q19 22 49 22t49 -22l320 -384q15 -17 15 -41q0 -26 -19 -45t-45 -19h-192v-384h576q16 0 25 -11l160 -192q7 -10 7 -21
-zM1920 448q0 -24 -15 -41l-320 -384q-20 -23 -49 -23t-49 23l-320 384q-15 17 -15 41q0 26 19 45t45 19h192v384h-576q-16 0 -25 12l-160 192q-7 9 -7 20q0 13 9.5 22.5t22.5 9.5h960q8 0 13.5 -2t9 -7t5.5 -8t3 -11.5t1 -11.5v-13v-11v-160v-416h192q26 0 45 -19t19 -45z
-" />
-    <glyph glyph-name="shopping_cart" unicode="&#xf07a;" horiz-adv-x="1664" 
-d="M640 0q0 -52 -38 -90t-90 -38t-90 38t-38 90t38 90t90 38t90 -38t38 -90zM1536 0q0 -52 -38 -90t-90 -38t-90 38t-38 90t38 90t90 38t90 -38t38 -90zM1664 1088v-512q0 -24 -16.5 -42.5t-40.5 -21.5l-1044 -122q13 -60 13 -70q0 -16 -24 -64h920q26 0 45 -19t19 -45
-t-19 -45t-45 -19h-1024q-26 0 -45 19t-19 45q0 11 8 31.5t16 36t21.5 40t15.5 29.5l-177 823h-204q-26 0 -45 19t-19 45t19 45t45 19h256q16 0 28.5 -6.5t19.5 -15.5t13 -24.5t8 -26t5.5 -29.5t4.5 -26h1201q26 0 45 -19t19 -45z" />
-    <glyph glyph-name="folder_close" unicode="&#xf07b;" horiz-adv-x="1664" 
-d="M1664 928v-704q0 -92 -66 -158t-158 -66h-1216q-92 0 -158 66t-66 158v960q0 92 66 158t158 66h320q92 0 158 -66t66 -158v-32h672q92 0 158 -66t66 -158z" />
-    <glyph glyph-name="folder_open" unicode="&#xf07c;" horiz-adv-x="1920" 
-d="M1879 584q0 -31 -31 -66l-336 -396q-43 -51 -120.5 -86.5t-143.5 -35.5h-1088q-34 0 -60.5 13t-26.5 43q0 31 31 66l336 396q43 51 120.5 86.5t143.5 35.5h1088q34 0 60.5 -13t26.5 -43zM1536 928v-160h-832q-94 0 -197 -47.5t-164 -119.5l-337 -396l-5 -6q0 4 -0.5 12.5
-t-0.5 12.5v960q0 92 66 158t158 66h320q92 0 158 -66t66 -158v-32h544q92 0 158 -66t66 -158z" />
-    <glyph glyph-name="resize_vertical" unicode="&#xf07d;" horiz-adv-x="768" 
-d="M704 1216q0 -26 -19 -45t-45 -19h-128v-1024h128q26 0 45 -19t19 -45t-19 -45l-256 -256q-19 -19 -45 -19t-45 19l-256 256q-19 19 -19 45t19 45t45 19h128v1024h-128q-26 0 -45 19t-19 45t19 45l256 256q19 19 45 19t45 -19l256 -256q19 -19 19 -45z" />
-    <glyph glyph-name="resize_horizontal" unicode="&#xf07e;" horiz-adv-x="1792" 
-d="M1792 640q0 -26 -19 -45l-256 -256q-19 -19 -45 -19t-45 19t-19 45v128h-1024v-128q0 -26 -19 -45t-45 -19t-45 19l-256 256q-19 19 -19 45t19 45l256 256q19 19 45 19t45 -19t19 -45v-128h1024v128q0 26 19 45t45 19t45 -19l256 -256q19 -19 19 -45z" />
-    <glyph glyph-name="bar_chart" unicode="&#xf080;" horiz-adv-x="2048" 
-d="M640 640v-512h-256v512h256zM1024 1152v-1024h-256v1024h256zM2048 0v-128h-2048v1536h128v-1408h1920zM1408 896v-768h-256v768h256zM1792 1280v-1152h-256v1152h256z" />
-    <glyph glyph-name="twitter_sign" unicode="&#xf081;" 
-d="M1280 926q-56 -25 -121 -34q68 40 93 117q-65 -38 -134 -51q-61 66 -153 66q-87 0 -148.5 -61.5t-61.5 -148.5q0 -29 5 -48q-129 7 -242 65t-192 155q-29 -50 -29 -106q0 -114 91 -175q-47 1 -100 26v-2q0 -75 50 -133.5t123 -72.5q-29 -8 -51 -8q-13 0 -39 4
-q21 -63 74.5 -104t121.5 -42q-116 -90 -261 -90q-26 0 -50 3q148 -94 322 -94q112 0 210 35.5t168 95t120.5 137t75 162t24.5 168.5q0 18 -1 27q63 45 105 109zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5
-t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
-    <glyph glyph-name="facebook_sign" unicode="&#xf082;" 
-d="M1248 1408q119 0 203.5 -84.5t84.5 -203.5v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-188v595h199l30 232h-229v148q0 56 23.5 84t91.5 28l122 1v207q-63 9 -178 9q-136 0 -217.5 -80t-81.5 -226v-171h-200v-232h200v-595h-532q-119 0 -203.5 84.5t-84.5 203.5v960
-q0 119 84.5 203.5t203.5 84.5h960z" />
-    <glyph glyph-name="camera_retro" unicode="&#xf083;" horiz-adv-x="1792" 
-d="M928 704q0 14 -9 23t-23 9q-66 0 -113 -47t-47 -113q0 -14 9 -23t23 -9t23 9t9 23q0 40 28 68t68 28q14 0 23 9t9 23zM1152 574q0 -106 -75 -181t-181 -75t-181 75t-75 181t75 181t181 75t181 -75t75 -181zM128 0h1536v128h-1536v-128zM1280 574q0 159 -112.5 271.5
-t-271.5 112.5t-271.5 -112.5t-112.5 -271.5t112.5 -271.5t271.5 -112.5t271.5 112.5t112.5 271.5zM256 1216h384v128h-384v-128zM128 1024h1536v118v138h-828l-64 -128h-644v-128zM1792 1280v-1280q0 -53 -37.5 -90.5t-90.5 -37.5h-1536q-53 0 -90.5 37.5t-37.5 90.5v1280
-q0 53 37.5 90.5t90.5 37.5h1536q53 0 90.5 -37.5t37.5 -90.5z" />
-    <glyph glyph-name="key" unicode="&#xf084;" horiz-adv-x="1792" 
-d="M832 1024q0 80 -56 136t-136 56t-136 -56t-56 -136q0 -42 19 -83q-41 19 -83 19q-80 0 -136 -56t-56 -136t56 -136t136 -56t136 56t56 136q0 42 -19 83q41 -19 83 -19q80 0 136 56t56 136zM1683 320q0 -17 -49 -66t-66 -49q-9 0 -28.5 16t-36.5 33t-38.5 40t-24.5 26
-l-96 -96l220 -220q28 -28 28 -68q0 -42 -39 -81t-81 -39q-40 0 -68 28l-671 671q-176 -131 -365 -131q-163 0 -265.5 102.5t-102.5 265.5q0 160 95 313t248 248t313 95q163 0 265.5 -102.5t102.5 -265.5q0 -189 -131 -365l355 -355l96 96q-3 3 -26 24.5t-40 38.5t-33 36.5
-t-16 28.5q0 17 49 66t66 49q13 0 23 -10q6 -6 46 -44.5t82 -79.5t86.5 -86t73 -78t28.5 -41z" />
-    <glyph glyph-name="cogs" unicode="&#xf085;" horiz-adv-x="1920" 
-d="M896 640q0 106 -75 181t-181 75t-181 -75t-75 -181t75 -181t181 -75t181 75t75 181zM1664 128q0 52 -38 90t-90 38t-90 -38t-38 -90q0 -53 37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1664 1152q0 52 -38 90t-90 38t-90 -38t-38 -90q0 -53 37.5 -90.5t90.5 -37.5
-t90.5 37.5t37.5 90.5zM1280 731v-185q0 -10 -7 -19.5t-16 -10.5l-155 -24q-11 -35 -32 -76q34 -48 90 -115q7 -11 7 -20q0 -12 -7 -19q-23 -30 -82.5 -89.5t-78.5 -59.5q-11 0 -21 7l-115 90q-37 -19 -77 -31q-11 -108 -23 -155q-7 -24 -30 -24h-186q-11 0 -20 7.5t-10 17.5
-l-23 153q-34 10 -75 31l-118 -89q-7 -7 -20 -7q-11 0 -21 8q-144 133 -144 160q0 9 7 19q10 14 41 53t47 61q-23 44 -35 82l-152 24q-10 1 -17 9.5t-7 19.5v185q0 10 7 19.5t16 10.5l155 24q11 35 32 76q-34 48 -90 115q-7 11 -7 20q0 12 7 20q22 30 82 89t79 59q11 0 21 -7
-l115 -90q34 18 77 32q11 108 23 154q7 24 30 24h186q11 0 20 -7.5t10 -17.5l23 -153q34 -10 75 -31l118 89q8 7 20 7q11 0 21 -8q144 -133 144 -160q0 -8 -7 -19q-12 -16 -42 -54t-45 -60q23 -48 34 -82l152 -23q10 -2 17 -10.5t7 -19.5zM1920 198v-140q0 -16 -149 -31
-q-12 -27 -30 -52q51 -113 51 -138q0 -4 -4 -7q-122 -71 -124 -71q-8 0 -46 47t-52 68q-20 -2 -30 -2t-30 2q-14 -21 -52 -68t-46 -47q-2 0 -124 71q-4 3 -4 7q0 25 51 138q-18 25 -30 52q-149 15 -149 31v140q0 16 149 31q13 29 30 52q-51 113 -51 138q0 4 4 7q4 2 35 20
-t59 34t30 16q8 0 46 -46.5t52 -67.5q20 2 30 2t30 -2q51 71 92 112l6 2q4 0 124 -70q4 -3 4 -7q0 -25 -51 -138q17 -23 30 -52q149 -15 149 -31zM1920 1222v-140q0 -16 -149 -31q-12 -27 -30 -52q51 -113 51 -138q0 -4 -4 -7q-122 -71 -124 -71q-8 0 -46 47t-52 68
-q-20 -2 -30 -2t-30 2q-14 -21 -52 -68t-46 -47q-2 0 -124 71q-4 3 -4 7q0 25 51 138q-18 25 -30 52q-149 15 -149 31v140q0 16 149 31q13 29 30 52q-51 113 -51 138q0 4 4 7q4 2 35 20t59 34t30 16q8 0 46 -46.5t52 -67.5q20 2 30 2t30 -2q51 71 92 112l6 2q4 0 124 -70
-q4 -3 4 -7q0 -25 -51 -138q17 -23 30 -52q149 -15 149 -31z" />
-    <glyph glyph-name="comments" unicode="&#xf086;" horiz-adv-x="1792" 
-d="M1408 768q0 -139 -94 -257t-256.5 -186.5t-353.5 -68.5q-86 0 -176 16q-124 -88 -278 -128q-36 -9 -86 -16h-3q-11 0 -20.5 8t-11.5 21q-1 3 -1 6.5t0.5 6.5t2 6l2.5 5t3.5 5.5t4 5t4.5 5t4 4.5q5 6 23 25t26 29.5t22.5 29t25 38.5t20.5 44q-124 72 -195 177t-71 224
-q0 139 94 257t256.5 186.5t353.5 68.5t353.5 -68.5t256.5 -186.5t94 -257zM1792 512q0 -120 -71 -224.5t-195 -176.5q10 -24 20.5 -44t25 -38.5t22.5 -29t26 -29.5t23 -25q1 -1 4 -4.5t4.5 -5t4 -5t3.5 -5.5l2.5 -5t2 -6t0.5 -6.5t-1 -6.5q-3 -14 -13 -22t-22 -7
-q-50 7 -86 16q-154 40 -278 128q-90 -16 -176 -16q-271 0 -472 132q58 -4 88 -4q161 0 309 45t264 129q125 92 192 212t67 254q0 77 -23 152q129 -71 204 -178t75 -230z" />
-    <glyph glyph-name="thumbs_up_alt" unicode="&#xf087;" 
-d="M256 192q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1408 768q0 51 -39 89.5t-89 38.5h-352q0 58 48 159.5t48 160.5q0 98 -32 145t-128 47q-26 -26 -38 -85t-30.5 -125.5t-59.5 -109.5q-22 -23 -77 -91q-4 -5 -23 -30t-31.5 -41t-34.5 -42.5
-t-40 -44t-38.5 -35.5t-40 -27t-35.5 -9h-32v-640h32q13 0 31.5 -3t33 -6.5t38 -11t35 -11.5t35.5 -12.5t29 -10.5q211 -73 342 -73h121q192 0 192 167q0 26 -5 56q30 16 47.5 52.5t17.5 73.5t-18 69q53 50 53 119q0 25 -10 55.5t-25 47.5q32 1 53.5 47t21.5 81zM1536 769
-q0 -89 -49 -163q9 -33 9 -69q0 -77 -38 -144q3 -21 3 -43q0 -101 -60 -178q1 -139 -85 -219.5t-227 -80.5h-36h-93q-96 0 -189.5 22.5t-216.5 65.5q-116 40 -138 40h-288q-53 0 -90.5 37.5t-37.5 90.5v640q0 53 37.5 90.5t90.5 37.5h274q36 24 137 155q58 75 107 128
-q24 25 35.5 85.5t30.5 126.5t62 108q39 37 90 37q84 0 151 -32.5t102 -101.5t35 -186q0 -93 -48 -192h176q104 0 180 -76t76 -179z" />
-    <glyph glyph-name="thumbs_down_alt" unicode="&#xf088;" 
-d="M256 1088q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1408 512q0 35 -21.5 81t-53.5 47q15 17 25 47.5t10 55.5q0 69 -53 119q18 31 18 69q0 37 -17.5 73.5t-47.5 52.5q5 30 5 56q0 85 -49 126t-136 41h-128q-131 0 -342 -73q-5 -2 -29 -10.5
-t-35.5 -12.5t-35 -11.5t-38 -11t-33 -6.5t-31.5 -3h-32v-640h32q16 0 35.5 -9t40 -27t38.5 -35.5t40 -44t34.5 -42.5t31.5 -41t23 -30q55 -68 77 -91q41 -43 59.5 -109.5t30.5 -125.5t38 -85q96 0 128 47t32 145q0 59 -48 160.5t-48 159.5h352q50 0 89 38.5t39 89.5z
-M1536 511q0 -103 -76 -179t-180 -76h-176q48 -99 48 -192q0 -118 -35 -186q-35 -69 -102 -101.5t-151 -32.5q-51 0 -90 37q-34 33 -54 82t-25.5 90.5t-17.5 84.5t-31 64q-48 50 -107 127q-101 131 -137 155h-274q-53 0 -90.5 37.5t-37.5 90.5v640q0 53 37.5 90.5t90.5 37.5
-h288q22 0 138 40q128 44 223 66t200 22h112q140 0 226.5 -79t85.5 -216v-5q60 -77 60 -178q0 -22 -3 -43q38 -67 38 -144q0 -36 -9 -69q49 -73 49 -163z" />
-    <glyph glyph-name="star_half" unicode="&#xf089;" horiz-adv-x="896" 
-d="M832 1504v-1339l-449 -236q-22 -12 -40 -12q-21 0 -31.5 14.5t-10.5 35.5q0 6 2 20l86 500l-364 354q-25 27 -25 48q0 37 56 46l502 73l225 455q19 41 49 41z" />
-    <glyph glyph-name="heart_empty" unicode="&#xf08a;" horiz-adv-x="1792" 
-d="M1664 940q0 81 -21.5 143t-55 98.5t-81.5 59.5t-94 31t-98 8t-112 -25.5t-110.5 -64t-86.5 -72t-60 -61.5q-18 -22 -49 -22t-49 22q-24 28 -60 61.5t-86.5 72t-110.5 64t-112 25.5t-98 -8t-94 -31t-81.5 -59.5t-55 -98.5t-21.5 -143q0 -168 187 -355l581 -560l580 559
-q188 188 188 356zM1792 940q0 -221 -229 -450l-623 -600q-18 -18 -44 -18t-44 18l-624 602q-10 8 -27.5 26t-55.5 65.5t-68 97.5t-53.5 121t-23.5 138q0 220 127 344t351 124q62 0 126.5 -21.5t120 -58t95.5 -68.5t76 -68q36 36 76 68t95.5 68.5t120 58t126.5 21.5
-q224 0 351 -124t127 -344z" />
-    <glyph glyph-name="signout" unicode="&#xf08b;" horiz-adv-x="1664" 
-d="M640 96q0 -4 1 -20t0.5 -26.5t-3 -23.5t-10 -19.5t-20.5 -6.5h-320q-119 0 -203.5 84.5t-84.5 203.5v704q0 119 84.5 203.5t203.5 84.5h320q13 0 22.5 -9.5t9.5 -22.5q0 -4 1 -20t0.5 -26.5t-3 -23.5t-10 -19.5t-20.5 -6.5h-320q-66 0 -113 -47t-47 -113v-704
-q0 -66 47 -113t113 -47h288h11h13t11.5 -1t11.5 -3t8 -5.5t7 -9t2 -13.5zM1568 640q0 -26 -19 -45l-544 -544q-19 -19 -45 -19t-45 19t-19 45v288h-448q-26 0 -45 19t-19 45v384q0 26 19 45t45 19h448v288q0 26 19 45t45 19t45 -19l544 -544q19 -19 19 -45z" />
-    <glyph glyph-name="linkedin_sign" unicode="&#xf08c;" 
-d="M237 122h231v694h-231v-694zM483 1030q-1 52 -36 86t-93 34t-94.5 -34t-36.5 -86q0 -51 35.5 -85.5t92.5 -34.5h1q59 0 95 34.5t36 85.5zM1068 122h231v398q0 154 -73 233t-193 79q-136 0 -209 -117h2v101h-231q3 -66 0 -694h231v388q0 38 7 56q15 35 45 59.5t74 24.5
-q116 0 116 -157v-371zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
-    <glyph glyph-name="pushpin" unicode="&#xf08d;" horiz-adv-x="1152" 
-d="M480 672v448q0 14 -9 23t-23 9t-23 -9t-9 -23v-448q0 -14 9 -23t23 -9t23 9t9 23zM1152 320q0 -26 -19 -45t-45 -19h-429l-51 -483q-2 -12 -10.5 -20.5t-20.5 -8.5h-1q-27 0 -32 27l-76 485h-404q-26 0 -45 19t-19 45q0 123 78.5 221.5t177.5 98.5v512q-52 0 -90 38
-t-38 90t38 90t90 38h640q52 0 90 -38t38 -90t-38 -90t-90 -38v-512q99 0 177.5 -98.5t78.5 -221.5z" />
-    <glyph glyph-name="external_link" unicode="&#xf08e;" horiz-adv-x="1792" 
-d="M1408 608v-320q0 -119 -84.5 -203.5t-203.5 -84.5h-832q-119 0 -203.5 84.5t-84.5 203.5v832q0 119 84.5 203.5t203.5 84.5h704q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-704q-66 0 -113 -47t-47 -113v-832q0 -66 47 -113t113 -47h832q66 0 113 47t47 113v320
-q0 14 9 23t23 9h64q14 0 23 -9t9 -23zM1792 1472v-512q0 -26 -19 -45t-45 -19t-45 19l-176 176l-652 -652q-10 -10 -23 -10t-23 10l-114 114q-10 10 -10 23t10 23l652 652l-176 176q-19 19 -19 45t19 45t45 19h512q26 0 45 -19t19 -45z" />
-    <glyph glyph-name="signin" unicode="&#xf090;" 
-d="M1184 640q0 -26 -19 -45l-544 -544q-19 -19 -45 -19t-45 19t-19 45v288h-448q-26 0 -45 19t-19 45v384q0 26 19 45t45 19h448v288q0 26 19 45t45 19t45 -19l544 -544q19 -19 19 -45zM1536 992v-704q0 -119 -84.5 -203.5t-203.5 -84.5h-320q-13 0 -22.5 9.5t-9.5 22.5
-q0 4 -1 20t-0.5 26.5t3 23.5t10 19.5t20.5 6.5h320q66 0 113 47t47 113v704q0 66 -47 113t-113 47h-288h-11h-13t-11.5 1t-11.5 3t-8 5.5t-7 9t-2 13.5q0 4 -1 20t-0.5 26.5t3 23.5t10 19.5t20.5 6.5h320q119 0 203.5 -84.5t84.5 -203.5z" />
-    <glyph glyph-name="trophy" unicode="&#xf091;" horiz-adv-x="1664" 
-d="M458 653q-74 162 -74 371h-256v-96q0 -78 94.5 -162t235.5 -113zM1536 928v96h-256q0 -209 -74 -371q141 29 235.5 113t94.5 162zM1664 1056v-128q0 -71 -41.5 -143t-112 -130t-173 -97.5t-215.5 -44.5q-42 -54 -95 -95q-38 -34 -52.5 -72.5t-14.5 -89.5q0 -54 30.5 -91
-t97.5 -37q75 0 133.5 -45.5t58.5 -114.5v-64q0 -14 -9 -23t-23 -9h-832q-14 0 -23 9t-9 23v64q0 69 58.5 114.5t133.5 45.5q67 0 97.5 37t30.5 91q0 51 -14.5 89.5t-52.5 72.5q-53 41 -95 95q-113 5 -215.5 44.5t-173 97.5t-112 130t-41.5 143v128q0 40 28 68t68 28h288v96
-q0 66 47 113t113 47h576q66 0 113 -47t47 -113v-96h288q40 0 68 -28t28 -68z" />
-    <glyph glyph-name="github_sign" unicode="&#xf092;" 
-d="M519 336q4 6 -3 13q-9 7 -14 2q-4 -6 3 -13q9 -7 14 -2zM491 377q-5 7 -12 4q-6 -4 0 -12q7 -8 12 -5q6 4 0 13zM450 417q2 4 -5 8q-7 2 -8 -2q-3 -5 4 -8q8 -2 9 2zM471 394q2 1 1.5 4.5t-3.5 5.5q-6 7 -10 3t1 -11q6 -6 11 -2zM557 319q2 7 -9 11q-9 3 -13 -4
-q-2 -7 9 -11q9 -3 13 4zM599 316q0 8 -12 8q-10 0 -10 -8t11 -8t11 8zM638 323q-2 7 -13 5t-9 -9q2 -8 12 -6t10 10zM1280 640q0 212 -150 362t-362 150t-362 -150t-150 -362q0 -167 98 -300.5t252 -185.5q18 -3 26.5 5t8.5 20q0 52 -1 95q-6 -1 -15.5 -2.5t-35.5 -2t-48 4
-t-43.5 20t-29.5 41.5q-23 59 -57 74q-2 1 -4.5 3.5l-8 8t-7 9.5t4 7.5t19.5 3.5q6 0 15 -2t30 -15.5t33 -35.5q16 -28 37.5 -42t43.5 -14t38 3.5t30 9.5q7 47 33 69q-49 6 -86 18.5t-73 39t-55.5 76t-19.5 119.5q0 79 53 137q-24 62 5 136q19 6 54.5 -7.5t60.5 -29.5l26 -16
-q58 17 128 17t128 -17q11 7 28.5 18t55.5 26t57 9q29 -74 5 -136q53 -58 53 -137q0 -57 -14 -100.5t-35.5 -70t-53.5 -44.5t-62.5 -26t-68.5 -12q35 -31 35 -95q0 -40 -0.5 -89t-0.5 -51q0 -12 8.5 -20t26.5 -5q154 52 252 185.5t98 300.5zM1536 1120v-960
-q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
-    <glyph glyph-name="upload_alt" unicode="&#xf093;" horiz-adv-x="1664" 
-d="M1280 64q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1536 64q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1664 288v-320q0 -40 -28 -68t-68 -28h-1472q-40 0 -68 28t-28 68v320q0 40 28 68t68 28h427q21 -56 70.5 -92
-t110.5 -36h256q61 0 110.5 36t70.5 92h427q40 0 68 -28t28 -68zM1339 936q-17 -40 -59 -40h-256v-448q0 -26 -19 -45t-45 -19h-256q-26 0 -45 19t-19 45v448h-256q-42 0 -59 40q-17 39 14 69l448 448q18 19 45 19t45 -19l448 -448q31 -30 14 -69z" />
-    <glyph glyph-name="lemon" unicode="&#xf094;" 
-d="M1407 710q0 44 -7 113.5t-18 96.5q-12 30 -17 44t-9 36.5t-4 48.5q0 23 5 68.5t5 67.5q0 37 -10 55q-4 1 -13 1q-19 0 -58 -4.5t-59 -4.5q-60 0 -176 24t-175 24q-43 0 -94.5 -11.5t-85 -23.5t-89.5 -34q-137 -54 -202 -103q-96 -73 -159.5 -189.5t-88 -236t-24.5 -248.5
-q0 -40 12.5 -120t12.5 -121q0 -23 -11 -66.5t-11 -65.5t12 -36.5t34 -14.5q24 0 72.5 11t73.5 11q57 0 169.5 -15.5t169.5 -15.5q181 0 284 36q129 45 235.5 152.5t166 245.5t59.5 275zM1535 712q0 -165 -70 -327.5t-196 -288t-281 -180.5q-124 -44 -326 -44
-q-57 0 -170 14.5t-169 14.5q-24 0 -72.5 -14.5t-73.5 -14.5q-73 0 -123.5 55.5t-50.5 128.5q0 24 11 68t11 67q0 40 -12.5 120.5t-12.5 121.5q0 111 18 217.5t54.5 209.5t100.5 194t150 156q78 59 232 120q194 78 316 78q60 0 175.5 -24t173.5 -24q19 0 57 5t58 5
-q81 0 118 -50.5t37 -134.5q0 -23 -5 -68t-5 -68q0 -13 2 -25t3.5 -16.5t7.5 -20.5t8 -20q16 -40 25 -118.5t9 -136.5z" />
-    <glyph glyph-name="phone" unicode="&#xf095;" horiz-adv-x="1408" 
-d="M1408 296q0 -27 -10 -70.5t-21 -68.5q-21 -50 -122 -106q-94 -51 -186 -51q-27 0 -53 3.5t-57.5 12.5t-47 14.5t-55.5 20.5t-49 18q-98 35 -175 83q-127 79 -264 216t-216 264q-48 77 -83 175q-3 9 -18 49t-20.5 55.5t-14.5 47t-12.5 57.5t-3.5 53q0 92 51 186
-q56 101 106 122q25 11 68.5 21t70.5 10q14 0 21 -3q18 -6 53 -76q11 -19 30 -54t35 -63.5t31 -53.5q3 -4 17.5 -25t21.5 -35.5t7 -28.5q0 -20 -28.5 -50t-62 -55t-62 -53t-28.5 -46q0 -9 5 -22.5t8.5 -20.5t14 -24t11.5 -19q76 -137 174 -235t235 -174q2 -1 19 -11.5t24 -14
-t20.5 -8.5t22.5 -5q18 0 46 28.5t53 62t55 62t50 28.5q14 0 28.5 -7t35.5 -21.5t25 -17.5q25 -15 53.5 -31t63.5 -35t54 -30q70 -35 76 -53q3 -7 3 -21z" />
-    <glyph glyph-name="check_empty" unicode="&#xf096;" horiz-adv-x="1408" 
-d="M1120 1280h-832q-66 0 -113 -47t-47 -113v-832q0 -66 47 -113t113 -47h832q66 0 113 47t47 113v832q0 66 -47 113t-113 47zM1408 1120v-832q0 -119 -84.5 -203.5t-203.5 -84.5h-832q-119 0 -203.5 84.5t-84.5 203.5v832q0 119 84.5 203.5t203.5 84.5h832
-q119 0 203.5 -84.5t84.5 -203.5z" />
-    <glyph glyph-name="bookmark_empty" unicode="&#xf097;" horiz-adv-x="1280" 
-d="M1152 1280h-1024v-1242l423 406l89 85l89 -85l423 -406v1242zM1164 1408q23 0 44 -9q33 -13 52.5 -41t19.5 -62v-1289q0 -34 -19.5 -62t-52.5 -41q-19 -8 -44 -8q-48 0 -83 32l-441 424l-441 -424q-36 -33 -83 -33q-23 0 -44 9q-33 13 -52.5 41t-19.5 62v1289
-q0 34 19.5 62t52.5 41q21 9 44 9h1048z" />
-    <glyph glyph-name="phone_sign" unicode="&#xf098;" 
-d="M1280 343q0 11 -2 16t-18 16.5t-40.5 25t-47.5 26.5t-45.5 25t-28.5 15q-5 3 -19 13t-25 15t-21 5q-15 0 -36.5 -20.5t-39.5 -45t-38.5 -45t-33.5 -20.5q-7 0 -16.5 3.5t-15.5 6.5t-17 9.5t-14 8.5q-99 55 -170 126.5t-127 170.5q-2 3 -8.5 14t-9.5 17t-6.5 15.5
-t-3.5 16.5q0 13 20.5 33.5t45 38.5t45 39.5t20.5 36.5q0 10 -5 21t-15 25t-13 19q-3 6 -15 28.5t-25 45.5t-26.5 47.5t-25 40.5t-16.5 18t-16 2q-48 0 -101 -22q-46 -21 -80 -94.5t-34 -130.5q0 -16 2.5 -34t5 -30.5t9 -33t10 -29.5t12.5 -33t11 -30q60 -164 216.5 -320.5
-t320.5 -216.5q6 -2 30 -11t33 -12.5t29.5 -10t33 -9t30.5 -5t34 -2.5q57 0 130.5 34t94.5 80q22 53 22 101zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z
-" />
-    <glyph glyph-name="twitter" unicode="&#xf099;" horiz-adv-x="1664" 
-d="M1620 1128q-67 -98 -162 -167q1 -14 1 -42q0 -130 -38 -259.5t-115.5 -248.5t-184.5 -210.5t-258 -146t-323 -54.5q-271 0 -496 145q35 -4 78 -4q225 0 401 138q-105 2 -188 64.5t-114 159.5q33 -5 61 -5q43 0 85 11q-112 23 -185.5 111.5t-73.5 205.5v4q68 -38 146 -41
-q-66 44 -105 115t-39 154q0 88 44 163q121 -149 294.5 -238.5t371.5 -99.5q-8 38 -8 74q0 134 94.5 228.5t228.5 94.5q140 0 236 -102q109 21 205 78q-37 -115 -142 -178q93 10 186 50z" />
-    <glyph glyph-name="facebook" unicode="&#xf09a;" horiz-adv-x="1024" 
-d="M959 1524v-264h-157q-86 0 -116 -36t-30 -108v-189h293l-39 -296h-254v-759h-306v759h-255v296h255v218q0 186 104 288.5t277 102.5q147 0 228 -12z" />
-    <glyph glyph-name="github" unicode="&#xf09b;" 
-d="M768 1408q209 0 385.5 -103t279.5 -279.5t103 -385.5q0 -251 -146.5 -451.5t-378.5 -277.5q-27 -5 -40 7t-13 30q0 3 0.5 76.5t0.5 134.5q0 97 -52 142q57 6 102.5 18t94 39t81 66.5t53 105t20.5 150.5q0 119 -79 206q37 91 -8 204q-28 9 -81 -11t-92 -44l-38 -24
-q-93 26 -192 26t-192 -26q-16 11 -42.5 27t-83.5 38.5t-85 13.5q-45 -113 -8 -204q-79 -87 -79 -206q0 -85 20.5 -150t52.5 -105t80.5 -67t94 -39t102.5 -18q-39 -36 -49 -103q-21 -10 -45 -15t-57 -5t-65.5 21.5t-55.5 62.5q-19 32 -48.5 52t-49.5 24l-20 3q-21 0 -29 -4.5
-t-5 -11.5t9 -14t13 -12l7 -5q22 -10 43.5 -38t31.5 -51l10 -23q13 -38 44 -61.5t67 -30t69.5 -7t55.5 3.5l23 4q0 -38 0.5 -88.5t0.5 -54.5q0 -18 -13 -30t-40 -7q-232 77 -378.5 277.5t-146.5 451.5q0 209 103 385.5t279.5 279.5t385.5 103zM291 305q3 7 -7 12
-q-10 3 -13 -2q-3 -7 7 -12q9 -6 13 2zM322 271q7 5 -2 16q-10 9 -16 3q-7 -5 2 -16q10 -10 16 -3zM352 226q9 7 0 19q-8 13 -17 6q-9 -5 0 -18t17 -7zM394 184q8 8 -4 19q-12 12 -20 3q-9 -8 4 -19q12 -12 20 -3zM451 159q3 11 -13 16q-15 4 -19 -7t13 -15q15 -6 19 6z
-M514 154q0 13 -17 11q-16 0 -16 -11q0 -13 17 -11q16 0 16 11zM572 164q-2 11 -18 9q-16 -3 -14 -15t18 -8t14 14z" />
-    <glyph glyph-name="unlock" unicode="&#xf09c;" horiz-adv-x="1664" 
-d="M1664 960v-256q0 -26 -19 -45t-45 -19h-64q-26 0 -45 19t-19 45v256q0 106 -75 181t-181 75t-181 -75t-75 -181v-192h96q40 0 68 -28t28 -68v-576q0 -40 -28 -68t-68 -28h-960q-40 0 -68 28t-28 68v576q0 40 28 68t68 28h672v192q0 185 131.5 316.5t316.5 131.5
-t316.5 -131.5t131.5 -316.5z" />
-    <glyph glyph-name="credit_card" unicode="&#xf09d;" horiz-adv-x="1920" 
-d="M1760 1408q66 0 113 -47t47 -113v-1216q0 -66 -47 -113t-113 -47h-1600q-66 0 -113 47t-47 113v1216q0 66 47 113t113 47h1600zM160 1280q-13 0 -22.5 -9.5t-9.5 -22.5v-224h1664v224q0 13 -9.5 22.5t-22.5 9.5h-1600zM1760 0q13 0 22.5 9.5t9.5 22.5v608h-1664v-608
-q0 -13 9.5 -22.5t22.5 -9.5h1600zM256 128v128h256v-128h-256zM640 128v128h384v-128h-384z" />
-    <glyph glyph-name="rss" unicode="&#xf09e;" horiz-adv-x="1408" 
-d="M384 192q0 -80 -56 -136t-136 -56t-136 56t-56 136t56 136t136 56t136 -56t56 -136zM896 69q2 -28 -17 -48q-18 -21 -47 -21h-135q-25 0 -43 16.5t-20 41.5q-22 229 -184.5 391.5t-391.5 184.5q-25 2 -41.5 20t-16.5 43v135q0 29 21 47q17 17 43 17h5q160 -13 306 -80.5
-t259 -181.5q114 -113 181.5 -259t80.5 -306zM1408 67q2 -27 -18 -47q-18 -20 -46 -20h-143q-26 0 -44.5 17.5t-19.5 42.5q-12 215 -101 408.5t-231.5 336t-336 231.5t-408.5 102q-25 1 -42.5 19.5t-17.5 43.5v143q0 28 20 46q18 18 44 18h3q262 -13 501.5 -120t425.5 -294
-q187 -186 294 -425.5t120 -501.5z" />
-    <glyph glyph-name="hdd" unicode="&#xf0a0;" 
-d="M1040 320q0 -33 -23.5 -56.5t-56.5 -23.5t-56.5 23.5t-23.5 56.5t23.5 56.5t56.5 23.5t56.5 -23.5t23.5 -56.5zM1296 320q0 -33 -23.5 -56.5t-56.5 -23.5t-56.5 23.5t-23.5 56.5t23.5 56.5t56.5 23.5t56.5 -23.5t23.5 -56.5zM1408 160v320q0 13 -9.5 22.5t-22.5 9.5
-h-1216q-13 0 -22.5 -9.5t-9.5 -22.5v-320q0 -13 9.5 -22.5t22.5 -9.5h1216q13 0 22.5 9.5t9.5 22.5zM178 640h1180l-157 482q-4 13 -16 21.5t-26 8.5h-782q-14 0 -26 -8.5t-16 -21.5zM1536 480v-320q0 -66 -47 -113t-113 -47h-1216q-66 0 -113 47t-47 113v320q0 25 16 75
-l197 606q17 53 63 86t101 33h782q55 0 101 -33t63 -86l197 -606q16 -50 16 -75z" />
-    <glyph glyph-name="bullhorn" unicode="&#xf0a1;" horiz-adv-x="1792" 
-d="M1664 896q53 0 90.5 -37.5t37.5 -90.5t-37.5 -90.5t-90.5 -37.5v-384q0 -52 -38 -90t-90 -38q-417 347 -812 380q-58 -19 -91 -66t-31 -100.5t40 -92.5q-20 -33 -23 -65.5t6 -58t33.5 -55t48 -50t61.5 -50.5q-29 -58 -111.5 -83t-168.5 -11.5t-132 55.5q-7 23 -29.5 87.5
-t-32 94.5t-23 89t-15 101t3.5 98.5t22 110.5h-122q-66 0 -113 47t-47 113v192q0 66 47 113t113 47h480q435 0 896 384q52 0 90 -38t38 -90v-384zM1536 292v954q-394 -302 -768 -343v-270q377 -42 768 -341z" />
-    <glyph glyph-name="bell" unicode="&#xf0a2;" horiz-adv-x="1792" 
-d="M912 -160q0 16 -16 16q-59 0 -101.5 42.5t-42.5 101.5q0 16 -16 16t-16 -16q0 -73 51.5 -124.5t124.5 -51.5q16 0 16 16zM246 128h1300q-266 300 -266 832q0 51 -24 105t-69 103t-121.5 80.5t-169.5 31.5t-169.5 -31.5t-121.5 -80.5t-69 -103t-24 -105q0 -532 -266 -832z
-M1728 128q0 -52 -38 -90t-90 -38h-448q0 -106 -75 -181t-181 -75t-181 75t-75 181h-448q-52 0 -90 38t-38 90q50 42 91 88t85 119.5t74.5 158.5t50 206t19.5 260q0 152 117 282.5t307 158.5q-8 19 -8 39q0 40 28 68t68 28t68 -28t28 -68q0 -20 -8 -39q190 -28 307 -158.5
-t117 -282.5q0 -139 19.5 -260t50 -206t74.5 -158.5t85 -119.5t91 -88z" />
-    <glyph glyph-name="certificate" unicode="&#xf0a3;" 
-d="M1376 640l138 -135q30 -28 20 -70q-12 -41 -52 -51l-188 -48l53 -186q12 -41 -19 -70q-29 -31 -70 -19l-186 53l-48 -188q-10 -40 -51 -52q-12 -2 -19 -2q-31 0 -51 22l-135 138l-135 -138q-28 -30 -70 -20q-41 11 -51 52l-48 188l-186 -53q-41 -12 -70 19q-31 29 -19 70
-l53 186l-188 48q-40 10 -52 51q-10 42 20 70l138 135l-138 135q-30 28 -20 70q12 41 52 51l188 48l-53 186q-12 41 19 70q29 31 70 19l186 -53l48 188q10 41 51 51q41 12 70 -19l135 -139l135 139q29 30 70 19q41 -10 51 -51l48 -188l186 53q41 12 70 -19q31 -29 19 -70
-l-53 -186l188 -48q40 -10 52 -51q10 -42 -20 -70z" />
-    <glyph glyph-name="hand_right" unicode="&#xf0a4;" horiz-adv-x="1792" 
-d="M256 192q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1664 768q0 51 -39 89.5t-89 38.5h-576q0 20 15 48.5t33 55t33 68t15 84.5q0 67 -44.5 97.5t-115.5 30.5q-24 0 -90 -139q-24 -44 -37 -65q-40 -64 -112 -145q-71 -81 -101 -106
-q-69 -57 -140 -57h-32v-640h32q72 0 167 -32t193.5 -64t179.5 -32q189 0 189 167q0 26 -5 56q30 16 47.5 52.5t17.5 73.5t-18 69q53 50 53 119q0 25 -10 55.5t-25 47.5h331q52 0 90 38t38 90zM1792 769q0 -105 -75.5 -181t-180.5 -76h-169q-4 -62 -37 -119q3 -21 3 -43
-q0 -101 -60 -178q1 -139 -85 -219.5t-227 -80.5q-133 0 -322 69q-164 59 -223 59h-288q-53 0 -90.5 37.5t-37.5 90.5v640q0 53 37.5 90.5t90.5 37.5h288q10 0 21.5 4.5t23.5 14t22.5 18t24 22.5t20.5 21.5t19 21.5t14 17q65 74 100 129q13 21 33 62t37 72t40.5 63t55 49.5
-t69.5 17.5q125 0 206.5 -67t81.5 -189q0 -68 -22 -128h374q104 0 180 -76t76 -179z" />
-    <glyph glyph-name="hand_left" unicode="&#xf0a5;" horiz-adv-x="1792" 
-d="M1376 128h32v640h-32q-35 0 -67.5 12t-62.5 37t-50 46t-49 54q-8 9 -12 14q-72 81 -112 145q-14 22 -38 68q-1 3 -10.5 22.5t-18.5 36t-20 35.5t-21.5 30.5t-18.5 11.5q-71 0 -115.5 -30.5t-44.5 -97.5q0 -43 15 -84.5t33 -68t33 -55t15 -48.5h-576q-50 0 -89 -38.5
-t-39 -89.5q0 -52 38 -90t90 -38h331q-15 -17 -25 -47.5t-10 -55.5q0 -69 53 -119q-18 -32 -18 -69t17.5 -73.5t47.5 -52.5q-4 -24 -4 -56q0 -85 48.5 -126t135.5 -41q84 0 183 32t194 64t167 32zM1664 192q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45z
-M1792 768v-640q0 -53 -37.5 -90.5t-90.5 -37.5h-288q-59 0 -223 -59q-190 -69 -317 -69q-142 0 -230 77.5t-87 217.5l1 5q-61 76 -61 178q0 22 3 43q-33 57 -37 119h-169q-105 0 -180.5 76t-75.5 181q0 103 76 179t180 76h374q-22 60 -22 128q0 122 81.5 189t206.5 67
-q38 0 69.5 -17.5t55 -49.5t40.5 -63t37 -72t33 -62q35 -55 100 -129q2 -3 14 -17t19 -21.5t20.5 -21.5t24 -22.5t22.5 -18t23.5 -14t21.5 -4.5h288q53 0 90.5 -37.5t37.5 -90.5z" />
-    <glyph glyph-name="hand_up" unicode="&#xf0a6;" 
-d="M1280 -64q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1408 700q0 189 -167 189q-26 0 -56 -5q-16 30 -52.5 47.5t-73.5 17.5t-69 -18q-50 53 -119 53q-25 0 -55.5 -10t-47.5 -25v331q0 52 -38 90t-90 38q-51 0 -89.5 -39t-38.5 -89v-576
-q-20 0 -48.5 15t-55 33t-68 33t-84.5 15q-67 0 -97.5 -44.5t-30.5 -115.5q0 -24 139 -90q44 -24 65 -37q64 -40 145 -112q81 -71 106 -101q57 -69 57 -140v-32h640v32q0 72 32 167t64 193.5t32 179.5zM1536 705q0 -133 -69 -322q-59 -164 -59 -223v-288q0 -53 -37.5 -90.5
-t-90.5 -37.5h-640q-53 0 -90.5 37.5t-37.5 90.5v288q0 10 -4.5 21.5t-14 23.5t-18 22.5t-22.5 24t-21.5 20.5t-21.5 19t-17 14q-74 65 -129 100q-21 13 -62 33t-72 37t-63 40.5t-49.5 55t-17.5 69.5q0 125 67 206.5t189 81.5q68 0 128 -22v374q0 104 76 180t179 76
-q105 0 181 -75.5t76 -180.5v-169q62 -4 119 -37q21 3 43 3q101 0 178 -60q139 1 219.5 -85t80.5 -227z" />
-    <glyph glyph-name="hand_down" unicode="&#xf0a7;" 
-d="M1408 576q0 84 -32 183t-64 194t-32 167v32h-640v-32q0 -35 -12 -67.5t-37 -62.5t-46 -50t-54 -49q-9 -8 -14 -12q-81 -72 -145 -112q-22 -14 -68 -38q-3 -1 -22.5 -10.5t-36 -18.5t-35.5 -20t-30.5 -21.5t-11.5 -18.5q0 -71 30.5 -115.5t97.5 -44.5q43 0 84.5 15t68 33
-t55 33t48.5 15v-576q0 -50 38.5 -89t89.5 -39q52 0 90 38t38 90v331q46 -35 103 -35q69 0 119 53q32 -18 69 -18t73.5 17.5t52.5 47.5q24 -4 56 -4q85 0 126 48.5t41 135.5zM1280 1344q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1536 580
-q0 -142 -77.5 -230t-217.5 -87l-5 1q-76 -61 -178 -61q-22 0 -43 3q-54 -30 -119 -37v-169q0 -105 -76 -180.5t-181 -75.5q-103 0 -179 76t-76 180v374q-54 -22 -128 -22q-121 0 -188.5 81.5t-67.5 206.5q0 38 17.5 69.5t49.5 55t63 40.5t72 37t62 33q55 35 129 100
-q3 2 17 14t21.5 19t21.5 20.5t22.5 24t18 22.5t14 23.5t4.5 21.5v288q0 53 37.5 90.5t90.5 37.5h640q53 0 90.5 -37.5t37.5 -90.5v-288q0 -59 59 -223q69 -190 69 -317z" />
-    <glyph glyph-name="circle_arrow_left" unicode="&#xf0a8;" 
-d="M1280 576v128q0 26 -19 45t-45 19h-502l189 189q19 19 19 45t-19 45l-91 91q-18 18 -45 18t-45 -18l-362 -362l-91 -91q-18 -18 -18 -45t18 -45l91 -91l362 -362q18 -18 45 -18t45 18l91 91q18 18 18 45t-18 45l-189 189h502q26 0 45 19t19 45zM1536 640
-q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
-    <glyph glyph-name="circle_arrow_right" unicode="&#xf0a9;" 
-d="M1285 640q0 27 -18 45l-91 91l-362 362q-18 18 -45 18t-45 -18l-91 -91q-18 -18 -18 -45t18 -45l189 -189h-502q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45t45 -19h502l-189 -189q-19 -19 -19 -45t19 -45l91 -91q18 -18 45 -18t45 18l362 362l91 91q18 18 18 45zM1536 640
-q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
-    <glyph glyph-name="circle_arrow_up" unicode="&#xf0aa;" 
-d="M1284 641q0 27 -18 45l-362 362l-91 91q-18 18 -45 18t-45 -18l-91 -91l-362 -362q-18 -18 -18 -45t18 -45l91 -91q18 -18 45 -18t45 18l189 189v-502q0 -26 19 -45t45 -19h128q26 0 45 19t19 45v502l189 -189q19 -19 45 -19t45 19l91 91q18 18 18 45zM1536 640
-q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
-    <glyph glyph-name="circle_arrow_down" unicode="&#xf0ab;" 
-d="M1284 639q0 27 -18 45l-91 91q-18 18 -45 18t-45 -18l-189 -189v502q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-502l-189 189q-19 19 -45 19t-45 -19l-91 -91q-18 -18 -18 -45t18 -45l362 -362l91 -91q18 -18 45 -18t45 18l91 91l362 362q18 18 18 45zM1536 640
-q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
-    <glyph glyph-name="globe" unicode="&#xf0ac;" 
-d="M768 1408q209 0 385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103zM1042 887q-2 -1 -9.5 -9.5t-13.5 -9.5q2 0 4.5 5t5 11t3.5 7q6 7 22 15q14 6 52 12q34 8 51 -11
-q-2 2 9.5 13t14.5 12q3 2 15 4.5t15 7.5l2 22q-12 -1 -17.5 7t-6.5 21q0 -2 -6 -8q0 7 -4.5 8t-11.5 -1t-9 -1q-10 3 -15 7.5t-8 16.5t-4 15q-2 5 -9.5 11t-9.5 10q-1 2 -2.5 5.5t-3 6.5t-4 5.5t-5.5 2.5t-7 -5t-7.5 -10t-4.5 -5q-3 2 -6 1.5t-4.5 -1t-4.5 -3t-5 -3.5
-q-3 -2 -8.5 -3t-8.5 -2q15 5 -1 11q-10 4 -16 3q9 4 7.5 12t-8.5 14h5q-1 4 -8.5 8.5t-17.5 8.5t-13 6q-8 5 -34 9.5t-33 0.5q-5 -6 -4.5 -10.5t4 -14t3.5 -12.5q1 -6 -5.5 -13t-6.5 -12q0 -7 14 -15.5t10 -21.5q-3 -8 -16 -16t-16 -12q-5 -8 -1.5 -18.5t10.5 -16.5
-q2 -2 1.5 -4t-3.5 -4.5t-5.5 -4t-6.5 -3.5l-3 -2q-11 -5 -20.5 6t-13.5 26q-7 25 -16 30q-23 8 -29 -1q-5 13 -41 26q-25 9 -58 4q6 1 0 15q-7 15 -19 12q3 6 4 17.5t1 13.5q3 13 12 23q1 1 7 8.5t9.5 13.5t0.5 6q35 -4 50 11q5 5 11.5 17t10.5 17q9 6 14 5.5t14.5 -5.5
-t14.5 -5q14 -1 15.5 11t-7.5 20q12 -1 3 17q-4 7 -8 9q-12 4 -27 -5q-8 -4 2 -8q-1 1 -9.5 -10.5t-16.5 -17.5t-16 5q-1 1 -5.5 13.5t-9.5 13.5q-8 0 -16 -15q3 8 -11 15t-24 8q19 12 -8 27q-7 4 -20.5 5t-19.5 -4q-5 -7 -5.5 -11.5t5 -8t10.5 -5.5t11.5 -4t8.5 -3
-q14 -10 8 -14q-2 -1 -8.5 -3.5t-11.5 -4.5t-6 -4q-3 -4 0 -14t-2 -14q-5 5 -9 17.5t-7 16.5q7 -9 -25 -6l-10 1q-4 0 -16 -2t-20.5 -1t-13.5 8q-4 8 0 20q1 4 4 2q-4 3 -11 9.5t-10 8.5q-46 -15 -94 -41q6 -1 12 1q5 2 13 6.5t10 5.5q34 14 42 7l5 5q14 -16 20 -25
-q-7 4 -30 1q-20 -6 -22 -12q7 -12 5 -18q-4 3 -11.5 10t-14.5 11t-15 5q-16 0 -22 -1q-146 -80 -235 -222q7 -7 12 -8q4 -1 5 -9t2.5 -11t11.5 3q9 -8 3 -19q1 1 44 -27q19 -17 21 -21q3 -11 -10 -18q-1 2 -9 9t-9 4q-3 -5 0.5 -18.5t10.5 -12.5q-7 0 -9.5 -16t-2.5 -35.5
-t-1 -23.5l2 -1q-3 -12 5.5 -34.5t21.5 -19.5q-13 -3 20 -43q6 -8 8 -9q3 -2 12 -7.5t15 -10t10 -10.5q4 -5 10 -22.5t14 -23.5q-2 -6 9.5 -20t10.5 -23q-1 0 -2.5 -1t-2.5 -1q3 -7 15.5 -14t15.5 -13q1 -3 2 -10t3 -11t8 -2q2 20 -24 62q-15 25 -17 29q-3 5 -5.5 15.5
-t-4.5 14.5q2 0 6 -1.5t8.5 -3.5t7.5 -4t2 -3q-3 -7 2 -17.5t12 -18.5t17 -19t12 -13q6 -6 14 -19.5t0 -13.5q9 0 20 -10.5t17 -19.5q5 -8 8 -26t5 -24q2 -7 8.5 -13.5t12.5 -9.5l16 -8t13 -7q5 -2 18.5 -10.5t21.5 -11.5q10 -4 16 -4t14.5 2.5t13.5 3.5q15 2 29 -15t21 -21
-q36 -19 55 -11q-2 -1 0.5 -7.5t8 -15.5t9 -14.5t5.5 -8.5q5 -6 18 -15t18 -15q6 4 7 9q-3 -8 7 -20t18 -10q14 3 14 32q-31 -15 -49 18q0 1 -2.5 5.5t-4 8.5t-2.5 8.5t0 7.5t5 3q9 0 10 3.5t-2 12.5t-4 13q-1 8 -11 20t-12 15q-5 -9 -16 -8t-16 9q0 -1 -1.5 -5.5t-1.5 -6.5
-q-13 0 -15 1q1 3 2.5 17.5t3.5 22.5q1 4 5.5 12t7.5 14.5t4 12.5t-4.5 9.5t-17.5 2.5q-19 -1 -26 -20q-1 -3 -3 -10.5t-5 -11.5t-9 -7q-7 -3 -24 -2t-24 5q-13 8 -22.5 29t-9.5 37q0 10 2.5 26.5t3 25t-5.5 24.5q3 2 9 9.5t10 10.5q2 1 4.5 1.5t4.5 0t4 1.5t3 6q-1 1 -4 3
-q-3 3 -4 3q7 -3 28.5 1.5t27.5 -1.5q15 -11 22 2q0 1 -2.5 9.5t-0.5 13.5q5 -27 29 -9q3 -3 15.5 -5t17.5 -5q3 -2 7 -5.5t5.5 -4.5t5 0.5t8.5 6.5q10 -14 12 -24q11 -40 19 -44q7 -3 11 -2t4.5 9.5t0 14t-1.5 12.5l-1 8v18l-1 8q-15 3 -18.5 12t1.5 18.5t15 18.5q1 1 8 3.5
-t15.5 6.5t12.5 8q21 19 15 35q7 0 11 9q-1 0 -5 3t-7.5 5t-4.5 2q9 5 2 16q5 3 7.5 11t7.5 10q9 -12 21 -2q8 8 1 16q5 7 20.5 10.5t18.5 9.5q7 -2 8 2t1 12t3 12q4 5 15 9t13 5l17 11q3 4 0 4q18 -2 31 11q10 11 -6 20q3 6 -3 9.5t-15 5.5q3 1 11.5 0.5t10.5 1.5
-q15 10 -7 16q-17 5 -43 -12zM879 10q206 36 351 189q-3 3 -12.5 4.5t-12.5 3.5q-18 7 -24 8q1 7 -2.5 13t-8 9t-12.5 8t-11 7q-2 2 -7 6t-7 5.5t-7.5 4.5t-8.5 2t-10 -1l-3 -1q-3 -1 -5.5 -2.5t-5.5 -3t-4 -3t0 -2.5q-21 17 -36 22q-5 1 -11 5.5t-10.5 7t-10 1.5t-11.5 -7
-q-5 -5 -6 -15t-2 -13q-7 5 0 17.5t2 18.5q-3 6 -10.5 4.5t-12 -4.5t-11.5 -8.5t-9 -6.5t-8.5 -5.5t-8.5 -7.5q-3 -4 -6 -12t-5 -11q-2 4 -11.5 6.5t-9.5 5.5q2 -10 4 -35t5 -38q7 -31 -12 -48q-27 -25 -29 -40q-4 -22 12 -26q0 -7 -8 -20.5t-7 -21.5q0 -6 2 -16z" />
-    <glyph glyph-name="wrench" unicode="&#xf0ad;" horiz-adv-x="1664" 
-d="M384 64q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1028 484l-682 -682q-37 -37 -90 -37q-52 0 -91 37l-106 108q-38 36 -38 90q0 53 38 91l681 681q39 -98 114.5 -173.5t173.5 -114.5zM1662 919q0 -39 -23 -106q-47 -134 -164.5 -217.5
-t-258.5 -83.5q-185 0 -316.5 131.5t-131.5 316.5t131.5 316.5t316.5 131.5q58 0 121.5 -16.5t107.5 -46.5q16 -11 16 -28t-16 -28l-293 -169v-224l193 -107q5 3 79 48.5t135.5 81t70.5 35.5q15 0 23.5 -10t8.5 -25z" />
-    <glyph glyph-name="tasks" unicode="&#xf0ae;" horiz-adv-x="1792" 
-d="M1024 128h640v128h-640v-128zM640 640h1024v128h-1024v-128zM1280 1152h384v128h-384v-128zM1792 320v-256q0 -26 -19 -45t-45 -19h-1664q-26 0 -45 19t-19 45v256q0 26 19 45t45 19h1664q26 0 45 -19t19 -45zM1792 832v-256q0 -26 -19 -45t-45 -19h-1664q-26 0 -45 19
-t-19 45v256q0 26 19 45t45 19h1664q26 0 45 -19t19 -45zM1792 1344v-256q0 -26 -19 -45t-45 -19h-1664q-26 0 -45 19t-19 45v256q0 26 19 45t45 19h1664q26 0 45 -19t19 -45z" />
-    <glyph glyph-name="filter" unicode="&#xf0b0;" horiz-adv-x="1408" 
-d="M1403 1241q17 -41 -14 -70l-493 -493v-742q0 -42 -39 -59q-13 -5 -25 -5q-27 0 -45 19l-256 256q-19 19 -19 45v486l-493 493q-31 29 -14 70q17 39 59 39h1280q42 0 59 -39z" />
-    <glyph glyph-name="briefcase" unicode="&#xf0b1;" horiz-adv-x="1792" 
-d="M640 1280h512v128h-512v-128zM1792 640v-480q0 -66 -47 -113t-113 -47h-1472q-66 0 -113 47t-47 113v480h672v-160q0 -26 19 -45t45 -19h320q26 0 45 19t19 45v160h672zM1024 640v-128h-256v128h256zM1792 1120v-384h-1792v384q0 66 47 113t113 47h352v160q0 40 28 68
-t68 28h576q40 0 68 -28t28 -68v-160h352q66 0 113 -47t47 -113z" />
-    <glyph glyph-name="fullscreen" unicode="&#xf0b2;" 
-d="M1283 995l-355 -355l355 -355l144 144q29 31 70 14q39 -17 39 -59v-448q0 -26 -19 -45t-45 -19h-448q-42 0 -59 40q-17 39 14 69l144 144l-355 355l-355 -355l144 -144q31 -30 14 -69q-17 -40 -59 -40h-448q-26 0 -45 19t-19 45v448q0 42 40 59q39 17 69 -14l144 -144
-l355 355l-355 355l-144 -144q-19 -19 -45 -19q-12 0 -24 5q-40 17 -40 59v448q0 26 19 45t45 19h448q42 0 59 -40q17 -39 -14 -69l-144 -144l355 -355l355 355l-144 144q-31 30 -14 69q17 40 59 40h448q26 0 45 -19t19 -45v-448q0 -42 -39 -59q-13 -5 -25 -5q-26 0 -45 19z
-" />
-    <glyph glyph-name="group" unicode="&#xf0c0;" horiz-adv-x="1920" 
-d="M593 640q-162 -5 -265 -128h-134q-82 0 -138 40.5t-56 118.5q0 353 124 353q6 0 43.5 -21t97.5 -42.5t119 -21.5q67 0 133 23q-5 -37 -5 -66q0 -139 81 -256zM1664 3q0 -120 -73 -189.5t-194 -69.5h-874q-121 0 -194 69.5t-73 189.5q0 53 3.5 103.5t14 109t26.5 108.5
-t43 97.5t62 81t85.5 53.5t111.5 20q10 0 43 -21.5t73 -48t107 -48t135 -21.5t135 21.5t107 48t73 48t43 21.5q61 0 111.5 -20t85.5 -53.5t62 -81t43 -97.5t26.5 -108.5t14 -109t3.5 -103.5zM640 1280q0 -106 -75 -181t-181 -75t-181 75t-75 181t75 181t181 75t181 -75
-t75 -181zM1344 896q0 -159 -112.5 -271.5t-271.5 -112.5t-271.5 112.5t-112.5 271.5t112.5 271.5t271.5 112.5t271.5 -112.5t112.5 -271.5zM1920 671q0 -78 -56 -118.5t-138 -40.5h-134q-103 123 -265 128q81 117 81 256q0 29 -5 66q66 -23 133 -23q59 0 119 21.5t97.5 42.5
-t43.5 21q124 0 124 -353zM1792 1280q0 -106 -75 -181t-181 -75t-181 75t-75 181t75 181t181 75t181 -75t75 -181z" />
-    <glyph glyph-name="link" unicode="&#xf0c1;" horiz-adv-x="1664" 
-d="M1456 320q0 40 -28 68l-208 208q-28 28 -68 28q-42 0 -72 -32q3 -3 19 -18.5t21.5 -21.5t15 -19t13 -25.5t3.5 -27.5q0 -40 -28 -68t-68 -28q-15 0 -27.5 3.5t-25.5 13t-19 15t-21.5 21.5t-18.5 19q-33 -31 -33 -73q0 -40 28 -68l206 -207q27 -27 68 -27q40 0 68 26
-l147 146q28 28 28 67zM753 1025q0 40 -28 68l-206 207q-28 28 -68 28q-39 0 -68 -27l-147 -146q-28 -28 -28 -67q0 -40 28 -68l208 -208q27 -27 68 -27q42 0 72 31q-3 3 -19 18.5t-21.5 21.5t-15 19t-13 25.5t-3.5 27.5q0 40 28 68t68 28q15 0 27.5 -3.5t25.5 -13t19 -15
-t21.5 -21.5t18.5 -19q33 31 33 73zM1648 320q0 -120 -85 -203l-147 -146q-83 -83 -203 -83q-121 0 -204 85l-206 207q-83 83 -83 203q0 123 88 209l-88 88q-86 -88 -208 -88q-120 0 -204 84l-208 208q-84 84 -84 204t85 203l147 146q83 83 203 83q121 0 204 -85l206 -207
-q83 -83 83 -203q0 -123 -88 -209l88 -88q86 88 208 88q120 0 204 -84l208 -208q84 -84 84 -204z" />
-    <glyph glyph-name="cloud" unicode="&#xf0c2;" horiz-adv-x="1920" 
-d="M1920 384q0 -159 -112.5 -271.5t-271.5 -112.5h-1088q-185 0 -316.5 131.5t-131.5 316.5q0 132 71 241.5t187 163.5q-2 28 -2 43q0 212 150 362t362 150q158 0 286.5 -88t187.5 -230q70 62 166 62q106 0 181 -75t75 -181q0 -75 -41 -138q129 -30 213 -134.5t84 -239.5z
-" />
-    <glyph glyph-name="beaker" unicode="&#xf0c3;" horiz-adv-x="1664" 
-d="M1527 88q56 -89 21.5 -152.5t-140.5 -63.5h-1152q-106 0 -140.5 63.5t21.5 152.5l503 793v399h-64q-26 0 -45 19t-19 45t19 45t45 19h512q26 0 45 -19t19 -45t-19 -45t-45 -19h-64v-399zM748 813l-272 -429h712l-272 429l-20 31v37v399h-128v-399v-37z" />
-    <glyph glyph-name="cut" unicode="&#xf0c4;" horiz-adv-x="1792" 
-d="M960 640q26 0 45 -19t19 -45t-19 -45t-45 -19t-45 19t-19 45t19 45t45 19zM1260 576l507 -398q28 -20 25 -56q-5 -35 -35 -51l-128 -64q-13 -7 -29 -7q-17 0 -31 8l-690 387l-110 -66q-8 -4 -12 -5q14 -49 10 -97q-7 -77 -56 -147.5t-132 -123.5q-132 -84 -277 -84
-q-136 0 -222 78q-90 84 -79 207q7 76 56 147t131 124q132 84 278 84q83 0 151 -31q9 13 22 22l122 73l-122 73q-13 9 -22 22q-68 -31 -151 -31q-146 0 -278 84q-82 53 -131 124t-56 147q-5 59 15.5 113t63.5 93q85 79 222 79q145 0 277 -84q83 -52 132 -123t56 -148
-q4 -48 -10 -97q4 -1 12 -5l110 -66l690 387q14 8 31 8q16 0 29 -7l128 -64q30 -16 35 -51q3 -36 -25 -56zM579 836q46 42 21 108t-106 117q-92 59 -192 59q-74 0 -113 -36q-46 -42 -21 -108t106 -117q92 -59 192 -59q74 0 113 36zM494 91q81 51 106 117t-21 108
-q-39 36 -113 36q-100 0 -192 -59q-81 -51 -106 -117t21 -108q39 -36 113 -36q100 0 192 59zM672 704l96 -58v11q0 36 33 56l14 8l-79 47l-26 -26q-3 -3 -10 -11t-12 -12q-2 -2 -4 -3.5t-3 -2.5zM896 480l96 -32l736 576l-128 64l-768 -431v-113l-160 -96l9 -8q2 -2 7 -6
-q4 -4 11 -12t11 -12l26 -26zM1600 64l128 64l-520 408l-177 -138q-2 -3 -13 -7z" />
-    <glyph glyph-name="copy" unicode="&#xf0c5;" horiz-adv-x="1792" 
-d="M1696 1152q40 0 68 -28t28 -68v-1216q0 -40 -28 -68t-68 -28h-960q-40 0 -68 28t-28 68v288h-544q-40 0 -68 28t-28 68v672q0 40 20 88t48 76l408 408q28 28 76 48t88 20h416q40 0 68 -28t28 -68v-328q68 40 128 40h416zM1152 939l-299 -299h299v299zM512 1323l-299 -299
-h299v299zM708 676l316 316v416h-384v-416q0 -40 -28 -68t-68 -28h-416v-640h512v256q0 40 20 88t48 76zM1664 -128v1152h-384v-416q0 -40 -28 -68t-68 -28h-416v-640h896z" />
-    <glyph glyph-name="paper_clip" unicode="&#xf0c6;" horiz-adv-x="1408" 
-d="M1404 151q0 -117 -79 -196t-196 -79q-135 0 -235 100l-777 776q-113 115 -113 271q0 159 110 270t269 111q158 0 273 -113l605 -606q10 -10 10 -22q0 -16 -30.5 -46.5t-46.5 -30.5q-13 0 -23 10l-606 607q-79 77 -181 77q-106 0 -179 -75t-73 -181q0 -105 76 -181
-l776 -777q63 -63 145 -63q64 0 106 42t42 106q0 82 -63 145l-581 581q-26 24 -60 24q-29 0 -48 -19t-19 -48q0 -32 25 -59l410 -410q10 -10 10 -22q0 -16 -31 -47t-47 -31q-12 0 -22 10l-410 410q-63 61 -63 149q0 82 57 139t139 57q88 0 149 -63l581 -581q100 -98 100 -235
-z" />
-    <glyph glyph-name="save" unicode="&#xf0c7;" 
-d="M384 0h768v384h-768v-384zM1280 0h128v896q0 14 -10 38.5t-20 34.5l-281 281q-10 10 -34 20t-39 10v-416q0 -40 -28 -68t-68 -28h-576q-40 0 -68 28t-28 68v416h-128v-1280h128v416q0 40 28 68t68 28h832q40 0 68 -28t28 -68v-416zM896 928v320q0 13 -9.5 22.5t-22.5 9.5
-h-192q-13 0 -22.5 -9.5t-9.5 -22.5v-320q0 -13 9.5 -22.5t22.5 -9.5h192q13 0 22.5 9.5t9.5 22.5zM1536 896v-928q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68v1344q0 40 28 68t68 28h928q40 0 88 -20t76 -48l280 -280q28 -28 48 -76t20 -88z" />
-    <glyph glyph-name="sign_blank" unicode="&#xf0c8;" 
-d="M1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
-    <glyph glyph-name="reorder" unicode="&#xf0c9;" 
-d="M1536 192v-128q0 -26 -19 -45t-45 -19h-1408q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1408q26 0 45 -19t19 -45zM1536 704v-128q0 -26 -19 -45t-45 -19h-1408q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1408q26 0 45 -19t19 -45zM1536 1216v-128q0 -26 -19 -45
-t-45 -19h-1408q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1408q26 0 45 -19t19 -45z" />
-    <glyph glyph-name="ul" unicode="&#xf0ca;" horiz-adv-x="1792" 
-d="M384 128q0 -80 -56 -136t-136 -56t-136 56t-56 136t56 136t136 56t136 -56t56 -136zM384 640q0 -80 -56 -136t-136 -56t-136 56t-56 136t56 136t136 56t136 -56t56 -136zM1792 224v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1216q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5
-t22.5 9.5h1216q13 0 22.5 -9.5t9.5 -22.5zM384 1152q0 -80 -56 -136t-136 -56t-136 56t-56 136t56 136t136 56t136 -56t56 -136zM1792 736v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1216q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1216q13 0 22.5 -9.5t9.5 -22.5z
-M1792 1248v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1216q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1216q13 0 22.5 -9.5t9.5 -22.5z" />
-    <glyph glyph-name="ol" unicode="&#xf0cb;" horiz-adv-x="1792" 
-d="M381 -84q0 -80 -54.5 -126t-135.5 -46q-106 0 -172 66l57 88q49 -45 106 -45q29 0 50.5 14.5t21.5 42.5q0 64 -105 56l-26 56q8 10 32.5 43.5t42.5 54t37 38.5v1q-16 0 -48.5 -1t-48.5 -1v-53h-106v152h333v-88l-95 -115q51 -12 81 -49t30 -88zM383 543v-159h-362
-q-6 36 -6 54q0 51 23.5 93t56.5 68t66 47.5t56.5 43.5t23.5 45q0 25 -14.5 38.5t-39.5 13.5q-46 0 -81 -58l-85 59q24 51 71.5 79.5t105.5 28.5q73 0 123 -41.5t50 -112.5q0 -50 -34 -91.5t-75 -64.5t-75.5 -50.5t-35.5 -52.5h127v60h105zM1792 224v-192q0 -13 -9.5 -22.5
-t-22.5 -9.5h-1216q-13 0 -22.5 9.5t-9.5 22.5v192q0 14 9 23t23 9h1216q13 0 22.5 -9.5t9.5 -22.5zM384 1123v-99h-335v99h107q0 41 0.5 121.5t0.5 121.5v12h-2q-8 -17 -50 -54l-71 76l136 127h106v-404h108zM1792 736v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1216
-q-13 0 -22.5 9.5t-9.5 22.5v192q0 14 9 23t23 9h1216q13 0 22.5 -9.5t9.5 -22.5zM1792 1248v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1216q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1216q13 0 22.5 -9.5t9.5 -22.5z" />
-    <glyph glyph-name="strikethrough" unicode="&#xf0cc;" horiz-adv-x="1792" 
-d="M1760 640q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-1728q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h1728zM483 704q-28 35 -51 80q-48 98 -48 188q0 181 134 309q133 127 393 127q50 0 167 -19q66 -12 177 -48q10 -38 21 -118q14 -123 14 -183q0 -18 -5 -45l-12 -3l-84 6
-l-14 2q-50 149 -103 205q-88 91 -210 91q-114 0 -182 -59q-67 -58 -67 -146q0 -73 66 -140t279 -129q69 -20 173 -66q58 -28 95 -52h-743zM990 448h411q7 -39 7 -92q0 -111 -41 -212q-23 -56 -71 -104q-37 -35 -109 -81q-80 -48 -153 -66q-80 -21 -203 -21q-114 0 -195 23
-l-140 40q-57 16 -72 28q-8 8 -8 22v13q0 108 -2 156q-1 30 0 68l2 37v44l102 2q15 -34 30 -71t22.5 -56t12.5 -27q35 -57 80 -94q43 -36 105 -57q59 -22 132 -22q64 0 139 27q77 26 122 86q47 61 47 129q0 84 -81 157q-34 29 -137 71z" />
-    <glyph glyph-name="underline" unicode="&#xf0cd;" 
-d="M48 1313q-37 2 -45 4l-3 88q13 1 40 1q60 0 112 -4q132 -7 166 -7q86 0 168 3q116 4 146 5q56 0 86 2l-1 -14l2 -64v-9q-60 -9 -124 -9q-60 0 -79 -25q-13 -14 -13 -132q0 -13 0.5 -32.5t0.5 -25.5l1 -229l14 -280q6 -124 51 -202q35 -59 96 -92q88 -47 177 -47
-q104 0 191 28q56 18 99 51q48 36 65 64q36 56 53 114q21 73 21 229q0 79 -3.5 128t-11 122.5t-13.5 159.5l-4 59q-5 67 -24 88q-34 35 -77 34l-100 -2l-14 3l2 86h84l205 -10q76 -3 196 10l18 -2q6 -38 6 -51q0 -7 -4 -31q-45 -12 -84 -13q-73 -11 -79 -17q-15 -15 -15 -41
-q0 -7 1.5 -27t1.5 -31q8 -19 22 -396q6 -195 -15 -304q-15 -76 -41 -122q-38 -65 -112 -123q-75 -57 -182 -89q-109 -33 -255 -33q-167 0 -284 46q-119 47 -179 122q-61 76 -83 195q-16 80 -16 237v333q0 188 -17 213q-25 36 -147 39zM1536 -96v64q0 14 -9 23t-23 9h-1472
-q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h1472q14 0 23 9t9 23z" />
-    <glyph glyph-name="table" unicode="&#xf0ce;" horiz-adv-x="1664" 
-d="M512 160v192q0 14 -9 23t-23 9h-320q-14 0 -23 -9t-9 -23v-192q0 -14 9 -23t23 -9h320q14 0 23 9t9 23zM512 544v192q0 14 -9 23t-23 9h-320q-14 0 -23 -9t-9 -23v-192q0 -14 9 -23t23 -9h320q14 0 23 9t9 23zM1024 160v192q0 14 -9 23t-23 9h-320q-14 0 -23 -9t-9 -23
-v-192q0 -14 9 -23t23 -9h320q14 0 23 9t9 23zM512 928v192q0 14 -9 23t-23 9h-320q-14 0 -23 -9t-9 -23v-192q0 -14 9 -23t23 -9h320q14 0 23 9t9 23zM1024 544v192q0 14 -9 23t-23 9h-320q-14 0 -23 -9t-9 -23v-192q0 -14 9 -23t23 -9h320q14 0 23 9t9 23zM1536 160v192
-q0 14 -9 23t-23 9h-320q-14 0 -23 -9t-9 -23v-192q0 -14 9 -23t23 -9h320q14 0 23 9t9 23zM1024 928v192q0 14 -9 23t-23 9h-320q-14 0 -23 -9t-9 -23v-192q0 -14 9 -23t23 -9h320q14 0 23 9t9 23zM1536 544v192q0 14 -9 23t-23 9h-320q-14 0 -23 -9t-9 -23v-192
-q0 -14 9 -23t23 -9h320q14 0 23 9t9 23zM1536 928v192q0 14 -9 23t-23 9h-320q-14 0 -23 -9t-9 -23v-192q0 -14 9 -23t23 -9h320q14 0 23 9t9 23zM1664 1248v-1088q0 -66 -47 -113t-113 -47h-1344q-66 0 -113 47t-47 113v1088q0 66 47 113t113 47h1344q66 0 113 -47t47 -113
-z" />
-    <glyph glyph-name="magic" unicode="&#xf0d0;" horiz-adv-x="1664" 
-d="M1190 955l293 293l-107 107l-293 -293zM1637 1248q0 -27 -18 -45l-1286 -1286q-18 -18 -45 -18t-45 18l-198 198q-18 18 -18 45t18 45l1286 1286q18 18 45 18t45 -18l198 -198q18 -18 18 -45zM286 1438l98 -30l-98 -30l-30 -98l-30 98l-98 30l98 30l30 98zM636 1276
-l196 -60l-196 -60l-60 -196l-60 196l-196 60l196 60l60 196zM1566 798l98 -30l-98 -30l-30 -98l-30 98l-98 30l98 30l30 98zM926 1438l98 -30l-98 -30l-30 -98l-30 98l-98 30l98 30l30 98z" />
-    <glyph glyph-name="truck" unicode="&#xf0d1;" horiz-adv-x="1792" 
-d="M640 128q0 52 -38 90t-90 38t-90 -38t-38 -90t38 -90t90 -38t90 38t38 90zM256 640h384v256h-158q-13 0 -22 -9l-195 -195q-9 -9 -9 -22v-30zM1536 128q0 52 -38 90t-90 38t-90 -38t-38 -90t38 -90t90 -38t90 38t38 90zM1792 1216v-1024q0 -15 -4 -26.5t-13.5 -18.5
-t-16.5 -11.5t-23.5 -6t-22.5 -2t-25.5 0t-22.5 0.5q0 -106 -75 -181t-181 -75t-181 75t-75 181h-384q0 -106 -75 -181t-181 -75t-181 75t-75 181h-64q-3 0 -22.5 -0.5t-25.5 0t-22.5 2t-23.5 6t-16.5 11.5t-13.5 18.5t-4 26.5q0 26 19 45t45 19v320q0 8 -0.5 35t0 38
-t2.5 34.5t6.5 37t14 30.5t22.5 30l198 198q19 19 50.5 32t58.5 13h160v192q0 26 19 45t45 19h1024q26 0 45 -19t19 -45z" />
-    <glyph glyph-name="pinterest" unicode="&#xf0d2;" 
-d="M1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103q-111 0 -218 32q59 93 78 164q9 34 54 211q20 -39 73 -67.5t114 -28.5q121 0 216 68.5t147 188.5t52 270q0 114 -59.5 214t-172.5 163t-255 63q-105 0 -196 -29t-154.5 -77t-109 -110.5t-67 -129.5t-21.5 -134
-q0 -104 40 -183t117 -111q30 -12 38 20q2 7 8 31t8 30q6 23 -11 43q-51 61 -51 151q0 151 104.5 259.5t273.5 108.5q151 0 235.5 -82t84.5 -213q0 -170 -68.5 -289t-175.5 -119q-61 0 -98 43.5t-23 104.5q8 35 26.5 93.5t30 103t11.5 75.5q0 50 -27 83t-77 33
-q-62 0 -105 -57t-43 -142q0 -73 25 -122l-99 -418q-17 -70 -13 -177q-206 91 -333 281t-127 423q0 209 103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
-    <glyph glyph-name="pinterest_sign" unicode="&#xf0d3;" 
-d="M1248 1408q119 0 203.5 -84.5t84.5 -203.5v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-725q85 122 108 210q9 34 53 209q21 -39 73.5 -67t112.5 -28q181 0 295.5 147.5t114.5 373.5q0 84 -35 162.5t-96.5 139t-152.5 97t-197 36.5q-104 0 -194.5 -28.5t-153 -76.5
-t-107.5 -109.5t-66.5 -128t-21.5 -132.5q0 -102 39.5 -180t116.5 -110q13 -5 23.5 0t14.5 19q10 44 15 61q6 23 -11 42q-50 62 -50 150q0 150 103.5 256.5t270.5 106.5q149 0 232.5 -81t83.5 -210q0 -168 -67.5 -286t-173.5 -118q-60 0 -97 43.5t-23 103.5q8 34 26.5 92.5
-t29.5 102t11 74.5q0 49 -26.5 81.5t-75.5 32.5q-61 0 -103.5 -56.5t-42.5 -139.5q0 -72 24 -121l-98 -414q-24 -100 -7 -254h-183q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960z" />
-    <glyph glyph-name="google_plus_sign" unicode="&#xf0d4;" 
-d="M917 631q0 26 -6 64h-362v-132h217q-3 -24 -16.5 -50t-37.5 -53t-66.5 -44.5t-96.5 -17.5q-99 0 -169 71t-70 171t70 171t169 71q92 0 153 -59l104 101q-108 100 -257 100q-160 0 -272 -112.5t-112 -271.5t112 -271.5t272 -112.5q165 0 266.5 105t101.5 270zM1262 585
-h109v110h-109v110h-110v-110h-110v-110h110v-110h110v110zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
-    <glyph glyph-name="google_plus" unicode="&#xf0d5;" horiz-adv-x="2304" 
-d="M1437 623q0 -208 -87 -370.5t-248 -254t-369 -91.5q-149 0 -285 58t-234 156t-156 234t-58 285t58 285t156 234t234 156t285 58q286 0 491 -192l-199 -191q-117 113 -292 113q-123 0 -227.5 -62t-165.5 -168.5t-61 -232.5t61 -232.5t165.5 -168.5t227.5 -62
-q83 0 152.5 23t114.5 57.5t78.5 78.5t49 83t21.5 74h-416v252h692q12 -63 12 -122zM2304 745v-210h-209v-209h-210v209h-209v210h209v209h210v-209h209z" />
-    <glyph glyph-name="money" unicode="&#xf0d6;" horiz-adv-x="1920" 
-d="M768 384h384v96h-128v448h-114l-148 -137l77 -80q42 37 55 57h2v-288h-128v-96zM1280 640q0 -70 -21 -142t-59.5 -134t-101.5 -101t-138 -39t-138 39t-101.5 101t-59.5 134t-21 142t21 142t59.5 134t101.5 101t138 39t138 -39t101.5 -101t59.5 -134t21 -142zM1792 384
-v512q-106 0 -181 75t-75 181h-1152q0 -106 -75 -181t-181 -75v-512q106 0 181 -75t75 -181h1152q0 106 75 181t181 75zM1920 1216v-1152q0 -26 -19 -45t-45 -19h-1792q-26 0 -45 19t-19 45v1152q0 26 19 45t45 19h1792q26 0 45 -19t19 -45z" />
-    <glyph glyph-name="caret_down" unicode="&#xf0d7;" horiz-adv-x="1024" 
-d="M1024 832q0 -26 -19 -45l-448 -448q-19 -19 -45 -19t-45 19l-448 448q-19 19 -19 45t19 45t45 19h896q26 0 45 -19t19 -45z" />
-    <glyph glyph-name="caret_up" unicode="&#xf0d8;" horiz-adv-x="1024" 
-d="M1024 320q0 -26 -19 -45t-45 -19h-896q-26 0 -45 19t-19 45t19 45l448 448q19 19 45 19t45 -19l448 -448q19 -19 19 -45z" />
-    <glyph glyph-name="caret_left" unicode="&#xf0d9;" horiz-adv-x="640" 
-d="M640 1088v-896q0 -26 -19 -45t-45 -19t-45 19l-448 448q-19 19 -19 45t19 45l448 448q19 19 45 19t45 -19t19 -45z" />
-    <glyph glyph-name="caret_right" unicode="&#xf0da;" horiz-adv-x="640" 
-d="M576 640q0 -26 -19 -45l-448 -448q-19 -19 -45 -19t-45 19t-19 45v896q0 26 19 45t45 19t45 -19l448 -448q19 -19 19 -45z" />
-    <glyph glyph-name="columns" unicode="&#xf0db;" horiz-adv-x="1664" 
-d="M160 0h608v1152h-640v-1120q0 -13 9.5 -22.5t22.5 -9.5zM1536 32v1120h-640v-1152h608q13 0 22.5 9.5t9.5 22.5zM1664 1248v-1216q0 -66 -47 -113t-113 -47h-1344q-66 0 -113 47t-47 113v1216q0 66 47 113t113 47h1344q66 0 113 -47t47 -113z" />
-    <glyph glyph-name="sort" unicode="&#xf0dc;" horiz-adv-x="1024" 
-d="M1024 448q0 -26 -19 -45l-448 -448q-19 -19 -45 -19t-45 19l-448 448q-19 19 -19 45t19 45t45 19h896q26 0 45 -19t19 -45zM1024 832q0 -26 -19 -45t-45 -19h-896q-26 0 -45 19t-19 45t19 45l448 448q19 19 45 19t45 -19l448 -448q19 -19 19 -45z" />
-    <glyph glyph-name="sort_down" unicode="&#xf0dd;" horiz-adv-x="1024" 
-d="M1024 448q0 -26 -19 -45l-448 -448q-19 -19 -45 -19t-45 19l-448 448q-19 19 -19 45t19 45t45 19h896q26 0 45 -19t19 -45z" />
-    <glyph glyph-name="sort_up" unicode="&#xf0de;" horiz-adv-x="1024" 
-d="M1024 832q0 -26 -19 -45t-45 -19h-896q-26 0 -45 19t-19 45t19 45l448 448q19 19 45 19t45 -19l448 -448q19 -19 19 -45z" />
-    <glyph glyph-name="envelope_alt" unicode="&#xf0e0;" horiz-adv-x="1792" 
-d="M1792 826v-794q0 -66 -47 -113t-113 -47h-1472q-66 0 -113 47t-47 113v794q44 -49 101 -87q362 -246 497 -345q57 -42 92.5 -65.5t94.5 -48t110 -24.5h1h1q51 0 110 24.5t94.5 48t92.5 65.5q170 123 498 345q57 39 100 87zM1792 1120q0 -79 -49 -151t-122 -123
-q-376 -261 -468 -325q-10 -7 -42.5 -30.5t-54 -38t-52 -32.5t-57.5 -27t-50 -9h-1h-1q-23 0 -50 9t-57.5 27t-52 32.5t-54 38t-42.5 30.5q-91 64 -262 182.5t-205 142.5q-62 42 -117 115.5t-55 136.5q0 78 41.5 130t118.5 52h1472q65 0 112.5 -47t47.5 -113z" />
-    <glyph glyph-name="linkedin" unicode="&#xf0e1;" 
-d="M349 911v-991h-330v991h330zM370 1217q1 -73 -50.5 -122t-135.5 -49h-2q-82 0 -132 49t-50 122q0 74 51.5 122.5t134.5 48.5t133 -48.5t51 -122.5zM1536 488v-568h-329v530q0 105 -40.5 164.5t-126.5 59.5q-63 0 -105.5 -34.5t-63.5 -85.5q-11 -30 -11 -81v-553h-329
-q2 399 2 647t-1 296l-1 48h329v-144h-2q20 32 41 56t56.5 52t87 43.5t114.5 15.5q171 0 275 -113.5t104 -332.5z" />
-    <glyph glyph-name="undo" unicode="&#xf0e2;" 
-d="M1536 640q0 -156 -61 -298t-164 -245t-245 -164t-298 -61q-172 0 -327 72.5t-264 204.5q-7 10 -6.5 22.5t8.5 20.5l137 138q10 9 25 9q16 -2 23 -12q73 -95 179 -147t225 -52q104 0 198.5 40.5t163.5 109.5t109.5 163.5t40.5 198.5t-40.5 198.5t-109.5 163.5
-t-163.5 109.5t-198.5 40.5q-98 0 -188 -35.5t-160 -101.5l137 -138q31 -30 14 -69q-17 -40 -59 -40h-448q-26 0 -45 19t-19 45v448q0 42 40 59q39 17 69 -14l130 -129q107 101 244.5 156.5t284.5 55.5q156 0 298 -61t245 -164t164 -245t61 -298z" />
-    <glyph glyph-name="legal" unicode="&#xf0e3;" horiz-adv-x="1792" 
-d="M1771 0q0 -53 -37 -90l-107 -108q-39 -37 -91 -37q-53 0 -90 37l-363 364q-38 36 -38 90q0 53 43 96l-256 256l-126 -126q-14 -14 -34 -14t-34 14q2 -2 12.5 -12t12.5 -13t10 -11.5t10 -13.5t6 -13.5t5.5 -16.5t1.5 -18q0 -38 -28 -68q-3 -3 -16.5 -18t-19 -20.5
-t-18.5 -16.5t-22 -15.5t-22 -9t-26 -4.5q-40 0 -68 28l-408 408q-28 28 -28 68q0 13 4.5 26t9 22t15.5 22t16.5 18.5t20.5 19t18 16.5q30 28 68 28q10 0 18 -1.5t16.5 -5.5t13.5 -6t13.5 -10t11.5 -10t13 -12.5t12 -12.5q-14 14 -14 34t14 34l348 348q14 14 34 14t34 -14
-q-2 2 -12.5 12t-12.5 13t-10 11.5t-10 13.5t-6 13.5t-5.5 16.5t-1.5 18q0 38 28 68q3 3 16.5 18t19 20.5t18.5 16.5t22 15.5t22 9t26 4.5q40 0 68 -28l408 -408q28 -28 28 -68q0 -13 -4.5 -26t-9 -22t-15.5 -22t-16.5 -18.5t-20.5 -19t-18 -16.5q-30 -28 -68 -28
-q-10 0 -18 1.5t-16.5 5.5t-13.5 6t-13.5 10t-11.5 10t-13 12.5t-12 12.5q14 -14 14 -34t-14 -34l-126 -126l256 -256q43 43 96 43q52 0 91 -37l363 -363q37 -39 37 -91z" />
-    <glyph glyph-name="dashboard" unicode="&#xf0e4;" horiz-adv-x="1792" 
-d="M384 384q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM576 832q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1004 351l101 382q6 26 -7.5 48.5t-38.5 29.5
-t-48 -6.5t-30 -39.5l-101 -382q-60 -5 -107 -43.5t-63 -98.5q-20 -77 20 -146t117 -89t146 20t89 117q16 60 -6 117t-72 91zM1664 384q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1024 1024q0 53 -37.5 90.5
-t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1472 832q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1792 384q0 -261 -141 -483q-19 -29 -54 -29h-1402q-35 0 -54 29
-q-141 221 -141 483q0 182 71 348t191 286t286 191t348 71t348 -71t286 -191t191 -286t71 -348z" />
-    <glyph glyph-name="comment_alt" unicode="&#xf0e5;" horiz-adv-x="1792" 
-d="M896 1152q-204 0 -381.5 -69.5t-282 -187.5t-104.5 -255q0 -112 71.5 -213.5t201.5 -175.5l87 -50l-27 -96q-24 -91 -70 -172q152 63 275 171l43 38l57 -6q69 -8 130 -8q204 0 381.5 69.5t282 187.5t104.5 255t-104.5 255t-282 187.5t-381.5 69.5zM1792 640
-q0 -174 -120 -321.5t-326 -233t-450 -85.5q-70 0 -145 8q-198 -175 -460 -242q-49 -14 -114 -22h-5q-15 0 -27 10.5t-16 27.5v1q-3 4 -0.5 12t2 10t4.5 9.5l6 9t7 8.5t8 9q7 8 31 34.5t34.5 38t31 39.5t32.5 51t27 59t26 76q-157 89 -247.5 220t-90.5 281q0 174 120 321.5
-t326 233t450 85.5t450 -85.5t326 -233t120 -321.5z" />
-    <glyph glyph-name="comments_alt" unicode="&#xf0e6;" horiz-adv-x="1792" 
-d="M704 1152q-153 0 -286 -52t-211.5 -141t-78.5 -191q0 -82 53 -158t149 -132l97 -56l-35 -84q34 20 62 39l44 31l53 -10q78 -14 153 -14q153 0 286 52t211.5 141t78.5 191t-78.5 191t-211.5 141t-286 52zM704 1280q191 0 353.5 -68.5t256.5 -186.5t94 -257t-94 -257
-t-256.5 -186.5t-353.5 -68.5q-86 0 -176 16q-124 -88 -278 -128q-36 -9 -86 -16h-3q-11 0 -20.5 8t-11.5 21q-1 3 -1 6.5t0.5 6.5t2 6l2.5 5t3.5 5.5t4 5t4.5 5t4 4.5q5 6 23 25t26 29.5t22.5 29t25 38.5t20.5 44q-124 72 -195 177t-71 224q0 139 94 257t256.5 186.5
-t353.5 68.5zM1526 111q10 -24 20.5 -44t25 -38.5t22.5 -29t26 -29.5t23 -25q1 -1 4 -4.5t4.5 -5t4 -5t3.5 -5.5l2.5 -5t2 -6t0.5 -6.5t-1 -6.5q-3 -14 -13 -22t-22 -7q-50 7 -86 16q-154 40 -278 128q-90 -16 -176 -16q-271 0 -472 132q58 -4 88 -4q161 0 309 45t264 129
-q125 92 192 212t67 254q0 77 -23 152q129 -71 204 -178t75 -230q0 -120 -71 -224.5t-195 -176.5z" />
-    <glyph glyph-name="bolt" unicode="&#xf0e7;" horiz-adv-x="896" 
-d="M885 970q18 -20 7 -44l-540 -1157q-13 -25 -42 -25q-4 0 -14 2q-17 5 -25.5 19t-4.5 30l197 808l-406 -101q-4 -1 -12 -1q-18 0 -31 11q-18 15 -13 39l201 825q4 14 16 23t28 9h328q19 0 32 -12.5t13 -29.5q0 -8 -5 -18l-171 -463l396 98q8 2 12 2q19 0 34 -15z" />
-    <glyph glyph-name="sitemap" unicode="&#xf0e8;" horiz-adv-x="1792" 
-d="M1792 288v-320q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v320q0 40 28 68t68 28h96v192h-512v-192h96q40 0 68 -28t28 -68v-320q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v320q0 40 28 68t68 28h96v192h-512v-192h96q40 0 68 -28t28 -68v-320
-q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v320q0 40 28 68t68 28h96v192q0 52 38 90t90 38h512v192h-96q-40 0 -68 28t-28 68v320q0 40 28 68t68 28h320q40 0 68 -28t28 -68v-320q0 -40 -28 -68t-68 -28h-96v-192h512q52 0 90 -38t38 -90v-192h96q40 0 68 -28t28 -68
-z" />
-    <glyph glyph-name="umbrella" unicode="&#xf0e9;" horiz-adv-x="1664" 
-d="M896 708v-580q0 -104 -76 -180t-180 -76t-180 76t-76 180q0 26 19 45t45 19t45 -19t19 -45q0 -50 39 -89t89 -39t89 39t39 89v580q33 11 64 11t64 -11zM1664 681q0 -13 -9.5 -22.5t-22.5 -9.5q-11 0 -23 10q-49 46 -93 69t-102 23q-68 0 -128 -37t-103 -97
-q-7 -10 -17.5 -28t-14.5 -24q-11 -17 -28 -17q-18 0 -29 17q-4 6 -14.5 24t-17.5 28q-43 60 -102.5 97t-127.5 37t-127.5 -37t-102.5 -97q-7 -10 -17.5 -28t-14.5 -24q-11 -17 -29 -17q-17 0 -28 17q-4 6 -14.5 24t-17.5 28q-43 60 -103 97t-128 37q-58 0 -102 -23t-93 -69
-q-12 -10 -23 -10q-13 0 -22.5 9.5t-9.5 22.5q0 5 1 7q45 183 172.5 319.5t298 204.5t360.5 68q140 0 274.5 -40t246.5 -113.5t194.5 -187t115.5 -251.5q1 -2 1 -7zM896 1408v-98q-42 2 -64 2t-64 -2v98q0 26 19 45t45 19t45 -19t19 -45z" />
-    <glyph glyph-name="paste" unicode="&#xf0ea;" horiz-adv-x="1792" 
-d="M768 -128h896v640h-416q-40 0 -68 28t-28 68v416h-384v-1152zM1024 1312v64q0 13 -9.5 22.5t-22.5 9.5h-704q-13 0 -22.5 -9.5t-9.5 -22.5v-64q0 -13 9.5 -22.5t22.5 -9.5h704q13 0 22.5 9.5t9.5 22.5zM1280 640h299l-299 299v-299zM1792 512v-672q0 -40 -28 -68t-68 -28
-h-960q-40 0 -68 28t-28 68v160h-544q-40 0 -68 28t-28 68v1344q0 40 28 68t68 28h1088q40 0 68 -28t28 -68v-328q21 -13 36 -28l408 -408q28 -28 48 -76t20 -88z" />
-    <glyph glyph-name="light_bulb" unicode="&#xf0eb;" horiz-adv-x="1024" 
-d="M736 960q0 -13 -9.5 -22.5t-22.5 -9.5t-22.5 9.5t-9.5 22.5q0 46 -54 71t-106 25q-13 0 -22.5 9.5t-9.5 22.5t9.5 22.5t22.5 9.5q50 0 99.5 -16t87 -54t37.5 -90zM896 960q0 72 -34.5 134t-90 101.5t-123 62t-136.5 22.5t-136.5 -22.5t-123 -62t-90 -101.5t-34.5 -134
-q0 -101 68 -180q10 -11 30.5 -33t30.5 -33q128 -153 141 -298h228q13 145 141 298q10 11 30.5 33t30.5 33q68 79 68 180zM1024 960q0 -155 -103 -268q-45 -49 -74.5 -87t-59.5 -95.5t-34 -107.5q47 -28 47 -82q0 -37 -25 -64q25 -27 25 -64q0 -52 -45 -81q13 -23 13 -47
-q0 -46 -31.5 -71t-77.5 -25q-20 -44 -60 -70t-87 -26t-87 26t-60 70q-46 0 -77.5 25t-31.5 71q0 24 13 47q-45 29 -45 81q0 37 25 64q-25 27 -25 64q0 54 47 82q-4 50 -34 107.5t-59.5 95.5t-74.5 87q-103 113 -103 268q0 99 44.5 184.5t117 142t164 89t186.5 32.5
-t186.5 -32.5t164 -89t117 -142t44.5 -184.5z" />
-    <glyph glyph-name="exchange" unicode="&#xf0ec;" horiz-adv-x="1792" 
-d="M1792 352v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1376v-192q0 -13 -9.5 -22.5t-22.5 -9.5q-12 0 -24 10l-319 320q-9 9 -9 22q0 14 9 23l320 320q9 9 23 9q13 0 22.5 -9.5t9.5 -22.5v-192h1376q13 0 22.5 -9.5t9.5 -22.5zM1792 896q0 -14 -9 -23l-320 -320q-9 -9 -23 -9
-q-13 0 -22.5 9.5t-9.5 22.5v192h-1376q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1376v192q0 14 9 23t23 9q12 0 24 -10l319 -319q9 -9 9 -23z" />
-    <glyph glyph-name="cloud_download" unicode="&#xf0ed;" horiz-adv-x="1920" 
-d="M1280 608q0 14 -9 23t-23 9h-224v352q0 13 -9.5 22.5t-22.5 9.5h-192q-13 0 -22.5 -9.5t-9.5 -22.5v-352h-224q-13 0 -22.5 -9.5t-9.5 -22.5q0 -14 9 -23l352 -352q9 -9 23 -9t23 9l351 351q10 12 10 24zM1920 384q0 -159 -112.5 -271.5t-271.5 -112.5h-1088
-q-185 0 -316.5 131.5t-131.5 316.5q0 130 70 240t188 165q-2 30 -2 43q0 212 150 362t362 150q156 0 285.5 -87t188.5 -231q71 62 166 62q106 0 181 -75t75 -181q0 -76 -41 -138q130 -31 213.5 -135.5t83.5 -238.5z" />
-    <glyph glyph-name="cloud_upload" unicode="&#xf0ee;" horiz-adv-x="1920" 
-d="M1280 672q0 14 -9 23l-352 352q-9 9 -23 9t-23 -9l-351 -351q-10 -12 -10 -24q0 -14 9 -23t23 -9h224v-352q0 -13 9.5 -22.5t22.5 -9.5h192q13 0 22.5 9.5t9.5 22.5v352h224q13 0 22.5 9.5t9.5 22.5zM1920 384q0 -159 -112.5 -271.5t-271.5 -112.5h-1088
-q-185 0 -316.5 131.5t-131.5 316.5q0 130 70 240t188 165q-2 30 -2 43q0 212 150 362t362 150q156 0 285.5 -87t188.5 -231q71 62 166 62q106 0 181 -75t75 -181q0 -76 -41 -138q130 -31 213.5 -135.5t83.5 -238.5z" />
-    <glyph glyph-name="user_md" unicode="&#xf0f0;" horiz-adv-x="1408" 
-d="M384 192q0 -26 -19 -45t-45 -19t-45 19t-19 45t19 45t45 19t45 -19t19 -45zM1408 131q0 -121 -73 -190t-194 -69h-874q-121 0 -194 69t-73 190q0 68 5.5 131t24 138t47.5 132.5t81 103t120 60.5q-22 -52 -22 -120v-203q-58 -20 -93 -70t-35 -111q0 -80 56 -136t136 -56
-t136 56t56 136q0 61 -35.5 111t-92.5 70v203q0 62 25 93q132 -104 295 -104t295 104q25 -31 25 -93v-64q-106 0 -181 -75t-75 -181v-89q-32 -29 -32 -71q0 -40 28 -68t68 -28t68 28t28 68q0 42 -32 71v89q0 52 38 90t90 38t90 -38t38 -90v-89q-32 -29 -32 -71q0 -40 28 -68
-t68 -28t68 28t28 68q0 42 -32 71v89q0 68 -34.5 127.5t-93.5 93.5q0 10 0.5 42.5t0 48t-2.5 41.5t-7 47t-13 40q68 -15 120 -60.5t81 -103t47.5 -132.5t24 -138t5.5 -131zM1088 1024q0 -159 -112.5 -271.5t-271.5 -112.5t-271.5 112.5t-112.5 271.5t112.5 271.5t271.5 112.5
-t271.5 -112.5t112.5 -271.5z" />
-    <glyph glyph-name="stethoscope" unicode="&#xf0f1;" horiz-adv-x="1408" 
-d="M1280 832q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1408 832q0 -62 -35.5 -111t-92.5 -70v-395q0 -159 -131.5 -271.5t-316.5 -112.5t-316.5 112.5t-131.5 271.5v132q-164 20 -274 128t-110 252v512q0 26 19 45t45 19q6 0 16 -2q17 30 47 48
-t65 18q53 0 90.5 -37.5t37.5 -90.5t-37.5 -90.5t-90.5 -37.5q-33 0 -64 18v-402q0 -106 94 -181t226 -75t226 75t94 181v402q-31 -18 -64 -18q-53 0 -90.5 37.5t-37.5 90.5t37.5 90.5t90.5 37.5q35 0 65 -18t47 -48q10 2 16 2q26 0 45 -19t19 -45v-512q0 -144 -110 -252
-t-274 -128v-132q0 -106 94 -181t226 -75t226 75t94 181v395q-57 21 -92.5 70t-35.5 111q0 80 56 136t136 56t136 -56t56 -136z" />
-    <glyph glyph-name="suitcase" unicode="&#xf0f2;" horiz-adv-x="1792" 
-d="M640 1152h512v128h-512v-128zM288 1152v-1280h-64q-92 0 -158 66t-66 158v832q0 92 66 158t158 66h64zM1408 1152v-1280h-1024v1280h128v160q0 40 28 68t68 28h576q40 0 68 -28t28 -68v-160h128zM1792 928v-832q0 -92 -66 -158t-158 -66h-64v1280h64q92 0 158 -66
-t66 -158z" />
-    <glyph glyph-name="bell_alt" unicode="&#xf0f3;" horiz-adv-x="1792" 
-d="M912 -160q0 16 -16 16q-59 0 -101.5 42.5t-42.5 101.5q0 16 -16 16t-16 -16q0 -73 51.5 -124.5t124.5 -51.5q16 0 16 16zM1728 128q0 -52 -38 -90t-90 -38h-448q0 -106 -75 -181t-181 -75t-181 75t-75 181h-448q-52 0 -90 38t-38 90q50 42 91 88t85 119.5t74.5 158.5
-t50 206t19.5 260q0 152 117 282.5t307 158.5q-8 19 -8 39q0 40 28 68t68 28t68 -28t28 -68q0 -20 -8 -39q190 -28 307 -158.5t117 -282.5q0 -139 19.5 -260t50 -206t74.5 -158.5t85 -119.5t91 -88z" />
-    <glyph glyph-name="coffee" unicode="&#xf0f4;" horiz-adv-x="1920" 
-d="M1664 896q0 80 -56 136t-136 56h-64v-384h64q80 0 136 56t56 136zM0 128h1792q0 -106 -75 -181t-181 -75h-1280q-106 0 -181 75t-75 181zM1856 896q0 -159 -112.5 -271.5t-271.5 -112.5h-64v-32q0 -92 -66 -158t-158 -66h-704q-92 0 -158 66t-66 158v736q0 26 19 45
-t45 19h1152q159 0 271.5 -112.5t112.5 -271.5z" />
-    <glyph glyph-name="food" unicode="&#xf0f5;" horiz-adv-x="1408" 
-d="M640 1472v-640q0 -61 -35.5 -111t-92.5 -70v-779q0 -52 -38 -90t-90 -38h-128q-52 0 -90 38t-38 90v779q-57 20 -92.5 70t-35.5 111v640q0 26 19 45t45 19t45 -19t19 -45v-416q0 -26 19 -45t45 -19t45 19t19 45v416q0 26 19 45t45 19t45 -19t19 -45v-416q0 -26 19 -45
-t45 -19t45 19t19 45v416q0 26 19 45t45 19t45 -19t19 -45zM1408 1472v-1600q0 -52 -38 -90t-90 -38h-128q-52 0 -90 38t-38 90v512h-224q-13 0 -22.5 9.5t-9.5 22.5v800q0 132 94 226t226 94h256q26 0 45 -19t19 -45z" />
-    <glyph glyph-name="file_text_alt" unicode="&#xf0f6;" 
-d="M1468 1156q28 -28 48 -76t20 -88v-1152q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68v1600q0 40 28 68t68 28h896q40 0 88 -20t76 -48zM1024 1400v-376h376q-10 29 -22 41l-313 313q-12 12 -41 22zM1408 -128v1024h-416q-40 0 -68 28t-28 68v416h-768v-1536h1280z
-M384 736q0 14 9 23t23 9h704q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-704q-14 0 -23 9t-9 23v64zM1120 512q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-704q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h704zM1120 256q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-704
-q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h704z" />
-    <glyph glyph-name="building" unicode="&#xf0f7;" horiz-adv-x="1408" 
-d="M384 224v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM384 480v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z
-M640 480v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM384 736v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z
-M1152 224v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM896 480v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z
-M640 736v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM384 992v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z
-M1152 480v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM896 736v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z
-M640 992v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM384 1248v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z
-M1152 736v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM896 992v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z
-M640 1248v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM1152 992v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z
-M896 1248v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM1152 1248v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z
-M896 -128h384v1536h-1152v-1536h384v224q0 13 9.5 22.5t22.5 9.5h320q13 0 22.5 -9.5t9.5 -22.5v-224zM1408 1472v-1664q0 -26 -19 -45t-45 -19h-1280q-26 0 -45 19t-19 45v1664q0 26 19 45t45 19h1280q26 0 45 -19t19 -45z" />
-    <glyph glyph-name="hospital" unicode="&#xf0f8;" horiz-adv-x="1408" 
-d="M384 224v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM384 480v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z
-M640 480v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM384 736v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z
-M1152 224v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM896 480v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z
-M640 736v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM1152 480v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z
-M896 736v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM1152 736v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z
-M896 -128h384v1152h-256v-32q0 -40 -28 -68t-68 -28h-448q-40 0 -68 28t-28 68v32h-256v-1152h384v224q0 13 9.5 22.5t22.5 9.5h320q13 0 22.5 -9.5t9.5 -22.5v-224zM896 1056v320q0 13 -9.5 22.5t-22.5 9.5h-64q-13 0 -22.5 -9.5t-9.5 -22.5v-96h-128v96q0 13 -9.5 22.5
-t-22.5 9.5h-64q-13 0 -22.5 -9.5t-9.5 -22.5v-320q0 -13 9.5 -22.5t22.5 -9.5h64q13 0 22.5 9.5t9.5 22.5v96h128v-96q0 -13 9.5 -22.5t22.5 -9.5h64q13 0 22.5 9.5t9.5 22.5zM1408 1088v-1280q0 -26 -19 -45t-45 -19h-1280q-26 0 -45 19t-19 45v1280q0 26 19 45t45 19h320
-v288q0 40 28 68t68 28h448q40 0 68 -28t28 -68v-288h320q26 0 45 -19t19 -45z" />
-    <glyph glyph-name="ambulance" unicode="&#xf0f9;" horiz-adv-x="1920" 
-d="M640 128q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM256 640h384v256h-158q-14 -2 -22 -9l-195 -195q-7 -12 -9 -22v-30zM1536 128q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5
-t90.5 37.5t37.5 90.5zM1664 800v192q0 14 -9 23t-23 9h-224v224q0 14 -9 23t-23 9h-192q-14 0 -23 -9t-9 -23v-224h-224q-14 0 -23 -9t-9 -23v-192q0 -14 9 -23t23 -9h224v-224q0 -14 9 -23t23 -9h192q14 0 23 9t9 23v224h224q14 0 23 9t9 23zM1920 1344v-1152
-q0 -26 -19 -45t-45 -19h-192q0 -106 -75 -181t-181 -75t-181 75t-75 181h-384q0 -106 -75 -181t-181 -75t-181 75t-75 181h-128q-26 0 -45 19t-19 45t19 45t45 19v416q0 26 13 58t32 51l198 198q19 19 51 32t58 13h160v320q0 26 19 45t45 19h1152q26 0 45 -19t19 -45z" />
-    <glyph glyph-name="medkit" unicode="&#xf0fa;" horiz-adv-x="1792" 
-d="M1280 416v192q0 14 -9 23t-23 9h-224v224q0 14 -9 23t-23 9h-192q-14 0 -23 -9t-9 -23v-224h-224q-14 0 -23 -9t-9 -23v-192q0 -14 9 -23t23 -9h224v-224q0 -14 9 -23t23 -9h192q14 0 23 9t9 23v224h224q14 0 23 9t9 23zM640 1152h512v128h-512v-128zM256 1152v-1280h-32
-q-92 0 -158 66t-66 158v832q0 92 66 158t158 66h32zM1440 1152v-1280h-1088v1280h160v160q0 40 28 68t68 28h576q40 0 68 -28t28 -68v-160h160zM1792 928v-832q0 -92 -66 -158t-158 -66h-32v1280h32q92 0 158 -66t66 -158z" />
-    <glyph glyph-name="fighter_jet" unicode="&#xf0fb;" horiz-adv-x="1920" 
-d="M1920 576q-1 -32 -288 -96l-352 -32l-224 -64h-64l-293 -352h69q26 0 45 -4.5t19 -11.5t-19 -11.5t-45 -4.5h-96h-160h-64v32h64v416h-160l-192 -224h-96l-32 32v192h32v32h128v8l-192 24v128l192 24v8h-128v32h-32v192l32 32h96l192 -224h160v416h-64v32h64h160h96
-q26 0 45 -4.5t19 -11.5t-19 -11.5t-45 -4.5h-69l293 -352h64l224 -64l352 -32q128 -28 200 -52t80 -34z" />
-    <glyph glyph-name="beer" unicode="&#xf0fc;" horiz-adv-x="1664" 
-d="M640 640v384h-256v-256q0 -53 37.5 -90.5t90.5 -37.5h128zM1664 192v-192h-1152v192l128 192h-128q-159 0 -271.5 112.5t-112.5 271.5v320l-64 64l32 128h480l32 128h960l32 -192l-64 -32v-800z" />
-    <glyph glyph-name="h_sign" unicode="&#xf0fd;" 
-d="M1280 192v896q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-320h-512v320q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-896q0 -26 19 -45t45 -19h128q26 0 45 19t19 45v320h512v-320q0 -26 19 -45t45 -19h128q26 0 45 19t19 45zM1536 1120v-960
-q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
-    <glyph glyph-name="f0fe" unicode="&#xf0fe;" 
-d="M1280 576v128q0 26 -19 45t-45 19h-320v320q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-320h-320q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45t45 -19h320v-320q0 -26 19 -45t45 -19h128q26 0 45 19t19 45v320h320q26 0 45 19t19 45zM1536 1120v-960
-q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
-    <glyph glyph-name="double_angle_left" unicode="&#xf100;" horiz-adv-x="1024" 
-d="M627 160q0 -13 -10 -23l-50 -50q-10 -10 -23 -10t-23 10l-466 466q-10 10 -10 23t10 23l466 466q10 10 23 10t23 -10l50 -50q10 -10 10 -23t-10 -23l-393 -393l393 -393q10 -10 10 -23zM1011 160q0 -13 -10 -23l-50 -50q-10 -10 -23 -10t-23 10l-466 466q-10 10 -10 23
-t10 23l466 466q10 10 23 10t23 -10l50 -50q10 -10 10 -23t-10 -23l-393 -393l393 -393q10 -10 10 -23z" />
-    <glyph glyph-name="double_angle_right" unicode="&#xf101;" horiz-adv-x="1024" 
-d="M595 576q0 -13 -10 -23l-466 -466q-10 -10 -23 -10t-23 10l-50 50q-10 10 -10 23t10 23l393 393l-393 393q-10 10 -10 23t10 23l50 50q10 10 23 10t23 -10l466 -466q10 -10 10 -23zM979 576q0 -13 -10 -23l-466 -466q-10 -10 -23 -10t-23 10l-50 50q-10 10 -10 23t10 23
-l393 393l-393 393q-10 10 -10 23t10 23l50 50q10 10 23 10t23 -10l466 -466q10 -10 10 -23z" />
-    <glyph glyph-name="double_angle_up" unicode="&#xf102;" horiz-adv-x="1152" 
-d="M1075 224q0 -13 -10 -23l-50 -50q-10 -10 -23 -10t-23 10l-393 393l-393 -393q-10 -10 -23 -10t-23 10l-50 50q-10 10 -10 23t10 23l466 466q10 10 23 10t23 -10l466 -466q10 -10 10 -23zM1075 608q0 -13 -10 -23l-50 -50q-10 -10 -23 -10t-23 10l-393 393l-393 -393
-q-10 -10 -23 -10t-23 10l-50 50q-10 10 -10 23t10 23l466 466q10 10 23 10t23 -10l466 -466q10 -10 10 -23z" />
-    <glyph glyph-name="double_angle_down" unicode="&#xf103;" horiz-adv-x="1152" 
-d="M1075 672q0 -13 -10 -23l-466 -466q-10 -10 -23 -10t-23 10l-466 466q-10 10 -10 23t10 23l50 50q10 10 23 10t23 -10l393 -393l393 393q10 10 23 10t23 -10l50 -50q10 -10 10 -23zM1075 1056q0 -13 -10 -23l-466 -466q-10 -10 -23 -10t-23 10l-466 466q-10 10 -10 23
-t10 23l50 50q10 10 23 10t23 -10l393 -393l393 393q10 10 23 10t23 -10l50 -50q10 -10 10 -23z" />
-    <glyph glyph-name="angle_left" unicode="&#xf104;" horiz-adv-x="640" 
-d="M627 992q0 -13 -10 -23l-393 -393l393 -393q10 -10 10 -23t-10 -23l-50 -50q-10 -10 -23 -10t-23 10l-466 466q-10 10 -10 23t10 23l466 466q10 10 23 10t23 -10l50 -50q10 -10 10 -23z" />
-    <glyph glyph-name="angle_right" unicode="&#xf105;" horiz-adv-x="640" 
-d="M595 576q0 -13 -10 -23l-466 -466q-10 -10 -23 -10t-23 10l-50 50q-10 10 -10 23t10 23l393 393l-393 393q-10 10 -10 23t10 23l50 50q10 10 23 10t23 -10l466 -466q10 -10 10 -23z" />
-    <glyph glyph-name="angle_up" unicode="&#xf106;" horiz-adv-x="1152" 
-d="M1075 352q0 -13 -10 -23l-50 -50q-10 -10 -23 -10t-23 10l-393 393l-393 -393q-10 -10 -23 -10t-23 10l-50 50q-10 10 -10 23t10 23l466 466q10 10 23 10t23 -10l466 -466q10 -10 10 -23z" />
-    <glyph glyph-name="angle_down" unicode="&#xf107;" horiz-adv-x="1152" 
-d="M1075 800q0 -13 -10 -23l-466 -466q-10 -10 -23 -10t-23 10l-466 466q-10 10 -10 23t10 23l50 50q10 10 23 10t23 -10l393 -393l393 393q10 10 23 10t23 -10l50 -50q10 -10 10 -23z" />
-    <glyph glyph-name="desktop" unicode="&#xf108;" horiz-adv-x="1920" 
-d="M1792 544v832q0 13 -9.5 22.5t-22.5 9.5h-1600q-13 0 -22.5 -9.5t-9.5 -22.5v-832q0 -13 9.5 -22.5t22.5 -9.5h1600q13 0 22.5 9.5t9.5 22.5zM1920 1376v-1088q0 -66 -47 -113t-113 -47h-544q0 -37 16 -77.5t32 -71t16 -43.5q0 -26 -19 -45t-45 -19h-512q-26 0 -45 19
-t-19 45q0 14 16 44t32 70t16 78h-544q-66 0 -113 47t-47 113v1088q0 66 47 113t113 47h1600q66 0 113 -47t47 -113z" />
-    <glyph glyph-name="laptop" unicode="&#xf109;" horiz-adv-x="1920" 
-d="M416 256q-66 0 -113 47t-47 113v704q0 66 47 113t113 47h1088q66 0 113 -47t47 -113v-704q0 -66 -47 -113t-113 -47h-1088zM384 1120v-704q0 -13 9.5 -22.5t22.5 -9.5h1088q13 0 22.5 9.5t9.5 22.5v704q0 13 -9.5 22.5t-22.5 9.5h-1088q-13 0 -22.5 -9.5t-9.5 -22.5z
-M1760 192h160v-96q0 -40 -47 -68t-113 -28h-1600q-66 0 -113 28t-47 68v96h160h1600zM1040 96q16 0 16 16t-16 16h-160q-16 0 -16 -16t16 -16h160z" />
-    <glyph glyph-name="tablet" unicode="&#xf10a;" horiz-adv-x="1152" 
-d="M640 128q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1024 288v960q0 13 -9.5 22.5t-22.5 9.5h-832q-13 0 -22.5 -9.5t-9.5 -22.5v-960q0 -13 9.5 -22.5t22.5 -9.5h832q13 0 22.5 9.5t9.5 22.5zM1152 1248v-1088q0 -66 -47 -113t-113 -47h-832
-q-66 0 -113 47t-47 113v1088q0 66 47 113t113 47h832q66 0 113 -47t47 -113z" />
-    <glyph glyph-name="mobile_phone" unicode="&#xf10b;" horiz-adv-x="768" 
-d="M464 128q0 33 -23.5 56.5t-56.5 23.5t-56.5 -23.5t-23.5 -56.5t23.5 -56.5t56.5 -23.5t56.5 23.5t23.5 56.5zM672 288v704q0 13 -9.5 22.5t-22.5 9.5h-512q-13 0 -22.5 -9.5t-9.5 -22.5v-704q0 -13 9.5 -22.5t22.5 -9.5h512q13 0 22.5 9.5t9.5 22.5zM480 1136
-q0 16 -16 16h-160q-16 0 -16 -16t16 -16h160q16 0 16 16zM768 1152v-1024q0 -52 -38 -90t-90 -38h-512q-52 0 -90 38t-38 90v1024q0 52 38 90t90 38h512q52 0 90 -38t38 -90z" />
-    <glyph glyph-name="circle_blank" unicode="&#xf10c;" 
-d="M768 1184q-148 0 -273 -73t-198 -198t-73 -273t73 -273t198 -198t273 -73t273 73t198 198t73 273t-73 273t-198 198t-273 73zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103
-t279.5 -279.5t103 -385.5z" />
-    <glyph glyph-name="quote_left" unicode="&#xf10d;" horiz-adv-x="1664" 
-d="M768 576v-384q0 -80 -56 -136t-136 -56h-384q-80 0 -136 56t-56 136v704q0 104 40.5 198.5t109.5 163.5t163.5 109.5t198.5 40.5h64q26 0 45 -19t19 -45v-128q0 -26 -19 -45t-45 -19h-64q-106 0 -181 -75t-75 -181v-32q0 -40 28 -68t68 -28h224q80 0 136 -56t56 -136z
-M1664 576v-384q0 -80 -56 -136t-136 -56h-384q-80 0 -136 56t-56 136v704q0 104 40.5 198.5t109.5 163.5t163.5 109.5t198.5 40.5h64q26 0 45 -19t19 -45v-128q0 -26 -19 -45t-45 -19h-64q-106 0 -181 -75t-75 -181v-32q0 -40 28 -68t68 -28h224q80 0 136 -56t56 -136z" />
-    <glyph glyph-name="quote_right" unicode="&#xf10e;" horiz-adv-x="1664" 
-d="M768 1216v-704q0 -104 -40.5 -198.5t-109.5 -163.5t-163.5 -109.5t-198.5 -40.5h-64q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h64q106 0 181 75t75 181v32q0 40 -28 68t-68 28h-224q-80 0 -136 56t-56 136v384q0 80 56 136t136 56h384q80 0 136 -56t56 -136zM1664 1216
-v-704q0 -104 -40.5 -198.5t-109.5 -163.5t-163.5 -109.5t-198.5 -40.5h-64q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h64q106 0 181 75t75 181v32q0 40 -28 68t-68 28h-224q-80 0 -136 56t-56 136v384q0 80 56 136t136 56h384q80 0 136 -56t56 -136z" />
-    <glyph glyph-name="spinner" unicode="&#xf110;" horiz-adv-x="1792" 
-d="M526 142q0 -53 -37.5 -90.5t-90.5 -37.5q-52 0 -90 38t-38 90q0 53 37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1024 -64q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM320 640q0 -53 -37.5 -90.5t-90.5 -37.5
-t-90.5 37.5t-37.5 90.5t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1522 142q0 -52 -38 -90t-90 -38q-53 0 -90.5 37.5t-37.5 90.5t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM558 1138q0 -66 -47 -113t-113 -47t-113 47t-47 113t47 113t113 47t113 -47t47 -113z
-M1728 640q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1088 1344q0 -80 -56 -136t-136 -56t-136 56t-56 136t56 136t136 56t136 -56t56 -136zM1618 1138q0 -93 -66 -158.5t-158 -65.5q-93 0 -158.5 65.5t-65.5 158.5
-q0 92 65.5 158t158.5 66q92 0 158 -66t66 -158z" />
-    <glyph glyph-name="circle" unicode="&#xf111;" 
-d="M1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
-    <glyph glyph-name="reply" unicode="&#xf112;" horiz-adv-x="1792" 
-d="M1792 416q0 -166 -127 -451q-3 -7 -10.5 -24t-13.5 -30t-13 -22q-12 -17 -28 -17q-15 0 -23.5 10t-8.5 25q0 9 2.5 26.5t2.5 23.5q5 68 5 123q0 101 -17.5 181t-48.5 138.5t-80 101t-105.5 69.5t-133 42.5t-154 21.5t-175.5 6h-224v-256q0 -26 -19 -45t-45 -19t-45 19
-l-512 512q-19 19 -19 45t19 45l512 512q19 19 45 19t45 -19t19 -45v-256h224q713 0 875 -403q53 -134 53 -333z" />
-    <glyph glyph-name="github_alt" unicode="&#xf113;" horiz-adv-x="1664" 
-d="M640 320q0 -40 -12.5 -82t-43 -76t-72.5 -34t-72.5 34t-43 76t-12.5 82t12.5 82t43 76t72.5 34t72.5 -34t43 -76t12.5 -82zM1280 320q0 -40 -12.5 -82t-43 -76t-72.5 -34t-72.5 34t-43 76t-12.5 82t12.5 82t43 76t72.5 34t72.5 -34t43 -76t12.5 -82zM1440 320
-q0 120 -69 204t-187 84q-41 0 -195 -21q-71 -11 -157 -11t-157 11q-152 21 -195 21q-118 0 -187 -84t-69 -204q0 -88 32 -153.5t81 -103t122 -60t140 -29.5t149 -7h168q82 0 149 7t140 29.5t122 60t81 103t32 153.5zM1664 496q0 -207 -61 -331q-38 -77 -105.5 -133t-141 -86
-t-170 -47.5t-171.5 -22t-167 -4.5q-78 0 -142 3t-147.5 12.5t-152.5 30t-137 51.5t-121 81t-86 115q-62 123 -62 331q0 237 136 396q-27 82 -27 170q0 116 51 218q108 0 190 -39.5t189 -123.5q147 35 309 35q148 0 280 -32q105 82 187 121t189 39q51 -102 51 -218
-q0 -87 -27 -168q136 -160 136 -398z" />
-    <glyph glyph-name="folder_close_alt" unicode="&#xf114;" horiz-adv-x="1664" 
-d="M1536 224v704q0 40 -28 68t-68 28h-704q-40 0 -68 28t-28 68v64q0 40 -28 68t-68 28h-320q-40 0 -68 -28t-28 -68v-960q0 -40 28 -68t68 -28h1216q40 0 68 28t28 68zM1664 928v-704q0 -92 -66 -158t-158 -66h-1216q-92 0 -158 66t-66 158v960q0 92 66 158t158 66h320
-q92 0 158 -66t66 -158v-32h672q92 0 158 -66t66 -158z" />
-    <glyph glyph-name="folder_open_alt" unicode="&#xf115;" horiz-adv-x="1920" 
-d="M1781 605q0 35 -53 35h-1088q-40 0 -85.5 -21.5t-71.5 -52.5l-294 -363q-18 -24 -18 -40q0 -35 53 -35h1088q40 0 86 22t71 53l294 363q18 22 18 39zM640 768h768v160q0 40 -28 68t-68 28h-576q-40 0 -68 28t-28 68v64q0 40 -28 68t-68 28h-320q-40 0 -68 -28t-28 -68
-v-853l256 315q44 53 116 87.5t140 34.5zM1909 605q0 -62 -46 -120l-295 -363q-43 -53 -116 -87.5t-140 -34.5h-1088q-92 0 -158 66t-66 158v960q0 92 66 158t158 66h320q92 0 158 -66t66 -158v-32h544q92 0 158 -66t66 -158v-160h192q54 0 99 -24.5t67 -70.5q15 -32 15 -68z
-" />
-    <glyph glyph-name="expand_alt" unicode="&#xf116;" horiz-adv-x="1792" 
- />
-    <glyph glyph-name="collapse_alt" unicode="&#xf117;" horiz-adv-x="1792" 
- />
-    <glyph glyph-name="smile" unicode="&#xf118;" 
-d="M1134 461q-37 -121 -138 -195t-228 -74t-228 74t-138 195q-8 25 4 48.5t38 31.5q25 8 48.5 -4t31.5 -38q25 -80 92.5 -129.5t151.5 -49.5t151.5 49.5t92.5 129.5q8 26 32 38t49 4t37 -31.5t4 -48.5zM640 896q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5
-t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1152 896q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1408 640q0 130 -51 248.5t-136.5 204t-204 136.5t-248.5 51t-248.5 -51t-204 -136.5t-136.5 -204t-51 -248.5
-t51 -248.5t136.5 -204t204 -136.5t248.5 -51t248.5 51t204 136.5t136.5 204t51 248.5zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
-    <glyph glyph-name="frown" unicode="&#xf119;" 
-d="M1134 307q8 -25 -4 -48.5t-37 -31.5t-49 4t-32 38q-25 80 -92.5 129.5t-151.5 49.5t-151.5 -49.5t-92.5 -129.5q-8 -26 -31.5 -38t-48.5 -4q-26 8 -38 31.5t-4 48.5q37 121 138 195t228 74t228 -74t138 -195zM640 896q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5
-t-37.5 90.5t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1152 896q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1408 640q0 130 -51 248.5t-136.5 204t-204 136.5t-248.5 51t-248.5 -51t-204 -136.5t-136.5 -204
-t-51 -248.5t51 -248.5t136.5 -204t204 -136.5t248.5 -51t248.5 51t204 136.5t136.5 204t51 248.5zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
-    <glyph glyph-name="meh" unicode="&#xf11a;" 
-d="M1152 448q0 -26 -19 -45t-45 -19h-640q-26 0 -45 19t-19 45t19 45t45 19h640q26 0 45 -19t19 -45zM640 896q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1152 896q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5
-t-37.5 90.5t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1408 640q0 130 -51 248.5t-136.5 204t-204 136.5t-248.5 51t-248.5 -51t-204 -136.5t-136.5 -204t-51 -248.5t51 -248.5t136.5 -204t204 -136.5t248.5 -51t248.5 51t204 136.5t136.5 204t51 248.5zM1536 640
-q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
-    <glyph glyph-name="gamepad" unicode="&#xf11b;" horiz-adv-x="1920" 
-d="M832 448v128q0 14 -9 23t-23 9h-192v192q0 14 -9 23t-23 9h-128q-14 0 -23 -9t-9 -23v-192h-192q-14 0 -23 -9t-9 -23v-128q0 -14 9 -23t23 -9h192v-192q0 -14 9 -23t23 -9h128q14 0 23 9t9 23v192h192q14 0 23 9t9 23zM1408 384q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5
-t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1664 640q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1920 512q0 -212 -150 -362t-362 -150q-192 0 -338 128h-220q-146 -128 -338 -128q-212 0 -362 150
-t-150 362t150 362t362 150h896q212 0 362 -150t150 -362z" />
-    <glyph glyph-name="keyboard" unicode="&#xf11c;" horiz-adv-x="1920" 
-d="M384 368v-96q0 -16 -16 -16h-96q-16 0 -16 16v96q0 16 16 16h96q16 0 16 -16zM512 624v-96q0 -16 -16 -16h-224q-16 0 -16 16v96q0 16 16 16h224q16 0 16 -16zM384 880v-96q0 -16 -16 -16h-96q-16 0 -16 16v96q0 16 16 16h96q16 0 16 -16zM1408 368v-96q0 -16 -16 -16
-h-864q-16 0 -16 16v96q0 16 16 16h864q16 0 16 -16zM768 624v-96q0 -16 -16 -16h-96q-16 0 -16 16v96q0 16 16 16h96q16 0 16 -16zM640 880v-96q0 -16 -16 -16h-96q-16 0 -16 16v96q0 16 16 16h96q16 0 16 -16zM1024 624v-96q0 -16 -16 -16h-96q-16 0 -16 16v96q0 16 16 16
-h96q16 0 16 -16zM896 880v-96q0 -16 -16 -16h-96q-16 0 -16 16v96q0 16 16 16h96q16 0 16 -16zM1280 624v-96q0 -16 -16 -16h-96q-16 0 -16 16v96q0 16 16 16h96q16 0 16 -16zM1664 368v-96q0 -16 -16 -16h-96q-16 0 -16 16v96q0 16 16 16h96q16 0 16 -16zM1152 880v-96
-q0 -16 -16 -16h-96q-16 0 -16 16v96q0 16 16 16h96q16 0 16 -16zM1408 880v-96q0 -16 -16 -16h-96q-16 0 -16 16v96q0 16 16 16h96q16 0 16 -16zM1664 880v-352q0 -16 -16 -16h-224q-16 0 -16 16v96q0 16 16 16h112v240q0 16 16 16h96q16 0 16 -16zM1792 128v896h-1664v-896
-h1664zM1920 1024v-896q0 -53 -37.5 -90.5t-90.5 -37.5h-1664q-53 0 -90.5 37.5t-37.5 90.5v896q0 53 37.5 90.5t90.5 37.5h1664q53 0 90.5 -37.5t37.5 -90.5z" />
-    <glyph glyph-name="flag_alt" unicode="&#xf11d;" horiz-adv-x="1792" 
-d="M1664 491v616q-169 -91 -306 -91q-82 0 -145 32q-100 49 -184 76.5t-178 27.5q-173 0 -403 -127v-599q245 113 433 113q55 0 103.5 -7.5t98 -26t77 -31t82.5 -39.5l28 -14q44 -22 101 -22q120 0 293 92zM320 1280q0 -35 -17.5 -64t-46.5 -46v-1266q0 -14 -9 -23t-23 -9
-h-64q-14 0 -23 9t-9 23v1266q-29 17 -46.5 46t-17.5 64q0 53 37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1792 1216v-763q0 -39 -35 -57q-10 -5 -17 -9q-218 -116 -369 -116q-88 0 -158 35l-28 14q-64 33 -99 48t-91 29t-114 14q-102 0 -235.5 -44t-228.5 -102
-q-15 -9 -33 -9q-16 0 -32 8q-32 19 -32 56v742q0 35 31 55q35 21 78.5 42.5t114 52t152.5 49.5t155 19q112 0 209 -31t209 -86q38 -19 89 -19q122 0 310 112q22 12 31 17q31 16 62 -2q31 -20 31 -55z" />
-    <glyph glyph-name="flag_checkered" unicode="&#xf11e;" horiz-adv-x="1792" 
-d="M832 536v192q-181 -16 -384 -117v-185q205 96 384 110zM832 954v197q-172 -8 -384 -126v-189q215 111 384 118zM1664 491v184q-235 -116 -384 -71v224q-20 6 -39 15q-5 3 -33 17t-34.5 17t-31.5 15t-34.5 15.5t-32.5 13t-36 12.5t-35 8.5t-39.5 7.5t-39.5 4t-44 2
-q-23 0 -49 -3v-222h19q102 0 192.5 -29t197.5 -82q19 -9 39 -15v-188q42 -17 91 -17q120 0 293 92zM1664 918v189q-169 -91 -306 -91q-45 0 -78 8v-196q148 -42 384 90zM320 1280q0 -35 -17.5 -64t-46.5 -46v-1266q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v1266
-q-29 17 -46.5 46t-17.5 64q0 53 37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1792 1216v-763q0 -39 -35 -57q-10 -5 -17 -9q-218 -116 -369 -116q-88 0 -158 35l-28 14q-64 33 -99 48t-91 29t-114 14q-102 0 -235.5 -44t-228.5 -102q-15 -9 -33 -9q-16 0 -32 8
-q-32 19 -32 56v742q0 35 31 55q35 21 78.5 42.5t114 52t152.5 49.5t155 19q112 0 209 -31t209 -86q38 -19 89 -19q122 0 310 112q22 12 31 17q31 16 62 -2q31 -20 31 -55z" />
-    <glyph glyph-name="terminal" unicode="&#xf120;" horiz-adv-x="1664" 
-d="M585 553l-466 -466q-10 -10 -23 -10t-23 10l-50 50q-10 10 -10 23t10 23l393 393l-393 393q-10 10 -10 23t10 23l50 50q10 10 23 10t23 -10l466 -466q10 -10 10 -23t-10 -23zM1664 96v-64q0 -14 -9 -23t-23 -9h-960q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h960q14 0 23 -9
-t9 -23z" />
-    <glyph glyph-name="code" unicode="&#xf121;" horiz-adv-x="1920" 
-d="M617 137l-50 -50q-10 -10 -23 -10t-23 10l-466 466q-10 10 -10 23t10 23l466 466q10 10 23 10t23 -10l50 -50q10 -10 10 -23t-10 -23l-393 -393l393 -393q10 -10 10 -23t-10 -23zM1208 1204l-373 -1291q-4 -13 -15.5 -19.5t-23.5 -2.5l-62 17q-13 4 -19.5 15.5t-2.5 24.5
-l373 1291q4 13 15.5 19.5t23.5 2.5l62 -17q13 -4 19.5 -15.5t2.5 -24.5zM1865 553l-466 -466q-10 -10 -23 -10t-23 10l-50 50q-10 10 -10 23t10 23l393 393l-393 393q-10 10 -10 23t10 23l50 50q10 10 23 10t23 -10l466 -466q10 -10 10 -23t-10 -23z" />
-    <glyph glyph-name="reply_all" unicode="&#xf122;" horiz-adv-x="1792" 
-d="M640 454v-70q0 -42 -39 -59q-13 -5 -25 -5q-27 0 -45 19l-512 512q-19 19 -19 45t19 45l512 512q29 31 70 14q39 -17 39 -59v-69l-397 -398q-19 -19 -19 -45t19 -45zM1792 416q0 -58 -17 -133.5t-38.5 -138t-48 -125t-40.5 -90.5l-20 -40q-8 -17 -28 -17q-6 0 -9 1
-q-25 8 -23 34q43 400 -106 565q-64 71 -170.5 110.5t-267.5 52.5v-251q0 -42 -39 -59q-13 -5 -25 -5q-27 0 -45 19l-512 512q-19 19 -19 45t19 45l512 512q29 31 70 14q39 -17 39 -59v-262q411 -28 599 -221q169 -173 169 -509z" />
-    <glyph glyph-name="star_half_empty" unicode="&#xf123;" horiz-adv-x="1664" 
-d="M1186 579l257 250l-356 52l-66 10l-30 60l-159 322v-963l59 -31l318 -168l-60 355l-12 66zM1638 841l-363 -354l86 -500q5 -33 -6 -51.5t-34 -18.5q-17 0 -40 12l-449 236l-449 -236q-23 -12 -40 -12q-23 0 -34 18.5t-6 51.5l86 500l-364 354q-32 32 -23 59.5t54 34.5
-l502 73l225 455q20 41 49 41q28 0 49 -41l225 -455l502 -73q45 -7 54 -34.5t-24 -59.5z" />
-    <glyph glyph-name="location_arrow" unicode="&#xf124;" horiz-adv-x="1408" 
-d="M1401 1187l-640 -1280q-17 -35 -57 -35q-5 0 -15 2q-22 5 -35.5 22.5t-13.5 39.5v576h-576q-22 0 -39.5 13.5t-22.5 35.5t4 42t29 30l1280 640q13 7 29 7q27 0 45 -19q15 -14 18.5 -34.5t-6.5 -39.5z" />
-    <glyph glyph-name="crop" unicode="&#xf125;" horiz-adv-x="1664" 
-d="M557 256h595v595zM512 301l595 595h-595v-595zM1664 224v-192q0 -14 -9 -23t-23 -9h-224v-224q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v224h-864q-14 0 -23 9t-9 23v864h-224q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h224v224q0 14 9 23t23 9h192q14 0 23 -9t9 -23
-v-224h851l246 247q10 9 23 9t23 -9q9 -10 9 -23t-9 -23l-247 -246v-851h224q14 0 23 -9t9 -23z" />
-    <glyph glyph-name="code_fork" unicode="&#xf126;" horiz-adv-x="1024" 
-d="M288 64q0 40 -28 68t-68 28t-68 -28t-28 -68t28 -68t68 -28t68 28t28 68zM288 1216q0 40 -28 68t-68 28t-68 -28t-28 -68t28 -68t68 -28t68 28t28 68zM928 1088q0 40 -28 68t-68 28t-68 -28t-28 -68t28 -68t68 -28t68 28t28 68zM1024 1088q0 -52 -26 -96.5t-70 -69.5
-q-2 -287 -226 -414q-67 -38 -203 -81q-128 -40 -169.5 -71t-41.5 -100v-26q44 -25 70 -69.5t26 -96.5q0 -80 -56 -136t-136 -56t-136 56t-56 136q0 52 26 96.5t70 69.5v820q-44 25 -70 69.5t-26 96.5q0 80 56 136t136 56t136 -56t56 -136q0 -52 -26 -96.5t-70 -69.5v-497
-q54 26 154 57q55 17 87.5 29.5t70.5 31t59 39.5t40.5 51t28 69.5t8.5 91.5q-44 25 -70 69.5t-26 96.5q0 80 56 136t136 56t136 -56t56 -136z" />
-    <glyph glyph-name="unlink" unicode="&#xf127;" horiz-adv-x="1664" 
-d="M439 265l-256 -256q-11 -9 -23 -9t-23 9q-9 10 -9 23t9 23l256 256q10 9 23 9t23 -9q9 -10 9 -23t-9 -23zM608 224v-320q0 -14 -9 -23t-23 -9t-23 9t-9 23v320q0 14 9 23t23 9t23 -9t9 -23zM384 448q0 -14 -9 -23t-23 -9h-320q-14 0 -23 9t-9 23t9 23t23 9h320
-q14 0 23 -9t9 -23zM1648 320q0 -120 -85 -203l-147 -146q-83 -83 -203 -83q-121 0 -204 85l-334 335q-21 21 -42 56l239 18l273 -274q27 -27 68 -27.5t68 26.5l147 146q28 28 28 67q0 40 -28 68l-274 275l18 239q35 -21 56 -42l336 -336q84 -86 84 -204zM1031 1044l-239 -18
-l-273 274q-28 28 -68 28q-39 0 -68 -27l-147 -146q-28 -28 -28 -67q0 -40 28 -68l274 -274l-18 -240q-35 21 -56 42l-336 336q-84 86 -84 204q0 120 85 203l147 146q83 83 203 83q121 0 204 -85l334 -335q21 -21 42 -56zM1664 960q0 -14 -9 -23t-23 -9h-320q-14 0 -23 9
-t-9 23t9 23t23 9h320q14 0 23 -9t9 -23zM1120 1504v-320q0 -14 -9 -23t-23 -9t-23 9t-9 23v320q0 14 9 23t23 9t23 -9t9 -23zM1527 1353l-256 -256q-11 -9 -23 -9t-23 9q-9 10 -9 23t9 23l256 256q10 9 23 9t23 -9q9 -10 9 -23t-9 -23z" />
-    <glyph glyph-name="question" unicode="&#xf128;" horiz-adv-x="1024" 
-d="M704 280v-240q0 -16 -12 -28t-28 -12h-240q-16 0 -28 12t-12 28v240q0 16 12 28t28 12h240q16 0 28 -12t12 -28zM1020 880q0 -54 -15.5 -101t-35 -76.5t-55 -59.5t-57.5 -43.5t-61 -35.5q-41 -23 -68.5 -65t-27.5 -67q0 -17 -12 -32.5t-28 -15.5h-240q-15 0 -25.5 18.5
-t-10.5 37.5v45q0 83 65 156.5t143 108.5q59 27 84 56t25 76q0 42 -46.5 74t-107.5 32q-65 0 -108 -29q-35 -25 -107 -115q-13 -16 -31 -16q-12 0 -25 8l-164 125q-13 10 -15.5 25t5.5 28q160 266 464 266q80 0 161 -31t146 -83t106 -127.5t41 -158.5z" />
-    <glyph glyph-name="_279" unicode="&#xf129;" horiz-adv-x="640" 
-d="M640 192v-128q0 -26 -19 -45t-45 -19h-512q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h64v384h-64q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h384q26 0 45 -19t19 -45v-576h64q26 0 45 -19t19 -45zM512 1344v-192q0 -26 -19 -45t-45 -19h-256q-26 0 -45 19t-19 45v192
-q0 26 19 45t45 19h256q26 0 45 -19t19 -45z" />
-    <glyph glyph-name="exclamation" unicode="&#xf12a;" horiz-adv-x="640" 
-d="M512 288v-224q0 -26 -19 -45t-45 -19h-256q-26 0 -45 19t-19 45v224q0 26 19 45t45 19h256q26 0 45 -19t19 -45zM542 1344l-28 -768q-1 -26 -20.5 -45t-45.5 -19h-256q-26 0 -45.5 19t-20.5 45l-28 768q-1 26 17.5 45t44.5 19h320q26 0 44.5 -19t17.5 -45z" />
-    <glyph glyph-name="superscript" unicode="&#xf12b;" 
-d="M897 167v-167h-248l-159 252l-24 42q-8 9 -11 21h-3q-1 -3 -2.5 -6.5t-3.5 -8t-3 -6.5q-10 -20 -25 -44l-155 -250h-258v167h128l197 291l-185 272h-137v168h276l139 -228q2 -4 23 -42q8 -9 11 -21h3q3 9 11 21l25 42l140 228h257v-168h-125l-184 -267l204 -296h109z
-M1534 846v-206h-514l-3 27q-4 28 -4 46q0 64 26 117t65 86.5t84 65t84 54.5t65 54t26 64q0 38 -29.5 62.5t-70.5 24.5q-51 0 -97 -39q-14 -11 -36 -38l-105 92q26 37 63 66q83 65 188 65q110 0 178 -59.5t68 -158.5q0 -56 -24.5 -103t-62 -76.5t-81.5 -58.5t-82 -50.5
-t-65.5 -51.5t-30.5 -63h232v80h126z" />
-    <glyph glyph-name="subscript" unicode="&#xf12c;" 
-d="M897 167v-167h-248l-159 252l-24 42q-8 9 -11 21h-3q-1 -3 -2.5 -6.5t-3.5 -8t-3 -6.5q-10 -20 -25 -44l-155 -250h-258v167h128l197 291l-185 272h-137v168h276l139 -228q2 -4 23 -42q8 -9 11 -21h3q3 9 11 21l25 42l140 228h257v-168h-125l-184 -267l204 -296h109z
-M1536 -50v-206h-514l-4 27q-3 45 -3 46q0 64 26 117t65 86.5t84 65t84 54.5t65 54t26 64q0 38 -29.5 62.5t-70.5 24.5q-51 0 -97 -39q-14 -11 -36 -38l-105 92q26 37 63 66q80 65 188 65q110 0 178 -59.5t68 -158.5q0 -66 -34.5 -118.5t-84 -86t-99.5 -62.5t-87 -63t-41 -73
-h232v80h126z" />
-    <glyph glyph-name="_283" unicode="&#xf12d;" horiz-adv-x="1920" 
-d="M896 128l336 384h-768l-336 -384h768zM1909 1205q15 -34 9.5 -71.5t-30.5 -65.5l-896 -1024q-38 -44 -96 -44h-768q-38 0 -69.5 20.5t-47.5 54.5q-15 34 -9.5 71.5t30.5 65.5l896 1024q38 44 96 44h768q38 0 69.5 -20.5t47.5 -54.5z" />
-    <glyph glyph-name="puzzle_piece" unicode="&#xf12e;" horiz-adv-x="1664" 
-d="M1664 438q0 -81 -44.5 -135t-123.5 -54q-41 0 -77.5 17.5t-59 38t-56.5 38t-71 17.5q-110 0 -110 -124q0 -39 16 -115t15 -115v-5q-22 0 -33 -1q-34 -3 -97.5 -11.5t-115.5 -13.5t-98 -5q-61 0 -103 26.5t-42 83.5q0 37 17.5 71t38 56.5t38 59t17.5 77.5q0 79 -54 123.5
-t-135 44.5q-84 0 -143 -45.5t-59 -127.5q0 -43 15 -83t33.5 -64.5t33.5 -53t15 -50.5q0 -45 -46 -89q-37 -35 -117 -35q-95 0 -245 24q-9 2 -27.5 4t-27.5 4l-13 2q-1 0 -3 1q-2 0 -2 1v1024q2 -1 17.5 -3.5t34 -5t21.5 -3.5q150 -24 245 -24q80 0 117 35q46 44 46 89
-q0 22 -15 50.5t-33.5 53t-33.5 64.5t-15 83q0 82 59 127.5t144 45.5q80 0 134 -44.5t54 -123.5q0 -41 -17.5 -77.5t-38 -59t-38 -56.5t-17.5 -71q0 -57 42 -83.5t103 -26.5q64 0 180 15t163 17v-2q-1 -2 -3.5 -17.5t-5 -34t-3.5 -21.5q-24 -150 -24 -245q0 -80 35 -117
-q44 -46 89 -46q22 0 50.5 15t53 33.5t64.5 33.5t83 15q82 0 127.5 -59t45.5 -143z" />
-    <glyph glyph-name="microphone" unicode="&#xf130;" horiz-adv-x="1152" 
-d="M1152 832v-128q0 -221 -147.5 -384.5t-364.5 -187.5v-132h256q26 0 45 -19t19 -45t-19 -45t-45 -19h-640q-26 0 -45 19t-19 45t19 45t45 19h256v132q-217 24 -364.5 187.5t-147.5 384.5v128q0 26 19 45t45 19t45 -19t19 -45v-128q0 -185 131.5 -316.5t316.5 -131.5
-t316.5 131.5t131.5 316.5v128q0 26 19 45t45 19t45 -19t19 -45zM896 1216v-512q0 -132 -94 -226t-226 -94t-226 94t-94 226v512q0 132 94 226t226 94t226 -94t94 -226z" />
-    <glyph glyph-name="microphone_off" unicode="&#xf131;" horiz-adv-x="1408" 
-d="M271 591l-101 -101q-42 103 -42 214v128q0 26 19 45t45 19t45 -19t19 -45v-128q0 -53 15 -113zM1385 1193l-361 -361v-128q0 -132 -94 -226t-226 -94q-55 0 -109 19l-96 -96q97 -51 205 -51q185 0 316.5 131.5t131.5 316.5v128q0 26 19 45t45 19t45 -19t19 -45v-128
-q0 -221 -147.5 -384.5t-364.5 -187.5v-132h256q26 0 45 -19t19 -45t-19 -45t-45 -19h-640q-26 0 -45 19t-19 45t19 45t45 19h256v132q-125 13 -235 81l-254 -254q-10 -10 -23 -10t-23 10l-82 82q-10 10 -10 23t10 23l1234 1234q10 10 23 10t23 -10l82 -82q10 -10 10 -23
-t-10 -23zM1005 1325l-621 -621v512q0 132 94 226t226 94q102 0 184.5 -59t116.5 -152z" />
-    <glyph glyph-name="shield" unicode="&#xf132;" horiz-adv-x="1280" 
-d="M1088 576v640h-448v-1137q119 63 213 137q235 184 235 360zM1280 1344v-768q0 -86 -33.5 -170.5t-83 -150t-118 -127.5t-126.5 -103t-121 -77.5t-89.5 -49.5t-42.5 -20q-12 -6 -26 -6t-26 6q-16 7 -42.5 20t-89.5 49.5t-121 77.5t-126.5 103t-118 127.5t-83 150
-t-33.5 170.5v768q0 26 19 45t45 19h1152q26 0 45 -19t19 -45z" />
-    <glyph glyph-name="calendar_empty" unicode="&#xf133;" horiz-adv-x="1664" 
-d="M128 -128h1408v1024h-1408v-1024zM512 1088v288q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-288q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM1280 1088v288q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-288q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM1664 1152v-1280
-q0 -52 -38 -90t-90 -38h-1408q-52 0 -90 38t-38 90v1280q0 52 38 90t90 38h128v96q0 66 47 113t113 47h64q66 0 113 -47t47 -113v-96h384v96q0 66 47 113t113 47h64q66 0 113 -47t47 -113v-96h128q52 0 90 -38t38 -90z" />
-    <glyph glyph-name="fire_extinguisher" unicode="&#xf134;" horiz-adv-x="1408" 
-d="M512 1344q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1408 1376v-320q0 -16 -12 -25q-8 -7 -20 -7q-4 0 -7 1l-448 96q-11 2 -18 11t-7 20h-256v-102q111 -23 183.5 -111t72.5 -203v-800q0 -26 -19 -45t-45 -19h-512q-26 0 -45 19t-19 45v800
-q0 106 62.5 190.5t161.5 114.5v111h-32q-59 0 -115 -23.5t-91.5 -53t-66 -66.5t-40.5 -53.5t-14 -24.5q-17 -35 -57 -35q-16 0 -29 7q-23 12 -31.5 37t3.5 49q5 10 14.5 26t37.5 53.5t60.5 70t85 67t108.5 52.5q-25 42 -25 86q0 66 47 113t113 47t113 -47t47 -113
-q0 -33 -14 -64h302q0 11 7 20t18 11l448 96q3 1 7 1q12 0 20 -7q12 -9 12 -25z" />
-    <glyph glyph-name="rocket" unicode="&#xf135;" horiz-adv-x="1664" 
-d="M1440 1088q0 40 -28 68t-68 28t-68 -28t-28 -68t28 -68t68 -28t68 28t28 68zM1664 1376q0 -249 -75.5 -430.5t-253.5 -360.5q-81 -80 -195 -176l-20 -379q-2 -16 -16 -26l-384 -224q-7 -4 -16 -4q-12 0 -23 9l-64 64q-13 14 -8 32l85 276l-281 281l-276 -85q-3 -1 -9 -1
-q-14 0 -23 9l-64 64q-17 19 -5 39l224 384q10 14 26 16l379 20q96 114 176 195q188 187 358 258t431 71q14 0 24 -9.5t10 -22.5z" />
-    <glyph glyph-name="maxcdn" unicode="&#xf136;" horiz-adv-x="1792" 
-d="M1745 763l-164 -763h-334l178 832q13 56 -15 88q-27 33 -83 33h-169l-204 -953h-334l204 953h-286l-204 -953h-334l204 953l-153 327h1276q101 0 189.5 -40.5t147.5 -113.5q60 -73 81 -168.5t0 -194.5z" />
-    <glyph glyph-name="chevron_sign_left" unicode="&#xf137;" 
-d="M909 141l102 102q19 19 19 45t-19 45l-307 307l307 307q19 19 19 45t-19 45l-102 102q-19 19 -45 19t-45 -19l-454 -454q-19 -19 -19 -45t19 -45l454 -454q19 -19 45 -19t45 19zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5
-t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
-    <glyph glyph-name="chevron_sign_right" unicode="&#xf138;" 
-d="M717 141l454 454q19 19 19 45t-19 45l-454 454q-19 19 -45 19t-45 -19l-102 -102q-19 -19 -19 -45t19 -45l307 -307l-307 -307q-19 -19 -19 -45t19 -45l102 -102q19 -19 45 -19t45 19zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5
-t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
-    <glyph glyph-name="chevron_sign_up" unicode="&#xf139;" 
-d="M1165 397l102 102q19 19 19 45t-19 45l-454 454q-19 19 -45 19t-45 -19l-454 -454q-19 -19 -19 -45t19 -45l102 -102q19 -19 45 -19t45 19l307 307l307 -307q19 -19 45 -19t45 19zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5
-t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
-    <glyph glyph-name="chevron_sign_down" unicode="&#xf13a;" 
-d="M813 237l454 454q19 19 19 45t-19 45l-102 102q-19 19 -45 19t-45 -19l-307 -307l-307 307q-19 19 -45 19t-45 -19l-102 -102q-19 -19 -19 -45t19 -45l454 -454q19 -19 45 -19t45 19zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5
-t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
-    <glyph glyph-name="html5" unicode="&#xf13b;" horiz-adv-x="1408" 
-d="M1130 939l16 175h-884l47 -534h612l-22 -228l-197 -53l-196 53l-13 140h-175l22 -278l362 -100h4v1l359 99l50 544h-644l-15 181h674zM0 1408h1408l-128 -1438l-578 -162l-574 162z" />
-    <glyph glyph-name="css3" unicode="&#xf13c;" horiz-adv-x="1792" 
-d="M275 1408h1505l-266 -1333l-804 -267l-698 267l71 356h297l-29 -147l422 -161l486 161l68 339h-1208l58 297h1209l38 191h-1208z" />
-    <glyph glyph-name="anchor" unicode="&#xf13d;" horiz-adv-x="1792" 
-d="M960 1280q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1792 352v-352q0 -22 -20 -30q-8 -2 -12 -2q-12 0 -23 9l-93 93q-119 -143 -318.5 -226.5t-429.5 -83.5t-429.5 83.5t-318.5 226.5l-93 -93q-9 -9 -23 -9q-4 0 -12 2q-20 8 -20 30v352
-q0 14 9 23t23 9h352q22 0 30 -20q8 -19 -7 -35l-100 -100q67 -91 189.5 -153.5t271.5 -82.5v647h-192q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h192v163q-58 34 -93 92.5t-35 128.5q0 106 75 181t181 75t181 -75t75 -181q0 -70 -35 -128.5t-93 -92.5v-163h192q26 0 45 -19
-t19 -45v-128q0 -26 -19 -45t-45 -19h-192v-647q149 20 271.5 82.5t189.5 153.5l-100 100q-15 16 -7 35q8 20 30 20h352q14 0 23 -9t9 -23z" />
-    <glyph glyph-name="unlock_alt" unicode="&#xf13e;" horiz-adv-x="1152" 
-d="M1056 768q40 0 68 -28t28 -68v-576q0 -40 -28 -68t-68 -28h-960q-40 0 -68 28t-28 68v576q0 40 28 68t68 28h32v320q0 185 131.5 316.5t316.5 131.5t316.5 -131.5t131.5 -316.5q0 -26 -19 -45t-45 -19h-64q-26 0 -45 19t-19 45q0 106 -75 181t-181 75t-181 -75t-75 -181
-v-320h736z" />
-    <glyph glyph-name="bullseye" unicode="&#xf140;" 
-d="M1024 640q0 -106 -75 -181t-181 -75t-181 75t-75 181t75 181t181 75t181 -75t75 -181zM1152 640q0 159 -112.5 271.5t-271.5 112.5t-271.5 -112.5t-112.5 -271.5t112.5 -271.5t271.5 -112.5t271.5 112.5t112.5 271.5zM1280 640q0 -212 -150 -362t-362 -150t-362 150
-t-150 362t150 362t362 150t362 -150t150 -362zM1408 640q0 130 -51 248.5t-136.5 204t-204 136.5t-248.5 51t-248.5 -51t-204 -136.5t-136.5 -204t-51 -248.5t51 -248.5t136.5 -204t204 -136.5t248.5 -51t248.5 51t204 136.5t136.5 204t51 248.5zM1536 640
-q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
-    <glyph glyph-name="ellipsis_horizontal" unicode="&#xf141;" horiz-adv-x="1408" 
-d="M384 800v-192q0 -40 -28 -68t-68 -28h-192q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h192q40 0 68 -28t28 -68zM896 800v-192q0 -40 -28 -68t-68 -28h-192q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h192q40 0 68 -28t28 -68zM1408 800v-192q0 -40 -28 -68t-68 -28h-192
-q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h192q40 0 68 -28t28 -68z" />
-    <glyph glyph-name="ellipsis_vertical" unicode="&#xf142;" horiz-adv-x="384" 
-d="M384 288v-192q0 -40 -28 -68t-68 -28h-192q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h192q40 0 68 -28t28 -68zM384 800v-192q0 -40 -28 -68t-68 -28h-192q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h192q40 0 68 -28t28 -68zM384 1312v-192q0 -40 -28 -68t-68 -28h-192
-q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h192q40 0 68 -28t28 -68z" />
-    <glyph glyph-name="_303" unicode="&#xf143;" 
-d="M512 256q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM863 162q-13 233 -176.5 396.5t-396.5 176.5q-14 1 -24 -9t-10 -23v-128q0 -13 8.5 -22t21.5 -10q154 -11 264 -121t121 -264q1 -13 10 -21.5t22 -8.5h128
-q13 0 23 10t9 24zM1247 161q-5 154 -56 297.5t-139.5 260t-205 205t-260 139.5t-297.5 56q-14 1 -23 -9q-10 -10 -10 -23v-128q0 -13 9 -22t22 -10q204 -7 378 -111.5t278.5 -278.5t111.5 -378q1 -13 10 -22t22 -9h128q13 0 23 10q11 9 9 23zM1536 1120v-960
-q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
-    <glyph glyph-name="play_sign" unicode="&#xf144;" 
-d="M768 1408q209 0 385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103zM1152 585q32 18 32 55t-32 55l-544 320q-31 19 -64 1q-32 -19 -32 -56v-640q0 -37 32 -56
-q16 -8 32 -8q17 0 32 9z" />
-    <glyph glyph-name="ticket" unicode="&#xf145;" horiz-adv-x="1792" 
-d="M1024 1084l316 -316l-572 -572l-316 316zM813 105l618 618q19 19 19 45t-19 45l-362 362q-18 18 -45 18t-45 -18l-618 -618q-19 -19 -19 -45t19 -45l362 -362q18 -18 45 -18t45 18zM1702 742l-907 -908q-37 -37 -90.5 -37t-90.5 37l-126 126q56 56 56 136t-56 136
-t-136 56t-136 -56l-125 126q-37 37 -37 90.5t37 90.5l907 906q37 37 90.5 37t90.5 -37l125 -125q-56 -56 -56 -136t56 -136t136 -56t136 56l126 -125q37 -37 37 -90.5t-37 -90.5z" />
-    <glyph glyph-name="minus_sign_alt" unicode="&#xf146;" 
-d="M1280 576v128q0 26 -19 45t-45 19h-896q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45t45 -19h896q26 0 45 19t19 45zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5
-t84.5 -203.5z" />
-    <glyph glyph-name="check_minus" unicode="&#xf147;" horiz-adv-x="1408" 
-d="M1152 736v-64q0 -14 -9 -23t-23 -9h-832q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h832q14 0 23 -9t9 -23zM1280 288v832q0 66 -47 113t-113 47h-832q-66 0 -113 -47t-47 -113v-832q0 -66 47 -113t113 -47h832q66 0 113 47t47 113zM1408 1120v-832q0 -119 -84.5 -203.5
-t-203.5 -84.5h-832q-119 0 -203.5 84.5t-84.5 203.5v832q0 119 84.5 203.5t203.5 84.5h832q119 0 203.5 -84.5t84.5 -203.5z" />
-    <glyph glyph-name="level_up" unicode="&#xf148;" horiz-adv-x="1024" 
-d="M1018 933q-18 -37 -58 -37h-192v-864q0 -14 -9 -23t-23 -9h-704q-21 0 -29 18q-8 20 4 35l160 192q9 11 25 11h320v640h-192q-40 0 -58 37q-17 37 9 68l320 384q18 22 49 22t49 -22l320 -384q27 -32 9 -68z" />
-    <glyph glyph-name="level_down" unicode="&#xf149;" horiz-adv-x="1024" 
-d="M32 1280h704q13 0 22.5 -9.5t9.5 -23.5v-863h192q40 0 58 -37t-9 -69l-320 -384q-18 -22 -49 -22t-49 22l-320 384q-26 31 -9 69q18 37 58 37h192v640h-320q-14 0 -25 11l-160 192q-13 14 -4 34q9 19 29 19z" />
-    <glyph glyph-name="check_sign" unicode="&#xf14a;" 
-d="M685 237l614 614q19 19 19 45t-19 45l-102 102q-19 19 -45 19t-45 -19l-467 -467l-211 211q-19 19 -45 19t-45 -19l-102 -102q-19 -19 -19 -45t19 -45l358 -358q19 -19 45 -19t45 19zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5
-t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
-    <glyph glyph-name="edit_sign" unicode="&#xf14b;" 
-d="M404 428l152 -152l-52 -52h-56v96h-96v56zM818 818q14 -13 -3 -30l-291 -291q-17 -17 -30 -3q-14 13 3 30l291 291q17 17 30 3zM544 128l544 544l-288 288l-544 -544v-288h288zM1152 736l92 92q28 28 28 68t-28 68l-152 152q-28 28 -68 28t-68 -28l-92 -92zM1536 1120
-v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
-    <glyph glyph-name="_312" unicode="&#xf14c;" 
-d="M1280 608v480q0 26 -19 45t-45 19h-480q-42 0 -59 -39q-17 -41 14 -70l144 -144l-534 -534q-19 -19 -19 -45t19 -45l102 -102q19 -19 45 -19t45 19l534 534l144 -144q18 -19 45 -19q12 0 25 5q39 17 39 59zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960
-q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
-    <glyph glyph-name="share_sign" unicode="&#xf14d;" 
-d="M1005 435l352 352q19 19 19 45t-19 45l-352 352q-30 31 -69 14q-40 -17 -40 -59v-160q-119 0 -216 -19.5t-162.5 -51t-114 -79t-76.5 -95.5t-44.5 -109t-21.5 -111.5t-5 -110.5q0 -181 167 -404q11 -12 25 -12q7 0 13 3q22 9 19 33q-44 354 62 473q46 52 130 75.5
-t224 23.5v-160q0 -42 40 -59q12 -5 24 -5q26 0 45 19zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
-    <glyph glyph-name="compass" unicode="&#xf14e;" 
-d="M640 448l256 128l-256 128v-256zM1024 1039v-542l-512 -256v542zM1312 640q0 148 -73 273t-198 198t-273 73t-273 -73t-198 -198t-73 -273t73 -273t198 -198t273 -73t273 73t198 198t73 273zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103
-t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
-    <glyph glyph-name="collapse" unicode="&#xf150;" 
-d="M1145 861q18 -35 -5 -66l-320 -448q-19 -27 -52 -27t-52 27l-320 448q-23 31 -5 66q17 35 57 35h640q40 0 57 -35zM1280 160v960q0 13 -9.5 22.5t-22.5 9.5h-960q-13 0 -22.5 -9.5t-9.5 -22.5v-960q0 -13 9.5 -22.5t22.5 -9.5h960q13 0 22.5 9.5t9.5 22.5zM1536 1120
-v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
-    <glyph glyph-name="collapse_top" unicode="&#xf151;" 
-d="M1145 419q-17 -35 -57 -35h-640q-40 0 -57 35q-18 35 5 66l320 448q19 27 52 27t52 -27l320 -448q23 -31 5 -66zM1280 160v960q0 13 -9.5 22.5t-22.5 9.5h-960q-13 0 -22.5 -9.5t-9.5 -22.5v-960q0 -13 9.5 -22.5t22.5 -9.5h960q13 0 22.5 9.5t9.5 22.5zM1536 1120v-960
-q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
-    <glyph glyph-name="_317" unicode="&#xf152;" 
-d="M1088 640q0 -33 -27 -52l-448 -320q-31 -23 -66 -5q-35 17 -35 57v640q0 40 35 57q35 18 66 -5l448 -320q27 -19 27 -52zM1280 160v960q0 14 -9 23t-23 9h-960q-14 0 -23 -9t-9 -23v-960q0 -14 9 -23t23 -9h960q14 0 23 9t9 23zM1536 1120v-960q0 -119 -84.5 -203.5
-t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
-    <glyph glyph-name="eur" unicode="&#xf153;" horiz-adv-x="1024" 
-d="M976 229l35 -159q3 -12 -3 -22.5t-17 -14.5l-5 -1q-4 -2 -10.5 -3.5t-16 -4.5t-21.5 -5.5t-25.5 -5t-30 -5t-33.5 -4.5t-36.5 -3t-38.5 -1q-234 0 -409 130.5t-238 351.5h-95q-13 0 -22.5 9.5t-9.5 22.5v113q0 13 9.5 22.5t22.5 9.5h66q-2 57 1 105h-67q-14 0 -23 9
-t-9 23v114q0 14 9 23t23 9h98q67 210 243.5 338t400.5 128q102 0 194 -23q11 -3 20 -15q6 -11 3 -24l-43 -159q-3 -13 -14 -19.5t-24 -2.5l-4 1q-4 1 -11.5 2.5l-17.5 3.5t-22.5 3.5t-26 3t-29 2.5t-29.5 1q-126 0 -226 -64t-150 -176h468q16 0 25 -12q10 -12 7 -26
-l-24 -114q-5 -26 -32 -26h-488q-3 -37 0 -105h459q15 0 25 -12q9 -12 6 -27l-24 -112q-2 -11 -11 -18.5t-20 -7.5h-387q48 -117 149.5 -185.5t228.5 -68.5q18 0 36 1.5t33.5 3.5t29.5 4.5t24.5 5t18.5 4.5l12 3l5 2q13 5 26 -2q12 -7 15 -21z" />
-    <glyph glyph-name="gbp" unicode="&#xf154;" horiz-adv-x="1024" 
-d="M1020 399v-367q0 -14 -9 -23t-23 -9h-956q-14 0 -23 9t-9 23v150q0 13 9.5 22.5t22.5 9.5h97v383h-95q-14 0 -23 9.5t-9 22.5v131q0 14 9 23t23 9h95v223q0 171 123.5 282t314.5 111q185 0 335 -125q9 -8 10 -20.5t-7 -22.5l-103 -127q-9 -11 -22 -12q-13 -2 -23 7
-q-5 5 -26 19t-69 32t-93 18q-85 0 -137 -47t-52 -123v-215h305q13 0 22.5 -9t9.5 -23v-131q0 -13 -9.5 -22.5t-22.5 -9.5h-305v-379h414v181q0 13 9 22.5t23 9.5h162q14 0 23 -9.5t9 -22.5z" />
-    <glyph glyph-name="usd" unicode="&#xf155;" horiz-adv-x="1024" 
-d="M978 351q0 -153 -99.5 -263.5t-258.5 -136.5v-175q0 -14 -9 -23t-23 -9h-135q-13 0 -22.5 9.5t-9.5 22.5v175q-66 9 -127.5 31t-101.5 44.5t-74 48t-46.5 37.5t-17.5 18q-17 21 -2 41l103 135q7 10 23 12q15 2 24 -9l2 -2q113 -99 243 -125q37 -8 74 -8q81 0 142.5 43
-t61.5 122q0 28 -15 53t-33.5 42t-58.5 37.5t-66 32t-80 32.5q-39 16 -61.5 25t-61.5 26.5t-62.5 31t-56.5 35.5t-53.5 42.5t-43.5 49t-35.5 58t-21 66.5t-8.5 78q0 138 98 242t255 134v180q0 13 9.5 22.5t22.5 9.5h135q14 0 23 -9t9 -23v-176q57 -6 110.5 -23t87 -33.5
-t63.5 -37.5t39 -29t15 -14q17 -18 5 -38l-81 -146q-8 -15 -23 -16q-14 -3 -27 7q-3 3 -14.5 12t-39 26.5t-58.5 32t-74.5 26t-85.5 11.5q-95 0 -155 -43t-60 -111q0 -26 8.5 -48t29.5 -41.5t39.5 -33t56 -31t60.5 -27t70 -27.5q53 -20 81 -31.5t76 -35t75.5 -42.5t62 -50
-t53 -63.5t31.5 -76.5t13 -94z" />
-    <glyph glyph-name="inr" unicode="&#xf156;" horiz-adv-x="898" 
-d="M898 1066v-102q0 -14 -9 -23t-23 -9h-168q-23 -144 -129 -234t-276 -110q167 -178 459 -536q14 -16 4 -34q-8 -18 -29 -18h-195q-16 0 -25 12q-306 367 -498 571q-9 9 -9 22v127q0 13 9.5 22.5t22.5 9.5h112q132 0 212.5 43t102.5 125h-427q-14 0 -23 9t-9 23v102
-q0 14 9 23t23 9h413q-57 113 -268 113h-145q-13 0 -22.5 9.5t-9.5 22.5v133q0 14 9 23t23 9h832q14 0 23 -9t9 -23v-102q0 -14 -9 -23t-23 -9h-233q47 -61 64 -144h171q14 0 23 -9t9 -23z" />
-    <glyph glyph-name="jpy" unicode="&#xf157;" horiz-adv-x="1027" 
-d="M603 0h-172q-13 0 -22.5 9t-9.5 23v330h-288q-13 0 -22.5 9t-9.5 23v103q0 13 9.5 22.5t22.5 9.5h288v85h-288q-13 0 -22.5 9t-9.5 23v104q0 13 9.5 22.5t22.5 9.5h214l-321 578q-8 16 0 32q10 16 28 16h194q19 0 29 -18l215 -425q19 -38 56 -125q10 24 30.5 68t27.5 61
-l191 420q8 19 29 19h191q17 0 27 -16q9 -14 1 -31l-313 -579h215q13 0 22.5 -9.5t9.5 -22.5v-104q0 -14 -9.5 -23t-22.5 -9h-290v-85h290q13 0 22.5 -9.5t9.5 -22.5v-103q0 -14 -9.5 -23t-22.5 -9h-290v-330q0 -13 -9.5 -22.5t-22.5 -9.5z" />
-    <glyph glyph-name="rub" unicode="&#xf158;" horiz-adv-x="1280" 
-d="M1043 971q0 100 -65 162t-171 62h-320v-448h320q106 0 171 62t65 162zM1280 971q0 -193 -126.5 -315t-326.5 -122h-340v-118h505q14 0 23 -9t9 -23v-128q0 -14 -9 -23t-23 -9h-505v-192q0 -14 -9.5 -23t-22.5 -9h-167q-14 0 -23 9t-9 23v192h-224q-14 0 -23 9t-9 23v128
-q0 14 9 23t23 9h224v118h-224q-14 0 -23 9t-9 23v149q0 13 9 22.5t23 9.5h224v629q0 14 9 23t23 9h539q200 0 326.5 -122t126.5 -315z" />
-    <glyph glyph-name="krw" unicode="&#xf159;" horiz-adv-x="1792" 
-d="M514 341l81 299h-159l75 -300q1 -1 1 -3t1 -3q0 1 0.5 3.5t0.5 3.5zM630 768l35 128h-292l32 -128h225zM822 768h139l-35 128h-70zM1271 340l78 300h-162l81 -299q0 -1 0.5 -3.5t1.5 -3.5q0 1 0.5 3t0.5 3zM1382 768l33 128h-297l34 -128h230zM1792 736v-64q0 -14 -9 -23
-t-23 -9h-213l-164 -616q-7 -24 -31 -24h-159q-24 0 -31 24l-166 616h-209l-167 -616q-7 -24 -31 -24h-159q-11 0 -19.5 7t-10.5 17l-160 616h-208q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h175l-33 128h-142q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h109l-89 344q-5 15 5 28
-q10 12 26 12h137q26 0 31 -24l90 -360h359l97 360q7 24 31 24h126q24 0 31 -24l98 -360h365l93 360q5 24 31 24h137q16 0 26 -12q10 -13 5 -28l-91 -344h111q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-145l-34 -128h179q14 0 23 -9t9 -23z" />
-    <glyph glyph-name="btc" unicode="&#xf15a;" horiz-adv-x="1280" 
-d="M1167 896q18 -182 -131 -258q117 -28 175 -103t45 -214q-7 -71 -32.5 -125t-64.5 -89t-97 -58.5t-121.5 -34.5t-145.5 -15v-255h-154v251q-80 0 -122 1v-252h-154v255q-18 0 -54 0.5t-55 0.5h-200l31 183h111q50 0 58 51v402h16q-6 1 -16 1v287q-13 68 -89 68h-111v164
-l212 -1q64 0 97 1v252h154v-247q82 2 122 2v245h154v-252q79 -7 140 -22.5t113 -45t82.5 -78t36.5 -114.5zM952 351q0 36 -15 64t-37 46t-57.5 30.5t-65.5 18.5t-74 9t-69 3t-64.5 -1t-47.5 -1v-338q8 0 37 -0.5t48 -0.5t53 1.5t58.5 4t57 8.5t55.5 14t47.5 21t39.5 30
-t24.5 40t9.5 51zM881 827q0 33 -12.5 58.5t-30.5 42t-48 28t-55 16.5t-61.5 8t-58 2.5t-54 -1t-39.5 -0.5v-307q5 0 34.5 -0.5t46.5 0t50 2t55 5.5t51.5 11t48.5 18.5t37 27t27 38.5t9 51z" />
-    <glyph glyph-name="file" unicode="&#xf15b;" 
-d="M1024 1024v472q22 -14 36 -28l408 -408q14 -14 28 -36h-472zM896 992q0 -40 28 -68t68 -28h544v-1056q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68v1600q0 40 28 68t68 28h800v-544z" />
-    <glyph glyph-name="file_text" unicode="&#xf15c;" 
-d="M1468 1060q14 -14 28 -36h-472v472q22 -14 36 -28zM992 896h544v-1056q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68v1600q0 40 28 68t68 28h800v-544q0 -40 28 -68t68 -28zM1152 160v64q0 14 -9 23t-23 9h-704q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h704
-q14 0 23 9t9 23zM1152 416v64q0 14 -9 23t-23 9h-704q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h704q14 0 23 9t9 23zM1152 672v64q0 14 -9 23t-23 9h-704q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h704q14 0 23 9t9 23z" />
-    <glyph glyph-name="sort_by_alphabet" unicode="&#xf15d;" horiz-adv-x="1664" 
-d="M1191 1128h177l-72 218l-12 47q-2 16 -2 20h-4l-3 -20q0 -1 -3.5 -18t-7.5 -29zM736 96q0 -12 -10 -24l-319 -319q-10 -9 -23 -9q-12 0 -23 9l-320 320q-15 16 -7 35q8 20 30 20h192v1376q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-1376h192q14 0 23 -9t9 -23zM1572 -23
-v-233h-584v90l369 529q12 18 21 27l11 9v3q-2 0 -6.5 -0.5t-7.5 -0.5q-12 -3 -30 -3h-232v-115h-120v229h567v-89l-369 -530q-6 -8 -21 -26l-11 -11v-2l14 2q9 2 30 2h248v119h121zM1661 874v-106h-288v106h75l-47 144h-243l-47 -144h75v-106h-287v106h70l230 662h162
-l230 -662h70z" />
-    <glyph glyph-name="_329" unicode="&#xf15e;" horiz-adv-x="1664" 
-d="M1191 104h177l-72 218l-12 47q-2 16 -2 20h-4l-3 -20q0 -1 -3.5 -18t-7.5 -29zM736 96q0 -12 -10 -24l-319 -319q-10 -9 -23 -9q-12 0 -23 9l-320 320q-15 16 -7 35q8 20 30 20h192v1376q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-1376h192q14 0 23 -9t9 -23zM1661 -150
-v-106h-288v106h75l-47 144h-243l-47 -144h75v-106h-287v106h70l230 662h162l230 -662h70zM1572 1001v-233h-584v90l369 529q12 18 21 27l11 9v3q-2 0 -6.5 -0.5t-7.5 -0.5q-12 -3 -30 -3h-232v-115h-120v229h567v-89l-369 -530q-6 -8 -21 -26l-11 -10v-3l14 3q9 1 30 1h248
-v119h121z" />
-    <glyph glyph-name="sort_by_attributes" unicode="&#xf160;" horiz-adv-x="1792" 
-d="M736 96q0 -12 -10 -24l-319 -319q-10 -9 -23 -9q-12 0 -23 9l-320 320q-15 16 -7 35q8 20 30 20h192v1376q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-1376h192q14 0 23 -9t9 -23zM1792 -32v-192q0 -14 -9 -23t-23 -9h-832q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h832
-q14 0 23 -9t9 -23zM1600 480v-192q0 -14 -9 -23t-23 -9h-640q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h640q14 0 23 -9t9 -23zM1408 992v-192q0 -14 -9 -23t-23 -9h-448q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h448q14 0 23 -9t9 -23zM1216 1504v-192q0 -14 -9 -23t-23 -9h-256
-q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h256q14 0 23 -9t9 -23z" />
-    <glyph glyph-name="sort_by_attributes_alt" unicode="&#xf161;" horiz-adv-x="1792" 
-d="M1216 -32v-192q0 -14 -9 -23t-23 -9h-256q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h256q14 0 23 -9t9 -23zM736 96q0 -12 -10 -24l-319 -319q-10 -9 -23 -9q-12 0 -23 9l-320 320q-15 16 -7 35q8 20 30 20h192v1376q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-1376h192
-q14 0 23 -9t9 -23zM1408 480v-192q0 -14 -9 -23t-23 -9h-448q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h448q14 0 23 -9t9 -23zM1600 992v-192q0 -14 -9 -23t-23 -9h-640q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h640q14 0 23 -9t9 -23zM1792 1504v-192q0 -14 -9 -23t-23 -9h-832
-q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h832q14 0 23 -9t9 -23z" />
-    <glyph glyph-name="sort_by_order" unicode="&#xf162;" 
-d="M1346 223q0 63 -44 116t-103 53q-52 0 -83 -37t-31 -94t36.5 -95t104.5 -38q50 0 85 27t35 68zM736 96q0 -12 -10 -24l-319 -319q-10 -9 -23 -9q-12 0 -23 9l-320 320q-15 16 -7 35q8 20 30 20h192v1376q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-1376h192q14 0 23 -9t9 -23
-zM1486 165q0 -62 -13 -121.5t-41 -114t-68 -95.5t-98.5 -65.5t-127.5 -24.5q-62 0 -108 16q-24 8 -42 15l39 113q15 -7 31 -11q37 -13 75 -13q84 0 134.5 58.5t66.5 145.5h-2q-21 -23 -61.5 -37t-84.5 -14q-106 0 -173 71.5t-67 172.5q0 105 72 178t181 73q123 0 205 -94.5
-t82 -252.5zM1456 882v-114h-469v114h167v432q0 7 0.5 19t0.5 17v16h-2l-7 -12q-8 -13 -26 -31l-62 -58l-82 86l192 185h123v-654h165z" />
-    <glyph glyph-name="sort_by_order_alt" unicode="&#xf163;" 
-d="M1346 1247q0 63 -44 116t-103 53q-52 0 -83 -37t-31 -94t36.5 -95t104.5 -38q50 0 85 27t35 68zM736 96q0 -12 -10 -24l-319 -319q-10 -9 -23 -9q-12 0 -23 9l-320 320q-15 16 -7 35q8 20 30 20h192v1376q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-1376h192q14 0 23 -9
-t9 -23zM1456 -142v-114h-469v114h167v432q0 7 0.5 19t0.5 17v16h-2l-7 -12q-8 -13 -26 -31l-62 -58l-82 86l192 185h123v-654h165zM1486 1189q0 -62 -13 -121.5t-41 -114t-68 -95.5t-98.5 -65.5t-127.5 -24.5q-62 0 -108 16q-24 8 -42 15l39 113q15 -7 31 -11q37 -13 75 -13
-q84 0 134.5 58.5t66.5 145.5h-2q-21 -23 -61.5 -37t-84.5 -14q-106 0 -173 71.5t-67 172.5q0 105 72 178t181 73q123 0 205 -94.5t82 -252.5z" />
-    <glyph glyph-name="_334" unicode="&#xf164;" horiz-adv-x="1664" 
-d="M256 192q0 26 -19 45t-45 19q-27 0 -45.5 -19t-18.5 -45q0 -27 18.5 -45.5t45.5 -18.5q26 0 45 18.5t19 45.5zM416 704v-640q0 -26 -19 -45t-45 -19h-288q-26 0 -45 19t-19 45v640q0 26 19 45t45 19h288q26 0 45 -19t19 -45zM1600 704q0 -86 -55 -149q15 -44 15 -76
-q3 -76 -43 -137q17 -56 0 -117q-15 -57 -54 -94q9 -112 -49 -181q-64 -76 -197 -78h-36h-76h-17q-66 0 -144 15.5t-121.5 29t-120.5 39.5q-123 43 -158 44q-26 1 -45 19.5t-19 44.5v641q0 25 18 43.5t43 20.5q24 2 76 59t101 121q68 87 101 120q18 18 31 48t17.5 48.5
-t13.5 60.5q7 39 12.5 61t19.5 52t34 50q19 19 45 19q46 0 82.5 -10.5t60 -26t40 -40.5t24 -45t12 -50t5 -45t0.5 -39q0 -38 -9.5 -76t-19 -60t-27.5 -56q-3 -6 -10 -18t-11 -22t-8 -24h277q78 0 135 -57t57 -135z" />
-    <glyph glyph-name="_335" unicode="&#xf165;" horiz-adv-x="1664" 
-d="M256 960q0 -26 -19 -45t-45 -19q-27 0 -45.5 19t-18.5 45q0 27 18.5 45.5t45.5 18.5q26 0 45 -18.5t19 -45.5zM416 448v640q0 26 -19 45t-45 19h-288q-26 0 -45 -19t-19 -45v-640q0 -26 19 -45t45 -19h288q26 0 45 19t19 45zM1545 597q55 -61 55 -149q-1 -78 -57.5 -135
-t-134.5 -57h-277q4 -14 8 -24t11 -22t10 -18q18 -37 27 -57t19 -58.5t10 -76.5q0 -24 -0.5 -39t-5 -45t-12 -50t-24 -45t-40 -40.5t-60 -26t-82.5 -10.5q-26 0 -45 19q-20 20 -34 50t-19.5 52t-12.5 61q-9 42 -13.5 60.5t-17.5 48.5t-31 48q-33 33 -101 120q-49 64 -101 121
-t-76 59q-25 2 -43 20.5t-18 43.5v641q0 26 19 44.5t45 19.5q35 1 158 44q77 26 120.5 39.5t121.5 29t144 15.5h17h76h36q133 -2 197 -78q58 -69 49 -181q39 -37 54 -94q17 -61 0 -117q46 -61 43 -137q0 -32 -15 -76z" />
-    <glyph glyph-name="youtube_sign" unicode="&#xf166;" 
-d="M919 233v157q0 50 -29 50q-17 0 -33 -16v-224q16 -16 33 -16q29 0 29 49zM1103 355h66v34q0 51 -33 51t-33 -51v-34zM532 621v-70h-80v-423h-74v423h-78v70h232zM733 495v-367h-67v40q-39 -45 -76 -45q-33 0 -42 28q-6 17 -6 54v290h66v-270q0 -24 1 -26q1 -15 15 -15
-q20 0 42 31v280h67zM985 384v-146q0 -52 -7 -73q-12 -42 -53 -42q-35 0 -68 41v-36h-67v493h67v-161q32 40 68 40q41 0 53 -42q7 -21 7 -74zM1236 255v-9q0 -29 -2 -43q-3 -22 -15 -40q-27 -40 -80 -40q-52 0 -81 38q-21 27 -21 86v129q0 59 20 86q29 38 80 38t78 -38
-q21 -29 21 -86v-76h-133v-65q0 -51 34 -51q24 0 30 26q0 1 0.5 7t0.5 16.5v21.5h68zM785 1079v-156q0 -51 -32 -51t-32 51v156q0 52 32 52t32 -52zM1318 366q0 177 -19 260q-10 44 -43 73.5t-76 34.5q-136 15 -412 15q-275 0 -411 -15q-44 -5 -76.5 -34.5t-42.5 -73.5
-q-20 -87 -20 -260q0 -176 20 -260q10 -43 42.5 -73t75.5 -35q137 -15 412 -15t412 15q43 5 75.5 35t42.5 73q20 84 20 260zM563 1017l90 296h-75l-51 -195l-53 195h-78q7 -23 23 -69l24 -69q35 -103 46 -158v-201h74v201zM852 936v130q0 58 -21 87q-29 38 -78 38
-q-51 0 -78 -38q-21 -29 -21 -87v-130q0 -58 21 -87q27 -38 78 -38q49 0 78 38q21 27 21 87zM1033 816h67v370h-67v-283q-22 -31 -42 -31q-15 0 -16 16q-1 2 -1 26v272h-67v-293q0 -37 6 -55q11 -27 43 -27q36 0 77 45v-40zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5
-h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
-    <glyph glyph-name="youtube" unicode="&#xf167;" 
-d="M971 292v-211q0 -67 -39 -67q-23 0 -45 22v301q22 22 45 22q39 0 39 -67zM1309 291v-46h-90v46q0 68 45 68t45 -68zM343 509h107v94h-312v-94h105v-569h100v569zM631 -60h89v494h-89v-378q-30 -42 -57 -42q-18 0 -21 21q-1 3 -1 35v364h-89v-391q0 -49 8 -73
-q12 -37 58 -37q48 0 102 61v-54zM1060 88v197q0 73 -9 99q-17 56 -71 56q-50 0 -93 -54v217h-89v-663h89v48q45 -55 93 -55q54 0 71 55q9 27 9 100zM1398 98v13h-91q0 -51 -2 -61q-7 -36 -40 -36q-46 0 -46 69v87h179v103q0 79 -27 116q-39 51 -106 51q-68 0 -107 -51
-q-28 -37 -28 -116v-173q0 -79 29 -116q39 -51 108 -51q72 0 108 53q18 27 21 54q2 9 2 58zM790 1011v210q0 69 -43 69t-43 -69v-210q0 -70 43 -70t43 70zM1509 260q0 -234 -26 -350q-14 -59 -58 -99t-102 -46q-184 -21 -555 -21t-555 21q-58 6 -102.5 46t-57.5 99
-q-26 112 -26 350q0 234 26 350q14 59 58 99t103 47q183 20 554 20t555 -20q58 -7 102.5 -47t57.5 -99q26 -112 26 -350zM511 1536h102l-121 -399v-271h-100v271q-14 74 -61 212q-37 103 -65 187h106l71 -263zM881 1203v-175q0 -81 -28 -118q-38 -51 -106 -51q-67 0 -105 51
-q-28 38 -28 118v175q0 80 28 117q38 51 105 51q68 0 106 -51q28 -37 28 -117zM1216 1365v-499h-91v55q-53 -62 -103 -62q-46 0 -59 37q-8 24 -8 75v394h91v-367q0 -33 1 -35q3 -22 21 -22q27 0 57 43v381h91z" />
-    <glyph glyph-name="xing" unicode="&#xf168;" horiz-adv-x="1408" 
-d="M597 869q-10 -18 -257 -456q-27 -46 -65 -46h-239q-21 0 -31 17t0 36l253 448q1 0 0 1l-161 279q-12 22 -1 37q9 15 32 15h239q40 0 66 -45zM1403 1511q11 -16 0 -37l-528 -934v-1l336 -615q11 -20 1 -37q-10 -15 -32 -15h-239q-42 0 -66 45l-339 622q18 32 531 942
-q25 45 64 45h241q22 0 31 -15z" />
-    <glyph glyph-name="xing_sign" unicode="&#xf169;" 
-d="M685 771q0 1 -126 222q-21 34 -52 34h-184q-18 0 -26 -11q-7 -12 1 -29l125 -216v-1l-196 -346q-9 -14 0 -28q8 -13 24 -13h185q31 0 50 36zM1309 1268q-7 12 -24 12h-187q-30 0 -49 -35l-411 -729q1 -2 262 -481q20 -35 52 -35h184q18 0 25 12q8 13 -1 28l-260 476v1
-l409 723q8 16 0 28zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
-    <glyph glyph-name="youtube_play" unicode="&#xf16a;" horiz-adv-x="1792" 
-d="M711 408l484 250l-484 253v-503zM896 1270q168 0 324.5 -4.5t229.5 -9.5l73 -4q1 0 17 -1.5t23 -3t23.5 -4.5t28.5 -8t28 -13t31 -19.5t29 -26.5q6 -6 15.5 -18.5t29 -58.5t26.5 -101q8 -64 12.5 -136.5t5.5 -113.5v-40v-136q1 -145 -18 -290q-7 -55 -25 -99.5t-32 -61.5
-l-14 -17q-14 -15 -29 -26.5t-31 -19t-28 -12.5t-28.5 -8t-24 -4.5t-23 -3t-16.5 -1.5q-251 -19 -627 -19q-207 2 -359.5 6.5t-200.5 7.5l-49 4l-36 4q-36 5 -54.5 10t-51 21t-56.5 41q-6 6 -15.5 18.5t-29 58.5t-26.5 101q-8 64 -12.5 136.5t-5.5 113.5v40v136
-q-1 145 18 290q7 55 25 99.5t32 61.5l14 17q14 15 29 26.5t31 19.5t28 13t28.5 8t23.5 4.5t23 3t17 1.5q251 18 627 18z" />
-    <glyph glyph-name="dropbox" unicode="&#xf16b;" horiz-adv-x="1792" 
-d="M402 829l494 -305l-342 -285l-490 319zM1388 274v-108l-490 -293v-1l-1 1l-1 -1v1l-489 293v108l147 -96l342 284v2l1 -1l1 1v-2l343 -284zM554 1418l342 -285l-494 -304l-338 270zM1390 829l338 -271l-489 -319l-343 285zM1239 1418l489 -319l-338 -270l-494 304z" />
-    <glyph glyph-name="stackexchange" unicode="&#xf16c;" 
-d="M1289 -96h-1118v480h-160v-640h1438v640h-160v-480zM347 428l33 157l783 -165l-33 -156zM450 802l67 146l725 -339l-67 -145zM651 1158l102 123l614 -513l-102 -123zM1048 1536l477 -641l-128 -96l-477 641zM330 65v159h800v-159h-800z" />
-    <glyph glyph-name="instagram" unicode="&#xf16d;" 
-d="M1024 640q0 106 -75 181t-181 75t-181 -75t-75 -181t75 -181t181 -75t181 75t75 181zM1162 640q0 -164 -115 -279t-279 -115t-279 115t-115 279t115 279t279 115t279 -115t115 -279zM1270 1050q0 -38 -27 -65t-65 -27t-65 27t-27 65t27 65t65 27t65 -27t27 -65zM768 1270
-q-7 0 -76.5 0.5t-105.5 0t-96.5 -3t-103 -10t-71.5 -18.5q-50 -20 -88 -58t-58 -88q-11 -29 -18.5 -71.5t-10 -103t-3 -96.5t0 -105.5t0.5 -76.5t-0.5 -76.5t0 -105.5t3 -96.5t10 -103t18.5 -71.5q20 -50 58 -88t88 -58q29 -11 71.5 -18.5t103 -10t96.5 -3t105.5 0t76.5 0.5
-t76.5 -0.5t105.5 0t96.5 3t103 10t71.5 18.5q50 20 88 58t58 88q11 29 18.5 71.5t10 103t3 96.5t0 105.5t-0.5 76.5t0.5 76.5t0 105.5t-3 96.5t-10 103t-18.5 71.5q-20 50 -58 88t-88 58q-29 11 -71.5 18.5t-103 10t-96.5 3t-105.5 0t-76.5 -0.5zM1536 640q0 -229 -5 -317
-q-10 -208 -124 -322t-322 -124q-88 -5 -317 -5t-317 5q-208 10 -322 124t-124 322q-5 88 -5 317t5 317q10 208 124 322t322 124q88 5 317 5t317 -5q208 -10 322 -124t124 -322q5 -88 5 -317z" />
-    <glyph glyph-name="flickr" unicode="&#xf16e;" 
-d="M1248 1408q119 0 203.5 -84.5t84.5 -203.5v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960zM698 640q0 88 -62 150t-150 62t-150 -62t-62 -150t62 -150t150 -62t150 62t62 150zM1262 640q0 88 -62 150
-t-150 62t-150 -62t-62 -150t62 -150t150 -62t150 62t62 150z" />
-    <glyph glyph-name="adn" unicode="&#xf170;" 
-d="M768 914l201 -306h-402zM1133 384h94l-459 691l-459 -691h94l104 160h522zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
-    <glyph glyph-name="f171" unicode="&#xf171;" horiz-adv-x="1408" 
-d="M815 677q8 -63 -50.5 -101t-111.5 -6q-39 17 -53.5 58t-0.5 82t52 58q36 18 72.5 12t64 -35.5t27.5 -67.5zM926 698q-14 107 -113 164t-197 13q-63 -28 -100.5 -88.5t-34.5 -129.5q4 -91 77.5 -155t165.5 -56q91 8 152 84t50 168zM1165 1240q-20 27 -56 44.5t-58 22
-t-71 12.5q-291 47 -566 -2q-43 -7 -66 -12t-55 -22t-50 -43q30 -28 76 -45.5t73.5 -22t87.5 -11.5q228 -29 448 -1q63 8 89.5 12t72.5 21.5t75 46.5zM1222 205q-8 -26 -15.5 -76.5t-14 -84t-28.5 -70t-58 -56.5q-86 -48 -189.5 -71.5t-202 -22t-201.5 18.5q-46 8 -81.5 18
-t-76.5 27t-73 43.5t-52 61.5q-25 96 -57 292l6 16l18 9q223 -148 506.5 -148t507.5 148q21 -6 24 -23t-5 -45t-8 -37zM1403 1166q-26 -167 -111 -655q-5 -30 -27 -56t-43.5 -40t-54.5 -31q-252 -126 -610 -88q-248 27 -394 139q-15 12 -25.5 26.5t-17 35t-9 34t-6 39.5
-t-5.5 35q-9 50 -26.5 150t-28 161.5t-23.5 147.5t-22 158q3 26 17.5 48.5t31.5 37.5t45 30t46 22.5t48 18.5q125 46 313 64q379 37 676 -50q155 -46 215 -122q16 -20 16.5 -51t-5.5 -54z" />
-    <glyph glyph-name="bitbucket_sign" unicode="&#xf172;" 
-d="M848 666q0 43 -41 66t-77 1q-43 -20 -42.5 -72.5t43.5 -70.5q39 -23 81 4t36 72zM928 682q8 -66 -36 -121t-110 -61t-119 40t-56 113q-2 49 25.5 93t72.5 64q70 31 141.5 -10t81.5 -118zM1100 1073q-20 -21 -53.5 -34t-53 -16t-63.5 -8q-155 -20 -324 0q-44 6 -63 9.5
-t-52.5 16t-54.5 32.5q13 19 36 31t40 15.5t47 8.5q198 35 408 1q33 -5 51 -8.5t43 -16t39 -31.5zM1142 327q0 7 5.5 26.5t3 32t-17.5 16.5q-161 -106 -365 -106t-366 106l-12 -6l-5 -12q26 -154 41 -210q47 -81 204 -108q249 -46 428 53q34 19 49 51.5t22.5 85.5t12.5 71z
-M1272 1020q9 53 -8 75q-43 55 -155 88q-216 63 -487 36q-132 -12 -226 -46q-38 -15 -59.5 -25t-47 -34t-29.5 -54q8 -68 19 -138t29 -171t24 -137q1 -5 5 -31t7 -36t12 -27t22 -28q105 -80 284 -100q259 -28 440 63q24 13 39.5 23t31 29t19.5 40q48 267 80 473zM1536 1120
-v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
-    <glyph glyph-name="tumblr" unicode="&#xf173;" horiz-adv-x="1024" 
-d="M944 207l80 -237q-23 -35 -111 -66t-177 -32q-104 -2 -190.5 26t-142.5 74t-95 106t-55.5 120t-16.5 118v544h-168v215q72 26 129 69.5t91 90t58 102t34 99t15 88.5q1 5 4.5 8.5t7.5 3.5h244v-424h333v-252h-334v-518q0 -30 6.5 -56t22.5 -52.5t49.5 -41.5t81.5 -14
-q78 2 134 29z" />
-    <glyph glyph-name="tumblr_sign" unicode="&#xf174;" 
-d="M1136 75l-62 183q-44 -22 -103 -22q-36 -1 -62 10.5t-38.5 31.5t-17.5 40.5t-5 43.5v398h257v194h-256v326h-188q-8 0 -9 -10q-5 -44 -17.5 -87t-39 -95t-77 -95t-118.5 -68v-165h130v-418q0 -57 21.5 -115t65 -111t121 -85.5t176.5 -30.5q69 1 136.5 25t85.5 50z
-M1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
-    <glyph glyph-name="long_arrow_down" unicode="&#xf175;" horiz-adv-x="768" 
-d="M765 237q8 -19 -5 -35l-350 -384q-10 -10 -23 -10q-14 0 -24 10l-355 384q-13 16 -5 35q9 19 29 19h224v1248q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-1248h224q21 0 29 -19z" />
-    <glyph glyph-name="long_arrow_up" unicode="&#xf176;" horiz-adv-x="768" 
-d="M765 1043q-9 -19 -29 -19h-224v-1248q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v1248h-224q-21 0 -29 19t5 35l350 384q10 10 23 10q14 0 24 -10l355 -384q13 -16 5 -35z" />
-    <glyph glyph-name="long_arrow_left" unicode="&#xf177;" horiz-adv-x="1792" 
-d="M1792 736v-192q0 -14 -9 -23t-23 -9h-1248v-224q0 -21 -19 -29t-35 5l-384 350q-10 10 -10 23q0 14 10 24l384 354q16 14 35 6q19 -9 19 -29v-224h1248q14 0 23 -9t9 -23z" />
-    <glyph glyph-name="long_arrow_right" unicode="&#xf178;" horiz-adv-x="1792" 
-d="M1728 643q0 -14 -10 -24l-384 -354q-16 -14 -35 -6q-19 9 -19 29v224h-1248q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h1248v224q0 21 19 29t35 -5l384 -350q10 -10 10 -23z" />
-    <glyph glyph-name="apple" unicode="&#xf179;" horiz-adv-x="1408" 
-d="M1393 321q-39 -125 -123 -250q-129 -196 -257 -196q-49 0 -140 32q-86 32 -151 32q-61 0 -142 -33q-81 -34 -132 -34q-152 0 -301 259q-147 261 -147 503q0 228 113 374q113 144 284 144q72 0 177 -30q104 -30 138 -30q45 0 143 34q102 34 173 34q119 0 213 -65
-q52 -36 104 -100q-79 -67 -114 -118q-65 -94 -65 -207q0 -124 69 -223t158 -126zM1017 1494q0 -61 -29 -136q-30 -75 -93 -138q-54 -54 -108 -72q-37 -11 -104 -17q3 149 78 257q74 107 250 148q1 -3 2.5 -11t2.5 -11q0 -4 0.5 -10t0.5 -10z" />
-    <glyph glyph-name="windows" unicode="&#xf17a;" horiz-adv-x="1664" 
-d="M682 530v-651l-682 94v557h682zM682 1273v-659h-682v565zM1664 530v-786l-907 125v661h907zM1664 1408v-794h-907v669z" />
-    <glyph glyph-name="android" unicode="&#xf17b;" horiz-adv-x="1408" 
-d="M493 1053q16 0 27.5 11.5t11.5 27.5t-11.5 27.5t-27.5 11.5t-27 -11.5t-11 -27.5t11 -27.5t27 -11.5zM915 1053q16 0 27 11.5t11 27.5t-11 27.5t-27 11.5t-27.5 -11.5t-11.5 -27.5t11.5 -27.5t27.5 -11.5zM103 869q42 0 72 -30t30 -72v-430q0 -43 -29.5 -73t-72.5 -30
-t-73 30t-30 73v430q0 42 30 72t73 30zM1163 850v-666q0 -46 -32 -78t-77 -32h-75v-227q0 -43 -30 -73t-73 -30t-73 30t-30 73v227h-138v-227q0 -43 -30 -73t-73 -30q-42 0 -72 30t-30 73l-1 227h-74q-46 0 -78 32t-32 78v666h918zM931 1255q107 -55 171 -153.5t64 -215.5
-h-925q0 117 64 215.5t172 153.5l-71 131q-7 13 5 20q13 6 20 -6l72 -132q95 42 201 42t201 -42l72 132q7 12 20 6q12 -7 5 -20zM1408 767v-430q0 -43 -30 -73t-73 -30q-42 0 -72 30t-30 73v430q0 43 30 72.5t72 29.5q43 0 73 -29.5t30 -72.5z" />
-    <glyph glyph-name="linux" unicode="&#xf17c;" 
-d="M663 1125q-11 -1 -15.5 -10.5t-8.5 -9.5q-5 -1 -5 5q0 12 19 15h10zM750 1111q-4 -1 -11.5 6.5t-17.5 4.5q24 11 32 -2q3 -6 -3 -9zM399 684q-4 1 -6 -3t-4.5 -12.5t-5.5 -13.5t-10 -13q-10 -11 -1 -12q4 -1 12.5 7t12.5 18q1 3 2 7t2 6t1.5 4.5t0.5 4v3t-1 2.5t-3 2z
-M1254 325q0 18 -55 42q4 15 7.5 27.5t5 26t3 21.5t0.5 22.5t-1 19.5t-3.5 22t-4 20.5t-5 25t-5.5 26.5q-10 48 -47 103t-72 75q24 -20 57 -83q87 -162 54 -278q-11 -40 -50 -42q-31 -4 -38.5 18.5t-8 83.5t-11.5 107q-9 39 -19.5 69t-19.5 45.5t-15.5 24.5t-13 15t-7.5 7
-q-14 62 -31 103t-29.5 56t-23.5 33t-15 40q-4 21 6 53.5t4.5 49.5t-44.5 25q-15 3 -44.5 18t-35.5 16q-8 1 -11 26t8 51t36 27q37 3 51 -30t4 -58q-11 -19 -2 -26.5t30 -0.5q13 4 13 36v37q-5 30 -13.5 50t-21 30.5t-23.5 15t-27 7.5q-107 -8 -89 -134q0 -15 -1 -15
-q-9 9 -29.5 10.5t-33 -0.5t-15.5 5q1 57 -16 90t-45 34q-27 1 -41.5 -27.5t-16.5 -59.5q-1 -15 3.5 -37t13 -37.5t15.5 -13.5q10 3 16 14q4 9 -7 8q-7 0 -15.5 14.5t-9.5 33.5q-1 22 9 37t34 14q17 0 27 -21t9.5 -39t-1.5 -22q-22 -15 -31 -29q-8 -12 -27.5 -23.5
-t-20.5 -12.5q-13 -14 -15.5 -27t7.5 -18q14 -8 25 -19.5t16 -19t18.5 -13t35.5 -6.5q47 -2 102 15q2 1 23 7t34.5 10.5t29.5 13t21 17.5q9 14 20 8q5 -3 6.5 -8.5t-3 -12t-16.5 -9.5q-20 -6 -56.5 -21.5t-45.5 -19.5q-44 -19 -70 -23q-25 -5 -79 2q-10 2 -9 -2t17 -19
-q25 -23 67 -22q17 1 36 7t36 14t33.5 17.5t30 17t24.5 12t17.5 2.5t8.5 -11q0 -2 -1 -4.5t-4 -5t-6 -4.5t-8.5 -5t-9 -4.5t-10 -5t-9.5 -4.5q-28 -14 -67.5 -44t-66.5 -43t-49 -1q-21 11 -63 73q-22 31 -25 22q-1 -3 -1 -10q0 -25 -15 -56.5t-29.5 -55.5t-21 -58t11.5 -63
-q-23 -6 -62.5 -90t-47.5 -141q-2 -18 -1.5 -69t-5.5 -59q-8 -24 -29 -3q-32 31 -36 94q-2 28 4 56q4 19 -1 18q-2 -1 -4 -5q-36 -65 10 -166q5 -12 25 -28t24 -20q20 -23 104 -90.5t93 -76.5q16 -15 17.5 -38t-14 -43t-45.5 -23q8 -15 29 -44.5t28 -54t7 -70.5q46 24 7 92
-q-4 8 -10.5 16t-9.5 12t-2 6q3 5 13 9.5t20 -2.5q46 -52 166 -36q133 15 177 87q23 38 34 30q12 -6 10 -52q-1 -25 -23 -92q-9 -23 -6 -37.5t24 -15.5q3 19 14.5 77t13.5 90q2 21 -6.5 73.5t-7.5 97t23 70.5q15 18 51 18q1 37 34.5 53t72.5 10.5t60 -22.5zM626 1152
-q3 17 -2.5 30t-11.5 15q-9 2 -9 -7q2 -5 5 -6q10 0 7 -15q-3 -20 8 -20q3 0 3 3zM1045 955q-2 8 -6.5 11.5t-13 5t-14.5 5.5q-5 3 -9.5 8t-7 8t-5.5 6.5t-4 4t-4 -1.5q-14 -16 7 -43.5t39 -31.5q9 -1 14.5 8t3.5 20zM867 1168q0 11 -5 19.5t-11 12.5t-9 3q-6 0 -8 -2t0 -4
-t5 -3q14 -4 18 -31q0 -3 8 2q2 2 2 3zM921 1401q0 2 -2.5 5t-9 7t-9.5 6q-15 15 -24 15q-9 -1 -11.5 -7.5t-1 -13t-0.5 -12.5q-1 -4 -6 -10.5t-6 -9t3 -8.5q4 -3 8 0t11 9t15 9q1 1 9 1t15 2t9 7zM1486 60q20 -12 31 -24.5t12 -24t-2.5 -22.5t-15.5 -22t-23.5 -19.5
-t-30 -18.5t-31.5 -16.5t-32 -15.5t-27 -13q-38 -19 -85.5 -56t-75.5 -64q-17 -16 -68 -19.5t-89 14.5q-18 9 -29.5 23.5t-16.5 25.5t-22 19.5t-47 9.5q-44 1 -130 1q-19 0 -57 -1.5t-58 -2.5q-44 -1 -79.5 -15t-53.5 -30t-43.5 -28.5t-53.5 -11.5q-29 1 -111 31t-146 43
-q-19 4 -51 9.5t-50 9t-39.5 9.5t-33.5 14.5t-17 19.5q-10 23 7 66.5t18 54.5q1 16 -4 40t-10 42.5t-4.5 36.5t10.5 27q14 12 57 14t60 12q30 18 42 35t12 51q21 -73 -32 -106q-32 -20 -83 -15q-34 3 -43 -10q-13 -15 5 -57q2 -6 8 -18t8.5 -18t4.5 -17t1 -22q0 -15 -17 -49
-t-14 -48q3 -17 37 -26q20 -6 84.5 -18.5t99.5 -20.5q24 -6 74 -22t82.5 -23t55.5 -4q43 6 64.5 28t23 48t-7.5 58.5t-19 52t-20 36.5q-121 190 -169 242q-68 74 -113 40q-11 -9 -15 15q-3 16 -2 38q1 29 10 52t24 47t22 42q8 21 26.5 72t29.5 78t30 61t39 54
-q110 143 124 195q-12 112 -16 310q-2 90 24 151.5t106 104.5q39 21 104 21q53 1 106 -13.5t89 -41.5q57 -42 91.5 -121.5t29.5 -147.5q-5 -95 30 -214q34 -113 133 -218q55 -59 99.5 -163t59.5 -191q8 -49 5 -84.5t-12 -55.5t-20 -22q-10 -2 -23.5 -19t-27 -35.5
-t-40.5 -33.5t-61 -14q-18 1 -31.5 5t-22.5 13.5t-13.5 15.5t-11.5 20.5t-9 19.5q-22 37 -41 30t-28 -49t7 -97q20 -70 1 -195q-10 -65 18 -100.5t73 -33t85 35.5q59 49 89.5 66.5t103.5 42.5q53 18 77 36.5t18.5 34.5t-25 28.5t-51.5 23.5q-33 11 -49.5 48t-15 72.5
-t15.5 47.5q1 -31 8 -56.5t14.5 -40.5t20.5 -28.5t21 -19t21.5 -13t16.5 -9.5z" />
-    <glyph glyph-name="dribble" unicode="&#xf17d;" 
-d="M1024 36q-42 241 -140 498h-2l-2 -1q-16 -6 -43 -16.5t-101 -49t-137 -82t-131 -114.5t-103 -148l-15 11q184 -150 418 -150q132 0 256 52zM839 643q-21 49 -53 111q-311 -93 -673 -93q-1 -7 -1 -21q0 -124 44 -236.5t124 -201.5q50 89 123.5 166.5t142.5 124.5t130.5 81
-t99.5 48l37 13q4 1 13 3.5t13 4.5zM732 855q-120 213 -244 378q-138 -65 -234 -186t-128 -272q302 0 606 80zM1416 536q-210 60 -409 29q87 -239 128 -469q111 75 185 189.5t96 250.5zM611 1277q-1 0 -2 -1q1 1 2 1zM1201 1132q-185 164 -433 164q-76 0 -155 -19
-q131 -170 246 -382q69 26 130 60.5t96.5 61.5t65.5 57t37.5 40.5zM1424 647q-3 232 -149 410l-1 -1q-9 -12 -19 -24.5t-43.5 -44.5t-71 -60.5t-100 -65t-131.5 -64.5q25 -53 44 -95q2 -5 6.5 -17t7.5 -17q36 5 74.5 7t73.5 2t69 -1.5t64 -4t56.5 -5.5t48 -6.5t36.5 -6
-t25 -4.5zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
-    <glyph glyph-name="skype" unicode="&#xf17e;" 
-d="M1173 473q0 50 -19.5 91.5t-48.5 68.5t-73 49t-82.5 34t-87.5 23l-104 24q-30 7 -44 10.5t-35 11.5t-30 16t-16.5 21t-7.5 30q0 77 144 77q43 0 77 -12t54 -28.5t38 -33.5t40 -29t48 -12q47 0 75.5 32t28.5 77q0 55 -56 99.5t-142 67.5t-182 23q-68 0 -132 -15.5
-t-119.5 -47t-89 -87t-33.5 -128.5q0 -61 19 -106.5t56 -75.5t80 -48.5t103 -32.5l146 -36q90 -22 112 -36q32 -20 32 -60q0 -39 -40 -64.5t-105 -25.5q-51 0 -91.5 16t-65 38.5t-45.5 45t-46 38.5t-54 16q-50 0 -75.5 -30t-25.5 -75q0 -92 122 -157.5t291 -65.5
-q73 0 140 18.5t122.5 53.5t88.5 93.5t33 131.5zM1536 256q0 -159 -112.5 -271.5t-271.5 -112.5q-130 0 -234 80q-77 -16 -150 -16q-143 0 -273.5 55.5t-225 150t-150 225t-55.5 273.5q0 73 16 150q-80 104 -80 234q0 159 112.5 271.5t271.5 112.5q130 0 234 -80
-q77 16 150 16q143 0 273.5 -55.5t225 -150t150 -225t55.5 -273.5q0 -73 -16 -150q80 -104 80 -234z" />
-    <glyph glyph-name="foursquare" unicode="&#xf180;" horiz-adv-x="1280" 
-d="M1000 1102l37 194q5 23 -9 40t-35 17h-712q-23 0 -38.5 -17t-15.5 -37v-1101q0 -7 6 -1l291 352q23 26 38 33.5t48 7.5h239q22 0 37 14.5t18 29.5q24 130 37 191q4 21 -11.5 40t-36.5 19h-294q-29 0 -48 19t-19 48v42q0 29 19 47.5t48 18.5h346q18 0 35 13.5t20 29.5z
-M1227 1324q-15 -73 -53.5 -266.5t-69.5 -350t-35 -173.5q-6 -22 -9 -32.5t-14 -32.5t-24.5 -33t-38.5 -21t-58 -10h-271q-13 0 -22 -10q-8 -9 -426 -494q-22 -25 -58.5 -28.5t-48.5 5.5q-55 22 -55 98v1410q0 55 38 102.5t120 47.5h888q95 0 127 -53t10 -159zM1227 1324
-l-158 -790q4 17 35 173.5t69.5 350t53.5 266.5z" />
-    <glyph glyph-name="trello" unicode="&#xf181;" 
-d="M704 192v1024q0 14 -9 23t-23 9h-480q-14 0 -23 -9t-9 -23v-1024q0 -14 9 -23t23 -9h480q14 0 23 9t9 23zM1376 576v640q0 14 -9 23t-23 9h-480q-14 0 -23 -9t-9 -23v-640q0 -14 9 -23t23 -9h480q14 0 23 9t9 23zM1536 1344v-1408q0 -26 -19 -45t-45 -19h-1408
-q-26 0 -45 19t-19 45v1408q0 26 19 45t45 19h1408q26 0 45 -19t19 -45z" />
-    <glyph glyph-name="female" unicode="&#xf182;" horiz-adv-x="1280" 
-d="M1280 480q0 -40 -28 -68t-68 -28q-51 0 -80 43l-227 341h-45v-132l247 -411q9 -15 9 -33q0 -26 -19 -45t-45 -19h-192v-272q0 -46 -33 -79t-79 -33h-160q-46 0 -79 33t-33 79v272h-192q-26 0 -45 19t-19 45q0 18 9 33l247 411v132h-45l-227 -341q-29 -43 -80 -43
-q-40 0 -68 28t-28 68q0 29 16 53l256 384q73 107 176 107h384q103 0 176 -107l256 -384q16 -24 16 -53zM864 1280q0 -93 -65.5 -158.5t-158.5 -65.5t-158.5 65.5t-65.5 158.5t65.5 158.5t158.5 65.5t158.5 -65.5t65.5 -158.5z" />
-    <glyph glyph-name="male" unicode="&#xf183;" horiz-adv-x="1024" 
-d="M1024 832v-416q0 -40 -28 -68t-68 -28t-68 28t-28 68v352h-64v-912q0 -46 -33 -79t-79 -33t-79 33t-33 79v464h-64v-464q0 -46 -33 -79t-79 -33t-79 33t-33 79v912h-64v-352q0 -40 -28 -68t-68 -28t-68 28t-28 68v416q0 80 56 136t136 56h640q80 0 136 -56t56 -136z
-M736 1280q0 -93 -65.5 -158.5t-158.5 -65.5t-158.5 65.5t-65.5 158.5t65.5 158.5t158.5 65.5t158.5 -65.5t65.5 -158.5z" />
-    <glyph glyph-name="gittip" unicode="&#xf184;" 
-d="M773 234l350 473q16 22 24.5 59t-6 85t-61.5 79q-40 26 -83 25.5t-73.5 -17.5t-54.5 -45q-36 -40 -96 -40q-59 0 -95 40q-24 28 -54.5 45t-73.5 17.5t-84 -25.5q-46 -31 -60.5 -79t-6 -85t24.5 -59zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103
-t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
-    <glyph glyph-name="sun" unicode="&#xf185;" horiz-adv-x="1792" 
-d="M1472 640q0 117 -45.5 223.5t-123 184t-184 123t-223.5 45.5t-223.5 -45.5t-184 -123t-123 -184t-45.5 -223.5t45.5 -223.5t123 -184t184 -123t223.5 -45.5t223.5 45.5t184 123t123 184t45.5 223.5zM1748 363q-4 -15 -20 -20l-292 -96v-306q0 -16 -13 -26q-15 -10 -29 -4
-l-292 94l-180 -248q-10 -13 -26 -13t-26 13l-180 248l-292 -94q-14 -6 -29 4q-13 10 -13 26v306l-292 96q-16 5 -20 20q-5 17 4 29l180 248l-180 248q-9 13 -4 29q4 15 20 20l292 96v306q0 16 13 26q15 10 29 4l292 -94l180 248q9 12 26 12t26 -12l180 -248l292 94
-q14 6 29 -4q13 -10 13 -26v-306l292 -96q16 -5 20 -20q5 -16 -4 -29l-180 -248l180 -248q9 -12 4 -29z" />
-    <glyph glyph-name="_366" unicode="&#xf186;" 
-d="M1262 233q-54 -9 -110 -9q-182 0 -337 90t-245 245t-90 337q0 192 104 357q-201 -60 -328.5 -229t-127.5 -384q0 -130 51 -248.5t136.5 -204t204 -136.5t248.5 -51q144 0 273.5 61.5t220.5 171.5zM1465 318q-94 -203 -283.5 -324.5t-413.5 -121.5q-156 0 -298 61
-t-245 164t-164 245t-61 298q0 153 57.5 292.5t156 241.5t235.5 164.5t290 68.5q44 2 61 -39q18 -41 -15 -72q-86 -78 -131.5 -181.5t-45.5 -218.5q0 -148 73 -273t198 -198t273 -73q118 0 228 51q41 18 72 -13q14 -14 17.5 -34t-4.5 -38z" />
-    <glyph glyph-name="archive" unicode="&#xf187;" horiz-adv-x="1792" 
-d="M1088 704q0 26 -19 45t-45 19h-256q-26 0 -45 -19t-19 -45t19 -45t45 -19h256q26 0 45 19t19 45zM1664 896v-960q0 -26 -19 -45t-45 -19h-1408q-26 0 -45 19t-19 45v960q0 26 19 45t45 19h1408q26 0 45 -19t19 -45zM1728 1344v-256q0 -26 -19 -45t-45 -19h-1536
-q-26 0 -45 19t-19 45v256q0 26 19 45t45 19h1536q26 0 45 -19t19 -45z" />
-    <glyph glyph-name="bug" unicode="&#xf188;" horiz-adv-x="1664" 
-d="M1632 576q0 -26 -19 -45t-45 -19h-224q0 -171 -67 -290l208 -209q19 -19 19 -45t-19 -45q-18 -19 -45 -19t-45 19l-198 197q-5 -5 -15 -13t-42 -28.5t-65 -36.5t-82 -29t-97 -13v896h-128v-896q-51 0 -101.5 13.5t-87 33t-66 39t-43.5 32.5l-15 14l-183 -207
-q-20 -21 -48 -21q-24 0 -43 16q-19 18 -20.5 44.5t15.5 46.5l202 227q-58 114 -58 274h-224q-26 0 -45 19t-19 45t19 45t45 19h224v294l-173 173q-19 19 -19 45t19 45t45 19t45 -19l173 -173h844l173 173q19 19 45 19t45 -19t19 -45t-19 -45l-173 -173v-294h224q26 0 45 -19
-t19 -45zM1152 1152h-640q0 133 93.5 226.5t226.5 93.5t226.5 -93.5t93.5 -226.5z" />
-    <glyph glyph-name="vk" unicode="&#xf189;" horiz-adv-x="1920" 
-d="M1917 1016q23 -64 -150 -294q-24 -32 -65 -85q-40 -51 -55 -72t-30.5 -49.5t-12 -42t13 -34.5t32.5 -43t57 -53q4 -2 5 -4q141 -131 191 -221q3 -5 6.5 -12.5t7 -26.5t-0.5 -34t-25 -27.5t-59 -12.5l-256 -4q-24 -5 -56 5t-52 22l-20 12q-30 21 -70 64t-68.5 77.5t-61 58
-t-56.5 15.5q-3 -1 -8 -3.5t-17 -14.5t-21.5 -29.5t-17 -52t-6.5 -77.5q0 -15 -3.5 -27.5t-7.5 -18.5l-4 -5q-18 -19 -53 -22h-115q-71 -4 -146 16.5t-131.5 53t-103 66t-70.5 57.5l-25 24q-10 10 -27.5 30t-71.5 91t-106 151t-122.5 211t-130.5 272q-6 16 -6 27t3 16l4 6
-q15 19 57 19l274 2q12 -2 23 -6.5t16 -8.5l5 -3q16 -11 24 -32q20 -50 46 -103.5t41 -81.5l16 -29q29 -60 56 -104t48.5 -68.5t41.5 -38.5t34 -14t27 5q2 1 5 5t12 22t13.5 47t9.5 81t0 125q-2 40 -9 73t-14 46l-6 12q-25 34 -85 43q-13 2 5 24q16 19 38 30q53 26 239 24
-q82 -1 135 -13q20 -5 33.5 -13.5t20.5 -24t10.5 -32t3.5 -45.5t-1 -55t-2.5 -70.5t-1.5 -82.5q0 -11 -1 -42t-0.5 -48t3.5 -40.5t11.5 -39t22.5 -24.5q8 -2 17 -4t26 11t38 34.5t52 67t68 107.5q60 104 107 225q4 10 10 17.5t11 10.5l4 3l5 2.5t13 3t20 0.5l288 2
-q39 5 64 -2.5t31 -16.5z" />
-    <glyph glyph-name="weibo" unicode="&#xf18a;" horiz-adv-x="1792" 
-d="M675 252q21 34 11 69t-45 50q-34 14 -73 1t-60 -46q-22 -34 -13 -68.5t43 -50.5t74.5 -2.5t62.5 47.5zM769 373q8 13 3.5 26.5t-17.5 18.5q-14 5 -28.5 -0.5t-21.5 -18.5q-17 -31 13 -45q14 -5 29 0.5t22 18.5zM943 266q-45 -102 -158 -150t-224 -12
-q-107 34 -147.5 126.5t6.5 187.5q47 93 151.5 139t210.5 19q111 -29 158.5 -119.5t2.5 -190.5zM1255 426q-9 96 -89 170t-208.5 109t-274.5 21q-223 -23 -369.5 -141.5t-132.5 -264.5q9 -96 89 -170t208.5 -109t274.5 -21q223 23 369.5 141.5t132.5 264.5zM1563 422
-q0 -68 -37 -139.5t-109 -137t-168.5 -117.5t-226 -83t-270.5 -31t-275 33.5t-240.5 93t-171.5 151t-65 199.5q0 115 69.5 245t197.5 258q169 169 341.5 236t246.5 -7q65 -64 20 -209q-4 -14 -1 -20t10 -7t14.5 0.5t13.5 3.5l6 2q139 59 246 59t153 -61q45 -63 0 -178
-q-2 -13 -4.5 -20t4.5 -12.5t12 -7.5t17 -6q57 -18 103 -47t80 -81.5t34 -116.5zM1489 1046q42 -47 54.5 -108.5t-6.5 -117.5q-8 -23 -29.5 -34t-44.5 -4q-23 8 -34 29.5t-4 44.5q20 63 -24 111t-107 35q-24 -5 -45 8t-25 37q-5 24 8 44.5t37 25.5q60 13 119 -5.5t101 -65.5z
-M1670 1209q87 -96 112.5 -222.5t-13.5 -241.5q-9 -27 -34 -40t-52 -4t-40 34t-5 52q28 82 10 172t-80 158q-62 69 -148 95.5t-173 8.5q-28 -6 -52 9.5t-30 43.5t9.5 51.5t43.5 29.5q123 26 244 -11.5t208 -134.5z" />
-    <glyph glyph-name="renren" unicode="&#xf18b;" 
-d="M1133 -34q-171 -94 -368 -94q-196 0 -367 94q138 87 235.5 211t131.5 268q35 -144 132.5 -268t235.5 -211zM638 1394v-485q0 -252 -126.5 -459.5t-330.5 -306.5q-181 215 -181 495q0 187 83.5 349.5t229.5 269.5t325 137zM1536 638q0 -280 -181 -495
-q-204 99 -330.5 306.5t-126.5 459.5v485q179 -30 325 -137t229.5 -269.5t83.5 -349.5z" />
-    <glyph glyph-name="_372" unicode="&#xf18c;" horiz-adv-x="1408" 
-d="M1402 433q-32 -80 -76 -138t-91 -88.5t-99 -46.5t-101.5 -14.5t-96.5 8.5t-86.5 22t-69.5 27.5t-46 22.5l-17 10q-113 -228 -289.5 -359.5t-384.5 -132.5q-19 0 -32 13t-13 32t13 31.5t32 12.5q173 1 322.5 107.5t251.5 294.5q-36 -14 -72 -23t-83 -13t-91 2.5t-93 28.5
-t-92 59t-84.5 100t-74.5 146q114 47 214 57t167.5 -7.5t124.5 -56.5t88.5 -77t56.5 -82q53 131 79 291q-7 -1 -18 -2.5t-46.5 -2.5t-69.5 0.5t-81.5 10t-88.5 23t-84 42.5t-75 65t-54.5 94.5t-28.5 127.5q70 28 133.5 36.5t112.5 -1t92 -30t73.5 -50t56 -61t42 -63t27.5 -56
-t16 -39.5l4 -16q12 122 12 195q-8 6 -21.5 16t-49 44.5t-63.5 71.5t-54 93t-33 112.5t12 127t70 138.5q73 -25 127.5 -61.5t84.5 -76.5t48 -85t20.5 -89t-0.5 -85.5t-13 -76.5t-19 -62t-17 -42l-7 -15q1 -4 1 -50t-1 -72q3 7 10 18.5t30.5 43t50.5 58t71 55.5t91.5 44.5
-t112 14.5t132.5 -24q-2 -78 -21.5 -141.5t-50 -104.5t-69.5 -71.5t-81.5 -45.5t-84.5 -24t-80 -9.5t-67.5 1t-46.5 4.5l-17 3q-23 -147 -73 -283q6 7 18 18.5t49.5 41t77.5 52.5t99.5 42t117.5 20t129 -23.5t137 -77.5z" />
-    <glyph glyph-name="stack_exchange" unicode="&#xf18d;" horiz-adv-x="1280" 
-d="M1259 283v-66q0 -85 -57.5 -144.5t-138.5 -59.5h-57l-260 -269v269h-529q-81 0 -138.5 59.5t-57.5 144.5v66h1238zM1259 609v-255h-1238v255h1238zM1259 937v-255h-1238v255h1238zM1259 1077v-67h-1238v67q0 84 57.5 143.5t138.5 59.5h846q81 0 138.5 -59.5t57.5 -143.5z
-" />
-    <glyph glyph-name="_374" unicode="&#xf18e;" 
-d="M1152 640q0 -14 -9 -23l-320 -320q-9 -9 -23 -9q-13 0 -22.5 9.5t-9.5 22.5v192h-352q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h352v192q0 14 9 23t23 9q12 0 24 -10l319 -319q9 -9 9 -23zM1312 640q0 148 -73 273t-198 198t-273 73t-273 -73t-198 -198
-t-73 -273t73 -273t198 -198t273 -73t273 73t198 198t73 273zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
-    <glyph glyph-name="arrow_circle_alt_left" unicode="&#xf190;" 
-d="M1152 736v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-352v-192q0 -14 -9 -23t-23 -9q-12 0 -24 10l-319 319q-9 9 -9 23t9 23l320 320q9 9 23 9q13 0 22.5 -9.5t9.5 -22.5v-192h352q13 0 22.5 -9.5t9.5 -22.5zM1312 640q0 148 -73 273t-198 198t-273 73t-273 -73t-198 -198
-t-73 -273t73 -273t198 -198t273 -73t273 73t198 198t73 273zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
-    <glyph glyph-name="_376" unicode="&#xf191;" 
-d="M1024 960v-640q0 -26 -19 -45t-45 -19q-20 0 -37 12l-448 320q-27 19 -27 52t27 52l448 320q17 12 37 12q26 0 45 -19t19 -45zM1280 160v960q0 13 -9.5 22.5t-22.5 9.5h-960q-13 0 -22.5 -9.5t-9.5 -22.5v-960q0 -13 9.5 -22.5t22.5 -9.5h960q13 0 22.5 9.5t9.5 22.5z
-M1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
-    <glyph glyph-name="dot_circle_alt" unicode="&#xf192;" 
-d="M1024 640q0 -106 -75 -181t-181 -75t-181 75t-75 181t75 181t181 75t181 -75t75 -181zM768 1184q-148 0 -273 -73t-198 -198t-73 -273t73 -273t198 -198t273 -73t273 73t198 198t73 273t-73 273t-198 198t-273 73zM1536 640q0 -209 -103 -385.5t-279.5 -279.5
-t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
-    <glyph glyph-name="_378" unicode="&#xf193;" horiz-adv-x="1664" 
-d="M1023 349l102 -204q-58 -179 -210 -290t-339 -111q-156 0 -288.5 77.5t-210 210t-77.5 288.5q0 181 104.5 330t274.5 211l17 -131q-122 -54 -195 -165.5t-73 -244.5q0 -185 131.5 -316.5t316.5 -131.5q126 0 232.5 65t165 175.5t49.5 236.5zM1571 249l58 -114l-256 -128
-q-13 -7 -29 -7q-40 0 -57 35l-239 477h-472q-24 0 -42.5 16.5t-21.5 40.5l-96 779q-2 17 6 42q14 51 57 82.5t97 31.5q66 0 113 -47t47 -113q0 -69 -52 -117.5t-120 -41.5l37 -289h423v-128h-407l16 -128h455q40 0 57 -35l228 -455z" />
-    <glyph glyph-name="vimeo_square" unicode="&#xf194;" 
-d="M1292 898q10 216 -161 222q-231 8 -312 -261q44 19 82 19q85 0 74 -96q-4 -57 -74 -167t-105 -110q-43 0 -82 169q-13 54 -45 255q-30 189 -160 177q-59 -7 -164 -100l-81 -72l-81 -72l52 -67q76 52 87 52q57 0 107 -179q15 -55 45 -164.5t45 -164.5q68 -179 164 -179
-q157 0 383 294q220 283 226 444zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
-    <glyph glyph-name="_380" unicode="&#xf195;" horiz-adv-x="1152" 
-d="M1152 704q0 -191 -94.5 -353t-256.5 -256.5t-353 -94.5h-160q-14 0 -23 9t-9 23v611l-215 -66q-3 -1 -9 -1q-10 0 -19 6q-13 10 -13 26v128q0 23 23 31l233 71v93l-215 -66q-3 -1 -9 -1q-10 0 -19 6q-13 10 -13 26v128q0 23 23 31l233 71v250q0 14 9 23t23 9h160
-q14 0 23 -9t9 -23v-181l375 116q15 5 28 -5t13 -26v-128q0 -23 -23 -31l-393 -121v-93l375 116q15 5 28 -5t13 -26v-128q0 -23 -23 -31l-393 -121v-487q188 13 318 151t130 328q0 14 9 23t23 9h160q14 0 23 -9t9 -23z" />
-    <glyph glyph-name="plus_square_o" unicode="&#xf196;" horiz-adv-x="1408" 
-d="M1152 736v-64q0 -14 -9 -23t-23 -9h-352v-352q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v352h-352q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h352v352q0 14 9 23t23 9h64q14 0 23 -9t9 -23v-352h352q14 0 23 -9t9 -23zM1280 288v832q0 66 -47 113t-113 47h-832
-q-66 0 -113 -47t-47 -113v-832q0 -66 47 -113t113 -47h832q66 0 113 47t47 113zM1408 1120v-832q0 -119 -84.5 -203.5t-203.5 -84.5h-832q-119 0 -203.5 84.5t-84.5 203.5v832q0 119 84.5 203.5t203.5 84.5h832q119 0 203.5 -84.5t84.5 -203.5z" />
-    <glyph glyph-name="_382" unicode="&#xf197;" horiz-adv-x="2176" 
-d="M620 416q-110 -64 -268 -64h-128v64h-64q-13 0 -22.5 23.5t-9.5 56.5q0 24 7 49q-58 2 -96.5 10.5t-38.5 20.5t38.5 20.5t96.5 10.5q-7 25 -7 49q0 33 9.5 56.5t22.5 23.5h64v64h128q158 0 268 -64h1113q42 -7 106.5 -18t80.5 -14q89 -15 150 -40.5t83.5 -47.5t22.5 -40
-t-22.5 -40t-83.5 -47.5t-150 -40.5q-16 -3 -80.5 -14t-106.5 -18h-1113zM1739 668q53 -36 53 -92t-53 -92l81 -30q68 48 68 122t-68 122zM625 400h1015q-217 -38 -456 -80q-57 0 -113 -24t-83 -48l-28 -24l-288 -288q-26 -26 -70.5 -45t-89.5 -19h-96l-93 464h29
-q157 0 273 64zM352 816h-29l93 464h96q46 0 90 -19t70 -45l288 -288q4 -4 11 -10.5t30.5 -23t48.5 -29t61.5 -23t72.5 -10.5l456 -80h-1015q-116 64 -273 64z" />
-    <glyph glyph-name="_383" unicode="&#xf198;" horiz-adv-x="1664" 
-d="M1519 760q62 0 103.5 -40.5t41.5 -101.5q0 -97 -93 -130l-172 -59l56 -167q7 -21 7 -47q0 -59 -42 -102t-101 -43q-47 0 -85.5 27t-53.5 72l-55 165l-310 -106l55 -164q8 -24 8 -47q0 -59 -42 -102t-102 -43q-47 0 -85 27t-53 72l-55 163l-153 -53q-29 -9 -50 -9
-q-61 0 -101.5 40t-40.5 101q0 47 27.5 85t71.5 53l156 53l-105 313l-156 -54q-26 -8 -48 -8q-60 0 -101 40.5t-41 100.5q0 47 27.5 85t71.5 53l157 53l-53 159q-8 24 -8 47q0 60 42 102.5t102 42.5q47 0 85 -27t53 -72l54 -160l310 105l-54 160q-8 24 -8 47q0 59 42.5 102
-t101.5 43q47 0 85.5 -27.5t53.5 -71.5l53 -161l162 55q21 6 43 6q60 0 102.5 -39.5t42.5 -98.5q0 -45 -30 -81.5t-74 -51.5l-157 -54l105 -316l164 56q24 8 46 8zM725 498l310 105l-105 315l-310 -107z" />
-    <glyph glyph-name="_384" unicode="&#xf199;" 
-d="M1248 1408q119 0 203.5 -84.5t84.5 -203.5v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960zM1280 352v436q-31 -35 -64 -55q-34 -22 -132.5 -85t-151.5 -99q-98 -69 -164 -69v0v0q-66 0 -164 69
-q-47 32 -142 92.5t-142 92.5q-12 8 -33 27t-31 27v-436q0 -40 28 -68t68 -28h832q40 0 68 28t28 68zM1280 925q0 41 -27.5 70t-68.5 29h-832q-40 0 -68 -28t-28 -68q0 -37 30.5 -76.5t67.5 -64.5q47 -32 137.5 -89t129.5 -83q3 -2 17 -11.5t21 -14t21 -13t23.5 -13
-t21.5 -9.5t22.5 -7.5t20.5 -2.5t20.5 2.5t22.5 7.5t21.5 9.5t23.5 13t21 13t21 14t17 11.5l267 174q35 23 66.5 62.5t31.5 73.5z" />
-    <glyph glyph-name="_385" unicode="&#xf19a;" horiz-adv-x="1792" 
-d="M127 640q0 163 67 313l367 -1005q-196 95 -315 281t-119 411zM1415 679q0 -19 -2.5 -38.5t-10 -49.5t-11.5 -44t-17.5 -59t-17.5 -58l-76 -256l-278 826q46 3 88 8q19 2 26 18.5t-2.5 31t-28.5 13.5l-205 -10q-75 1 -202 10q-12 1 -20.5 -5t-11.5 -15t-1.5 -18.5t9 -16.5
-t19.5 -8l80 -8l120 -328l-168 -504l-280 832q46 3 88 8q19 2 26 18.5t-2.5 31t-28.5 13.5l-205 -10q-7 0 -23 0.5t-26 0.5q105 160 274.5 253.5t367.5 93.5q147 0 280.5 -53t238.5 -149h-10q-55 0 -92 -40.5t-37 -95.5q0 -12 2 -24t4 -21.5t8 -23t9 -21t12 -22.5t12.5 -21
-t14.5 -24t14 -23q63 -107 63 -212zM909 573l237 -647q1 -6 5 -11q-126 -44 -255 -44q-112 0 -217 32zM1570 1009q95 -174 95 -369q0 -209 -104 -385.5t-279 -278.5l235 678q59 169 59 276q0 42 -6 79zM896 1536q182 0 348 -71t286 -191t191 -286t71 -348t-71 -348t-191 -286
-t-286 -191t-348 -71t-348 71t-286 191t-191 286t-71 348t71 348t191 286t286 191t348 71zM896 -215q173 0 331.5 68t273 182.5t182.5 273t68 331.5t-68 331.5t-182.5 273t-273 182.5t-331.5 68t-331.5 -68t-273 -182.5t-182.5 -273t-68 -331.5t68 -331.5t182.5 -273
-t273 -182.5t331.5 -68z" />
-    <glyph glyph-name="_386" unicode="&#xf19b;" horiz-adv-x="1792" 
-d="M1086 1536v-1536l-272 -128q-228 20 -414 102t-293 208.5t-107 272.5q0 140 100.5 263.5t275 205.5t391.5 108v-172q-217 -38 -356.5 -150t-139.5 -255q0 -152 154.5 -267t388.5 -145v1360zM1755 954l37 -390l-525 114l147 83q-119 70 -280 99v172q277 -33 481 -157z" />
-    <glyph glyph-name="_387" unicode="&#xf19c;" horiz-adv-x="2048" 
-d="M960 1536l960 -384v-128h-128q0 -26 -20.5 -45t-48.5 -19h-1526q-28 0 -48.5 19t-20.5 45h-128v128zM256 896h256v-768h128v768h256v-768h128v768h256v-768h128v768h256v-768h59q28 0 48.5 -19t20.5 -45v-64h-1664v64q0 26 20.5 45t48.5 19h59v768zM1851 -64
-q28 0 48.5 -19t20.5 -45v-128h-1920v128q0 26 20.5 45t48.5 19h1782z" />
-    <glyph glyph-name="_388" unicode="&#xf19d;" horiz-adv-x="2304" 
-d="M1774 700l18 -316q4 -69 -82 -128t-235 -93.5t-323 -34.5t-323 34.5t-235 93.5t-82 128l18 316l574 -181q22 -7 48 -7t48 7zM2304 1024q0 -23 -22 -31l-1120 -352q-4 -1 -10 -1t-10 1l-652 206q-43 -34 -71 -111.5t-34 -178.5q63 -36 63 -109q0 -69 -58 -107l58 -433
-q2 -14 -8 -25q-9 -11 -24 -11h-192q-15 0 -24 11q-10 11 -8 25l58 433q-58 38 -58 107q0 73 65 111q11 207 98 330l-333 104q-22 8 -22 31t22 31l1120 352q4 1 10 1t10 -1l1120 -352q22 -8 22 -31z" />
-    <glyph glyph-name="_389" unicode="&#xf19e;" 
-d="M859 579l13 -707q-62 11 -105 11q-41 0 -105 -11l13 707q-40 69 -168.5 295.5t-216.5 374.5t-181 287q58 -15 108 -15q44 0 111 15q63 -111 133.5 -229.5t167 -276.5t138.5 -227q37 61 109.5 177.5t117.5 190t105 176t107 189.5q54 -14 107 -14q56 0 114 14v0
-q-28 -39 -60 -88.5t-49.5 -78.5t-56.5 -96t-49 -84q-146 -248 -353 -610z" />
-    <glyph glyph-name="uniF1A0" unicode="&#xf1a0;" 
-d="M768 750h725q12 -67 12 -128q0 -217 -91 -387.5t-259.5 -266.5t-386.5 -96q-157 0 -299 60.5t-245 163.5t-163.5 245t-60.5 299t60.5 299t163.5 245t245 163.5t299 60.5q300 0 515 -201l-209 -201q-123 119 -306 119q-129 0 -238.5 -65t-173.5 -176.5t-64 -243.5
-t64 -243.5t173.5 -176.5t238.5 -65q87 0 160 24t120 60t82 82t51.5 87t22.5 78h-436v264z" />
-    <glyph glyph-name="f1a1" unicode="&#xf1a1;" horiz-adv-x="1792" 
-d="M1095 369q16 -16 0 -31q-62 -62 -199 -62t-199 62q-16 15 0 31q6 6 15 6t15 -6q48 -49 169 -49q120 0 169 49q6 6 15 6t15 -6zM788 550q0 -37 -26 -63t-63 -26t-63.5 26t-26.5 63q0 38 26.5 64t63.5 26t63 -26.5t26 -63.5zM1183 550q0 -37 -26.5 -63t-63.5 -26t-63 26
-t-26 63t26 63.5t63 26.5t63.5 -26t26.5 -64zM1434 670q0 49 -35 84t-85 35t-86 -36q-130 90 -311 96l63 283l200 -45q0 -37 26 -63t63 -26t63.5 26.5t26.5 63.5t-26.5 63.5t-63.5 26.5q-54 0 -80 -50l-221 49q-19 5 -25 -16l-69 -312q-180 -7 -309 -97q-35 37 -87 37
-q-50 0 -85 -35t-35 -84q0 -35 18.5 -64t49.5 -44q-6 -27 -6 -56q0 -142 140 -243t337 -101q198 0 338 101t140 243q0 32 -7 57q30 15 48 43.5t18 63.5zM1792 640q0 -182 -71 -348t-191 -286t-286 -191t-348 -71t-348 71t-286 191t-191 286t-71 348t71 348t191 286t286 191
-t348 71t348 -71t286 -191t191 -286t71 -348z" />
-    <glyph glyph-name="_392" unicode="&#xf1a2;" 
-d="M939 407q13 -13 0 -26q-53 -53 -171 -53t-171 53q-13 13 0 26q5 6 13 6t13 -6q42 -42 145 -42t145 42q5 6 13 6t13 -6zM676 563q0 -31 -23 -54t-54 -23t-54 23t-23 54q0 32 22.5 54.5t54.5 22.5t54.5 -22.5t22.5 -54.5zM1014 563q0 -31 -23 -54t-54 -23t-54 23t-23 54
-q0 32 22.5 54.5t54.5 22.5t54.5 -22.5t22.5 -54.5zM1229 666q0 42 -30 72t-73 30q-42 0 -73 -31q-113 78 -267 82l54 243l171 -39q1 -32 23.5 -54t53.5 -22q32 0 54.5 22.5t22.5 54.5t-22.5 54.5t-54.5 22.5q-48 0 -69 -43l-189 42q-17 5 -21 -13l-60 -268q-154 -6 -265 -83
-q-30 32 -74 32q-43 0 -73 -30t-30 -72q0 -30 16 -55t42 -38q-5 -25 -5 -48q0 -122 120 -208.5t289 -86.5q170 0 290 86.5t120 208.5q0 25 -6 49q25 13 40.5 37.5t15.5 54.5zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960
-q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
-    <glyph glyph-name="_393" unicode="&#xf1a3;" 
-d="M866 697l90 27v62q0 79 -58 135t-138 56t-138 -55.5t-58 -134.5v-283q0 -20 -14 -33.5t-33 -13.5t-32.5 13.5t-13.5 33.5v120h-151v-122q0 -82 57.5 -139t139.5 -57q81 0 138.5 56.5t57.5 136.5v280q0 19 13.5 33t33.5 14q19 0 32.5 -14t13.5 -33v-54zM1199 502v122h-150
-v-126q0 -20 -13.5 -33.5t-33.5 -13.5q-19 0 -32.5 14t-13.5 33v123l-90 -26l-60 28v-123q0 -80 58 -137t139 -57t138.5 57t57.5 139zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103
-t385.5 -103t279.5 -279.5t103 -385.5z" />
-    <glyph glyph-name="f1a4" unicode="&#xf1a4;" horiz-adv-x="1920" 
-d="M1062 824v118q0 42 -30 72t-72 30t-72 -30t-30 -72v-612q0 -175 -126 -299t-303 -124q-178 0 -303.5 125.5t-125.5 303.5v266h328v-262q0 -43 30 -72.5t72 -29.5t72 29.5t30 72.5v620q0 171 126.5 292t301.5 121q176 0 302 -122t126 -294v-136l-195 -58zM1592 602h328
-v-266q0 -178 -125.5 -303.5t-303.5 -125.5q-177 0 -303 124.5t-126 300.5v268l131 -61l195 58v-270q0 -42 30 -71.5t72 -29.5t72 29.5t30 71.5v275z" />
-    <glyph glyph-name="_395" unicode="&#xf1a5;" 
-d="M1472 160v480h-704v704h-480q-93 0 -158.5 -65.5t-65.5 -158.5v-480h704v-704h480q93 0 158.5 65.5t65.5 158.5zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5
-t84.5 -203.5z" />
-    <glyph glyph-name="_396" unicode="&#xf1a6;" horiz-adv-x="2048" 
-d="M328 1254h204v-983h-532v697h328v286zM328 435v369h-123v-369h123zM614 968v-697h205v697h-205zM614 1254v-204h205v204h-205zM901 968h533v-942h-533v163h328v82h-328v697zM1229 435v369h-123v-369h123zM1516 968h532v-942h-532v163h327v82h-327v697zM1843 435v369h-123
-v-369h123z" />
-    <glyph glyph-name="_397" unicode="&#xf1a7;" 
-d="M1046 516q0 -64 -38 -109t-91 -45q-43 0 -70 15v277q28 17 70 17q53 0 91 -45.5t38 -109.5zM703 944q0 -64 -38 -109.5t-91 -45.5q-43 0 -70 15v277q28 17 70 17q53 0 91 -45t38 -109zM1265 513q0 134 -88 229t-213 95q-20 0 -39 -3q-23 -78 -78 -136q-87 -95 -211 -101
-v-636l211 41v206q51 -19 117 -19q125 0 213 95t88 229zM922 940q0 134 -88.5 229t-213.5 95q-74 0 -141 -36h-186v-840l211 41v206q55 -19 116 -19q125 0 213.5 95t88.5 229zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960
-q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
-    <glyph glyph-name="_398" unicode="&#xf1a8;" horiz-adv-x="2038" 
-d="M1222 607q75 3 143.5 -20.5t118 -58.5t101 -94.5t84 -108t75.5 -120.5q33 -56 78.5 -109t75.5 -80.5t99 -88.5q-48 -30 -108.5 -57.5t-138.5 -59t-114 -47.5q-44 37 -74 115t-43.5 164.5t-33 180.5t-42.5 168.5t-72.5 123t-122.5 48.5l-10 -2l-6 -4q4 -5 13 -14
-q6 -5 28 -23.5t25.5 -22t19 -18t18 -20.5t11.5 -21t10.5 -27.5t4.5 -31t4 -40.5l1 -33q1 -26 -2.5 -57.5t-7.5 -52t-12.5 -58.5t-11.5 -53q-35 1 -101 -9.5t-98 -10.5q-39 0 -72 10q-2 16 -2 47q0 74 3 96q2 13 31.5 41.5t57 59t26.5 51.5q-24 2 -43 -24
-q-36 -53 -111.5 -99.5t-136.5 -46.5q-25 0 -75.5 63t-106.5 139.5t-84 96.5q-6 4 -27 30q-482 -112 -513 -112q-16 0 -28 11t-12 27q0 15 8.5 26.5t22.5 14.5l486 106q-8 14 -8 25t5.5 17.5t16 11.5t20 7t23 4.5t18.5 4.5q4 1 15.5 7.5t17.5 6.5q15 0 28 -16t20 -33
-q163 37 172 37q17 0 29.5 -11t12.5 -28q0 -15 -8.5 -26t-23.5 -14l-182 -40l-1 -16q-1 -26 81.5 -117.5t104.5 -91.5q47 0 119 80t72 129q0 36 -23.5 53t-51 18.5t-51 11.5t-23.5 34q0 16 10 34l-68 19q43 44 43 117q0 26 -5 58q82 16 144 16q44 0 71.5 -1.5t48.5 -8.5
-t31 -13.5t20.5 -24.5t15.5 -33.5t17 -47.5t24 -60l50 25q-3 -40 -23 -60t-42.5 -21t-40 -6.5t-16.5 -20.5zM1282 842q-5 5 -13.5 15.5t-12 14.5t-10.5 11.5t-10 10.5l-8 8t-8.5 7.5t-8 5t-8.5 4.5q-7 3 -14.5 5t-20.5 2.5t-22 0.5h-32.5h-37.5q-126 0 -217 -43
-q16 30 36 46.5t54 29.5t65.5 36t46 36.5t50 55t43.5 50.5q12 -9 28 -31.5t32 -36.5t38 -13l12 1v-76l22 -1q247 95 371 190q28 21 50 39t42.5 37.5t33 31t29.5 34t24 31t24.5 37t23 38t27 47.5t29.5 53l7 9q-2 -53 -43 -139q-79 -165 -205 -264t-306 -142q-14 -3 -42 -7.5
-t-50 -9.5t-39 -14q3 -19 24.5 -46t21.5 -34q0 -11 -26 -30zM1061 -79q39 26 131.5 47.5t146.5 21.5q9 0 22.5 -15.5t28 -42.5t26 -50t24 -51t14.5 -33q-121 -45 -244 -45q-61 0 -125 11zM822 568l48 12l109 -177l-73 -48zM1323 51q3 -15 3 -16q0 -7 -17.5 -14.5t-46 -13
-t-54 -9.5t-53.5 -7.5t-32 -4.5l-7 43q21 2 60.5 8.5t72 10t60.5 3.5h14zM866 679l-96 -20l-6 17q10 1 32.5 7t34.5 6q19 0 35 -10zM1061 45h31l10 -83l-41 -12v95zM1950 1535v1v-1zM1950 1535l-1 -5l-2 -2l1 3zM1950 1535l1 1z" />
-    <glyph glyph-name="_399" unicode="&#xf1a9;" 
-d="M1167 -50q-5 19 -24 5q-30 -22 -87 -39t-131 -17q-129 0 -193 49q-5 4 -13 4q-11 0 -26 -12q-7 -6 -7.5 -16t7.5 -20q34 -32 87.5 -46t102.5 -12.5t99 4.5q41 4 84.5 20.5t65 30t28.5 20.5q12 12 7 29zM1128 65q-19 47 -39 61q-23 15 -76 15q-47 0 -71 -10
-q-29 -12 -78 -56q-26 -24 -12 -44q9 -8 17.5 -4.5t31.5 23.5q3 2 10.5 8.5t10.5 8.5t10 7t11.5 7t12.5 5t15 4.5t16.5 2.5t20.5 1q27 0 44.5 -7.5t23 -14.5t13.5 -22q10 -17 12.5 -20t12.5 1q23 12 14 34zM1483 346q0 22 -5 44.5t-16.5 45t-34 36.5t-52.5 14
-q-33 0 -97 -41.5t-129 -83.5t-101 -42q-27 -1 -63.5 19t-76 49t-83.5 58t-100 49t-111 19q-115 -1 -197 -78.5t-84 -178.5q-2 -112 74 -164q29 -20 62.5 -28.5t103.5 -8.5q57 0 132 32.5t134 71t120 70.5t93 31q26 -1 65 -31.5t71.5 -67t68 -67.5t55.5 -32q35 -3 58.5 14
-t55.5 63q28 41 42.5 101t14.5 106zM1536 506q0 -164 -62 -304.5t-166 -236t-242.5 -149.5t-290.5 -54t-293 57.5t-247.5 157t-170.5 241.5t-64 302q0 89 19.5 172.5t49 145.5t70.5 118.5t78.5 94t78.5 69.5t64.5 46.5t42.5 24.5q14 8 51 26.5t54.5 28.5t48 30t60.5 44
-q36 28 58 72.5t30 125.5q129 -155 186 -193q44 -29 130 -68t129 -66q21 -13 39 -25t60.5 -46.5t76 -70.5t75 -95t69 -122t47 -148.5t19.5 -177.5z" />
-    <glyph glyph-name="_400" unicode="&#xf1aa;" 
-d="M1070 463l-160 -160l-151 -152l-30 -30q-65 -64 -151.5 -87t-171.5 -2q-16 -70 -72 -115t-129 -45q-85 0 -145 60.5t-60 145.5q0 72 44.5 128t113.5 72q-22 86 1 173t88 152l12 12l151 -152l-11 -11q-37 -37 -37 -89t37 -90q37 -37 89 -37t89 37l30 30l151 152l161 160z
-M729 1145l12 -12l-152 -152l-12 12q-37 37 -89 37t-89 -37t-37 -89.5t37 -89.5l29 -29l152 -152l160 -160l-151 -152l-161 160l-151 152l-30 30q-68 67 -90 159.5t5 179.5q-70 15 -115 71t-45 129q0 85 60 145.5t145 60.5q76 0 133.5 -49t69.5 -123q84 20 169.5 -3.5
-t149.5 -87.5zM1536 78q0 -85 -60 -145.5t-145 -60.5q-74 0 -131 47t-71 118q-86 -28 -179.5 -6t-161.5 90l-11 12l151 152l12 -12q37 -37 89 -37t89 37t37 89t-37 89l-30 30l-152 152l-160 160l152 152l160 -160l152 -152l29 -30q64 -64 87.5 -150.5t2.5 -171.5
-q76 -11 126.5 -68.5t50.5 -134.5zM1534 1202q0 -77 -51 -135t-127 -69q26 -85 3 -176.5t-90 -158.5l-12 -12l-151 152l12 12q37 37 37 89t-37 89t-89 37t-89 -37l-30 -30l-152 -152l-160 -160l-152 152l161 160l152 152l29 30q67 67 159 89.5t178 -3.5q11 75 68.5 126
-t135.5 51q85 0 145 -60.5t60 -145.5z" />
-    <glyph glyph-name="f1ab" unicode="&#xf1ab;" 
-d="M654 458q-1 -3 -12.5 0.5t-31.5 11.5l-20 9q-44 20 -87 49q-7 5 -41 31.5t-38 28.5q-67 -103 -134 -181q-81 -95 -105 -110q-4 -2 -19.5 -4t-18.5 0q6 4 82 92q21 24 85.5 115t78.5 118q17 30 51 98.5t36 77.5q-8 1 -110 -33q-8 -2 -27.5 -7.5t-34.5 -9.5t-17 -5
-q-2 -2 -2 -10.5t-1 -9.5q-5 -10 -31 -15q-23 -7 -47 0q-18 4 -28 21q-4 6 -5 23q6 2 24.5 5t29.5 6q58 16 105 32q100 35 102 35q10 2 43 19.5t44 21.5q9 3 21.5 8t14.5 5.5t6 -0.5q2 -12 -1 -33q0 -2 -12.5 -27t-26.5 -53.5t-17 -33.5q-25 -50 -77 -131l64 -28
-q12 -6 74.5 -32t67.5 -28q4 -1 10.5 -25.5t4.5 -30.5zM449 944q3 -15 -4 -28q-12 -23 -50 -38q-30 -12 -60 -12q-26 3 -49 26q-14 15 -18 41l1 3q3 -3 19.5 -5t26.5 0t58 16q36 12 55 14q17 0 21 -17zM1147 815l63 -227l-139 42zM39 15l694 232v1032l-694 -233v-1031z
-M1280 332l102 -31l-181 657l-100 31l-216 -536l102 -31l45 110l211 -65zM777 1294l573 -184v380zM1088 -29l158 -13l-54 -160l-40 66q-130 -83 -276 -108q-58 -12 -91 -12h-84q-79 0 -199.5 39t-183.5 85q-8 7 -8 16q0 8 5 13.5t13 5.5q4 0 18 -7.5t30.5 -16.5t20.5 -11
-q73 -37 159.5 -61.5t157.5 -24.5q95 0 167 14.5t157 50.5q15 7 30.5 15.5t34 19t28.5 16.5zM1536 1050v-1079l-774 246q-14 -6 -375 -127.5t-368 -121.5q-13 0 -18 13q0 1 -1 3v1078q3 9 4 10q5 6 20 11q107 36 149 50v384l558 -198q2 0 160.5 55t316 108.5t161.5 53.5
-q20 0 20 -21v-418z" />
-    <glyph glyph-name="_402" unicode="&#xf1ac;" horiz-adv-x="1792" 
-d="M288 1152q66 0 113 -47t47 -113v-1088q0 -66 -47 -113t-113 -47h-128q-66 0 -113 47t-47 113v1088q0 66 47 113t113 47h128zM1664 989q58 -34 93 -93t35 -128v-768q0 -106 -75 -181t-181 -75h-864q-66 0 -113 47t-47 113v1536q0 40 28 68t68 28h672q40 0 88 -20t76 -48
-l152 -152q28 -28 48 -76t20 -88v-163zM928 0v128q0 14 -9 23t-23 9h-128q-14 0 -23 -9t-9 -23v-128q0 -14 9 -23t23 -9h128q14 0 23 9t9 23zM928 256v128q0 14 -9 23t-23 9h-128q-14 0 -23 -9t-9 -23v-128q0 -14 9 -23t23 -9h128q14 0 23 9t9 23zM928 512v128q0 14 -9 23
-t-23 9h-128q-14 0 -23 -9t-9 -23v-128q0 -14 9 -23t23 -9h128q14 0 23 9t9 23zM1184 0v128q0 14 -9 23t-23 9h-128q-14 0 -23 -9t-9 -23v-128q0 -14 9 -23t23 -9h128q14 0 23 9t9 23zM1184 256v128q0 14 -9 23t-23 9h-128q-14 0 -23 -9t-9 -23v-128q0 -14 9 -23t23 -9h128
-q14 0 23 9t9 23zM1184 512v128q0 14 -9 23t-23 9h-128q-14 0 -23 -9t-9 -23v-128q0 -14 9 -23t23 -9h128q14 0 23 9t9 23zM1440 0v128q0 14 -9 23t-23 9h-128q-14 0 -23 -9t-9 -23v-128q0 -14 9 -23t23 -9h128q14 0 23 9t9 23zM1440 256v128q0 14 -9 23t-23 9h-128
-q-14 0 -23 -9t-9 -23v-128q0 -14 9 -23t23 -9h128q14 0 23 9t9 23zM1440 512v128q0 14 -9 23t-23 9h-128q-14 0 -23 -9t-9 -23v-128q0 -14 9 -23t23 -9h128q14 0 23 9t9 23zM1536 896v256h-160q-40 0 -68 28t-28 68v160h-640v-512h896z" />
-    <glyph glyph-name="_403" unicode="&#xf1ad;" 
-d="M1344 1536q26 0 45 -19t19 -45v-1664q0 -26 -19 -45t-45 -19h-1280q-26 0 -45 19t-19 45v1664q0 26 19 45t45 19h1280zM512 1248v-64q0 -14 9 -23t23 -9h64q14 0 23 9t9 23v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23zM512 992v-64q0 -14 9 -23t23 -9h64q14 0 23 9
-t9 23v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23zM512 736v-64q0 -14 9 -23t23 -9h64q14 0 23 9t9 23v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23zM512 480v-64q0 -14 9 -23t23 -9h64q14 0 23 9t9 23v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23zM384 160v64
-q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM384 416v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM384 672v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h64
-q14 0 23 9t9 23zM384 928v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM384 1184v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM896 -96v192q0 14 -9 23t-23 9h-320q-14 0 -23 -9
-t-9 -23v-192q0 -14 9 -23t23 -9h320q14 0 23 9t9 23zM896 416v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM896 672v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM896 928v64
-q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM896 1184v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM1152 160v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h64
-q14 0 23 9t9 23zM1152 416v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM1152 672v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM1152 928v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9
-t-9 -23v-64q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM1152 1184v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h64q14 0 23 9t9 23z" />
-    <glyph glyph-name="_404" unicode="&#xf1ae;" horiz-adv-x="1280" 
-d="M1188 988l-292 -292v-824q0 -46 -33 -79t-79 -33t-79 33t-33 79v384h-64v-384q0 -46 -33 -79t-79 -33t-79 33t-33 79v824l-292 292q-28 28 -28 68t28 68q29 28 68.5 28t67.5 -28l228 -228h368l228 228q28 28 68 28t68 -28q28 -29 28 -68.5t-28 -67.5zM864 1152
-q0 -93 -65.5 -158.5t-158.5 -65.5t-158.5 65.5t-65.5 158.5t65.5 158.5t158.5 65.5t158.5 -65.5t65.5 -158.5z" />
-    <glyph glyph-name="uniF1B1" unicode="&#xf1b0;" horiz-adv-x="1664" 
-d="M780 1064q0 -60 -19 -113.5t-63 -92.5t-105 -39q-76 0 -138 57.5t-92 135.5t-30 151q0 60 19 113.5t63 92.5t105 39q77 0 138.5 -57.5t91.5 -135t30 -151.5zM438 581q0 -80 -42 -139t-119 -59q-76 0 -141.5 55.5t-100.5 133.5t-35 152q0 80 42 139.5t119 59.5
-q76 0 141.5 -55.5t100.5 -134t35 -152.5zM832 608q118 0 255 -97.5t229 -237t92 -254.5q0 -46 -17 -76.5t-48.5 -45t-64.5 -20t-76 -5.5q-68 0 -187.5 45t-182.5 45q-66 0 -192.5 -44.5t-200.5 -44.5q-183 0 -183 146q0 86 56 191.5t139.5 192.5t187.5 146t193 59zM1071 819
-q-61 0 -105 39t-63 92.5t-19 113.5q0 74 30 151.5t91.5 135t138.5 57.5q61 0 105 -39t63 -92.5t19 -113.5q0 -73 -30 -151t-92 -135.5t-138 -57.5zM1503 923q77 0 119 -59.5t42 -139.5q0 -74 -35 -152t-100.5 -133.5t-141.5 -55.5q-77 0 -119 59t-42 139q0 74 35 152.5
-t100.5 134t141.5 55.5z" />
-    <glyph glyph-name="_406" unicode="&#xf1b1;" horiz-adv-x="768" 
-d="M704 1008q0 -145 -57 -243.5t-152 -135.5l45 -821q2 -26 -16 -45t-44 -19h-192q-26 0 -44 19t-16 45l45 821q-95 37 -152 135.5t-57 243.5q0 128 42.5 249.5t117.5 200t160 78.5t160 -78.5t117.5 -200t42.5 -249.5z" />
-    <glyph glyph-name="_407" unicode="&#xf1b2;" horiz-adv-x="1792" 
-d="M896 -93l640 349v636l-640 -233v-752zM832 772l698 254l-698 254l-698 -254zM1664 1024v-768q0 -35 -18 -65t-49 -47l-704 -384q-28 -16 -61 -16t-61 16l-704 384q-31 17 -49 47t-18 65v768q0 40 23 73t61 47l704 256q22 8 44 8t44 -8l704 -256q38 -14 61 -47t23 -73z
-" />
-    <glyph glyph-name="_408" unicode="&#xf1b3;" horiz-adv-x="2304" 
-d="M640 -96l384 192v314l-384 -164v-342zM576 358l404 173l-404 173l-404 -173zM1664 -96l384 192v314l-384 -164v-342zM1600 358l404 173l-404 173l-404 -173zM1152 651l384 165v266l-384 -164v-267zM1088 1030l441 189l-441 189l-441 -189zM2176 512v-416q0 -36 -19 -67
-t-52 -47l-448 -224q-25 -14 -57 -14t-57 14l-448 224q-4 2 -7 4q-2 -2 -7 -4l-448 -224q-25 -14 -57 -14t-57 14l-448 224q-33 16 -52 47t-19 67v416q0 38 21.5 70t56.5 48l434 186v400q0 38 21.5 70t56.5 48l448 192q23 10 50 10t50 -10l448 -192q35 -16 56.5 -48t21.5 -70
-v-400l434 -186q36 -16 57 -48t21 -70z" />
-    <glyph glyph-name="_409" unicode="&#xf1b4;" horiz-adv-x="2048" 
-d="M1848 1197h-511v-124h511v124zM1596 771q-90 0 -146 -52.5t-62 -142.5h408q-18 195 -200 195zM1612 186q63 0 122 32t76 87h221q-100 -307 -427 -307q-214 0 -340.5 132t-126.5 347q0 208 130.5 345.5t336.5 137.5q138 0 240.5 -68t153 -179t50.5 -248q0 -17 -2 -47h-658
-q0 -111 57.5 -171.5t166.5 -60.5zM277 236h296q205 0 205 167q0 180 -199 180h-302v-347zM277 773h281q78 0 123.5 36.5t45.5 113.5q0 144 -190 144h-260v-294zM0 1282h594q87 0 155 -14t126.5 -47.5t90 -96.5t31.5 -154q0 -181 -172 -263q114 -32 172 -115t58 -204
-q0 -75 -24.5 -136.5t-66 -103.5t-98.5 -71t-121 -42t-134 -13h-611v1260z" />
-    <glyph glyph-name="_410" unicode="&#xf1b5;" 
-d="M1248 1408q119 0 203.5 -84.5t84.5 -203.5v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960zM499 1041h-371v-787h382q117 0 197 57.5t80 170.5q0 158 -143 200q107 52 107 164q0 57 -19.5 96.5
-t-56.5 60.5t-79 29.5t-97 8.5zM477 723h-176v184h163q119 0 119 -90q0 -94 -106 -94zM486 388h-185v217h189q124 0 124 -113q0 -104 -128 -104zM1136 356q-68 0 -104 38t-36 107h411q1 10 1 30q0 132 -74.5 220.5t-203.5 88.5q-128 0 -210 -86t-82 -216q0 -135 79 -217
-t213 -82q205 0 267 191h-138q-11 -34 -47.5 -54t-75.5 -20zM1126 722q113 0 124 -122h-254q4 56 39 89t91 33zM964 988h319v-77h-319v77z" />
-    <glyph glyph-name="_411" unicode="&#xf1b6;" horiz-adv-x="1792" 
-d="M1582 954q0 -101 -71.5 -172.5t-172.5 -71.5t-172.5 71.5t-71.5 172.5t71.5 172.5t172.5 71.5t172.5 -71.5t71.5 -172.5zM812 212q0 104 -73 177t-177 73q-27 0 -54 -6l104 -42q77 -31 109.5 -106.5t1.5 -151.5q-31 -77 -107 -109t-152 -1q-21 8 -62 24.5t-61 24.5
-q32 -60 91 -96.5t130 -36.5q104 0 177 73t73 177zM1642 953q0 126 -89.5 215.5t-215.5 89.5q-127 0 -216.5 -89.5t-89.5 -215.5q0 -127 89.5 -216t216.5 -89q126 0 215.5 89t89.5 216zM1792 953q0 -189 -133.5 -322t-321.5 -133l-437 -319q-12 -129 -109 -218t-229 -89
-q-121 0 -214 76t-118 192l-230 92v429l389 -157q79 48 173 48q13 0 35 -2l284 407q2 187 135.5 319t320.5 132q188 0 321.5 -133.5t133.5 -321.5z" />
-    <glyph glyph-name="_412" unicode="&#xf1b7;" 
-d="M1242 889q0 80 -57 136.5t-137 56.5t-136.5 -57t-56.5 -136q0 -80 56.5 -136.5t136.5 -56.5t137 56.5t57 136.5zM632 301q0 -83 -58 -140.5t-140 -57.5q-56 0 -103 29t-72 77q52 -20 98 -40q60 -24 120 1.5t85 86.5q24 60 -1.5 120t-86.5 84l-82 33q22 5 42 5
-q82 0 140 -57.5t58 -140.5zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v153l172 -69q20 -92 93.5 -152t168.5 -60q104 0 181 70t87 173l345 252q150 0 255.5 105.5t105.5 254.5q0 150 -105.5 255.5t-255.5 105.5
-q-148 0 -253 -104.5t-107 -252.5l-225 -322q-9 1 -28 1q-75 0 -137 -37l-297 119v468q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5zM1289 887q0 -100 -71 -170.5t-171 -70.5t-170.5 70.5t-70.5 170.5t70.5 171t170.5 71q101 0 171.5 -70.5t70.5 -171.5z
-" />
-    <glyph glyph-name="_413" unicode="&#xf1b8;" horiz-adv-x="1792" 
-d="M836 367l-15 -368l-2 -22l-420 29q-36 3 -67 31.5t-47 65.5q-11 27 -14.5 55t4 65t12 55t21.5 64t19 53q78 -12 509 -28zM449 953l180 -379l-147 92q-63 -72 -111.5 -144.5t-72.5 -125t-39.5 -94.5t-18.5 -63l-4 -21l-190 357q-17 26 -18 56t6 47l8 18q35 63 114 188
-l-140 86zM1680 436l-188 -359q-12 -29 -36.5 -46.5t-43.5 -20.5l-18 -4q-71 -7 -219 -12l8 -164l-230 367l211 362l7 -173q170 -16 283 -5t170 33zM895 1360q-47 -63 -265 -435l-317 187l-19 12l225 356q20 31 60 45t80 10q24 -2 48.5 -12t42 -21t41.5 -33t36 -34.5
-t36 -39.5t32 -35zM1550 1053l212 -363q18 -37 12.5 -76t-27.5 -74q-13 -20 -33 -37t-38 -28t-48.5 -22t-47 -16t-51.5 -14t-46 -12q-34 72 -265 436l313 195zM1407 1279l142 83l-220 -373l-419 20l151 86q-34 89 -75 166t-75.5 123.5t-64.5 80t-47 46.5l-17 13l405 -1
-q31 3 58 -10.5t39 -28.5l11 -15q39 -61 112 -190z" />
-    <glyph glyph-name="_414" unicode="&#xf1b9;" horiz-adv-x="2048" 
-d="M480 448q0 66 -47 113t-113 47t-113 -47t-47 -113t47 -113t113 -47t113 47t47 113zM516 768h1016l-89 357q-2 8 -14 17.5t-21 9.5h-768q-9 0 -21 -9.5t-14 -17.5zM1888 448q0 66 -47 113t-113 47t-113 -47t-47 -113t47 -113t113 -47t113 47t47 113zM2048 544v-384
-q0 -14 -9 -23t-23 -9h-96v-128q0 -80 -56 -136t-136 -56t-136 56t-56 136v128h-1024v-128q0 -80 -56 -136t-136 -56t-136 56t-56 136v128h-96q-14 0 -23 9t-9 23v384q0 93 65.5 158.5t158.5 65.5h28l105 419q23 94 104 157.5t179 63.5h768q98 0 179 -63.5t104 -157.5
-l105 -419h28q93 0 158.5 -65.5t65.5 -158.5z" />
-    <glyph glyph-name="_415" unicode="&#xf1ba;" horiz-adv-x="2048" 
-d="M1824 640q93 0 158.5 -65.5t65.5 -158.5v-384q0 -14 -9 -23t-23 -9h-96v-64q0 -80 -56 -136t-136 -56t-136 56t-56 136v64h-1024v-64q0 -80 -56 -136t-136 -56t-136 56t-56 136v64h-96q-14 0 -23 9t-9 23v384q0 93 65.5 158.5t158.5 65.5h28l105 419q23 94 104 157.5
-t179 63.5h128v224q0 14 9 23t23 9h448q14 0 23 -9t9 -23v-224h128q98 0 179 -63.5t104 -157.5l105 -419h28zM320 160q66 0 113 47t47 113t-47 113t-113 47t-113 -47t-47 -113t47 -113t113 -47zM516 640h1016l-89 357q-2 8 -14 17.5t-21 9.5h-768q-9 0 -21 -9.5t-14 -17.5z
-M1728 160q66 0 113 47t47 113t-47 113t-113 47t-113 -47t-47 -113t47 -113t113 -47z" />
-    <glyph glyph-name="_416" unicode="&#xf1bb;" 
-d="M1504 64q0 -26 -19 -45t-45 -19h-462q1 -17 6 -87.5t5 -108.5q0 -25 -18 -42.5t-43 -17.5h-320q-25 0 -43 17.5t-18 42.5q0 38 5 108.5t6 87.5h-462q-26 0 -45 19t-19 45t19 45l402 403h-229q-26 0 -45 19t-19 45t19 45l402 403h-197q-26 0 -45 19t-19 45t19 45l384 384
-q19 19 45 19t45 -19l384 -384q19 -19 19 -45t-19 -45t-45 -19h-197l402 -403q19 -19 19 -45t-19 -45t-45 -19h-229l402 -403q19 -19 19 -45z" />
-    <glyph glyph-name="_417" unicode="&#xf1bc;" 
-d="M1127 326q0 32 -30 51q-193 115 -447 115q-133 0 -287 -34q-42 -9 -42 -52q0 -20 13.5 -34.5t35.5 -14.5q5 0 37 8q132 27 243 27q226 0 397 -103q19 -11 33 -11q19 0 33 13.5t14 34.5zM1223 541q0 40 -35 61q-237 141 -548 141q-153 0 -303 -42q-48 -13 -48 -64
-q0 -25 17.5 -42.5t42.5 -17.5q7 0 37 8q122 33 251 33q279 0 488 -124q24 -13 38 -13q25 0 42.5 17.5t17.5 42.5zM1331 789q0 47 -40 70q-126 73 -293 110.5t-343 37.5q-204 0 -364 -47q-23 -7 -38.5 -25.5t-15.5 -48.5q0 -31 20.5 -52t51.5 -21q11 0 40 8q133 37 307 37
-q159 0 309.5 -34t253.5 -95q21 -12 40 -12q29 0 50.5 20.5t21.5 51.5zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
-    <glyph glyph-name="_418" unicode="&#xf1bd;" horiz-adv-x="1024" 
-d="M1024 1233l-303 -582l24 -31h279v-415h-507l-44 -30l-142 -273l-30 -30h-301v303l303 583l-24 30h-279v415h507l44 30l142 273l30 30h301v-303z" />
-    <glyph glyph-name="_419" unicode="&#xf1be;" horiz-adv-x="2304" 
-d="M784 164l16 241l-16 523q-1 10 -7.5 17t-16.5 7q-9 0 -16 -7t-7 -17l-14 -523l14 -241q1 -10 7.5 -16.5t15.5 -6.5q22 0 24 23zM1080 193l11 211l-12 586q0 16 -13 24q-8 5 -16 5t-16 -5q-13 -8 -13 -24l-1 -6l-10 -579q0 -1 11 -236v-1q0 -10 6 -17q9 -11 23 -11
-q11 0 20 9q9 7 9 20zM35 533l20 -128l-20 -126q-2 -9 -9 -9t-9 9l-17 126l17 128q2 9 9 9t9 -9zM121 612l26 -207l-26 -203q-2 -9 -10 -9q-9 0 -9 10l-23 202l23 207q0 9 9 9q8 0 10 -9zM401 159zM213 650l25 -245l-25 -237q0 -11 -11 -11q-10 0 -12 11l-21 237l21 245
-q2 12 12 12q11 0 11 -12zM307 657l23 -252l-23 -244q-2 -13 -14 -13q-13 0 -13 13l-21 244l21 252q0 13 13 13q12 0 14 -13zM401 639l21 -234l-21 -246q-2 -16 -16 -16q-6 0 -10.5 4.5t-4.5 11.5l-20 246l20 234q0 6 4.5 10.5t10.5 4.5q14 0 16 -15zM784 164zM495 785
-l21 -380l-21 -246q0 -7 -5 -12.5t-12 -5.5q-16 0 -18 18l-18 246l18 380q2 18 18 18q7 0 12 -5.5t5 -12.5zM589 871l19 -468l-19 -244q0 -8 -5.5 -13.5t-13.5 -5.5q-18 0 -20 19l-16 244l16 468q2 19 20 19q8 0 13.5 -5.5t5.5 -13.5zM687 911l18 -506l-18 -242
-q-2 -21 -22 -21q-19 0 -21 21l-16 242l16 506q0 9 6.5 15.5t14.5 6.5q9 0 15 -6.5t7 -15.5zM1079 169v0v0v0zM881 915l15 -510l-15 -239q0 -10 -7.5 -17.5t-17.5 -7.5t-17 7t-8 18l-14 239l14 510q0 11 7.5 18t17.5 7t17.5 -7t7.5 -18zM980 896l14 -492l-14 -236
-q0 -11 -8 -19t-19 -8t-19 8t-9 19l-12 236l12 492q1 12 9 20t19 8t18.5 -8t8.5 -20zM1192 404l-14 -231v0q0 -13 -9 -22t-22 -9t-22 9t-10 22l-6 114l-6 117l12 636v3q2 15 12 24q9 7 20 7q8 0 15 -5q14 -8 16 -26zM2304 423q0 -117 -83 -199.5t-200 -82.5h-786
-q-13 2 -22 11t-9 22v899q0 23 28 33q85 34 181 34q195 0 338 -131.5t160 -323.5q53 22 110 22q117 0 200 -83t83 -201z" />
-    <glyph glyph-name="uniF1C0" unicode="&#xf1c0;" 
-d="M768 768q237 0 443 43t325 127v-170q0 -69 -103 -128t-280 -93.5t-385 -34.5t-385 34.5t-280 93.5t-103 128v170q119 -84 325 -127t443 -43zM768 0q237 0 443 43t325 127v-170q0 -69 -103 -128t-280 -93.5t-385 -34.5t-385 34.5t-280 93.5t-103 128v170q119 -84 325 -127
-t443 -43zM768 384q237 0 443 43t325 127v-170q0 -69 -103 -128t-280 -93.5t-385 -34.5t-385 34.5t-280 93.5t-103 128v170q119 -84 325 -127t443 -43zM768 1536q208 0 385 -34.5t280 -93.5t103 -128v-128q0 -69 -103 -128t-280 -93.5t-385 -34.5t-385 34.5t-280 93.5
-t-103 128v128q0 69 103 128t280 93.5t385 34.5z" />
-    <glyph glyph-name="uniF1C1" unicode="&#xf1c1;" 
-d="M1468 1156q28 -28 48 -76t20 -88v-1152q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68v1600q0 40 28 68t68 28h896q40 0 88 -20t76 -48zM1024 1400v-376h376q-10 29 -22 41l-313 313q-12 12 -41 22zM1408 -128v1024h-416q-40 0 -68 28t-28 68v416h-768v-1536h1280z
-M894 465q33 -26 84 -56q59 7 117 7q147 0 177 -49q16 -22 2 -52q0 -1 -1 -2l-2 -2v-1q-6 -38 -71 -38q-48 0 -115 20t-130 53q-221 -24 -392 -83q-153 -262 -242 -262q-15 0 -28 7l-24 12q-1 1 -6 5q-10 10 -6 36q9 40 56 91.5t132 96.5q14 9 23 -6q2 -2 2 -4q52 85 107 197
-q68 136 104 262q-24 82 -30.5 159.5t6.5 127.5q11 40 42 40h21h1q23 0 35 -15q18 -21 9 -68q-2 -6 -4 -8q1 -3 1 -8v-30q-2 -123 -14 -192q55 -164 146 -238zM318 54q52 24 137 158q-51 -40 -87.5 -84t-49.5 -74zM716 974q-15 -42 -2 -132q1 7 7 44q0 3 7 43q1 4 4 8
-q-1 1 -1 2q-1 2 -1 3q-1 22 -13 36q0 -1 -1 -2v-2zM592 313q135 54 284 81q-2 1 -13 9.5t-16 13.5q-76 67 -127 176q-27 -86 -83 -197q-30 -56 -45 -83zM1238 329q-24 24 -140 24q76 -28 124 -28q14 0 18 1q0 1 -2 3z" />
-    <glyph glyph-name="_422" unicode="&#xf1c2;" 
-d="M1468 1156q28 -28 48 -76t20 -88v-1152q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68v1600q0 40 28 68t68 28h896q40 0 88 -20t76 -48zM1024 1400v-376h376q-10 29 -22 41l-313 313q-12 12 -41 22zM1408 -128v1024h-416q-40 0 -68 28t-28 68v416h-768v-1536h1280z
-M233 768v-107h70l164 -661h159l128 485q7 20 10 46q2 16 2 24h4l3 -24q1 -3 3.5 -20t5.5 -26l128 -485h159l164 661h70v107h-300v-107h90l-99 -438q-5 -20 -7 -46l-2 -21h-4q0 3 -0.5 6.5t-1.5 8t-1 6.5q-1 5 -4 21t-5 25l-144 545h-114l-144 -545q-2 -9 -4.5 -24.5
-t-3.5 -21.5l-4 -21h-4l-2 21q-2 26 -7 46l-99 438h90v107h-300z" />
-    <glyph glyph-name="_423" unicode="&#xf1c3;" 
-d="M1468 1156q28 -28 48 -76t20 -88v-1152q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68v1600q0 40 28 68t68 28h896q40 0 88 -20t76 -48zM1024 1400v-376h376q-10 29 -22 41l-313 313q-12 12 -41 22zM1408 -128v1024h-416q-40 0 -68 28t-28 68v416h-768v-1536h1280z
-M429 106v-106h281v106h-75l103 161q5 7 10 16.5t7.5 13.5t3.5 4h2q1 -4 5 -10q2 -4 4.5 -7.5t6 -8t6.5 -8.5l107 -161h-76v-106h291v106h-68l-192 273l195 282h67v107h-279v-107h74l-103 -159q-4 -7 -10 -16.5t-9 -13.5l-2 -3h-2q-1 4 -5 10q-6 11 -17 23l-106 159h76v107
-h-290v-107h68l189 -272l-194 -283h-68z" />
-    <glyph glyph-name="_424" unicode="&#xf1c4;" 
-d="M1468 1156q28 -28 48 -76t20 -88v-1152q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68v1600q0 40 28 68t68 28h896q40 0 88 -20t76 -48zM1024 1400v-376h376q-10 29 -22 41l-313 313q-12 12 -41 22zM1408 -128v1024h-416q-40 0 -68 28t-28 68v416h-768v-1536h1280z
-M416 106v-106h327v106h-93v167h137q76 0 118 15q67 23 106.5 87t39.5 146q0 81 -37 141t-100 87q-48 19 -130 19h-368v-107h92v-555h-92zM769 386h-119v268h120q52 0 83 -18q56 -33 56 -115q0 -89 -62 -120q-31 -15 -78 -15z" />
-    <glyph glyph-name="_425" unicode="&#xf1c5;" 
-d="M1468 1156q28 -28 48 -76t20 -88v-1152q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68v1600q0 40 28 68t68 28h896q40 0 88 -20t76 -48zM1024 1400v-376h376q-10 29 -22 41l-313 313q-12 12 -41 22zM1408 -128v1024h-416q-40 0 -68 28t-28 68v416h-768v-1536h1280z
-M1280 320v-320h-1024v192l192 192l128 -128l384 384zM448 512q-80 0 -136 56t-56 136t56 136t136 56t136 -56t56 -136t-56 -136t-136 -56z" />
-    <glyph glyph-name="_426" unicode="&#xf1c6;" 
-d="M640 1152v128h-128v-128h128zM768 1024v128h-128v-128h128zM640 896v128h-128v-128h128zM768 768v128h-128v-128h128zM1468 1156q28 -28 48 -76t20 -88v-1152q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68v1600q0 40 28 68t68 28h896q40 0 88 -20t76 -48zM1024 1400
-v-376h376q-10 29 -22 41l-313 313q-12 12 -41 22zM1408 -128v1024h-416q-40 0 -68 28t-28 68v416h-128v-128h-128v128h-512v-1536h1280zM781 593l107 -349q8 -27 8 -52q0 -83 -72.5 -137.5t-183.5 -54.5t-183.5 54.5t-72.5 137.5q0 25 8 52q21 63 120 396v128h128v-128h79
-q22 0 39 -13t23 -34zM640 128q53 0 90.5 19t37.5 45t-37.5 45t-90.5 19t-90.5 -19t-37.5 -45t37.5 -45t90.5 -19z" />
-    <glyph glyph-name="_427" unicode="&#xf1c7;" 
-d="M1468 1156q28 -28 48 -76t20 -88v-1152q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68v1600q0 40 28 68t68 28h896q40 0 88 -20t76 -48zM1024 1400v-376h376q-10 29 -22 41l-313 313q-12 12 -41 22zM1408 -128v1024h-416q-40 0 -68 28t-28 68v416h-768v-1536h1280z
-M620 686q20 -8 20 -30v-544q0 -22 -20 -30q-8 -2 -12 -2q-12 0 -23 9l-166 167h-131q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h131l166 167q16 15 35 7zM1037 -3q31 0 50 24q129 159 129 363t-129 363q-16 21 -43 24t-47 -14q-21 -17 -23.5 -43.5t14.5 -47.5
-q100 -123 100 -282t-100 -282q-17 -21 -14.5 -47.5t23.5 -42.5q18 -15 40 -15zM826 145q27 0 47 20q87 93 87 219t-87 219q-18 19 -45 20t-46 -17t-20 -44.5t18 -46.5q52 -57 52 -131t-52 -131q-19 -20 -18 -46.5t20 -44.5q20 -17 44 -17z" />
-    <glyph glyph-name="_428" unicode="&#xf1c8;" 
-d="M1468 1156q28 -28 48 -76t20 -88v-1152q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68v1600q0 40 28 68t68 28h896q40 0 88 -20t76 -48zM1024 1400v-376h376q-10 29 -22 41l-313 313q-12 12 -41 22zM1408 -128v1024h-416q-40 0 -68 28t-28 68v416h-768v-1536h1280z
-M768 768q52 0 90 -38t38 -90v-384q0 -52 -38 -90t-90 -38h-384q-52 0 -90 38t-38 90v384q0 52 38 90t90 38h384zM1260 766q20 -8 20 -30v-576q0 -22 -20 -30q-8 -2 -12 -2q-14 0 -23 9l-265 266v90l265 266q9 9 23 9q4 0 12 -2z" />
-    <glyph glyph-name="_429" unicode="&#xf1c9;" 
-d="M1468 1156q28 -28 48 -76t20 -88v-1152q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68v1600q0 40 28 68t68 28h896q40 0 88 -20t76 -48zM1024 1400v-376h376q-10 29 -22 41l-313 313q-12 12 -41 22zM1408 -128v1024h-416q-40 0 -68 28t-28 68v416h-768v-1536h1280z
-M480 768q8 11 21 12.5t24 -6.5l51 -38q11 -8 12.5 -21t-6.5 -24l-182 -243l182 -243q8 -11 6.5 -24t-12.5 -21l-51 -38q-11 -8 -24 -6.5t-21 12.5l-226 301q-14 19 0 38zM1282 467q14 -19 0 -38l-226 -301q-8 -11 -21 -12.5t-24 6.5l-51 38q-11 8 -12.5 21t6.5 24l182 243
-l-182 243q-8 11 -6.5 24t12.5 21l51 38q11 8 24 6.5t21 -12.5zM662 6q-13 2 -20.5 13t-5.5 24l138 831q2 13 13 20.5t24 5.5l63 -10q13 -2 20.5 -13t5.5 -24l-138 -831q-2 -13 -13 -20.5t-24 -5.5z" />
-    <glyph glyph-name="_430" unicode="&#xf1ca;" 
-d="M1497 709v-198q-101 -23 -198 -23q-65 -136 -165.5 -271t-181.5 -215.5t-128 -106.5q-80 -45 -162 3q-28 17 -60.5 43.5t-85 83.5t-102.5 128.5t-107.5 184t-105.5 244t-91.5 314.5t-70.5 390h283q26 -218 70 -398.5t104.5 -317t121.5 -235.5t140 -195q169 169 287 406
-q-142 72 -223 220t-81 333q0 192 104 314.5t284 122.5q178 0 273 -105.5t95 -297.5q0 -159 -58 -286q-7 -1 -19.5 -3t-46 -2t-63 6t-62 25.5t-50.5 51.5q31 103 31 184q0 87 -29 132t-79 45q-53 0 -85 -49.5t-32 -140.5q0 -186 105 -293.5t267 -107.5q62 0 121 14z" />
-    <glyph glyph-name="_431" unicode="&#xf1cb;" horiz-adv-x="1792" 
-d="M216 367l603 -402v359l-334 223zM154 511l193 129l-193 129v-258zM973 -35l603 402l-269 180l-334 -223v-359zM896 458l272 182l-272 182l-272 -182zM485 733l334 223v359l-603 -402zM1445 640l193 -129v258zM1307 733l269 180l-603 402v-359zM1792 913v-546
-q0 -41 -34 -64l-819 -546q-21 -13 -43 -13t-43 13l-819 546q-34 23 -34 64v546q0 41 34 64l819 546q21 13 43 13t43 -13l819 -546q34 -23 34 -64z" />
-    <glyph glyph-name="_432" unicode="&#xf1cc;" horiz-adv-x="2048" 
-d="M1800 764q111 -46 179.5 -145.5t68.5 -221.5q0 -164 -118 -280.5t-285 -116.5q-4 0 -11.5 0.5t-10.5 0.5h-1209h-1h-2h-5q-170 10 -288 125.5t-118 280.5q0 110 55 203t147 147q-12 39 -12 82q0 115 82 196t199 81q95 0 172 -58q75 154 222.5 248t326.5 94
-q166 0 306 -80.5t221.5 -218.5t81.5 -301q0 -6 -0.5 -18t-0.5 -18zM468 498q0 -122 84 -193t208 -71q137 0 240 99q-16 20 -47.5 56.5t-43.5 50.5q-67 -65 -144 -65q-55 0 -93.5 33.5t-38.5 87.5q0 53 38.5 87t91.5 34q44 0 84.5 -21t73 -55t65 -75t69 -82t77 -75t97 -55
-t121.5 -21q121 0 204.5 71.5t83.5 190.5q0 121 -84 192t-207 71q-143 0 -241 -97l93 -108q66 64 142 64q52 0 92 -33t40 -84q0 -57 -37 -91.5t-94 -34.5q-43 0 -82.5 21t-72 55t-65.5 75t-69.5 82t-77.5 75t-96.5 55t-118.5 21q-122 0 -207 -70.5t-85 -189.5z" />
-    <glyph glyph-name="_433" unicode="&#xf1cd;" horiz-adv-x="1792" 
-d="M896 1536q182 0 348 -71t286 -191t191 -286t71 -348t-71 -348t-191 -286t-286 -191t-348 -71t-348 71t-286 191t-191 286t-71 348t71 348t191 286t286 191t348 71zM896 1408q-190 0 -361 -90l194 -194q82 28 167 28t167 -28l194 194q-171 90 -361 90zM218 279l194 194
-q-28 82 -28 167t28 167l-194 194q-90 -171 -90 -361t90 -361zM896 -128q190 0 361 90l-194 194q-82 -28 -167 -28t-167 28l-194 -194q171 -90 361 -90zM896 256q159 0 271.5 112.5t112.5 271.5t-112.5 271.5t-271.5 112.5t-271.5 -112.5t-112.5 -271.5t112.5 -271.5
-t271.5 -112.5zM1380 473l194 -194q90 171 90 361t-90 361l-194 -194q28 -82 28 -167t-28 -167z" />
-    <glyph glyph-name="_434" unicode="&#xf1ce;" horiz-adv-x="1792" 
-d="M1760 640q0 -176 -68.5 -336t-184 -275.5t-275.5 -184t-336 -68.5t-336 68.5t-275.5 184t-184 275.5t-68.5 336q0 213 97 398.5t265 305.5t374 151v-228q-221 -45 -366.5 -221t-145.5 -406q0 -130 51 -248.5t136.5 -204t204 -136.5t248.5 -51t248.5 51t204 136.5
-t136.5 204t51 248.5q0 230 -145.5 406t-366.5 221v228q206 -31 374 -151t265 -305.5t97 -398.5z" />
-    <glyph glyph-name="uniF1D0" unicode="&#xf1d0;" horiz-adv-x="1792" 
-d="M19 662q8 217 116 406t305 318h5q0 -1 -1 -3q-8 -8 -28 -33.5t-52 -76.5t-60 -110.5t-44.5 -135.5t-14 -150.5t39 -157.5t108.5 -154q50 -50 102 -69.5t90.5 -11.5t69.5 23.5t47 32.5l16 16q39 51 53 116.5t6.5 122.5t-21 107t-26.5 80l-14 29q-10 25 -30.5 49.5t-43 41
-t-43.5 29.5t-35 19l-13 6l104 115q39 -17 78 -52t59 -61l19 -27q1 48 -18.5 103.5t-40.5 87.5l-20 31l161 183l160 -181q-33 -46 -52.5 -102.5t-22.5 -90.5l-4 -33q22 37 61.5 72.5t67.5 52.5l28 17l103 -115q-44 -14 -85 -50t-60 -65l-19 -29q-31 -56 -48 -133.5t-7 -170
-t57 -156.5q33 -45 77.5 -60.5t85 -5.5t76 26.5t57.5 33.5l21 16q60 53 96.5 115t48.5 121.5t10 121.5t-18 118t-37 107.5t-45.5 93t-45 72t-34.5 47.5l-13 17q-14 13 -7 13l10 -3q40 -29 62.5 -46t62 -50t64 -58t58.5 -65t55.5 -77t45.5 -88t38 -103t23.5 -117t10.5 -136
-q3 -259 -108 -465t-312 -321t-456 -115q-185 0 -351 74t-283.5 198t-184 293t-60.5 353z" />
-    <glyph glyph-name="uniF1D1" unicode="&#xf1d1;" horiz-adv-x="1792" 
-d="M874 -102v-66q-208 6 -385 109.5t-283 275.5l58 34q29 -49 73 -99l65 57q148 -168 368 -212l-17 -86q65 -12 121 -13zM276 428l-83 -28q22 -60 49 -112l-57 -33q-98 180 -98 385t98 385l57 -33q-30 -56 -49 -112l82 -28q-35 -100 -35 -212q0 -109 36 -212zM1528 251
-l58 -34q-106 -172 -283 -275.5t-385 -109.5v66q56 1 121 13l-17 86q220 44 368 212l65 -57q44 50 73 99zM1377 805l-233 -80q14 -42 14 -85t-14 -85l232 -80q-31 -92 -98 -169l-185 162q-57 -67 -147 -85l48 -241q-52 -10 -98 -10t-98 10l48 241q-90 18 -147 85l-185 -162
-q-67 77 -98 169l232 80q-14 42 -14 85t14 85l-233 80q33 93 99 169l185 -162q59 68 147 86l-48 240q44 10 98 10t98 -10l-48 -240q88 -18 147 -86l185 162q66 -76 99 -169zM874 1448v-66q-65 -2 -121 -13l17 -86q-220 -42 -368 -211l-65 56q-38 -42 -73 -98l-57 33
-q106 172 282 275.5t385 109.5zM1705 640q0 -205 -98 -385l-57 33q27 52 49 112l-83 28q36 103 36 212q0 112 -35 212l82 28q-19 56 -49 112l57 33q98 -180 98 -385zM1585 1063l-57 -33q-35 56 -73 98l-65 -56q-148 169 -368 211l17 86q-56 11 -121 13v66q209 -6 385 -109.5
-t282 -275.5zM1748 640q0 173 -67.5 331t-181.5 272t-272 181.5t-331 67.5t-331 -67.5t-272 -181.5t-181.5 -272t-67.5 -331t67.5 -331t181.5 -272t272 -181.5t331 -67.5t331 67.5t272 181.5t181.5 272t67.5 331zM1792 640q0 -182 -71 -348t-191 -286t-286 -191t-348 -71
-t-348 71t-286 191t-191 286t-71 348t71 348t191 286t286 191t348 71t348 -71t286 -191t191 -286t71 -348z" />
-    <glyph glyph-name="uniF1D2" unicode="&#xf1d2;" 
-d="M582 228q0 -66 -93 -66q-107 0 -107 63q0 64 98 64q102 0 102 -61zM546 694q0 -85 -74 -85q-77 0 -77 84q0 90 77 90q36 0 55 -25.5t19 -63.5zM712 769v125q-78 -29 -135 -29q-50 29 -110 29q-86 0 -145 -57t-59 -143q0 -50 29.5 -102t73.5 -67v-3q-38 -17 -38 -85
-q0 -53 41 -77v-3q-113 -37 -113 -139q0 -45 20 -78.5t54 -51t72 -25.5t81 -8q224 0 224 188q0 67 -48 99t-126 46q-27 5 -51.5 20.5t-24.5 39.5q0 44 49 52q77 15 122 70t45 134q0 24 -10 52q37 9 49 13zM771 350h137q-2 27 -2 82v387q0 46 2 69h-137q3 -23 3 -71v-392
-q0 -50 -3 -75zM1280 366v121q-30 -21 -68 -21q-53 0 -53 82v225h52q9 0 26.5 -1t26.5 -1v117h-105q0 82 3 102h-140q4 -24 4 -55v-47h-60v-117q36 3 37 3q3 0 11 -0.5t12 -0.5v-2h-2v-217q0 -37 2.5 -64t11.5 -56.5t24.5 -48.5t43.5 -31t66 -12q64 0 108 24zM924 1072
-q0 36 -24 63.5t-60 27.5t-60.5 -27t-24.5 -64q0 -36 25 -62.5t60 -26.5t59.5 27t24.5 62zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
-    <glyph glyph-name="_438" unicode="&#xf1d3;" horiz-adv-x="1792" 
-d="M595 22q0 100 -165 100q-158 0 -158 -104q0 -101 172 -101q151 0 151 105zM536 777q0 61 -30 102t-89 41q-124 0 -124 -145q0 -135 124 -135q119 0 119 137zM805 1101v-202q-36 -12 -79 -22q16 -43 16 -84q0 -127 -73 -216.5t-197 -112.5q-40 -8 -59.5 -27t-19.5 -58
-q0 -31 22.5 -51.5t58 -32t78.5 -22t86 -25.5t78.5 -37.5t58 -64t22.5 -98.5q0 -304 -363 -304q-69 0 -130 12.5t-116 41t-87.5 82t-32.5 127.5q0 165 182 225v4q-67 41 -67 126q0 109 63 137v4q-72 24 -119.5 108.5t-47.5 165.5q0 139 95 231.5t235 92.5q96 0 178 -47
-q98 0 218 47zM1123 220h-222q4 45 4 134v609q0 94 -4 128h222q-4 -33 -4 -124v-613q0 -89 4 -134zM1724 442v-196q-71 -39 -174 -39q-62 0 -107 20t-70 50t-39.5 78t-18.5 92t-4 103v351h2v4q-7 0 -19 1t-18 1q-21 0 -59 -6v190h96v76q0 54 -6 89h227q-6 -41 -6 -165h171
-v-190q-15 0 -43.5 2t-42.5 2h-85v-365q0 -131 87 -131q61 0 109 33zM1148 1389q0 -58 -39 -101.5t-96 -43.5q-58 0 -98 43.5t-40 101.5q0 59 39.5 103t98.5 44q58 0 96.5 -44.5t38.5 -102.5z" />
-    <glyph glyph-name="_439" unicode="&#xf1d4;" 
-d="M809 532l266 499h-112l-157 -312q-24 -48 -44 -92l-42 92l-155 312h-120l263 -493v-324h101v318zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
-    <glyph glyph-name="uniF1D5" unicode="&#xf1d5;" horiz-adv-x="1280" 
-d="M842 964q0 -80 -57 -136.5t-136 -56.5q-60 0 -111 35q-62 -67 -115 -146q-247 -371 -202 -859q1 -22 -12.5 -38.5t-34.5 -18.5h-5q-20 0 -35 13.5t-17 33.5q-14 126 -3.5 247.5t29.5 217t54 186t69 155.5t74 125q61 90 132 165q-16 35 -16 77q0 80 56.5 136.5t136.5 56.5
-t136.5 -56.5t56.5 -136.5zM1223 953q0 -158 -78 -292t-212.5 -212t-292.5 -78q-64 0 -131 14q-21 5 -32.5 23.5t-6.5 39.5q5 20 23 31.5t39 7.5q51 -13 108 -13q97 0 186 38t153 102t102 153t38 186t-38 186t-102 153t-153 102t-186 38t-186 -38t-153 -102t-102 -153
-t-38 -186q0 -114 52 -218q10 -20 3.5 -40t-25.5 -30t-39.5 -3t-30.5 26q-64 123 -64 265q0 119 46.5 227t124.5 186t186 124t226 46q158 0 292.5 -78t212.5 -212.5t78 -292.5z" />
-    <glyph glyph-name="uniF1D6" unicode="&#xf1d6;" horiz-adv-x="1792" 
-d="M270 730q-8 19 -8 52q0 20 11 49t24 45q-1 22 7.5 53t22.5 43q0 139 92.5 288.5t217.5 209.5q139 66 324 66q133 0 266 -55q49 -21 90 -48t71 -56t55 -68t42 -74t32.5 -84.5t25.5 -89.5t22 -98l1 -5q55 -83 55 -150q0 -14 -9 -40t-9 -38q0 -1 1.5 -3.5t3.5 -5t2 -3.5
-q77 -114 120.5 -214.5t43.5 -208.5q0 -43 -19.5 -100t-55.5 -57q-9 0 -19.5 7.5t-19 17.5t-19 26t-16 26.5t-13.5 26t-9 17.5q-1 1 -3 1l-5 -4q-59 -154 -132 -223q20 -20 61.5 -38.5t69 -41.5t35.5 -65q-2 -4 -4 -16t-7 -18q-64 -97 -302 -97q-53 0 -110.5 9t-98 20
-t-104.5 30q-15 5 -23 7q-14 4 -46 4.5t-40 1.5q-41 -45 -127.5 -65t-168.5 -20q-35 0 -69 1.5t-93 9t-101 20.5t-74.5 40t-32.5 64q0 40 10 59.5t41 48.5q11 2 40.5 13t49.5 12q4 0 14 2q2 2 2 4l-2 3q-48 11 -108 105.5t-73 156.5l-5 3q-4 0 -12 -20q-18 -41 -54.5 -74.5
-t-77.5 -37.5h-1q-4 0 -6 4.5t-5 5.5q-23 54 -23 100q0 275 252 466z" />
-    <glyph glyph-name="uniF1D7" unicode="&#xf1d7;" horiz-adv-x="2048" 
-d="M580 1075q0 41 -25 66t-66 25q-43 0 -76 -25.5t-33 -65.5q0 -39 33 -64.5t76 -25.5q41 0 66 24.5t25 65.5zM1323 568q0 28 -25.5 50t-65.5 22q-27 0 -49.5 -22.5t-22.5 -49.5q0 -28 22.5 -50.5t49.5 -22.5q40 0 65.5 22t25.5 51zM1087 1075q0 41 -24.5 66t-65.5 25
-q-43 0 -76 -25.5t-33 -65.5q0 -39 33 -64.5t76 -25.5q41 0 65.5 24.5t24.5 65.5zM1722 568q0 28 -26 50t-65 22q-27 0 -49.5 -22.5t-22.5 -49.5q0 -28 22.5 -50.5t49.5 -22.5q39 0 65 22t26 51zM1456 965q-31 4 -70 4q-169 0 -311 -77t-223.5 -208.5t-81.5 -287.5
-q0 -78 23 -152q-35 -3 -68 -3q-26 0 -50 1.5t-55 6.5t-44.5 7t-54.5 10.5t-50 10.5l-253 -127l72 218q-290 203 -290 490q0 169 97.5 311t264 223.5t363.5 81.5q176 0 332.5 -66t262 -182.5t136.5 -260.5zM2048 404q0 -117 -68.5 -223.5t-185.5 -193.5l55 -181l-199 109
-q-150 -37 -218 -37q-169 0 -311 70.5t-223.5 191.5t-81.5 264t81.5 264t223.5 191.5t311 70.5q161 0 303 -70.5t227.5 -192t85.5 -263.5z" />
-    <glyph glyph-name="_443" unicode="&#xf1d8;" horiz-adv-x="1792" 
-d="M1764 1525q33 -24 27 -64l-256 -1536q-5 -29 -32 -45q-14 -8 -31 -8q-11 0 -24 5l-453 185l-242 -295q-18 -23 -49 -23q-13 0 -22 4q-19 7 -30.5 23.5t-11.5 36.5v349l864 1059l-1069 -925l-395 162q-37 14 -40 55q-2 40 32 59l1664 960q15 9 32 9q20 0 36 -11z" />
-    <glyph glyph-name="_444" unicode="&#xf1d9;" horiz-adv-x="1792" 
-d="M1764 1525q33 -24 27 -64l-256 -1536q-5 -29 -32 -45q-14 -8 -31 -8q-11 0 -24 5l-527 215l-298 -327q-18 -21 -47 -21q-14 0 -23 4q-19 7 -30 23.5t-11 36.5v452l-472 193q-37 14 -40 55q-3 39 32 59l1664 960q35 21 68 -2zM1422 26l221 1323l-1434 -827l336 -137
-l863 639l-478 -797z" />
-    <glyph glyph-name="_445" unicode="&#xf1da;" 
-d="M1536 640q0 -156 -61 -298t-164 -245t-245 -164t-298 -61q-172 0 -327 72.5t-264 204.5q-7 10 -6.5 22.5t8.5 20.5l137 138q10 9 25 9q16 -2 23 -12q73 -95 179 -147t225 -52q104 0 198.5 40.5t163.5 109.5t109.5 163.5t40.5 198.5t-40.5 198.5t-109.5 163.5
-t-163.5 109.5t-198.5 40.5q-98 0 -188 -35.5t-160 -101.5l137 -138q31 -30 14 -69q-17 -40 -59 -40h-448q-26 0 -45 19t-19 45v448q0 42 40 59q39 17 69 -14l130 -129q107 101 244.5 156.5t284.5 55.5q156 0 298 -61t245 -164t164 -245t61 -298zM896 928v-448q0 -14 -9 -23
-t-23 -9h-320q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h224v352q0 14 9 23t23 9h64q14 0 23 -9t9 -23z" />
-    <glyph glyph-name="_446" unicode="&#xf1db;" 
-d="M768 1280q-130 0 -248.5 -51t-204 -136.5t-136.5 -204t-51 -248.5t51 -248.5t136.5 -204t204 -136.5t248.5 -51t248.5 51t204 136.5t136.5 204t51 248.5t-51 248.5t-136.5 204t-204 136.5t-248.5 51zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103
-t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
-    <glyph glyph-name="_447" unicode="&#xf1dc;" horiz-adv-x="1792" 
-d="M1682 -128q-44 0 -132.5 3.5t-133.5 3.5q-44 0 -132 -3.5t-132 -3.5q-24 0 -37 20.5t-13 45.5q0 31 17 46t39 17t51 7t45 15q33 21 33 140l-1 391q0 21 -1 31q-13 4 -50 4h-675q-38 0 -51 -4q-1 -10 -1 -31l-1 -371q0 -142 37 -164q16 -10 48 -13t57 -3.5t45 -15
-t20 -45.5q0 -26 -12.5 -48t-36.5 -22q-47 0 -139.5 3.5t-138.5 3.5q-43 0 -128 -3.5t-127 -3.5q-23 0 -35.5 21t-12.5 45q0 30 15.5 45t36 17.5t47.5 7.5t42 15q33 23 33 143l-1 57v813q0 3 0.5 26t0 36.5t-1.5 38.5t-3.5 42t-6.5 36.5t-11 31.5t-16 18q-15 10 -45 12t-53 2
-t-41 14t-18 45q0 26 12 48t36 22q46 0 138.5 -3.5t138.5 -3.5q42 0 126.5 3.5t126.5 3.5q25 0 37.5 -22t12.5 -48q0 -30 -17 -43.5t-38.5 -14.5t-49.5 -4t-43 -13q-35 -21 -35 -160l1 -320q0 -21 1 -32q13 -3 39 -3h699q25 0 38 3q1 11 1 32l1 320q0 139 -35 160
-q-18 11 -58.5 12.5t-66 13t-25.5 49.5q0 26 12.5 48t37.5 22q44 0 132 -3.5t132 -3.5q43 0 129 3.5t129 3.5q25 0 37.5 -22t12.5 -48q0 -30 -17.5 -44t-40 -14.5t-51.5 -3t-44 -12.5q-35 -23 -35 -161l1 -943q0 -119 34 -140q16 -10 46 -13.5t53.5 -4.5t41.5 -15.5t18 -44.5
-q0 -26 -12 -48t-36 -22z" />
-    <glyph glyph-name="_448" unicode="&#xf1dd;" horiz-adv-x="1280" 
-d="M1278 1347v-73q0 -29 -18.5 -61t-42.5 -32q-50 0 -54 -1q-26 -6 -32 -31q-3 -11 -3 -64v-1152q0 -25 -18 -43t-43 -18h-108q-25 0 -43 18t-18 43v1218h-143v-1218q0 -25 -17.5 -43t-43.5 -18h-108q-26 0 -43.5 18t-17.5 43v496q-147 12 -245 59q-126 58 -192 179
-q-64 117 -64 259q0 166 88 286q88 118 209 159q111 37 417 37h479q25 0 43 -18t18 -43z" />
-    <glyph glyph-name="_449" unicode="&#xf1de;" 
-d="M352 128v-128h-352v128h352zM704 256q26 0 45 -19t19 -45v-256q0 -26 -19 -45t-45 -19h-256q-26 0 -45 19t-19 45v256q0 26 19 45t45 19h256zM864 640v-128h-864v128h864zM224 1152v-128h-224v128h224zM1536 128v-128h-736v128h736zM576 1280q26 0 45 -19t19 -45v-256
-q0 -26 -19 -45t-45 -19h-256q-26 0 -45 19t-19 45v256q0 26 19 45t45 19h256zM1216 768q26 0 45 -19t19 -45v-256q0 -26 -19 -45t-45 -19h-256q-26 0 -45 19t-19 45v256q0 26 19 45t45 19h256zM1536 640v-128h-224v128h224zM1536 1152v-128h-864v128h864z" />
-    <glyph glyph-name="uniF1E0" unicode="&#xf1e0;" 
-d="M1216 512q133 0 226.5 -93.5t93.5 -226.5t-93.5 -226.5t-226.5 -93.5t-226.5 93.5t-93.5 226.5q0 12 2 34l-360 180q-92 -86 -218 -86q-133 0 -226.5 93.5t-93.5 226.5t93.5 226.5t226.5 93.5q126 0 218 -86l360 180q-2 22 -2 34q0 133 93.5 226.5t226.5 93.5
-t226.5 -93.5t93.5 -226.5t-93.5 -226.5t-226.5 -93.5q-126 0 -218 86l-360 -180q2 -22 2 -34t-2 -34l360 -180q92 86 218 86z" />
-    <glyph glyph-name="_451" unicode="&#xf1e1;" 
-d="M1280 341q0 88 -62.5 151t-150.5 63q-84 0 -145 -58l-241 120q2 16 2 23t-2 23l241 120q61 -58 145 -58q88 0 150.5 63t62.5 151t-62.5 150.5t-150.5 62.5t-151 -62.5t-63 -150.5q0 -7 2 -23l-241 -120q-62 57 -145 57q-88 0 -150.5 -62.5t-62.5 -150.5t62.5 -150.5
-t150.5 -62.5q83 0 145 57l241 -120q-2 -16 -2 -23q0 -88 63 -150.5t151 -62.5t150.5 62.5t62.5 150.5zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
-    <glyph glyph-name="_452" unicode="&#xf1e2;" horiz-adv-x="1792" 
-d="M571 947q-10 25 -34 35t-49 0q-108 -44 -191 -127t-127 -191q-10 -25 0 -49t35 -34q13 -5 24 -5q42 0 60 40q34 84 98.5 148.5t148.5 98.5q25 11 35 35t0 49zM1513 1303l46 -46l-244 -243l68 -68q19 -19 19 -45.5t-19 -45.5l-64 -64q89 -161 89 -343q0 -143 -55.5 -273.5
-t-150 -225t-225 -150t-273.5 -55.5t-273.5 55.5t-225 150t-150 225t-55.5 273.5t55.5 273.5t150 225t225 150t273.5 55.5q182 0 343 -89l64 64q19 19 45.5 19t45.5 -19l68 -68zM1521 1359q-10 -10 -22 -10q-13 0 -23 10l-91 90q-9 10 -9 23t9 23q10 9 23 9t23 -9l90 -91
-q10 -9 10 -22.5t-10 -22.5zM1751 1129q-11 -9 -23 -9t-23 9l-90 91q-10 9 -10 22.5t10 22.5q9 10 22.5 10t22.5 -10l91 -90q9 -10 9 -23t-9 -23zM1792 1312q0 -14 -9 -23t-23 -9h-96q-14 0 -23 9t-9 23t9 23t23 9h96q14 0 23 -9t9 -23zM1600 1504v-96q0 -14 -9 -23t-23 -9
-t-23 9t-9 23v96q0 14 9 23t23 9t23 -9t9 -23zM1751 1449l-91 -90q-10 -10 -22 -10q-13 0 -23 10q-10 9 -10 22.5t10 22.5l90 91q10 9 23 9t23 -9q9 -10 9 -23t-9 -23z" />
-    <glyph glyph-name="_453" unicode="&#xf1e3;" horiz-adv-x="1792" 
-d="M609 720l287 208l287 -208l-109 -336h-355zM896 1536q182 0 348 -71t286 -191t191 -286t71 -348t-71 -348t-191 -286t-286 -191t-348 -71t-348 71t-286 191t-191 286t-71 348t71 348t191 286t286 191t348 71zM1515 186q149 203 149 454v3l-102 -89l-240 224l63 323
-l134 -12q-150 206 -389 282l53 -124l-287 -159l-287 159l53 124q-239 -76 -389 -282l135 12l62 -323l-240 -224l-102 89v-3q0 -251 149 -454l30 132l326 -40l139 -298l-116 -69q117 -39 240 -39t240 39l-116 69l139 298l326 40z" />
-    <glyph glyph-name="_454" unicode="&#xf1e4;" horiz-adv-x="1792" 
-d="M448 224v-192q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h192q14 0 23 -9t9 -23zM256 608v-192q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h192q14 0 23 -9t9 -23zM832 224v-192q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23
-v192q0 14 9 23t23 9h192q14 0 23 -9t9 -23zM640 608v-192q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h192q14 0 23 -9t9 -23zM66 768q-28 0 -47 19t-19 46v129h514v-129q0 -27 -19 -46t-46 -19h-383zM1216 224v-192q0 -14 -9 -23t-23 -9h-192
-q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h192q14 0 23 -9t9 -23zM1024 608v-192q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h192q14 0 23 -9t9 -23zM1600 224v-192q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h192q14 0 23 -9t9 -23
-zM1408 608v-192q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h192q14 0 23 -9t9 -23zM1792 1016v-13h-514v10q0 104 -382 102q-382 -1 -382 -102v-10h-514v13q0 17 8.5 43t34 64t65.5 75.5t110.5 76t160 67.5t224 47.5t293.5 18.5t293 -18.5t224 -47.5
-t160.5 -67.5t110.5 -76t65.5 -75.5t34 -64t8.5 -43zM1792 608v-192q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h192q14 0 23 -9t9 -23zM1792 962v-129q0 -27 -19 -46t-46 -19h-384q-27 0 -46 19t-19 46v129h514z" />
-    <glyph glyph-name="_455" unicode="&#xf1e5;" horiz-adv-x="1792" 
-d="M704 1216v-768q0 -26 -19 -45t-45 -19v-576q0 -26 -19 -45t-45 -19h-512q-26 0 -45 19t-19 45v512l249 873q7 23 31 23h424zM1024 1216v-704h-256v704h256zM1792 320v-512q0 -26 -19 -45t-45 -19h-512q-26 0 -45 19t-19 45v576q-26 0 -45 19t-19 45v768h424q24 0 31 -23z
-M736 1504v-224h-352v224q0 14 9 23t23 9h288q14 0 23 -9t9 -23zM1408 1504v-224h-352v224q0 14 9 23t23 9h288q14 0 23 -9t9 -23z" />
-    <glyph glyph-name="_456" unicode="&#xf1e6;" horiz-adv-x="1792" 
-d="M1755 1083q37 -38 37 -90.5t-37 -90.5l-401 -400l150 -150l-160 -160q-163 -163 -389.5 -186.5t-411.5 100.5l-362 -362h-181v181l362 362q-124 185 -100.5 411.5t186.5 389.5l160 160l150 -150l400 401q38 37 91 37t90 -37t37 -90.5t-37 -90.5l-400 -401l234 -234
-l401 400q38 37 91 37t90 -37z" />
-    <glyph glyph-name="_457" unicode="&#xf1e7;" horiz-adv-x="1792" 
-d="M873 796q0 -83 -63.5 -142.5t-152.5 -59.5t-152.5 59.5t-63.5 142.5q0 84 63.5 143t152.5 59t152.5 -59t63.5 -143zM1375 796q0 -83 -63 -142.5t-153 -59.5q-89 0 -152.5 59.5t-63.5 142.5q0 84 63.5 143t152.5 59q90 0 153 -59t63 -143zM1600 616v667q0 87 -32 123.5
-t-111 36.5h-1112q-83 0 -112.5 -34t-29.5 -126v-673q43 -23 88.5 -40t81 -28t81 -18.5t71 -11t70 -4t58.5 -0.5t56.5 2t44.5 2q68 1 95 -27q6 -6 10 -9q26 -25 61 -51q7 91 118 87q5 0 36.5 -1.5t43 -2t45.5 -1t53 1t54.5 4.5t61 8.5t62 13.5t67 19.5t67.5 27t72 34.5z
-M1763 621q-121 -149 -372 -252q84 -285 -23 -465q-66 -113 -183 -148q-104 -32 -182 15q-86 51 -82 164l-1 326v1q-8 2 -24.5 6t-23.5 5l-1 -338q4 -114 -83 -164q-79 -47 -183 -15q-117 36 -182 150q-105 180 -22 463q-251 103 -372 252q-25 37 -4 63t60 -1q4 -2 11.5 -7
-t10.5 -8v694q0 72 47 123t114 51h1257q67 0 114 -51t47 -123v-694l21 15q39 27 60 1t-4 -63z" />
-    <glyph glyph-name="_458" unicode="&#xf1e8;" horiz-adv-x="1792" 
-d="M896 1102v-434h-145v434h145zM1294 1102v-434h-145v434h145zM1294 342l253 254v795h-1194v-1049h326v-217l217 217h398zM1692 1536v-1013l-434 -434h-326l-217 -217h-217v217h-398v1158l109 289h1483z" />
-    <glyph glyph-name="_459" unicode="&#xf1e9;" 
-d="M773 217v-127q-1 -292 -6 -305q-12 -32 -51 -40q-54 -9 -181.5 38t-162.5 89q-13 15 -17 36q-1 12 4 26q4 10 34 47t181 216q1 0 60 70q15 19 39.5 24.5t49.5 -3.5q24 -10 37.5 -29t12.5 -42zM624 468q-3 -55 -52 -70l-120 -39q-275 -88 -292 -88q-35 2 -54 36
-q-12 25 -17 75q-8 76 1 166.5t30 124.5t56 32q13 0 202 -77q71 -29 115 -47l84 -34q23 -9 35.5 -30.5t11.5 -48.5zM1450 171q-7 -54 -91.5 -161t-135.5 -127q-37 -14 -63 7q-14 10 -184 287l-47 77q-14 21 -11.5 46t19.5 46q35 43 83 26q1 -1 119 -40q203 -66 242 -79.5
-t47 -20.5q28 -22 22 -61zM778 803q5 -102 -54 -122q-58 -17 -114 71l-378 598q-8 35 19 62q41 43 207.5 89.5t224.5 31.5q40 -10 49 -45q3 -18 22 -305.5t24 -379.5zM1440 695q3 -39 -26 -59q-15 -10 -329 -86q-67 -15 -91 -23l1 2q-23 -6 -46 4t-37 32q-30 47 0 87
-q1 1 75 102q125 171 150 204t34 39q28 19 65 2q48 -23 123 -133.5t81 -167.5v-3z" />
-    <glyph glyph-name="_460" unicode="&#xf1ea;" horiz-adv-x="2048" 
-d="M1024 1024h-384v-384h384v384zM1152 384v-128h-640v128h640zM1152 1152v-640h-640v640h640zM1792 384v-128h-512v128h512zM1792 640v-128h-512v128h512zM1792 896v-128h-512v128h512zM1792 1152v-128h-512v128h512zM256 192v960h-128v-960q0 -26 19 -45t45 -19t45 19
-t19 45zM1920 192v1088h-1536v-1088q0 -33 -11 -64h1483q26 0 45 19t19 45zM2048 1408v-1216q0 -80 -56 -136t-136 -56h-1664q-80 0 -136 56t-56 136v1088h256v128h1792z" />
-    <glyph glyph-name="_461" unicode="&#xf1eb;" horiz-adv-x="2048" 
-d="M1024 13q-20 0 -93 73.5t-73 93.5q0 32 62.5 54t103.5 22t103.5 -22t62.5 -54q0 -20 -73 -93.5t-93 -73.5zM1294 284q-2 0 -40 25t-101.5 50t-128.5 25t-128.5 -25t-101 -50t-40.5 -25q-18 0 -93.5 75t-75.5 93q0 13 10 23q78 77 196 121t233 44t233 -44t196 -121
-q10 -10 10 -23q0 -18 -75.5 -93t-93.5 -75zM1567 556q-11 0 -23 8q-136 105 -252 154.5t-268 49.5q-85 0 -170.5 -22t-149 -53t-113.5 -62t-79 -53t-31 -22q-17 0 -92 75t-75 93q0 12 10 22q132 132 320 205t380 73t380 -73t320 -205q10 -10 10 -22q0 -18 -75 -93t-92 -75z
-M1838 827q-11 0 -22 9q-179 157 -371.5 236.5t-420.5 79.5t-420.5 -79.5t-371.5 -236.5q-11 -9 -22 -9q-17 0 -92.5 75t-75.5 93q0 13 10 23q187 186 445 288t527 102t527 -102t445 -288q10 -10 10 -23q0 -18 -75.5 -93t-92.5 -75z" />
-    <glyph glyph-name="_462" unicode="&#xf1ec;" horiz-adv-x="1792" 
-d="M384 0q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM768 0q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM384 384q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5
-t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1152 0q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM768 384q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5
-t37.5 90.5zM384 768q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1152 384q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM768 768q0 53 -37.5 90.5t-90.5 37.5
-t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1536 0v384q0 52 -38 90t-90 38t-90 -38t-38 -90v-384q0 -52 38 -90t90 -38t90 38t38 90zM1152 768q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5z
-M1536 1088v256q0 26 -19 45t-45 19h-1280q-26 0 -45 -19t-19 -45v-256q0 -26 19 -45t45 -19h1280q26 0 45 19t19 45zM1536 768q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1664 1408v-1536q0 -52 -38 -90t-90 -38
-h-1408q-52 0 -90 38t-38 90v1536q0 52 38 90t90 38h1408q52 0 90 -38t38 -90z" />
-    <glyph glyph-name="_463" unicode="&#xf1ed;" 
-d="M1519 890q18 -84 -4 -204q-87 -444 -565 -444h-44q-25 0 -44 -16.5t-24 -42.5l-4 -19l-55 -346l-2 -15q-5 -26 -24.5 -42.5t-44.5 -16.5h-251q-21 0 -33 15t-9 36q9 56 26.5 168t26.5 168t27 167.5t27 167.5q5 37 43 37h131q133 -2 236 21q175 39 287 144q102 95 155 246
-q24 70 35 133q1 6 2.5 7.5t3.5 1t6 -3.5q79 -59 98 -162zM1347 1172q0 -107 -46 -236q-80 -233 -302 -315q-113 -40 -252 -42q0 -1 -90 -1l-90 1q-100 0 -118 -96q-2 -8 -85 -530q-1 -10 -12 -10h-295q-22 0 -36.5 16.5t-11.5 38.5l232 1471q5 29 27.5 48t51.5 19h598
-q34 0 97.5 -13t111.5 -32q107 -41 163.5 -123t56.5 -196z" />
-    <glyph glyph-name="_464" unicode="&#xf1ee;" horiz-adv-x="1792" 
-d="M441 864q33 0 52 -26q266 -364 362 -774h-446q-127 441 -367 749q-12 16 -3 33.5t29 17.5h373zM1000 507q-49 -199 -125 -393q-79 310 -256 594q40 221 44 449q211 -340 337 -650zM1099 1216q235 -324 384.5 -698.5t184.5 -773.5h-451q-41 665 -553 1472h435zM1792 640
-q0 -424 -101 -812q-67 560 -359 1083q-25 301 -106 584q-4 16 5.5 28.5t25.5 12.5h359q21 0 38.5 -13t22.5 -33q115 -409 115 -850z" />
-    <glyph glyph-name="uniF1F0" unicode="&#xf1f0;" horiz-adv-x="2304" 
-d="M1975 546h-138q14 37 66 179l3 9q4 10 10 26t9 26l12 -55zM531 611l-58 295q-11 54 -75 54h-268l-2 -13q311 -79 403 -336zM710 960l-162 -438l-17 89q-26 70 -85 129.5t-131 88.5l135 -510h175l261 641h-176zM849 318h166l104 642h-166zM1617 944q-69 27 -149 27
-q-123 0 -201 -59t-79 -153q-1 -102 145 -174q48 -23 67 -41t19 -39q0 -30 -30 -46t-69 -16q-86 0 -156 33l-22 11l-23 -144q74 -34 185 -34q130 -1 208.5 59t80.5 160q0 106 -140 174q-49 25 -71 42t-22 38q0 22 24.5 38.5t70.5 16.5q70 1 124 -24l15 -8zM2042 960h-128
-q-65 0 -87 -54l-246 -588h174l35 96h212q5 -22 20 -96h154zM2304 1280v-1280q0 -52 -38 -90t-90 -38h-2048q-52 0 -90 38t-38 90v1280q0 52 38 90t90 38h2048q52 0 90 -38t38 -90z" />
-    <glyph glyph-name="_466" unicode="&#xf1f1;" horiz-adv-x="2304" 
-d="M1119 1195q-128 85 -281 85q-103 0 -197.5 -40.5t-162.5 -108.5t-108.5 -162t-40.5 -197q0 -104 40.5 -198t108.5 -162t162 -108.5t198 -40.5q153 0 281 85q-131 107 -178 265.5t0.5 316.5t177.5 265zM1152 1171q-126 -99 -172 -249.5t-0.5 -300.5t172.5 -249
-q127 99 172.5 249t-0.5 300.5t-172 249.5zM1185 1195q130 -107 177.5 -265.5t0.5 -317t-178 -264.5q128 -85 281 -85q104 0 198 40.5t162 108.5t108.5 162t40.5 198q0 103 -40.5 197t-108.5 162t-162.5 108.5t-197.5 40.5q-153 0 -281 -85zM1926 473h7v3h-17v-3h7v-17h3v17z
-M1955 456h4v20h-5l-6 -13l-6 13h-5v-20h3v15l6 -13h4l5 13v-15zM1947 16v-2h-2h-3v3h3h2v-1zM1947 7h3l-4 5h2l1 1q1 1 1 3t-1 3l-1 1h-3h-6v-13h3v5h1zM685 75q0 19 11 31t30 12q18 0 29 -12.5t11 -30.5q0 -19 -11 -31t-29 -12q-19 0 -30 12t-11 31zM1158 119q30 0 35 -32
-h-70q5 32 35 32zM1514 75q0 19 11 31t29 12t29.5 -12.5t11.5 -30.5q0 -19 -11 -31t-30 -12q-18 0 -29 12t-11 31zM1786 75q0 18 11.5 30.5t29.5 12.5t29.5 -12.5t11.5 -30.5q0 -19 -11.5 -31t-29.5 -12t-29.5 12.5t-11.5 30.5zM1944 3q-2 0 -4 1q-1 0 -3 2t-2 3q-1 2 -1 4
-q0 3 1 4q0 2 2 4l1 1q2 0 2 1q2 1 4 1q3 0 4 -1l4 -2l2 -4v-1q1 -2 1 -3l-1 -1v-3t-1 -1l-1 -2q-2 -2 -4 -2q-1 -1 -4 -1zM599 7h30v85q0 24 -14.5 38.5t-39.5 15.5q-32 0 -47 -24q-14 24 -45 24q-24 0 -39 -20v16h-30v-135h30v75q0 36 33 36q30 0 30 -36v-75h29v75
-q0 36 33 36q30 0 30 -36v-75zM765 7h29v68v67h-29v-16q-17 20 -43 20q-29 0 -48 -20t-19 -51t19 -51t48 -20q28 0 43 20v-17zM943 48q0 34 -47 40l-14 2q-23 4 -23 14q0 15 25 15q23 0 43 -11l12 24q-22 14 -55 14q-26 0 -41 -12t-15 -32q0 -33 47 -39l13 -2q24 -4 24 -14
-q0 -17 -31 -17q-25 0 -45 14l-13 -23q25 -17 58 -17q29 0 45.5 12t16.5 32zM1073 14l-8 25q-13 -7 -26 -7q-19 0 -19 22v61h48v27h-48v41h-30v-41h-28v-27h28v-61q0 -50 47 -50q21 0 36 10zM1159 146q-29 0 -48 -20t-19 -51q0 -32 19.5 -51.5t49.5 -19.5q33 0 55 19l-14 22
-q-18 -15 -39 -15q-34 0 -41 33h101v12q0 32 -18 51.5t-46 19.5zM1318 146q-23 0 -35 -20v16h-30v-135h30v76q0 35 29 35q10 0 18 -4l9 28q-9 4 -21 4zM1348 75q0 -31 19.5 -51t52.5 -20q29 0 48 16l-14 24q-18 -13 -35 -12q-18 0 -29.5 12t-11.5 31t11.5 31t29.5 12
-q19 0 35 -12l14 24q-20 16 -48 16q-33 0 -52.5 -20t-19.5 -51zM1593 7h30v68v67h-30v-16q-15 20 -42 20q-29 0 -48.5 -20t-19.5 -51t19.5 -51t48.5 -20q28 0 42 20v-17zM1726 146q-23 0 -35 -20v16h-29v-135h29v76q0 35 29 35q10 0 18 -4l9 28q-8 4 -21 4zM1866 7h29v68v122
-h-29v-71q-15 20 -43 20t-47.5 -20.5t-19.5 -50.5t19.5 -50.5t47.5 -20.5q29 0 43 20v-17zM1944 27l-2 -1h-3q-2 -1 -4 -3q-3 -1 -3 -4q-1 -2 -1 -6q0 -3 1 -5q0 -2 3 -4q2 -2 4 -3t5 -1q4 0 6 1q0 1 2 2l2 1q1 1 3 4q1 2 1 5q0 4 -1 6q-1 1 -3 4q0 1 -2 2l-2 1q-1 0 -3 0.5
-t-3 0.5zM2304 1280v-1280q0 -52 -38 -90t-90 -38h-2048q-52 0 -90 38t-38 90v1280q0 52 38 90t90 38h2048q52 0 90 -38t38 -90z" />
-    <glyph glyph-name="_467" unicode="&#xf1f2;" horiz-adv-x="2304" 
-d="M313 759q0 -51 -36 -84q-29 -26 -89 -26h-17v220h17q61 0 89 -27q36 -31 36 -83zM2089 824q0 -52 -64 -52h-19v101h20q63 0 63 -49zM380 759q0 74 -50 120.5t-129 46.5h-95v-333h95q74 0 119 38q60 51 60 128zM410 593h65v333h-65v-333zM730 694q0 40 -20.5 62t-75.5 42
-q-29 10 -39.5 19t-10.5 23q0 16 13.5 26.5t34.5 10.5q29 0 53 -27l34 44q-41 37 -98 37q-44 0 -74 -27.5t-30 -67.5q0 -35 18 -55.5t64 -36.5q37 -13 45 -19q19 -12 19 -34q0 -20 -14 -33.5t-36 -13.5q-48 0 -71 44l-42 -40q44 -64 115 -64q51 0 83 30.5t32 79.5zM1008 604
-v77q-37 -37 -78 -37q-49 0 -80.5 32.5t-31.5 82.5q0 48 31.5 81.5t77.5 33.5q43 0 81 -38v77q-40 20 -80 20q-74 0 -125.5 -50.5t-51.5 -123.5t51 -123.5t125 -50.5q42 0 81 19zM2240 0v527q-65 -40 -144.5 -84t-237.5 -117t-329.5 -137.5t-417.5 -134.5t-504 -118h1569
-q26 0 45 19t19 45zM1389 757q0 75 -53 128t-128 53t-128 -53t-53 -128t53 -128t128 -53t128 53t53 128zM1541 584l144 342h-71l-90 -224l-89 224h-71l142 -342h35zM1714 593h184v56h-119v90h115v56h-115v74h119v57h-184v-333zM2105 593h80l-105 140q76 16 76 94q0 47 -31 73
-t-87 26h-97v-333h65v133h9zM2304 1274v-1268q0 -56 -38.5 -95t-93.5 -39h-2040q-55 0 -93.5 39t-38.5 95v1268q0 56 38.5 95t93.5 39h2040q55 0 93.5 -39t38.5 -95z" />
-    <glyph glyph-name="f1f3" unicode="&#xf1f3;" horiz-adv-x="2304" 
-d="M119 854h89l-45 108zM740 328l74 79l-70 79h-163v-49h142v-55h-142v-54h159zM898 406l99 -110v217zM1186 453q0 33 -40 33h-84v-69h83q41 0 41 36zM1475 457q0 29 -42 29h-82v-61h81q43 0 43 32zM1197 923q0 29 -42 29h-82v-60h81q43 0 43 31zM1656 854h89l-44 108z
-M699 1009v-271h-66v212l-94 -212h-57l-94 212v-212h-132l-25 60h-135l-25 -60h-70l116 271h96l110 -257v257h106l85 -184l77 184h108zM1255 453q0 -20 -5.5 -35t-14 -25t-22.5 -16.5t-26 -10t-31.5 -4.5t-31.5 -1t-32.5 0.5t-29.5 0.5v-91h-126l-80 90l-83 -90h-256v271h260
-l80 -89l82 89h207q109 0 109 -89zM964 794v-56h-217v271h217v-57h-152v-49h148v-55h-148v-54h152zM2304 235v-229q0 -55 -38.5 -94.5t-93.5 -39.5h-2040q-55 0 -93.5 39.5t-38.5 94.5v678h111l25 61h55l25 -61h218v46l19 -46h113l20 47v-47h541v99l10 1q10 0 10 -14v-86h279
-v23q23 -12 55 -18t52.5 -6.5t63 0.5t51.5 1l25 61h56l25 -61h227v58l34 -58h182v378h-180v-44l-25 44h-185v-44l-23 44h-249q-69 0 -109 -22v22h-172v-22q-24 22 -73 22h-628l-43 -97l-43 97h-198v-44l-22 44h-169l-78 -179v391q0 55 38.5 94.5t93.5 39.5h2040
-q55 0 93.5 -39.5t38.5 -94.5v-678h-120q-51 0 -81 -22v22h-177q-55 0 -78 -22v22h-316v-22q-31 22 -87 22h-209v-22q-23 22 -91 22h-234l-54 -58l-50 58h-349v-378h343l55 59l52 -59h211v89h21q59 0 90 13v-102h174v99h8q8 0 10 -2t2 -10v-87h529q57 0 88 24v-24h168
-q60 0 95 17zM1546 469q0 -23 -12 -43t-34 -29q25 -9 34 -26t9 -46v-54h-65v45q0 33 -12 43.5t-46 10.5h-69v-99h-65v271h154q48 0 77 -15t29 -58zM1269 936q0 -24 -12.5 -44t-33.5 -29q26 -9 34.5 -25.5t8.5 -46.5v-53h-65q0 9 0.5 26.5t0 25t-3 18.5t-8.5 16t-17.5 8.5
-t-29.5 3.5h-70v-98h-64v271l153 -1q49 0 78 -14.5t29 -57.5zM1798 327v-56h-216v271h216v-56h-151v-49h148v-55h-148v-54zM1372 1009v-271h-66v271h66zM2065 357q0 -86 -102 -86h-126v58h126q34 0 34 25q0 16 -17 21t-41.5 5t-49.5 3.5t-42 22.5t-17 55q0 39 26 60t66 21
-h130v-57h-119q-36 0 -36 -25q0 -16 17.5 -20.5t42 -4t49 -2.5t42 -21.5t17.5 -54.5zM2304 407v-101q-24 -35 -88 -35h-125v58h125q33 0 33 25q0 13 -12.5 19t-31 5.5t-40 2t-40 8t-31 24t-12.5 48.5q0 39 26.5 60t66.5 21h129v-57h-118q-36 0 -36 -25q0 -20 29 -22t68.5 -5
-t56.5 -26zM2139 1008v-270h-92l-122 203v-203h-132l-26 60h-134l-25 -60h-75q-129 0 -129 133q0 138 133 138h63v-59q-7 0 -28 1t-28.5 0.5t-23 -2t-21.5 -6.5t-14.5 -13.5t-11.5 -23t-3 -33.5q0 -38 13.5 -58t49.5 -20h29l92 213h97l109 -256v256h99l114 -188v188h66z" />
-    <glyph glyph-name="_469" unicode="&#xf1f4;" horiz-adv-x="2304" 
-d="M745 630q0 -37 -25.5 -61.5t-62.5 -24.5q-29 0 -46.5 16t-17.5 44q0 37 25 62.5t62 25.5q28 0 46.5 -16.5t18.5 -45.5zM1530 779q0 -42 -22 -57t-66 -15l-32 -1l17 107q2 11 13 11h18q22 0 35 -2t25 -12.5t12 -30.5zM1881 630q0 -36 -25.5 -61t-61.5 -25q-29 0 -47 16
-t-18 44q0 37 25 62.5t62 25.5q28 0 46.5 -16.5t18.5 -45.5zM513 801q0 59 -38.5 85.5t-100.5 26.5h-160q-19 0 -21 -19l-65 -408q-1 -6 3 -11t10 -5h76q20 0 22 19l18 110q1 8 7 13t15 6.5t17 1.5t19 -1t14 -1q86 0 135 48.5t49 134.5zM822 489l41 261q1 6 -3 11t-10 5h-76
-q-14 0 -17 -33q-27 40 -95 40q-72 0 -122.5 -54t-50.5 -127q0 -59 34.5 -94t92.5 -35q28 0 58 12t48 32q-4 -12 -4 -21q0 -16 13 -16h69q19 0 22 19zM1269 752q0 5 -4 9.5t-9 4.5h-77q-11 0 -18 -10l-106 -156l-44 150q-5 16 -22 16h-75q-5 0 -9 -4.5t-4 -9.5q0 -2 19.5 -59
-t42 -123t23.5 -70q-82 -112 -82 -120q0 -13 13 -13h77q11 0 18 10l255 368q2 2 2 7zM1649 801q0 59 -38.5 85.5t-100.5 26.5h-159q-20 0 -22 -19l-65 -408q-1 -6 3 -11t10 -5h82q12 0 16 13l18 116q1 8 7 13t15 6.5t17 1.5t19 -1t14 -1q86 0 135 48.5t49 134.5zM1958 489
-l41 261q1 6 -3 11t-10 5h-76q-14 0 -17 -33q-26 40 -95 40q-72 0 -122.5 -54t-50.5 -127q0 -59 34.5 -94t92.5 -35q29 0 59 12t47 32q0 -1 -2 -9t-2 -12q0 -16 13 -16h69q19 0 22 19zM2176 898v1q0 14 -13 14h-74q-11 0 -13 -11l-65 -416l-1 -2q0 -5 4 -9.5t10 -4.5h66
-q19 0 21 19zM392 764q-5 -35 -26 -46t-60 -11l-33 -1l17 107q2 11 13 11h19q40 0 58 -11.5t12 -48.5zM2304 1280v-1280q0 -52 -38 -90t-90 -38h-2048q-52 0 -90 38t-38 90v1280q0 52 38 90t90 38h2048q52 0 90 -38t38 -90z" />
-    <glyph glyph-name="_470" unicode="&#xf1f5;" horiz-adv-x="2304" 
-d="M1597 633q0 -69 -21 -106q-19 -35 -52 -35q-23 0 -41 9v224q29 30 57 30q57 0 57 -122zM2035 669h-110q6 98 56 98q51 0 54 -98zM476 534q0 59 -33 91.5t-101 57.5q-36 13 -52 24t-16 25q0 26 38 26q58 0 124 -33l18 112q-67 32 -149 32q-77 0 -123 -38q-48 -39 -48 -109
-q0 -58 32.5 -90.5t99.5 -56.5q39 -14 54.5 -25.5t15.5 -27.5q0 -31 -48 -31q-29 0 -70 12.5t-72 30.5l-18 -113q72 -41 168 -41q81 0 129 37q51 41 51 117zM771 749l19 111h-96v135l-129 -21l-18 -114l-46 -8l-17 -103h62v-219q0 -84 44 -120q38 -30 111 -30q32 0 79 11v118
-q-32 -7 -44 -7q-42 0 -42 50v197h77zM1087 724v139q-15 3 -28 3q-32 0 -55.5 -16t-33.5 -46l-10 56h-131v-471h150v306q26 31 82 31q16 0 26 -2zM1124 389h150v471h-150v-471zM1746 638q0 122 -45 179q-40 52 -111 52q-64 0 -117 -56l-8 47h-132v-645l150 25v151
-q36 -11 68 -11q83 0 134 56q61 65 61 202zM1278 986q0 33 -23 56t-56 23t-56 -23t-23 -56t23 -56.5t56 -23.5t56 23.5t23 56.5zM2176 629q0 113 -48 176q-50 64 -144 64q-96 0 -151.5 -66t-55.5 -180q0 -128 63 -188q55 -55 161 -55q101 0 160 40l-16 103q-57 -31 -128 -31
-q-43 0 -63 19q-23 19 -28 66h248q2 14 2 52zM2304 1280v-1280q0 -52 -38 -90t-90 -38h-2048q-52 0 -90 38t-38 90v1280q0 52 38 90t90 38h2048q52 0 90 -38t38 -90z" />
-    <glyph glyph-name="_471" unicode="&#xf1f6;" horiz-adv-x="2048" 
-d="M1558 684q61 -356 298 -556q0 -52 -38 -90t-90 -38h-448q0 -106 -75 -181t-181 -75t-180.5 74.5t-75.5 180.5zM1024 -176q16 0 16 16t-16 16q-59 0 -101.5 42.5t-42.5 101.5q0 16 -16 16t-16 -16q0 -73 51.5 -124.5t124.5 -51.5zM2026 1424q8 -10 7.5 -23.5t-10.5 -22.5
-l-1872 -1622q-10 -8 -23.5 -7t-21.5 11l-84 96q-8 10 -7.5 23.5t10.5 21.5l186 161q-19 32 -19 66q50 42 91 88t85 119.5t74.5 158.5t50 206t19.5 260q0 152 117 282.5t307 158.5q-8 19 -8 39q0 40 28 68t68 28t68 -28t28 -68q0 -20 -8 -39q124 -18 219 -82.5t148 -157.5
-l418 363q10 8 23.5 7t21.5 -11z" />
-    <glyph glyph-name="_472" unicode="&#xf1f7;" horiz-adv-x="2048" 
-d="M1040 -160q0 16 -16 16q-59 0 -101.5 42.5t-42.5 101.5q0 16 -16 16t-16 -16q0 -73 51.5 -124.5t124.5 -51.5q16 0 16 16zM503 315l877 760q-42 88 -132.5 146.5t-223.5 58.5q-93 0 -169.5 -31.5t-121.5 -80.5t-69 -103t-24 -105q0 -384 -137 -645zM1856 128
-q0 -52 -38 -90t-90 -38h-448q0 -106 -75 -181t-181 -75t-180.5 74.5t-75.5 180.5l149 129h757q-166 187 -227 459l111 97q61 -356 298 -556zM1942 1520l84 -96q8 -10 7.5 -23.5t-10.5 -22.5l-1872 -1622q-10 -8 -23.5 -7t-21.5 11l-84 96q-8 10 -7.5 23.5t10.5 21.5l186 161
-q-19 32 -19 66q50 42 91 88t85 119.5t74.5 158.5t50 206t19.5 260q0 152 117 282.5t307 158.5q-8 19 -8 39q0 40 28 68t68 28t68 -28t28 -68q0 -20 -8 -39q124 -18 219 -82.5t148 -157.5l418 363q10 8 23.5 7t21.5 -11z" />
-    <glyph glyph-name="_473" unicode="&#xf1f8;" horiz-adv-x="1408" 
-d="M512 160v704q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-704q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM768 160v704q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-704q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM1024 160v704q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-704
-q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM480 1152h448l-48 117q-7 9 -17 11h-317q-10 -2 -17 -11zM1408 1120v-64q0 -14 -9 -23t-23 -9h-96v-948q0 -83 -47 -143.5t-113 -60.5h-832q-66 0 -113 58.5t-47 141.5v952h-96q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h309l70 167
-q15 37 54 63t79 26h320q40 0 79 -26t54 -63l70 -167h309q14 0 23 -9t9 -23z" />
-    <glyph glyph-name="_474" unicode="&#xf1f9;" 
-d="M1150 462v-109q0 -50 -36.5 -89t-94 -60.5t-118 -32.5t-117.5 -11q-205 0 -342.5 139t-137.5 346q0 203 136 339t339 136q34 0 75.5 -4.5t93 -18t92.5 -34t69 -56.5t28 -81v-109q0 -16 -16 -16h-118q-16 0 -16 16v70q0 43 -65.5 67.5t-137.5 24.5q-140 0 -228.5 -91.5
-t-88.5 -237.5q0 -151 91.5 -249.5t233.5 -98.5q68 0 138 24t70 66v70q0 7 4.5 11.5t10.5 4.5h119q6 0 11 -4.5t5 -11.5zM768 1280q-130 0 -248.5 -51t-204 -136.5t-136.5 -204t-51 -248.5t51 -248.5t136.5 -204t204 -136.5t248.5 -51t248.5 51t204 136.5t136.5 204t51 248.5
-t-51 248.5t-136.5 204t-204 136.5t-248.5 51zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
-    <glyph glyph-name="_475" unicode="&#xf1fa;" 
-d="M972 761q0 108 -53.5 169t-147.5 61q-63 0 -124 -30.5t-110 -84.5t-79.5 -137t-30.5 -180q0 -112 53.5 -173t150.5 -61q96 0 176 66.5t122.5 166t42.5 203.5zM1536 640q0 -111 -37 -197t-98.5 -135t-131.5 -74.5t-145 -27.5q-6 0 -15.5 -0.5t-16.5 -0.5q-95 0 -142 53
-q-28 33 -33 83q-52 -66 -131.5 -110t-173.5 -44q-161 0 -249.5 95.5t-88.5 269.5q0 157 66 290t179 210.5t246 77.5q87 0 155 -35.5t106 -99.5l2 19l11 56q1 6 5.5 12t9.5 6h118q5 0 13 -11q5 -5 3 -16l-120 -614q-5 -24 -5 -48q0 -39 12.5 -52t44.5 -13q28 1 57 5.5t73 24
-t77 50t57 89.5t24 137q0 292 -174 466t-466 174q-130 0 -248.5 -51t-204 -136.5t-136.5 -204t-51 -248.5t51 -248.5t136.5 -204t204 -136.5t248.5 -51q228 0 405 144q11 9 24 8t21 -12l41 -49q8 -12 7 -24q-2 -13 -12 -22q-102 -83 -227.5 -128t-258.5 -45q-156 0 -298 61
-t-245 164t-164 245t-61 298t61 298t164 245t245 164t298 61q344 0 556 -212t212 -556z" />
-    <glyph glyph-name="_476" unicode="&#xf1fb;" horiz-adv-x="1792" 
-d="M1698 1442q94 -94 94 -226.5t-94 -225.5l-225 -223l104 -104q10 -10 10 -23t-10 -23l-210 -210q-10 -10 -23 -10t-23 10l-105 105l-603 -603q-37 -37 -90 -37h-203l-256 -128l-64 64l128 256v203q0 53 37 90l603 603l-105 105q-10 10 -10 23t10 23l210 210q10 10 23 10
-t23 -10l104 -104l223 225q93 94 225.5 94t226.5 -94zM512 64l576 576l-192 192l-576 -576v-192h192z" />
-    <glyph glyph-name="f1fc" unicode="&#xf1fc;" horiz-adv-x="1792" 
-d="M1615 1536q70 0 122.5 -46.5t52.5 -116.5q0 -63 -45 -151q-332 -629 -465 -752q-97 -91 -218 -91q-126 0 -216.5 92.5t-90.5 219.5q0 128 92 212l638 579q59 54 130 54zM706 502q39 -76 106.5 -130t150.5 -76l1 -71q4 -213 -129.5 -347t-348.5 -134q-123 0 -218 46.5
-t-152.5 127.5t-86.5 183t-29 220q7 -5 41 -30t62 -44.5t59 -36.5t46 -17q41 0 55 37q25 66 57.5 112.5t69.5 76t88 47.5t103 25.5t125 10.5z" />
-    <glyph glyph-name="_478" unicode="&#xf1fd;" horiz-adv-x="1792" 
-d="M1792 128v-384h-1792v384q45 0 85 14t59 27.5t47 37.5q30 27 51.5 38t56.5 11q24 0 44 -7t31 -15t33 -27q29 -25 47 -38t58 -27t86 -14q45 0 85 14.5t58 27t48 37.5q21 19 32.5 27t31 15t43.5 7q35 0 56.5 -11t51.5 -38q28 -24 47 -37.5t59 -27.5t85 -14t85 14t59 27.5
-t47 37.5q30 27 51.5 38t56.5 11q34 0 55.5 -11t51.5 -38q28 -24 47 -37.5t59 -27.5t85 -14zM1792 448v-192q-24 0 -44 7t-31 15t-33 27q-29 25 -47 38t-58 27t-85 14q-46 0 -86 -14t-58 -27t-47 -38q-22 -19 -33 -27t-31 -15t-44 -7q-35 0 -56.5 11t-51.5 38q-29 25 -47 38
-t-58 27t-86 14q-45 0 -85 -14.5t-58 -27t-48 -37.5q-21 -19 -32.5 -27t-31 -15t-43.5 -7q-35 0 -56.5 11t-51.5 38q-28 24 -47 37.5t-59 27.5t-85 14q-46 0 -86 -14t-58 -27t-47 -38q-30 -27 -51.5 -38t-56.5 -11v192q0 80 56 136t136 56h64v448h256v-448h256v448h256v-448
-h256v448h256v-448h64q80 0 136 -56t56 -136zM512 1312q0 -77 -36 -118.5t-92 -41.5q-53 0 -90.5 37.5t-37.5 90.5q0 29 9.5 51t23.5 34t31 28t31 31.5t23.5 44.5t9.5 67q38 0 83 -74t45 -150zM1024 1312q0 -77 -36 -118.5t-92 -41.5q-53 0 -90.5 37.5t-37.5 90.5
-q0 29 9.5 51t23.5 34t31 28t31 31.5t23.5 44.5t9.5 67q38 0 83 -74t45 -150zM1536 1312q0 -77 -36 -118.5t-92 -41.5q-53 0 -90.5 37.5t-37.5 90.5q0 29 9.5 51t23.5 34t31 28t31 31.5t23.5 44.5t9.5 67q38 0 83 -74t45 -150z" />
-    <glyph glyph-name="_479" unicode="&#xf1fe;" horiz-adv-x="2048" 
-d="M2048 0v-128h-2048v1536h128v-1408h1920zM1664 1024l256 -896h-1664v576l448 576l576 -576z" />
-    <glyph glyph-name="_480" unicode="&#xf200;" horiz-adv-x="1792" 
-d="M768 646l546 -546q-106 -108 -247.5 -168t-298.5 -60q-209 0 -385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103v-762zM955 640h773q0 -157 -60 -298.5t-168 -247.5zM1664 768h-768v768q209 0 385.5 -103t279.5 -279.5t103 -385.5z" />
-    <glyph glyph-name="_481" unicode="&#xf201;" horiz-adv-x="2048" 
-d="M2048 0v-128h-2048v1536h128v-1408h1920zM1920 1248v-435q0 -21 -19.5 -29.5t-35.5 7.5l-121 121l-633 -633q-10 -10 -23 -10t-23 10l-233 233l-416 -416l-192 192l585 585q10 10 23 10t23 -10l233 -233l464 464l-121 121q-16 16 -7.5 35.5t29.5 19.5h435q14 0 23 -9
-t9 -23z" />
-    <glyph glyph-name="_482" unicode="&#xf202;" horiz-adv-x="1792" 
-d="M1292 832q0 -6 10 -41q10 -29 25 -49.5t41 -34t44 -20t55 -16.5q325 -91 325 -332q0 -146 -105.5 -242.5t-254.5 -96.5q-59 0 -111.5 18.5t-91.5 45.5t-77 74.5t-63 87.5t-53.5 103.5t-43.5 103t-39.5 106.5t-35.5 95q-32 81 -61.5 133.5t-73.5 96.5t-104 64t-142 20
-q-96 0 -183 -55.5t-138 -144.5t-51 -185q0 -160 106.5 -279.5t263.5 -119.5q177 0 258 95q56 63 83 116l84 -152q-15 -34 -44 -70l1 -1q-131 -152 -388 -152q-147 0 -269.5 79t-190.5 207.5t-68 274.5q0 105 43.5 206t116 176.5t172 121.5t204.5 46q87 0 159 -19t123.5 -50
-t95 -80t72.5 -99t58.5 -117t50.5 -124.5t50 -130.5t55 -127q96 -200 233 -200q81 0 138.5 48.5t57.5 128.5q0 42 -19 72t-50.5 46t-72.5 31.5t-84.5 27t-87.5 34t-81 52t-65 82t-39 122.5q-3 16 -3 33q0 110 87.5 192t198.5 78q78 -3 120.5 -14.5t90.5 -53.5h-1
-q12 -11 23 -24.5t26 -36t19 -27.5l-129 -99q-26 49 -54 70v1q-23 21 -97 21q-49 0 -84 -33t-35 -83z" />
-    <glyph glyph-name="_483" unicode="&#xf203;" 
-d="M1432 484q0 173 -234 239q-35 10 -53 16.5t-38 25t-29 46.5q0 2 -2 8.5t-3 12t-1 7.5q0 36 24.5 59.5t60.5 23.5q54 0 71 -15h-1q20 -15 39 -51l93 71q-39 54 -49 64q-33 29 -67.5 39t-85.5 10q-80 0 -142 -57.5t-62 -137.5q0 -7 2 -23q16 -96 64.5 -140t148.5 -73
-q29 -8 49 -15.5t45 -21.5t38.5 -34.5t13.5 -46.5v-5q1 -58 -40.5 -93t-100.5 -35q-97 0 -167 144q-23 47 -51.5 121.5t-48 125.5t-54 110.5t-74 95.5t-103.5 60.5t-147 24.5q-101 0 -192 -56t-144 -148t-50 -192v-1q4 -108 50.5 -199t133.5 -147.5t196 -56.5q186 0 279 110
-q20 27 31 51l-60 109q-42 -80 -99 -116t-146 -36q-115 0 -191 87t-76 204q0 105 82 189t186 84q112 0 170 -53.5t104 -172.5q8 -21 25.5 -68.5t28.5 -76.5t31.5 -74.5t38.5 -74t45.5 -62.5t55.5 -53.5t66 -33t80 -13.5q107 0 183 69.5t76 174.5zM1536 1120v-960
-q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
-    <glyph glyph-name="_484" unicode="&#xf204;" horiz-adv-x="2048" 
-d="M1152 640q0 104 -40.5 198.5t-109.5 163.5t-163.5 109.5t-198.5 40.5t-198.5 -40.5t-163.5 -109.5t-109.5 -163.5t-40.5 -198.5t40.5 -198.5t109.5 -163.5t163.5 -109.5t198.5 -40.5t198.5 40.5t163.5 109.5t109.5 163.5t40.5 198.5zM1920 640q0 104 -40.5 198.5
-t-109.5 163.5t-163.5 109.5t-198.5 40.5h-386q119 -90 188.5 -224t69.5 -288t-69.5 -288t-188.5 -224h386q104 0 198.5 40.5t163.5 109.5t109.5 163.5t40.5 198.5zM2048 640q0 -130 -51 -248.5t-136.5 -204t-204 -136.5t-248.5 -51h-768q-130 0 -248.5 51t-204 136.5
-t-136.5 204t-51 248.5t51 248.5t136.5 204t204 136.5t248.5 51h768q130 0 248.5 -51t204 -136.5t136.5 -204t51 -248.5z" />
-    <glyph glyph-name="_485" unicode="&#xf205;" horiz-adv-x="2048" 
-d="M0 640q0 130 51 248.5t136.5 204t204 136.5t248.5 51h768q130 0 248.5 -51t204 -136.5t136.5 -204t51 -248.5t-51 -248.5t-136.5 -204t-204 -136.5t-248.5 -51h-768q-130 0 -248.5 51t-204 136.5t-136.5 204t-51 248.5zM1408 128q104 0 198.5 40.5t163.5 109.5
-t109.5 163.5t40.5 198.5t-40.5 198.5t-109.5 163.5t-163.5 109.5t-198.5 40.5t-198.5 -40.5t-163.5 -109.5t-109.5 -163.5t-40.5 -198.5t40.5 -198.5t109.5 -163.5t163.5 -109.5t198.5 -40.5z" />
-    <glyph glyph-name="_486" unicode="&#xf206;" horiz-adv-x="2304" 
-d="M762 384h-314q-40 0 -57.5 35t6.5 67l188 251q-65 31 -137 31q-132 0 -226 -94t-94 -226t94 -226t226 -94q115 0 203 72.5t111 183.5zM576 512h186q-18 85 -75 148zM1056 512l288 384h-480l-99 -132q105 -103 126 -252h165zM2176 448q0 132 -94 226t-226 94
-q-60 0 -121 -24l174 -260q15 -23 10 -49t-27 -40q-15 -11 -36 -11q-35 0 -53 29l-174 260q-93 -95 -93 -225q0 -132 94 -226t226 -94t226 94t94 226zM2304 448q0 -185 -131.5 -316.5t-316.5 -131.5t-316.5 131.5t-131.5 316.5q0 97 39.5 183.5t109.5 149.5l-65 98l-353 -469
-q-18 -26 -51 -26h-197q-23 -164 -149 -274t-294 -110q-185 0 -316.5 131.5t-131.5 316.5t131.5 316.5t316.5 131.5q114 0 215 -55l137 183h-224q-26 0 -45 19t-19 45t19 45t45 19h384v-128h435l-85 128h-222q-26 0 -45 19t-19 45t19 45t45 19h256q33 0 53 -28l267 -400
-q91 44 192 44q185 0 316.5 -131.5t131.5 -316.5z" />
-    <glyph glyph-name="_487" unicode="&#xf207;" 
-d="M384 320q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1408 320q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1362 716l-72 384q-5 23 -22.5 37.5t-40.5 14.5
-h-918q-23 0 -40.5 -14.5t-22.5 -37.5l-72 -384q-5 -30 14 -53t49 -23h1062q30 0 49 23t14 53zM1136 1328q0 20 -14 34t-34 14h-640q-20 0 -34 -14t-14 -34t14 -34t34 -14h640q20 0 34 14t14 34zM1536 603v-603h-128v-128q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5
-t-37.5 90.5v128h-768v-128q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5v128h-128v603q0 112 25 223l103 454q9 78 97.5 137t230 89t312.5 30t312.5 -30t230 -89t97.5 -137l105 -454q23 -102 23 -223z" />
-    <glyph glyph-name="_488" unicode="&#xf208;" horiz-adv-x="2048" 
-d="M1463 704q0 -35 -25 -60.5t-61 -25.5h-702q-36 0 -61 25.5t-25 60.5t25 60.5t61 25.5h702q36 0 61 -25.5t25 -60.5zM1677 704q0 86 -23 170h-982q-36 0 -61 25t-25 60q0 36 25 61t61 25h908q-88 143 -235 227t-320 84q-177 0 -327.5 -87.5t-238 -237.5t-87.5 -327
-q0 -86 23 -170h982q36 0 61 -25t25 -60q0 -36 -25 -61t-61 -25h-908q88 -143 235.5 -227t320.5 -84q132 0 253 51.5t208 139t139 208t52 253.5zM2048 959q0 -35 -25 -60t-61 -25h-131q17 -85 17 -170q0 -167 -65.5 -319.5t-175.5 -263t-262.5 -176t-319.5 -65.5
-q-246 0 -448.5 133t-301.5 350h-189q-36 0 -61 25t-25 61q0 35 25 60t61 25h132q-17 85 -17 170q0 167 65.5 319.5t175.5 263t262.5 176t320.5 65.5q245 0 447.5 -133t301.5 -350h188q36 0 61 -25t25 -61z" />
-    <glyph glyph-name="_489" unicode="&#xf209;" horiz-adv-x="1280" 
-d="M953 1158l-114 -328l117 -21q165 451 165 518q0 56 -38 56q-57 0 -130 -225zM654 471l33 -88q37 42 71 67l-33 5.5t-38.5 7t-32.5 8.5zM362 1367q0 -98 159 -521q17 10 49 10q15 0 75 -5l-121 351q-75 220 -123 220q-19 0 -29 -17.5t-10 -37.5zM283 608q0 -36 51.5 -119
-t117.5 -153t100 -70q14 0 25.5 13t11.5 27q0 24 -32 102q-13 32 -32 72t-47.5 89t-61.5 81t-62 32q-20 0 -45.5 -27t-25.5 -47zM125 273q0 -41 25 -104q59 -145 183.5 -227t281.5 -82q227 0 382 170q152 169 152 427q0 43 -1 67t-11.5 62t-30.5 56q-56 49 -211.5 75.5
-t-270.5 26.5q-37 0 -49 -11q-12 -5 -12 -35q0 -34 21.5 -60t55.5 -40t77.5 -23.5t87.5 -11.5t85 -4t70 0h23q24 0 40 -19q15 -19 19 -55q-28 -28 -96 -54q-61 -22 -93 -46q-64 -46 -108.5 -114t-44.5 -137q0 -31 18.5 -88.5t18.5 -87.5l-3 -12q-4 -12 -4 -14
-q-137 10 -146 216q-8 -2 -41 -2q2 -7 2 -21q0 -53 -40.5 -89.5t-94.5 -36.5q-82 0 -166.5 78t-84.5 159q0 34 33 67q52 -64 60 -76q77 -104 133 -104q12 0 26.5 8.5t14.5 20.5q0 34 -87.5 145t-116.5 111q-43 0 -70 -44.5t-27 -90.5zM11 264q0 101 42.5 163t136.5 88
-q-28 74 -28 104q0 62 61 123t122 61q29 0 70 -15q-163 462 -163 567q0 80 41 130.5t119 50.5q131 0 325 -581q6 -17 8 -23q6 16 29 79.5t43.5 118.5t54 127.5t64.5 123t70.5 86.5t76.5 36q71 0 112 -49t41 -122q0 -108 -159 -550q61 -15 100.5 -46t58.5 -78t26 -93.5
-t7 -110.5q0 -150 -47 -280t-132 -225t-211 -150t-278 -55q-111 0 -223 42q-149 57 -258 191.5t-109 286.5z" />
-    <glyph glyph-name="_490" unicode="&#xf20a;" horiz-adv-x="2048" 
-d="M785 528h207q-14 -158 -98.5 -248.5t-214.5 -90.5q-162 0 -254.5 116t-92.5 316q0 194 93 311.5t233 117.5q148 0 232 -87t97 -247h-203q-5 64 -35.5 99t-81.5 35q-57 0 -88.5 -60.5t-31.5 -177.5q0 -48 5 -84t18 -69.5t40 -51.5t66 -18q95 0 109 139zM1497 528h206
-q-14 -158 -98 -248.5t-214 -90.5q-162 0 -254.5 116t-92.5 316q0 194 93 311.5t233 117.5q148 0 232 -87t97 -247h-204q-4 64 -35 99t-81 35q-57 0 -88.5 -60.5t-31.5 -177.5q0 -48 5 -84t18 -69.5t39.5 -51.5t65.5 -18q49 0 76.5 38t33.5 101zM1856 647q0 207 -15.5 307
-t-60.5 161q-6 8 -13.5 14t-21.5 15t-16 11q-86 63 -697 63q-625 0 -710 -63q-5 -4 -17.5 -11.5t-21 -14t-14.5 -14.5q-45 -60 -60 -159.5t-15 -308.5q0 -208 15 -307.5t60 -160.5q6 -8 15 -15t20.5 -14t17.5 -12q44 -33 239.5 -49t470.5 -16q610 0 697 65q5 4 17 11t20.5 14
-t13.5 16q46 60 61 159t15 309zM2048 1408v-1536h-2048v1536h2048z" />
-    <glyph glyph-name="_491" unicode="&#xf20b;" 
-d="M992 912v-496q0 -14 -9 -23t-23 -9h-160q-14 0 -23 9t-9 23v496q0 112 -80 192t-192 80h-272v-1152q0 -14 -9 -23t-23 -9h-160q-14 0 -23 9t-9 23v1344q0 14 9 23t23 9h464q135 0 249 -66.5t180.5 -180.5t66.5 -249zM1376 1376v-880q0 -135 -66.5 -249t-180.5 -180.5
-t-249 -66.5h-464q-14 0 -23 9t-9 23v960q0 14 9 23t23 9h160q14 0 23 -9t9 -23v-768h272q112 0 192 80t80 192v880q0 14 9 23t23 9h160q14 0 23 -9t9 -23z" />
-    <glyph glyph-name="_492" unicode="&#xf20c;" 
-d="M1311 694v-114q0 -24 -13.5 -38t-37.5 -14h-202q-24 0 -38 14t-14 38v114q0 24 14 38t38 14h202q24 0 37.5 -14t13.5 -38zM821 464v250q0 53 -32.5 85.5t-85.5 32.5h-133q-68 0 -96 -52q-28 52 -96 52h-130q-53 0 -85.5 -32.5t-32.5 -85.5v-250q0 -22 21 -22h55
-q22 0 22 22v230q0 24 13.5 38t38.5 14h94q24 0 38 -14t14 -38v-230q0 -22 21 -22h54q22 0 22 22v230q0 24 14 38t38 14h97q24 0 37.5 -14t13.5 -38v-230q0 -22 22 -22h55q21 0 21 22zM1410 560v154q0 53 -33 85.5t-86 32.5h-264q-53 0 -86 -32.5t-33 -85.5v-410
-q0 -21 22 -21h55q21 0 21 21v180q31 -42 94 -42h191q53 0 86 32.5t33 85.5zM1536 1176v-1072q0 -96 -68 -164t-164 -68h-1072q-96 0 -164 68t-68 164v1072q0 96 68 164t164 68h1072q96 0 164 -68t68 -164z" />
-    <glyph glyph-name="_493" unicode="&#xf20d;" 
-d="M915 450h-294l147 551zM1001 128h311l-324 1024h-440l-324 -1024h311l383 314zM1536 1120v-960q0 -118 -85 -203t-203 -85h-960q-118 0 -203 85t-85 203v960q0 118 85 203t203 85h960q118 0 203 -85t85 -203z" />
-    <glyph glyph-name="_494" unicode="&#xf20e;" horiz-adv-x="2048" 
-d="M2048 641q0 -21 -13 -36.5t-33 -19.5l-205 -356q3 -9 3 -18q0 -20 -12.5 -35.5t-32.5 -19.5l-193 -337q3 -8 3 -16q0 -23 -16.5 -40t-40.5 -17q-25 0 -41 18h-400q-17 -20 -43 -20t-43 20h-399q-17 -20 -43 -20q-23 0 -40 16.5t-17 40.5q0 8 4 20l-193 335
-q-20 4 -32.5 19.5t-12.5 35.5q0 9 3 18l-206 356q-20 5 -32.5 20.5t-12.5 35.5q0 21 13.5 36.5t33.5 19.5l199 344q0 1 -0.5 3t-0.5 3q0 36 34 51l209 363q-4 10 -4 18q0 24 17 40.5t40 16.5q26 0 44 -21h396q16 21 43 21t43 -21h398q18 21 44 21q23 0 40 -16.5t17 -40.5
-q0 -6 -4 -18l207 -358q23 -1 39 -17.5t16 -38.5q0 -13 -7 -27l187 -324q19 -4 31.5 -19.5t12.5 -35.5zM1063 -158h389l-342 354h-143l-342 -354h360q18 16 39 16t39 -16zM112 654q1 -4 1 -13q0 -10 -2 -15l208 -360l15 -6l188 199v347l-187 194q-13 -8 -29 -10zM986 1438
-h-388l190 -200l554 200h-280q-16 -16 -38 -16t-38 16zM1689 226q1 6 5 11l-64 68l-17 -79h76zM1583 226l22 105l-252 266l-296 -307l63 -64h463zM1495 -142l16 28l65 310h-427l333 -343q8 4 13 5zM578 -158h5l342 354h-373v-335l4 -6q14 -5 22 -13zM552 226h402l64 66
-l-309 321l-157 -166v-221zM359 226h163v189l-168 -177q4 -8 5 -12zM358 1051q0 -1 0.5 -2t0.5 -2q0 -16 -8 -29l171 -177v269zM552 1121v-311l153 -157l297 314l-223 236zM556 1425l-4 -8v-264l205 74l-191 201q-6 -2 -10 -3zM1447 1438h-16l-621 -224l213 -225zM1023 946
-l-297 -315l311 -319l296 307zM688 634l-136 141v-284zM1038 270l-42 -44h85zM1374 618l238 -251l132 624l-3 5l-1 1zM1718 1018q-8 13 -8 29v2l-216 376q-5 1 -13 5l-437 -463l310 -327zM522 1142v223l-163 -282zM522 196h-163l163 -283v283zM1607 196l-48 -227l130 227h-82
-zM1729 266l207 361q-2 10 -2 14q0 1 3 16l-171 296l-129 -612l77 -82q5 3 15 7z" />
-    <glyph glyph-name="f210" unicode="&#xf210;" 
-d="M0 856q0 131 91.5 226.5t222.5 95.5h742l352 358v-1470q0 -132 -91.5 -227t-222.5 -95h-780q-131 0 -222.5 95t-91.5 227v790zM1232 102l-176 180v425q0 46 -32 79t-78 33h-484q-46 0 -78 -33t-32 -79v-492q0 -46 32.5 -79.5t77.5 -33.5h770z" />
-    <glyph glyph-name="_496" unicode="&#xf211;" 
-d="M934 1386q-317 -121 -556 -362.5t-358 -560.5q-20 89 -20 176q0 208 102.5 384.5t278.5 279t384 102.5q82 0 169 -19zM1203 1267q93 -65 164 -155q-389 -113 -674.5 -400.5t-396.5 -676.5q-93 72 -155 162q112 386 395 671t667 399zM470 -67q115 356 379.5 622t619.5 384
-q40 -92 54 -195q-292 -120 -516 -345t-343 -518q-103 14 -194 52zM1536 -125q-193 50 -367 115q-135 -84 -290 -107q109 205 274 370.5t369 275.5q-21 -152 -101 -284q65 -175 115 -370z" />
-    <glyph glyph-name="f212" unicode="&#xf212;" horiz-adv-x="2048" 
-d="M1893 1144l155 -1272q-131 0 -257 57q-200 91 -393 91q-226 0 -374 -148q-148 148 -374 148q-193 0 -393 -91q-128 -57 -252 -57h-5l155 1272q224 127 482 127q233 0 387 -106q154 106 387 106q258 0 482 -127zM1398 157q129 0 232 -28.5t260 -93.5l-124 1021
-q-171 78 -368 78q-224 0 -374 -141q-150 141 -374 141q-197 0 -368 -78l-124 -1021q105 43 165.5 65t148.5 39.5t178 17.5q202 0 374 -108q172 108 374 108zM1438 191l-55 907q-211 -4 -359 -155q-152 155 -374 155q-176 0 -336 -66l-114 -941q124 51 228.5 76t221.5 25
-q209 0 374 -102q172 107 374 102z" />
-    <glyph glyph-name="_498" unicode="&#xf213;" horiz-adv-x="2048" 
-d="M1500 165v733q0 21 -15 36t-35 15h-93q-20 0 -35 -15t-15 -36v-733q0 -20 15 -35t35 -15h93q20 0 35 15t15 35zM1216 165v531q0 20 -15 35t-35 15h-101q-20 0 -35 -15t-15 -35v-531q0 -20 15 -35t35 -15h101q20 0 35 15t15 35zM924 165v429q0 20 -15 35t-35 15h-101
-q-20 0 -35 -15t-15 -35v-429q0 -20 15 -35t35 -15h101q20 0 35 15t15 35zM632 165v362q0 20 -15 35t-35 15h-101q-20 0 -35 -15t-15 -35v-362q0 -20 15 -35t35 -15h101q20 0 35 15t15 35zM2048 311q0 -166 -118 -284t-284 -118h-1244q-166 0 -284 118t-118 284
-q0 116 63 214.5t168 148.5q-10 34 -10 73q0 113 80.5 193.5t193.5 80.5q102 0 180 -67q45 183 194 300t338 117q149 0 275 -73.5t199.5 -199.5t73.5 -275q0 -66 -14 -122q135 -33 221 -142.5t86 -247.5z" />
-    <glyph glyph-name="_499" unicode="&#xf214;" 
-d="M0 1536h1536v-1392l-776 -338l-760 338v1392zM1436 209v926h-1336v-926l661 -294zM1436 1235v201h-1336v-201h1336zM181 937v-115h-37v115h37zM181 789v-115h-37v115h37zM181 641v-115h-37v115h37zM181 493v-115h-37v115h37zM181 345v-115h-37v115h37zM207 202l15 34
-l105 -47l-15 -33zM343 142l15 34l105 -46l-15 -34zM478 82l15 34l105 -46l-15 -34zM614 23l15 33l104 -46l-15 -34zM797 10l105 46l15 -33l-105 -47zM932 70l105 46l15 -34l-105 -46zM1068 130l105 46l15 -34l-105 -46zM1203 189l105 47l15 -34l-105 -46zM259 1389v-36h-114
-v36h114zM421 1389v-36h-115v36h115zM583 1389v-36h-115v36h115zM744 1389v-36h-114v36h114zM906 1389v-36h-114v36h114zM1068 1389v-36h-115v36h115zM1230 1389v-36h-115v36h115zM1391 1389v-36h-114v36h114zM181 1049v-79h-37v115h115v-36h-78zM421 1085v-36h-115v36h115z
-M583 1085v-36h-115v36h115zM744 1085v-36h-114v36h114zM906 1085v-36h-114v36h114zM1068 1085v-36h-115v36h115zM1230 1085v-36h-115v36h115zM1355 970v79h-78v36h115v-115h-37zM1355 822v115h37v-115h-37zM1355 674v115h37v-115h-37zM1355 526v115h37v-115h-37zM1355 378
-v115h37v-115h-37zM1355 230v115h37v-115h-37zM760 265q-129 0 -221 91.5t-92 221.5q0 129 92 221t221 92q130 0 221.5 -92t91.5 -221q0 -130 -91.5 -221.5t-221.5 -91.5zM595 646q0 -36 19.5 -56.5t49.5 -25t64 -7t64 -2t49.5 -9t19.5 -30.5q0 -49 -112 -49q-97 0 -123 51
-h-3l-31 -63q67 -42 162 -42q29 0 56.5 5t55.5 16t45.5 33t17.5 53q0 46 -27.5 69.5t-67.5 27t-79.5 3t-67 5t-27.5 25.5q0 21 20.5 33t40.5 15t41 3q34 0 70.5 -11t51.5 -34h3l30 58q-3 1 -21 8.5t-22.5 9t-19.5 7t-22 7t-20 4.5t-24 4t-23 1q-29 0 -56.5 -5t-54 -16.5
-t-43 -34t-16.5 -53.5z" />
-    <glyph glyph-name="_500" unicode="&#xf215;" horiz-adv-x="2048" 
-d="M863 504q0 112 -79.5 191.5t-191.5 79.5t-191 -79.5t-79 -191.5t79 -191t191 -79t191.5 79t79.5 191zM1726 505q0 112 -79 191t-191 79t-191.5 -79t-79.5 -191q0 -113 79.5 -192t191.5 -79t191 79.5t79 191.5zM2048 1314v-1348q0 -44 -31.5 -75.5t-76.5 -31.5h-1832
-q-45 0 -76.5 31.5t-31.5 75.5v1348q0 44 31.5 75.5t76.5 31.5h431q44 0 76 -31.5t32 -75.5v-161h754v161q0 44 32 75.5t76 31.5h431q45 0 76.5 -31.5t31.5 -75.5z" />
-    <glyph glyph-name="_501" unicode="&#xf216;" horiz-adv-x="2048" 
-d="M1430 953zM1690 749q148 0 253 -98.5t105 -244.5q0 -157 -109 -261.5t-267 -104.5q-85 0 -162 27.5t-138 73.5t-118 106t-109 126t-103.5 132.5t-108.5 126.5t-117 106t-136 73.5t-159 27.5q-154 0 -251.5 -91.5t-97.5 -244.5q0 -157 104 -250t263 -93q100 0 208 37.5
-t193 98.5q5 4 21 18.5t30 24t22 9.5q14 0 24.5 -10.5t10.5 -24.5q0 -24 -60 -77q-101 -88 -234.5 -142t-260.5 -54q-133 0 -245.5 58t-180 165t-67.5 241q0 205 141.5 341t347.5 136q120 0 226.5 -43.5t185.5 -113t151.5 -153t139 -167.5t133.5 -153.5t149.5 -113
-t172.5 -43.5q102 0 168.5 61.5t66.5 162.5q0 95 -64.5 159t-159.5 64q-30 0 -81.5 -18.5t-68.5 -18.5q-20 0 -35.5 15t-15.5 35q0 18 8.5 57t8.5 59q0 159 -107.5 263t-266.5 104q-58 0 -111.5 -18.5t-84 -40.5t-55.5 -40.5t-33 -18.5q-15 0 -25.5 10.5t-10.5 25.5
-q0 19 25 46q59 67 147 103.5t182 36.5q191 0 318 -125.5t127 -315.5q0 -37 -4 -66q57 15 115 15z" />
-    <glyph glyph-name="_502" unicode="&#xf217;" horiz-adv-x="1664" 
-d="M1216 832q0 26 -19 45t-45 19h-128v128q0 26 -19 45t-45 19t-45 -19t-19 -45v-128h-128q-26 0 -45 -19t-19 -45t19 -45t45 -19h128v-128q0 -26 19 -45t45 -19t45 19t19 45v128h128q26 0 45 19t19 45zM640 0q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5
-t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1536 0q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1664 1088v-512q0 -24 -16 -42.5t-41 -21.5l-1044 -122q1 -7 4.5 -21.5t6 -26.5t2.5 -22q0 -16 -24 -64h920
-q26 0 45 -19t19 -45t-19 -45t-45 -19h-1024q-26 0 -45 19t-19 45q0 14 11 39.5t29.5 59.5t20.5 38l-177 823h-204q-26 0 -45 19t-19 45t19 45t45 19h256q16 0 28.5 -6.5t20 -15.5t13 -24.5t7.5 -26.5t5.5 -29.5t4.5 -25.5h1201q26 0 45 -19t19 -45z" />
-    <glyph glyph-name="_503" unicode="&#xf218;" horiz-adv-x="1664" 
-d="M1280 832q0 26 -19 45t-45 19t-45 -19l-147 -146v293q0 26 -19 45t-45 19t-45 -19t-19 -45v-293l-147 146q-19 19 -45 19t-45 -19t-19 -45t19 -45l256 -256q19 -19 45 -19t45 19l256 256q19 19 19 45zM640 0q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5
-t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1536 0q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1664 1088v-512q0 -24 -16 -42.5t-41 -21.5l-1044 -122q1 -7 4.5 -21.5t6 -26.5t2.5 -22q0 -16 -24 -64h920
-q26 0 45 -19t19 -45t-19 -45t-45 -19h-1024q-26 0 -45 19t-19 45q0 14 11 39.5t29.5 59.5t20.5 38l-177 823h-204q-26 0 -45 19t-19 45t19 45t45 19h256q16 0 28.5 -6.5t20 -15.5t13 -24.5t7.5 -26.5t5.5 -29.5t4.5 -25.5h1201q26 0 45 -19t19 -45z" />
-    <glyph glyph-name="_504" unicode="&#xf219;" horiz-adv-x="2048" 
-d="M212 768l623 -665l-300 665h-323zM1024 -4l349 772h-698zM538 896l204 384h-262l-288 -384h346zM1213 103l623 665h-323zM683 896h682l-204 384h-274zM1510 896h346l-288 384h-262zM1651 1382l384 -512q14 -18 13 -41.5t-17 -40.5l-960 -1024q-18 -20 -47 -20t-47 20
-l-960 1024q-16 17 -17 40.5t13 41.5l384 512q18 26 51 26h1152q33 0 51 -26z" />
-    <glyph glyph-name="_505" unicode="&#xf21a;" horiz-adv-x="2048" 
-d="M1811 -19q19 19 45 19t45 -19l128 -128l-90 -90l-83 83l-83 -83q-18 -19 -45 -19t-45 19l-83 83l-83 -83q-19 -19 -45 -19t-45 19l-83 83l-83 -83q-19 -19 -45 -19t-45 19l-83 83l-83 -83q-19 -19 -45 -19t-45 19l-83 83l-83 -83q-19 -19 -45 -19t-45 19l-83 83l-83 -83
-q-19 -19 -45 -19t-45 19l-83 83l-83 -83q-19 -19 -45 -19t-45 19l-128 128l90 90l83 -83l83 83q19 19 45 19t45 -19l83 -83l83 83q19 19 45 19t45 -19l83 -83l83 83q19 19 45 19t45 -19l83 -83l83 83q19 19 45 19t45 -19l83 -83l83 83q19 19 45 19t45 -19l83 -83l83 83
-q19 19 45 19t45 -19l83 -83zM237 19q-19 -19 -45 -19t-45 19l-128 128l90 90l83 -82l83 82q19 19 45 19t45 -19l83 -82l64 64v293l-210 314q-17 26 -7 56.5t40 40.5l177 58v299h128v128h256v128h256v-128h256v-128h128v-299l177 -58q30 -10 40 -40.5t-7 -56.5l-210 -314
-v-293l19 18q19 19 45 19t45 -19l83 -82l83 82q19 19 45 19t45 -19l128 -128l-90 -90l-83 83l-83 -83q-18 -19 -45 -19t-45 19l-83 83l-83 -83q-19 -19 -45 -19t-45 19l-83 83l-83 -83q-19 -19 -45 -19t-45 19l-83 83l-83 -83q-19 -19 -45 -19t-45 19l-83 83l-83 -83
-q-19 -19 -45 -19t-45 19l-83 83l-83 -83q-19 -19 -45 -19t-45 19l-83 83zM640 1152v-128l384 128l384 -128v128h-128v128h-512v-128h-128z" />
-    <glyph glyph-name="_506" unicode="&#xf21b;" 
-d="M576 0l96 448l-96 128l-128 64zM832 0l128 640l-128 -64l-96 -128zM992 1010q-2 4 -4 6q-10 8 -96 8q-70 0 -167 -19q-7 -2 -21 -2t-21 2q-97 19 -167 19q-86 0 -96 -8q-2 -2 -4 -6q2 -18 4 -27q2 -3 7.5 -6.5t7.5 -10.5q2 -4 7.5 -20.5t7 -20.5t7.5 -17t8.5 -17t9 -14
-t12 -13.5t14 -9.5t17.5 -8t20.5 -4t24.5 -2q36 0 59 12.5t32.5 30t14.5 34.5t11.5 29.5t17.5 12.5h12q11 0 17.5 -12.5t11.5 -29.5t14.5 -34.5t32.5 -30t59 -12.5q13 0 24.5 2t20.5 4t17.5 8t14 9.5t12 13.5t9 14t8.5 17t7.5 17t7 20.5t7.5 20.5q2 7 7.5 10.5t7.5 6.5
-q2 9 4 27zM1408 131q0 -121 -73 -190t-194 -69h-874q-121 0 -194 69t-73 190q0 61 4.5 118t19 125.5t37.5 123.5t63.5 103.5t93.5 74.5l-90 220h214q-22 64 -22 128q0 12 2 32q-194 40 -194 96q0 57 210 99q17 62 51.5 134t70.5 114q32 37 76 37q30 0 84 -31t84 -31t84 31
-t84 31q44 0 76 -37q36 -42 70.5 -114t51.5 -134q210 -42 210 -99q0 -56 -194 -96q7 -81 -20 -160h214l-82 -225q63 -33 107.5 -96.5t65.5 -143.5t29 -151.5t8 -148.5z" />
-    <glyph glyph-name="_507" unicode="&#xf21c;" horiz-adv-x="2304" 
-d="M2301 500q12 -103 -22 -198.5t-99 -163.5t-158.5 -106t-196.5 -31q-161 11 -279.5 125t-134.5 274q-12 111 27.5 210.5t118.5 170.5l-71 107q-96 -80 -151 -194t-55 -244q0 -27 -18.5 -46.5t-45.5 -19.5h-256h-69q-23 -164 -149 -274t-294 -110q-185 0 -316.5 131.5
-t-131.5 316.5t131.5 316.5t316.5 131.5q76 0 152 -27l24 45q-123 110 -304 110h-64q-26 0 -45 19t-19 45t19 45t45 19h128q78 0 145 -13.5t116.5 -38.5t71.5 -39.5t51 -36.5h512h115l-85 128h-222q-30 0 -49 22.5t-14 52.5q4 23 23 38t43 15h253q33 0 53 -28l70 -105
-l114 114q19 19 46 19h101q26 0 45 -19t19 -45v-128q0 -26 -19 -45t-45 -19h-179l115 -172q131 63 275 36q143 -26 244 -134.5t118 -253.5zM448 128q115 0 203 72.5t111 183.5h-314q-35 0 -55 31q-18 32 -1 63l147 277q-47 13 -91 13q-132 0 -226 -94t-94 -226t94 -226
-t226 -94zM1856 128q132 0 226 94t94 226t-94 226t-226 94q-60 0 -121 -24l174 -260q15 -23 10 -49t-27 -40q-15 -11 -36 -11q-35 0 -53 29l-174 260q-93 -95 -93 -225q0 -132 94 -226t226 -94z" />
-    <glyph glyph-name="_508" unicode="&#xf21d;" 
-d="M1408 0q0 -63 -61.5 -113.5t-164 -81t-225 -46t-253.5 -15.5t-253.5 15.5t-225 46t-164 81t-61.5 113.5q0 49 33 88.5t91 66.5t118 44.5t131 29.5q26 5 48 -10.5t26 -41.5q5 -26 -10.5 -48t-41.5 -26q-58 -10 -106 -23.5t-76.5 -25.5t-48.5 -23.5t-27.5 -19.5t-8.5 -12
-q3 -11 27 -26.5t73 -33t114 -32.5t160.5 -25t201.5 -10t201.5 10t160.5 25t114 33t73 33.5t27 27.5q-1 4 -8.5 11t-27.5 19t-48.5 23.5t-76.5 25t-106 23.5q-26 4 -41.5 26t-10.5 48q4 26 26 41.5t48 10.5q71 -12 131 -29.5t118 -44.5t91 -66.5t33 -88.5zM1024 896v-384
-q0 -26 -19 -45t-45 -19h-64v-384q0 -26 -19 -45t-45 -19h-256q-26 0 -45 19t-19 45v384h-64q-26 0 -45 19t-19 45v384q0 53 37.5 90.5t90.5 37.5h384q53 0 90.5 -37.5t37.5 -90.5zM928 1280q0 -93 -65.5 -158.5t-158.5 -65.5t-158.5 65.5t-65.5 158.5t65.5 158.5t158.5 65.5
-t158.5 -65.5t65.5 -158.5z" />
-    <glyph glyph-name="_509" unicode="&#xf21e;" horiz-adv-x="1792" 
-d="M1280 512h305q-5 -6 -10 -10.5t-9 -7.5l-3 -4l-623 -600q-18 -18 -44 -18t-44 18l-624 602q-5 2 -21 20h369q22 0 39.5 13.5t22.5 34.5l70 281l190 -667q6 -20 23 -33t39 -13q21 0 38 13t23 33l146 485l56 -112q18 -35 57 -35zM1792 940q0 -145 -103 -300h-369l-111 221
-q-8 17 -25.5 27t-36.5 8q-45 -5 -56 -46l-129 -430l-196 686q-6 20 -23.5 33t-39.5 13t-39 -13.5t-22 -34.5l-116 -464h-423q-103 155 -103 300q0 220 127 344t351 124q62 0 126.5 -21.5t120 -58t95.5 -68.5t76 -68q36 36 76 68t95.5 68.5t120 58t126.5 21.5q224 0 351 -124
-t127 -344z" />
-    <glyph glyph-name="venus" unicode="&#xf221;" horiz-adv-x="1280" 
-d="M1152 960q0 -221 -147.5 -384.5t-364.5 -187.5v-260h224q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-224v-224q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v224h-224q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h224v260q-150 16 -271.5 103t-186 224t-52.5 292
-q11 134 80.5 249t182 188t245.5 88q170 19 319 -54t236 -212t87 -306zM128 960q0 -185 131.5 -316.5t316.5 -131.5t316.5 131.5t131.5 316.5t-131.5 316.5t-316.5 131.5t-316.5 -131.5t-131.5 -316.5z" />
-    <glyph glyph-name="_511" unicode="&#xf222;" 
-d="M1472 1408q26 0 45 -19t19 -45v-416q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v262l-382 -383q126 -156 126 -359q0 -117 -45.5 -223.5t-123 -184t-184 -123t-223.5 -45.5t-223.5 45.5t-184 123t-123 184t-45.5 223.5t45.5 223.5t123 184t184 123t223.5 45.5
-q203 0 359 -126l382 382h-261q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h416zM576 0q185 0 316.5 131.5t131.5 316.5t-131.5 316.5t-316.5 131.5t-316.5 -131.5t-131.5 -316.5t131.5 -316.5t316.5 -131.5z" />
-    <glyph glyph-name="_512" unicode="&#xf223;" horiz-adv-x="1280" 
-d="M830 1220q145 -72 233.5 -210.5t88.5 -305.5q0 -221 -147.5 -384.5t-364.5 -187.5v-132h96q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-96v-96q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v96h-96q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h96v132q-217 24 -364.5 187.5
-t-147.5 384.5q0 167 88.5 305.5t233.5 210.5q-165 96 -228 273q-6 16 3.5 29.5t26.5 13.5h69q21 0 29 -20q44 -106 140 -171t214 -65t214 65t140 171q8 20 37 20h61q17 0 26.5 -13.5t3.5 -29.5q-63 -177 -228 -273zM576 256q185 0 316.5 131.5t131.5 316.5t-131.5 316.5
-t-316.5 131.5t-316.5 -131.5t-131.5 -316.5t131.5 -316.5t316.5 -131.5z" />
-    <glyph glyph-name="_513" unicode="&#xf224;" 
-d="M1024 1504q0 14 9 23t23 9h288q26 0 45 -19t19 -45v-288q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v134l-254 -255q126 -158 126 -359q0 -221 -147.5 -384.5t-364.5 -187.5v-132h96q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-96v-96q0 -14 -9 -23t-23 -9h-64
-q-14 0 -23 9t-9 23v96h-96q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h96v132q-149 16 -270.5 103t-186.5 223.5t-53 291.5q16 204 160 353.5t347 172.5q118 14 228 -19t198 -103l255 254h-134q-14 0 -23 9t-9 23v64zM576 256q185 0 316.5 131.5t131.5 316.5t-131.5 316.5
-t-316.5 131.5t-316.5 -131.5t-131.5 -316.5t131.5 -316.5t316.5 -131.5z" />
-    <glyph glyph-name="_514" unicode="&#xf225;" horiz-adv-x="1792" 
-d="M1280 1504q0 14 9 23t23 9h288q26 0 45 -19t19 -45v-288q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v134l-254 -255q126 -158 126 -359q0 -221 -147.5 -384.5t-364.5 -187.5v-132h96q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-96v-96q0 -14 -9 -23t-23 -9h-64
-q-14 0 -23 9t-9 23v96h-96q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h96v132q-217 24 -364.5 187.5t-147.5 384.5q0 201 126 359l-52 53l-101 -111q-9 -10 -22 -10.5t-23 7.5l-48 44q-10 8 -10.5 21.5t8.5 23.5l105 115l-111 112v-134q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9
-t-9 23v288q0 26 19 45t45 19h288q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-133l106 -107l86 94q9 10 22 10.5t23 -7.5l48 -44q10 -8 10.5 -21.5t-8.5 -23.5l-90 -99l57 -56q158 126 359 126t359 -126l255 254h-134q-14 0 -23 9t-9 23v64zM832 256q185 0 316.5 131.5
-t131.5 316.5t-131.5 316.5t-316.5 131.5t-316.5 -131.5t-131.5 -316.5t131.5 -316.5t316.5 -131.5z" />
-    <glyph glyph-name="_515" unicode="&#xf226;" horiz-adv-x="1792" 
-d="M1790 1007q12 -155 -52.5 -292t-186 -224t-271.5 -103v-260h224q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-224v-224q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v224h-512v-224q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v224h-224q-14 0 -23 9t-9 23v64q0 14 9 23
-t23 9h224v260q-150 16 -271.5 103t-186 224t-52.5 292q17 206 164.5 356.5t352.5 169.5q206 21 377 -94q171 115 377 94q205 -19 352.5 -169.5t164.5 -356.5zM896 647q128 131 128 313t-128 313q-128 -131 -128 -313t128 -313zM576 512q115 0 218 57q-154 165 -154 391
-q0 224 154 391q-103 57 -218 57q-185 0 -316.5 -131.5t-131.5 -316.5t131.5 -316.5t316.5 -131.5zM1152 128v260q-137 15 -256 94q-119 -79 -256 -94v-260h512zM1216 512q185 0 316.5 131.5t131.5 316.5t-131.5 316.5t-316.5 131.5q-115 0 -218 -57q154 -167 154 -391
-q0 -226 -154 -391q103 -57 218 -57z" />
-    <glyph glyph-name="_516" unicode="&#xf227;" horiz-adv-x="1920" 
-d="M1536 1120q0 14 9 23t23 9h288q26 0 45 -19t19 -45v-288q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v134l-254 -255q76 -95 107.5 -214t9.5 -247q-31 -182 -166 -312t-318 -156q-210 -29 -384.5 80t-241.5 300q-117 6 -221 57.5t-177.5 133t-113.5 192.5t-32 230
-q9 135 78 252t182 191.5t248 89.5q118 14 227.5 -19t198.5 -103l255 254h-134q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h288q26 0 45 -19t19 -45v-288q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v134l-254 -255q59 -74 93 -169q182 -9 328 -124l255 254h-134q-14 0 -23 9
-t-9 23v64zM1024 704q0 20 -4 58q-162 -25 -271 -150t-109 -292q0 -20 4 -58q162 25 271 150t109 292zM128 704q0 -168 111 -294t276 -149q-3 29 -3 59q0 210 135 369.5t338 196.5q-53 120 -163.5 193t-245.5 73q-185 0 -316.5 -131.5t-131.5 -316.5zM1088 -128
-q185 0 316.5 131.5t131.5 316.5q0 168 -111 294t-276 149q3 -28 3 -59q0 -210 -135 -369.5t-338 -196.5q53 -120 163.5 -193t245.5 -73z" />
-    <glyph glyph-name="_517" unicode="&#xf228;" horiz-adv-x="2048" 
-d="M1664 1504q0 14 9 23t23 9h288q26 0 45 -19t19 -45v-288q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v134l-254 -255q76 -95 107.5 -214t9.5 -247q-32 -180 -164.5 -310t-313.5 -157q-223 -34 -409 90q-117 -78 -256 -93v-132h96q14 0 23 -9t9 -23v-64q0 -14 -9 -23
-t-23 -9h-96v-96q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v96h-96q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h96v132q-155 17 -279.5 109.5t-187 237.5t-39.5 307q25 187 159.5 322.5t320.5 164.5q224 34 410 -90q146 97 320 97q201 0 359 -126l255 254h-134q-14 0 -23 9
-t-9 23v64zM896 391q128 131 128 313t-128 313q-128 -131 -128 -313t128 -313zM128 704q0 -185 131.5 -316.5t316.5 -131.5q117 0 218 57q-154 167 -154 391t154 391q-101 57 -218 57q-185 0 -316.5 -131.5t-131.5 -316.5zM1216 256q185 0 316.5 131.5t131.5 316.5
-t-131.5 316.5t-316.5 131.5q-117 0 -218 -57q154 -167 154 -391t-154 -391q101 -57 218 -57z" />
-    <glyph glyph-name="_518" unicode="&#xf229;" 
-d="M1472 1408q26 0 45 -19t19 -45v-416q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v262l-213 -214l140 -140q9 -10 9 -23t-9 -22l-46 -46q-9 -9 -22 -9t-23 9l-140 141l-78 -79q126 -156 126 -359q0 -117 -45.5 -223.5t-123 -184t-184 -123t-223.5 -45.5t-223.5 45.5
-t-184 123t-123 184t-45.5 223.5t45.5 223.5t123 184t184 123t223.5 45.5q203 0 359 -126l78 78l-172 172q-9 10 -9 23t9 22l46 46q9 9 22 9t23 -9l172 -172l213 213h-261q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h416zM576 0q185 0 316.5 131.5t131.5 316.5t-131.5 316.5
-t-316.5 131.5t-316.5 -131.5t-131.5 -316.5t131.5 -316.5t316.5 -131.5z" />
-    <glyph glyph-name="_519" unicode="&#xf22a;" horiz-adv-x="1280" 
-d="M640 892q217 -24 364.5 -187.5t147.5 -384.5q0 -167 -87 -306t-236 -212t-319 -54q-133 15 -245.5 88t-182 188t-80.5 249q-12 155 52.5 292t186 224t271.5 103v132h-160q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h160v165l-92 -92q-10 -9 -23 -9t-22 9l-46 46q-9 9 -9 22
-t9 23l202 201q19 19 45 19t45 -19l202 -201q9 -10 9 -23t-9 -22l-46 -46q-9 -9 -22 -9t-23 9l-92 92v-165h160q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-160v-132zM576 -128q185 0 316.5 131.5t131.5 316.5t-131.5 316.5t-316.5 131.5t-316.5 -131.5t-131.5 -316.5
-t131.5 -316.5t316.5 -131.5z" />
-    <glyph glyph-name="_520" unicode="&#xf22b;" horiz-adv-x="2048" 
-d="M1901 621q19 -19 19 -45t-19 -45l-294 -294q-9 -10 -22.5 -10t-22.5 10l-45 45q-10 9 -10 22.5t10 22.5l185 185h-294v-224q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v224h-132q-24 -217 -187.5 -364.5t-384.5 -147.5q-167 0 -306 87t-212 236t-54 319q15 133 88 245.5
-t188 182t249 80.5q155 12 292 -52.5t224 -186t103 -271.5h132v224q0 14 9 23t23 9h64q14 0 23 -9t9 -23v-224h294l-185 185q-10 9 -10 22.5t10 22.5l45 45q9 10 22.5 10t22.5 -10zM576 128q185 0 316.5 131.5t131.5 316.5t-131.5 316.5t-316.5 131.5t-316.5 -131.5
-t-131.5 -316.5t131.5 -316.5t316.5 -131.5z" />
-    <glyph glyph-name="_521" unicode="&#xf22c;" horiz-adv-x="1280" 
-d="M1152 960q0 -221 -147.5 -384.5t-364.5 -187.5v-612q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v612q-217 24 -364.5 187.5t-147.5 384.5q0 117 45.5 223.5t123 184t184 123t223.5 45.5t223.5 -45.5t184 -123t123 -184t45.5 -223.5zM576 512q185 0 316.5 131.5
-t131.5 316.5t-131.5 316.5t-316.5 131.5t-316.5 -131.5t-131.5 -316.5t131.5 -316.5t316.5 -131.5z" />
-    <glyph glyph-name="_522" unicode="&#xf22d;" horiz-adv-x="1280" 
-d="M1024 576q0 185 -131.5 316.5t-316.5 131.5t-316.5 -131.5t-131.5 -316.5t131.5 -316.5t316.5 -131.5t316.5 131.5t131.5 316.5zM1152 576q0 -117 -45.5 -223.5t-123 -184t-184 -123t-223.5 -45.5t-223.5 45.5t-184 123t-123 184t-45.5 223.5t45.5 223.5t123 184t184 123
-t223.5 45.5t223.5 -45.5t184 -123t123 -184t45.5 -223.5z" />
-    <glyph glyph-name="_523" unicode="&#xf22e;" horiz-adv-x="1792" 
- />
-    <glyph glyph-name="_524" unicode="&#xf22f;" horiz-adv-x="1792" 
- />
-    <glyph glyph-name="_525" unicode="&#xf230;" 
-d="M1451 1408q35 0 60 -25t25 -60v-1366q0 -35 -25 -60t-60 -25h-391v595h199l30 232h-229v148q0 56 23.5 84t91.5 28l122 1v207q-63 9 -178 9q-136 0 -217.5 -80t-81.5 -226v-171h-200v-232h200v-595h-735q-35 0 -60 25t-25 60v1366q0 35 25 60t60 25h1366z" />
-    <glyph glyph-name="_526" unicode="&#xf231;" horiz-adv-x="1280" 
-d="M0 939q0 108 37.5 203.5t103.5 166.5t152 123t185 78t202 26q158 0 294 -66.5t221 -193.5t85 -287q0 -96 -19 -188t-60 -177t-100 -149.5t-145 -103t-189 -38.5q-68 0 -135 32t-96 88q-10 -39 -28 -112.5t-23.5 -95t-20.5 -71t-26 -71t-32 -62.5t-46 -77.5t-62 -86.5
-l-14 -5l-9 10q-15 157 -15 188q0 92 21.5 206.5t66.5 287.5t52 203q-32 65 -32 169q0 83 52 156t132 73q61 0 95 -40.5t34 -102.5q0 -66 -44 -191t-44 -187q0 -63 45 -104.5t109 -41.5q55 0 102 25t78.5 68t56 95t38 110.5t20 111t6.5 99.5q0 173 -109.5 269.5t-285.5 96.5
-q-200 0 -334 -129.5t-134 -328.5q0 -44 12.5 -85t27 -65t27 -45.5t12.5 -30.5q0 -28 -15 -73t-37 -45q-2 0 -17 3q-51 15 -90.5 56t-61 94.5t-32.5 108t-11 106.5z" />
-    <glyph glyph-name="_527" unicode="&#xf232;" 
-d="M985 562q13 0 97.5 -44t89.5 -53q2 -5 2 -15q0 -33 -17 -76q-16 -39 -71 -65.5t-102 -26.5q-57 0 -190 62q-98 45 -170 118t-148 185q-72 107 -71 194v8q3 91 74 158q24 22 52 22q6 0 18 -1.5t19 -1.5q19 0 26.5 -6.5t15.5 -27.5q8 -20 33 -88t25 -75q0 -21 -34.5 -57.5
-t-34.5 -46.5q0 -7 5 -15q34 -73 102 -137q56 -53 151 -101q12 -7 22 -7q15 0 54 48.5t52 48.5zM782 32q127 0 243.5 50t200.5 134t134 200.5t50 243.5t-50 243.5t-134 200.5t-200.5 134t-243.5 50t-243.5 -50t-200.5 -134t-134 -200.5t-50 -243.5q0 -203 120 -368l-79 -233
-l242 77q158 -104 345 -104zM782 1414q153 0 292.5 -60t240.5 -161t161 -240.5t60 -292.5t-60 -292.5t-161 -240.5t-240.5 -161t-292.5 -60q-195 0 -365 94l-417 -134l136 405q-108 178 -108 389q0 153 60 292.5t161 240.5t240.5 161t292.5 60z" />
-    <glyph glyph-name="_528" unicode="&#xf233;" horiz-adv-x="1792" 
-d="M128 128h1024v128h-1024v-128zM128 640h1024v128h-1024v-128zM1696 192q0 40 -28 68t-68 28t-68 -28t-28 -68t28 -68t68 -28t68 28t28 68zM128 1152h1024v128h-1024v-128zM1696 704q0 40 -28 68t-68 28t-68 -28t-28 -68t28 -68t68 -28t68 28t28 68zM1696 1216
-q0 40 -28 68t-68 28t-68 -28t-28 -68t28 -68t68 -28t68 28t28 68zM1792 384v-384h-1792v384h1792zM1792 896v-384h-1792v384h1792zM1792 1408v-384h-1792v384h1792z" />
-    <glyph glyph-name="_529" unicode="&#xf234;" horiz-adv-x="2048" 
-d="M704 640q-159 0 -271.5 112.5t-112.5 271.5t112.5 271.5t271.5 112.5t271.5 -112.5t112.5 -271.5t-112.5 -271.5t-271.5 -112.5zM1664 512h352q13 0 22.5 -9.5t9.5 -22.5v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-352v-352q0 -13 -9.5 -22.5t-22.5 -9.5h-192q-13 0 -22.5 9.5
-t-9.5 22.5v352h-352q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h352v352q0 13 9.5 22.5t22.5 9.5h192q13 0 22.5 -9.5t9.5 -22.5v-352zM928 288q0 -52 38 -90t90 -38h256v-238q-68 -50 -171 -50h-874q-121 0 -194 69t-73 190q0 53 3.5 103.5t14 109t26.5 108.5
-t43 97.5t62 81t85.5 53.5t111.5 20q19 0 39 -17q79 -61 154.5 -91.5t164.5 -30.5t164.5 30.5t154.5 91.5q20 17 39 17q132 0 217 -96h-223q-52 0 -90 -38t-38 -90v-192z" />
-    <glyph glyph-name="_530" unicode="&#xf235;" horiz-adv-x="2048" 
-d="M704 640q-159 0 -271.5 112.5t-112.5 271.5t112.5 271.5t271.5 112.5t271.5 -112.5t112.5 -271.5t-112.5 -271.5t-271.5 -112.5zM1781 320l249 -249q9 -9 9 -23q0 -13 -9 -22l-136 -136q-9 -9 -22 -9q-14 0 -23 9l-249 249l-249 -249q-9 -9 -23 -9q-13 0 -22 9l-136 136
-q-9 9 -9 22q0 14 9 23l249 249l-249 249q-9 9 -9 23q0 13 9 22l136 136q9 9 22 9q14 0 23 -9l249 -249l249 249q9 9 23 9q13 0 22 -9l136 -136q9 -9 9 -22q0 -14 -9 -23zM1283 320l-181 -181q-37 -37 -37 -91q0 -53 37 -90l83 -83q-21 -3 -44 -3h-874q-121 0 -194 69
-t-73 190q0 53 3.5 103.5t14 109t26.5 108.5t43 97.5t62 81t85.5 53.5t111.5 20q19 0 39 -17q154 -122 319 -122t319 122q20 17 39 17q28 0 57 -6q-28 -27 -41 -50t-13 -56q0 -54 37 -91z" />
-    <glyph glyph-name="_531" unicode="&#xf236;" horiz-adv-x="2048" 
-d="M256 512h1728q26 0 45 -19t19 -45v-448h-256v256h-1536v-256h-256v1216q0 26 19 45t45 19h128q26 0 45 -19t19 -45v-704zM832 832q0 106 -75 181t-181 75t-181 -75t-75 -181t75 -181t181 -75t181 75t75 181zM2048 576v64q0 159 -112.5 271.5t-271.5 112.5h-704
-q-26 0 -45 -19t-19 -45v-384h1152z" />
-    <glyph glyph-name="_532" unicode="&#xf237;" 
-d="M1536 1536l-192 -448h192v-192h-274l-55 -128h329v-192h-411l-357 -832l-357 832h-411v192h329l-55 128h-274v192h192l-192 448h256l323 -768h378l323 768h256zM768 320l108 256h-216z" />
-    <glyph glyph-name="_533" unicode="&#xf238;" 
-d="M1088 1536q185 0 316.5 -93.5t131.5 -226.5v-896q0 -130 -125.5 -222t-305.5 -97l213 -202q16 -15 8 -35t-30 -20h-1056q-22 0 -30 20t8 35l213 202q-180 5 -305.5 97t-125.5 222v896q0 133 131.5 226.5t316.5 93.5h640zM768 192q80 0 136 56t56 136t-56 136t-136 56
-t-136 -56t-56 -136t56 -136t136 -56zM1344 768v512h-1152v-512h1152z" />
-    <glyph glyph-name="_534" unicode="&#xf239;" 
-d="M1088 1536q185 0 316.5 -93.5t131.5 -226.5v-896q0 -130 -125.5 -222t-305.5 -97l213 -202q16 -15 8 -35t-30 -20h-1056q-22 0 -30 20t8 35l213 202q-180 5 -305.5 97t-125.5 222v896q0 133 131.5 226.5t316.5 93.5h640zM288 224q66 0 113 47t47 113t-47 113t-113 47
-t-113 -47t-47 -113t47 -113t113 -47zM704 768v512h-544v-512h544zM1248 224q66 0 113 47t47 113t-47 113t-113 47t-113 -47t-47 -113t47 -113t113 -47zM1408 768v512h-576v-512h576z" />
-    <glyph glyph-name="_535" unicode="&#xf23a;" horiz-adv-x="1792" 
-d="M597 1115v-1173q0 -25 -12.5 -42.5t-36.5 -17.5q-17 0 -33 8l-465 233q-21 10 -35.5 33.5t-14.5 46.5v1140q0 20 10 34t29 14q14 0 44 -15l511 -256q3 -3 3 -5zM661 1014l534 -866l-534 266v600zM1792 996v-1054q0 -25 -14 -40.5t-38 -15.5t-47 13l-441 220zM1789 1116
-q0 -3 -256.5 -419.5t-300.5 -487.5l-390 634l324 527q17 28 52 28q14 0 26 -6l541 -270q4 -2 4 -6z" />
-    <glyph glyph-name="_536" unicode="&#xf23b;" 
-d="M809 532l266 499h-112l-157 -312q-24 -48 -44 -92l-42 92l-155 312h-120l263 -493v-324h101v318zM1536 1408v-1536h-1536v1536h1536z" />
-    <glyph glyph-name="_537" unicode="&#xf23c;" horiz-adv-x="2296" 
-d="M478 -139q-8 -16 -27 -34.5t-37 -25.5q-25 -9 -51.5 3.5t-28.5 31.5q-1 22 40 55t68 38q23 4 34 -21.5t2 -46.5zM1819 -139q7 -16 26 -34.5t38 -25.5q25 -9 51.5 3.5t27.5 31.5q2 22 -39.5 55t-68.5 38q-22 4 -33 -21.5t-2 -46.5zM1867 -30q13 -27 56.5 -59.5t77.5 -41.5
-q45 -13 82 4.5t37 50.5q0 46 -67.5 100.5t-115.5 59.5q-40 5 -63.5 -37.5t-6.5 -76.5zM428 -30q-13 -27 -56 -59.5t-77 -41.5q-45 -13 -82 4.5t-37 50.5q0 46 67.5 100.5t115.5 59.5q40 5 63 -37.5t6 -76.5zM1158 1094h1q-41 0 -76 -15q27 -8 44 -30.5t17 -49.5
-q0 -35 -27 -60t-65 -25q-52 0 -80 43q-5 -23 -5 -42q0 -74 56 -126.5t135 -52.5q80 0 136 52.5t56 126.5t-56 126.5t-136 52.5zM1462 1312q-99 109 -220.5 131.5t-245.5 -44.5q27 60 82.5 96.5t118 39.5t121.5 -17t99.5 -74.5t44.5 -131.5zM2212 73q8 -11 -11 -42
-q7 -23 7 -40q1 -56 -44.5 -112.5t-109.5 -91.5t-118 -37q-48 -2 -92 21.5t-66 65.5q-687 -25 -1259 0q-23 -41 -66.5 -65t-92.5 -22q-86 3 -179.5 80.5t-92.5 160.5q2 22 7 40q-19 31 -11 42q6 10 31 1q14 22 41 51q-7 29 2 38q11 10 39 -4q29 20 59 34q0 29 13 37
-q23 12 51 -16q35 5 61 -2q18 -4 38 -19v73q-11 0 -18 2q-53 10 -97 44.5t-55 87.5q-9 38 0 81q15 62 93 95q2 17 19 35.5t36 23.5t33 -7.5t19 -30.5h13q46 -5 60 -23q3 -3 5 -7q10 1 30.5 3.5t30.5 3.5q-15 11 -30 17q-23 40 -91 43q0 6 1 10q-62 2 -118.5 18.5t-84.5 47.5
-q-32 36 -42.5 92t-2.5 112q16 126 90 179q23 16 52 4.5t32 -40.5q0 -1 1.5 -14t2.5 -21t3 -20t5.5 -19t8.5 -10q27 -14 76 -12q48 46 98 74q-40 4 -162 -14l47 46q61 58 163 111q145 73 282 86q-20 8 -41 15.5t-47 14t-42.5 10.5t-47.5 11t-43 10q595 126 904 -139
-q98 -84 158 -222q85 -10 121 9h1q5 3 8.5 10t5.5 19t3 19.5t3 21.5l1 14q3 28 32 40t52 -5q73 -52 91 -178q7 -57 -3.5 -113t-42.5 -91q-28 -32 -83.5 -48.5t-115.5 -18.5v-10q-71 -2 -95 -43q-14 -5 -31 -17q11 -1 32 -3.5t30 -3.5q1 5 5 8q16 18 60 23h13q5 18 19 30t33 8
-t36 -23t19 -36q79 -32 93 -95q9 -40 1 -81q-12 -53 -56 -88t-97 -44q-10 -2 -17 -2q0 -49 -1 -73q20 15 38 19q26 7 61 2q28 28 51 16q14 -9 14 -37q33 -16 59 -34q27 13 38 4q10 -10 2 -38q28 -30 41 -51q23 8 31 -1zM1937 1025q0 -29 -9 -54q82 -32 112 -132
-q4 37 -9.5 98.5t-41.5 90.5q-20 19 -36 17t-16 -20zM1859 925q35 -42 47.5 -108.5t-0.5 -124.5q67 13 97 45q13 14 18 28q-3 64 -31 114.5t-79 66.5q-15 -15 -52 -21zM1822 921q-30 0 -44 1q42 -115 53 -239q21 0 43 3q16 68 1 135t-53 100zM258 839q30 100 112 132
-q-9 25 -9 54q0 18 -16.5 20t-35.5 -17q-28 -29 -41.5 -90.5t-9.5 -98.5zM294 737q29 -31 97 -45q-13 58 -0.5 124.5t47.5 108.5v0q-37 6 -52 21q-51 -16 -78.5 -66t-31.5 -115q9 -17 18 -28zM471 683q14 124 73 235q-19 -4 -55 -18l-45 -19v1q-46 -89 -20 -196q25 -3 47 -3z
-M1434 644q8 -38 16.5 -108.5t11.5 -89.5q3 -18 9.5 -21.5t23.5 4.5q40 20 62 85.5t23 125.5q-24 2 -146 4zM1152 1285q-116 0 -199 -82.5t-83 -198.5q0 -117 83 -199.5t199 -82.5t199 82.5t83 199.5q0 116 -83 198.5t-199 82.5zM1380 646q-105 2 -211 0v1q-1 -27 2.5 -86
-t13.5 -66q29 -14 93.5 -14.5t95.5 10.5q9 3 11 39t-0.5 69.5t-4.5 46.5zM1112 447q8 4 9.5 48t-0.5 88t-4 63v1q-212 -3 -214 -3q-4 -20 -7 -62t0 -83t14 -46q34 -15 101 -16t101 10zM718 636q-16 -59 4.5 -118.5t77.5 -84.5q15 -8 24 -5t12 21q3 16 8 90t10 103
-q-69 -2 -136 -6zM591 510q3 -23 -34 -36q132 -141 271.5 -240t305.5 -154q172 49 310.5 146t293.5 250q-33 13 -30 34q0 2 0.5 3.5t1.5 3t1 2.5v1v-1q-17 2 -50 5.5t-48 4.5q-26 -90 -82 -132q-51 -38 -82 1q-5 6 -9 14q-7 13 -17 62q-2 -5 -5 -9t-7.5 -7t-8 -5.5t-9.5 -4
-l-10 -2.5t-12 -2l-12 -1.5t-13.5 -1t-13.5 -0.5q-106 -9 -163 11q-4 -17 -10 -26.5t-21 -15t-23 -7t-36 -3.5q-6 -1 -9 -1q-179 -17 -203 40q-2 -63 -56 -54q-47 8 -91 54q-12 13 -20 26q-17 29 -26 65q-58 -6 -87 -10q1 -2 4 -10zM507 -118q3 14 3 30q-17 71 -51 130
-t-73 70q-41 12 -101.5 -14.5t-104.5 -80t-39 -107.5q35 -53 100 -93t119 -42q51 -2 94 28t53 79zM510 53q23 -63 27 -119q195 113 392 174q-98 52 -180.5 120t-179.5 165q-6 -4 -29 -13q0 -1 -1 -4t-1 -5q31 -18 22 -37q-12 -23 -56 -34q-10 -13 -29 -24h-1q-2 -83 1 -150
-q19 -34 35 -73zM579 -113q532 -21 1145 0q-254 147 -428 196q-76 -35 -156 -57q-8 -3 -16 0q-65 21 -129 49q-208 -60 -416 -188h-1v-1q1 0 1 1zM1763 -67q4 54 28 120q14 38 33 71l-1 -1q3 77 3 153q-15 8 -30 25q-42 9 -56 33q-9 20 22 38q-2 4 -2 9q-16 4 -28 12
-q-204 -190 -383 -284q198 -59 414 -176zM2155 -90q5 54 -39 107.5t-104 80t-102 14.5q-38 -11 -72.5 -70.5t-51.5 -129.5q0 -16 3 -30q10 -49 53 -79t94 -28q54 2 119 42t100 93z" />
-    <glyph glyph-name="_538" unicode="&#xf23d;" horiz-adv-x="2304" 
-d="M1524 -25q0 -68 -48 -116t-116 -48t-116.5 48t-48.5 116t48.5 116.5t116.5 48.5t116 -48.5t48 -116.5zM775 -25q0 -68 -48.5 -116t-116.5 -48t-116 48t-48 116t48 116.5t116 48.5t116.5 -48.5t48.5 -116.5zM0 1469q57 -60 110.5 -104.5t121 -82t136 -63t166 -45.5
-t200 -31.5t250 -18.5t304 -9.5t372.5 -2.5q139 0 244.5 -5t181 -16.5t124 -27.5t71 -39.5t24 -51.5t-19.5 -64t-56.5 -76.5t-89.5 -91t-116 -104.5t-139 -119q-185 -157 -286 -247q29 51 76.5 109t94 105.5t94.5 98.5t83 91.5t54 80.5t13 70t-45.5 55.5t-116.5 41t-204 23.5
-t-304 5q-168 -2 -314 6t-256 23t-204.5 41t-159.5 51.5t-122.5 62.5t-91.5 66.5t-68 71.5t-50.5 69.5t-40 68t-36.5 59.5z" />
-    <glyph glyph-name="_539" unicode="&#xf23e;" horiz-adv-x="1792" 
-d="M896 1472q-169 0 -323 -66t-265.5 -177.5t-177.5 -265.5t-66 -323t66 -323t177.5 -265.5t265.5 -177.5t323 -66t323 66t265.5 177.5t177.5 265.5t66 323t-66 323t-177.5 265.5t-265.5 177.5t-323 66zM896 1536q182 0 348 -71t286 -191t191 -286t71 -348t-71 -348
-t-191 -286t-286 -191t-348 -71t-348 71t-286 191t-191 286t-71 348t71 348t191 286t286 191t348 71zM496 704q16 0 16 -16v-480q0 -16 -16 -16h-32q-16 0 -16 16v480q0 16 16 16h32zM896 640q53 0 90.5 -37.5t37.5 -90.5q0 -35 -17.5 -64t-46.5 -46v-114q0 -14 -9 -23
-t-23 -9h-64q-14 0 -23 9t-9 23v114q-29 17 -46.5 46t-17.5 64q0 53 37.5 90.5t90.5 37.5zM896 1408q209 0 385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103zM544 928v-96
-q0 -14 9 -23t23 -9h64q14 0 23 9t9 23v96q0 93 65.5 158.5t158.5 65.5t158.5 -65.5t65.5 -158.5v-96q0 -14 9 -23t23 -9h64q14 0 23 9t9 23v96q0 146 -103 249t-249 103t-249 -103t-103 -249zM1408 192v512q0 26 -19 45t-45 19h-896q-26 0 -45 -19t-19 -45v-512
-q0 -26 19 -45t45 -19h896q26 0 45 19t19 45z" />
-    <glyph glyph-name="_540" unicode="&#xf240;" horiz-adv-x="2304" 
-d="M1920 1024v-768h-1664v768h1664zM2048 448h128v384h-128v288q0 14 -9 23t-23 9h-1856q-14 0 -23 -9t-9 -23v-960q0 -14 9 -23t23 -9h1856q14 0 23 9t9 23v288zM2304 832v-384q0 -53 -37.5 -90.5t-90.5 -37.5v-160q0 -66 -47 -113t-113 -47h-1856q-66 0 -113 47t-47 113
-v960q0 66 47 113t113 47h1856q66 0 113 -47t47 -113v-160q53 0 90.5 -37.5t37.5 -90.5z" />
-    <glyph glyph-name="_541" unicode="&#xf241;" horiz-adv-x="2304" 
-d="M256 256v768h1280v-768h-1280zM2176 960q53 0 90.5 -37.5t37.5 -90.5v-384q0 -53 -37.5 -90.5t-90.5 -37.5v-160q0 -66 -47 -113t-113 -47h-1856q-66 0 -113 47t-47 113v960q0 66 47 113t113 47h1856q66 0 113 -47t47 -113v-160zM2176 448v384h-128v288q0 14 -9 23t-23 9
-h-1856q-14 0 -23 -9t-9 -23v-960q0 -14 9 -23t23 -9h1856q14 0 23 9t9 23v288h128z" />
-    <glyph glyph-name="_542" unicode="&#xf242;" horiz-adv-x="2304" 
-d="M256 256v768h896v-768h-896zM2176 960q53 0 90.5 -37.5t37.5 -90.5v-384q0 -53 -37.5 -90.5t-90.5 -37.5v-160q0 -66 -47 -113t-113 -47h-1856q-66 0 -113 47t-47 113v960q0 66 47 113t113 47h1856q66 0 113 -47t47 -113v-160zM2176 448v384h-128v288q0 14 -9 23t-23 9
-h-1856q-14 0 -23 -9t-9 -23v-960q0 -14 9 -23t23 -9h1856q14 0 23 9t9 23v288h128z" />
-    <glyph glyph-name="_543" unicode="&#xf243;" horiz-adv-x="2304" 
-d="M256 256v768h512v-768h-512zM2176 960q53 0 90.5 -37.5t37.5 -90.5v-384q0 -53 -37.5 -90.5t-90.5 -37.5v-160q0 -66 -47 -113t-113 -47h-1856q-66 0 -113 47t-47 113v960q0 66 47 113t113 47h1856q66 0 113 -47t47 -113v-160zM2176 448v384h-128v288q0 14 -9 23t-23 9
-h-1856q-14 0 -23 -9t-9 -23v-960q0 -14 9 -23t23 -9h1856q14 0 23 9t9 23v288h128z" />
-    <glyph glyph-name="_544" unicode="&#xf244;" horiz-adv-x="2304" 
-d="M2176 960q53 0 90.5 -37.5t37.5 -90.5v-384q0 -53 -37.5 -90.5t-90.5 -37.5v-160q0 -66 -47 -113t-113 -47h-1856q-66 0 -113 47t-47 113v960q0 66 47 113t113 47h1856q66 0 113 -47t47 -113v-160zM2176 448v384h-128v288q0 14 -9 23t-23 9h-1856q-14 0 -23 -9t-9 -23
-v-960q0 -14 9 -23t23 -9h1856q14 0 23 9t9 23v288h128z" />
-    <glyph glyph-name="_545" unicode="&#xf245;" horiz-adv-x="1280" 
-d="M1133 493q31 -30 14 -69q-17 -40 -59 -40h-382l201 -476q10 -25 0 -49t-34 -35l-177 -75q-25 -10 -49 0t-35 34l-191 452l-312 -312q-19 -19 -45 -19q-12 0 -24 5q-40 17 -40 59v1504q0 42 40 59q12 5 24 5q27 0 45 -19z" />
-    <glyph glyph-name="_546" unicode="&#xf246;" horiz-adv-x="1024" 
-d="M832 1408q-320 0 -320 -224v-416h128v-128h-128v-544q0 -224 320 -224h64v-128h-64q-272 0 -384 146q-112 -146 -384 -146h-64v128h64q320 0 320 224v544h-128v128h128v416q0 224 -320 224h-64v128h64q272 0 384 -146q112 146 384 146h64v-128h-64z" />
-    <glyph glyph-name="_547" unicode="&#xf247;" horiz-adv-x="2048" 
-d="M2048 1152h-128v-1024h128v-384h-384v128h-1280v-128h-384v384h128v1024h-128v384h384v-128h1280v128h384v-384zM1792 1408v-128h128v128h-128zM128 1408v-128h128v128h-128zM256 -128v128h-128v-128h128zM1664 0v128h128v1024h-128v128h-1280v-128h-128v-1024h128v-128
-h1280zM1920 -128v128h-128v-128h128zM1280 896h384v-768h-896v256h-384v768h896v-256zM512 512h640v512h-640v-512zM1536 256v512h-256v-384h-384v-128h640z" />
-    <glyph glyph-name="_548" unicode="&#xf248;" horiz-adv-x="2304" 
-d="M2304 768h-128v-640h128v-384h-384v128h-896v-128h-384v384h128v128h-384v-128h-384v384h128v640h-128v384h384v-128h896v128h384v-384h-128v-128h384v128h384v-384zM2048 1024v-128h128v128h-128zM1408 1408v-128h128v128h-128zM128 1408v-128h128v128h-128zM256 256
-v128h-128v-128h128zM1536 384h-128v-128h128v128zM384 384h896v128h128v640h-128v128h-896v-128h-128v-640h128v-128zM896 -128v128h-128v-128h128zM2176 -128v128h-128v-128h128zM2048 128v640h-128v128h-384v-384h128v-384h-384v128h-384v-128h128v-128h896v128h128z" />
-    <glyph glyph-name="_549" unicode="&#xf249;" 
-d="M1024 288v-416h-928q-40 0 -68 28t-28 68v1344q0 40 28 68t68 28h1344q40 0 68 -28t28 -68v-928h-416q-40 0 -68 -28t-28 -68zM1152 256h381q-15 -82 -65 -132l-184 -184q-50 -50 -132 -65v381z" />
-    <glyph glyph-name="_550" unicode="&#xf24a;" 
-d="M1400 256h-248v-248q29 10 41 22l185 185q12 12 22 41zM1120 384h288v896h-1280v-1280h896v288q0 40 28 68t68 28zM1536 1312v-1024q0 -40 -20 -88t-48 -76l-184 -184q-28 -28 -76 -48t-88 -20h-1024q-40 0 -68 28t-28 68v1344q0 40 28 68t68 28h1344q40 0 68 -28t28 -68
-z" />
-    <glyph glyph-name="_551" unicode="&#xf24b;" horiz-adv-x="2304" 
-d="M1951 538q0 -26 -15.5 -44.5t-38.5 -23.5q-8 -2 -18 -2h-153v140h153q10 0 18 -2q23 -5 38.5 -23.5t15.5 -44.5zM1933 751q0 -25 -15 -42t-38 -21q-3 -1 -15 -1h-139v129h139q3 0 8.5 -0.5t6.5 -0.5q23 -4 38 -21.5t15 -42.5zM728 587v308h-228v-308q0 -58 -38 -94.5
-t-105 -36.5q-108 0 -229 59v-112q53 -15 121 -23t109 -9l42 -1q328 0 328 217zM1442 403v113q-99 -52 -200 -59q-108 -8 -169 41t-61 142t61 142t169 41q101 -7 200 -58v112q-48 12 -100 19.5t-80 9.5l-28 2q-127 6 -218.5 -14t-140.5 -60t-71 -88t-22 -106t22 -106t71 -88
-t140.5 -60t218.5 -14q101 4 208 31zM2176 518q0 54 -43 88.5t-109 39.5v3q57 8 89 41.5t32 79.5q0 55 -41 88t-107 36q-3 0 -12 0.5t-14 0.5h-455v-510h491q74 0 121.5 36.5t47.5 96.5zM2304 1280v-1280q0 -52 -38 -90t-90 -38h-2048q-52 0 -90 38t-38 90v1280q0 52 38 90
-t90 38h2048q52 0 90 -38t38 -90z" />
-    <glyph glyph-name="_552" unicode="&#xf24c;" horiz-adv-x="2304" 
-d="M858 295v693q-106 -41 -172 -135.5t-66 -211.5t66 -211.5t172 -134.5zM1362 641q0 117 -66 211.5t-172 135.5v-694q106 41 172 135.5t66 211.5zM1577 641q0 -159 -78.5 -294t-213.5 -213.5t-294 -78.5q-119 0 -227.5 46.5t-187 125t-125 187t-46.5 227.5q0 159 78.5 294
-t213.5 213.5t294 78.5t294 -78.5t213.5 -213.5t78.5 -294zM1960 634q0 139 -55.5 261.5t-147.5 205.5t-213.5 131t-252.5 48h-301q-176 0 -323.5 -81t-235 -230t-87.5 -335q0 -171 87 -317.5t236 -231.5t323 -85h301q129 0 251.5 50.5t214.5 135t147.5 202.5t55.5 246z
-M2304 1280v-1280q0 -52 -38 -90t-90 -38h-2048q-52 0 -90 38t-38 90v1280q0 52 38 90t90 38h2048q52 0 90 -38t38 -90z" />
-    <glyph glyph-name="_553" unicode="&#xf24d;" horiz-adv-x="1792" 
-d="M1664 -96v1088q0 13 -9.5 22.5t-22.5 9.5h-1088q-13 0 -22.5 -9.5t-9.5 -22.5v-1088q0 -13 9.5 -22.5t22.5 -9.5h1088q13 0 22.5 9.5t9.5 22.5zM1792 992v-1088q0 -66 -47 -113t-113 -47h-1088q-66 0 -113 47t-47 113v1088q0 66 47 113t113 47h1088q66 0 113 -47t47 -113
-zM1408 1376v-160h-128v160q0 13 -9.5 22.5t-22.5 9.5h-1088q-13 0 -22.5 -9.5t-9.5 -22.5v-1088q0 -13 9.5 -22.5t22.5 -9.5h160v-128h-160q-66 0 -113 47t-47 113v1088q0 66 47 113t113 47h1088q66 0 113 -47t47 -113z" />
-    <glyph glyph-name="_554" unicode="&#xf24e;" horiz-adv-x="2304" 
-d="M1728 1088l-384 -704h768zM448 1088l-384 -704h768zM1269 1280q-14 -40 -45.5 -71.5t-71.5 -45.5v-1291h608q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-1344q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h608v1291q-40 14 -71.5 45.5t-45.5 71.5h-491q-14 0 -23 9t-9 23v64
-q0 14 9 23t23 9h491q21 57 70 92.5t111 35.5t111 -35.5t70 -92.5h491q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-491zM1088 1264q33 0 56.5 23.5t23.5 56.5t-23.5 56.5t-56.5 23.5t-56.5 -23.5t-23.5 -56.5t23.5 -56.5t56.5 -23.5zM2176 384q0 -73 -46.5 -131t-117.5 -91
-t-144.5 -49.5t-139.5 -16.5t-139.5 16.5t-144.5 49.5t-117.5 91t-46.5 131q0 11 35 81t92 174.5t107 195.5t102 184t56 100q18 33 56 33t56 -33q4 -7 56 -100t102 -184t107 -195.5t92 -174.5t35 -81zM896 384q0 -73 -46.5 -131t-117.5 -91t-144.5 -49.5t-139.5 -16.5
-t-139.5 16.5t-144.5 49.5t-117.5 91t-46.5 131q0 11 35 81t92 174.5t107 195.5t102 184t56 100q18 33 56 33t56 -33q4 -7 56 -100t102 -184t107 -195.5t92 -174.5t35 -81z" />
-    <glyph glyph-name="_555" unicode="&#xf250;" 
-d="M1408 1408q0 -261 -106.5 -461.5t-266.5 -306.5q160 -106 266.5 -306.5t106.5 -461.5h96q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-1472q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h96q0 261 106.5 461.5t266.5 306.5q-160 106 -266.5 306.5t-106.5 461.5h-96q-14 0 -23 9
-t-9 23v64q0 14 9 23t23 9h1472q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-96zM874 700q77 29 149 92.5t129.5 152.5t92.5 210t35 253h-1024q0 -132 35 -253t92.5 -210t129.5 -152.5t149 -92.5q19 -7 30.5 -23.5t11.5 -36.5t-11.5 -36.5t-30.5 -23.5q-77 -29 -149 -92.5
-t-129.5 -152.5t-92.5 -210t-35 -253h1024q0 132 -35 253t-92.5 210t-129.5 152.5t-149 92.5q-19 7 -30.5 23.5t-11.5 36.5t11.5 36.5t30.5 23.5z" />
-    <glyph glyph-name="_556" unicode="&#xf251;" 
-d="M1408 1408q0 -261 -106.5 -461.5t-266.5 -306.5q160 -106 266.5 -306.5t106.5 -461.5h96q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-1472q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h96q0 261 106.5 461.5t266.5 306.5q-160 106 -266.5 306.5t-106.5 461.5h-96q-14 0 -23 9
-t-9 23v64q0 14 9 23t23 9h1472q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-96zM1280 1408h-1024q0 -66 9 -128h1006q9 61 9 128zM1280 -128q0 130 -34 249.5t-90.5 208t-126.5 152t-146 94.5h-230q-76 -31 -146 -94.5t-126.5 -152t-90.5 -208t-34 -249.5h1024z" />
-    <glyph glyph-name="_557" unicode="&#xf252;" 
-d="M1408 1408q0 -261 -106.5 -461.5t-266.5 -306.5q160 -106 266.5 -306.5t106.5 -461.5h96q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-1472q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h96q0 261 106.5 461.5t266.5 306.5q-160 106 -266.5 306.5t-106.5 461.5h-96q-14 0 -23 9
-t-9 23v64q0 14 9 23t23 9h1472q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-96zM1280 1408h-1024q0 -206 85 -384h854q85 178 85 384zM1223 192q-54 141 -145.5 241.5t-194.5 142.5h-230q-103 -42 -194.5 -142.5t-145.5 -241.5h910z" />
-    <glyph glyph-name="_558" unicode="&#xf253;" 
-d="M1408 1408q0 -261 -106.5 -461.5t-266.5 -306.5q160 -106 266.5 -306.5t106.5 -461.5h96q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-1472q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h96q0 261 106.5 461.5t266.5 306.5q-160 106 -266.5 306.5t-106.5 461.5h-96q-14 0 -23 9
-t-9 23v64q0 14 9 23t23 9h1472q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-96zM874 700q77 29 149 92.5t129.5 152.5t92.5 210t35 253h-1024q0 -132 35 -253t92.5 -210t129.5 -152.5t149 -92.5q19 -7 30.5 -23.5t11.5 -36.5t-11.5 -36.5t-30.5 -23.5q-137 -51 -244 -196
-h700q-107 145 -244 196q-19 7 -30.5 23.5t-11.5 36.5t11.5 36.5t30.5 23.5z" />
-    <glyph glyph-name="_559" unicode="&#xf254;" 
-d="M1504 -64q14 0 23 -9t9 -23v-128q0 -14 -9 -23t-23 -9h-1472q-14 0 -23 9t-9 23v128q0 14 9 23t23 9h1472zM130 0q3 55 16 107t30 95t46 87t53.5 76t64.5 69.5t66 60t70.5 55t66.5 47.5t65 43q-43 28 -65 43t-66.5 47.5t-70.5 55t-66 60t-64.5 69.5t-53.5 76t-46 87
-t-30 95t-16 107h1276q-3 -55 -16 -107t-30 -95t-46 -87t-53.5 -76t-64.5 -69.5t-66 -60t-70.5 -55t-66.5 -47.5t-65 -43q43 -28 65 -43t66.5 -47.5t70.5 -55t66 -60t64.5 -69.5t53.5 -76t46 -87t30 -95t16 -107h-1276zM1504 1536q14 0 23 -9t9 -23v-128q0 -14 -9 -23t-23 -9
-h-1472q-14 0 -23 9t-9 23v128q0 14 9 23t23 9h1472z" />
-    <glyph glyph-name="_560" unicode="&#xf255;" 
-d="M768 1152q-53 0 -90.5 -37.5t-37.5 -90.5v-128h-32v93q0 48 -32 81.5t-80 33.5q-46 0 -79 -33t-33 -79v-429l-32 30v172q0 48 -32 81.5t-80 33.5q-46 0 -79 -33t-33 -79v-224q0 -47 35 -82l310 -296q39 -39 39 -102q0 -26 19 -45t45 -19h640q26 0 45 19t19 45v25
-q0 41 10 77l108 436q10 36 10 77v246q0 48 -32 81.5t-80 33.5q-46 0 -79 -33t-33 -79v-32h-32v125q0 40 -25 72.5t-64 40.5q-14 2 -23 2q-46 0 -79 -33t-33 -79v-128h-32v122q0 51 -32.5 89.5t-82.5 43.5q-5 1 -13 1zM768 1280q84 0 149 -50q57 34 123 34q59 0 111 -27
-t86 -76q27 7 59 7q100 0 170 -71.5t70 -171.5v-246q0 -51 -13 -108l-109 -436q-6 -24 -6 -71q0 -80 -56 -136t-136 -56h-640q-84 0 -138 58.5t-54 142.5l-308 296q-76 73 -76 175v224q0 99 70.5 169.5t169.5 70.5q11 0 16 -1q6 95 75.5 160t164.5 65q52 0 98 -21
-q72 69 174 69z" />
-    <glyph glyph-name="_561" unicode="&#xf256;" horiz-adv-x="1792" 
-d="M880 1408q-46 0 -79 -33t-33 -79v-656h-32v528q0 46 -33 79t-79 33t-79 -33t-33 -79v-528v-256l-154 205q-38 51 -102 51q-53 0 -90.5 -37.5t-37.5 -90.5q0 -43 26 -77l384 -512q38 -51 102 -51h688q34 0 61 22t34 56l76 405q5 32 5 59v498q0 46 -33 79t-79 33t-79 -33
-t-33 -79v-272h-32v528q0 46 -33 79t-79 33t-79 -33t-33 -79v-528h-32v656q0 46 -33 79t-79 33zM880 1536q68 0 125.5 -35.5t88.5 -96.5q19 4 42 4q99 0 169.5 -70.5t70.5 -169.5v-17q105 6 180.5 -64t75.5 -175v-498q0 -40 -8 -83l-76 -404q-14 -79 -76.5 -131t-143.5 -52
-h-688q-60 0 -114.5 27.5t-90.5 74.5l-384 512q-51 68 -51 154q0 106 75 181t181 75q78 0 128 -34v434q0 99 70.5 169.5t169.5 70.5q23 0 42 -4q31 61 88.5 96.5t125.5 35.5z" />
-    <glyph glyph-name="_562" unicode="&#xf257;" horiz-adv-x="1792" 
-d="M1073 -128h-177q-163 0 -226 141q-23 49 -23 102v5q-62 30 -98.5 88.5t-36.5 127.5q0 38 5 48h-261q-106 0 -181 75t-75 181t75 181t181 75h113l-44 17q-74 28 -119.5 93.5t-45.5 145.5q0 106 75 181t181 75q46 0 91 -17l628 -239h401q106 0 181 -75t75 -181v-668
-q0 -88 -54 -157.5t-140 -90.5l-339 -85q-92 -23 -186 -23zM1024 583l-155 -71l-163 -74q-30 -14 -48 -41.5t-18 -60.5q0 -46 33 -79t79 -33q26 0 46 10l338 154q-49 10 -80.5 50t-31.5 90v55zM1344 272q0 46 -33 79t-79 33q-26 0 -46 -10l-290 -132q-28 -13 -37 -17
-t-30.5 -17t-29.5 -23.5t-16 -29t-8 -40.5q0 -50 31.5 -82t81.5 -32q20 0 38 9l352 160q30 14 48 41.5t18 60.5zM1112 1024l-650 248q-24 8 -46 8q-53 0 -90.5 -37.5t-37.5 -90.5q0 -40 22.5 -73t59.5 -47l526 -200v-64h-640q-53 0 -90.5 -37.5t-37.5 -90.5t37.5 -90.5
-t90.5 -37.5h535l233 106v198q0 63 46 106l111 102h-69zM1073 0q82 0 155 19l339 85q43 11 70 45.5t27 78.5v668q0 53 -37.5 90.5t-90.5 37.5h-308l-136 -126q-36 -33 -36 -82v-296q0 -46 33 -77t79 -31t79 35t33 81v208h32v-208q0 -70 -57 -114q52 -8 86.5 -48.5t34.5 -93.5
-q0 -42 -23 -78t-61 -53l-310 -141h91z" />
-    <glyph glyph-name="_563" unicode="&#xf258;" horiz-adv-x="2048" 
-d="M1151 1536q61 0 116 -28t91 -77l572 -781q118 -159 118 -359v-355q0 -80 -56 -136t-136 -56h-384q-80 0 -136 56t-56 136v177l-286 143h-546q-80 0 -136 56t-56 136v32q0 119 84.5 203.5t203.5 84.5h420l42 128h-686q-100 0 -173.5 67.5t-81.5 166.5q-65 79 -65 182v32
-q0 80 56 136t136 56h959zM1920 -64v355q0 157 -93 284l-573 781q-39 52 -103 52h-959q-26 0 -45 -19t-19 -45q0 -32 1.5 -49.5t9.5 -40.5t25 -43q10 31 35.5 50t56.5 19h832v-32h-832q-26 0 -45 -19t-19 -45q0 -44 3 -58q8 -44 44 -73t81 -29h640h91q40 0 68 -28t28 -68
-q0 -15 -5 -30l-64 -192q-10 -29 -35 -47.5t-56 -18.5h-443q-66 0 -113 -47t-47 -113v-32q0 -26 19 -45t45 -19h561q16 0 29 -7l317 -158q24 -13 38.5 -36t14.5 -50v-197q0 -26 19 -45t45 -19h384q26 0 45 19t19 45z" />
-    <glyph glyph-name="_564" unicode="&#xf259;" horiz-adv-x="2048" 
-d="M459 -256q-77 0 -137.5 47.5t-79.5 122.5l-101 401q-13 57 -13 108q0 45 -5 67l-116 477q-7 27 -7 57q0 93 62 161t155 78q17 85 82.5 139t152.5 54q83 0 148 -51.5t85 -132.5l83 -348l103 428q20 81 85 132.5t148 51.5q89 0 155.5 -57.5t80.5 -144.5q92 -10 152 -79
-t60 -162q0 -24 -7 -59l-123 -512q10 7 37.5 28.5t38.5 29.5t35 23t41 20.5t41.5 11t49.5 5.5q105 0 180 -74t75 -179q0 -62 -28.5 -118t-78.5 -94l-507 -380q-68 -51 -153 -51h-694zM1104 1408q-38 0 -68.5 -24t-39.5 -62l-164 -682h-127l-145 602q-9 38 -39.5 62t-68.5 24
-q-48 0 -80 -33t-32 -80q0 -15 3 -28l132 -547h-26l-99 408q-9 37 -40 62.5t-69 25.5q-47 0 -80 -33t-33 -79q0 -14 3 -26l116 -478q7 -28 9 -86t10 -88l100 -401q8 -32 34 -52.5t59 -20.5h694q42 0 76 26l507 379q56 43 56 110q0 52 -37.5 88.5t-89.5 36.5q-43 0 -77 -26
-l-307 -230v227q0 4 32 138t68 282t39 161q4 18 4 29q0 47 -32 81t-79 34q-39 0 -69.5 -24t-39.5 -62l-116 -482h-26l150 624q3 14 3 28q0 48 -31.5 82t-79.5 34z" />
-    <glyph glyph-name="_565" unicode="&#xf25a;" horiz-adv-x="1792" 
-d="M640 1408q-53 0 -90.5 -37.5t-37.5 -90.5v-512v-384l-151 202q-41 54 -107 54q-52 0 -89 -38t-37 -90q0 -43 26 -77l384 -512q38 -51 102 -51h718q22 0 39.5 13.5t22.5 34.5l92 368q24 96 24 194v217q0 41 -28 71t-68 30t-68 -28t-28 -68h-32v61q0 48 -32 81.5t-80 33.5
-q-46 0 -79 -33t-33 -79v-64h-32v90q0 55 -37 94.5t-91 39.5q-53 0 -90.5 -37.5t-37.5 -90.5v-96h-32v570q0 55 -37 94.5t-91 39.5zM640 1536q107 0 181.5 -77.5t74.5 -184.5v-220q22 2 32 2q99 0 173 -69q47 21 99 21q113 0 184 -87q27 7 56 7q94 0 159 -67.5t65 -161.5
-v-217q0 -116 -28 -225l-92 -368q-16 -64 -68 -104.5t-118 -40.5h-718q-60 0 -114.5 27.5t-90.5 74.5l-384 512q-51 68 -51 154q0 105 74.5 180.5t179.5 75.5q71 0 130 -35v547q0 106 75 181t181 75zM768 128v384h-32v-384h32zM1024 128v384h-32v-384h32zM1280 128v384h-32
-v-384h32z" />
-    <glyph glyph-name="_566" unicode="&#xf25b;" 
-d="M1288 889q60 0 107 -23q141 -63 141 -226v-177q0 -94 -23 -186l-85 -339q-21 -86 -90.5 -140t-157.5 -54h-668q-106 0 -181 75t-75 181v401l-239 628q-17 45 -17 91q0 106 75 181t181 75q80 0 145.5 -45.5t93.5 -119.5l17 -44v113q0 106 75 181t181 75t181 -75t75 -181
-v-261q27 5 48 5q69 0 127.5 -36.5t88.5 -98.5zM1072 896q-33 0 -60.5 -18t-41.5 -48l-74 -163l-71 -155h55q50 0 90 -31.5t50 -80.5l154 338q10 20 10 46q0 46 -33 79t-79 33zM1293 761q-22 0 -40.5 -8t-29 -16t-23.5 -29.5t-17 -30.5t-17 -37l-132 -290q-10 -20 -10 -46
-q0 -46 33 -79t79 -33q33 0 60.5 18t41.5 48l160 352q9 18 9 38q0 50 -32 81.5t-82 31.5zM128 1120q0 -22 8 -46l248 -650v-69l102 111q43 46 106 46h198l106 233v535q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5v-640h-64l-200 526q-14 37 -47 59.5t-73 22.5
-q-53 0 -90.5 -37.5t-37.5 -90.5zM1180 -128q44 0 78.5 27t45.5 70l85 339q19 73 19 155v91l-141 -310q-17 -38 -53 -61t-78 -23q-53 0 -93.5 34.5t-48.5 86.5q-44 -57 -114 -57h-208v32h208q46 0 81 33t35 79t-31 79t-77 33h-296q-49 0 -82 -36l-126 -136v-308
-q0 -53 37.5 -90.5t90.5 -37.5h668z" />
-    <glyph glyph-name="_567" unicode="&#xf25c;" horiz-adv-x="1973" 
-d="M857 992v-117q0 -13 -9.5 -22t-22.5 -9h-298v-812q0 -13 -9 -22.5t-22 -9.5h-135q-13 0 -22.5 9t-9.5 23v812h-297q-13 0 -22.5 9t-9.5 22v117q0 14 9 23t23 9h793q13 0 22.5 -9.5t9.5 -22.5zM1895 995l77 -961q1 -13 -8 -24q-10 -10 -23 -10h-134q-12 0 -21 8.5
-t-10 20.5l-46 588l-189 -425q-8 -19 -29 -19h-120q-20 0 -29 19l-188 427l-45 -590q-1 -12 -10 -20.5t-21 -8.5h-135q-13 0 -23 10q-9 10 -9 24l78 961q1 12 10 20.5t21 8.5h142q20 0 29 -19l220 -520q10 -24 20 -51q3 7 9.5 24.5t10.5 26.5l221 520q9 19 29 19h141
-q13 0 22 -8.5t10 -20.5z" />
-    <glyph glyph-name="_568" unicode="&#xf25d;" horiz-adv-x="1792" 
-d="M1042 833q0 88 -60 121q-33 18 -117 18h-123v-281h162q66 0 102 37t36 105zM1094 548l205 -373q8 -17 -1 -31q-8 -16 -27 -16h-152q-20 0 -28 17l-194 365h-155v-350q0 -14 -9 -23t-23 -9h-134q-14 0 -23 9t-9 23v960q0 14 9 23t23 9h294q128 0 190 -24q85 -31 134 -109
-t49 -180q0 -92 -42.5 -165.5t-115.5 -109.5q6 -10 9 -16zM896 1376q-150 0 -286 -58.5t-234.5 -157t-157 -234.5t-58.5 -286t58.5 -286t157 -234.5t234.5 -157t286 -58.5t286 58.5t234.5 157t157 234.5t58.5 286t-58.5 286t-157 234.5t-234.5 157t-286 58.5zM1792 640
-q0 -182 -71 -348t-191 -286t-286 -191t-348 -71t-348 71t-286 191t-191 286t-71 348t71 348t191 286t286 191t348 71t348 -71t286 -191t191 -286t71 -348z" />
-    <glyph glyph-name="_569" unicode="&#xf25e;" horiz-adv-x="1792" 
-d="M605 303q153 0 257 104q14 18 3 36l-45 82q-6 13 -24 17q-16 2 -27 -11l-4 -3q-4 -4 -11.5 -10t-17.5 -13.5t-23.5 -14.5t-28.5 -13t-33.5 -9.5t-37.5 -3.5q-76 0 -125 50t-49 127q0 76 48 125.5t122 49.5q37 0 71.5 -14t50.5 -28l16 -14q11 -11 26 -10q16 2 24 14l53 78
-q13 20 -2 39q-3 4 -11 12t-30 23.5t-48.5 28t-67.5 22.5t-86 10q-148 0 -246 -96.5t-98 -240.5q0 -146 97 -241.5t247 -95.5zM1235 303q153 0 257 104q14 18 4 36l-45 82q-8 14 -25 17q-16 2 -27 -11l-4 -3q-4 -4 -11.5 -10t-17.5 -13.5t-23.5 -14.5t-28.5 -13t-33.5 -9.5
-t-37.5 -3.5q-76 0 -125 50t-49 127q0 76 48 125.5t122 49.5q37 0 71.5 -14t50.5 -28l16 -14q11 -11 26 -10q16 2 24 14l53 78q13 20 -2 39q-3 4 -11 12t-30 23.5t-48.5 28t-67.5 22.5t-86 10q-147 0 -245.5 -96.5t-98.5 -240.5q0 -146 97 -241.5t247 -95.5zM896 1376
-q-150 0 -286 -58.5t-234.5 -157t-157 -234.5t-58.5 -286t58.5 -286t157 -234.5t234.5 -157t286 -58.5t286 58.5t234.5 157t157 234.5t58.5 286t-58.5 286t-157 234.5t-234.5 157t-286 58.5zM896 1536q182 0 348 -71t286 -191t191 -286t71 -348t-71 -348t-191 -286t-286 -191
-t-348 -71t-348 71t-286 191t-191 286t-71 348t71 348t191 286t286 191t348 71z" />
-    <glyph glyph-name="f260" unicode="&#xf260;" horiz-adv-x="2048" 
-d="M736 736l384 -384l-384 -384l-672 672l672 672l168 -168l-96 -96l-72 72l-480 -480l480 -480l193 193l-289 287zM1312 1312l672 -672l-672 -672l-168 168l96 96l72 -72l480 480l-480 480l-193 -193l289 -287l-96 -96l-384 384z" />
-    <glyph glyph-name="f261" unicode="&#xf261;" horiz-adv-x="1792" 
-d="M717 182l271 271l-279 279l-88 -88l192 -191l-96 -96l-279 279l279 279l40 -40l87 87l-127 128l-454 -454zM1075 190l454 454l-454 454l-271 -271l279 -279l88 88l-192 191l96 96l279 -279l-279 -279l-40 40l-87 -88zM1792 640q0 -182 -71 -348t-191 -286t-286 -191
-t-348 -71t-348 71t-286 191t-191 286t-71 348t71 348t191 286t286 191t348 71t348 -71t286 -191t191 -286t71 -348z" />
-    <glyph glyph-name="_572" unicode="&#xf262;" horiz-adv-x="2304" 
-d="M651 539q0 -39 -27.5 -66.5t-65.5 -27.5q-39 0 -66.5 27.5t-27.5 66.5q0 38 27.5 65.5t66.5 27.5q38 0 65.5 -27.5t27.5 -65.5zM1805 540q0 -39 -27.5 -66.5t-66.5 -27.5t-66.5 27.5t-27.5 66.5t27.5 66t66.5 27t66.5 -27t27.5 -66zM765 539q0 79 -56.5 136t-136.5 57
-t-136.5 -56.5t-56.5 -136.5t56.5 -136.5t136.5 -56.5t136.5 56.5t56.5 136.5zM1918 540q0 80 -56.5 136.5t-136.5 56.5q-79 0 -136 -56.5t-57 -136.5t56.5 -136.5t136.5 -56.5t136.5 56.5t56.5 136.5zM850 539q0 -116 -81.5 -197.5t-196.5 -81.5q-116 0 -197.5 82t-81.5 197
-t82 196.5t197 81.5t196.5 -81.5t81.5 -196.5zM2004 540q0 -115 -81.5 -196.5t-197.5 -81.5q-115 0 -196.5 81.5t-81.5 196.5t81.5 196.5t196.5 81.5q116 0 197.5 -81.5t81.5 -196.5zM1040 537q0 191 -135.5 326.5t-326.5 135.5q-125 0 -231 -62t-168 -168.5t-62 -231.5
-t62 -231.5t168 -168.5t231 -62q191 0 326.5 135.5t135.5 326.5zM1708 1110q-254 111 -556 111q-319 0 -573 -110q117 0 223 -45.5t182.5 -122.5t122 -183t45.5 -223q0 115 43.5 219.5t118 180.5t177.5 123t217 50zM2187 537q0 191 -135 326.5t-326 135.5t-326.5 -135.5
-t-135.5 -326.5t135.5 -326.5t326.5 -135.5t326 135.5t135 326.5zM1921 1103h383q-44 -51 -75 -114.5t-40 -114.5q110 -151 110 -337q0 -156 -77 -288t-209 -208.5t-287 -76.5q-133 0 -249 56t-196 155q-47 -56 -129 -179q-11 22 -53.5 82.5t-74.5 97.5
-q-80 -99 -196.5 -155.5t-249.5 -56.5q-155 0 -287 76.5t-209 208.5t-77 288q0 186 110 337q-9 51 -40 114.5t-75 114.5h365q149 100 355 156.5t432 56.5q224 0 421 -56t348 -157z" />
-    <glyph glyph-name="f263" unicode="&#xf263;" horiz-adv-x="1280" 
-d="M640 629q-188 0 -321 133t-133 320q0 188 133 321t321 133t321 -133t133 -321q0 -187 -133 -320t-321 -133zM640 1306q-92 0 -157.5 -65.5t-65.5 -158.5q0 -92 65.5 -157.5t157.5 -65.5t157.5 65.5t65.5 157.5q0 93 -65.5 158.5t-157.5 65.5zM1163 574q13 -27 15 -49.5
-t-4.5 -40.5t-26.5 -38.5t-42.5 -37t-61.5 -41.5q-115 -73 -315 -94l73 -72l267 -267q30 -31 30 -74t-30 -73l-12 -13q-31 -30 -74 -30t-74 30q-67 68 -267 268l-267 -268q-31 -30 -74 -30t-73 30l-12 13q-31 30 -31 73t31 74l267 267l72 72q-203 21 -317 94
-q-39 25 -61.5 41.5t-42.5 37t-26.5 38.5t-4.5 40.5t15 49.5q10 20 28 35t42 22t56 -2t65 -35q5 -4 15 -11t43 -24.5t69 -30.5t92 -24t113 -11q91 0 174 25.5t120 50.5l38 25q33 26 65 35t56 2t42 -22t28 -35z" />
-    <glyph glyph-name="_574" unicode="&#xf264;" 
-d="M927 956q0 -66 -46.5 -112.5t-112.5 -46.5t-112.5 46.5t-46.5 112.5t46.5 112.5t112.5 46.5t112.5 -46.5t46.5 -112.5zM1141 593q-10 20 -28 32t-47.5 9.5t-60.5 -27.5q-10 -8 -29 -20t-81 -32t-127 -20t-124 18t-86 36l-27 18q-31 25 -60.5 27.5t-47.5 -9.5t-28 -32
-q-22 -45 -2 -74.5t87 -73.5q83 -53 226 -67l-51 -52q-142 -142 -191 -190q-22 -22 -22 -52.5t22 -52.5l9 -9q22 -22 52.5 -22t52.5 22l191 191q114 -115 191 -191q22 -22 52.5 -22t52.5 22l9 9q22 22 22 52.5t-22 52.5l-191 190l-52 52q141 14 225 67q67 44 87 73.5t-2 74.5
-zM1092 956q0 134 -95 229t-229 95t-229 -95t-95 -229t95 -229t229 -95t229 95t95 229zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
-    <glyph glyph-name="_575" unicode="&#xf265;" horiz-adv-x="1720" 
-d="M1565 1408q65 0 110 -45.5t45 -110.5v-519q0 -176 -68 -336t-182.5 -275t-274 -182.5t-334.5 -67.5q-176 0 -335.5 67.5t-274.5 182.5t-183 275t-68 336v519q0 64 46 110t110 46h1409zM861 344q47 0 82 33l404 388q37 35 37 85q0 49 -34.5 83.5t-83.5 34.5q-47 0 -82 -33
-l-323 -310l-323 310q-35 33 -81 33q-49 0 -83.5 -34.5t-34.5 -83.5q0 -51 36 -85l405 -388q33 -33 81 -33z" />
-    <glyph glyph-name="_576" unicode="&#xf266;" horiz-adv-x="2304" 
-d="M1494 -103l-295 695q-25 -49 -158.5 -305.5t-198.5 -389.5q-1 -1 -27.5 -0.5t-26.5 1.5q-82 193 -255.5 587t-259.5 596q-21 50 -66.5 107.5t-103.5 100.5t-102 43q0 5 -0.5 24t-0.5 27h583v-50q-39 -2 -79.5 -16t-66.5 -43t-10 -64q26 -59 216.5 -499t235.5 -540
-q31 61 140 266.5t131 247.5q-19 39 -126 281t-136 295q-38 69 -201 71v50l513 -1v-47q-60 -2 -93.5 -25t-12.5 -69q33 -70 87 -189.5t86 -187.5q110 214 173 363q24 55 -10 79.5t-129 26.5q1 7 1 25v24q64 0 170.5 0.5t180 1t92.5 0.5v-49q-62 -2 -119 -33t-90 -81
-l-213 -442q13 -33 127.5 -290t121.5 -274l441 1017q-14 38 -49.5 62.5t-65 31.5t-55.5 8v50l460 -4l1 -2l-1 -44q-139 -4 -201 -145q-526 -1216 -559 -1291h-49z" />
-    <glyph glyph-name="_577" unicode="&#xf267;" horiz-adv-x="1792" 
-d="M949 643q0 -26 -16.5 -45t-41.5 -19q-26 0 -45 16.5t-19 41.5q0 26 17 45t42 19t44 -16.5t19 -41.5zM964 585l350 581q-9 -8 -67.5 -62.5t-125.5 -116.5t-136.5 -127t-117 -110.5t-50.5 -51.5l-349 -580q7 7 67 62t126 116.5t136 127t117 111t50 50.5zM1611 640
-q0 -201 -104 -371q-3 2 -17 11t-26.5 16.5t-16.5 7.5q-13 0 -13 -13q0 -10 59 -44q-74 -112 -184.5 -190.5t-241.5 -110.5l-16 67q-1 10 -15 10q-5 0 -8 -5.5t-2 -9.5l16 -68q-72 -15 -146 -15q-199 0 -372 105q1 2 13 20.5t21.5 33.5t9.5 19q0 13 -13 13q-6 0 -17 -14.5
-t-22.5 -34.5t-13.5 -23q-113 75 -192 187.5t-110 244.5l69 15q10 3 10 15q0 5 -5.5 8t-10.5 2l-68 -15q-14 72 -14 139q0 206 109 379q2 -1 18.5 -12t30 -19t17.5 -8q13 0 13 12q0 6 -12.5 15.5t-32.5 21.5l-20 12q77 112 189 189t244 107l15 -67q2 -10 15 -10q5 0 8 5.5
-t2 10.5l-15 66q71 13 134 13q204 0 379 -109q-39 -56 -39 -65q0 -13 12 -13q11 0 48 64q111 -75 187.5 -186t107.5 -241l-56 -12q-10 -2 -10 -16q0 -5 5.5 -8t9.5 -2l57 13q14 -72 14 -140zM1696 640q0 163 -63.5 311t-170.5 255t-255 170.5t-311 63.5t-311 -63.5
-t-255 -170.5t-170.5 -255t-63.5 -311t63.5 -311t170.5 -255t255 -170.5t311 -63.5t311 63.5t255 170.5t170.5 255t63.5 311zM1792 640q0 -182 -71 -348t-191 -286t-286 -191t-348 -71t-348 71t-286 191t-191 286t-71 348t71 348t191 286t286 191t348 71t348 -71t286 -191
-t191 -286t71 -348z" />
-    <glyph glyph-name="_578" unicode="&#xf268;" horiz-adv-x="1792" 
-d="M893 1536q240 2 451 -120q232 -134 352 -372l-742 39q-160 9 -294 -74.5t-185 -229.5l-276 424q128 159 311 245.5t383 87.5zM146 1131l337 -663q72 -143 211 -217t293 -45l-230 -451q-212 33 -385 157.5t-272.5 316t-99.5 411.5q0 267 146 491zM1732 962
-q58 -150 59.5 -310.5t-48.5 -306t-153 -272t-246 -209.5q-230 -133 -498 -119l405 623q88 131 82.5 290.5t-106.5 277.5zM896 942q125 0 213.5 -88.5t88.5 -213.5t-88.5 -213.5t-213.5 -88.5t-213.5 88.5t-88.5 213.5t88.5 213.5t213.5 88.5z" />
-    <glyph glyph-name="_579" unicode="&#xf269;" horiz-adv-x="1792" 
-d="M903 -256q-283 0 -504.5 150.5t-329.5 398.5q-58 131 -67 301t26 332.5t111 312t179 242.5l-11 -281q11 14 68 15.5t70 -15.5q42 81 160.5 138t234.5 59q-54 -45 -119.5 -148.5t-58.5 -163.5q25 -8 62.5 -13.5t63 -7.5t68 -4t50.5 -3q15 -5 9.5 -45.5t-30.5 -75.5
-q-5 -7 -16.5 -18.5t-56.5 -35.5t-101 -34l15 -189l-139 67q-18 -43 -7.5 -81.5t36 -66.5t65.5 -41.5t81 -6.5q51 9 98 34.5t83.5 45t73.5 17.5q61 -4 89.5 -33t19.5 -65q-1 -2 -2.5 -5.5t-8.5 -12.5t-18 -15.5t-31.5 -10.5t-46.5 -1q-60 -95 -144.5 -135.5t-209.5 -29.5
-q74 -61 162.5 -82.5t168.5 -6t154.5 52t128 87.5t80.5 104q43 91 39 192.5t-37.5 188.5t-78.5 125q87 -38 137 -79.5t77 -112.5q15 170 -57.5 343t-209.5 284q265 -77 412 -279.5t151 -517.5q2 -127 -40.5 -255t-123.5 -238t-189 -196t-247.5 -135.5t-288.5 -49.5z" />
-    <glyph glyph-name="_580" unicode="&#xf26a;" horiz-adv-x="1792" 
-d="M1493 1308q-165 110 -359 110q-155 0 -293 -73t-240 -200q-75 -93 -119.5 -218t-48.5 -266v-42q4 -141 48.5 -266t119.5 -218q102 -127 240 -200t293 -73q194 0 359 110q-121 -108 -274.5 -168t-322.5 -60q-29 0 -43 1q-175 8 -333 82t-272 193t-181 281t-67 339
-q0 182 71 348t191 286t286 191t348 71h3q168 -1 320.5 -60.5t273.5 -167.5zM1792 640q0 -192 -77 -362.5t-213 -296.5q-104 -63 -222 -63q-137 0 -255 84q154 56 253.5 233t99.5 405q0 227 -99 404t-253 234q119 83 254 83q119 0 226 -65q135 -125 210.5 -295t75.5 -361z
-" />
-    <glyph glyph-name="_581" unicode="&#xf26b;" horiz-adv-x="1792" 
-d="M1792 599q0 -56 -7 -104h-1151q0 -146 109.5 -244.5t257.5 -98.5q99 0 185.5 46.5t136.5 130.5h423q-56 -159 -170.5 -281t-267.5 -188.5t-321 -66.5q-187 0 -356 83q-228 -116 -394 -116q-237 0 -237 263q0 115 45 275q17 60 109 229q199 360 475 606
-q-184 -79 -427 -354q63 274 283.5 449.5t501.5 175.5q30 0 45 -1q255 117 433 117q64 0 116 -13t94.5 -40.5t66.5 -76.5t24 -115q0 -116 -75 -286q101 -182 101 -390zM1722 1239q0 83 -53 132t-137 49q-108 0 -254 -70q121 -47 222.5 -131.5t170.5 -195.5q51 135 51 216z
-M128 2q0 -86 48.5 -132.5t134.5 -46.5q115 0 266 83q-122 72 -213.5 183t-137.5 245q-98 -205 -98 -332zM632 715h728q-5 142 -113 237t-251 95q-144 0 -251.5 -95t-112.5 -237z" />
-    <glyph glyph-name="_582" unicode="&#xf26c;" horiz-adv-x="2048" 
-d="M1792 288v960q0 13 -9.5 22.5t-22.5 9.5h-1600q-13 0 -22.5 -9.5t-9.5 -22.5v-960q0 -13 9.5 -22.5t22.5 -9.5h1600q13 0 22.5 9.5t9.5 22.5zM1920 1248v-960q0 -66 -47 -113t-113 -47h-736v-128h352q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-832q-14 0 -23 9t-9 23
-v64q0 14 9 23t23 9h352v128h-736q-66 0 -113 47t-47 113v960q0 66 47 113t113 47h1600q66 0 113 -47t47 -113z" />
-    <glyph glyph-name="_583" unicode="&#xf26d;" horiz-adv-x="1792" 
-d="M138 1408h197q-70 -64 -126 -149q-36 -56 -59 -115t-30 -125.5t-8.5 -120t10.5 -132t21 -126t28 -136.5q4 -19 6 -28q51 -238 81 -329q57 -171 152 -275h-272q-48 0 -82 34t-34 82v1304q0 48 34 82t82 34zM1346 1408h308q48 0 82 -34t34 -82v-1304q0 -48 -34 -82t-82 -34
-h-178q212 210 196 565l-469 -101q-2 -45 -12 -82t-31 -72t-59.5 -59.5t-93.5 -36.5q-123 -26 -199 40q-32 27 -53 61t-51.5 129t-64.5 258q-35 163 -45.5 263t-5.5 139t23 77q20 41 62.5 73t102.5 45q45 12 83.5 6.5t67 -17t54 -35t43 -48t34.5 -56.5l468 100
-q-68 175 -180 287z" />
-    <glyph glyph-name="_584" unicode="&#xf26e;" 
-d="M1401 -11l-6 -6q-113 -113 -259 -175q-154 -64 -317 -64q-165 0 -317 64q-148 63 -259 175q-113 112 -175 258q-42 103 -54 189q-4 28 48 36q51 8 56 -20q1 -1 1 -4q18 -90 46 -159q50 -124 152 -226q98 -98 226 -152q132 -56 276 -56q143 0 276 56q128 55 225 152l6 6
-q10 10 25 6q12 -3 33 -22q36 -37 17 -58zM929 604l-66 -66l63 -63q21 -21 -7 -49q-17 -17 -32 -17q-10 0 -19 10l-62 61l-66 -66q-5 -5 -15 -5q-15 0 -31 16l-2 2q-18 15 -18 29q0 7 8 17l66 65l-66 66q-16 16 14 45q18 18 31 18q6 0 13 -5l65 -66l65 65q18 17 48 -13
-q27 -27 11 -44zM1400 547q0 -118 -46 -228q-45 -105 -126 -186q-80 -80 -187 -126t-228 -46t-228 46t-187 126q-82 82 -125 186q-15 33 -15 40h-1q-9 27 43 44q50 16 60 -12q37 -99 97 -167h1v339v2q3 136 102 232q105 103 253 103q147 0 251 -103t104 -249
-q0 -147 -104.5 -251t-250.5 -104q-58 0 -112 16q-28 11 -13 61q16 51 44 43l14 -3q14 -3 33 -6t30 -3q104 0 176 71.5t72 174.5q0 101 -72 171q-71 71 -175 71q-107 0 -178 -80q-64 -72 -64 -160v-413q110 -67 242 -67q96 0 185 36.5t156 103.5t103.5 155t36.5 183
-q0 198 -141 339q-140 140 -339 140q-200 0 -340 -140q-53 -53 -77 -87l-2 -2q-8 -11 -13 -15.5t-21.5 -9.5t-38.5 3q-21 5 -36.5 16.5t-15.5 26.5v680q0 15 10.5 26.5t27.5 11.5h877q30 0 30 -55t-30 -55h-811v-483h1q40 42 102 84t108 61q109 46 231 46q121 0 228 -46
-t187 -126q81 -81 126 -186q46 -112 46 -229zM1369 1128q9 -8 9 -18t-5.5 -18t-16.5 -21q-26 -26 -39 -26q-9 0 -16 7q-106 91 -207 133q-128 56 -276 56q-133 0 -262 -49q-27 -10 -45 37q-9 25 -8 38q3 16 16 20q130 57 299 57q164 0 316 -64q137 -58 235 -152z" />
-    <glyph glyph-name="_585" unicode="&#xf270;" horiz-adv-x="1792" 
-d="M1551 60q15 6 26 3t11 -17.5t-15 -33.5q-13 -16 -44 -43.5t-95.5 -68t-141 -74t-188 -58t-229.5 -24.5q-119 0 -238 31t-209 76.5t-172.5 104t-132.5 105t-84 87.5q-8 9 -10 16.5t1 12t8 7t11.5 2t11.5 -4.5q192 -117 300 -166q389 -176 799 -90q190 40 391 135z
-M1758 175q11 -16 2.5 -69.5t-28.5 -102.5q-34 -83 -85 -124q-17 -14 -26 -9t0 24q21 45 44.5 121.5t6.5 98.5q-5 7 -15.5 11.5t-27 6t-29.5 2.5t-35 0t-31.5 -2t-31 -3t-22.5 -2q-6 -1 -13 -1.5t-11 -1t-8.5 -1t-7 -0.5h-5.5h-4.5t-3 0.5t-2 1.5l-1.5 3q-6 16 47 40t103 30
-q46 7 108 1t76 -24zM1364 618q0 -31 13.5 -64t32 -58t37.5 -46t33 -32l13 -11l-227 -224q-40 37 -79 75.5t-58 58.5l-19 20q-11 11 -25 33q-38 -59 -97.5 -102.5t-127.5 -63.5t-140 -23t-137.5 21t-117.5 65.5t-83 113t-31 162.5q0 84 28 154t72 116.5t106.5 83t122.5 57
-t130 34.5t119.5 18.5t99.5 6.5v127q0 65 -21 97q-34 53 -121 53q-6 0 -16.5 -1t-40.5 -12t-56 -29.5t-56 -59.5t-48 -96l-294 27q0 60 22 119t67 113t108 95t151.5 65.5t190.5 24.5q100 0 181 -25t129.5 -61.5t81 -83t45 -86t12.5 -73.5v-589zM692 597q0 -86 70 -133
-q66 -44 139 -22q84 25 114 123q14 45 14 101v162q-59 -2 -111 -12t-106.5 -33.5t-87 -71t-32.5 -114.5z" />
-    <glyph glyph-name="_586" unicode="&#xf271;" horiz-adv-x="1792" 
-d="M1536 1280q52 0 90 -38t38 -90v-1280q0 -52 -38 -90t-90 -38h-1408q-52 0 -90 38t-38 90v1280q0 52 38 90t90 38h128v96q0 66 47 113t113 47h64q66 0 113 -47t47 -113v-96h384v96q0 66 47 113t113 47h64q66 0 113 -47t47 -113v-96h128zM1152 1376v-288q0 -14 9 -23t23 -9
-h64q14 0 23 9t9 23v288q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23zM384 1376v-288q0 -14 9 -23t23 -9h64q14 0 23 9t9 23v288q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23zM1536 -128v1024h-1408v-1024h1408zM896 448h224q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-224
-v-224q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v224h-224q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h224v224q0 14 9 23t23 9h64q14 0 23 -9t9 -23v-224z" />
-    <glyph glyph-name="_587" unicode="&#xf272;" horiz-adv-x="1792" 
-d="M1152 416v-64q0 -14 -9 -23t-23 -9h-576q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h576q14 0 23 -9t9 -23zM128 -128h1408v1024h-1408v-1024zM512 1088v288q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-288q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM1280 1088v288q0 14 -9 23
-t-23 9h-64q-14 0 -23 -9t-9 -23v-288q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM1664 1152v-1280q0 -52 -38 -90t-90 -38h-1408q-52 0 -90 38t-38 90v1280q0 52 38 90t90 38h128v96q0 66 47 113t113 47h64q66 0 113 -47t47 -113v-96h384v96q0 66 47 113t113 47h64q66 0 113 -47
-t47 -113v-96h128q52 0 90 -38t38 -90z" />
-    <glyph glyph-name="_588" unicode="&#xf273;" horiz-adv-x="1792" 
-d="M1111 151l-46 -46q-9 -9 -22 -9t-23 9l-188 189l-188 -189q-10 -9 -23 -9t-22 9l-46 46q-9 9 -9 22t9 23l189 188l-189 188q-9 10 -9 23t9 22l46 46q9 9 22 9t23 -9l188 -188l188 188q10 9 23 9t22 -9l46 -46q9 -9 9 -22t-9 -23l-188 -188l188 -188q9 -10 9 -23t-9 -22z
-M128 -128h1408v1024h-1408v-1024zM512 1088v288q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-288q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM1280 1088v288q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-288q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM1664 1152v-1280
-q0 -52 -38 -90t-90 -38h-1408q-52 0 -90 38t-38 90v1280q0 52 38 90t90 38h128v96q0 66 47 113t113 47h64q66 0 113 -47t47 -113v-96h384v96q0 66 47 113t113 47h64q66 0 113 -47t47 -113v-96h128q52 0 90 -38t38 -90z" />
-    <glyph glyph-name="_589" unicode="&#xf274;" horiz-adv-x="1792" 
-d="M1303 572l-512 -512q-10 -9 -23 -9t-23 9l-288 288q-9 10 -9 23t9 22l46 46q9 9 22 9t23 -9l220 -220l444 444q10 9 23 9t22 -9l46 -46q9 -9 9 -22t-9 -23zM128 -128h1408v1024h-1408v-1024zM512 1088v288q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-288q0 -14 9 -23
-t23 -9h64q14 0 23 9t9 23zM1280 1088v288q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-288q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM1664 1152v-1280q0 -52 -38 -90t-90 -38h-1408q-52 0 -90 38t-38 90v1280q0 52 38 90t90 38h128v96q0 66 47 113t113 47h64q66 0 113 -47
-t47 -113v-96h384v96q0 66 47 113t113 47h64q66 0 113 -47t47 -113v-96h128q52 0 90 -38t38 -90z" />
-    <glyph glyph-name="_590" unicode="&#xf275;" horiz-adv-x="1792" 
-d="M448 1536q26 0 45 -19t19 -45v-891l536 429q17 14 40 14q26 0 45 -19t19 -45v-379l536 429q17 14 40 14q26 0 45 -19t19 -45v-1152q0 -26 -19 -45t-45 -19h-1664q-26 0 -45 19t-19 45v1664q0 26 19 45t45 19h384z" />
-    <glyph glyph-name="_591" unicode="&#xf276;" horiz-adv-x="1024" 
-d="M512 448q66 0 128 15v-655q0 -26 -19 -45t-45 -19h-128q-26 0 -45 19t-19 45v655q62 -15 128 -15zM512 1536q212 0 362 -150t150 -362t-150 -362t-362 -150t-362 150t-150 362t150 362t362 150zM512 1312q14 0 23 9t9 23t-9 23t-23 9q-146 0 -249 -103t-103 -249
-q0 -14 9 -23t23 -9t23 9t9 23q0 119 84.5 203.5t203.5 84.5z" />
-    <glyph glyph-name="_592" unicode="&#xf277;" horiz-adv-x="1792" 
-d="M1745 1239q10 -10 10 -23t-10 -23l-141 -141q-28 -28 -68 -28h-1344q-26 0 -45 19t-19 45v256q0 26 19 45t45 19h576v64q0 26 19 45t45 19h128q26 0 45 -19t19 -45v-64h512q40 0 68 -28zM768 320h256v-512q0 -26 -19 -45t-45 -19h-128q-26 0 -45 19t-19 45v512zM1600 768
-q26 0 45 -19t19 -45v-256q0 -26 -19 -45t-45 -19h-1344q-40 0 -68 28l-141 141q-10 10 -10 23t10 23l141 141q28 28 68 28h512v192h256v-192h576z" />
-    <glyph glyph-name="_593" unicode="&#xf278;" horiz-adv-x="2048" 
-d="M2020 1525q28 -20 28 -53v-1408q0 -20 -11 -36t-29 -23l-640 -256q-24 -11 -48 0l-616 246l-616 -246q-10 -5 -24 -5q-19 0 -36 11q-28 20 -28 53v1408q0 20 11 36t29 23l640 256q24 11 48 0l616 -246l616 246q32 13 60 -6zM736 1390v-1270l576 -230v1270zM128 1173
-v-1270l544 217v1270zM1920 107v1270l-544 -217v-1270z" />
-    <glyph glyph-name="_594" unicode="&#xf279;" horiz-adv-x="1792" 
-d="M512 1536q13 0 22.5 -9.5t9.5 -22.5v-1472q0 -20 -17 -28l-480 -256q-7 -4 -15 -4q-13 0 -22.5 9.5t-9.5 22.5v1472q0 20 17 28l480 256q7 4 15 4zM1760 1536q13 0 22.5 -9.5t9.5 -22.5v-1472q0 -20 -17 -28l-480 -256q-7 -4 -15 -4q-13 0 -22.5 9.5t-9.5 22.5v1472
-q0 20 17 28l480 256q7 4 15 4zM640 1536q8 0 14 -3l512 -256q18 -10 18 -29v-1472q0 -13 -9.5 -22.5t-22.5 -9.5q-8 0 -14 3l-512 256q-18 10 -18 29v1472q0 13 9.5 22.5t22.5 9.5z" />
-    <glyph glyph-name="_595" unicode="&#xf27a;" horiz-adv-x="1792" 
-d="M640 640q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1024 640q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1408 640q0 53 -37.5 90.5t-90.5 37.5
-t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1792 640q0 -174 -120 -321.5t-326 -233t-450 -85.5q-110 0 -211 18q-173 -173 -435 -229q-52 -10 -86 -13q-12 -1 -22 6t-13 18q-4 15 20 37q5 5 23.5 21.5t25.5 23.5t23.5 25.5t24 31.5t20.5 37
-t20 48t14.5 57.5t12.5 72.5q-146 90 -229.5 216.5t-83.5 269.5q0 174 120 321.5t326 233t450 85.5t450 -85.5t326 -233t120 -321.5z" />
-    <glyph glyph-name="_596" unicode="&#xf27b;" horiz-adv-x="1792" 
-d="M640 640q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1024 640q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1408 640q0 -53 -37.5 -90.5t-90.5 -37.5
-t-90.5 37.5t-37.5 90.5t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM896 1152q-204 0 -381.5 -69.5t-282 -187.5t-104.5 -255q0 -112 71.5 -213.5t201.5 -175.5l87 -50l-27 -96q-24 -91 -70 -172q152 63 275 171l43 38l57 -6q69 -8 130 -8q204 0 381.5 69.5t282 187.5
-t104.5 255t-104.5 255t-282 187.5t-381.5 69.5zM1792 640q0 -174 -120 -321.5t-326 -233t-450 -85.5q-70 0 -145 8q-198 -175 -460 -242q-49 -14 -114 -22h-5q-15 0 -27 10.5t-16 27.5v1q-3 4 -0.5 12t2 10t4.5 9.5l6 9t7 8.5t8 9q7 8 31 34.5t34.5 38t31 39.5t32.5 51
-t27 59t26 76q-157 89 -247.5 220t-90.5 281q0 130 71 248.5t191 204.5t286 136.5t348 50.5t348 -50.5t286 -136.5t191 -204.5t71 -248.5z" />
-    <glyph glyph-name="_597" unicode="&#xf27c;" horiz-adv-x="1024" 
-d="M512 345l512 295v-591l-512 -296v592zM0 640v-591l512 296zM512 1527v-591l-512 -296v591zM512 936l512 295v-591z" />
-    <glyph glyph-name="_598" unicode="&#xf27d;" horiz-adv-x="1792" 
-d="M1709 1018q-10 -236 -332 -651q-333 -431 -562 -431q-142 0 -240 263q-44 160 -132 482q-72 262 -157 262q-18 0 -127 -76l-77 98q24 21 108 96.5t130 115.5q156 138 241 146q95 9 153 -55.5t81 -203.5q44 -287 66 -373q55 -249 120 -249q51 0 154 161q101 161 109 246
-q13 139 -109 139q-57 0 -121 -26q120 393 459 382q251 -8 236 -326z" />
-    <glyph glyph-name="f27e" unicode="&#xf27e;" 
-d="M0 1408h1536v-1536h-1536v1536zM1085 293l-221 631l221 297h-634l221 -297l-221 -631l317 -304z" />
-    <glyph glyph-name="uniF280" unicode="&#xf280;" 
-d="M0 1408h1536v-1536h-1536v1536zM908 1088l-12 -33l75 -83l-31 -114l25 -25l107 57l107 -57l25 25l-31 114l75 83l-12 33h-95l-53 96h-32l-53 -96h-95zM641 925q32 0 44.5 -16t11.5 -63l174 21q0 55 -17.5 92.5t-50.5 56t-69 25.5t-85 7q-133 0 -199 -57.5t-66 -182.5v-72
-h-96v-128h76q20 0 20 -8v-382q0 -14 -5 -20t-18 -7l-73 -7v-88h448v86l-149 14q-6 1 -8.5 1.5t-3.5 2.5t-0.5 4t1 7t0.5 10v387h191l38 128h-231q-6 0 -2 6t4 9v80q0 27 1.5 40.5t7.5 28t19.5 20t36.5 5.5zM1248 96v86l-54 9q-7 1 -9.5 2.5t-2.5 3t1 7.5t1 12v520h-275
-l-23 -101l83 -22q23 -7 23 -27v-370q0 -14 -6 -18.5t-20 -6.5l-70 -9v-86h352z" />
-    <glyph glyph-name="uniF281" unicode="&#xf281;" horiz-adv-x="1792" 
-d="M1792 690q0 -58 -29.5 -105.5t-79.5 -72.5q12 -46 12 -96q0 -155 -106.5 -287t-290.5 -208.5t-400 -76.5t-399.5 76.5t-290 208.5t-106.5 287q0 47 11 94q-51 25 -82 73.5t-31 106.5q0 82 58 140.5t141 58.5q85 0 145 -63q218 152 515 162l116 521q3 13 15 21t26 5
-l369 -81q18 37 54 59.5t79 22.5q62 0 106 -43.5t44 -105.5t-44 -106t-106 -44t-105.5 43.5t-43.5 105.5l-334 74l-104 -472q300 -9 519 -160q58 61 143 61q83 0 141 -58.5t58 -140.5zM418 491q0 -62 43.5 -106t105.5 -44t106 44t44 106t-44 105.5t-106 43.5q-61 0 -105 -44
-t-44 -105zM1228 136q11 11 11 26t-11 26q-10 10 -25 10t-26 -10q-41 -42 -121 -62t-160 -20t-160 20t-121 62q-11 10 -26 10t-25 -10q-11 -10 -11 -25.5t11 -26.5q43 -43 118.5 -68t122.5 -29.5t91 -4.5t91 4.5t122.5 29.5t118.5 68zM1225 341q62 0 105.5 44t43.5 106
-q0 61 -44 105t-105 44q-62 0 -106 -43.5t-44 -105.5t44 -106t106 -44z" />
-    <glyph glyph-name="_602" unicode="&#xf282;" horiz-adv-x="1792" 
-d="M69 741h1q16 126 58.5 241.5t115 217t167.5 176t223.5 117.5t276.5 43q231 0 414 -105.5t294 -303.5q104 -187 104 -442v-188h-1125q1 -111 53.5 -192.5t136.5 -122.5t189.5 -57t213 -3t208 46.5t173.5 84.5v-377q-92 -55 -229.5 -92t-312.5 -38t-316 53
-q-189 73 -311.5 249t-124.5 372q-3 242 111 412t325 268q-48 -60 -78 -125.5t-46 -159.5h635q8 77 -8 140t-47 101.5t-70.5 66.5t-80.5 41t-75 20.5t-56 8.5l-22 1q-135 -5 -259.5 -44.5t-223.5 -104.5t-176 -140.5t-138 -163.5z" />
-    <glyph glyph-name="_603" unicode="&#xf283;" horiz-adv-x="2304" 
-d="M0 32v608h2304v-608q0 -66 -47 -113t-113 -47h-1984q-66 0 -113 47t-47 113zM640 256v-128h384v128h-384zM256 256v-128h256v128h-256zM2144 1408q66 0 113 -47t47 -113v-224h-2304v224q0 66 47 113t113 47h1984z" />
-    <glyph glyph-name="_604" unicode="&#xf284;" horiz-adv-x="1792" 
-d="M1584 246l-218 111q-74 -120 -196.5 -189t-263.5 -69q-147 0 -271 72t-196 196t-72 270q0 110 42.5 209.5t115 172t172 115t209.5 42.5q131 0 247.5 -60.5t192.5 -168.5l215 125q-110 169 -286.5 265t-378.5 96q-161 0 -308 -63t-253 -169t-169 -253t-63 -308t63 -308
-t169 -253t253 -169t308 -63q213 0 397.5 107t290.5 292zM1030 643l693 -352q-116 -253 -334.5 -400t-492.5 -147q-182 0 -348 71t-286 191t-191 286t-71 348t71 348t191 286t286 191t348 71q260 0 470.5 -133.5t335.5 -366.5zM1543 640h-39v-160h-96v352h136q32 0 54.5 -20
-t28.5 -48t1 -56t-27.5 -48t-57.5 -20z" />
-    <glyph glyph-name="uniF285" unicode="&#xf285;" horiz-adv-x="1792" 
-d="M1427 827l-614 386l92 151h855zM405 562l-184 116v858l1183 -743zM1424 697l147 -95v-858l-532 335zM1387 718l-500 -802h-855l356 571z" />
-    <glyph glyph-name="uniF286" unicode="&#xf286;" horiz-adv-x="1792" 
-d="M640 528v224q0 16 -16 16h-96q-16 0 -16 -16v-224q0 -16 16 -16h96q16 0 16 16zM1152 528v224q0 16 -16 16h-96q-16 0 -16 -16v-224q0 -16 16 -16h96q16 0 16 16zM1664 496v-752h-640v320q0 80 -56 136t-136 56t-136 -56t-56 -136v-320h-640v752q0 16 16 16h96
-q16 0 16 -16v-112h128v624q0 16 16 16h96q16 0 16 -16v-112h128v112q0 16 16 16h96q16 0 16 -16v-112h128v112q0 6 2.5 9.5t8.5 5t9.5 2t11.5 0t9 -0.5v391q-32 15 -32 50q0 23 16.5 39t38.5 16t38.5 -16t16.5 -39q0 -35 -32 -50v-17q45 10 83 10q21 0 59.5 -7.5t54.5 -7.5
-q17 0 47 7.5t37 7.5q16 0 16 -16v-210q0 -15 -35 -21.5t-62 -6.5q-18 0 -54.5 7.5t-55.5 7.5q-40 0 -90 -12v-133q1 0 9 0.5t11.5 0t9.5 -2t8.5 -5t2.5 -9.5v-112h128v112q0 16 16 16h96q16 0 16 -16v-112h128v112q0 16 16 16h96q16 0 16 -16v-624h128v112q0 16 16 16h96
-q16 0 16 -16z" />
-    <glyph glyph-name="_607" unicode="&#xf287;" horiz-adv-x="2304" 
-d="M2288 731q16 -8 16 -27t-16 -27l-320 -192q-8 -5 -16 -5q-9 0 -16 4q-16 10 -16 28v128h-858q37 -58 83 -165q16 -37 24.5 -55t24 -49t27 -47t27 -34t31.5 -26t33 -8h96v96q0 14 9 23t23 9h320q14 0 23 -9t9 -23v-320q0 -14 -9 -23t-23 -9h-320q-14 0 -23 9t-9 23v96h-96
-q-32 0 -61 10t-51 23.5t-45 40.5t-37 46t-33.5 57t-28.5 57.5t-28 60.5q-23 53 -37 81.5t-36 65t-44.5 53.5t-46.5 17h-360q-22 -84 -91 -138t-157 -54q-106 0 -181 75t-75 181t75 181t181 75q88 0 157 -54t91 -138h104q24 0 46.5 17t44.5 53.5t36 65t37 81.5q19 41 28 60.5
-t28.5 57.5t33.5 57t37 46t45 40.5t51 23.5t61 10h107q21 57 70 92.5t111 35.5q80 0 136 -56t56 -136t-56 -136t-136 -56q-62 0 -111 35.5t-70 92.5h-107q-17 0 -33 -8t-31.5 -26t-27 -34t-27 -47t-24 -49t-24.5 -55q-46 -107 -83 -165h1114v128q0 18 16 28t32 -1z" />
-    <glyph glyph-name="_608" unicode="&#xf288;" horiz-adv-x="1792" 
-d="M1150 774q0 -56 -39.5 -95t-95.5 -39h-253v269h253q56 0 95.5 -39.5t39.5 -95.5zM1329 774q0 130 -91.5 222t-222.5 92h-433v-896h180v269h253q130 0 222 91.5t92 221.5zM1792 640q0 -182 -71 -348t-191 -286t-286 -191t-348 -71t-348 71t-286 191t-191 286t-71 348
-t71 348t191 286t286 191t348 71t348 -71t286 -191t191 -286t71 -348z" />
-    <glyph glyph-name="_609" unicode="&#xf289;" horiz-adv-x="2304" 
-d="M1645 438q0 59 -34 106.5t-87 68.5q-7 -45 -23 -92q-7 -24 -27.5 -38t-44.5 -14q-12 0 -24 3q-31 10 -45 38.5t-4 58.5q23 71 23 143q0 123 -61 227.5t-166 165.5t-228 61q-134 0 -247 -73t-167 -194q108 -28 188 -106q22 -23 22 -55t-22 -54t-54 -22t-55 22
-q-75 75 -180 75q-106 0 -181 -74.5t-75 -180.5t75 -180.5t181 -74.5h1046q79 0 134.5 55.5t55.5 133.5zM1798 438q0 -142 -100.5 -242t-242.5 -100h-1046q-169 0 -289 119.5t-120 288.5q0 153 100 267t249 136q62 184 221 298t354 114q235 0 408.5 -158.5t196.5 -389.5
-q116 -25 192.5 -118.5t76.5 -214.5zM2048 438q0 -175 -97 -319q-23 -33 -64 -33q-24 0 -43 13q-26 17 -32 48.5t12 57.5q71 104 71 233t-71 233q-18 26 -12 57t32 49t57.5 11.5t49.5 -32.5q97 -142 97 -318zM2304 438q0 -244 -134 -443q-23 -34 -64 -34q-23 0 -42 13
-q-26 18 -32.5 49t11.5 57q108 164 108 358q0 195 -108 357q-18 26 -11.5 57.5t32.5 48.5q26 18 57 12t49 -33q134 -198 134 -442z" />
-    <glyph glyph-name="_610" unicode="&#xf28a;" 
-d="M1500 -13q0 -89 -63 -152.5t-153 -63.5t-153.5 63.5t-63.5 152.5q0 90 63.5 153.5t153.5 63.5t153 -63.5t63 -153.5zM1267 268q-115 -15 -192.5 -102.5t-77.5 -205.5q0 -74 33 -138q-146 -78 -379 -78q-109 0 -201 21t-153.5 54.5t-110.5 76.5t-76 85t-44.5 83
-t-23.5 66.5t-6 39.5q0 19 4.5 42.5t18.5 56t36.5 58t64 43.5t94.5 18t94 -17.5t63 -41t35.5 -53t17.5 -49t4 -33.5q0 -34 -23 -81q28 -27 82 -42t93 -17l40 -1q115 0 190 51t75 133q0 26 -9 48.5t-31.5 44.5t-49.5 41t-74 44t-93.5 47.5t-119.5 56.5q-28 13 -43 20
-q-116 55 -187 100t-122.5 102t-72 125.5t-20.5 162.5q0 78 20.5 150t66 137.5t112.5 114t166.5 77t221.5 28.5q120 0 220 -26t164.5 -67t109.5 -94t64 -105.5t19 -103.5q0 -46 -15 -82.5t-36.5 -58t-48.5 -36t-49 -19.5t-39 -5h-8h-32t-39 5t-44 14t-41 28t-37 46t-24 70.5
-t-10 97.5q-15 16 -59 25.5t-81 10.5l-37 1q-68 0 -117.5 -31t-70.5 -70t-21 -76q0 -24 5 -43t24 -46t53 -51t97 -53.5t150 -58.5q76 -25 138.5 -53.5t109 -55.5t83 -59t60.5 -59.5t41 -62.5t26.5 -62t14.5 -63.5t6 -62t1 -62.5z" />
-    <glyph glyph-name="_611" unicode="&#xf28b;" 
-d="M704 352v576q0 14 -9 23t-23 9h-256q-14 0 -23 -9t-9 -23v-576q0 -14 9 -23t23 -9h256q14 0 23 9t9 23zM1152 352v576q0 14 -9 23t-23 9h-256q-14 0 -23 -9t-9 -23v-576q0 -14 9 -23t23 -9h256q14 0 23 9t9 23zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103
-t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
-    <glyph glyph-name="_612" unicode="&#xf28c;" 
-d="M768 1408q209 0 385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103zM768 96q148 0 273 73t198 198t73 273t-73 273t-198 198t-273 73t-273 -73t-198 -198t-73 -273
-t73 -273t198 -198t273 -73zM864 320q-14 0 -23 9t-9 23v576q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-576q0 -14 -9 -23t-23 -9h-192zM480 320q-14 0 -23 9t-9 23v576q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-576q0 -14 -9 -23t-23 -9h-192z" />
-    <glyph glyph-name="_613" unicode="&#xf28d;" 
-d="M1088 352v576q0 14 -9 23t-23 9h-576q-14 0 -23 -9t-9 -23v-576q0 -14 9 -23t23 -9h576q14 0 23 9t9 23zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5
-t103 -385.5z" />
-    <glyph glyph-name="_614" unicode="&#xf28e;" 
-d="M768 1408q209 0 385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103zM768 96q148 0 273 73t198 198t73 273t-73 273t-198 198t-273 73t-273 -73t-198 -198t-73 -273
-t73 -273t198 -198t273 -73zM480 320q-14 0 -23 9t-9 23v576q0 14 9 23t23 9h576q14 0 23 -9t9 -23v-576q0 -14 -9 -23t-23 -9h-576z" />
-    <glyph glyph-name="_615" unicode="&#xf290;" horiz-adv-x="1792" 
-d="M1757 128l35 -313q3 -28 -16 -50q-19 -21 -48 -21h-1664q-29 0 -48 21q-19 22 -16 50l35 313h1722zM1664 967l86 -775h-1708l86 775q3 24 21 40.5t43 16.5h256v-128q0 -53 37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5v128h384v-128q0 -53 37.5 -90.5t90.5 -37.5
-t90.5 37.5t37.5 90.5v128h256q25 0 43 -16.5t21 -40.5zM1280 1152v-256q0 -26 -19 -45t-45 -19t-45 19t-19 45v256q0 106 -75 181t-181 75t-181 -75t-75 -181v-256q0 -26 -19 -45t-45 -19t-45 19t-19 45v256q0 159 112.5 271.5t271.5 112.5t271.5 -112.5t112.5 -271.5z" />
-    <glyph glyph-name="_616" unicode="&#xf291;" horiz-adv-x="2048" 
-d="M1920 768q53 0 90.5 -37.5t37.5 -90.5t-37.5 -90.5t-90.5 -37.5h-15l-115 -662q-8 -46 -44 -76t-82 -30h-1280q-46 0 -82 30t-44 76l-115 662h-15q-53 0 -90.5 37.5t-37.5 90.5t37.5 90.5t90.5 37.5h1792zM485 -32q26 2 43.5 22.5t15.5 46.5l-32 416q-2 26 -22.5 43.5
-t-46.5 15.5t-43.5 -22.5t-15.5 -46.5l32 -416q2 -25 20.5 -42t43.5 -17h5zM896 32v416q0 26 -19 45t-45 19t-45 -19t-19 -45v-416q0 -26 19 -45t45 -19t45 19t19 45zM1280 32v416q0 26 -19 45t-45 19t-45 -19t-19 -45v-416q0 -26 19 -45t45 -19t45 19t19 45zM1632 27l32 416
-q2 26 -15.5 46.5t-43.5 22.5t-46.5 -15.5t-22.5 -43.5l-32 -416q-2 -26 15.5 -46.5t43.5 -22.5h5q25 0 43.5 17t20.5 42zM476 1244l-93 -412h-132l101 441q19 88 89 143.5t160 55.5h167q0 26 19 45t45 19h384q26 0 45 -19t19 -45h167q90 0 160 -55.5t89 -143.5l101 -441
-h-132l-93 412q-11 44 -45.5 72t-79.5 28h-167q0 -26 -19 -45t-45 -19h-384q-26 0 -45 19t-19 45h-167q-45 0 -79.5 -28t-45.5 -72z" />
-    <glyph glyph-name="_617" unicode="&#xf292;" horiz-adv-x="1792" 
-d="M991 512l64 256h-254l-64 -256h254zM1759 1016l-56 -224q-7 -24 -31 -24h-327l-64 -256h311q15 0 25 -12q10 -14 6 -28l-56 -224q-5 -24 -31 -24h-327l-81 -328q-7 -24 -31 -24h-224q-16 0 -26 12q-9 12 -6 28l78 312h-254l-81 -328q-7 -24 -31 -24h-225q-15 0 -25 12
-q-9 12 -6 28l78 312h-311q-15 0 -25 12q-9 12 -6 28l56 224q7 24 31 24h327l64 256h-311q-15 0 -25 12q-10 14 -6 28l56 224q5 24 31 24h327l81 328q7 24 32 24h224q15 0 25 -12q9 -12 6 -28l-78 -312h254l81 328q7 24 32 24h224q15 0 25 -12q9 -12 6 -28l-78 -312h311
-q15 0 25 -12q9 -12 6 -28z" />
-    <glyph glyph-name="_618" unicode="&#xf293;" 
-d="M841 483l148 -148l-149 -149zM840 1094l149 -149l-148 -148zM710 -130l464 464l-306 306l306 306l-464 464v-611l-255 255l-93 -93l320 -321l-320 -321l93 -93l255 255v-611zM1429 640q0 -209 -32 -365.5t-87.5 -257t-140.5 -162.5t-181.5 -86.5t-219.5 -24.5
-t-219.5 24.5t-181.5 86.5t-140.5 162.5t-87.5 257t-32 365.5t32 365.5t87.5 257t140.5 162.5t181.5 86.5t219.5 24.5t219.5 -24.5t181.5 -86.5t140.5 -162.5t87.5 -257t32 -365.5z" />
-    <glyph glyph-name="_619" unicode="&#xf294;" horiz-adv-x="1024" 
-d="M596 113l173 172l-173 172v-344zM596 823l173 172l-173 172v-344zM628 640l356 -356l-539 -540v711l-297 -296l-108 108l372 373l-372 373l108 108l297 -296v711l539 -540z" />
-    <glyph glyph-name="_620" unicode="&#xf295;" 
-d="M1280 256q0 52 -38 90t-90 38t-90 -38t-38 -90t38 -90t90 -38t90 38t38 90zM512 1024q0 52 -38 90t-90 38t-90 -38t-38 -90t38 -90t90 -38t90 38t38 90zM1536 256q0 -159 -112.5 -271.5t-271.5 -112.5t-271.5 112.5t-112.5 271.5t112.5 271.5t271.5 112.5t271.5 -112.5
-t112.5 -271.5zM1440 1344q0 -20 -13 -38l-1056 -1408q-19 -26 -51 -26h-160q-26 0 -45 19t-19 45q0 20 13 38l1056 1408q19 26 51 26h160q26 0 45 -19t19 -45zM768 1024q0 -159 -112.5 -271.5t-271.5 -112.5t-271.5 112.5t-112.5 271.5t112.5 271.5t271.5 112.5
-t271.5 -112.5t112.5 -271.5z" />
-    <glyph glyph-name="_621" unicode="&#xf296;" horiz-adv-x="1792" 
-d="M104 830l792 -1015l-868 630q-18 13 -25 34.5t0 42.5l101 308v0zM566 830h660l-330 -1015v0zM368 1442l198 -612h-462l198 612q8 23 33 23t33 -23zM1688 830l101 -308q7 -21 0 -42.5t-25 -34.5l-868 -630l792 1015v0zM1688 830h-462l198 612q8 23 33 23t33 -23z" />
-    <glyph glyph-name="_622" unicode="&#xf297;" horiz-adv-x="1792" 
-d="M384 704h160v224h-160v-224zM1221 372v92q-104 -36 -243 -38q-135 -1 -259.5 46.5t-220.5 122.5l1 -96q88 -80 212 -128.5t272 -47.5q129 0 238 49zM640 704h640v224h-640v-224zM1792 736q0 -187 -99 -352q89 -102 89 -229q0 -157 -129.5 -268t-313.5 -111
-q-122 0 -225 52.5t-161 140.5q-19 -1 -57 -1t-57 1q-58 -88 -161 -140.5t-225 -52.5q-184 0 -313.5 111t-129.5 268q0 127 89 229q-99 165 -99 352q0 209 120 385.5t326.5 279.5t449.5 103t449.5 -103t326.5 -279.5t120 -385.5z" />
-    <glyph glyph-name="_623" unicode="&#xf298;" 
-d="M515 625v-128h-252v128h252zM515 880v-127h-252v127h252zM1273 369v-128h-341v128h341zM1273 625v-128h-672v128h672zM1273 880v-127h-672v127h672zM1408 20v1240q0 8 -6 14t-14 6h-32l-378 -256l-210 171l-210 -171l-378 256h-32q-8 0 -14 -6t-6 -14v-1240q0 -8 6 -14
-t14 -6h1240q8 0 14 6t6 14zM553 1130l185 150h-406zM983 1130l221 150h-406zM1536 1260v-1240q0 -62 -43 -105t-105 -43h-1240q-62 0 -105 43t-43 105v1240q0 62 43 105t105 43h1240q62 0 105 -43t43 -105z" />
-    <glyph glyph-name="_624" unicode="&#xf299;" horiz-adv-x="1792" 
-d="M896 720q-104 196 -160 278q-139 202 -347 318q-34 19 -70 36q-89 40 -94 32t34 -38l39 -31q62 -43 112.5 -93.5t94.5 -116.5t70.5 -113t70.5 -131q9 -17 13 -25q44 -84 84 -153t98 -154t115.5 -150t131 -123.5t148.5 -90.5q153 -66 154 -60q1 3 -49 37q-53 36 -81 57
-q-77 58 -179 211t-185 310zM549 177q-76 60 -132.5 125t-98 143.5t-71 154.5t-58.5 186t-52 209t-60.5 252t-76.5 289q273 0 497.5 -36t379 -92t271 -144.5t185.5 -172.5t110 -198.5t56 -199.5t12.5 -198.5t-9.5 -173t-20 -143.5t-13 -107l323 -327h-104l-281 285
-q-22 -2 -91.5 -14t-121.5 -19t-138 -6t-160.5 17t-167.5 59t-179 111z" />
-    <glyph glyph-name="_625" unicode="&#xf29a;" horiz-adv-x="1792" 
-d="M1374 879q-6 26 -28.5 39.5t-48.5 7.5q-261 -62 -401 -62t-401 62q-26 6 -48.5 -7.5t-28.5 -39.5t7.5 -48.5t39.5 -28.5q194 -46 303 -58q-2 -158 -15.5 -269t-26.5 -155.5t-41 -115.5l-9 -21q-10 -25 1 -49t36 -34q9 -4 23 -4q44 0 60 41l8 20q54 139 71 259h42
-q17 -120 71 -259l8 -20q16 -41 60 -41q14 0 23 4q25 10 36 34t1 49l-9 21q-28 71 -41 115.5t-26.5 155.5t-15.5 269q109 12 303 58q26 6 39.5 28.5t7.5 48.5zM1024 1024q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5z
-M1600 640q0 -143 -55.5 -273.5t-150 -225t-225 -150t-273.5 -55.5t-273.5 55.5t-225 150t-150 225t-55.5 273.5t55.5 273.5t150 225t225 150t273.5 55.5t273.5 -55.5t225 -150t150 -225t55.5 -273.5zM896 1408q-156 0 -298 -61t-245 -164t-164 -245t-61 -298t61 -298
-t164 -245t245 -164t298 -61t298 61t245 164t164 245t61 298t-61 298t-164 245t-245 164t-298 61zM1792 640q0 -182 -71 -348t-191 -286t-286 -191t-348 -71t-348 71t-286 191t-191 286t-71 348t71 348t191 286t286 191t348 71t348 -71t286 -191t191 -286t71 -348z" />
-    <glyph glyph-name="_626" unicode="&#xf29b;" 
-d="M1438 723q34 -35 29 -82l-44 -551q-4 -42 -34.5 -70t-71.5 -28q-6 0 -9 1q-44 3 -72.5 36.5t-25.5 77.5l35 429l-143 -8q55 -113 55 -240q0 -216 -148 -372l-137 137q91 101 91 235q0 145 -102.5 248t-247.5 103q-134 0 -236 -92l-137 138q120 114 284 141l264 300
-l-149 87l-181 -161q-33 -30 -77 -27.5t-73 35.5t-26.5 77t34.5 73l239 213q26 23 60 26.5t64 -14.5l488 -283q36 -21 48 -68q17 -67 -26 -117l-205 -232l371 20q49 3 83 -32zM1240 1180q-74 0 -126 52t-52 126t52 126t126 52t126.5 -52t52.5 -126t-52.5 -126t-126.5 -52z
-M613 -62q106 0 196 61l139 -139q-146 -116 -335 -116q-148 0 -273.5 73t-198.5 198t-73 273q0 188 116 336l139 -139q-60 -88 -60 -197q0 -145 102.5 -247.5t247.5 -102.5z" />
-    <glyph glyph-name="_627" unicode="&#xf29c;" 
-d="M880 336v-160q0 -14 -9 -23t-23 -9h-160q-14 0 -23 9t-9 23v160q0 14 9 23t23 9h160q14 0 23 -9t9 -23zM1136 832q0 -50 -15 -90t-45.5 -69t-52 -44t-59.5 -36q-32 -18 -46.5 -28t-26 -24t-11.5 -29v-32q0 -14 -9 -23t-23 -9h-160q-14 0 -23 9t-9 23v68q0 35 10.5 64.5
-t24 47.5t39 35.5t41 25.5t44.5 21q53 25 75 43t22 49q0 42 -43.5 71.5t-95.5 29.5q-56 0 -95 -27q-29 -20 -80 -83q-9 -12 -25 -12q-11 0 -19 6l-108 82q-10 7 -12 20t5 23q122 192 349 192q129 0 238.5 -89.5t109.5 -214.5zM768 1280q-130 0 -248.5 -51t-204 -136.5
-t-136.5 -204t-51 -248.5t51 -248.5t136.5 -204t204 -136.5t248.5 -51t248.5 51t204 136.5t136.5 204t51 248.5t-51 248.5t-136.5 204t-204 136.5t-248.5 51zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5
-t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
-    <glyph glyph-name="_628" unicode="&#xf29d;" horiz-adv-x="1408" 
-d="M366 1225q-64 0 -110 45.5t-46 110.5q0 64 46 109.5t110 45.5t109.5 -45.5t45.5 -109.5q0 -65 -45.5 -110.5t-109.5 -45.5zM917 583q0 -50 -30 -67.5t-63.5 -6.5t-47.5 34l-367 438q-7 12 -14 15.5t-11 1.5l-3 -3q-7 -8 4 -21l122 -139l1 -354l-161 -457
-q-67 -192 -92 -234q-15 -26 -28 -32q-50 -26 -103 -1q-29 13 -41.5 43t-9.5 57q2 17 197 618l5 416l-85 -164l35 -222q4 -24 -1 -42t-14 -27.5t-19 -16t-17 -7.5l-7 -2q-19 -3 -34.5 3t-24 16t-14 22t-7.5 19.5t-2 9.5l-46 299l211 381q23 34 113 34q75 0 107 -40l424 -521
-q7 -5 14 -17l3 -3l-1 -1q7 -13 7 -29zM514 433q43 -113 88.5 -225t69.5 -168l24 -55q36 -93 42 -125q11 -70 -36 -97q-35 -22 -66 -16t-51 22t-29 35h-1q-6 16 -8 25l-124 351zM1338 -159q31 -49 31 -57q0 -5 -3 -7q-9 -5 -14.5 0.5t-15.5 26t-16 30.5q-114 172 -423 661
-q3 -1 7 1t7 4l3 2q11 9 11 17z" />
-    <glyph glyph-name="_629" unicode="&#xf29e;" horiz-adv-x="2304" 
-d="M504 542h171l-1 265zM1530 641q0 87 -50.5 140t-146.5 53h-54v-388h52q91 0 145 57t54 138zM956 1018l1 -756q0 -14 -9.5 -24t-23.5 -10h-216q-14 0 -23.5 10t-9.5 24v62h-291l-55 -81q-10 -15 -28 -15h-267q-21 0 -30.5 18t3.5 35l556 757q9 14 27 14h332q14 0 24 -10
-t10 -24zM1783 641q0 -193 -125.5 -303t-324.5 -110h-270q-14 0 -24 10t-10 24v756q0 14 10 24t24 10h268q200 0 326 -109t126 -302zM1939 640q0 -11 -0.5 -29t-8 -71.5t-21.5 -102t-44.5 -108t-73.5 -102.5h-51q38 45 66.5 104.5t41.5 112t21 98t9 72.5l1 27q0 8 -0.5 22.5
-t-7.5 60t-20 91.5t-41 111.5t-66 124.5h43q41 -47 72 -107t45.5 -111.5t23 -96t10.5 -70.5zM2123 640q0 -11 -0.5 -29t-8 -71.5t-21.5 -102t-45 -108t-74 -102.5h-51q38 45 66.5 104.5t41.5 112t21 98t9 72.5l1 27q0 8 -0.5 22.5t-7.5 60t-19.5 91.5t-40.5 111.5t-66 124.5
-h43q41 -47 72 -107t45.5 -111.5t23 -96t10.5 -70.5zM2304 640q0 -11 -0.5 -29t-8 -71.5t-21.5 -102t-44.5 -108t-73.5 -102.5h-51q38 45 66 104.5t41 112t21 98t9 72.5l1 27q0 8 -0.5 22.5t-7.5 60t-19.5 91.5t-40.5 111.5t-66 124.5h43q41 -47 72 -107t45.5 -111.5t23 -96
-t9.5 -70.5z" />
-    <glyph glyph-name="uniF2A0" unicode="&#xf2a0;" horiz-adv-x="1408" 
-d="M617 -153q0 11 -13 58t-31 107t-20 69q-1 4 -5 26.5t-8.5 36t-13.5 21.5q-15 14 -51 14q-23 0 -70 -5.5t-71 -5.5q-34 0 -47 11q-6 5 -11 15.5t-7.5 20t-6.5 24t-5 18.5q-37 128 -37 255t37 255q1 4 5 18.5t6.5 24t7.5 20t11 15.5q13 11 47 11q24 0 71 -5.5t70 -5.5
-q36 0 51 14q9 8 13.5 21.5t8.5 36t5 26.5q2 9 20 69t31 107t13 58q0 22 -43.5 52.5t-75.5 42.5q-20 8 -45 8q-34 0 -98 -18q-57 -17 -96.5 -40.5t-71 -66t-46 -70t-45.5 -94.5q-6 -12 -9 -19q-49 -107 -68 -216t-19 -244t19 -244t68 -216q56 -122 83 -161q63 -91 179 -127
-l6 -2q64 -18 98 -18q25 0 45 8q32 12 75.5 42.5t43.5 52.5zM776 760q-26 0 -45 19t-19 45.5t19 45.5q37 37 37 90q0 52 -37 91q-19 19 -19 45t19 45t45 19t45 -19q75 -75 75 -181t-75 -181q-21 -19 -45 -19zM957 579q-27 0 -45 19q-19 19 -19 45t19 45q112 114 112 272
-t-112 272q-19 19 -19 45t19 45t45 19t45 -19q150 -150 150 -362t-150 -362q-18 -19 -45 -19zM1138 398q-27 0 -45 19q-19 19 -19 45t19 45q90 91 138.5 208t48.5 245t-48.5 245t-138.5 208q-19 19 -19 45t19 45t45 19t45 -19q109 -109 167 -249t58 -294t-58 -294t-167 -249
-q-18 -19 -45 -19z" />
-    <glyph glyph-name="uniF2A1" unicode="&#xf2a1;" horiz-adv-x="2176" 
-d="M192 352q-66 0 -113 -47t-47 -113t47 -113t113 -47t113 47t47 113t-47 113t-113 47zM704 352q-66 0 -113 -47t-47 -113t47 -113t113 -47t113 47t47 113t-47 113t-113 47zM704 864q-66 0 -113 -47t-47 -113t47 -113t113 -47t113 47t47 113t-47 113t-113 47zM1472 352
-q-66 0 -113 -47t-47 -113t47 -113t113 -47t113 47t47 113t-47 113t-113 47zM1984 352q-66 0 -113 -47t-47 -113t47 -113t113 -47t113 47t47 113t-47 113t-113 47zM1472 864q-66 0 -113 -47t-47 -113t47 -113t113 -47t113 47t47 113t-47 113t-113 47zM1984 864
-q-66 0 -113 -47t-47 -113t47 -113t113 -47t113 47t47 113t-47 113t-113 47zM1984 1376q-66 0 -113 -47t-47 -113t47 -113t113 -47t113 47t47 113t-47 113t-113 47zM384 192q0 -80 -56 -136t-136 -56t-136 56t-56 136t56 136t136 56t136 -56t56 -136zM896 192q0 -80 -56 -136
-t-136 -56t-136 56t-56 136t56 136t136 56t136 -56t56 -136zM384 704q0 -80 -56 -136t-136 -56t-136 56t-56 136t56 136t136 56t136 -56t56 -136zM896 704q0 -80 -56 -136t-136 -56t-136 56t-56 136t56 136t136 56t136 -56t56 -136zM384 1216q0 -80 -56 -136t-136 -56
-t-136 56t-56 136t56 136t136 56t136 -56t56 -136zM1664 192q0 -80 -56 -136t-136 -56t-136 56t-56 136t56 136t136 56t136 -56t56 -136zM896 1216q0 -80 -56 -136t-136 -56t-136 56t-56 136t56 136t136 56t136 -56t56 -136zM2176 192q0 -80 -56 -136t-136 -56t-136 56
-t-56 136t56 136t136 56t136 -56t56 -136zM1664 704q0 -80 -56 -136t-136 -56t-136 56t-56 136t56 136t136 56t136 -56t56 -136zM2176 704q0 -80 -56 -136t-136 -56t-136 56t-56 136t56 136t136 56t136 -56t56 -136zM1664 1216q0 -80 -56 -136t-136 -56t-136 56t-56 136
-t56 136t136 56t136 -56t56 -136zM2176 1216q0 -80 -56 -136t-136 -56t-136 56t-56 136t56 136t136 56t136 -56t56 -136z" />
-    <glyph glyph-name="uniF2A2" unicode="&#xf2a2;" horiz-adv-x="1792" 
-d="M128 -192q0 -26 -19 -45t-45 -19t-45 19t-19 45t19 45t45 19t45 -19t19 -45zM320 0q0 -26 -19 -45t-45 -19t-45 19t-19 45t19 45t45 19t45 -19t19 -45zM365 365l256 -256l-90 -90l-256 256zM704 384q0 -26 -19 -45t-45 -19t-45 19t-19 45t19 45t45 19t45 -19t19 -45z
-M1411 704q0 -59 -11.5 -108.5t-37.5 -93.5t-44 -67.5t-53 -64.5q-31 -35 -45.5 -54t-33.5 -50t-26.5 -64t-7.5 -74q0 -159 -112.5 -271.5t-271.5 -112.5q-26 0 -45 19t-19 45t19 45t45 19q106 0 181 75t75 181q0 57 11.5 105.5t37 91t43.5 66.5t52 63q40 46 59.5 72
-t37.5 74.5t18 103.5q0 185 -131.5 316.5t-316.5 131.5t-316.5 -131.5t-131.5 -316.5q0 -26 -19 -45t-45 -19t-45 19t-19 45q0 117 45.5 223.5t123 184t184 123t223.5 45.5t223.5 -45.5t184 -123t123 -184t45.5 -223.5zM896 576q0 -26 -19 -45t-45 -19t-45 19t-19 45t19 45
-t45 19t45 -19t19 -45zM1184 704q0 -26 -19 -45t-45 -19t-45 19t-19 45q0 93 -65.5 158.5t-158.5 65.5q-92 0 -158 -65.5t-66 -158.5q0 -26 -19 -45t-45 -19t-45 19t-19 45q0 146 103 249t249 103t249 -103t103 -249zM1578 993q10 -25 -1 -49t-36 -34q-9 -4 -23 -4
-q-19 0 -35.5 11t-23.5 30q-68 178 -224 295q-21 16 -25 42t12 47q17 21 43 25t47 -12q183 -137 266 -351zM1788 1074q9 -25 -1.5 -49t-35.5 -34q-11 -4 -23 -4q-44 0 -60 41q-92 238 -297 393q-22 16 -25.5 42t12.5 47q16 22 42 25.5t47 -12.5q235 -175 341 -449z" />
-    <glyph glyph-name="uniF2A3" unicode="&#xf2a3;" horiz-adv-x="2304" 
-d="M1032 576q-59 2 -84 55q-17 34 -48 53.5t-68 19.5q-53 0 -90.5 -37.5t-37.5 -90.5q0 -56 36 -89l10 -8q34 -31 82 -31q37 0 68 19.5t48 53.5q25 53 84 55zM1600 704q0 56 -36 89l-10 8q-34 31 -82 31q-37 0 -68 -19.5t-48 -53.5q-25 -53 -84 -55q59 -2 84 -55
-q17 -34 48 -53.5t68 -19.5q53 0 90.5 37.5t37.5 90.5zM1174 925q-17 -35 -55 -48t-73 4q-62 31 -134 31q-51 0 -99 -17q3 0 9.5 0.5t9.5 0.5q92 0 170.5 -50t118.5 -133q17 -36 3.5 -73.5t-49.5 -54.5q-18 -9 -39 -9q21 0 39 -9q36 -17 49.5 -54.5t-3.5 -73.5
-q-40 -83 -118.5 -133t-170.5 -50h-6q-16 2 -44 4l-290 27l-239 -120q-14 -7 -29 -7q-40 0 -57 35l-160 320q-11 23 -4 47.5t29 37.5l209 119l148 267q17 155 91.5 291.5t195.5 236.5q31 25 70.5 21.5t64.5 -34.5t21.5 -70t-34.5 -65q-70 -59 -117 -128q123 84 267 101
-q40 5 71.5 -19t35.5 -64q5 -40 -19 -71.5t-64 -35.5q-84 -10 -159 -55q46 10 99 10q115 0 218 -50q36 -18 49 -55.5t-5 -73.5zM2137 1085l160 -320q11 -23 4 -47.5t-29 -37.5l-209 -119l-148 -267q-17 -155 -91.5 -291.5t-195.5 -236.5q-26 -22 -61 -22q-45 0 -74 35
-q-25 31 -21.5 70t34.5 65q70 59 117 128q-123 -84 -267 -101q-4 -1 -12 -1q-36 0 -63.5 24t-31.5 60q-5 40 19 71.5t64 35.5q84 10 159 55q-46 -10 -99 -10q-115 0 -218 50q-36 18 -49 55.5t5 73.5q17 35 55 48t73 -4q62 -31 134 -31q51 0 99 17q-3 0 -9.5 -0.5t-9.5 -0.5
-q-92 0 -170.5 50t-118.5 133q-17 36 -3.5 73.5t49.5 54.5q18 9 39 9q-21 0 -39 9q-36 17 -49.5 54.5t3.5 73.5q40 83 118.5 133t170.5 50h6h1q14 -2 42 -4l291 -27l239 120q14 7 29 7q40 0 57 -35z" />
-    <glyph glyph-name="uniF2A4" unicode="&#xf2a4;" horiz-adv-x="1792" 
-d="M1056 704q0 -26 19 -45t45 -19t45 19t19 45q0 146 -103 249t-249 103t-249 -103t-103 -249q0 -26 19 -45t45 -19t45 19t19 45q0 93 66 158.5t158 65.5t158 -65.5t66 -158.5zM835 1280q-117 0 -223.5 -45.5t-184 -123t-123 -184t-45.5 -223.5q0 -26 19 -45t45 -19t45 19
-t19 45q0 185 131.5 316.5t316.5 131.5t316.5 -131.5t131.5 -316.5q0 -55 -18 -103.5t-37.5 -74.5t-59.5 -72q-34 -39 -52 -63t-43.5 -66.5t-37 -91t-11.5 -105.5q0 -106 -75 -181t-181 -75q-26 0 -45 -19t-19 -45t19 -45t45 -19q159 0 271.5 112.5t112.5 271.5q0 41 7.5 74
-t26.5 64t33.5 50t45.5 54q35 41 53 64.5t44 67.5t37.5 93.5t11.5 108.5q0 117 -45.5 223.5t-123 184t-184 123t-223.5 45.5zM591 561l226 -226l-579 -579q-12 -12 -29 -12t-29 12l-168 168q-12 12 -12 29t12 29zM1612 1524l168 -168q12 -12 12 -29t-12 -30l-233 -233
-l-26 -25l-71 -71q-66 153 -195 258l91 91l207 207q13 12 30 12t29 -12z" />
-    <glyph glyph-name="uniF2A5" unicode="&#xf2a5;" 
-d="M866 1021q0 -27 -13 -94q-11 -50 -31.5 -150t-30.5 -150q-2 -11 -4.5 -12.5t-13.5 -2.5q-20 -2 -31 -2q-58 0 -84 49.5t-26 113.5q0 88 35 174t103 124q28 14 51 14q28 0 36.5 -16.5t8.5 -47.5zM1352 597q0 14 -39 75.5t-52 66.5q-21 8 -34 8q-91 0 -226 -77l-2 2
-q3 22 27.5 135t24.5 178q0 233 -242 233q-24 0 -68 -6q-94 -17 -168.5 -89.5t-111.5 -166.5t-37 -189q0 -146 80.5 -225t227.5 -79q25 0 25 -3t-1 -5q-4 -34 -26 -117q-14 -52 -51.5 -101t-82.5 -49q-42 0 -42 47q0 24 10.5 47.5t25 39.5t29.5 28.5t26 20t11 8.5q0 3 -7 10
-q-24 22 -58.5 36.5t-65.5 14.5q-35 0 -63.5 -34t-41 -75t-12.5 -75q0 -88 51.5 -142t138.5 -54q82 0 155 53t117.5 126t65.5 153q6 22 15.5 66.5t14.5 66.5q3 12 14 18q118 60 227 60q48 0 127 -18q1 -1 4 -1q5 0 9.5 4.5t4.5 8.5zM1536 1120v-960q0 -119 -84.5 -203.5
-t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
-    <glyph glyph-name="uniF2A6" unicode="&#xf2a6;" horiz-adv-x="1535" 
-d="M744 1231q0 24 -2 38.5t-8.5 30t-21 23t-37.5 7.5q-39 0 -78 -23q-105 -58 -159 -190.5t-54 -269.5q0 -44 8.5 -85.5t26.5 -80.5t52.5 -62.5t81.5 -23.5q4 0 18 -0.5t20 0t16 3t15 8.5t7 16q16 77 48 231.5t48 231.5q19 91 19 146zM1498 575q0 -7 -7.5 -13.5t-15.5 -6.5
-l-6 1q-22 3 -62 11t-72 12.5t-63 4.5q-167 0 -351 -93q-15 -8 -21 -27q-10 -36 -24.5 -105.5t-22.5 -100.5q-23 -91 -70 -179.5t-112.5 -164.5t-154.5 -123t-185 -47q-135 0 -214.5 83.5t-79.5 219.5q0 53 19.5 117t63 116.5t97.5 52.5q38 0 120 -33.5t83 -61.5
-q0 -1 -16.5 -12.5t-39.5 -31t-46 -44.5t-39 -61t-16 -74q0 -33 16.5 -53t48.5 -20q45 0 85 31.5t66.5 78t48 105.5t32.5 107t16 90v9q0 2 -3.5 3.5t-8.5 1.5h-10t-10 -0.5t-6 -0.5q-227 0 -352 122.5t-125 348.5q0 108 34.5 221t96 210t156 167.5t204.5 89.5q52 9 106 9
-q374 0 374 -360q0 -98 -38 -273t-43 -211l3 -3q101 57 182.5 88t167.5 31q22 0 53 -13q19 -7 80 -102.5t61 -116.5z" />
-    <glyph glyph-name="uniF2A7" unicode="&#xf2a7;" horiz-adv-x="1664" 
-d="M831 863q32 0 59 -18l222 -148q61 -40 110 -97l146 -170q40 -46 29 -106l-72 -413q-6 -32 -29.5 -53.5t-55.5 -25.5l-527 -56l-352 -32h-9q-39 0 -67.5 28t-28.5 68q0 37 27 64t65 32l260 32h-448q-41 0 -69.5 30t-26.5 71q2 39 32 65t69 26l442 1l-521 64q-41 5 -66 37
-t-19 73q6 35 34.5 57.5t65.5 22.5h10l481 -60l-351 94q-38 10 -62 41.5t-18 68.5q6 36 33 58.5t62 22.5q6 0 20 -2l448 -96l217 -37q1 0 3 -0.5t3 -0.5q23 0 30.5 23t-12.5 36l-186 125q-35 23 -42 63.5t18 73.5q27 38 76 38zM761 661l186 -125l-218 37l-5 2l-36 38
-l-238 262q-1 1 -2.5 3.5t-2.5 3.5q-24 31 -18.5 70t37.5 64q31 23 68 17.5t64 -33.5l142 -147q-2 -1 -5 -3.5t-4 -4.5q-32 -45 -23 -99t55 -85zM1648 1115l15 -266q4 -73 -11 -147l-48 -219q-12 -59 -67 -87l-106 -54q2 62 -39 109l-146 170q-53 61 -117 103l-222 148
-q-34 23 -76 23q-51 0 -88 -37l-235 312q-25 33 -18 73.5t41 63.5q33 22 71.5 14t62.5 -40l266 -352l-262 455q-21 35 -10.5 75t47.5 59q35 18 72.5 6t57.5 -46l241 -420l-136 337q-15 35 -4.5 74t44.5 56q37 19 76 6t56 -51l193 -415l101 -196q8 -15 23 -17.5t27 7.5t11 26
-l-12 224q-2 41 26 71t69 31q39 0 67 -28.5t30 -67.5z" />
-    <glyph glyph-name="uniF2A8" unicode="&#xf2a8;" horiz-adv-x="1792" 
-d="M335 180q-2 0 -6 2q-86 57 -168.5 145t-139.5 180q-21 30 -21 69q0 9 2 19t4 18t7 18t8.5 16t10.5 17t10 15t12 15.5t11 14.5q184 251 452 365q-110 198 -110 211q0 19 17 29q116 64 128 64q18 0 28 -16l124 -229q92 19 192 19q266 0 497.5 -137.5t378.5 -369.5
-q20 -31 20 -69t-20 -69q-91 -142 -218.5 -253.5t-278.5 -175.5q110 -198 110 -211q0 -20 -17 -29q-116 -64 -127 -64q-19 0 -29 16l-124 229l-64 119l-444 820l7 7q-58 -24 -99 -47q3 -5 127 -234t243 -449t119 -223q0 -7 -9 -9q-13 -3 -72 -3q-57 0 -60 7l-456 841
-q-39 -28 -82 -68q24 -43 214 -393.5t190 -354.5q0 -10 -11 -10q-14 0 -82.5 22t-72.5 28l-106 197l-224 413q-44 -53 -78 -106q2 -3 18 -25t23 -34l176 -327q0 -10 -10 -10zM1165 282l49 -91q273 111 450 385q-180 277 -459 389q67 -64 103 -148.5t36 -176.5
-q0 -106 -47 -200.5t-132 -157.5zM848 896q0 -20 14 -34t34 -14q86 0 147 -61t61 -147q0 -20 14 -34t34 -14t34 14t14 34q0 126 -89 215t-215 89q-20 0 -34 -14t-14 -34zM1214 961l-9 4l7 -7z" />
-    <glyph glyph-name="uniF2A9" unicode="&#xf2a9;" horiz-adv-x="1280" 
-d="M1050 430q0 -215 -147 -374q-148 -161 -378 -161q-232 0 -378 161q-147 159 -147 374q0 147 68 270.5t189 196.5t268 73q96 0 182 -31q-32 -62 -39 -126q-66 28 -143 28q-167 0 -280.5 -123t-113.5 -291q0 -170 112.5 -288.5t281.5 -118.5t281 118.5t112 288.5
-q0 89 -32 166q66 13 123 49q41 -98 41 -212zM846 619q0 -192 -79.5 -345t-238.5 -253l-14 -1q-29 0 -62 5q83 32 146.5 102.5t99.5 154.5t58.5 189t30 192.5t7.5 178.5q0 69 -3 103q55 -160 55 -326zM791 947v-2q-73 214 -206 440q88 -59 142.5 -186.5t63.5 -251.5z
-M1035 744q-83 0 -160 75q218 120 290 247q19 37 21 56q-42 -94 -139.5 -166.5t-204.5 -97.5q-35 54 -35 113q0 37 17 79t43 68q46 44 157 74q59 16 106 58.5t74 100.5q74 -105 74 -253q0 -109 -24 -170q-32 -77 -88.5 -130.5t-130.5 -53.5z" />
-    <glyph glyph-name="uniF2AA" unicode="&#xf2aa;" 
-d="M1050 495q0 78 -28 147q-41 -25 -85 -34q22 -50 22 -114q0 -117 -77 -198.5t-193 -81.5t-193.5 81.5t-77.5 198.5q0 115 78 199.5t193 84.5q53 0 98 -19q4 43 27 87q-60 21 -125 21q-154 0 -257.5 -108.5t-103.5 -263.5t103.5 -261t257.5 -106t257.5 106.5t103.5 260.5z
-M872 850q2 -24 2 -71q0 -63 -5 -123t-20.5 -132.5t-40.5 -130t-68.5 -106t-100.5 -70.5q21 -3 42 -3h10q219 139 219 411q0 116 -38 225zM872 850q-4 80 -44 171.5t-98 130.5q92 -156 142 -302zM1207 955q0 102 -51 174q-41 -86 -124 -109q-69 -19 -109 -53.5t-40 -99.5
-q0 -40 24 -77q74 17 140.5 67t95.5 115q-4 -52 -74.5 -111.5t-138.5 -97.5q52 -52 110 -52q51 0 90 37t60 90q17 42 17 117zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5
-t84.5 -203.5z" />
-    <glyph glyph-name="uniF2AB" unicode="&#xf2ab;" 
-d="M1279 388q0 22 -22 27q-67 15 -118 59t-80 108q-7 19 -7 25q0 15 19.5 26t43 17t43 20.5t19.5 36.5q0 19 -18.5 31.5t-38.5 12.5q-12 0 -32 -8t-31 -8q-4 0 -12 2q5 95 5 114q0 79 -17 114q-36 78 -103 121.5t-152 43.5q-199 0 -275 -165q-17 -35 -17 -114q0 -19 5 -114
-q-4 -2 -14 -2q-12 0 -32 7.5t-30 7.5q-21 0 -38.5 -12t-17.5 -32q0 -21 19.5 -35.5t43 -20.5t43 -17t19.5 -26q0 -6 -7 -25q-64 -138 -198 -167q-22 -5 -22 -27q0 -46 137 -68q2 -5 6 -26t11.5 -30.5t23.5 -9.5q12 0 37.5 4.5t39.5 4.5q35 0 67 -15t54 -32.5t57.5 -32.5
-t76.5 -15q43 0 79 15t57.5 32.5t53.5 32.5t67 15q14 0 39.5 -4t38.5 -4q16 0 23 10t11 30t6 25q137 22 137 68zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5
-t103 -385.5z" />
-    <glyph glyph-name="uniF2AC" unicode="&#xf2ac;" horiz-adv-x="1664" 
-d="M848 1408q134 1 240.5 -68.5t163.5 -192.5q27 -58 27 -179q0 -47 -9 -191q14 -7 28 -7q18 0 51 13.5t51 13.5q29 0 56 -18t27 -46q0 -32 -31.5 -54t-69 -31.5t-69 -29t-31.5 -47.5q0 -15 12 -43q37 -82 102.5 -150t144.5 -101q28 -12 80 -23q28 -6 28 -35
-q0 -70 -219 -103q-7 -11 -11 -39t-14 -46.5t-33 -18.5q-20 0 -62 6.5t-64 6.5q-37 0 -62 -5q-32 -5 -63 -22.5t-58 -38t-58 -40.5t-76 -33.5t-99 -13.5q-52 0 -96.5 13.5t-75 33.5t-57.5 40.5t-58 38t-62 22.5q-26 5 -63 5q-24 0 -65.5 -7.5t-58.5 -7.5q-25 0 -35 18.5
-t-14 47.5t-11 40q-219 33 -219 103q0 29 28 35q52 11 80 23q78 32 144.5 101t102.5 150q12 28 12 43q0 28 -31.5 47.5t-69.5 29.5t-69.5 31.5t-31.5 52.5q0 27 26 45.5t55 18.5q15 0 48 -13t53 -13q18 0 32 7q-9 142 -9 190q0 122 27 180q64 137 172 198t264 63z" />
-    <glyph glyph-name="uniF2AD" unicode="&#xf2ad;" 
-d="M1280 388q0 22 -22 27q-67 14 -118 58t-80 109q-7 14 -7 25q0 15 19.5 26t42.5 17t42.5 20.5t19.5 36.5q0 19 -18.5 31.5t-38.5 12.5q-11 0 -31 -8t-32 -8q-4 0 -12 2q5 63 5 115q0 78 -17 114q-36 78 -102.5 121.5t-152.5 43.5q-198 0 -275 -165q-18 -38 -18 -115
-q0 -38 6 -114q-10 -2 -15 -2q-11 0 -31.5 8t-30.5 8q-20 0 -37.5 -12.5t-17.5 -32.5q0 -21 19.5 -35.5t42.5 -20.5t42.5 -17t19.5 -26q0 -11 -7 -25q-64 -138 -198 -167q-22 -5 -22 -27q0 -47 138 -69q2 -5 6 -26t11 -30.5t23 -9.5q13 0 38.5 5t38.5 5q35 0 67.5 -15
-t54.5 -32.5t57.5 -32.5t76.5 -15q43 0 79 15t57.5 32.5t54 32.5t67.5 15q13 0 39 -4.5t39 -4.5q15 0 22.5 9.5t11.5 31t5 24.5q138 22 138 69zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960
-q119 0 203.5 -84.5t84.5 -203.5z" />
-    <glyph glyph-name="uniF2AE" unicode="&#xf2ae;" horiz-adv-x="2304" 
-d="M2304 1536q-69 -46 -125 -92t-89 -81t-59.5 -71.5t-37.5 -57.5t-22 -44.5t-14 -29.5q-10 -18 -35.5 -136.5t-48.5 -164.5q-15 -29 -50 -60.5t-67.5 -50.5t-72.5 -41t-48 -28q-47 -31 -151 -231q-341 14 -630 -158q-92 -53 -303 -179q47 16 86 31t55 22l15 7
-q71 27 163 64.5t133.5 53.5t108 34.5t142.5 31.5q186 31 465 -7q1 0 10 -3q11 -6 14 -17t-3 -22l-194 -345q-15 -29 -47 -22q-128 24 -354 24q-146 0 -402 -44.5t-392 -46.5q-82 -1 -149 13t-107 37t-61 40t-33 34l-1 1v2q0 6 6 6q138 0 371 55q192 366 374.5 524t383.5 158
-q5 0 14.5 -0.5t38 -5t55 -12t61.5 -24.5t63 -39.5t54 -59t40 -82.5l102 177q2 4 21 42.5t44.5 86.5t61 109.5t84 133.5t100.5 137q66 82 128 141.5t121.5 96.5t92.5 53.5t88 39.5z" />
-    <glyph glyph-name="uniF2B0" unicode="&#xf2b0;" 
-d="M1322 640q0 -45 -5 -76l-236 14l224 -78q-19 -73 -58 -141l-214 103l177 -158q-44 -61 -107 -108l-157 178l103 -215q-61 -37 -140 -59l-79 228l14 -240q-38 -6 -76 -6t-76 6l14 238l-78 -226q-74 19 -140 59l103 215l-157 -178q-59 43 -108 108l178 158l-214 -104
-q-39 69 -58 141l224 79l-237 -14q-5 42 -5 76q0 35 5 77l238 -14l-225 79q19 73 58 140l214 -104l-177 159q46 61 107 108l158 -178l-103 215q67 39 140 58l77 -224l-13 236q36 6 75 6q38 0 76 -6l-14 -237l78 225q74 -19 140 -59l-103 -214l158 178q61 -47 107 -108
-l-177 -159l213 104q37 -62 58 -141l-224 -78l237 14q5 -31 5 -77zM1352 640q0 160 -78.5 295.5t-213 214t-292.5 78.5q-119 0 -227 -46.5t-186.5 -125t-124.5 -187.5t-46 -229q0 -119 46 -228t124.5 -187.5t186.5 -125t227 -46.5q158 0 292.5 78.5t213 214t78.5 294.5z
-M1425 1023v-766l-657 -383l-657 383v766l657 383zM768 -183l708 412v823l-708 411l-708 -411v-823zM1536 1088v-896l-768 -448l-768 448v896l768 448z" />
-    <glyph glyph-name="uniF2B1" unicode="&#xf2b1;" horiz-adv-x="1664" 
-d="M339 1318h691l-26 -72h-665q-110 0 -188.5 -79t-78.5 -189v-771q0 -95 60.5 -169.5t153.5 -93.5q23 -5 98 -5v-72h-45q-140 0 -239.5 100t-99.5 240v771q0 140 99.5 240t239.5 100zM1190 1536h247l-482 -1294q-23 -61 -40.5 -103.5t-45 -98t-54 -93.5t-64.5 -78.5
-t-79.5 -65t-95.5 -41t-116 -18.5v195q163 26 220 182q20 52 20 105q0 54 -20 106l-285 733h228l187 -585zM1664 978v-1111h-795q37 55 45 73h678v1038q0 85 -49.5 155t-129.5 99l25 67q101 -34 163.5 -123.5t62.5 -197.5z" />
-    <glyph glyph-name="uniF2B2" unicode="&#xf2b2;" horiz-adv-x="1792" 
-d="M852 1227q0 -29 -17 -52.5t-45 -23.5t-45 23.5t-17 52.5t17 52.5t45 23.5t45 -23.5t17 -52.5zM688 -149v114q0 30 -20.5 51.5t-50.5 21.5t-50 -21.5t-20 -51.5v-114q0 -30 20.5 -52t49.5 -22q30 0 50.5 22t20.5 52zM860 -149v114q0 30 -20 51.5t-50 21.5t-50.5 -21.5
-t-20.5 -51.5v-114q0 -30 20.5 -52t50.5 -22q29 0 49.5 22t20.5 52zM1034 -149v114q0 30 -20.5 51.5t-50.5 21.5t-50.5 -21.5t-20.5 -51.5v-114q0 -30 20.5 -52t50.5 -22t50.5 22t20.5 52zM1208 -149v114q0 30 -20.5 51.5t-50.5 21.5t-50.5 -21.5t-20.5 -51.5v-114
-q0 -30 20.5 -52t50.5 -22t50.5 22t20.5 52zM1476 535q-84 -160 -232 -259.5t-323 -99.5q-123 0 -229.5 51.5t-178.5 137t-113 197.5t-41 232q0 88 21 174q-104 -175 -104 -390q0 -162 65 -312t185 -251q30 57 91 57q56 0 86 -50q32 50 87 50q56 0 86 -50q32 50 87 50t87 -50
-q30 50 86 50q28 0 52.5 -15.5t37.5 -40.5q112 94 177 231.5t73 287.5zM1326 564q0 75 -72 75q-17 0 -47 -6q-95 -19 -149 -19q-226 0 -226 243q0 86 30 204q-83 -127 -83 -275q0 -150 89 -260.5t235 -110.5q111 0 210 70q13 48 13 79zM884 1223q0 50 -32 89.5t-81 39.5
-t-81 -39.5t-32 -89.5q0 -51 31.5 -90.5t81.5 -39.5t81.5 39.5t31.5 90.5zM1513 884q0 96 -37.5 179t-113 137t-173.5 54q-77 0 -149 -35t-127 -94q-48 -159 -48 -268q0 -104 45.5 -157t147.5 -53q53 0 142 19q36 6 53 6q51 0 77.5 -28t26.5 -80q0 -26 -4 -46
-q75 68 117.5 165.5t42.5 200.5zM1792 667q0 -111 -33.5 -249.5t-93.5 -204.5q-58 -64 -195 -142.5t-228 -104.5l-4 -1v-114q0 -43 -29.5 -75t-72.5 -32q-56 0 -86 50q-32 -50 -87 -50t-87 50q-30 -50 -86 -50q-55 0 -87 50q-30 -50 -86 -50q-47 0 -75 33.5t-28 81.5
-q-90 -68 -198 -68q-118 0 -211 80q54 1 106 20q-113 31 -182 127q32 -7 71 -7q89 0 164 46q-192 192 -240 306q-24 56 -24 160q0 57 9 125.5t31.5 146.5t55 141t86.5 105t120 42q59 0 81 -52q19 29 42 54q2 3 12 13t13 16q10 15 23 38t25 42t28 39q87 111 211.5 177
-t260.5 66q35 0 62 -4q59 64 146 64q83 0 140 -57q5 -5 5 -12q0 -5 -6 -13.5t-12.5 -16t-16 -17l-10.5 -10.5q17 -6 36 -18t19 -24q0 -6 -16 -25q157 -138 197 -378q25 30 60 30q45 0 100 -49q90 -80 90 -279z" />
-    <glyph glyph-name="uniF2B3" unicode="&#xf2b3;" 
-d="M917 631q0 33 -6 64h-362v-132h217q-12 -76 -74.5 -120.5t-142.5 -44.5q-99 0 -169 71.5t-70 170.5t70 170.5t169 71.5q93 0 153 -59l104 101q-108 100 -257 100q-160 0 -272 -112.5t-112 -271.5t112 -271.5t272 -112.5q165 0 266.5 105t101.5 270zM1262 585h109v110
-h-109v110h-110v-110h-110v-110h110v-110h110v110zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
-    <glyph glyph-name="uniF2B4" unicode="&#xf2b4;" 
-d="M1536 1024v-839q0 -48 -49 -62q-174 -52 -338 -52q-73 0 -215.5 29.5t-227.5 29.5q-164 0 -370 -48v-338h-160v1368q-63 25 -101 81t-38 124q0 91 64 155t155 64t155 -64t64 -155q0 -68 -38 -124t-101 -81v-68q190 44 343 44q99 0 198 -15q14 -2 111.5 -22.5t149.5 -20.5
-q77 0 165 18q11 2 80 21t89 19q26 0 45 -19t19 -45z" />
-    <glyph glyph-name="uniF2B5" unicode="&#xf2b5;" horiz-adv-x="2304" 
-d="M192 384q40 0 56 32t0 64t-56 32t-56 -32t0 -64t56 -32zM1665 442q-10 13 -38.5 50t-41.5 54t-38 49t-42.5 53t-40.5 47t-45 49l-125 -140q-83 -94 -208.5 -92t-205.5 98q-57 69 -56.5 158t58.5 157l177 206q-22 11 -51 16.5t-47.5 6t-56.5 -0.5t-49 -1q-92 0 -158 -66
-l-158 -158h-155v-544q5 0 21 0.5t22 0t19.5 -2t20.5 -4.5t17.5 -8.5t18.5 -13.5l297 -292q115 -111 227 -111q78 0 125 47q57 -20 112.5 8t72.5 85q74 -6 127 44q20 18 36 45.5t14 50.5q10 -10 43 -10q43 0 77 21t49.5 53t12 71.5t-30.5 73.5zM1824 384h96v512h-93l-157 180
-q-66 76 -169 76h-167q-89 0 -146 -67l-209 -243q-28 -33 -28 -75t27 -75q43 -51 110 -52t111 49l193 218q25 23 53.5 21.5t47 -27t8.5 -56.5q16 -19 56 -63t60 -68q29 -36 82.5 -105.5t64.5 -84.5q52 -66 60 -140zM2112 384q40 0 56 32t0 64t-56 32t-56 -32t0 -64t56 -32z
-M2304 960v-640q0 -26 -19 -45t-45 -19h-434q-27 -65 -82 -106.5t-125 -51.5q-33 -48 -80.5 -81.5t-102.5 -45.5q-42 -53 -104.5 -81.5t-128.5 -24.5q-60 -34 -126 -39.5t-127.5 14t-117 53.5t-103.5 81l-287 282h-358q-26 0 -45 19t-19 45v672q0 26 19 45t45 19h421
-q14 14 47 48t47.5 48t44 40t50.5 37.5t51 25.5t62 19.5t68 5.5h117q99 0 181 -56q82 56 181 56h167q35 0 67 -6t56.5 -14.5t51.5 -26.5t44.5 -31t43 -39.5t39 -42t41 -48t41.5 -48.5h355q26 0 45 -19t19 -45z" />
-    <glyph glyph-name="uniF2B6" unicode="&#xf2b6;" horiz-adv-x="1792" 
-d="M1792 882v-978q0 -66 -47 -113t-113 -47h-1472q-66 0 -113 47t-47 113v978q0 15 11 24q8 7 39 34.5t41.5 36t45.5 37.5t70 55.5t96 73t143.5 107t192.5 140.5q5 4 52.5 40t71.5 52.5t64 35t69 18.5t69 -18.5t65 -35.5t71 -52t52 -40q110 -80 192.5 -140.5t143.5 -107
-t96 -73t70 -55.5t45.5 -37.5t41.5 -36t39 -34.5q11 -9 11 -24zM1228 297q263 191 345 252q11 8 12.5 20.5t-6.5 23.5l-38 52q-8 11 -21 12.5t-24 -6.5q-231 -169 -343 -250q-5 -3 -52 -39t-71.5 -52.5t-64.5 -35t-69 -18.5t-69 18.5t-64.5 35t-71.5 52.5t-52 39
-q-186 134 -343 250q-11 8 -24 6.5t-21 -12.5l-38 -52q-8 -11 -6.5 -23.5t12.5 -20.5q82 -61 345 -252q10 -8 50 -38t65 -47t64 -39.5t77.5 -33.5t75.5 -11t75.5 11t79 34.5t64.5 39.5t65 47.5t48 36.5z" />
-    <glyph glyph-name="uniF2B7" unicode="&#xf2b7;" horiz-adv-x="1792" 
-d="M1474 623l39 -51q8 -11 6.5 -23.5t-11.5 -20.5q-43 -34 -126.5 -98.5t-146.5 -113t-67 -51.5q-39 -32 -60 -48t-60.5 -41t-76.5 -36.5t-74 -11.5h-1h-1q-37 0 -74 11.5t-76 36.5t-61 41.5t-60 47.5q-5 4 -65 50.5t-143.5 111t-122.5 94.5q-11 8 -12.5 20.5t6.5 23.5
-l37 52q8 11 21.5 13t24.5 -7q94 -73 306 -236q5 -4 43.5 -35t60.5 -46.5t56.5 -32.5t58.5 -17h1h1q24 0 58.5 17t56.5 32.5t60.5 46.5t43.5 35q258 198 313 242q11 8 24 6.5t21 -12.5zM1664 -96v928q-90 83 -159 139q-91 74 -389 304q-3 2 -43 35t-61 48t-56 32.5t-59 17.5
-h-1h-1q-24 0 -59 -17.5t-56 -32.5t-61 -48t-43 -35q-215 -166 -315.5 -245.5t-129.5 -104t-82 -74.5q-14 -12 -21 -19v-928q0 -13 9.5 -22.5t22.5 -9.5h1472q13 0 22.5 9.5t9.5 22.5zM1792 832v-928q0 -66 -47 -113t-113 -47h-1472q-66 0 -113 47t-47 113v928q0 56 41 94
-q123 114 350 290.5t233 181.5q36 30 59 47.5t61.5 42t76 36.5t74.5 12h1h1q37 0 74.5 -12t76 -36.5t61.5 -42t59 -47.5q43 -36 156 -122t226 -177t201 -173q41 -38 41 -94z" />
-    <glyph glyph-name="uniF2B8" unicode="&#xf2b8;" 
-d="M330 1l202 -214l-34 236l-216 213zM556 -225l274 218l-11 245l-300 -215zM245 413l227 -213l-48 327l-245 204zM495 189l317 214l-14 324l-352 -200zM843 178l95 -80l-2 239l-103 79q0 -1 1 -8.5t0 -12t-5 -7.5l-78 -52l85 -70q7 -6 7 -88zM138 930l256 -200l-68 465
-l-279 173zM1173 267l15 234l-230 -164l2 -240zM417 722l373 194l-19 441l-423 -163zM1270 357l20 233l-226 142l-2 -105l144 -95q6 -4 4 -9l-7 -119zM1461 496l30 222l-179 -128l-20 -228zM1273 329l-71 49l-8 -117q0 -5 -4 -8l-234 -187q-7 -5 -14 0l-98 83l7 -161
-q0 -5 -4 -8l-293 -234q-4 -2 -6 -2q-8 2 -8 3l-228 242q-4 4 -59 277q-2 7 5 11l61 37q-94 86 -95 92l-72 351q-2 7 6 12l94 45q-133 100 -135 108l-96 466q-2 10 7 13l433 135q5 0 8 -1l317 -153q6 -4 6 -9l20 -463q0 -7 -6 -10l-118 -61l126 -85q5 -2 5 -8l5 -123l121 74
-q5 4 11 0l84 -56l3 110q0 6 5 9l206 126q6 3 11 0l245 -135q4 -4 5 -7t-6.5 -60t-17.5 -124.5t-10 -70.5q0 -5 -4 -7l-191 -153q-6 -5 -13 0z" />
-    <glyph glyph-name="uniF2B9" unicode="&#xf2b9;" horiz-adv-x="1664" 
-d="M1201 298q0 57 -5.5 107t-21 100.5t-39.5 86t-64 58t-91 22.5q-6 -4 -33.5 -20.5t-42.5 -24.5t-40.5 -20t-49 -17t-46.5 -5t-46.5 5t-49 17t-40.5 20t-42.5 24.5t-33.5 20.5q-51 0 -91 -22.5t-64 -58t-39.5 -86t-21 -100.5t-5.5 -107q0 -73 42 -121.5t103 -48.5h576
-q61 0 103 48.5t42 121.5zM1028 892q0 108 -76.5 184t-183.5 76t-183.5 -76t-76.5 -184q0 -107 76.5 -183t183.5 -76t183.5 76t76.5 183zM1664 352v-192q0 -14 -9 -23t-23 -9h-96v-224q0 -66 -47 -113t-113 -47h-1216q-66 0 -113 47t-47 113v1472q0 66 47 113t113 47h1216
-q66 0 113 -47t47 -113v-224h96q14 0 23 -9t9 -23v-192q0 -14 -9 -23t-23 -9h-96v-128h96q14 0 23 -9t9 -23v-192q0 -14 -9 -23t-23 -9h-96v-128h96q14 0 23 -9t9 -23z" />
-    <glyph glyph-name="uniF2BA" unicode="&#xf2ba;" horiz-adv-x="1664" 
-d="M1028 892q0 -107 -76.5 -183t-183.5 -76t-183.5 76t-76.5 183q0 108 76.5 184t183.5 76t183.5 -76t76.5 -184zM980 672q46 0 82.5 -17t60 -47.5t39.5 -67t24 -81t11.5 -82.5t3.5 -79q0 -67 -39.5 -118.5t-105.5 -51.5h-576q-66 0 -105.5 51.5t-39.5 118.5q0 48 4.5 93.5
-t18.5 98.5t36.5 91.5t63 64.5t93.5 26h5q7 -4 32 -19.5t35.5 -21t33 -17t37 -16t35 -9t39.5 -4.5t39.5 4.5t35 9t37 16t33 17t35.5 21t32 19.5zM1664 928q0 -13 -9.5 -22.5t-22.5 -9.5h-96v-128h96q13 0 22.5 -9.5t9.5 -22.5v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-96v-128h96
-q13 0 22.5 -9.5t9.5 -22.5v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-96v-224q0 -66 -47 -113t-113 -47h-1216q-66 0 -113 47t-47 113v1472q0 66 47 113t113 47h1216q66 0 113 -47t47 -113v-224h96q13 0 22.5 -9.5t9.5 -22.5v-192zM1408 -96v1472q0 13 -9.5 22.5t-22.5 9.5h-1216
-q-13 0 -22.5 -9.5t-9.5 -22.5v-1472q0 -13 9.5 -22.5t22.5 -9.5h1216q13 0 22.5 9.5t9.5 22.5z" />
-    <glyph glyph-name="uniF2BB" unicode="&#xf2bb;" horiz-adv-x="2048" 
-d="M1024 405q0 64 -9 117.5t-29.5 103t-60.5 78t-97 28.5q-6 -4 -30 -18t-37.5 -21.5t-35.5 -17.5t-43 -14.5t-42 -4.5t-42 4.5t-43 14.5t-35.5 17.5t-37.5 21.5t-30 18q-57 0 -97 -28.5t-60.5 -78t-29.5 -103t-9 -117.5t37 -106.5t91 -42.5h512q54 0 91 42.5t37 106.5z
-M867 925q0 94 -66.5 160.5t-160.5 66.5t-160.5 -66.5t-66.5 -160.5t66.5 -160.5t160.5 -66.5t160.5 66.5t66.5 160.5zM1792 416v64q0 14 -9 23t-23 9h-576q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h576q14 0 23 9t9 23zM1792 676v56q0 15 -10.5 25.5t-25.5 10.5h-568
-q-15 0 -25.5 -10.5t-10.5 -25.5v-56q0 -15 10.5 -25.5t25.5 -10.5h568q15 0 25.5 10.5t10.5 25.5zM1792 928v64q0 14 -9 23t-23 9h-576q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h576q14 0 23 9t9 23zM2048 1248v-1216q0 -66 -47 -113t-113 -47h-352v96q0 14 -9 23t-23 9
-h-64q-14 0 -23 -9t-9 -23v-96h-768v96q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-96h-352q-66 0 -113 47t-47 113v1216q0 66 47 113t113 47h1728q66 0 113 -47t47 -113z" />
-    <glyph glyph-name="uniF2BC" unicode="&#xf2bc;" horiz-adv-x="2048" 
-d="M1024 405q0 -64 -37 -106.5t-91 -42.5h-512q-54 0 -91 42.5t-37 106.5t9 117.5t29.5 103t60.5 78t97 28.5q6 -4 30 -18t37.5 -21.5t35.5 -17.5t43 -14.5t42 -4.5t42 4.5t43 14.5t35.5 17.5t37.5 21.5t30 18q57 0 97 -28.5t60.5 -78t29.5 -103t9 -117.5zM867 925
-q0 -94 -66.5 -160.5t-160.5 -66.5t-160.5 66.5t-66.5 160.5t66.5 160.5t160.5 66.5t160.5 -66.5t66.5 -160.5zM1792 480v-64q0 -14 -9 -23t-23 -9h-576q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h576q14 0 23 -9t9 -23zM1792 732v-56q0 -15 -10.5 -25.5t-25.5 -10.5h-568
-q-15 0 -25.5 10.5t-10.5 25.5v56q0 15 10.5 25.5t25.5 10.5h568q15 0 25.5 -10.5t10.5 -25.5zM1792 992v-64q0 -14 -9 -23t-23 -9h-576q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h576q14 0 23 -9t9 -23zM1920 32v1216q0 13 -9.5 22.5t-22.5 9.5h-1728q-13 0 -22.5 -9.5
-t-9.5 -22.5v-1216q0 -13 9.5 -22.5t22.5 -9.5h352v96q0 14 9 23t23 9h64q14 0 23 -9t9 -23v-96h768v96q0 14 9 23t23 9h64q14 0 23 -9t9 -23v-96h352q13 0 22.5 9.5t9.5 22.5zM2048 1248v-1216q0 -66 -47 -113t-113 -47h-1728q-66 0 -113 47t-47 113v1216q0 66 47 113
-t113 47h1728q66 0 113 -47t47 -113z" />
-    <glyph glyph-name="uniF2BD" unicode="&#xf2bd;" horiz-adv-x="1792" 
-d="M1523 197q-22 155 -87.5 257.5t-184.5 118.5q-67 -74 -159.5 -115.5t-195.5 -41.5t-195.5 41.5t-159.5 115.5q-119 -16 -184.5 -118.5t-87.5 -257.5q106 -150 271 -237.5t356 -87.5t356 87.5t271 237.5zM1280 896q0 159 -112.5 271.5t-271.5 112.5t-271.5 -112.5
-t-112.5 -271.5t112.5 -271.5t271.5 -112.5t271.5 112.5t112.5 271.5zM1792 640q0 -182 -71 -347.5t-190.5 -286t-285.5 -191.5t-349 -71q-182 0 -348 71t-286 191t-191 286t-71 348t71 348t191 286t286 191t348 71t348 -71t286 -191t191 -286t71 -348z" />
-    <glyph glyph-name="uniF2BE" unicode="&#xf2be;" horiz-adv-x="1792" 
-d="M896 1536q182 0 348 -71t286 -191t191 -286t71 -348q0 -181 -70.5 -347t-190.5 -286t-286 -191.5t-349 -71.5t-349 71t-285.5 191.5t-190.5 286t-71 347.5t71 348t191 286t286 191t348 71zM1515 185q149 205 149 455q0 156 -61 298t-164 245t-245 164t-298 61t-298 -61
-t-245 -164t-164 -245t-61 -298q0 -250 149 -455q66 327 306 327q131 -128 313 -128t313 128q240 0 306 -327zM1280 832q0 159 -112.5 271.5t-271.5 112.5t-271.5 -112.5t-112.5 -271.5t112.5 -271.5t271.5 -112.5t271.5 112.5t112.5 271.5z" />
-    <glyph glyph-name="uniF2C0" unicode="&#xf2c0;" 
-d="M1201 752q47 -14 89.5 -38t89 -73t79.5 -115.5t55 -172t22 -236.5q0 -154 -100 -263.5t-241 -109.5h-854q-141 0 -241 109.5t-100 263.5q0 131 22 236.5t55 172t79.5 115.5t89 73t89.5 38q-79 125 -79 272q0 104 40.5 198.5t109.5 163.5t163.5 109.5t198.5 40.5
-t198.5 -40.5t163.5 -109.5t109.5 -163.5t40.5 -198.5q0 -147 -79 -272zM768 1408q-159 0 -271.5 -112.5t-112.5 -271.5t112.5 -271.5t271.5 -112.5t271.5 112.5t112.5 271.5t-112.5 271.5t-271.5 112.5zM1195 -128q88 0 150.5 71.5t62.5 173.5q0 239 -78.5 377t-225.5 145
-q-145 -127 -336 -127t-336 127q-147 -7 -225.5 -145t-78.5 -377q0 -102 62.5 -173.5t150.5 -71.5h854z" />
-    <glyph glyph-name="uniF2C1" unicode="&#xf2c1;" horiz-adv-x="1280" 
-d="M1024 278q0 -64 -37 -107t-91 -43h-512q-54 0 -91 43t-37 107t9 118t29.5 104t61 78.5t96.5 28.5q80 -75 188 -75t188 75q56 0 96.5 -28.5t61 -78.5t29.5 -104t9 -118zM870 797q0 -94 -67.5 -160.5t-162.5 -66.5t-162.5 66.5t-67.5 160.5t67.5 160.5t162.5 66.5
-t162.5 -66.5t67.5 -160.5zM1152 -96v1376h-1024v-1376q0 -13 9.5 -22.5t22.5 -9.5h960q13 0 22.5 9.5t9.5 22.5zM1280 1376v-1472q0 -66 -47 -113t-113 -47h-960q-66 0 -113 47t-47 113v1472q0 66 47 113t113 47h352v-96q0 -14 9 -23t23 -9h192q14 0 23 9t9 23v96h352
-q66 0 113 -47t47 -113z" />
-    <glyph glyph-name="uniF2C2" unicode="&#xf2c2;" horiz-adv-x="2048" 
-d="M896 324q0 54 -7.5 100.5t-24.5 90t-51 68.5t-81 25q-64 -64 -156 -64t-156 64q-47 0 -81 -25t-51 -68.5t-24.5 -90t-7.5 -100.5q0 -55 31.5 -93.5t75.5 -38.5h426q44 0 75.5 38.5t31.5 93.5zM768 768q0 80 -56 136t-136 56t-136 -56t-56 -136t56 -136t136 -56t136 56
-t56 136zM1792 288v64q0 14 -9 23t-23 9h-704q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h704q14 0 23 9t9 23zM1408 544v64q0 14 -9 23t-23 9h-320q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h320q14 0 23 9t9 23zM1792 544v64q0 14 -9 23t-23 9h-192q-14 0 -23 -9t-9 -23
-v-64q0 -14 9 -23t23 -9h192q14 0 23 9t9 23zM1792 800v64q0 14 -9 23t-23 9h-704q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h704q14 0 23 9t9 23zM128 1152h1792v96q0 14 -9 23t-23 9h-1728q-14 0 -23 -9t-9 -23v-96zM2048 1248v-1216q0 -66 -47 -113t-113 -47h-1728
-q-66 0 -113 47t-47 113v1216q0 66 47 113t113 47h1728q66 0 113 -47t47 -113z" />
-    <glyph glyph-name="uniF2C3" unicode="&#xf2c3;" horiz-adv-x="2048" 
-d="M896 324q0 -55 -31.5 -93.5t-75.5 -38.5h-426q-44 0 -75.5 38.5t-31.5 93.5q0 54 7.5 100.5t24.5 90t51 68.5t81 25q64 -64 156 -64t156 64q47 0 81 -25t51 -68.5t24.5 -90t7.5 -100.5zM768 768q0 -80 -56 -136t-136 -56t-136 56t-56 136t56 136t136 56t136 -56t56 -136z
-M1792 352v-64q0 -14 -9 -23t-23 -9h-704q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h704q14 0 23 -9t9 -23zM1408 608v-64q0 -14 -9 -23t-23 -9h-320q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h320q14 0 23 -9t9 -23zM1792 608v-64q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v64
-q0 14 9 23t23 9h192q14 0 23 -9t9 -23zM1792 864v-64q0 -14 -9 -23t-23 -9h-704q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h704q14 0 23 -9t9 -23zM1920 32v1120h-1792v-1120q0 -13 9.5 -22.5t22.5 -9.5h1728q13 0 22.5 9.5t9.5 22.5zM2048 1248v-1216q0 -66 -47 -113t-113 -47
-h-1728q-66 0 -113 47t-47 113v1216q0 66 47 113t113 47h1728q66 0 113 -47t47 -113z" />
-    <glyph glyph-name="uniF2C4" unicode="&#xf2c4;" horiz-adv-x="1792" 
-d="M1255 749q0 318 -105 474.5t-330 156.5q-222 0 -326 -157t-104 -474q0 -316 104 -471.5t326 -155.5q74 0 131 17q-22 43 -39 73t-44 65t-53.5 56.5t-63 36t-77.5 14.5q-46 0 -79 -16l-49 97q105 91 276 91q132 0 215.5 -54t150.5 -155q67 149 67 402zM1645 117h117
-q3 -27 -2 -67t-26.5 -95t-58 -100.5t-107 -78t-162.5 -32.5q-71 0 -130.5 19t-105.5 56t-79 78t-66 96q-97 -27 -205 -27q-150 0 -292.5 58t-253 158.5t-178 249t-67.5 317.5q0 170 67.5 319.5t178.5 250.5t253.5 159t291.5 58q121 0 238.5 -36t217 -106t176 -164.5
-t119.5 -219t43 -261.5q0 -190 -80.5 -347.5t-218.5 -264.5q47 -70 93.5 -106.5t104.5 -36.5q61 0 94 37.5t38 85.5z" />
-    <glyph glyph-name="uniF2C5" unicode="&#xf2c5;" horiz-adv-x="2304" 
-d="M453 -101q0 -21 -16 -37.5t-37 -16.5q-1 0 -13 3q-63 15 -162 140q-225 284 -225 676q0 341 213 614q39 51 95 103.5t94 52.5q19 0 35 -13.5t16 -32.5q0 -27 -63 -90q-98 -102 -147 -184q-119 -199 -119 -449q0 -281 123 -491q50 -85 136 -173q2 -3 14.5 -16t19.5 -21
-t17 -20.5t14.5 -23.5t4.5 -21zM1796 33q0 -29 -17.5 -48.5t-46.5 -19.5h-1081q-26 0 -45 19t-19 45q0 29 17.5 48.5t46.5 19.5h1081q26 0 45 -19t19 -45zM1581 644q0 -134 -67 -233q-25 -38 -69.5 -78.5t-83.5 -60.5q-16 -10 -27 -10q-7 0 -15 6t-8 12q0 9 19 30t42 46
-t42 67.5t19 88.5q0 76 -35 130q-29 42 -46 42q-3 0 -3 -5q0 -12 7.5 -35.5t7.5 -36.5q0 -22 -21.5 -35t-44.5 -13q-66 0 -66 76q0 15 1.5 44t1.5 44q0 25 -10 46q-13 25 -42 53.5t-51 28.5q-5 0 -7 -0.5t-3.5 -2.5t-1.5 -6q0 -2 16 -26t16 -54q0 -37 -19 -68t-46 -54
-t-53.5 -46t-45.5 -54t-19 -68q0 -98 42 -160q29 -43 79 -63q16 -5 17 -10q1 -2 1 -5q0 -16 -18 -16q-6 0 -33 11q-119 43 -195 139.5t-76 218.5q0 55 24.5 115.5t60 115t70.5 108.5t59.5 113.5t24.5 111.5q0 53 -25 94q-29 48 -56 64q-19 9 -19 21q0 20 41 20q50 0 110 -29
-q41 -19 71 -44.5t49.5 -51t33.5 -62.5t22 -69t16 -80q0 -1 3 -17.5t4.5 -25t5.5 -25t9 -27t11 -21.5t14.5 -16.5t18.5 -5.5q23 0 37 14t14 37q0 25 -20 67t-20 52t10 10q27 0 93 -70q72 -76 102.5 -156t30.5 -186zM2304 615q0 -274 -138 -503q-19 -32 -48 -72t-68 -86.5
-t-81 -77t-74 -30.5q-16 0 -31 15.5t-15 31.5q0 15 29 50.5t68.5 77t48.5 52.5q183 230 183 531q0 131 -20.5 235t-72.5 211q-58 119 -163 228q-2 3 -13 13.5t-16.5 16.5t-15 17.5t-15 20t-9.5 18.5t-4 19q0 19 16 35.5t35 16.5q70 0 196 -169q98 -131 146 -273t60 -314
-q2 -42 2 -64z" />
-    <glyph glyph-name="uniF2C6" unicode="&#xf2c6;" horiz-adv-x="1792" 
-d="M1189 229l147 693q9 44 -10.5 63t-51.5 7l-864 -333q-29 -11 -39.5 -25t-2.5 -26.5t32 -19.5l221 -69l513 323q21 14 32 6q7 -5 -4 -15l-415 -375v0v0l-16 -228q23 0 45 22l108 104l224 -165q64 -36 81 38zM1792 640q0 -182 -71 -348t-191 -286t-286 -191t-348 -71
-t-348 71t-286 191t-191 286t-71 348t71 348t191 286t286 191t348 71t348 -71t286 -191t191 -286t71 -348z" />
-    <glyph glyph-name="uniF2C7" unicode="&#xf2c7;" horiz-adv-x="1024" 
-d="M640 192q0 -80 -56 -136t-136 -56t-136 56t-56 136q0 60 35 110t93 71v907h128v-907q58 -21 93 -71t35 -110zM768 192q0 77 -34 144t-94 112v768q0 80 -56 136t-136 56t-136 -56t-56 -136v-768q-60 -45 -94 -112t-34 -144q0 -133 93.5 -226.5t226.5 -93.5t226.5 93.5
-t93.5 226.5zM896 192q0 -185 -131.5 -316.5t-316.5 -131.5t-316.5 131.5t-131.5 316.5q0 182 128 313v711q0 133 93.5 226.5t226.5 93.5t226.5 -93.5t93.5 -226.5v-711q128 -131 128 -313zM1024 768v-128h-192v128h192zM1024 1024v-128h-192v128h192zM1024 1280v-128h-192
-v128h192z" />
-    <glyph glyph-name="uniF2C8" unicode="&#xf2c8;" horiz-adv-x="1024" 
-d="M640 192q0 -80 -56 -136t-136 -56t-136 56t-56 136q0 60 35 110t93 71v651h128v-651q58 -21 93 -71t35 -110zM768 192q0 77 -34 144t-94 112v768q0 80 -56 136t-136 56t-136 -56t-56 -136v-768q-60 -45 -94 -112t-34 -144q0 -133 93.5 -226.5t226.5 -93.5t226.5 93.5
-t93.5 226.5zM896 192q0 -185 -131.5 -316.5t-316.5 -131.5t-316.5 131.5t-131.5 316.5q0 182 128 313v711q0 133 93.5 226.5t226.5 93.5t226.5 -93.5t93.5 -226.5v-711q128 -131 128 -313zM1024 768v-128h-192v128h192zM1024 1024v-128h-192v128h192zM1024 1280v-128h-192
-v128h192z" />
-    <glyph glyph-name="uniF2C9" unicode="&#xf2c9;" horiz-adv-x="1024" 
-d="M640 192q0 -80 -56 -136t-136 -56t-136 56t-56 136q0 60 35 110t93 71v395h128v-395q58 -21 93 -71t35 -110zM768 192q0 77 -34 144t-94 112v768q0 80 -56 136t-136 56t-136 -56t-56 -136v-768q-60 -45 -94 -112t-34 -144q0 -133 93.5 -226.5t226.5 -93.5t226.5 93.5
-t93.5 226.5zM896 192q0 -185 -131.5 -316.5t-316.5 -131.5t-316.5 131.5t-131.5 316.5q0 182 128 313v711q0 133 93.5 226.5t226.5 93.5t226.5 -93.5t93.5 -226.5v-711q128 -131 128 -313zM1024 768v-128h-192v128h192zM1024 1024v-128h-192v128h192zM1024 1280v-128h-192
-v128h192z" />
-    <glyph glyph-name="uniF2CA" unicode="&#xf2ca;" horiz-adv-x="1024" 
-d="M640 192q0 -80 -56 -136t-136 -56t-136 56t-56 136q0 60 35 110t93 71v139h128v-139q58 -21 93 -71t35 -110zM768 192q0 77 -34 144t-94 112v768q0 80 -56 136t-136 56t-136 -56t-56 -136v-768q-60 -45 -94 -112t-34 -144q0 -133 93.5 -226.5t226.5 -93.5t226.5 93.5
-t93.5 226.5zM896 192q0 -185 -131.5 -316.5t-316.5 -131.5t-316.5 131.5t-131.5 316.5q0 182 128 313v711q0 133 93.5 226.5t226.5 93.5t226.5 -93.5t93.5 -226.5v-711q128 -131 128 -313zM1024 768v-128h-192v128h192zM1024 1024v-128h-192v128h192zM1024 1280v-128h-192
-v128h192z" />
-    <glyph glyph-name="uniF2CB" unicode="&#xf2cb;" horiz-adv-x="1024" 
-d="M640 192q0 -80 -56 -136t-136 -56t-136 56t-56 136q0 79 56 135.5t136 56.5t136 -56.5t56 -135.5zM768 192q0 77 -34 144t-94 112v768q0 80 -56 136t-136 56t-136 -56t-56 -136v-768q-60 -45 -94 -112t-34 -144q0 -133 93.5 -226.5t226.5 -93.5t226.5 93.5t93.5 226.5z
-M896 192q0 -185 -131.5 -316.5t-316.5 -131.5t-316.5 131.5t-131.5 316.5q0 182 128 313v711q0 133 93.5 226.5t226.5 93.5t226.5 -93.5t93.5 -226.5v-711q128 -131 128 -313zM1024 768v-128h-192v128h192zM1024 1024v-128h-192v128h192zM1024 1280v-128h-192v128h192z" />
-    <glyph glyph-name="uniF2CC" unicode="&#xf2cc;" horiz-adv-x="1920" 
-d="M1433 1287q10 -10 10 -23t-10 -23l-626 -626q-10 -10 -23 -10t-23 10l-82 82q-10 10 -10 23t10 23l44 44q-72 91 -81.5 207t46.5 215q-74 71 -176 71q-106 0 -181 -75t-75 -181v-1280h-256v1280q0 104 40.5 198.5t109.5 163.5t163.5 109.5t198.5 40.5q106 0 201 -41
-t166 -115q94 39 197 24.5t185 -79.5l44 44q10 10 23 10t23 -10zM1344 1024q26 0 45 -19t19 -45t-19 -45t-45 -19t-45 19t-19 45t19 45t45 19zM1600 896q-26 0 -45 19t-19 45t19 45t45 19t45 -19t19 -45t-19 -45t-45 -19zM1856 1024q26 0 45 -19t19 -45t-19 -45t-45 -19
-t-45 19t-19 45t19 45t45 19zM1216 896q26 0 45 -19t19 -45t-19 -45t-45 -19t-45 19t-19 45t19 45t45 19zM1408 832q0 26 19 45t45 19t45 -19t19 -45t-19 -45t-45 -19t-45 19t-19 45zM1728 896q26 0 45 -19t19 -45t-19 -45t-45 -19t-45 19t-19 45t19 45t45 19zM1088 768
-q26 0 45 -19t19 -45t-19 -45t-45 -19t-45 19t-19 45t19 45t45 19zM1344 640q-26 0 -45 19t-19 45t19 45t45 19t45 -19t19 -45t-19 -45t-45 -19zM1600 768q26 0 45 -19t19 -45t-19 -45t-45 -19t-45 19t-19 45t19 45t45 19zM1216 512q-26 0 -45 19t-19 45t19 45t45 19t45 -19
-t19 -45t-19 -45t-45 -19zM1472 640q26 0 45 -19t19 -45t-19 -45t-45 -19t-45 19t-19 45t19 45t45 19zM1088 512q26 0 45 -19t19 -45t-19 -45t-45 -19t-45 19t-19 45t19 45t45 19zM1344 512q26 0 45 -19t19 -45t-19 -45t-45 -19t-45 19t-19 45t19 45t45 19zM1216 384
-q26 0 45 -19t19 -45t-19 -45t-45 -19t-45 19t-19 45t19 45t45 19zM1088 256q26 0 45 -19t19 -45t-19 -45t-45 -19t-45 19t-19 45t19 45t45 19z" />
-    <glyph glyph-name="uniF2CD" unicode="&#xf2cd;" horiz-adv-x="1792" 
-d="M1664 448v-192q0 -169 -128 -286v-194q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v118q-63 -22 -128 -22h-768q-65 0 -128 22v-110q0 -17 -9.5 -28.5t-22.5 -11.5h-64q-13 0 -22.5 11.5t-9.5 28.5v186q-128 117 -128 286v192h1536zM704 864q0 -14 -9 -23t-23 -9t-23 9
-t-9 23t9 23t23 9t23 -9t9 -23zM768 928q0 -14 -9 -23t-23 -9t-23 9t-9 23t9 23t23 9t23 -9t9 -23zM704 992q0 -14 -9 -23t-23 -9t-23 9t-9 23t9 23t23 9t23 -9t9 -23zM832 992q0 -14 -9 -23t-23 -9t-23 9t-9 23t9 23t23 9t23 -9t9 -23zM768 1056q0 -14 -9 -23t-23 -9t-23 9
-t-9 23t9 23t23 9t23 -9t9 -23zM704 1120q0 -14 -9 -23t-23 -9t-23 9t-9 23t9 23t23 9t23 -9t9 -23zM1792 608v-64q0 -14 -9 -23t-23 -9h-1728q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h96v640q0 106 75 181t181 75q108 0 184 -78q46 19 98 12t93 -39l22 22q11 11 22 0l42 -42
-q11 -11 0 -22l-314 -314q-11 -11 -22 0l-42 42q-11 11 0 22l22 22q-36 46 -40.5 104t23.5 108q-37 35 -88 35q-53 0 -90.5 -37.5t-37.5 -90.5v-640h1504q14 0 23 -9t9 -23zM896 1056q0 -14 -9 -23t-23 -9t-23 9t-9 23t9 23t23 9t23 -9t9 -23zM832 1120q0 -14 -9 -23t-23 -9
-t-23 9t-9 23t9 23t23 9t23 -9t9 -23zM768 1184q0 -14 -9 -23t-23 -9t-23 9t-9 23t9 23t23 9t23 -9t9 -23zM960 1120q0 -14 -9 -23t-23 -9t-23 9t-9 23t9 23t23 9t23 -9t9 -23zM896 1184q0 -14 -9 -23t-23 -9t-23 9t-9 23t9 23t23 9t23 -9t9 -23zM832 1248q0 -14 -9 -23
-t-23 -9t-23 9t-9 23t9 23t23 9t23 -9t9 -23zM1024 1184q0 -14 -9 -23t-23 -9t-23 9t-9 23t9 23t23 9t23 -9t9 -23zM960 1248q0 -14 -9 -23t-23 -9t-23 9t-9 23t9 23t23 9t23 -9t9 -23zM1088 1248q0 -14 -9 -23t-23 -9t-23 9t-9 23t9 23t23 9t23 -9t9 -23z" />
-    <glyph glyph-name="uniF2CE" unicode="&#xf2ce;" 
-d="M994 344q0 -86 -17 -197q-31 -215 -55 -313q-22 -90 -152 -90t-152 90q-24 98 -55 313q-17 110 -17 197q0 168 224 168t224 -168zM1536 768q0 -240 -134 -434t-350 -280q-8 -3 -15 3t-6 15q7 48 10 66q4 32 6 47q1 9 9 12q159 81 255.5 234t96.5 337q0 180 -91 330.5
-t-247 234.5t-337 74q-124 -7 -237 -61t-193.5 -140.5t-128 -202t-46.5 -240.5q1 -184 99 -336.5t257 -231.5q7 -3 9 -12q3 -21 6 -45q1 -9 5 -32.5t6 -35.5q1 -9 -6.5 -15t-15.5 -2q-148 58 -261 169.5t-173.5 264t-52.5 319.5q7 143 66 273.5t154.5 227t225 157.5t272.5 70
-q164 10 315.5 -46.5t261 -160.5t175 -250.5t65.5 -308.5zM994 800q0 -93 -65.5 -158.5t-158.5 -65.5t-158.5 65.5t-65.5 158.5t65.5 158.5t158.5 65.5t158.5 -65.5t65.5 -158.5zM1282 768q0 -122 -53.5 -228.5t-146.5 -177.5q-8 -6 -16 -2t-10 14q-6 52 -29 92q-7 10 3 20
-q58 54 91 127t33 155q0 111 -58.5 204t-157.5 141.5t-212 36.5q-133 -15 -229 -113t-109 -231q-10 -92 23.5 -176t98.5 -144q10 -10 3 -20q-24 -41 -29 -93q-2 -9 -10 -13t-16 2q-95 74 -148.5 183t-51.5 234q3 131 69 244t177 181.5t241 74.5q144 7 268 -60t196.5 -187.5
-t72.5 -263.5z" />
-    <glyph glyph-name="uniF2D0" unicode="&#xf2d0;" horiz-adv-x="1792" 
-d="M256 128h1280v768h-1280v-768zM1792 1248v-1216q0 -66 -47 -113t-113 -47h-1472q-66 0 -113 47t-47 113v1216q0 66 47 113t113 47h1472q66 0 113 -47t47 -113z" />
-    <glyph glyph-name="uniF2D1" unicode="&#xf2d1;" horiz-adv-x="1792" 
-d="M1792 224v-192q0 -66 -47 -113t-113 -47h-1472q-66 0 -113 47t-47 113v192q0 66 47 113t113 47h1472q66 0 113 -47t47 -113z" />
-    <glyph glyph-name="uniF2D2" unicode="&#xf2d2;" horiz-adv-x="2048" 
-d="M256 0h768v512h-768v-512zM1280 512h512v768h-768v-256h96q66 0 113 -47t47 -113v-352zM2048 1376v-960q0 -66 -47 -113t-113 -47h-608v-352q0 -66 -47 -113t-113 -47h-960q-66 0 -113 47t-47 113v960q0 66 47 113t113 47h608v352q0 66 47 113t113 47h960q66 0 113 -47
-t47 -113z" />
-    <glyph glyph-name="uniF2D3" unicode="&#xf2d3;" horiz-adv-x="1792" 
-d="M1175 215l146 146q10 10 10 23t-10 23l-233 233l233 233q10 10 10 23t-10 23l-146 146q-10 10 -23 10t-23 -10l-233 -233l-233 233q-10 10 -23 10t-23 -10l-146 -146q-10 -10 -10 -23t10 -23l233 -233l-233 -233q-10 -10 -10 -23t10 -23l146 -146q10 -10 23 -10t23 10
-l233 233l233 -233q10 -10 23 -10t23 10zM1792 1248v-1216q0 -66 -47 -113t-113 -47h-1472q-66 0 -113 47t-47 113v1216q0 66 47 113t113 47h1472q66 0 113 -47t47 -113z" />
-    <glyph glyph-name="uniF2D4" unicode="&#xf2d4;" horiz-adv-x="1792" 
-d="M1257 425l-146 -146q-10 -10 -23 -10t-23 10l-169 169l-169 -169q-10 -10 -23 -10t-23 10l-146 146q-10 10 -10 23t10 23l169 169l-169 169q-10 10 -10 23t10 23l146 146q10 10 23 10t23 -10l169 -169l169 169q10 10 23 10t23 -10l146 -146q10 -10 10 -23t-10 -23
-l-169 -169l169 -169q10 -10 10 -23t-10 -23zM256 128h1280v1024h-1280v-1024zM1792 1248v-1216q0 -66 -47 -113t-113 -47h-1472q-66 0 -113 47t-47 113v1216q0 66 47 113t113 47h1472q66 0 113 -47t47 -113z" />
-    <glyph glyph-name="uniF2D5" unicode="&#xf2d5;" horiz-adv-x="1792" 
-d="M1070 358l306 564h-654l-306 -564h654zM1792 640q0 -182 -71 -348t-191 -286t-286 -191t-348 -71t-348 71t-286 191t-191 286t-71 348t71 348t191 286t286 191t348 71t348 -71t286 -191t191 -286t71 -348z" />
-    <glyph glyph-name="uniF2D6" unicode="&#xf2d6;" horiz-adv-x="1794" 
-d="M1291 1060q-15 17 -35 8.5t-26 -28.5t5 -38q14 -17 40 -14.5t34 20.5t-18 52zM895 814q-8 -8 -19.5 -8t-18.5 8q-8 8 -8 19t8 18q7 8 18.5 8t19.5 -8q7 -7 7 -18t-7 -19zM1060 740l-35 -35q-12 -13 -29.5 -13t-30.5 13l-38 38q-12 13 -12 30t12 30l35 35q12 12 29.5 12
-t30.5 -12l38 -39q12 -12 12 -29.5t-12 -29.5zM951 870q-7 -8 -18.5 -8t-19.5 8q-7 8 -7 19t7 19q8 8 19 8t19 -8t8 -19t-8 -19zM1354 968q-34 -64 -107.5 -85.5t-127.5 16.5q-38 28 -61 66.5t-21 87.5t39 92t75.5 53t70.5 -5t70 -51q2 -2 13 -12.5t14.5 -13.5t13 -13.5
-t12.5 -15.5t10 -15.5t8.5 -18t4 -18.5t1 -21t-5 -22t-9.5 -24zM1555 486q3 20 -8.5 34.5t-27.5 21.5t-33 17t-23 20q-40 71 -84 98.5t-113 11.5q19 13 40 18.5t33 4.5l12 -1q2 45 -34 90q6 20 6.5 40.5t-2.5 30.5l-3 10q43 24 71 65t34 91q10 84 -43 150.5t-137 76.5
-q-60 7 -114 -18.5t-82 -74.5q-30 -51 -33.5 -101t14.5 -87t43.5 -64t56.5 -42q-45 4 -88 36t-57 88q-28 108 32 222q-16 21 -29 32q-50 0 -89 -19q19 24 42 37t36 14l13 1q0 50 -13 78q-10 21 -32.5 28.5t-47 -3.5t-37.5 -40q2 4 4 7q-7 -28 -6.5 -75.5t19 -117t48.5 -122.5
-q-25 -14 -47 -36q-35 -16 -85.5 -70.5t-84.5 -101.5l-33 -46q-90 -34 -181 -125.5t-75 -162.5q1 -16 11 -27q-15 -12 -30 -30q-21 -25 -21 -54t21.5 -40t63.5 6q41 19 77 49.5t55 60.5q-2 2 -6.5 5t-20.5 7.5t-33 3.5q23 5 51 12.5t40 10t27.5 6t26 4t23.5 0.5q14 -7 22 34
-q7 37 7 90q0 102 -40 150q106 -103 101 -219q-1 -29 -15 -50t-27 -27l-13 -6q-4 -7 -19 -32t-26 -45.5t-26.5 -52t-25 -61t-17 -63t-6.5 -66.5t10 -63q-35 54 -37 80q-22 -24 -34.5 -39t-33.5 -42t-30.5 -46t-16.5 -41t-0.5 -38t25.5 -27q45 -25 144 64t190.5 221.5
-t122.5 228.5q86 52 145 115.5t86 119.5q47 -93 154 -178q104 -83 167 -80q39 2 46 43zM1794 640q0 -182 -71 -348t-191 -286t-286.5 -191t-348.5 -71t-348.5 71t-286.5 191t-191 286t-71 348t71 348t191 286t286.5 191t348.5 71t348.5 -71t286.5 -191t191 -286t71 -348z" />
-    <glyph glyph-name="uniF2D7" unicode="&#xf2d7;" 
-d="M518 1353v-655q103 -1 191.5 1.5t125.5 5.5l37 3q68 2 90.5 24.5t39.5 94.5l33 142h103l-14 -322l7 -319h-103l-29 127q-15 68 -45 93t-84 26q-87 8 -352 8v-556q0 -78 43.5 -115.5t133.5 -37.5h357q35 0 59.5 2t55 7.5t54 18t48.5 32t46 50.5t39 73l93 216h89
-q-6 -37 -31.5 -252t-30.5 -276q-146 5 -263.5 8t-162.5 4h-44h-628l-376 -12v102l127 25q67 13 91.5 37t25.5 79l8 643q3 402 -8 645q-2 61 -25.5 84t-91.5 36l-127 24v102l376 -12h702q139 0 374 27q-6 -68 -14 -194.5t-12 -219.5l-5 -92h-93l-32 124q-31 121 -74 179.5
-t-113 58.5h-548q-28 0 -35.5 -8.5t-7.5 -30.5z" />
-    <glyph glyph-name="uniF2D8" unicode="&#xf2d8;" 
-d="M922 739v-182q0 -4 0.5 -15t0 -15l-1.5 -12t-3.5 -11.5t-6.5 -7.5t-11 -5.5t-16 -1.5v309q9 0 16 -1t11 -5t6.5 -5.5t3.5 -9.5t1 -10.5v-13.5v-14zM1238 643v-121q0 -1 0.5 -12.5t0 -15.5t-2.5 -11.5t-7.5 -10.5t-13.5 -3q-9 0 -14 9q-4 10 -4 165v7v8.5v9t1.5 8.5l3.5 7
-t5 5.5t8 1.5q6 0 10 -1.5t6.5 -4.5t4 -6t2 -8.5t0.5 -8v-9.5v-9zM180 407h122v472h-122v-472zM614 407h106v472h-159l-28 -221q-20 148 -32 221h-158v-472h107v312l45 -312h76l43 319v-319zM1039 712q0 67 -5 90q-3 16 -11 28.5t-17 20.5t-25 14t-26.5 8.5t-31 4t-29 1.5
-h-29.5h-12h-91v-472h56q169 -1 197 24.5t25 180.5q-1 62 -1 100zM1356 515v133q0 29 -2 45t-9.5 33.5t-24.5 25t-46 7.5q-46 0 -77 -34v154h-117v-472h110l7 30q30 -36 77 -36q50 0 66 30.5t16 83.5zM1536 1248v-1216q0 -66 -47 -113t-113 -47h-1216q-66 0 -113 47t-47 113
-v1216q0 66 47 113t113 47h1216q66 0 113 -47t47 -113z" />
-    <glyph glyph-name="uniF2D9" unicode="&#xf2d9;" horiz-adv-x="2176" 
-d="M1143 -197q-6 1 -11 4q-13 8 -36 23t-86 65t-116.5 104.5t-112 140t-89.5 172.5q-17 3 -175 37q66 -213 235 -362t391 -184zM502 409l168 -28q-25 76 -41 167.5t-19 145.5l-4 53q-84 -82 -121 -224q5 -65 17 -114zM612 1018q-43 -64 -77 -148q44 46 74 68zM2049 584
-q0 161 -62 307t-167.5 252t-250.5 168.5t-304 62.5q-147 0 -281 -52.5t-240 -148.5q-30 -58 -45 -160q60 51 143 83.5t158.5 43t143 13.5t108.5 -1l40 -3q33 -1 53 -15.5t24.5 -33t6.5 -37t-1 -28.5q-126 11 -227.5 0.5t-183 -43.5t-142.5 -71.5t-131 -98.5
-q4 -36 11.5 -92.5t35.5 -178t62 -179.5q123 -6 247.5 14.5t214.5 53.5t162.5 67t109.5 59l37 24q22 16 39.5 20.5t30.5 -5t17 -34.5q14 -97 -39 -121q-208 -97 -467 -134q-135 -20 -317 -16q41 -96 110 -176.5t137 -127t130.5 -79t101.5 -43.5l39 -12q143 -23 263 15
-q195 99 314 289t119 418zM2123 621q-14 -135 -40 -212q-70 -208 -181.5 -346.5t-318.5 -253.5q-48 -33 -82 -44q-72 -26 -163 -16q-36 -3 -73 -3q-283 0 -504.5 173t-295.5 442q-1 0 -4 0.5t-5 0.5q-6 -50 2.5 -112.5t26 -115t36 -98t31.5 -71.5l14 -26q8 -12 54 -82
-q-71 38 -124.5 106.5t-78.5 140t-39.5 137t-17.5 107.5l-2 42q-5 2 -33.5 12.5t-48.5 18t-53 20.5t-57.5 25t-50 25.5t-42.5 27t-25 25.5q19 -10 50.5 -25.5t113 -45.5t145.5 -38l2 32q11 149 94 290q41 202 176 365q28 115 81 214q15 28 32 45t49 32q158 74 303.5 104
-t302 11t306.5 -97q220 -115 333 -336t87 -474z" />
-    <glyph glyph-name="uniF2DA" unicode="&#xf2da;" horiz-adv-x="1792" 
-d="M1341 752q29 44 -6.5 129.5t-121.5 142.5q-58 39 -125.5 53.5t-118 4.5t-68.5 -37q-12 -23 -4.5 -28t42.5 -10q23 -3 38.5 -5t44.5 -9.5t56 -17.5q36 -13 67.5 -31.5t53 -37t40 -38.5t30.5 -38t22 -34.5t16.5 -28.5t12 -18.5t10.5 -6t11 9.5zM1704 178
-q-52 -127 -148.5 -220t-214.5 -141.5t-253 -60.5t-266 13.5t-251 91t-210 161.5t-141.5 235.5t-46.5 303.5q1 41 8.5 84.5t12.5 64t24 80.5t23 73q-51 -208 1 -397t173 -318t291 -206t346 -83t349 74.5t289 244.5q20 27 18 14q0 -4 -4 -14zM1465 627q0 -104 -40.5 -199
-t-108.5 -164t-162 -109.5t-198 -40.5t-198 40.5t-162 109.5t-108.5 164t-40.5 199t40.5 199t108.5 164t162 109.5t198 40.5t198 -40.5t162 -109.5t108.5 -164t40.5 -199zM1752 915q-65 147 -180.5 251t-253 153.5t-292 53.5t-301 -36.5t-275.5 -129t-220 -211.5t-131 -297
-t-10 -373q-49 161 -51.5 311.5t35.5 272.5t109 227t165.5 180.5t207 126t232 71t242.5 9t236 -54t216 -124.5t178 -197q33 -50 62 -121t31 -112zM1690 573q12 244 -136.5 416t-396.5 240q-8 0 -10 5t24 8q125 -4 230 -50t173 -120t116 -168.5t58.5 -199t-1 -208
-t-61.5 -197.5t-122.5 -167t-185 -117.5t-248.5 -46.5q108 30 201.5 80t174 123t129.5 176.5t55 225.5z" />
-    <glyph glyph-name="uniF2DB" unicode="&#xf2db;" 
-d="M192 256v-128h-112q-16 0 -16 16v16h-48q-16 0 -16 16v32q0 16 16 16h48v16q0 16 16 16h112zM192 512v-128h-112q-16 0 -16 16v16h-48q-16 0 -16 16v32q0 16 16 16h48v16q0 16 16 16h112zM192 768v-128h-112q-16 0 -16 16v16h-48q-16 0 -16 16v32q0 16 16 16h48v16
-q0 16 16 16h112zM192 1024v-128h-112q-16 0 -16 16v16h-48q-16 0 -16 16v32q0 16 16 16h48v16q0 16 16 16h112zM192 1280v-128h-112q-16 0 -16 16v16h-48q-16 0 -16 16v32q0 16 16 16h48v16q0 16 16 16h112zM1280 1440v-1472q0 -40 -28 -68t-68 -28h-832q-40 0 -68 28
-t-28 68v1472q0 40 28 68t68 28h832q40 0 68 -28t28 -68zM1536 208v-32q0 -16 -16 -16h-48v-16q0 -16 -16 -16h-112v128h112q16 0 16 -16v-16h48q16 0 16 -16zM1536 464v-32q0 -16 -16 -16h-48v-16q0 -16 -16 -16h-112v128h112q16 0 16 -16v-16h48q16 0 16 -16zM1536 720v-32
-q0 -16 -16 -16h-48v-16q0 -16 -16 -16h-112v128h112q16 0 16 -16v-16h48q16 0 16 -16zM1536 976v-32q0 -16 -16 -16h-48v-16q0 -16 -16 -16h-112v128h112q16 0 16 -16v-16h48q16 0 16 -16zM1536 1232v-32q0 -16 -16 -16h-48v-16q0 -16 -16 -16h-112v128h112q16 0 16 -16v-16
-h48q16 0 16 -16z" />
-    <glyph glyph-name="uniF2DC" unicode="&#xf2dc;" horiz-adv-x="1664" 
-d="M1566 419l-167 -33l186 -107q23 -13 29.5 -38.5t-6.5 -48.5q-14 -23 -39 -29.5t-48 6.5l-186 106l55 -160q13 -38 -12 -63.5t-60.5 -20.5t-48.5 42l-102 300l-271 156v-313l208 -238q16 -18 17 -39t-11 -36.5t-28.5 -25t-37 -5.5t-36.5 22l-112 128v-214q0 -26 -19 -45
-t-45 -19t-45 19t-19 45v214l-112 -128q-16 -18 -36.5 -22t-37 5.5t-28.5 25t-11 36.5t17 39l208 238v313l-271 -156l-102 -300q-13 -37 -48.5 -42t-60.5 20.5t-12 63.5l55 160l-186 -106q-23 -13 -48 -6.5t-39 29.5q-13 23 -6.5 48.5t29.5 38.5l186 107l-167 33
-q-29 6 -42 29t-8.5 46.5t25.5 40t50 10.5l310 -62l271 157l-271 157l-310 -62q-4 -1 -13 -1q-27 0 -44 18t-19 40t11 43t40 26l167 33l-186 107q-23 13 -29.5 38.5t6.5 48.5t39 30t48 -7l186 -106l-55 160q-13 38 12 63.5t60.5 20.5t48.5 -42l102 -300l271 -156v313
-l-208 238q-16 18 -17 39t11 36.5t28.5 25t37 5.5t36.5 -22l112 -128v214q0 26 19 45t45 19t45 -19t19 -45v-214l112 128q16 18 36.5 22t37 -5.5t28.5 -25t11 -36.5t-17 -39l-208 -238v-313l271 156l102 300q13 37 48.5 42t60.5 -20.5t12 -63.5l-55 -160l186 106
-q23 13 48 6.5t39 -29.5q13 -23 6.5 -48.5t-29.5 -38.5l-186 -107l167 -33q27 -5 40 -26t11 -43t-19 -40t-44 -18q-9 0 -13 1l-310 62l-271 -157l271 -157l310 62q29 6 50 -10.5t25.5 -40t-8.5 -46.5t-42 -29z" />
-    <glyph glyph-name="uniF2DD" unicode="&#xf2dd;" horiz-adv-x="1792" 
-d="M1473 607q7 118 -33 226.5t-113 189t-177 131t-221 57.5q-116 7 -225.5 -32t-192 -110.5t-135 -175t-59.5 -220.5q-7 -118 33 -226.5t113 -189t177.5 -131t221.5 -57.5q155 -9 293 59t224 195.5t94 283.5zM1792 1536l-349 -348q120 -117 180.5 -272t50.5 -321
-q-11 -183 -102 -339t-241 -255.5t-332 -124.5l-999 -132l347 347q-120 116 -180.5 271.5t-50.5 321.5q11 184 102 340t241.5 255.5t332.5 124.5q167 22 500 66t500 66z" />
-    <glyph glyph-name="uniF2DE" unicode="&#xf2de;" horiz-adv-x="1792" 
-d="M948 508l163 -329h-51l-175 350l-171 -350h-49l179 374l-78 33l21 49l240 -102l-21 -50zM563 1100l304 -130l-130 -304l-304 130zM907 915l240 -103l-103 -239l-239 102zM1188 765l191 -81l-82 -190l-190 81zM1680 640q0 159 -62 304t-167.5 250.5t-250.5 167.5t-304 62
-t-304 -62t-250.5 -167.5t-167.5 -250.5t-62 -304t62 -304t167.5 -250.5t250.5 -167.5t304 -62t304 62t250.5 167.5t167.5 250.5t62 304zM1792 640q0 -182 -71 -348t-191 -286t-286 -191t-348 -71t-348 71t-286 191t-191 286t-71 348t71 348t191 286t286 191t348 71t348 -71
-t286 -191t191 -286t71 -348z" />
-    <glyph glyph-name="uniF2E0" unicode="&#xf2e0;" horiz-adv-x="1920" 
-d="M1334 302q-4 24 -27.5 34t-49.5 10.5t-48.5 12.5t-25.5 38q-5 47 33 139.5t75 181t32 127.5q-14 101 -117 103q-45 1 -75 -16l-3 -2l-5 -2.5t-4.5 -2t-5 -2t-5 -0.5t-6 1.5t-6 3.5t-6.5 5q-3 2 -9 8.5t-9 9t-8.5 7.5t-9.5 7.5t-9.5 5.5t-11 4.5t-11.5 2.5q-30 5 -48 -3
-t-45 -31q-1 -1 -9 -8.5t-12.5 -11t-15 -10t-16.5 -5.5t-17 3q-54 27 -84 40q-41 18 -94 -5t-76 -65q-16 -28 -41 -98.5t-43.5 -132.5t-40 -134t-21.5 -73q-22 -69 18.5 -119t110.5 -46q30 2 50.5 15t38.5 46q7 13 79 199.5t77 194.5q6 11 21.5 18t29.5 0q27 -15 21 -53
-q-2 -18 -51 -139.5t-50 -132.5q-6 -38 19.5 -56.5t60.5 -7t55 49.5q4 8 45.5 92t81.5 163.5t46 88.5q20 29 41 28q29 0 25 -38q-2 -16 -65.5 -147.5t-70.5 -159.5q-12 -53 13 -103t74 -74q17 -9 51 -15.5t71.5 -8t62.5 14t20 48.5zM383 86q3 -15 -5 -27.5t-23 -15.5
-q-14 -3 -26.5 5t-15.5 23q-3 14 5 27t22 16t27 -5t16 -23zM953 -177q12 -17 8.5 -37.5t-20.5 -32.5t-37.5 -8t-32.5 21q-11 17 -7.5 37.5t20.5 32.5t37.5 8t31.5 -21zM177 635q-18 -27 -49.5 -33t-57.5 13q-26 18 -32 50t12 58q18 27 49.5 33t57.5 -12q26 -19 32 -50.5
-t-12 -58.5zM1467 -42q19 -28 13 -61.5t-34 -52.5t-60.5 -13t-51.5 34t-13 61t33 53q28 19 60.5 13t52.5 -34zM1579 562q69 -113 42.5 -244.5t-134.5 -207.5q-90 -63 -199 -60q-20 -80 -84.5 -127t-143.5 -44.5t-140 57.5q-12 -9 -13 -10q-103 -71 -225 -48.5t-193 126.5
-q-50 73 -53 164q-83 14 -142.5 70.5t-80.5 128t-2 152t81 138.5q-36 60 -38 128t24.5 125t79.5 98.5t121 50.5q32 85 99 148t146.5 91.5t168 17t159.5 -66.5q72 21 140 17.5t128.5 -36t104.5 -80t67.5 -115t17.5 -140.5q52 -16 87 -57t45.5 -89t-5.5 -99.5t-58 -87.5z
-M455 1222q14 -20 9.5 -44.5t-24.5 -38.5q-19 -14 -43.5 -9.5t-37.5 24.5q-14 20 -9.5 44.5t24.5 38.5q19 14 43.5 9.5t37.5 -24.5zM614 1503q4 -16 -5 -30.5t-26 -18.5t-31 5.5t-18 26.5q-3 17 6.5 31t25.5 18q17 4 31 -5.5t17 -26.5zM1800 555q4 -20 -6.5 -37t-30.5 -21
-q-19 -4 -36 6.5t-21 30.5t6.5 37t30.5 22q20 4 36.5 -7.5t20.5 -30.5zM1136 1448q16 -27 8.5 -58.5t-35.5 -47.5q-27 -16 -57.5 -8.5t-46.5 34.5q-16 28 -8.5 59t34.5 48t58 9t47 -36zM1882 792q4 -15 -4 -27.5t-23 -16.5q-15 -3 -27.5 5.5t-15.5 22.5q-3 15 5 28t23 16
-q14 3 26.5 -5t15.5 -23zM1691 1033q15 -22 10.5 -49t-26.5 -43q-22 -15 -49 -10t-42 27t-10 49t27 43t48.5 11t41.5 -28z" />
-    <glyph glyph-name="uniF2E1" unicode="&#xf2e1;" horiz-adv-x="1792" 
- />
-    <glyph glyph-name="uniF2E2" unicode="&#xf2e2;" horiz-adv-x="1792" 
- />
-    <glyph glyph-name="uniF2E3" unicode="&#xf2e3;" horiz-adv-x="1792" 
- />
-    <glyph glyph-name="uniF2E4" unicode="&#xf2e4;" horiz-adv-x="1792" 
- />
-    <glyph glyph-name="uniF2E5" unicode="&#xf2e5;" horiz-adv-x="1792" 
- />
-    <glyph glyph-name="uniF2E6" unicode="&#xf2e6;" horiz-adv-x="1792" 
- />
-    <glyph glyph-name="uniF2E7" unicode="&#xf2e7;" horiz-adv-x="1792" 
- />
-    <glyph glyph-name="_698" unicode="&#xf2e8;" horiz-adv-x="1792" 
- />
-    <glyph glyph-name="uniF2E9" unicode="&#xf2e9;" horiz-adv-x="1792" 
- />
-    <glyph glyph-name="uniF2EA" unicode="&#xf2ea;" horiz-adv-x="1792" 
- />
-    <glyph glyph-name="uniF2EB" unicode="&#xf2eb;" horiz-adv-x="1792" 
- />
-    <glyph glyph-name="uniF2EC" unicode="&#xf2ec;" horiz-adv-x="1792" 
- />
-    <glyph glyph-name="uniF2ED" unicode="&#xf2ed;" horiz-adv-x="1792" 
- />
-    <glyph glyph-name="uniF2EE" unicode="&#xf2ee;" horiz-adv-x="1792" 
- />
-    <glyph glyph-name="lessequal" unicode="&#xf500;" horiz-adv-x="1792" 
- />
-  </font>
-</defs></svg>
diff --git a/docs/_build/html/_static/fonts/fontawesome-webfont.ttf b/docs/_build/html/_static/fonts/fontawesome-webfont.ttf
deleted file mode 100644
index 35acda2f..00000000
Binary files a/docs/_build/html/_static/fonts/fontawesome-webfont.ttf and /dev/null differ
diff --git a/docs/_build/html/_static/fonts/fontawesome-webfont.woff b/docs/_build/html/_static/fonts/fontawesome-webfont.woff
deleted file mode 100644
index 400014a4..00000000
Binary files a/docs/_build/html/_static/fonts/fontawesome-webfont.woff and /dev/null differ
diff --git a/docs/_build/html/_static/fonts/fontawesome-webfont.woff2 b/docs/_build/html/_static/fonts/fontawesome-webfont.woff2
deleted file mode 100644
index 4d13fc60..00000000
Binary files a/docs/_build/html/_static/fonts/fontawesome-webfont.woff2 and /dev/null differ
diff --git a/docs/_build/html/_static/jquery-3.5.1.js b/docs/_build/html/_static/jquery-3.5.1.js
deleted file mode 100644
index 50937333..00000000
--- a/docs/_build/html/_static/jquery-3.5.1.js
+++ /dev/null
@@ -1,10872 +0,0 @@
-/*!
- * jQuery JavaScript Library v3.5.1
- * https://jquery.com/
- *
- * Includes Sizzle.js
- * https://sizzlejs.com/
- *
- * Copyright JS Foundation and other contributors
- * Released under the MIT license
- * https://jquery.org/license
- *
- * Date: 2020-05-04T22:49Z
- */
-( function( global, factory ) {
-
-	"use strict";
-
-	if ( typeof module === "object" && typeof module.exports === "object" ) {
-
-		// For CommonJS and CommonJS-like environments where a proper `window`
-		// is present, execute the factory and get jQuery.
-		// For environments that do not have a `window` with a `document`
-		// (such as Node.js), expose a factory as module.exports.
-		// This accentuates the need for the creation of a real `window`.
-		// e.g. var jQuery = require("jquery")(window);
-		// See ticket #14549 for more info.
-		module.exports = global.document ?
-			factory( global, true ) :
-			function( w ) {
-				if ( !w.document ) {
-					throw new Error( "jQuery requires a window with a document" );
-				}
-				return factory( w );
-			};
-	} else {
-		factory( global );
-	}
-
-// Pass this if window is not defined yet
-} )( typeof window !== "undefined" ? window : this, function( window, noGlobal ) {
-
-// Edge <= 12 - 13+, Firefox <=18 - 45+, IE 10 - 11, Safari 5.1 - 9+, iOS 6 - 9.1
-// throw exceptions when non-strict code (e.g., ASP.NET 4.5) accesses strict mode
-// arguments.callee.caller (trac-13335). But as of jQuery 3.0 (2016), strict mode should be common
-// enough that all such attempts are guarded in a try block.
-"use strict";
-
-var arr = [];
-
-var getProto = Object.getPrototypeOf;
-
-var slice = arr.slice;
-
-var flat = arr.flat ? function( array ) {
-	return arr.flat.call( array );
-} : function( array ) {
-	return arr.concat.apply( [], array );
-};
-
-
-var push = arr.push;
-
-var indexOf = arr.indexOf;
-
-var class2type = {};
-
-var toString = class2type.toString;
-
-var hasOwn = class2type.hasOwnProperty;
-
-var fnToString = hasOwn.toString;
-
-var ObjectFunctionString = fnToString.call( Object );
-
-var support = {};
-
-var isFunction = function isFunction( obj ) {
-
-      // Support: Chrome <=57, Firefox <=52
-      // In some browsers, typeof returns "function" for HTML <object> elements
-      // (i.e., `typeof document.createElement( "object" ) === "function"`).
-      // We don't want to classify *any* DOM node as a function.
-      return typeof obj === "function" && typeof obj.nodeType !== "number";
-  };
-
-
-var isWindow = function isWindow( obj ) {
-		return obj != null && obj === obj.window;
-	};
-
-
-var document = window.document;
-
-
-
-	var preservedScriptAttributes = {
-		type: true,
-		src: true,
-		nonce: true,
-		noModule: true
-	};
-
-	function DOMEval( code, node, doc ) {
-		doc = doc || document;
-
-		var i, val,
-			script = doc.createElement( "script" );
-
-		script.text = code;
-		if ( node ) {
-			for ( i in preservedScriptAttributes ) {
-
-				// Support: Firefox 64+, Edge 18+
-				// Some browsers don't support the "nonce" property on scripts.
-				// On the other hand, just using `getAttribute` is not enough as
-				// the `nonce` attribute is reset to an empty string whenever it
-				// becomes browsing-context connected.
-				// See https://github.com/whatwg/html/issues/2369
-				// See https://html.spec.whatwg.org/#nonce-attributes
-				// The `node.getAttribute` check was added for the sake of
-				// `jQuery.globalEval` so that it can fake a nonce-containing node
-				// via an object.
-				val = node[ i ] || node.getAttribute && node.getAttribute( i );
-				if ( val ) {
-					script.setAttribute( i, val );
-				}
-			}
-		}
-		doc.head.appendChild( script ).parentNode.removeChild( script );
-	}
-
-
-function toType( obj ) {
-	if ( obj == null ) {
-		return obj + "";
-	}
-
-	// Support: Android <=2.3 only (functionish RegExp)
-	return typeof obj === "object" || typeof obj === "function" ?
-		class2type[ toString.call( obj ) ] || "object" :
-		typeof obj;
-}
-/* global Symbol */
-// Defining this global in .eslintrc.json would create a danger of using the global
-// unguarded in another place, it seems safer to define global only for this module
-
-
-
-var
-	version = "3.5.1",
-
-	// Define a local copy of jQuery
-	jQuery = function( selector, context ) {
-
-		// The jQuery object is actually just the init constructor 'enhanced'
-		// Need init if jQuery is called (just allow error to be thrown if not included)
-		return new jQuery.fn.init( selector, context );
-	};
-
-jQuery.fn = jQuery.prototype = {
-
-	// The current version of jQuery being used
-	jquery: version,
-
-	constructor: jQuery,
-
-	// The default length of a jQuery object is 0
-	length: 0,
-
-	toArray: function() {
-		return slice.call( this );
-	},
-
-	// Get the Nth element in the matched element set OR
-	// Get the whole matched element set as a clean array
-	get: function( num ) {
-
-		// Return all the elements in a clean array
-		if ( num == null ) {
-			return slice.call( this );
-		}
-
-		// Return just the one element from the set
-		return num < 0 ? this[ num + this.length ] : this[ num ];
-	},
-
-	// Take an array of elements and push it onto the stack
-	// (returning the new matched element set)
-	pushStack: function( elems ) {
-
-		// Build a new jQuery matched element set
-		var ret = jQuery.merge( this.constructor(), elems );
-
-		// Add the old object onto the stack (as a reference)
-		ret.prevObject = this;
-
-		// Return the newly-formed element set
-		return ret;
-	},
-
-	// Execute a callback for every element in the matched set.
-	each: function( callback ) {
-		return jQuery.each( this, callback );
-	},
-
-	map: function( callback ) {
-		return this.pushStack( jQuery.map( this, function( elem, i ) {
-			return callback.call( elem, i, elem );
-		} ) );
-	},
-
-	slice: function() {
-		return this.pushStack( slice.apply( this, arguments ) );
-	},
-
-	first: function() {
-		return this.eq( 0 );
-	},
-
-	last: function() {
-		return this.eq( -1 );
-	},
-
-	even: function() {
-		return this.pushStack( jQuery.grep( this, function( _elem, i ) {
-			return ( i + 1 ) % 2;
-		} ) );
-	},
-
-	odd: function() {
-		return this.pushStack( jQuery.grep( this, function( _elem, i ) {
-			return i % 2;
-		} ) );
-	},
-
-	eq: function( i ) {
-		var len = this.length,
-			j = +i + ( i < 0 ? len : 0 );
-		return this.pushStack( j >= 0 && j < len ? [ this[ j ] ] : [] );
-	},
-
-	end: function() {
-		return this.prevObject || this.constructor();
-	},
-
-	// For internal use only.
-	// Behaves like an Array's method, not like a jQuery method.
-	push: push,
-	sort: arr.sort,
-	splice: arr.splice
-};
-
-jQuery.extend = jQuery.fn.extend = function() {
-	var options, name, src, copy, copyIsArray, clone,
-		target = arguments[ 0 ] || {},
-		i = 1,
-		length = arguments.length,
-		deep = false;
-
-	// Handle a deep copy situation
-	if ( typeof target === "boolean" ) {
-		deep = target;
-
-		// Skip the boolean and the target
-		target = arguments[ i ] || {};
-		i++;
-	}
-
-	// Handle case when target is a string or something (possible in deep copy)
-	if ( typeof target !== "object" && !isFunction( target ) ) {
-		target = {};
-	}
-
-	// Extend jQuery itself if only one argument is passed
-	if ( i === length ) {
-		target = this;
-		i--;
-	}
-
-	for ( ; i < length; i++ ) {
-
-		// Only deal with non-null/undefined values
-		if ( ( options = arguments[ i ] ) != null ) {
-
-			// Extend the base object
-			for ( name in options ) {
-				copy = options[ name ];
-
-				// Prevent Object.prototype pollution
-				// Prevent never-ending loop
-				if ( name === "__proto__" || target === copy ) {
-					continue;
-				}
-
-				// Recurse if we're merging plain objects or arrays
-				if ( deep && copy && ( jQuery.isPlainObject( copy ) ||
-					( copyIsArray = Array.isArray( copy ) ) ) ) {
-					src = target[ name ];
-
-					// Ensure proper type for the source value
-					if ( copyIsArray && !Array.isArray( src ) ) {
-						clone = [];
-					} else if ( !copyIsArray && !jQuery.isPlainObject( src ) ) {
-						clone = {};
-					} else {
-						clone = src;
-					}
-					copyIsArray = false;
-
-					// Never move original objects, clone them
-					target[ name ] = jQuery.extend( deep, clone, copy );
-
-				// Don't bring in undefined values
-				} else if ( copy !== undefined ) {
-					target[ name ] = copy;
-				}
-			}
-		}
-	}
-
-	// Return the modified object
-	return target;
-};
-
-jQuery.extend( {
-
-	// Unique for each copy of jQuery on the page
-	expando: "jQuery" + ( version + Math.random() ).replace( /\D/g, "" ),
-
-	// Assume jQuery is ready without the ready module
-	isReady: true,
-
-	error: function( msg ) {
-		throw new Error( msg );
-	},
-
-	noop: function() {},
-
-	isPlainObject: function( obj ) {
-		var proto, Ctor;
-
-		// Detect obvious negatives
-		// Use toString instead of jQuery.type to catch host objects
-		if ( !obj || toString.call( obj ) !== "[object Object]" ) {
-			return false;
-		}
-
-		proto = getProto( obj );
-
-		// Objects with no prototype (e.g., `Object.create( null )`) are plain
-		if ( !proto ) {
-			return true;
-		}
-
-		// Objects with prototype are plain iff they were constructed by a global Object function
-		Ctor = hasOwn.call( proto, "constructor" ) && proto.constructor;
-		return typeof Ctor === "function" && fnToString.call( Ctor ) === ObjectFunctionString;
-	},
-
-	isEmptyObject: function( obj ) {
-		var name;
-
-		for ( name in obj ) {
-			return false;
-		}
-		return true;
-	},
-
-	// Evaluates a script in a provided context; falls back to the global one
-	// if not specified.
-	globalEval: function( code, options, doc ) {
-		DOMEval( code, { nonce: options && options.nonce }, doc );
-	},
-
-	each: function( obj, callback ) {
-		var length, i = 0;
-
-		if ( isArrayLike( obj ) ) {
-			length = obj.length;
-			for ( ; i < length; i++ ) {
-				if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) {
-					break;
-				}
-			}
-		} else {
-			for ( i in obj ) {
-				if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) {
-					break;
-				}
-			}
-		}
-
-		return obj;
-	},
-
-	// results is for internal usage only
-	makeArray: function( arr, results ) {
-		var ret = results || [];
-
-		if ( arr != null ) {
-			if ( isArrayLike( Object( arr ) ) ) {
-				jQuery.merge( ret,
-					typeof arr === "string" ?
-					[ arr ] : arr
-				);
-			} else {
-				push.call( ret, arr );
-			}
-		}
-
-		return ret;
-	},
-
-	inArray: function( elem, arr, i ) {
-		return arr == null ? -1 : indexOf.call( arr, elem, i );
-	},
-
-	// Support: Android <=4.0 only, PhantomJS 1 only
-	// push.apply(_, arraylike) throws on ancient WebKit
-	merge: function( first, second ) {
-		var len = +second.length,
-			j = 0,
-			i = first.length;
-
-		for ( ; j < len; j++ ) {
-			first[ i++ ] = second[ j ];
-		}
-
-		first.length = i;
-
-		return first;
-	},
-
-	grep: function( elems, callback, invert ) {
-		var callbackInverse,
-			matches = [],
-			i = 0,
-			length = elems.length,
-			callbackExpect = !invert;
-
-		// Go through the array, only saving the items
-		// that pass the validator function
-		for ( ; i < length; i++ ) {
-			callbackInverse = !callback( elems[ i ], i );
-			if ( callbackInverse !== callbackExpect ) {
-				matches.push( elems[ i ] );
-			}
-		}
-
-		return matches;
-	},
-
-	// arg is for internal usage only
-	map: function( elems, callback, arg ) {
-		var length, value,
-			i = 0,
-			ret = [];
-
-		// Go through the array, translating each of the items to their new values
-		if ( isArrayLike( elems ) ) {
-			length = elems.length;
-			for ( ; i < length; i++ ) {
-				value = callback( elems[ i ], i, arg );
-
-				if ( value != null ) {
-					ret.push( value );
-				}
-			}
-
-		// Go through every key on the object,
-		} else {
-			for ( i in elems ) {
-				value = callback( elems[ i ], i, arg );
-
-				if ( value != null ) {
-					ret.push( value );
-				}
-			}
-		}
-
-		// Flatten any nested arrays
-		return flat( ret );
-	},
-
-	// A global GUID counter for objects
-	guid: 1,
-
-	// jQuery.support is not used in Core but other projects attach their
-	// properties to it so it needs to exist.
-	support: support
-} );
-
-if ( typeof Symbol === "function" ) {
-	jQuery.fn[ Symbol.iterator ] = arr[ Symbol.iterator ];
-}
-
-// Populate the class2type map
-jQuery.each( "Boolean Number String Function Array Date RegExp Object Error Symbol".split( " " ),
-function( _i, name ) {
-	class2type[ "[object " + name + "]" ] = name.toLowerCase();
-} );
-
-function isArrayLike( obj ) {
-
-	// Support: real iOS 8.2 only (not reproducible in simulator)
-	// `in` check used to prevent JIT error (gh-2145)
-	// hasOwn isn't used here due to false negatives
-	// regarding Nodelist length in IE
-	var length = !!obj && "length" in obj && obj.length,
-		type = toType( obj );
-
-	if ( isFunction( obj ) || isWindow( obj ) ) {
-		return false;
-	}
-
-	return type === "array" || length === 0 ||
-		typeof length === "number" && length > 0 && ( length - 1 ) in obj;
-}
-var Sizzle =
-/*!
- * Sizzle CSS Selector Engine v2.3.5
- * https://sizzlejs.com/
- *
- * Copyright JS Foundation and other contributors
- * Released under the MIT license
- * https://js.foundation/
- *
- * Date: 2020-03-14
- */
-( function( window ) {
-var i,
-	support,
-	Expr,
-	getText,
-	isXML,
-	tokenize,
-	compile,
-	select,
-	outermostContext,
-	sortInput,
-	hasDuplicate,
-
-	// Local document vars
-	setDocument,
-	document,
-	docElem,
-	documentIsHTML,
-	rbuggyQSA,
-	rbuggyMatches,
-	matches,
-	contains,
-
-	// Instance-specific data
-	expando = "sizzle" + 1 * new Date(),
-	preferredDoc = window.document,
-	dirruns = 0,
-	done = 0,
-	classCache = createCache(),
-	tokenCache = createCache(),
-	compilerCache = createCache(),
-	nonnativeSelectorCache = createCache(),
-	sortOrder = function( a, b ) {
-		if ( a === b ) {
-			hasDuplicate = true;
-		}
-		return 0;
-	},
-
-	// Instance methods
-	hasOwn = ( {} ).hasOwnProperty,
-	arr = [],
-	pop = arr.pop,
-	pushNative = arr.push,
-	push = arr.push,
-	slice = arr.slice,
-
-	// Use a stripped-down indexOf as it's faster than native
-	// https://jsperf.com/thor-indexof-vs-for/5
-	indexOf = function( list, elem ) {
-		var i = 0,
-			len = list.length;
-		for ( ; i < len; i++ ) {
-			if ( list[ i ] === elem ) {
-				return i;
-			}
-		}
-		return -1;
-	},
-
-	booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|" +
-		"ismap|loop|multiple|open|readonly|required|scoped",
-
-	// Regular expressions
-
-	// http://www.w3.org/TR/css3-selectors/#whitespace
-	whitespace = "[\\x20\\t\\r\\n\\f]",
-
-	// https://www.w3.org/TR/css-syntax-3/#ident-token-diagram
-	identifier = "(?:\\\\[\\da-fA-F]{1,6}" + whitespace +
-		"?|\\\\[^\\r\\n\\f]|[\\w-]|[^\0-\\x7f])+",
-
-	// Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors
-	attributes = "\\[" + whitespace + "*(" + identifier + ")(?:" + whitespace +
-
-		// Operator (capture 2)
-		"*([*^$|!~]?=)" + whitespace +
-
-		// "Attribute values must be CSS identifiers [capture 5]
-		// or strings [capture 3 or capture 4]"
-		"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" +
-		whitespace + "*\\]",
-
-	pseudos = ":(" + identifier + ")(?:\\((" +
-
-		// To reduce the number of selectors needing tokenize in the preFilter, prefer arguments:
-		// 1. quoted (capture 3; capture 4 or capture 5)
-		"('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" +
-
-		// 2. simple (capture 6)
-		"((?:\\\\.|[^\\\\()[\\]]|" + attributes + ")*)|" +
-
-		// 3. anything else (capture 2)
-		".*" +
-		")\\)|)",
-
-	// Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter
-	rwhitespace = new RegExp( whitespace + "+", "g" ),
-	rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" +
-		whitespace + "+$", "g" ),
-
-	rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ),
-	rcombinators = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace +
-		"*" ),
-	rdescend = new RegExp( whitespace + "|>" ),
-
-	rpseudo = new RegExp( pseudos ),
-	ridentifier = new RegExp( "^" + identifier + "$" ),
-
-	matchExpr = {
-		"ID": new RegExp( "^#(" + identifier + ")" ),
-		"CLASS": new RegExp( "^\\.(" + identifier + ")" ),
-		"TAG": new RegExp( "^(" + identifier + "|[*])" ),
-		"ATTR": new RegExp( "^" + attributes ),
-		"PSEUDO": new RegExp( "^" + pseudos ),
-		"CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" +
-			whitespace + "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" +
-			whitespace + "*(\\d+)|))" + whitespace + "*\\)|)", "i" ),
-		"bool": new RegExp( "^(?:" + booleans + ")$", "i" ),
-
-		// For use in libraries implementing .is()
-		// We use this for POS matching in `select`
-		"needsContext": new RegExp( "^" + whitespace +
-			"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" + whitespace +
-			"*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" )
-	},
-
-	rhtml = /HTML$/i,
-	rinputs = /^(?:input|select|textarea|button)$/i,
-	rheader = /^h\d$/i,
-
-	rnative = /^[^{]+\{\s*\[native \w/,
-
-	// Easily-parseable/retrievable ID or TAG or CLASS selectors
-	rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,
-
-	rsibling = /[+~]/,
-
-	// CSS escapes
-	// http://www.w3.org/TR/CSS21/syndata.html#escaped-characters
-	runescape = new RegExp( "\\\\[\\da-fA-F]{1,6}" + whitespace + "?|\\\\([^\\r\\n\\f])", "g" ),
-	funescape = function( escape, nonHex ) {
-		var high = "0x" + escape.slice( 1 ) - 0x10000;
-
-		return nonHex ?
-
-			// Strip the backslash prefix from a non-hex escape sequence
-			nonHex :
-
-			// Replace a hexadecimal escape sequence with the encoded Unicode code point
-			// Support: IE <=11+
-			// For values outside the Basic Multilingual Plane (BMP), manually construct a
-			// surrogate pair
-			high < 0 ?
-				String.fromCharCode( high + 0x10000 ) :
-				String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 );
-	},
-
-	// CSS string/identifier serialization
-	// https://drafts.csswg.org/cssom/#common-serializing-idioms
-	rcssescape = /([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,
-	fcssescape = function( ch, asCodePoint ) {
-		if ( asCodePoint ) {
-
-			// U+0000 NULL becomes U+FFFD REPLACEMENT CHARACTER
-			if ( ch === "\0" ) {
-				return "\uFFFD";
-			}
-
-			// Control characters and (dependent upon position) numbers get escaped as code points
-			return ch.slice( 0, -1 ) + "\\" +
-				ch.charCodeAt( ch.length - 1 ).toString( 16 ) + " ";
-		}
-
-		// Other potentially-special ASCII characters get backslash-escaped
-		return "\\" + ch;
-	},
-
-	// Used for iframes
-	// See setDocument()
-	// Removing the function wrapper causes a "Permission Denied"
-	// error in IE
-	unloadHandler = function() {
-		setDocument();
-	},
-
-	inDisabledFieldset = addCombinator(
-		function( elem ) {
-			return elem.disabled === true && elem.nodeName.toLowerCase() === "fieldset";
-		},
-		{ dir: "parentNode", next: "legend" }
-	);
-
-// Optimize for push.apply( _, NodeList )
-try {
-	push.apply(
-		( arr = slice.call( preferredDoc.childNodes ) ),
-		preferredDoc.childNodes
-	);
-
-	// Support: Android<4.0
-	// Detect silently failing push.apply
-	// eslint-disable-next-line no-unused-expressions
-	arr[ preferredDoc.childNodes.length ].nodeType;
-} catch ( e ) {
-	push = { apply: arr.length ?
-
-		// Leverage slice if possible
-		function( target, els ) {
-			pushNative.apply( target, slice.call( els ) );
-		} :
-
-		// Support: IE<9
-		// Otherwise append directly
-		function( target, els ) {
-			var j = target.length,
-				i = 0;
-
-			// Can't trust NodeList.length
-			while ( ( target[ j++ ] = els[ i++ ] ) ) {}
-			target.length = j - 1;
-		}
-	};
-}
-
-function Sizzle( selector, context, results, seed ) {
-	var m, i, elem, nid, match, groups, newSelector,
-		newContext = context && context.ownerDocument,
-
-		// nodeType defaults to 9, since context defaults to document
-		nodeType = context ? context.nodeType : 9;
-
-	results = results || [];
-
-	// Return early from calls with invalid selector or context
-	if ( typeof selector !== "string" || !selector ||
-		nodeType !== 1 && nodeType !== 9 && nodeType !== 11 ) {
-
-		return results;
-	}
-
-	// Try to shortcut find operations (as opposed to filters) in HTML documents
-	if ( !seed ) {
-		setDocument( context );
-		context = context || document;
-
-		if ( documentIsHTML ) {
-
-			// If the selector is sufficiently simple, try using a "get*By*" DOM method
-			// (excepting DocumentFragment context, where the methods don't exist)
-			if ( nodeType !== 11 && ( match = rquickExpr.exec( selector ) ) ) {
-
-				// ID selector
-				if ( ( m = match[ 1 ] ) ) {
-
-					// Document context
-					if ( nodeType === 9 ) {
-						if ( ( elem = context.getElementById( m ) ) ) {
-
-							// Support: IE, Opera, Webkit
-							// TODO: identify versions
-							// getElementById can match elements by name instead of ID
-							if ( elem.id === m ) {
-								results.push( elem );
-								return results;
-							}
-						} else {
-							return results;
-						}
-
-					// Element context
-					} else {
-
-						// Support: IE, Opera, Webkit
-						// TODO: identify versions
-						// getElementById can match elements by name instead of ID
-						if ( newContext && ( elem = newContext.getElementById( m ) ) &&
-							contains( context, elem ) &&
-							elem.id === m ) {
-
-							results.push( elem );
-							return results;
-						}
-					}
-
-				// Type selector
-				} else if ( match[ 2 ] ) {
-					push.apply( results, context.getElementsByTagName( selector ) );
-					return results;
-
-				// Class selector
-				} else if ( ( m = match[ 3 ] ) && support.getElementsByClassName &&
-					context.getElementsByClassName ) {
-
-					push.apply( results, context.getElementsByClassName( m ) );
-					return results;
-				}
-			}
-
-			// Take advantage of querySelectorAll
-			if ( support.qsa &&
-				!nonnativeSelectorCache[ selector + " " ] &&
-				( !rbuggyQSA || !rbuggyQSA.test( selector ) ) &&
-
-				// Support: IE 8 only
-				// Exclude object elements
-				( nodeType !== 1 || context.nodeName.toLowerCase() !== "object" ) ) {
-
-				newSelector = selector;
-				newContext = context;
-
-				// qSA considers elements outside a scoping root when evaluating child or
-				// descendant combinators, which is not what we want.
-				// In such cases, we work around the behavior by prefixing every selector in the
-				// list with an ID selector referencing the scope context.
-				// The technique has to be used as well when a leading combinator is used
-				// as such selectors are not recognized by querySelectorAll.
-				// Thanks to Andrew Dupont for this technique.
-				if ( nodeType === 1 &&
-					( rdescend.test( selector ) || rcombinators.test( selector ) ) ) {
-
-					// Expand context for sibling selectors
-					newContext = rsibling.test( selector ) && testContext( context.parentNode ) ||
-						context;
-
-					// We can use :scope instead of the ID hack if the browser
-					// supports it & if we're not changing the context.
-					if ( newContext !== context || !support.scope ) {
-
-						// Capture the context ID, setting it first if necessary
-						if ( ( nid = context.getAttribute( "id" ) ) ) {
-							nid = nid.replace( rcssescape, fcssescape );
-						} else {
-							context.setAttribute( "id", ( nid = expando ) );
-						}
-					}
-
-					// Prefix every selector in the list
-					groups = tokenize( selector );
-					i = groups.length;
-					while ( i-- ) {
-						groups[ i ] = ( nid ? "#" + nid : ":scope" ) + " " +
-							toSelector( groups[ i ] );
-					}
-					newSelector = groups.join( "," );
-				}
-
-				try {
-					push.apply( results,
-						newContext.querySelectorAll( newSelector )
-					);
-					return results;
-				} catch ( qsaError ) {
-					nonnativeSelectorCache( selector, true );
-				} finally {
-					if ( nid === expando ) {
-						context.removeAttribute( "id" );
-					}
-				}
-			}
-		}
-	}
-
-	// All others
-	return select( selector.replace( rtrim, "$1" ), context, results, seed );
-}
-
-/**
- * Create key-value caches of limited size
- * @returns {function(string, object)} Returns the Object data after storing it on itself with
- *	property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength)
- *	deleting the oldest entry
- */
-function createCache() {
-	var keys = [];
-
-	function cache( key, value ) {
-
-		// Use (key + " ") to avoid collision with native prototype properties (see Issue #157)
-		if ( keys.push( key + " " ) > Expr.cacheLength ) {
-
-			// Only keep the most recent entries
-			delete cache[ keys.shift() ];
-		}
-		return ( cache[ key + " " ] = value );
-	}
-	return cache;
-}
-
-/**
- * Mark a function for special use by Sizzle
- * @param {Function} fn The function to mark
- */
-function markFunction( fn ) {
-	fn[ expando ] = true;
-	return fn;
-}
-
-/**
- * Support testing using an element
- * @param {Function} fn Passed the created element and returns a boolean result
- */
-function assert( fn ) {
-	var el = document.createElement( "fieldset" );
-
-	try {
-		return !!fn( el );
-	} catch ( e ) {
-		return false;
-	} finally {
-
-		// Remove from its parent by default
-		if ( el.parentNode ) {
-			el.parentNode.removeChild( el );
-		}
-
-		// release memory in IE
-		el = null;
-	}
-}
-
-/**
- * Adds the same handler for all of the specified attrs
- * @param {String} attrs Pipe-separated list of attributes
- * @param {Function} handler The method that will be applied
- */
-function addHandle( attrs, handler ) {
-	var arr = attrs.split( "|" ),
-		i = arr.length;
-
-	while ( i-- ) {
-		Expr.attrHandle[ arr[ i ] ] = handler;
-	}
-}
-
-/**
- * Checks document order of two siblings
- * @param {Element} a
- * @param {Element} b
- * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b
- */
-function siblingCheck( a, b ) {
-	var cur = b && a,
-		diff = cur && a.nodeType === 1 && b.nodeType === 1 &&
-			a.sourceIndex - b.sourceIndex;
-
-	// Use IE sourceIndex if available on both nodes
-	if ( diff ) {
-		return diff;
-	}
-
-	// Check if b follows a
-	if ( cur ) {
-		while ( ( cur = cur.nextSibling ) ) {
-			if ( cur === b ) {
-				return -1;
-			}
-		}
-	}
-
-	return a ? 1 : -1;
-}
-
-/**
- * Returns a function to use in pseudos for input types
- * @param {String} type
- */
-function createInputPseudo( type ) {
-	return function( elem ) {
-		var name = elem.nodeName.toLowerCase();
-		return name === "input" && elem.type === type;
-	};
-}
-
-/**
- * Returns a function to use in pseudos for buttons
- * @param {String} type
- */
-function createButtonPseudo( type ) {
-	return function( elem ) {
-		var name = elem.nodeName.toLowerCase();
-		return ( name === "input" || name === "button" ) && elem.type === type;
-	};
-}
-
-/**
- * Returns a function to use in pseudos for :enabled/:disabled
- * @param {Boolean} disabled true for :disabled; false for :enabled
- */
-function createDisabledPseudo( disabled ) {
-
-	// Known :disabled false positives: fieldset[disabled] > legend:nth-of-type(n+2) :can-disable
-	return function( elem ) {
-
-		// Only certain elements can match :enabled or :disabled
-		// https://html.spec.whatwg.org/multipage/scripting.html#selector-enabled
-		// https://html.spec.whatwg.org/multipage/scripting.html#selector-disabled
-		if ( "form" in elem ) {
-
-			// Check for inherited disabledness on relevant non-disabled elements:
-			// * listed form-associated elements in a disabled fieldset
-			//   https://html.spec.whatwg.org/multipage/forms.html#category-listed
-			//   https://html.spec.whatwg.org/multipage/forms.html#concept-fe-disabled
-			// * option elements in a disabled optgroup
-			//   https://html.spec.whatwg.org/multipage/forms.html#concept-option-disabled
-			// All such elements have a "form" property.
-			if ( elem.parentNode && elem.disabled === false ) {
-
-				// Option elements defer to a parent optgroup if present
-				if ( "label" in elem ) {
-					if ( "label" in elem.parentNode ) {
-						return elem.parentNode.disabled === disabled;
-					} else {
-						return elem.disabled === disabled;
-					}
-				}
-
-				// Support: IE 6 - 11
-				// Use the isDisabled shortcut property to check for disabled fieldset ancestors
-				return elem.isDisabled === disabled ||
-
-					// Where there is no isDisabled, check manually
-					/* jshint -W018 */
-					elem.isDisabled !== !disabled &&
-					inDisabledFieldset( elem ) === disabled;
-			}
-
-			return elem.disabled === disabled;
-
-		// Try to winnow out elements that can't be disabled before trusting the disabled property.
-		// Some victims get caught in our net (label, legend, menu, track), but it shouldn't
-		// even exist on them, let alone have a boolean value.
-		} else if ( "label" in elem ) {
-			return elem.disabled === disabled;
-		}
-
-		// Remaining elements are neither :enabled nor :disabled
-		return false;
-	};
-}
-
-/**
- * Returns a function to use in pseudos for positionals
- * @param {Function} fn
- */
-function createPositionalPseudo( fn ) {
-	return markFunction( function( argument ) {
-		argument = +argument;
-		return markFunction( function( seed, matches ) {
-			var j,
-				matchIndexes = fn( [], seed.length, argument ),
-				i = matchIndexes.length;
-
-			// Match elements found at the specified indexes
-			while ( i-- ) {
-				if ( seed[ ( j = matchIndexes[ i ] ) ] ) {
-					seed[ j ] = !( matches[ j ] = seed[ j ] );
-				}
-			}
-		} );
-	} );
-}
-
-/**
- * Checks a node for validity as a Sizzle context
- * @param {Element|Object=} context
- * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value
- */
-function testContext( context ) {
-	return context && typeof context.getElementsByTagName !== "undefined" && context;
-}
-
-// Expose support vars for convenience
-support = Sizzle.support = {};
-
-/**
- * Detects XML nodes
- * @param {Element|Object} elem An element or a document
- * @returns {Boolean} True iff elem is a non-HTML XML node
- */
-isXML = Sizzle.isXML = function( elem ) {
-	var namespace = elem.namespaceURI,
-		docElem = ( elem.ownerDocument || elem ).documentElement;
-
-	// Support: IE <=8
-	// Assume HTML when documentElement doesn't yet exist, such as inside loading iframes
-	// https://bugs.jquery.com/ticket/4833
-	return !rhtml.test( namespace || docElem && docElem.nodeName || "HTML" );
-};
-
-/**
- * Sets document-related variables once based on the current document
- * @param {Element|Object} [doc] An element or document object to use to set the document
- * @returns {Object} Returns the current document
- */
-setDocument = Sizzle.setDocument = function( node ) {
-	var hasCompare, subWindow,
-		doc = node ? node.ownerDocument || node : preferredDoc;
-
-	// Return early if doc is invalid or already selected
-	// Support: IE 11+, Edge 17 - 18+
-	// IE/Edge sometimes throw a "Permission denied" error when strict-comparing
-	// two documents; shallow comparisons work.
-	// eslint-disable-next-line eqeqeq
-	if ( doc == document || doc.nodeType !== 9 || !doc.documentElement ) {
-		return document;
-	}
-
-	// Update global variables
-	document = doc;
-	docElem = document.documentElement;
-	documentIsHTML = !isXML( document );
-
-	// Support: IE 9 - 11+, Edge 12 - 18+
-	// Accessing iframe documents after unload throws "permission denied" errors (jQuery #13936)
-	// Support: IE 11+, Edge 17 - 18+
-	// IE/Edge sometimes throw a "Permission denied" error when strict-comparing
-	// two documents; shallow comparisons work.
-	// eslint-disable-next-line eqeqeq
-	if ( preferredDoc != document &&
-		( subWindow = document.defaultView ) && subWindow.top !== subWindow ) {
-
-		// Support: IE 11, Edge
-		if ( subWindow.addEventListener ) {
-			subWindow.addEventListener( "unload", unloadHandler, false );
-
-		// Support: IE 9 - 10 only
-		} else if ( subWindow.attachEvent ) {
-			subWindow.attachEvent( "onunload", unloadHandler );
-		}
-	}
-
-	// Support: IE 8 - 11+, Edge 12 - 18+, Chrome <=16 - 25 only, Firefox <=3.6 - 31 only,
-	// Safari 4 - 5 only, Opera <=11.6 - 12.x only
-	// IE/Edge & older browsers don't support the :scope pseudo-class.
-	// Support: Safari 6.0 only
-	// Safari 6.0 supports :scope but it's an alias of :root there.
-	support.scope = assert( function( el ) {
-		docElem.appendChild( el ).appendChild( document.createElement( "div" ) );
-		return typeof el.querySelectorAll !== "undefined" &&
-			!el.querySelectorAll( ":scope fieldset div" ).length;
-	} );
-
-	/* Attributes
-	---------------------------------------------------------------------- */
-
-	// Support: IE<8
-	// Verify that getAttribute really returns attributes and not properties
-	// (excepting IE8 booleans)
-	support.attributes = assert( function( el ) {
-		el.className = "i";
-		return !el.getAttribute( "className" );
-	} );
-
-	/* getElement(s)By*
-	---------------------------------------------------------------------- */
-
-	// Check if getElementsByTagName("*") returns only elements
-	support.getElementsByTagName = assert( function( el ) {
-		el.appendChild( document.createComment( "" ) );
-		return !el.getElementsByTagName( "*" ).length;
-	} );
-
-	// Support: IE<9
-	support.getElementsByClassName = rnative.test( document.getElementsByClassName );
-
-	// Support: IE<10
-	// Check if getElementById returns elements by name
-	// The broken getElementById methods don't pick up programmatically-set names,
-	// so use a roundabout getElementsByName test
-	support.getById = assert( function( el ) {
-		docElem.appendChild( el ).id = expando;
-		return !document.getElementsByName || !document.getElementsByName( expando ).length;
-	} );
-
-	// ID filter and find
-	if ( support.getById ) {
-		Expr.filter[ "ID" ] = function( id ) {
-			var attrId = id.replace( runescape, funescape );
-			return function( elem ) {
-				return elem.getAttribute( "id" ) === attrId;
-			};
-		};
-		Expr.find[ "ID" ] = function( id, context ) {
-			if ( typeof context.getElementById !== "undefined" && documentIsHTML ) {
-				var elem = context.getElementById( id );
-				return elem ? [ elem ] : [];
-			}
-		};
-	} else {
-		Expr.filter[ "ID" ] =  function( id ) {
-			var attrId = id.replace( runescape, funescape );
-			return function( elem ) {
-				var node = typeof elem.getAttributeNode !== "undefined" &&
-					elem.getAttributeNode( "id" );
-				return node && node.value === attrId;
-			};
-		};
-
-		// Support: IE 6 - 7 only
-		// getElementById is not reliable as a find shortcut
-		Expr.find[ "ID" ] = function( id, context ) {
-			if ( typeof context.getElementById !== "undefined" && documentIsHTML ) {
-				var node, i, elems,
-					elem = context.getElementById( id );
-
-				if ( elem ) {
-
-					// Verify the id attribute
-					node = elem.getAttributeNode( "id" );
-					if ( node && node.value === id ) {
-						return [ elem ];
-					}
-
-					// Fall back on getElementsByName
-					elems = context.getElementsByName( id );
-					i = 0;
-					while ( ( elem = elems[ i++ ] ) ) {
-						node = elem.getAttributeNode( "id" );
-						if ( node && node.value === id ) {
-							return [ elem ];
-						}
-					}
-				}
-
-				return [];
-			}
-		};
-	}
-
-	// Tag
-	Expr.find[ "TAG" ] = support.getElementsByTagName ?
-		function( tag, context ) {
-			if ( typeof context.getElementsByTagName !== "undefined" ) {
-				return context.getElementsByTagName( tag );
-
-			// DocumentFragment nodes don't have gEBTN
-			} else if ( support.qsa ) {
-				return context.querySelectorAll( tag );
-			}
-		} :
-
-		function( tag, context ) {
-			var elem,
-				tmp = [],
-				i = 0,
-
-				// By happy coincidence, a (broken) gEBTN appears on DocumentFragment nodes too
-				results = context.getElementsByTagName( tag );
-
-			// Filter out possible comments
-			if ( tag === "*" ) {
-				while ( ( elem = results[ i++ ] ) ) {
-					if ( elem.nodeType === 1 ) {
-						tmp.push( elem );
-					}
-				}
-
-				return tmp;
-			}
-			return results;
-		};
-
-	// Class
-	Expr.find[ "CLASS" ] = support.getElementsByClassName && function( className, context ) {
-		if ( typeof context.getElementsByClassName !== "undefined" && documentIsHTML ) {
-			return context.getElementsByClassName( className );
-		}
-	};
-
-	/* QSA/matchesSelector
-	---------------------------------------------------------------------- */
-
-	// QSA and matchesSelector support
-
-	// matchesSelector(:active) reports false when true (IE9/Opera 11.5)
-	rbuggyMatches = [];
-
-	// qSa(:focus) reports false when true (Chrome 21)
-	// We allow this because of a bug in IE8/9 that throws an error
-	// whenever `document.activeElement` is accessed on an iframe
-	// So, we allow :focus to pass through QSA all the time to avoid the IE error
-	// See https://bugs.jquery.com/ticket/13378
-	rbuggyQSA = [];
-
-	if ( ( support.qsa = rnative.test( document.querySelectorAll ) ) ) {
-
-		// Build QSA regex
-		// Regex strategy adopted from Diego Perini
-		assert( function( el ) {
-
-			var input;
-
-			// Select is set to empty string on purpose
-			// This is to test IE's treatment of not explicitly
-			// setting a boolean content attribute,
-			// since its presence should be enough
-			// https://bugs.jquery.com/ticket/12359
-			docElem.appendChild( el ).innerHTML = "<a id='" + expando + "'></a>" +
-				"<select id='" + expando + "-\r\\' msallowcapture=''>" +
-				"<option selected=''></option></select>";
-
-			// Support: IE8, Opera 11-12.16
-			// Nothing should be selected when empty strings follow ^= or $= or *=
-			// The test attribute must be unknown in Opera but "safe" for WinRT
-			// https://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section
-			if ( el.querySelectorAll( "[msallowcapture^='']" ).length ) {
-				rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" );
-			}
-
-			// Support: IE8
-			// Boolean attributes and "value" are not treated correctly
-			if ( !el.querySelectorAll( "[selected]" ).length ) {
-				rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" );
-			}
-
-			// Support: Chrome<29, Android<4.4, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.8+
-			if ( !el.querySelectorAll( "[id~=" + expando + "-]" ).length ) {
-				rbuggyQSA.push( "~=" );
-			}
-
-			// Support: IE 11+, Edge 15 - 18+
-			// IE 11/Edge don't find elements on a `[name='']` query in some cases.
-			// Adding a temporary attribute to the document before the selection works
-			// around the issue.
-			// Interestingly, IE 10 & older don't seem to have the issue.
-			input = document.createElement( "input" );
-			input.setAttribute( "name", "" );
-			el.appendChild( input );
-			if ( !el.querySelectorAll( "[name='']" ).length ) {
-				rbuggyQSA.push( "\\[" + whitespace + "*name" + whitespace + "*=" +
-					whitespace + "*(?:''|\"\")" );
-			}
-
-			// Webkit/Opera - :checked should return selected option elements
-			// http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
-			// IE8 throws error here and will not see later tests
-			if ( !el.querySelectorAll( ":checked" ).length ) {
-				rbuggyQSA.push( ":checked" );
-			}
-
-			// Support: Safari 8+, iOS 8+
-			// https://bugs.webkit.org/show_bug.cgi?id=136851
-			// In-page `selector#id sibling-combinator selector` fails
-			if ( !el.querySelectorAll( "a#" + expando + "+*" ).length ) {
-				rbuggyQSA.push( ".#.+[+~]" );
-			}
-
-			// Support: Firefox <=3.6 - 5 only
-			// Old Firefox doesn't throw on a badly-escaped identifier.
-			el.querySelectorAll( "\\\f" );
-			rbuggyQSA.push( "[\\r\\n\\f]" );
-		} );
-
-		assert( function( el ) {
-			el.innerHTML = "<a href='' disabled='disabled'></a>" +
-				"<select disabled='disabled'><option/></select>";
-
-			// Support: Windows 8 Native Apps
-			// The type and name attributes are restricted during .innerHTML assignment
-			var input = document.createElement( "input" );
-			input.setAttribute( "type", "hidden" );
-			el.appendChild( input ).setAttribute( "name", "D" );
-
-			// Support: IE8
-			// Enforce case-sensitivity of name attribute
-			if ( el.querySelectorAll( "[name=d]" ).length ) {
-				rbuggyQSA.push( "name" + whitespace + "*[*^$|!~]?=" );
-			}
-
-			// FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled)
-			// IE8 throws error here and will not see later tests
-			if ( el.querySelectorAll( ":enabled" ).length !== 2 ) {
-				rbuggyQSA.push( ":enabled", ":disabled" );
-			}
-
-			// Support: IE9-11+
-			// IE's :disabled selector does not pick up the children of disabled fieldsets
-			docElem.appendChild( el ).disabled = true;
-			if ( el.querySelectorAll( ":disabled" ).length !== 2 ) {
-				rbuggyQSA.push( ":enabled", ":disabled" );
-			}
-
-			// Support: Opera 10 - 11 only
-			// Opera 10-11 does not throw on post-comma invalid pseudos
-			el.querySelectorAll( "*,:x" );
-			rbuggyQSA.push( ",.*:" );
-		} );
-	}
-
-	if ( ( support.matchesSelector = rnative.test( ( matches = docElem.matches ||
-		docElem.webkitMatchesSelector ||
-		docElem.mozMatchesSelector ||
-		docElem.oMatchesSelector ||
-		docElem.msMatchesSelector ) ) ) ) {
-
-		assert( function( el ) {
-
-			// Check to see if it's possible to do matchesSelector
-			// on a disconnected node (IE 9)
-			support.disconnectedMatch = matches.call( el, "*" );
-
-			// This should fail with an exception
-			// Gecko does not error, returns false instead
-			matches.call( el, "[s!='']:x" );
-			rbuggyMatches.push( "!=", pseudos );
-		} );
-	}
-
-	rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join( "|" ) );
-	rbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join( "|" ) );
-
-	/* Contains
-	---------------------------------------------------------------------- */
-	hasCompare = rnative.test( docElem.compareDocumentPosition );
-
-	// Element contains another
-	// Purposefully self-exclusive
-	// As in, an element does not contain itself
-	contains = hasCompare || rnative.test( docElem.contains ) ?
-		function( a, b ) {
-			var adown = a.nodeType === 9 ? a.documentElement : a,
-				bup = b && b.parentNode;
-			return a === bup || !!( bup && bup.nodeType === 1 && (
-				adown.contains ?
-					adown.contains( bup ) :
-					a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16
-			) );
-		} :
-		function( a, b ) {
-			if ( b ) {
-				while ( ( b = b.parentNode ) ) {
-					if ( b === a ) {
-						return true;
-					}
-				}
-			}
-			return false;
-		};
-
-	/* Sorting
-	---------------------------------------------------------------------- */
-
-	// Document order sorting
-	sortOrder = hasCompare ?
-	function( a, b ) {
-
-		// Flag for duplicate removal
-		if ( a === b ) {
-			hasDuplicate = true;
-			return 0;
-		}
-
-		// Sort on method existence if only one input has compareDocumentPosition
-		var compare = !a.compareDocumentPosition - !b.compareDocumentPosition;
-		if ( compare ) {
-			return compare;
-		}
-
-		// Calculate position if both inputs belong to the same document
-		// Support: IE 11+, Edge 17 - 18+
-		// IE/Edge sometimes throw a "Permission denied" error when strict-comparing
-		// two documents; shallow comparisons work.
-		// eslint-disable-next-line eqeqeq
-		compare = ( a.ownerDocument || a ) == ( b.ownerDocument || b ) ?
-			a.compareDocumentPosition( b ) :
-
-			// Otherwise we know they are disconnected
-			1;
-
-		// Disconnected nodes
-		if ( compare & 1 ||
-			( !support.sortDetached && b.compareDocumentPosition( a ) === compare ) ) {
-
-			// Choose the first element that is related to our preferred document
-			// Support: IE 11+, Edge 17 - 18+
-			// IE/Edge sometimes throw a "Permission denied" error when strict-comparing
-			// two documents; shallow comparisons work.
-			// eslint-disable-next-line eqeqeq
-			if ( a == document || a.ownerDocument == preferredDoc &&
-				contains( preferredDoc, a ) ) {
-				return -1;
-			}
-
-			// Support: IE 11+, Edge 17 - 18+
-			// IE/Edge sometimes throw a "Permission denied" error when strict-comparing
-			// two documents; shallow comparisons work.
-			// eslint-disable-next-line eqeqeq
-			if ( b == document || b.ownerDocument == preferredDoc &&
-				contains( preferredDoc, b ) ) {
-				return 1;
-			}
-
-			// Maintain original order
-			return sortInput ?
-				( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) :
-				0;
-		}
-
-		return compare & 4 ? -1 : 1;
-	} :
-	function( a, b ) {
-
-		// Exit early if the nodes are identical
-		if ( a === b ) {
-			hasDuplicate = true;
-			return 0;
-		}
-
-		var cur,
-			i = 0,
-			aup = a.parentNode,
-			bup = b.parentNode,
-			ap = [ a ],
-			bp = [ b ];
-
-		// Parentless nodes are either documents or disconnected
-		if ( !aup || !bup ) {
-
-			// Support: IE 11+, Edge 17 - 18+
-			// IE/Edge sometimes throw a "Permission denied" error when strict-comparing
-			// two documents; shallow comparisons work.
-			/* eslint-disable eqeqeq */
-			return a == document ? -1 :
-				b == document ? 1 :
-				/* eslint-enable eqeqeq */
-				aup ? -1 :
-				bup ? 1 :
-				sortInput ?
-				( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) :
-				0;
-
-		// If the nodes are siblings, we can do a quick check
-		} else if ( aup === bup ) {
-			return siblingCheck( a, b );
-		}
-
-		// Otherwise we need full lists of their ancestors for comparison
-		cur = a;
-		while ( ( cur = cur.parentNode ) ) {
-			ap.unshift( cur );
-		}
-		cur = b;
-		while ( ( cur = cur.parentNode ) ) {
-			bp.unshift( cur );
-		}
-
-		// Walk down the tree looking for a discrepancy
-		while ( ap[ i ] === bp[ i ] ) {
-			i++;
-		}
-
-		return i ?
-
-			// Do a sibling check if the nodes have a common ancestor
-			siblingCheck( ap[ i ], bp[ i ] ) :
-
-			// Otherwise nodes in our document sort first
-			// Support: IE 11+, Edge 17 - 18+
-			// IE/Edge sometimes throw a "Permission denied" error when strict-comparing
-			// two documents; shallow comparisons work.
-			/* eslint-disable eqeqeq */
-			ap[ i ] == preferredDoc ? -1 :
-			bp[ i ] == preferredDoc ? 1 :
-			/* eslint-enable eqeqeq */
-			0;
-	};
-
-	return document;
-};
-
-Sizzle.matches = function( expr, elements ) {
-	return Sizzle( expr, null, null, elements );
-};
-
-Sizzle.matchesSelector = function( elem, expr ) {
-	setDocument( elem );
-
-	if ( support.matchesSelector && documentIsHTML &&
-		!nonnativeSelectorCache[ expr + " " ] &&
-		( !rbuggyMatches || !rbuggyMatches.test( expr ) ) &&
-		( !rbuggyQSA     || !rbuggyQSA.test( expr ) ) ) {
-
-		try {
-			var ret = matches.call( elem, expr );
-
-			// IE 9's matchesSelector returns false on disconnected nodes
-			if ( ret || support.disconnectedMatch ||
-
-				// As well, disconnected nodes are said to be in a document
-				// fragment in IE 9
-				elem.document && elem.document.nodeType !== 11 ) {
-				return ret;
-			}
-		} catch ( e ) {
-			nonnativeSelectorCache( expr, true );
-		}
-	}
-
-	return Sizzle( expr, document, null, [ elem ] ).length > 0;
-};
-
-Sizzle.contains = function( context, elem ) {
-
-	// Set document vars if needed
-	// Support: IE 11+, Edge 17 - 18+
-	// IE/Edge sometimes throw a "Permission denied" error when strict-comparing
-	// two documents; shallow comparisons work.
-	// eslint-disable-next-line eqeqeq
-	if ( ( context.ownerDocument || context ) != document ) {
-		setDocument( context );
-	}
-	return contains( context, elem );
-};
-
-Sizzle.attr = function( elem, name ) {
-
-	// Set document vars if needed
-	// Support: IE 11+, Edge 17 - 18+
-	// IE/Edge sometimes throw a "Permission denied" error when strict-comparing
-	// two documents; shallow comparisons work.
-	// eslint-disable-next-line eqeqeq
-	if ( ( elem.ownerDocument || elem ) != document ) {
-		setDocument( elem );
-	}
-
-	var fn = Expr.attrHandle[ name.toLowerCase() ],
-
-		// Don't get fooled by Object.prototype properties (jQuery #13807)
-		val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ?
-			fn( elem, name, !documentIsHTML ) :
-			undefined;
-
-	return val !== undefined ?
-		val :
-		support.attributes || !documentIsHTML ?
-			elem.getAttribute( name ) :
-			( val = elem.getAttributeNode( name ) ) && val.specified ?
-				val.value :
-				null;
-};
-
-Sizzle.escape = function( sel ) {
-	return ( sel + "" ).replace( rcssescape, fcssescape );
-};
-
-Sizzle.error = function( msg ) {
-	throw new Error( "Syntax error, unrecognized expression: " + msg );
-};
-
-/**
- * Document sorting and removing duplicates
- * @param {ArrayLike} results
- */
-Sizzle.uniqueSort = function( results ) {
-	var elem,
-		duplicates = [],
-		j = 0,
-		i = 0;
-
-	// Unless we *know* we can detect duplicates, assume their presence
-	hasDuplicate = !support.detectDuplicates;
-	sortInput = !support.sortStable && results.slice( 0 );
-	results.sort( sortOrder );
-
-	if ( hasDuplicate ) {
-		while ( ( elem = results[ i++ ] ) ) {
-			if ( elem === results[ i ] ) {
-				j = duplicates.push( i );
-			}
-		}
-		while ( j-- ) {
-			results.splice( duplicates[ j ], 1 );
-		}
-	}
-
-	// Clear input after sorting to release objects
-	// See https://github.com/jquery/sizzle/pull/225
-	sortInput = null;
-
-	return results;
-};
-
-/**
- * Utility function for retrieving the text value of an array of DOM nodes
- * @param {Array|Element} elem
- */
-getText = Sizzle.getText = function( elem ) {
-	var node,
-		ret = "",
-		i = 0,
-		nodeType = elem.nodeType;
-
-	if ( !nodeType ) {
-
-		// If no nodeType, this is expected to be an array
-		while ( ( node = elem[ i++ ] ) ) {
-
-			// Do not traverse comment nodes
-			ret += getText( node );
-		}
-	} else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) {
-
-		// Use textContent for elements
-		// innerText usage removed for consistency of new lines (jQuery #11153)
-		if ( typeof elem.textContent === "string" ) {
-			return elem.textContent;
-		} else {
-
-			// Traverse its children
-			for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
-				ret += getText( elem );
-			}
-		}
-	} else if ( nodeType === 3 || nodeType === 4 ) {
-		return elem.nodeValue;
-	}
-
-	// Do not include comment or processing instruction nodes
-
-	return ret;
-};
-
-Expr = Sizzle.selectors = {
-
-	// Can be adjusted by the user
-	cacheLength: 50,
-
-	createPseudo: markFunction,
-
-	match: matchExpr,
-
-	attrHandle: {},
-
-	find: {},
-
-	relative: {
-		">": { dir: "parentNode", first: true },
-		" ": { dir: "parentNode" },
-		"+": { dir: "previousSibling", first: true },
-		"~": { dir: "previousSibling" }
-	},
-
-	preFilter: {
-		"ATTR": function( match ) {
-			match[ 1 ] = match[ 1 ].replace( runescape, funescape );
-
-			// Move the given value to match[3] whether quoted or unquoted
-			match[ 3 ] = ( match[ 3 ] || match[ 4 ] ||
-				match[ 5 ] || "" ).replace( runescape, funescape );
-
-			if ( match[ 2 ] === "~=" ) {
-				match[ 3 ] = " " + match[ 3 ] + " ";
-			}
-
-			return match.slice( 0, 4 );
-		},
-
-		"CHILD": function( match ) {
-
-			/* matches from matchExpr["CHILD"]
-				1 type (only|nth|...)
-				2 what (child|of-type)
-				3 argument (even|odd|\d*|\d*n([+-]\d+)?|...)
-				4 xn-component of xn+y argument ([+-]?\d*n|)
-				5 sign of xn-component
-				6 x of xn-component
-				7 sign of y-component
-				8 y of y-component
-			*/
-			match[ 1 ] = match[ 1 ].toLowerCase();
-
-			if ( match[ 1 ].slice( 0, 3 ) === "nth" ) {
-
-				// nth-* requires argument
-				if ( !match[ 3 ] ) {
-					Sizzle.error( match[ 0 ] );
-				}
-
-				// numeric x and y parameters for Expr.filter.CHILD
-				// remember that false/true cast respectively to 0/1
-				match[ 4 ] = +( match[ 4 ] ?
-					match[ 5 ] + ( match[ 6 ] || 1 ) :
-					2 * ( match[ 3 ] === "even" || match[ 3 ] === "odd" ) );
-				match[ 5 ] = +( ( match[ 7 ] + match[ 8 ] ) || match[ 3 ] === "odd" );
-
-				// other types prohibit arguments
-			} else if ( match[ 3 ] ) {
-				Sizzle.error( match[ 0 ] );
-			}
-
-			return match;
-		},
-
-		"PSEUDO": function( match ) {
-			var excess,
-				unquoted = !match[ 6 ] && match[ 2 ];
-
-			if ( matchExpr[ "CHILD" ].test( match[ 0 ] ) ) {
-				return null;
-			}
-
-			// Accept quoted arguments as-is
-			if ( match[ 3 ] ) {
-				match[ 2 ] = match[ 4 ] || match[ 5 ] || "";
-
-			// Strip excess characters from unquoted arguments
-			} else if ( unquoted && rpseudo.test( unquoted ) &&
-
-				// Get excess from tokenize (recursively)
-				( excess = tokenize( unquoted, true ) ) &&
-
-				// advance to the next closing parenthesis
-				( excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length ) ) {
-
-				// excess is a negative index
-				match[ 0 ] = match[ 0 ].slice( 0, excess );
-				match[ 2 ] = unquoted.slice( 0, excess );
-			}
-
-			// Return only captures needed by the pseudo filter method (type and argument)
-			return match.slice( 0, 3 );
-		}
-	},
-
-	filter: {
-
-		"TAG": function( nodeNameSelector ) {
-			var nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase();
-			return nodeNameSelector === "*" ?
-				function() {
-					return true;
-				} :
-				function( elem ) {
-					return elem.nodeName && elem.nodeName.toLowerCase() === nodeName;
-				};
-		},
-
-		"CLASS": function( className ) {
-			var pattern = classCache[ className + " " ];
-
-			return pattern ||
-				( pattern = new RegExp( "(^|" + whitespace +
-					")" + className + "(" + whitespace + "|$)" ) ) && classCache(
-						className, function( elem ) {
-							return pattern.test(
-								typeof elem.className === "string" && elem.className ||
-								typeof elem.getAttribute !== "undefined" &&
-									elem.getAttribute( "class" ) ||
-								""
-							);
-				} );
-		},
-
-		"ATTR": function( name, operator, check ) {
-			return function( elem ) {
-				var result = Sizzle.attr( elem, name );
-
-				if ( result == null ) {
-					return operator === "!=";
-				}
-				if ( !operator ) {
-					return true;
-				}
-
-				result += "";
-
-				/* eslint-disable max-len */
-
-				return operator === "=" ? result === check :
-					operator === "!=" ? result !== check :
-					operator === "^=" ? check && result.indexOf( check ) === 0 :
-					operator === "*=" ? check && result.indexOf( check ) > -1 :
-					operator === "$=" ? check && result.slice( -check.length ) === check :
-					operator === "~=" ? ( " " + result.replace( rwhitespace, " " ) + " " ).indexOf( check ) > -1 :
-					operator === "|=" ? result === check || result.slice( 0, check.length + 1 ) === check + "-" :
-					false;
-				/* eslint-enable max-len */
-
-			};
-		},
-
-		"CHILD": function( type, what, _argument, first, last ) {
-			var simple = type.slice( 0, 3 ) !== "nth",
-				forward = type.slice( -4 ) !== "last",
-				ofType = what === "of-type";
-
-			return first === 1 && last === 0 ?
-
-				// Shortcut for :nth-*(n)
-				function( elem ) {
-					return !!elem.parentNode;
-				} :
-
-				function( elem, _context, xml ) {
-					var cache, uniqueCache, outerCache, node, nodeIndex, start,
-						dir = simple !== forward ? "nextSibling" : "previousSibling",
-						parent = elem.parentNode,
-						name = ofType && elem.nodeName.toLowerCase(),
-						useCache = !xml && !ofType,
-						diff = false;
-
-					if ( parent ) {
-
-						// :(first|last|only)-(child|of-type)
-						if ( simple ) {
-							while ( dir ) {
-								node = elem;
-								while ( ( node = node[ dir ] ) ) {
-									if ( ofType ?
-										node.nodeName.toLowerCase() === name :
-										node.nodeType === 1 ) {
-
-										return false;
-									}
-								}
-
-								// Reverse direction for :only-* (if we haven't yet done so)
-								start = dir = type === "only" && !start && "nextSibling";
-							}
-							return true;
-						}
-
-						start = [ forward ? parent.firstChild : parent.lastChild ];
-
-						// non-xml :nth-child(...) stores cache data on `parent`
-						if ( forward && useCache ) {
-
-							// Seek `elem` from a previously-cached index
-
-							// ...in a gzip-friendly way
-							node = parent;
-							outerCache = node[ expando ] || ( node[ expando ] = {} );
-
-							// Support: IE <9 only
-							// Defend against cloned attroperties (jQuery gh-1709)
-							uniqueCache = outerCache[ node.uniqueID ] ||
-								( outerCache[ node.uniqueID ] = {} );
-
-							cache = uniqueCache[ type ] || [];
-							nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ];
-							diff = nodeIndex && cache[ 2 ];
-							node = nodeIndex && parent.childNodes[ nodeIndex ];
-
-							while ( ( node = ++nodeIndex && node && node[ dir ] ||
-
-								// Fallback to seeking `elem` from the start
-								( diff = nodeIndex = 0 ) || start.pop() ) ) {
-
-								// When found, cache indexes on `parent` and break
-								if ( node.nodeType === 1 && ++diff && node === elem ) {
-									uniqueCache[ type ] = [ dirruns, nodeIndex, diff ];
-									break;
-								}
-							}
-
-						} else {
-
-							// Use previously-cached element index if available
-							if ( useCache ) {
-
-								// ...in a gzip-friendly way
-								node = elem;
-								outerCache = node[ expando ] || ( node[ expando ] = {} );
-
-								// Support: IE <9 only
-								// Defend against cloned attroperties (jQuery gh-1709)
-								uniqueCache = outerCache[ node.uniqueID ] ||
-									( outerCache[ node.uniqueID ] = {} );
-
-								cache = uniqueCache[ type ] || [];
-								nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ];
-								diff = nodeIndex;
-							}
-
-							// xml :nth-child(...)
-							// or :nth-last-child(...) or :nth(-last)?-of-type(...)
-							if ( diff === false ) {
-
-								// Use the same loop as above to seek `elem` from the start
-								while ( ( node = ++nodeIndex && node && node[ dir ] ||
-									( diff = nodeIndex = 0 ) || start.pop() ) ) {
-
-									if ( ( ofType ?
-										node.nodeName.toLowerCase() === name :
-										node.nodeType === 1 ) &&
-										++diff ) {
-
-										// Cache the index of each encountered element
-										if ( useCache ) {
-											outerCache = node[ expando ] ||
-												( node[ expando ] = {} );
-
-											// Support: IE <9 only
-											// Defend against cloned attroperties (jQuery gh-1709)
-											uniqueCache = outerCache[ node.uniqueID ] ||
-												( outerCache[ node.uniqueID ] = {} );
-
-											uniqueCache[ type ] = [ dirruns, diff ];
-										}
-
-										if ( node === elem ) {
-											break;
-										}
-									}
-								}
-							}
-						}
-
-						// Incorporate the offset, then check against cycle size
-						diff -= last;
-						return diff === first || ( diff % first === 0 && diff / first >= 0 );
-					}
-				};
-		},
-
-		"PSEUDO": function( pseudo, argument ) {
-
-			// pseudo-class names are case-insensitive
-			// http://www.w3.org/TR/selectors/#pseudo-classes
-			// Prioritize by case sensitivity in case custom pseudos are added with uppercase letters
-			// Remember that setFilters inherits from pseudos
-			var args,
-				fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] ||
-					Sizzle.error( "unsupported pseudo: " + pseudo );
-
-			// The user may use createPseudo to indicate that
-			// arguments are needed to create the filter function
-			// just as Sizzle does
-			if ( fn[ expando ] ) {
-				return fn( argument );
-			}
-
-			// But maintain support for old signatures
-			if ( fn.length > 1 ) {
-				args = [ pseudo, pseudo, "", argument ];
-				return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ?
-					markFunction( function( seed, matches ) {
-						var idx,
-							matched = fn( seed, argument ),
-							i = matched.length;
-						while ( i-- ) {
-							idx = indexOf( seed, matched[ i ] );
-							seed[ idx ] = !( matches[ idx ] = matched[ i ] );
-						}
-					} ) :
-					function( elem ) {
-						return fn( elem, 0, args );
-					};
-			}
-
-			return fn;
-		}
-	},
-
-	pseudos: {
-
-		// Potentially complex pseudos
-		"not": markFunction( function( selector ) {
-
-			// Trim the selector passed to compile
-			// to avoid treating leading and trailing
-			// spaces as combinators
-			var input = [],
-				results = [],
-				matcher = compile( selector.replace( rtrim, "$1" ) );
-
-			return matcher[ expando ] ?
-				markFunction( function( seed, matches, _context, xml ) {
-					var elem,
-						unmatched = matcher( seed, null, xml, [] ),
-						i = seed.length;
-
-					// Match elements unmatched by `matcher`
-					while ( i-- ) {
-						if ( ( elem = unmatched[ i ] ) ) {
-							seed[ i ] = !( matches[ i ] = elem );
-						}
-					}
-				} ) :
-				function( elem, _context, xml ) {
-					input[ 0 ] = elem;
-					matcher( input, null, xml, results );
-
-					// Don't keep the element (issue #299)
-					input[ 0 ] = null;
-					return !results.pop();
-				};
-		} ),
-
-		"has": markFunction( function( selector ) {
-			return function( elem ) {
-				return Sizzle( selector, elem ).length > 0;
-			};
-		} ),
-
-		"contains": markFunction( function( text ) {
-			text = text.replace( runescape, funescape );
-			return function( elem ) {
-				return ( elem.textContent || getText( elem ) ).indexOf( text ) > -1;
-			};
-		} ),
-
-		// "Whether an element is represented by a :lang() selector
-		// is based solely on the element's language value
-		// being equal to the identifier C,
-		// or beginning with the identifier C immediately followed by "-".
-		// The matching of C against the element's language value is performed case-insensitively.
-		// The identifier C does not have to be a valid language name."
-		// http://www.w3.org/TR/selectors/#lang-pseudo
-		"lang": markFunction( function( lang ) {
-
-			// lang value must be a valid identifier
-			if ( !ridentifier.test( lang || "" ) ) {
-				Sizzle.error( "unsupported lang: " + lang );
-			}
-			lang = lang.replace( runescape, funescape ).toLowerCase();
-			return function( elem ) {
-				var elemLang;
-				do {
-					if ( ( elemLang = documentIsHTML ?
-						elem.lang :
-						elem.getAttribute( "xml:lang" ) || elem.getAttribute( "lang" ) ) ) {
-
-						elemLang = elemLang.toLowerCase();
-						return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0;
-					}
-				} while ( ( elem = elem.parentNode ) && elem.nodeType === 1 );
-				return false;
-			};
-		} ),
-
-		// Miscellaneous
-		"target": function( elem ) {
-			var hash = window.location && window.location.hash;
-			return hash && hash.slice( 1 ) === elem.id;
-		},
-
-		"root": function( elem ) {
-			return elem === docElem;
-		},
-
-		"focus": function( elem ) {
-			return elem === document.activeElement &&
-				( !document.hasFocus || document.hasFocus() ) &&
-				!!( elem.type || elem.href || ~elem.tabIndex );
-		},
-
-		// Boolean properties
-		"enabled": createDisabledPseudo( false ),
-		"disabled": createDisabledPseudo( true ),
-
-		"checked": function( elem ) {
-
-			// In CSS3, :checked should return both checked and selected elements
-			// http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
-			var nodeName = elem.nodeName.toLowerCase();
-			return ( nodeName === "input" && !!elem.checked ) ||
-				( nodeName === "option" && !!elem.selected );
-		},
-
-		"selected": function( elem ) {
-
-			// Accessing this property makes selected-by-default
-			// options in Safari work properly
-			if ( elem.parentNode ) {
-				// eslint-disable-next-line no-unused-expressions
-				elem.parentNode.selectedIndex;
-			}
-
-			return elem.selected === true;
-		},
-
-		// Contents
-		"empty": function( elem ) {
-
-			// http://www.w3.org/TR/selectors/#empty-pseudo
-			// :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5),
-			//   but not by others (comment: 8; processing instruction: 7; etc.)
-			// nodeType < 6 works because attributes (2) do not appear as children
-			for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
-				if ( elem.nodeType < 6 ) {
-					return false;
-				}
-			}
-			return true;
-		},
-
-		"parent": function( elem ) {
-			return !Expr.pseudos[ "empty" ]( elem );
-		},
-
-		// Element/input types
-		"header": function( elem ) {
-			return rheader.test( elem.nodeName );
-		},
-
-		"input": function( elem ) {
-			return rinputs.test( elem.nodeName );
-		},
-
-		"button": function( elem ) {
-			var name = elem.nodeName.toLowerCase();
-			return name === "input" && elem.type === "button" || name === "button";
-		},
-
-		"text": function( elem ) {
-			var attr;
-			return elem.nodeName.toLowerCase() === "input" &&
-				elem.type === "text" &&
-
-				// Support: IE<8
-				// New HTML5 attribute values (e.g., "search") appear with elem.type === "text"
-				( ( attr = elem.getAttribute( "type" ) ) == null ||
-					attr.toLowerCase() === "text" );
-		},
-
-		// Position-in-collection
-		"first": createPositionalPseudo( function() {
-			return [ 0 ];
-		} ),
-
-		"last": createPositionalPseudo( function( _matchIndexes, length ) {
-			return [ length - 1 ];
-		} ),
-
-		"eq": createPositionalPseudo( function( _matchIndexes, length, argument ) {
-			return [ argument < 0 ? argument + length : argument ];
-		} ),
-
-		"even": createPositionalPseudo( function( matchIndexes, length ) {
-			var i = 0;
-			for ( ; i < length; i += 2 ) {
-				matchIndexes.push( i );
-			}
-			return matchIndexes;
-		} ),
-
-		"odd": createPositionalPseudo( function( matchIndexes, length ) {
-			var i = 1;
-			for ( ; i < length; i += 2 ) {
-				matchIndexes.push( i );
-			}
-			return matchIndexes;
-		} ),
-
-		"lt": createPositionalPseudo( function( matchIndexes, length, argument ) {
-			var i = argument < 0 ?
-				argument + length :
-				argument > length ?
-					length :
-					argument;
-			for ( ; --i >= 0; ) {
-				matchIndexes.push( i );
-			}
-			return matchIndexes;
-		} ),
-
-		"gt": createPositionalPseudo( function( matchIndexes, length, argument ) {
-			var i = argument < 0 ? argument + length : argument;
-			for ( ; ++i < length; ) {
-				matchIndexes.push( i );
-			}
-			return matchIndexes;
-		} )
-	}
-};
-
-Expr.pseudos[ "nth" ] = Expr.pseudos[ "eq" ];
-
-// Add button/input type pseudos
-for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) {
-	Expr.pseudos[ i ] = createInputPseudo( i );
-}
-for ( i in { submit: true, reset: true } ) {
-	Expr.pseudos[ i ] = createButtonPseudo( i );
-}
-
-// Easy API for creating new setFilters
-function setFilters() {}
-setFilters.prototype = Expr.filters = Expr.pseudos;
-Expr.setFilters = new setFilters();
-
-tokenize = Sizzle.tokenize = function( selector, parseOnly ) {
-	var matched, match, tokens, type,
-		soFar, groups, preFilters,
-		cached = tokenCache[ selector + " " ];
-
-	if ( cached ) {
-		return parseOnly ? 0 : cached.slice( 0 );
-	}
-
-	soFar = selector;
-	groups = [];
-	preFilters = Expr.preFilter;
-
-	while ( soFar ) {
-
-		// Comma and first run
-		if ( !matched || ( match = rcomma.exec( soFar ) ) ) {
-			if ( match ) {
-
-				// Don't consume trailing commas as valid
-				soFar = soFar.slice( match[ 0 ].length ) || soFar;
-			}
-			groups.push( ( tokens = [] ) );
-		}
-
-		matched = false;
-
-		// Combinators
-		if ( ( match = rcombinators.exec( soFar ) ) ) {
-			matched = match.shift();
-			tokens.push( {
-				value: matched,
-
-				// Cast descendant combinators to space
-				type: match[ 0 ].replace( rtrim, " " )
-			} );
-			soFar = soFar.slice( matched.length );
-		}
-
-		// Filters
-		for ( type in Expr.filter ) {
-			if ( ( match = matchExpr[ type ].exec( soFar ) ) && ( !preFilters[ type ] ||
-				( match = preFilters[ type ]( match ) ) ) ) {
-				matched = match.shift();
-				tokens.push( {
-					value: matched,
-					type: type,
-					matches: match
-				} );
-				soFar = soFar.slice( matched.length );
-			}
-		}
-
-		if ( !matched ) {
-			break;
-		}
-	}
-
-	// Return the length of the invalid excess
-	// if we're just parsing
-	// Otherwise, throw an error or return tokens
-	return parseOnly ?
-		soFar.length :
-		soFar ?
-			Sizzle.error( selector ) :
-
-			// Cache the tokens
-			tokenCache( selector, groups ).slice( 0 );
-};
-
-function toSelector( tokens ) {
-	var i = 0,
-		len = tokens.length,
-		selector = "";
-	for ( ; i < len; i++ ) {
-		selector += tokens[ i ].value;
-	}
-	return selector;
-}
-
-function addCombinator( matcher, combinator, base ) {
-	var dir = combinator.dir,
-		skip = combinator.next,
-		key = skip || dir,
-		checkNonElements = base && key === "parentNode",
-		doneName = done++;
-
-	return combinator.first ?
-
-		// Check against closest ancestor/preceding element
-		function( elem, context, xml ) {
-			while ( ( elem = elem[ dir ] ) ) {
-				if ( elem.nodeType === 1 || checkNonElements ) {
-					return matcher( elem, context, xml );
-				}
-			}
-			return false;
-		} :
-
-		// Check against all ancestor/preceding elements
-		function( elem, context, xml ) {
-			var oldCache, uniqueCache, outerCache,
-				newCache = [ dirruns, doneName ];
-
-			// We can't set arbitrary data on XML nodes, so they don't benefit from combinator caching
-			if ( xml ) {
-				while ( ( elem = elem[ dir ] ) ) {
-					if ( elem.nodeType === 1 || checkNonElements ) {
-						if ( matcher( elem, context, xml ) ) {
-							return true;
-						}
-					}
-				}
-			} else {
-				while ( ( elem = elem[ dir ] ) ) {
-					if ( elem.nodeType === 1 || checkNonElements ) {
-						outerCache = elem[ expando ] || ( elem[ expando ] = {} );
-
-						// Support: IE <9 only
-						// Defend against cloned attroperties (jQuery gh-1709)
-						uniqueCache = outerCache[ elem.uniqueID ] ||
-							( outerCache[ elem.uniqueID ] = {} );
-
-						if ( skip && skip === elem.nodeName.toLowerCase() ) {
-							elem = elem[ dir ] || elem;
-						} else if ( ( oldCache = uniqueCache[ key ] ) &&
-							oldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) {
-
-							// Assign to newCache so results back-propagate to previous elements
-							return ( newCache[ 2 ] = oldCache[ 2 ] );
-						} else {
-
-							// Reuse newcache so results back-propagate to previous elements
-							uniqueCache[ key ] = newCache;
-
-							// A match means we're done; a fail means we have to keep checking
-							if ( ( newCache[ 2 ] = matcher( elem, context, xml ) ) ) {
-								return true;
-							}
-						}
-					}
-				}
-			}
-			return false;
-		};
-}
-
-function elementMatcher( matchers ) {
-	return matchers.length > 1 ?
-		function( elem, context, xml ) {
-			var i = matchers.length;
-			while ( i-- ) {
-				if ( !matchers[ i ]( elem, context, xml ) ) {
-					return false;
-				}
-			}
-			return true;
-		} :
-		matchers[ 0 ];
-}
-
-function multipleContexts( selector, contexts, results ) {
-	var i = 0,
-		len = contexts.length;
-	for ( ; i < len; i++ ) {
-		Sizzle( selector, contexts[ i ], results );
-	}
-	return results;
-}
-
-function condense( unmatched, map, filter, context, xml ) {
-	var elem,
-		newUnmatched = [],
-		i = 0,
-		len = unmatched.length,
-		mapped = map != null;
-
-	for ( ; i < len; i++ ) {
-		if ( ( elem = unmatched[ i ] ) ) {
-			if ( !filter || filter( elem, context, xml ) ) {
-				newUnmatched.push( elem );
-				if ( mapped ) {
-					map.push( i );
-				}
-			}
-		}
-	}
-
-	return newUnmatched;
-}
-
-function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) {
-	if ( postFilter && !postFilter[ expando ] ) {
-		postFilter = setMatcher( postFilter );
-	}
-	if ( postFinder && !postFinder[ expando ] ) {
-		postFinder = setMatcher( postFinder, postSelector );
-	}
-	return markFunction( function( seed, results, context, xml ) {
-		var temp, i, elem,
-			preMap = [],
-			postMap = [],
-			preexisting = results.length,
-
-			// Get initial elements from seed or context
-			elems = seed || multipleContexts(
-				selector || "*",
-				context.nodeType ? [ context ] : context,
-				[]
-			),
-
-			// Prefilter to get matcher input, preserving a map for seed-results synchronization
-			matcherIn = preFilter && ( seed || !selector ) ?
-				condense( elems, preMap, preFilter, context, xml ) :
-				elems,
-
-			matcherOut = matcher ?
-
-				// If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results,
-				postFinder || ( seed ? preFilter : preexisting || postFilter ) ?
-
-					// ...intermediate processing is necessary
-					[] :
-
-					// ...otherwise use results directly
-					results :
-				matcherIn;
-
-		// Find primary matches
-		if ( matcher ) {
-			matcher( matcherIn, matcherOut, context, xml );
-		}
-
-		// Apply postFilter
-		if ( postFilter ) {
-			temp = condense( matcherOut, postMap );
-			postFilter( temp, [], context, xml );
-
-			// Un-match failing elements by moving them back to matcherIn
-			i = temp.length;
-			while ( i-- ) {
-				if ( ( elem = temp[ i ] ) ) {
-					matcherOut[ postMap[ i ] ] = !( matcherIn[ postMap[ i ] ] = elem );
-				}
-			}
-		}
-
-		if ( seed ) {
-			if ( postFinder || preFilter ) {
-				if ( postFinder ) {
-
-					// Get the final matcherOut by condensing this intermediate into postFinder contexts
-					temp = [];
-					i = matcherOut.length;
-					while ( i-- ) {
-						if ( ( elem = matcherOut[ i ] ) ) {
-
-							// Restore matcherIn since elem is not yet a final match
-							temp.push( ( matcherIn[ i ] = elem ) );
-						}
-					}
-					postFinder( null, ( matcherOut = [] ), temp, xml );
-				}
-
-				// Move matched elements from seed to results to keep them synchronized
-				i = matcherOut.length;
-				while ( i-- ) {
-					if ( ( elem = matcherOut[ i ] ) &&
-						( temp = postFinder ? indexOf( seed, elem ) : preMap[ i ] ) > -1 ) {
-
-						seed[ temp ] = !( results[ temp ] = elem );
-					}
-				}
-			}
-
-		// Add elements to results, through postFinder if defined
-		} else {
-			matcherOut = condense(
-				matcherOut === results ?
-					matcherOut.splice( preexisting, matcherOut.length ) :
-					matcherOut
-			);
-			if ( postFinder ) {
-				postFinder( null, results, matcherOut, xml );
-			} else {
-				push.apply( results, matcherOut );
-			}
-		}
-	} );
-}
-
-function matcherFromTokens( tokens ) {
-	var checkContext, matcher, j,
-		len = tokens.length,
-		leadingRelative = Expr.relative[ tokens[ 0 ].type ],
-		implicitRelative = leadingRelative || Expr.relative[ " " ],
-		i = leadingRelative ? 1 : 0,
-
-		// The foundational matcher ensures that elements are reachable from top-level context(s)
-		matchContext = addCombinator( function( elem ) {
-			return elem === checkContext;
-		}, implicitRelative, true ),
-		matchAnyContext = addCombinator( function( elem ) {
-			return indexOf( checkContext, elem ) > -1;
-		}, implicitRelative, true ),
-		matchers = [ function( elem, context, xml ) {
-			var ret = ( !leadingRelative && ( xml || context !== outermostContext ) ) || (
-				( checkContext = context ).nodeType ?
-					matchContext( elem, context, xml ) :
-					matchAnyContext( elem, context, xml ) );
-
-			// Avoid hanging onto element (issue #299)
-			checkContext = null;
-			return ret;
-		} ];
-
-	for ( ; i < len; i++ ) {
-		if ( ( matcher = Expr.relative[ tokens[ i ].type ] ) ) {
-			matchers = [ addCombinator( elementMatcher( matchers ), matcher ) ];
-		} else {
-			matcher = Expr.filter[ tokens[ i ].type ].apply( null, tokens[ i ].matches );
-
-			// Return special upon seeing a positional matcher
-			if ( matcher[ expando ] ) {
-
-				// Find the next relative operator (if any) for proper handling
-				j = ++i;
-				for ( ; j < len; j++ ) {
-					if ( Expr.relative[ tokens[ j ].type ] ) {
-						break;
-					}
-				}
-				return setMatcher(
-					i > 1 && elementMatcher( matchers ),
-					i > 1 && toSelector(
-
-					// If the preceding token was a descendant combinator, insert an implicit any-element `*`
-					tokens
-						.slice( 0, i - 1 )
-						.concat( { value: tokens[ i - 2 ].type === " " ? "*" : "" } )
-					).replace( rtrim, "$1" ),
-					matcher,
-					i < j && matcherFromTokens( tokens.slice( i, j ) ),
-					j < len && matcherFromTokens( ( tokens = tokens.slice( j ) ) ),
-					j < len && toSelector( tokens )
-				);
-			}
-			matchers.push( matcher );
-		}
-	}
-
-	return elementMatcher( matchers );
-}
-
-function matcherFromGroupMatchers( elementMatchers, setMatchers ) {
-	var bySet = setMatchers.length > 0,
-		byElement = elementMatchers.length > 0,
-		superMatcher = function( seed, context, xml, results, outermost ) {
-			var elem, j, matcher,
-				matchedCount = 0,
-				i = "0",
-				unmatched = seed && [],
-				setMatched = [],
-				contextBackup = outermostContext,
-
-				// We must always have either seed elements or outermost context
-				elems = seed || byElement && Expr.find[ "TAG" ]( "*", outermost ),
-
-				// Use integer dirruns iff this is the outermost matcher
-				dirrunsUnique = ( dirruns += contextBackup == null ? 1 : Math.random() || 0.1 ),
-				len = elems.length;
-
-			if ( outermost ) {
-
-				// Support: IE 11+, Edge 17 - 18+
-				// IE/Edge sometimes throw a "Permission denied" error when strict-comparing
-				// two documents; shallow comparisons work.
-				// eslint-disable-next-line eqeqeq
-				outermostContext = context == document || context || outermost;
-			}
-
-			// Add elements passing elementMatchers directly to results
-			// Support: IE<9, Safari
-			// Tolerate NodeList properties (IE: "length"; Safari: <number>) matching elements by id
-			for ( ; i !== len && ( elem = elems[ i ] ) != null; i++ ) {
-				if ( byElement && elem ) {
-					j = 0;
-
-					// Support: IE 11+, Edge 17 - 18+
-					// IE/Edge sometimes throw a "Permission denied" error when strict-comparing
-					// two documents; shallow comparisons work.
-					// eslint-disable-next-line eqeqeq
-					if ( !context && elem.ownerDocument != document ) {
-						setDocument( elem );
-						xml = !documentIsHTML;
-					}
-					while ( ( matcher = elementMatchers[ j++ ] ) ) {
-						if ( matcher( elem, context || document, xml ) ) {
-							results.push( elem );
-							break;
-						}
-					}
-					if ( outermost ) {
-						dirruns = dirrunsUnique;
-					}
-				}
-
-				// Track unmatched elements for set filters
-				if ( bySet ) {
-
-					// They will have gone through all possible matchers
-					if ( ( elem = !matcher && elem ) ) {
-						matchedCount--;
-					}
-
-					// Lengthen the array for every element, matched or not
-					if ( seed ) {
-						unmatched.push( elem );
-					}
-				}
-			}
-
-			// `i` is now the count of elements visited above, and adding it to `matchedCount`
-			// makes the latter nonnegative.
-			matchedCount += i;
-
-			// Apply set filters to unmatched elements
-			// NOTE: This can be skipped if there are no unmatched elements (i.e., `matchedCount`
-			// equals `i`), unless we didn't visit _any_ elements in the above loop because we have
-			// no element matchers and no seed.
-			// Incrementing an initially-string "0" `i` allows `i` to remain a string only in that
-			// case, which will result in a "00" `matchedCount` that differs from `i` but is also
-			// numerically zero.
-			if ( bySet && i !== matchedCount ) {
-				j = 0;
-				while ( ( matcher = setMatchers[ j++ ] ) ) {
-					matcher( unmatched, setMatched, context, xml );
-				}
-
-				if ( seed ) {
-
-					// Reintegrate element matches to eliminate the need for sorting
-					if ( matchedCount > 0 ) {
-						while ( i-- ) {
-							if ( !( unmatched[ i ] || setMatched[ i ] ) ) {
-								setMatched[ i ] = pop.call( results );
-							}
-						}
-					}
-
-					// Discard index placeholder values to get only actual matches
-					setMatched = condense( setMatched );
-				}
-
-				// Add matches to results
-				push.apply( results, setMatched );
-
-				// Seedless set matches succeeding multiple successful matchers stipulate sorting
-				if ( outermost && !seed && setMatched.length > 0 &&
-					( matchedCount + setMatchers.length ) > 1 ) {
-
-					Sizzle.uniqueSort( results );
-				}
-			}
-
-			// Override manipulation of globals by nested matchers
-			if ( outermost ) {
-				dirruns = dirrunsUnique;
-				outermostContext = contextBackup;
-			}
-
-			return unmatched;
-		};
-
-	return bySet ?
-		markFunction( superMatcher ) :
-		superMatcher;
-}
-
-compile = Sizzle.compile = function( selector, match /* Internal Use Only */ ) {
-	var i,
-		setMatchers = [],
-		elementMatchers = [],
-		cached = compilerCache[ selector + " " ];
-
-	if ( !cached ) {
-
-		// Generate a function of recursive functions that can be used to check each element
-		if ( !match ) {
-			match = tokenize( selector );
-		}
-		i = match.length;
-		while ( i-- ) {
-			cached = matcherFromTokens( match[ i ] );
-			if ( cached[ expando ] ) {
-				setMatchers.push( cached );
-			} else {
-				elementMatchers.push( cached );
-			}
-		}
-
-		// Cache the compiled function
-		cached = compilerCache(
-			selector,
-			matcherFromGroupMatchers( elementMatchers, setMatchers )
-		);
-
-		// Save selector and tokenization
-		cached.selector = selector;
-	}
-	return cached;
-};
-
-/**
- * A low-level selection function that works with Sizzle's compiled
- *  selector functions
- * @param {String|Function} selector A selector or a pre-compiled
- *  selector function built with Sizzle.compile
- * @param {Element} context
- * @param {Array} [results]
- * @param {Array} [seed] A set of elements to match against
- */
-select = Sizzle.select = function( selector, context, results, seed ) {
-	var i, tokens, token, type, find,
-		compiled = typeof selector === "function" && selector,
-		match = !seed && tokenize( ( selector = compiled.selector || selector ) );
-
-	results = results || [];
-
-	// Try to minimize operations if there is only one selector in the list and no seed
-	// (the latter of which guarantees us context)
-	if ( match.length === 1 ) {
-
-		// Reduce context if the leading compound selector is an ID
-		tokens = match[ 0 ] = match[ 0 ].slice( 0 );
-		if ( tokens.length > 2 && ( token = tokens[ 0 ] ).type === "ID" &&
-			context.nodeType === 9 && documentIsHTML && Expr.relative[ tokens[ 1 ].type ] ) {
-
-			context = ( Expr.find[ "ID" ]( token.matches[ 0 ]
-				.replace( runescape, funescape ), context ) || [] )[ 0 ];
-			if ( !context ) {
-				return results;
-
-			// Precompiled matchers will still verify ancestry, so step up a level
-			} else if ( compiled ) {
-				context = context.parentNode;
-			}
-
-			selector = selector.slice( tokens.shift().value.length );
-		}
-
-		// Fetch a seed set for right-to-left matching
-		i = matchExpr[ "needsContext" ].test( selector ) ? 0 : tokens.length;
-		while ( i-- ) {
-			token = tokens[ i ];
-
-			// Abort if we hit a combinator
-			if ( Expr.relative[ ( type = token.type ) ] ) {
-				break;
-			}
-			if ( ( find = Expr.find[ type ] ) ) {
-
-				// Search, expanding context for leading sibling combinators
-				if ( ( seed = find(
-					token.matches[ 0 ].replace( runescape, funescape ),
-					rsibling.test( tokens[ 0 ].type ) && testContext( context.parentNode ) ||
-						context
-				) ) ) {
-
-					// If seed is empty or no tokens remain, we can return early
-					tokens.splice( i, 1 );
-					selector = seed.length && toSelector( tokens );
-					if ( !selector ) {
-						push.apply( results, seed );
-						return results;
-					}
-
-					break;
-				}
-			}
-		}
-	}
-
-	// Compile and execute a filtering function if one is not provided
-	// Provide `match` to avoid retokenization if we modified the selector above
-	( compiled || compile( selector, match ) )(
-		seed,
-		context,
-		!documentIsHTML,
-		results,
-		!context || rsibling.test( selector ) && testContext( context.parentNode ) || context
-	);
-	return results;
-};
-
-// One-time assignments
-
-// Sort stability
-support.sortStable = expando.split( "" ).sort( sortOrder ).join( "" ) === expando;
-
-// Support: Chrome 14-35+
-// Always assume duplicates if they aren't passed to the comparison function
-support.detectDuplicates = !!hasDuplicate;
-
-// Initialize against the default document
-setDocument();
-
-// Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27)
-// Detached nodes confoundingly follow *each other*
-support.sortDetached = assert( function( el ) {
-
-	// Should return 1, but returns 4 (following)
-	return el.compareDocumentPosition( document.createElement( "fieldset" ) ) & 1;
-} );
-
-// Support: IE<8
-// Prevent attribute/property "interpolation"
-// https://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx
-if ( !assert( function( el ) {
-	el.innerHTML = "<a href='#'></a>";
-	return el.firstChild.getAttribute( "href" ) === "#";
-} ) ) {
-	addHandle( "type|href|height|width", function( elem, name, isXML ) {
-		if ( !isXML ) {
-			return elem.getAttribute( name, name.toLowerCase() === "type" ? 1 : 2 );
-		}
-	} );
-}
-
-// Support: IE<9
-// Use defaultValue in place of getAttribute("value")
-if ( !support.attributes || !assert( function( el ) {
-	el.innerHTML = "<input/>";
-	el.firstChild.setAttribute( "value", "" );
-	return el.firstChild.getAttribute( "value" ) === "";
-} ) ) {
-	addHandle( "value", function( elem, _name, isXML ) {
-		if ( !isXML && elem.nodeName.toLowerCase() === "input" ) {
-			return elem.defaultValue;
-		}
-	} );
-}
-
-// Support: IE<9
-// Use getAttributeNode to fetch booleans when getAttribute lies
-if ( !assert( function( el ) {
-	return el.getAttribute( "disabled" ) == null;
-} ) ) {
-	addHandle( booleans, function( elem, name, isXML ) {
-		var val;
-		if ( !isXML ) {
-			return elem[ name ] === true ? name.toLowerCase() :
-				( val = elem.getAttributeNode( name ) ) && val.specified ?
-					val.value :
-					null;
-		}
-	} );
-}
-
-return Sizzle;
-
-} )( window );
-
-
-
-jQuery.find = Sizzle;
-jQuery.expr = Sizzle.selectors;
-
-// Deprecated
-jQuery.expr[ ":" ] = jQuery.expr.pseudos;
-jQuery.uniqueSort = jQuery.unique = Sizzle.uniqueSort;
-jQuery.text = Sizzle.getText;
-jQuery.isXMLDoc = Sizzle.isXML;
-jQuery.contains = Sizzle.contains;
-jQuery.escapeSelector = Sizzle.escape;
-
-
-
-
-var dir = function( elem, dir, until ) {
-	var matched = [],
-		truncate = until !== undefined;
-
-	while ( ( elem = elem[ dir ] ) && elem.nodeType !== 9 ) {
-		if ( elem.nodeType === 1 ) {
-			if ( truncate && jQuery( elem ).is( until ) ) {
-				break;
-			}
-			matched.push( elem );
-		}
-	}
-	return matched;
-};
-
-
-var siblings = function( n, elem ) {
-	var matched = [];
-
-	for ( ; n; n = n.nextSibling ) {
-		if ( n.nodeType === 1 && n !== elem ) {
-			matched.push( n );
-		}
-	}
-
-	return matched;
-};
-
-
-var rneedsContext = jQuery.expr.match.needsContext;
-
-
-
-function nodeName( elem, name ) {
-
-  return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase();
-
-};
-var rsingleTag = ( /^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i );
-
-
-
-// Implement the identical functionality for filter and not
-function winnow( elements, qualifier, not ) {
-	if ( isFunction( qualifier ) ) {
-		return jQuery.grep( elements, function( elem, i ) {
-			return !!qualifier.call( elem, i, elem ) !== not;
-		} );
-	}
-
-	// Single element
-	if ( qualifier.nodeType ) {
-		return jQuery.grep( elements, function( elem ) {
-			return ( elem === qualifier ) !== not;
-		} );
-	}
-
-	// Arraylike of elements (jQuery, arguments, Array)
-	if ( typeof qualifier !== "string" ) {
-		return jQuery.grep( elements, function( elem ) {
-			return ( indexOf.call( qualifier, elem ) > -1 ) !== not;
-		} );
-	}
-
-	// Filtered directly for both simple and complex selectors
-	return jQuery.filter( qualifier, elements, not );
-}
-
-jQuery.filter = function( expr, elems, not ) {
-	var elem = elems[ 0 ];
-
-	if ( not ) {
-		expr = ":not(" + expr + ")";
-	}
-
-	if ( elems.length === 1 && elem.nodeType === 1 ) {
-		return jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : [];
-	}
-
-	return jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) {
-		return elem.nodeType === 1;
-	} ) );
-};
-
-jQuery.fn.extend( {
-	find: function( selector ) {
-		var i, ret,
-			len = this.length,
-			self = this;
-
-		if ( typeof selector !== "string" ) {
-			return this.pushStack( jQuery( selector ).filter( function() {
-				for ( i = 0; i < len; i++ ) {
-					if ( jQuery.contains( self[ i ], this ) ) {
-						return true;
-					}
-				}
-			} ) );
-		}
-
-		ret = this.pushStack( [] );
-
-		for ( i = 0; i < len; i++ ) {
-			jQuery.find( selector, self[ i ], ret );
-		}
-
-		return len > 1 ? jQuery.uniqueSort( ret ) : ret;
-	},
-	filter: function( selector ) {
-		return this.pushStack( winnow( this, selector || [], false ) );
-	},
-	not: function( selector ) {
-		return this.pushStack( winnow( this, selector || [], true ) );
-	},
-	is: function( selector ) {
-		return !!winnow(
-			this,
-
-			// If this is a positional/relative selector, check membership in the returned set
-			// so $("p:first").is("p:last") won't return true for a doc with two "p".
-			typeof selector === "string" && rneedsContext.test( selector ) ?
-				jQuery( selector ) :
-				selector || [],
-			false
-		).length;
-	}
-} );
-
-
-// Initialize a jQuery object
-
-
-// A central reference to the root jQuery(document)
-var rootjQuery,
-
-	// A simple way to check for HTML strings
-	// Prioritize #id over <tag> to avoid XSS via location.hash (#9521)
-	// Strict HTML recognition (#11290: must start with <)
-	// Shortcut simple #id case for speed
-	rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/,
-
-	init = jQuery.fn.init = function( selector, context, root ) {
-		var match, elem;
-
-		// HANDLE: $(""), $(null), $(undefined), $(false)
-		if ( !selector ) {
-			return this;
-		}
-
-		// Method init() accepts an alternate rootjQuery
-		// so migrate can support jQuery.sub (gh-2101)
-		root = root || rootjQuery;
-
-		// Handle HTML strings
-		if ( typeof selector === "string" ) {
-			if ( selector[ 0 ] === "<" &&
-				selector[ selector.length - 1 ] === ">" &&
-				selector.length >= 3 ) {
-
-				// Assume that strings that start and end with <> are HTML and skip the regex check
-				match = [ null, selector, null ];
-
-			} else {
-				match = rquickExpr.exec( selector );
-			}
-
-			// Match html or make sure no context is specified for #id
-			if ( match && ( match[ 1 ] || !context ) ) {
-
-				// HANDLE: $(html) -> $(array)
-				if ( match[ 1 ] ) {
-					context = context instanceof jQuery ? context[ 0 ] : context;
-
-					// Option to run scripts is true for back-compat
-					// Intentionally let the error be thrown if parseHTML is not present
-					jQuery.merge( this, jQuery.parseHTML(
-						match[ 1 ],
-						context && context.nodeType ? context.ownerDocument || context : document,
-						true
-					) );
-
-					// HANDLE: $(html, props)
-					if ( rsingleTag.test( match[ 1 ] ) && jQuery.isPlainObject( context ) ) {
-						for ( match in context ) {
-
-							// Properties of context are called as methods if possible
-							if ( isFunction( this[ match ] ) ) {
-								this[ match ]( context[ match ] );
-
-							// ...and otherwise set as attributes
-							} else {
-								this.attr( match, context[ match ] );
-							}
-						}
-					}
-
-					return this;
-
-				// HANDLE: $(#id)
-				} else {
-					elem = document.getElementById( match[ 2 ] );
-
-					if ( elem ) {
-
-						// Inject the element directly into the jQuery object
-						this[ 0 ] = elem;
-						this.length = 1;
-					}
-					return this;
-				}
-
-			// HANDLE: $(expr, $(...))
-			} else if ( !context || context.jquery ) {
-				return ( context || root ).find( selector );
-
-			// HANDLE: $(expr, context)
-			// (which is just equivalent to: $(context).find(expr)
-			} else {
-				return this.constructor( context ).find( selector );
-			}
-
-		// HANDLE: $(DOMElement)
-		} else if ( selector.nodeType ) {
-			this[ 0 ] = selector;
-			this.length = 1;
-			return this;
-
-		// HANDLE: $(function)
-		// Shortcut for document ready
-		} else if ( isFunction( selector ) ) {
-			return root.ready !== undefined ?
-				root.ready( selector ) :
-
-				// Execute immediately if ready is not present
-				selector( jQuery );
-		}
-
-		return jQuery.makeArray( selector, this );
-	};
-
-// Give the init function the jQuery prototype for later instantiation
-init.prototype = jQuery.fn;
-
-// Initialize central reference
-rootjQuery = jQuery( document );
-
-
-var rparentsprev = /^(?:parents|prev(?:Until|All))/,
-
-	// Methods guaranteed to produce a unique set when starting from a unique set
-	guaranteedUnique = {
-		children: true,
-		contents: true,
-		next: true,
-		prev: true
-	};
-
-jQuery.fn.extend( {
-	has: function( target ) {
-		var targets = jQuery( target, this ),
-			l = targets.length;
-
-		return this.filter( function() {
-			var i = 0;
-			for ( ; i < l; i++ ) {
-				if ( jQuery.contains( this, targets[ i ] ) ) {
-					return true;
-				}
-			}
-		} );
-	},
-
-	closest: function( selectors, context ) {
-		var cur,
-			i = 0,
-			l = this.length,
-			matched = [],
-			targets = typeof selectors !== "string" && jQuery( selectors );
-
-		// Positional selectors never match, since there's no _selection_ context
-		if ( !rneedsContext.test( selectors ) ) {
-			for ( ; i < l; i++ ) {
-				for ( cur = this[ i ]; cur && cur !== context; cur = cur.parentNode ) {
-
-					// Always skip document fragments
-					if ( cur.nodeType < 11 && ( targets ?
-						targets.index( cur ) > -1 :
-
-						// Don't pass non-elements to Sizzle
-						cur.nodeType === 1 &&
-							jQuery.find.matchesSelector( cur, selectors ) ) ) {
-
-						matched.push( cur );
-						break;
-					}
-				}
-			}
-		}
-
-		return this.pushStack( matched.length > 1 ? jQuery.uniqueSort( matched ) : matched );
-	},
-
-	// Determine the position of an element within the set
-	index: function( elem ) {
-
-		// No argument, return index in parent
-		if ( !elem ) {
-			return ( this[ 0 ] && this[ 0 ].parentNode ) ? this.first().prevAll().length : -1;
-		}
-
-		// Index in selector
-		if ( typeof elem === "string" ) {
-			return indexOf.call( jQuery( elem ), this[ 0 ] );
-		}
-
-		// Locate the position of the desired element
-		return indexOf.call( this,
-
-			// If it receives a jQuery object, the first element is used
-			elem.jquery ? elem[ 0 ] : elem
-		);
-	},
-
-	add: function( selector, context ) {
-		return this.pushStack(
-			jQuery.uniqueSort(
-				jQuery.merge( this.get(), jQuery( selector, context ) )
-			)
-		);
-	},
-
-	addBack: function( selector ) {
-		return this.add( selector == null ?
-			this.prevObject : this.prevObject.filter( selector )
-		);
-	}
-} );
-
-function sibling( cur, dir ) {
-	while ( ( cur = cur[ dir ] ) && cur.nodeType !== 1 ) {}
-	return cur;
-}
-
-jQuery.each( {
-	parent: function( elem ) {
-		var parent = elem.parentNode;
-		return parent && parent.nodeType !== 11 ? parent : null;
-	},
-	parents: function( elem ) {
-		return dir( elem, "parentNode" );
-	},
-	parentsUntil: function( elem, _i, until ) {
-		return dir( elem, "parentNode", until );
-	},
-	next: function( elem ) {
-		return sibling( elem, "nextSibling" );
-	},
-	prev: function( elem ) {
-		return sibling( elem, "previousSibling" );
-	},
-	nextAll: function( elem ) {
-		return dir( elem, "nextSibling" );
-	},
-	prevAll: function( elem ) {
-		return dir( elem, "previousSibling" );
-	},
-	nextUntil: function( elem, _i, until ) {
-		return dir( elem, "nextSibling", until );
-	},
-	prevUntil: function( elem, _i, until ) {
-		return dir( elem, "previousSibling", until );
-	},
-	siblings: function( elem ) {
-		return siblings( ( elem.parentNode || {} ).firstChild, elem );
-	},
-	children: function( elem ) {
-		return siblings( elem.firstChild );
-	},
-	contents: function( elem ) {
-		if ( elem.contentDocument != null &&
-
-			// Support: IE 11+
-			// <object> elements with no `data` attribute has an object
-			// `contentDocument` with a `null` prototype.
-			getProto( elem.contentDocument ) ) {
-
-			return elem.contentDocument;
-		}
-
-		// Support: IE 9 - 11 only, iOS 7 only, Android Browser <=4.3 only
-		// Treat the template element as a regular one in browsers that
-		// don't support it.
-		if ( nodeName( elem, "template" ) ) {
-			elem = elem.content || elem;
-		}
-
-		return jQuery.merge( [], elem.childNodes );
-	}
-}, function( name, fn ) {
-	jQuery.fn[ name ] = function( until, selector ) {
-		var matched = jQuery.map( this, fn, until );
-
-		if ( name.slice( -5 ) !== "Until" ) {
-			selector = until;
-		}
-
-		if ( selector && typeof selector === "string" ) {
-			matched = jQuery.filter( selector, matched );
-		}
-
-		if ( this.length > 1 ) {
-
-			// Remove duplicates
-			if ( !guaranteedUnique[ name ] ) {
-				jQuery.uniqueSort( matched );
-			}
-
-			// Reverse order for parents* and prev-derivatives
-			if ( rparentsprev.test( name ) ) {
-				matched.reverse();
-			}
-		}
-
-		return this.pushStack( matched );
-	};
-} );
-var rnothtmlwhite = ( /[^\x20\t\r\n\f]+/g );
-
-
-
-// Convert String-formatted options into Object-formatted ones
-function createOptions( options ) {
-	var object = {};
-	jQuery.each( options.match( rnothtmlwhite ) || [], function( _, flag ) {
-		object[ flag ] = true;
-	} );
-	return object;
-}
-
-/*
- * Create a callback list using the following parameters:
- *
- *	options: an optional list of space-separated options that will change how
- *			the callback list behaves or a more traditional option object
- *
- * By default a callback list will act like an event callback list and can be
- * "fired" multiple times.
- *
- * Possible options:
- *
- *	once:			will ensure the callback list can only be fired once (like a Deferred)
- *
- *	memory:			will keep track of previous values and will call any callback added
- *					after the list has been fired right away with the latest "memorized"
- *					values (like a Deferred)
- *
- *	unique:			will ensure a callback can only be added once (no duplicate in the list)
- *
- *	stopOnFalse:	interrupt callings when a callback returns false
- *
- */
-jQuery.Callbacks = function( options ) {
-
-	// Convert options from String-formatted to Object-formatted if needed
-	// (we check in cache first)
-	options = typeof options === "string" ?
-		createOptions( options ) :
-		jQuery.extend( {}, options );
-
-	var // Flag to know if list is currently firing
-		firing,
-
-		// Last fire value for non-forgettable lists
-		memory,
-
-		// Flag to know if list was already fired
-		fired,
-
-		// Flag to prevent firing
-		locked,
-
-		// Actual callback list
-		list = [],
-
-		// Queue of execution data for repeatable lists
-		queue = [],
-
-		// Index of currently firing callback (modified by add/remove as needed)
-		firingIndex = -1,
-
-		// Fire callbacks
-		fire = function() {
-
-			// Enforce single-firing
-			locked = locked || options.once;
-
-			// Execute callbacks for all pending executions,
-			// respecting firingIndex overrides and runtime changes
-			fired = firing = true;
-			for ( ; queue.length; firingIndex = -1 ) {
-				memory = queue.shift();
-				while ( ++firingIndex < list.length ) {
-
-					// Run callback and check for early termination
-					if ( list[ firingIndex ].apply( memory[ 0 ], memory[ 1 ] ) === false &&
-						options.stopOnFalse ) {
-
-						// Jump to end and forget the data so .add doesn't re-fire
-						firingIndex = list.length;
-						memory = false;
-					}
-				}
-			}
-
-			// Forget the data if we're done with it
-			if ( !options.memory ) {
-				memory = false;
-			}
-
-			firing = false;
-
-			// Clean up if we're done firing for good
-			if ( locked ) {
-
-				// Keep an empty list if we have data for future add calls
-				if ( memory ) {
-					list = [];
-
-				// Otherwise, this object is spent
-				} else {
-					list = "";
-				}
-			}
-		},
-
-		// Actual Callbacks object
-		self = {
-
-			// Add a callback or a collection of callbacks to the list
-			add: function() {
-				if ( list ) {
-
-					// If we have memory from a past run, we should fire after adding
-					if ( memory && !firing ) {
-						firingIndex = list.length - 1;
-						queue.push( memory );
-					}
-
-					( function add( args ) {
-						jQuery.each( args, function( _, arg ) {
-							if ( isFunction( arg ) ) {
-								if ( !options.unique || !self.has( arg ) ) {
-									list.push( arg );
-								}
-							} else if ( arg && arg.length && toType( arg ) !== "string" ) {
-
-								// Inspect recursively
-								add( arg );
-							}
-						} );
-					} )( arguments );
-
-					if ( memory && !firing ) {
-						fire();
-					}
-				}
-				return this;
-			},
-
-			// Remove a callback from the list
-			remove: function() {
-				jQuery.each( arguments, function( _, arg ) {
-					var index;
-					while ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) {
-						list.splice( index, 1 );
-
-						// Handle firing indexes
-						if ( index <= firingIndex ) {
-							firingIndex--;
-						}
-					}
-				} );
-				return this;
-			},
-
-			// Check if a given callback is in the list.
-			// If no argument is given, return whether or not list has callbacks attached.
-			has: function( fn ) {
-				return fn ?
-					jQuery.inArray( fn, list ) > -1 :
-					list.length > 0;
-			},
-
-			// Remove all callbacks from the list
-			empty: function() {
-				if ( list ) {
-					list = [];
-				}
-				return this;
-			},
-
-			// Disable .fire and .add
-			// Abort any current/pending executions
-			// Clear all callbacks and values
-			disable: function() {
-				locked = queue = [];
-				list = memory = "";
-				return this;
-			},
-			disabled: function() {
-				return !list;
-			},
-
-			// Disable .fire
-			// Also disable .add unless we have memory (since it would have no effect)
-			// Abort any pending executions
-			lock: function() {
-				locked = queue = [];
-				if ( !memory && !firing ) {
-					list = memory = "";
-				}
-				return this;
-			},
-			locked: function() {
-				return !!locked;
-			},
-
-			// Call all callbacks with the given context and arguments
-			fireWith: function( context, args ) {
-				if ( !locked ) {
-					args = args || [];
-					args = [ context, args.slice ? args.slice() : args ];
-					queue.push( args );
-					if ( !firing ) {
-						fire();
-					}
-				}
-				return this;
-			},
-
-			// Call all the callbacks with the given arguments
-			fire: function() {
-				self.fireWith( this, arguments );
-				return this;
-			},
-
-			// To know if the callbacks have already been called at least once
-			fired: function() {
-				return !!fired;
-			}
-		};
-
-	return self;
-};
-
-
-function Identity( v ) {
-	return v;
-}
-function Thrower( ex ) {
-	throw ex;
-}
-
-function adoptValue( value, resolve, reject, noValue ) {
-	var method;
-
-	try {
-
-		// Check for promise aspect first to privilege synchronous behavior
-		if ( value && isFunction( ( method = value.promise ) ) ) {
-			method.call( value ).done( resolve ).fail( reject );
-
-		// Other thenables
-		} else if ( value && isFunction( ( method = value.then ) ) ) {
-			method.call( value, resolve, reject );
-
-		// Other non-thenables
-		} else {
-
-			// Control `resolve` arguments by letting Array#slice cast boolean `noValue` to integer:
-			// * false: [ value ].slice( 0 ) => resolve( value )
-			// * true: [ value ].slice( 1 ) => resolve()
-			resolve.apply( undefined, [ value ].slice( noValue ) );
-		}
-
-	// For Promises/A+, convert exceptions into rejections
-	// Since jQuery.when doesn't unwrap thenables, we can skip the extra checks appearing in
-	// Deferred#then to conditionally suppress rejection.
-	} catch ( value ) {
-
-		// Support: Android 4.0 only
-		// Strict mode functions invoked without .call/.apply get global-object context
-		reject.apply( undefined, [ value ] );
-	}
-}
-
-jQuery.extend( {
-
-	Deferred: function( func ) {
-		var tuples = [
-
-				// action, add listener, callbacks,
-				// ... .then handlers, argument index, [final state]
-				[ "notify", "progress", jQuery.Callbacks( "memory" ),
-					jQuery.Callbacks( "memory" ), 2 ],
-				[ "resolve", "done", jQuery.Callbacks( "once memory" ),
-					jQuery.Callbacks( "once memory" ), 0, "resolved" ],
-				[ "reject", "fail", jQuery.Callbacks( "once memory" ),
-					jQuery.Callbacks( "once memory" ), 1, "rejected" ]
-			],
-			state = "pending",
-			promise = {
-				state: function() {
-					return state;
-				},
-				always: function() {
-					deferred.done( arguments ).fail( arguments );
-					return this;
-				},
-				"catch": function( fn ) {
-					return promise.then( null, fn );
-				},
-
-				// Keep pipe for back-compat
-				pipe: function( /* fnDone, fnFail, fnProgress */ ) {
-					var fns = arguments;
-
-					return jQuery.Deferred( function( newDefer ) {
-						jQuery.each( tuples, function( _i, tuple ) {
-
-							// Map tuples (progress, done, fail) to arguments (done, fail, progress)
-							var fn = isFunction( fns[ tuple[ 4 ] ] ) && fns[ tuple[ 4 ] ];
-
-							// deferred.progress(function() { bind to newDefer or newDefer.notify })
-							// deferred.done(function() { bind to newDefer or newDefer.resolve })
-							// deferred.fail(function() { bind to newDefer or newDefer.reject })
-							deferred[ tuple[ 1 ] ]( function() {
-								var returned = fn && fn.apply( this, arguments );
-								if ( returned && isFunction( returned.promise ) ) {
-									returned.promise()
-										.progress( newDefer.notify )
-										.done( newDefer.resolve )
-										.fail( newDefer.reject );
-								} else {
-									newDefer[ tuple[ 0 ] + "With" ](
-										this,
-										fn ? [ returned ] : arguments
-									);
-								}
-							} );
-						} );
-						fns = null;
-					} ).promise();
-				},
-				then: function( onFulfilled, onRejected, onProgress ) {
-					var maxDepth = 0;
-					function resolve( depth, deferred, handler, special ) {
-						return function() {
-							var that = this,
-								args = arguments,
-								mightThrow = function() {
-									var returned, then;
-
-									// Support: Promises/A+ section 2.3.3.3.3
-									// https://promisesaplus.com/#point-59
-									// Ignore double-resolution attempts
-									if ( depth < maxDepth ) {
-										return;
-									}
-
-									returned = handler.apply( that, args );
-
-									// Support: Promises/A+ section 2.3.1
-									// https://promisesaplus.com/#point-48
-									if ( returned === deferred.promise() ) {
-										throw new TypeError( "Thenable self-resolution" );
-									}
-
-									// Support: Promises/A+ sections 2.3.3.1, 3.5
-									// https://promisesaplus.com/#point-54
-									// https://promisesaplus.com/#point-75
-									// Retrieve `then` only once
-									then = returned &&
-
-										// Support: Promises/A+ section 2.3.4
-										// https://promisesaplus.com/#point-64
-										// Only check objects and functions for thenability
-										( typeof returned === "object" ||
-											typeof returned === "function" ) &&
-										returned.then;
-
-									// Handle a returned thenable
-									if ( isFunction( then ) ) {
-
-										// Special processors (notify) just wait for resolution
-										if ( special ) {
-											then.call(
-												returned,
-												resolve( maxDepth, deferred, Identity, special ),
-												resolve( maxDepth, deferred, Thrower, special )
-											);
-
-										// Normal processors (resolve) also hook into progress
-										} else {
-
-											// ...and disregard older resolution values
-											maxDepth++;
-
-											then.call(
-												returned,
-												resolve( maxDepth, deferred, Identity, special ),
-												resolve( maxDepth, deferred, Thrower, special ),
-												resolve( maxDepth, deferred, Identity,
-													deferred.notifyWith )
-											);
-										}
-
-									// Handle all other returned values
-									} else {
-
-										// Only substitute handlers pass on context
-										// and multiple values (non-spec behavior)
-										if ( handler !== Identity ) {
-											that = undefined;
-											args = [ returned ];
-										}
-
-										// Process the value(s)
-										// Default process is resolve
-										( special || deferred.resolveWith )( that, args );
-									}
-								},
-
-								// Only normal processors (resolve) catch and reject exceptions
-								process = special ?
-									mightThrow :
-									function() {
-										try {
-											mightThrow();
-										} catch ( e ) {
-
-											if ( jQuery.Deferred.exceptionHook ) {
-												jQuery.Deferred.exceptionHook( e,
-													process.stackTrace );
-											}
-
-											// Support: Promises/A+ section 2.3.3.3.4.1
-											// https://promisesaplus.com/#point-61
-											// Ignore post-resolution exceptions
-											if ( depth + 1 >= maxDepth ) {
-
-												// Only substitute handlers pass on context
-												// and multiple values (non-spec behavior)
-												if ( handler !== Thrower ) {
-													that = undefined;
-													args = [ e ];
-												}
-
-												deferred.rejectWith( that, args );
-											}
-										}
-									};
-
-							// Support: Promises/A+ section 2.3.3.3.1
-							// https://promisesaplus.com/#point-57
-							// Re-resolve promises immediately to dodge false rejection from
-							// subsequent errors
-							if ( depth ) {
-								process();
-							} else {
-
-								// Call an optional hook to record the stack, in case of exception
-								// since it's otherwise lost when execution goes async
-								if ( jQuery.Deferred.getStackHook ) {
-									process.stackTrace = jQuery.Deferred.getStackHook();
-								}
-								window.setTimeout( process );
-							}
-						};
-					}
-
-					return jQuery.Deferred( function( newDefer ) {
-
-						// progress_handlers.add( ... )
-						tuples[ 0 ][ 3 ].add(
-							resolve(
-								0,
-								newDefer,
-								isFunction( onProgress ) ?
-									onProgress :
-									Identity,
-								newDefer.notifyWith
-							)
-						);
-
-						// fulfilled_handlers.add( ... )
-						tuples[ 1 ][ 3 ].add(
-							resolve(
-								0,
-								newDefer,
-								isFunction( onFulfilled ) ?
-									onFulfilled :
-									Identity
-							)
-						);
-
-						// rejected_handlers.add( ... )
-						tuples[ 2 ][ 3 ].add(
-							resolve(
-								0,
-								newDefer,
-								isFunction( onRejected ) ?
-									onRejected :
-									Thrower
-							)
-						);
-					} ).promise();
-				},
-
-				// Get a promise for this deferred
-				// If obj is provided, the promise aspect is added to the object
-				promise: function( obj ) {
-					return obj != null ? jQuery.extend( obj, promise ) : promise;
-				}
-			},
-			deferred = {};
-
-		// Add list-specific methods
-		jQuery.each( tuples, function( i, tuple ) {
-			var list = tuple[ 2 ],
-				stateString = tuple[ 5 ];
-
-			// promise.progress = list.add
-			// promise.done = list.add
-			// promise.fail = list.add
-			promise[ tuple[ 1 ] ] = list.add;
-
-			// Handle state
-			if ( stateString ) {
-				list.add(
-					function() {
-
-						// state = "resolved" (i.e., fulfilled)
-						// state = "rejected"
-						state = stateString;
-					},
-
-					// rejected_callbacks.disable
-					// fulfilled_callbacks.disable
-					tuples[ 3 - i ][ 2 ].disable,
-
-					// rejected_handlers.disable
-					// fulfilled_handlers.disable
-					tuples[ 3 - i ][ 3 ].disable,
-
-					// progress_callbacks.lock
-					tuples[ 0 ][ 2 ].lock,
-
-					// progress_handlers.lock
-					tuples[ 0 ][ 3 ].lock
-				);
-			}
-
-			// progress_handlers.fire
-			// fulfilled_handlers.fire
-			// rejected_handlers.fire
-			list.add( tuple[ 3 ].fire );
-
-			// deferred.notify = function() { deferred.notifyWith(...) }
-			// deferred.resolve = function() { deferred.resolveWith(...) }
-			// deferred.reject = function() { deferred.rejectWith(...) }
-			deferred[ tuple[ 0 ] ] = function() {
-				deferred[ tuple[ 0 ] + "With" ]( this === deferred ? undefined : this, arguments );
-				return this;
-			};
-
-			// deferred.notifyWith = list.fireWith
-			// deferred.resolveWith = list.fireWith
-			// deferred.rejectWith = list.fireWith
-			deferred[ tuple[ 0 ] + "With" ] = list.fireWith;
-		} );
-
-		// Make the deferred a promise
-		promise.promise( deferred );
-
-		// Call given func if any
-		if ( func ) {
-			func.call( deferred, deferred );
-		}
-
-		// All done!
-		return deferred;
-	},
-
-	// Deferred helper
-	when: function( singleValue ) {
-		var
-
-			// count of uncompleted subordinates
-			remaining = arguments.length,
-
-			// count of unprocessed arguments
-			i = remaining,
-
-			// subordinate fulfillment data
-			resolveContexts = Array( i ),
-			resolveValues = slice.call( arguments ),
-
-			// the master Deferred
-			master = jQuery.Deferred(),
-
-			// subordinate callback factory
-			updateFunc = function( i ) {
-				return function( value ) {
-					resolveContexts[ i ] = this;
-					resolveValues[ i ] = arguments.length > 1 ? slice.call( arguments ) : value;
-					if ( !( --remaining ) ) {
-						master.resolveWith( resolveContexts, resolveValues );
-					}
-				};
-			};
-
-		// Single- and empty arguments are adopted like Promise.resolve
-		if ( remaining <= 1 ) {
-			adoptValue( singleValue, master.done( updateFunc( i ) ).resolve, master.reject,
-				!remaining );
-
-			// Use .then() to unwrap secondary thenables (cf. gh-3000)
-			if ( master.state() === "pending" ||
-				isFunction( resolveValues[ i ] && resolveValues[ i ].then ) ) {
-
-				return master.then();
-			}
-		}
-
-		// Multiple arguments are aggregated like Promise.all array elements
-		while ( i-- ) {
-			adoptValue( resolveValues[ i ], updateFunc( i ), master.reject );
-		}
-
-		return master.promise();
-	}
-} );
-
-
-// These usually indicate a programmer mistake during development,
-// warn about them ASAP rather than swallowing them by default.
-var rerrorNames = /^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/;
-
-jQuery.Deferred.exceptionHook = function( error, stack ) {
-
-	// Support: IE 8 - 9 only
-	// Console exists when dev tools are open, which can happen at any time
-	if ( window.console && window.console.warn && error && rerrorNames.test( error.name ) ) {
-		window.console.warn( "jQuery.Deferred exception: " + error.message, error.stack, stack );
-	}
-};
-
-
-
-
-jQuery.readyException = function( error ) {
-	window.setTimeout( function() {
-		throw error;
-	} );
-};
-
-
-
-
-// The deferred used on DOM ready
-var readyList = jQuery.Deferred();
-
-jQuery.fn.ready = function( fn ) {
-
-	readyList
-		.then( fn )
-
-		// Wrap jQuery.readyException in a function so that the lookup
-		// happens at the time of error handling instead of callback
-		// registration.
-		.catch( function( error ) {
-			jQuery.readyException( error );
-		} );
-
-	return this;
-};
-
-jQuery.extend( {
-
-	// Is the DOM ready to be used? Set to true once it occurs.
-	isReady: false,
-
-	// A counter to track how many items to wait for before
-	// the ready event fires. See #6781
-	readyWait: 1,
-
-	// Handle when the DOM is ready
-	ready: function( wait ) {
-
-		// Abort if there are pending holds or we're already ready
-		if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) {
-			return;
-		}
-
-		// Remember that the DOM is ready
-		jQuery.isReady = true;
-
-		// If a normal DOM Ready event fired, decrement, and wait if need be
-		if ( wait !== true && --jQuery.readyWait > 0 ) {
-			return;
-		}
-
-		// If there are functions bound, to execute
-		readyList.resolveWith( document, [ jQuery ] );
-	}
-} );
-
-jQuery.ready.then = readyList.then;
-
-// The ready event handler and self cleanup method
-function completed() {
-	document.removeEventListener( "DOMContentLoaded", completed );
-	window.removeEventListener( "load", completed );
-	jQuery.ready();
-}
-
-// Catch cases where $(document).ready() is called
-// after the browser event has already occurred.
-// Support: IE <=9 - 10 only
-// Older IE sometimes signals "interactive" too soon
-if ( document.readyState === "complete" ||
-	( document.readyState !== "loading" && !document.documentElement.doScroll ) ) {
-
-	// Handle it asynchronously to allow scripts the opportunity to delay ready
-	window.setTimeout( jQuery.ready );
-
-} else {
-
-	// Use the handy event callback
-	document.addEventListener( "DOMContentLoaded", completed );
-
-	// A fallback to window.onload, that will always work
-	window.addEventListener( "load", completed );
-}
-
-
-
-
-// Multifunctional method to get and set values of a collection
-// The value/s can optionally be executed if it's a function
-var access = function( elems, fn, key, value, chainable, emptyGet, raw ) {
-	var i = 0,
-		len = elems.length,
-		bulk = key == null;
-
-	// Sets many values
-	if ( toType( key ) === "object" ) {
-		chainable = true;
-		for ( i in key ) {
-			access( elems, fn, i, key[ i ], true, emptyGet, raw );
-		}
-
-	// Sets one value
-	} else if ( value !== undefined ) {
-		chainable = true;
-
-		if ( !isFunction( value ) ) {
-			raw = true;
-		}
-
-		if ( bulk ) {
-
-			// Bulk operations run against the entire set
-			if ( raw ) {
-				fn.call( elems, value );
-				fn = null;
-
-			// ...except when executing function values
-			} else {
-				bulk = fn;
-				fn = function( elem, _key, value ) {
-					return bulk.call( jQuery( elem ), value );
-				};
-			}
-		}
-
-		if ( fn ) {
-			for ( ; i < len; i++ ) {
-				fn(
-					elems[ i ], key, raw ?
-					value :
-					value.call( elems[ i ], i, fn( elems[ i ], key ) )
-				);
-			}
-		}
-	}
-
-	if ( chainable ) {
-		return elems;
-	}
-
-	// Gets
-	if ( bulk ) {
-		return fn.call( elems );
-	}
-
-	return len ? fn( elems[ 0 ], key ) : emptyGet;
-};
-
-
-// Matches dashed string for camelizing
-var rmsPrefix = /^-ms-/,
-	rdashAlpha = /-([a-z])/g;
-
-// Used by camelCase as callback to replace()
-function fcamelCase( _all, letter ) {
-	return letter.toUpperCase();
-}
-
-// Convert dashed to camelCase; used by the css and data modules
-// Support: IE <=9 - 11, Edge 12 - 15
-// Microsoft forgot to hump their vendor prefix (#9572)
-function camelCase( string ) {
-	return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase );
-}
-var acceptData = function( owner ) {
-
-	// Accepts only:
-	//  - Node
-	//    - Node.ELEMENT_NODE
-	//    - Node.DOCUMENT_NODE
-	//  - Object
-	//    - Any
-	return owner.nodeType === 1 || owner.nodeType === 9 || !( +owner.nodeType );
-};
-
-
-
-
-function Data() {
-	this.expando = jQuery.expando + Data.uid++;
-}
-
-Data.uid = 1;
-
-Data.prototype = {
-
-	cache: function( owner ) {
-
-		// Check if the owner object already has a cache
-		var value = owner[ this.expando ];
-
-		// If not, create one
-		if ( !value ) {
-			value = {};
-
-			// We can accept data for non-element nodes in modern browsers,
-			// but we should not, see #8335.
-			// Always return an empty object.
-			if ( acceptData( owner ) ) {
-
-				// If it is a node unlikely to be stringify-ed or looped over
-				// use plain assignment
-				if ( owner.nodeType ) {
-					owner[ this.expando ] = value;
-
-				// Otherwise secure it in a non-enumerable property
-				// configurable must be true to allow the property to be
-				// deleted when data is removed
-				} else {
-					Object.defineProperty( owner, this.expando, {
-						value: value,
-						configurable: true
-					} );
-				}
-			}
-		}
-
-		return value;
-	},
-	set: function( owner, data, value ) {
-		var prop,
-			cache = this.cache( owner );
-
-		// Handle: [ owner, key, value ] args
-		// Always use camelCase key (gh-2257)
-		if ( typeof data === "string" ) {
-			cache[ camelCase( data ) ] = value;
-
-		// Handle: [ owner, { properties } ] args
-		} else {
-
-			// Copy the properties one-by-one to the cache object
-			for ( prop in data ) {
-				cache[ camelCase( prop ) ] = data[ prop ];
-			}
-		}
-		return cache;
-	},
-	get: function( owner, key ) {
-		return key === undefined ?
-			this.cache( owner ) :
-
-			// Always use camelCase key (gh-2257)
-			owner[ this.expando ] && owner[ this.expando ][ camelCase( key ) ];
-	},
-	access: function( owner, key, value ) {
-
-		// In cases where either:
-		//
-		//   1. No key was specified
-		//   2. A string key was specified, but no value provided
-		//
-		// Take the "read" path and allow the get method to determine
-		// which value to return, respectively either:
-		//
-		//   1. The entire cache object
-		//   2. The data stored at the key
-		//
-		if ( key === undefined ||
-				( ( key && typeof key === "string" ) && value === undefined ) ) {
-
-			return this.get( owner, key );
-		}
-
-		// When the key is not a string, or both a key and value
-		// are specified, set or extend (existing objects) with either:
-		//
-		//   1. An object of properties
-		//   2. A key and value
-		//
-		this.set( owner, key, value );
-
-		// Since the "set" path can have two possible entry points
-		// return the expected data based on which path was taken[*]
-		return value !== undefined ? value : key;
-	},
-	remove: function( owner, key ) {
-		var i,
-			cache = owner[ this.expando ];
-
-		if ( cache === undefined ) {
-			return;
-		}
-
-		if ( key !== undefined ) {
-
-			// Support array or space separated string of keys
-			if ( Array.isArray( key ) ) {
-
-				// If key is an array of keys...
-				// We always set camelCase keys, so remove that.
-				key = key.map( camelCase );
-			} else {
-				key = camelCase( key );
-
-				// If a key with the spaces exists, use it.
-				// Otherwise, create an array by matching non-whitespace
-				key = key in cache ?
-					[ key ] :
-					( key.match( rnothtmlwhite ) || [] );
-			}
-
-			i = key.length;
-
-			while ( i-- ) {
-				delete cache[ key[ i ] ];
-			}
-		}
-
-		// Remove the expando if there's no more data
-		if ( key === undefined || jQuery.isEmptyObject( cache ) ) {
-
-			// Support: Chrome <=35 - 45
-			// Webkit & Blink performance suffers when deleting properties
-			// from DOM nodes, so set to undefined instead
-			// https://bugs.chromium.org/p/chromium/issues/detail?id=378607 (bug restricted)
-			if ( owner.nodeType ) {
-				owner[ this.expando ] = undefined;
-			} else {
-				delete owner[ this.expando ];
-			}
-		}
-	},
-	hasData: function( owner ) {
-		var cache = owner[ this.expando ];
-		return cache !== undefined && !jQuery.isEmptyObject( cache );
-	}
-};
-var dataPriv = new Data();
-
-var dataUser = new Data();
-
-
-
-//	Implementation Summary
-//
-//	1. Enforce API surface and semantic compatibility with 1.9.x branch
-//	2. Improve the module's maintainability by reducing the storage
-//		paths to a single mechanism.
-//	3. Use the same single mechanism to support "private" and "user" data.
-//	4. _Never_ expose "private" data to user code (TODO: Drop _data, _removeData)
-//	5. Avoid exposing implementation details on user objects (eg. expando properties)
-//	6. Provide a clear path for implementation upgrade to WeakMap in 2014
-
-var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,
-	rmultiDash = /[A-Z]/g;
-
-function getData( data ) {
-	if ( data === "true" ) {
-		return true;
-	}
-
-	if ( data === "false" ) {
-		return false;
-	}
-
-	if ( data === "null" ) {
-		return null;
-	}
-
-	// Only convert to a number if it doesn't change the string
-	if ( data === +data + "" ) {
-		return +data;
-	}
-
-	if ( rbrace.test( data ) ) {
-		return JSON.parse( data );
-	}
-
-	return data;
-}
-
-function dataAttr( elem, key, data ) {
-	var name;
-
-	// If nothing was found internally, try to fetch any
-	// data from the HTML5 data-* attribute
-	if ( data === undefined && elem.nodeType === 1 ) {
-		name = "data-" + key.replace( rmultiDash, "-$&" ).toLowerCase();
-		data = elem.getAttribute( name );
-
-		if ( typeof data === "string" ) {
-			try {
-				data = getData( data );
-			} catch ( e ) {}
-
-			// Make sure we set the data so it isn't changed later
-			dataUser.set( elem, key, data );
-		} else {
-			data = undefined;
-		}
-	}
-	return data;
-}
-
-jQuery.extend( {
-	hasData: function( elem ) {
-		return dataUser.hasData( elem ) || dataPriv.hasData( elem );
-	},
-
-	data: function( elem, name, data ) {
-		return dataUser.access( elem, name, data );
-	},
-
-	removeData: function( elem, name ) {
-		dataUser.remove( elem, name );
-	},
-
-	// TODO: Now that all calls to _data and _removeData have been replaced
-	// with direct calls to dataPriv methods, these can be deprecated.
-	_data: function( elem, name, data ) {
-		return dataPriv.access( elem, name, data );
-	},
-
-	_removeData: function( elem, name ) {
-		dataPriv.remove( elem, name );
-	}
-} );
-
-jQuery.fn.extend( {
-	data: function( key, value ) {
-		var i, name, data,
-			elem = this[ 0 ],
-			attrs = elem && elem.attributes;
-
-		// Gets all values
-		if ( key === undefined ) {
-			if ( this.length ) {
-				data = dataUser.get( elem );
-
-				if ( elem.nodeType === 1 && !dataPriv.get( elem, "hasDataAttrs" ) ) {
-					i = attrs.length;
-					while ( i-- ) {
-
-						// Support: IE 11 only
-						// The attrs elements can be null (#14894)
-						if ( attrs[ i ] ) {
-							name = attrs[ i ].name;
-							if ( name.indexOf( "data-" ) === 0 ) {
-								name = camelCase( name.slice( 5 ) );
-								dataAttr( elem, name, data[ name ] );
-							}
-						}
-					}
-					dataPriv.set( elem, "hasDataAttrs", true );
-				}
-			}
-
-			return data;
-		}
-
-		// Sets multiple values
-		if ( typeof key === "object" ) {
-			return this.each( function() {
-				dataUser.set( this, key );
-			} );
-		}
-
-		return access( this, function( value ) {
-			var data;
-
-			// The calling jQuery object (element matches) is not empty
-			// (and therefore has an element appears at this[ 0 ]) and the
-			// `value` parameter was not undefined. An empty jQuery object
-			// will result in `undefined` for elem = this[ 0 ] which will
-			// throw an exception if an attempt to read a data cache is made.
-			if ( elem && value === undefined ) {
-
-				// Attempt to get data from the cache
-				// The key will always be camelCased in Data
-				data = dataUser.get( elem, key );
-				if ( data !== undefined ) {
-					return data;
-				}
-
-				// Attempt to "discover" the data in
-				// HTML5 custom data-* attrs
-				data = dataAttr( elem, key );
-				if ( data !== undefined ) {
-					return data;
-				}
-
-				// We tried really hard, but the data doesn't exist.
-				return;
-			}
-
-			// Set the data...
-			this.each( function() {
-
-				// We always store the camelCased key
-				dataUser.set( this, key, value );
-			} );
-		}, null, value, arguments.length > 1, null, true );
-	},
-
-	removeData: function( key ) {
-		return this.each( function() {
-			dataUser.remove( this, key );
-		} );
-	}
-} );
-
-
-jQuery.extend( {
-	queue: function( elem, type, data ) {
-		var queue;
-
-		if ( elem ) {
-			type = ( type || "fx" ) + "queue";
-			queue = dataPriv.get( elem, type );
-
-			// Speed up dequeue by getting out quickly if this is just a lookup
-			if ( data ) {
-				if ( !queue || Array.isArray( data ) ) {
-					queue = dataPriv.access( elem, type, jQuery.makeArray( data ) );
-				} else {
-					queue.push( data );
-				}
-			}
-			return queue || [];
-		}
-	},
-
-	dequeue: function( elem, type ) {
-		type = type || "fx";
-
-		var queue = jQuery.queue( elem, type ),
-			startLength = queue.length,
-			fn = queue.shift(),
-			hooks = jQuery._queueHooks( elem, type ),
-			next = function() {
-				jQuery.dequeue( elem, type );
-			};
-
-		// If the fx queue is dequeued, always remove the progress sentinel
-		if ( fn === "inprogress" ) {
-			fn = queue.shift();
-			startLength--;
-		}
-
-		if ( fn ) {
-
-			// Add a progress sentinel to prevent the fx queue from being
-			// automatically dequeued
-			if ( type === "fx" ) {
-				queue.unshift( "inprogress" );
-			}
-
-			// Clear up the last queue stop function
-			delete hooks.stop;
-			fn.call( elem, next, hooks );
-		}
-
-		if ( !startLength && hooks ) {
-			hooks.empty.fire();
-		}
-	},
-
-	// Not public - generate a queueHooks object, or return the current one
-	_queueHooks: function( elem, type ) {
-		var key = type + "queueHooks";
-		return dataPriv.get( elem, key ) || dataPriv.access( elem, key, {
-			empty: jQuery.Callbacks( "once memory" ).add( function() {
-				dataPriv.remove( elem, [ type + "queue", key ] );
-			} )
-		} );
-	}
-} );
-
-jQuery.fn.extend( {
-	queue: function( type, data ) {
-		var setter = 2;
-
-		if ( typeof type !== "string" ) {
-			data = type;
-			type = "fx";
-			setter--;
-		}
-
-		if ( arguments.length < setter ) {
-			return jQuery.queue( this[ 0 ], type );
-		}
-
-		return data === undefined ?
-			this :
-			this.each( function() {
-				var queue = jQuery.queue( this, type, data );
-
-				// Ensure a hooks for this queue
-				jQuery._queueHooks( this, type );
-
-				if ( type === "fx" && queue[ 0 ] !== "inprogress" ) {
-					jQuery.dequeue( this, type );
-				}
-			} );
-	},
-	dequeue: function( type ) {
-		return this.each( function() {
-			jQuery.dequeue( this, type );
-		} );
-	},
-	clearQueue: function( type ) {
-		return this.queue( type || "fx", [] );
-	},
-
-	// Get a promise resolved when queues of a certain type
-	// are emptied (fx is the type by default)
-	promise: function( type, obj ) {
-		var tmp,
-			count = 1,
-			defer = jQuery.Deferred(),
-			elements = this,
-			i = this.length,
-			resolve = function() {
-				if ( !( --count ) ) {
-					defer.resolveWith( elements, [ elements ] );
-				}
-			};
-
-		if ( typeof type !== "string" ) {
-			obj = type;
-			type = undefined;
-		}
-		type = type || "fx";
-
-		while ( i-- ) {
-			tmp = dataPriv.get( elements[ i ], type + "queueHooks" );
-			if ( tmp && tmp.empty ) {
-				count++;
-				tmp.empty.add( resolve );
-			}
-		}
-		resolve();
-		return defer.promise( obj );
-	}
-} );
-var pnum = ( /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/ ).source;
-
-var rcssNum = new RegExp( "^(?:([+-])=|)(" + pnum + ")([a-z%]*)$", "i" );
-
-
-var cssExpand = [ "Top", "Right", "Bottom", "Left" ];
-
-var documentElement = document.documentElement;
-
-
-
-	var isAttached = function( elem ) {
-			return jQuery.contains( elem.ownerDocument, elem );
-		},
-		composed = { composed: true };
-
-	// Support: IE 9 - 11+, Edge 12 - 18+, iOS 10.0 - 10.2 only
-	// Check attachment across shadow DOM boundaries when possible (gh-3504)
-	// Support: iOS 10.0-10.2 only
-	// Early iOS 10 versions support `attachShadow` but not `getRootNode`,
-	// leading to errors. We need to check for `getRootNode`.
-	if ( documentElement.getRootNode ) {
-		isAttached = function( elem ) {
-			return jQuery.contains( elem.ownerDocument, elem ) ||
-				elem.getRootNode( composed ) === elem.ownerDocument;
-		};
-	}
-var isHiddenWithinTree = function( elem, el ) {
-
-		// isHiddenWithinTree might be called from jQuery#filter function;
-		// in that case, element will be second argument
-		elem = el || elem;
-
-		// Inline style trumps all
-		return elem.style.display === "none" ||
-			elem.style.display === "" &&
-
-			// Otherwise, check computed style
-			// Support: Firefox <=43 - 45
-			// Disconnected elements can have computed display: none, so first confirm that elem is
-			// in the document.
-			isAttached( elem ) &&
-
-			jQuery.css( elem, "display" ) === "none";
-	};
-
-
-
-function adjustCSS( elem, prop, valueParts, tween ) {
-	var adjusted, scale,
-		maxIterations = 20,
-		currentValue = tween ?
-			function() {
-				return tween.cur();
-			} :
-			function() {
-				return jQuery.css( elem, prop, "" );
-			},
-		initial = currentValue(),
-		unit = valueParts && valueParts[ 3 ] || ( jQuery.cssNumber[ prop ] ? "" : "px" ),
-
-		// Starting value computation is required for potential unit mismatches
-		initialInUnit = elem.nodeType &&
-			( jQuery.cssNumber[ prop ] || unit !== "px" && +initial ) &&
-			rcssNum.exec( jQuery.css( elem, prop ) );
-
-	if ( initialInUnit && initialInUnit[ 3 ] !== unit ) {
-
-		// Support: Firefox <=54
-		// Halve the iteration target value to prevent interference from CSS upper bounds (gh-2144)
-		initial = initial / 2;
-
-		// Trust units reported by jQuery.css
-		unit = unit || initialInUnit[ 3 ];
-
-		// Iteratively approximate from a nonzero starting point
-		initialInUnit = +initial || 1;
-
-		while ( maxIterations-- ) {
-
-			// Evaluate and update our best guess (doubling guesses that zero out).
-			// Finish if the scale equals or crosses 1 (making the old*new product non-positive).
-			jQuery.style( elem, prop, initialInUnit + unit );
-			if ( ( 1 - scale ) * ( 1 - ( scale = currentValue() / initial || 0.5 ) ) <= 0 ) {
-				maxIterations = 0;
-			}
-			initialInUnit = initialInUnit / scale;
-
-		}
-
-		initialInUnit = initialInUnit * 2;
-		jQuery.style( elem, prop, initialInUnit + unit );
-
-		// Make sure we update the tween properties later on
-		valueParts = valueParts || [];
-	}
-
-	if ( valueParts ) {
-		initialInUnit = +initialInUnit || +initial || 0;
-
-		// Apply relative offset (+=/-=) if specified
-		adjusted = valueParts[ 1 ] ?
-			initialInUnit + ( valueParts[ 1 ] + 1 ) * valueParts[ 2 ] :
-			+valueParts[ 2 ];
-		if ( tween ) {
-			tween.unit = unit;
-			tween.start = initialInUnit;
-			tween.end = adjusted;
-		}
-	}
-	return adjusted;
-}
-
-
-var defaultDisplayMap = {};
-
-function getDefaultDisplay( elem ) {
-	var temp,
-		doc = elem.ownerDocument,
-		nodeName = elem.nodeName,
-		display = defaultDisplayMap[ nodeName ];
-
-	if ( display ) {
-		return display;
-	}
-
-	temp = doc.body.appendChild( doc.createElement( nodeName ) );
-	display = jQuery.css( temp, "display" );
-
-	temp.parentNode.removeChild( temp );
-
-	if ( display === "none" ) {
-		display = "block";
-	}
-	defaultDisplayMap[ nodeName ] = display;
-
-	return display;
-}
-
-function showHide( elements, show ) {
-	var display, elem,
-		values = [],
-		index = 0,
-		length = elements.length;
-
-	// Determine new display value for elements that need to change
-	for ( ; index < length; index++ ) {
-		elem = elements[ index ];
-		if ( !elem.style ) {
-			continue;
-		}
-
-		display = elem.style.display;
-		if ( show ) {
-
-			// Since we force visibility upon cascade-hidden elements, an immediate (and slow)
-			// check is required in this first loop unless we have a nonempty display value (either
-			// inline or about-to-be-restored)
-			if ( display === "none" ) {
-				values[ index ] = dataPriv.get( elem, "display" ) || null;
-				if ( !values[ index ] ) {
-					elem.style.display = "";
-				}
-			}
-			if ( elem.style.display === "" && isHiddenWithinTree( elem ) ) {
-				values[ index ] = getDefaultDisplay( elem );
-			}
-		} else {
-			if ( display !== "none" ) {
-				values[ index ] = "none";
-
-				// Remember what we're overwriting
-				dataPriv.set( elem, "display", display );
-			}
-		}
-	}
-
-	// Set the display of the elements in a second loop to avoid constant reflow
-	for ( index = 0; index < length; index++ ) {
-		if ( values[ index ] != null ) {
-			elements[ index ].style.display = values[ index ];
-		}
-	}
-
-	return elements;
-}
-
-jQuery.fn.extend( {
-	show: function() {
-		return showHide( this, true );
-	},
-	hide: function() {
-		return showHide( this );
-	},
-	toggle: function( state ) {
-		if ( typeof state === "boolean" ) {
-			return state ? this.show() : this.hide();
-		}
-
-		return this.each( function() {
-			if ( isHiddenWithinTree( this ) ) {
-				jQuery( this ).show();
-			} else {
-				jQuery( this ).hide();
-			}
-		} );
-	}
-} );
-var rcheckableType = ( /^(?:checkbox|radio)$/i );
-
-var rtagName = ( /<([a-z][^\/\0>\x20\t\r\n\f]*)/i );
-
-var rscriptType = ( /^$|^module$|\/(?:java|ecma)script/i );
-
-
-
-( function() {
-	var fragment = document.createDocumentFragment(),
-		div = fragment.appendChild( document.createElement( "div" ) ),
-		input = document.createElement( "input" );
-
-	// Support: Android 4.0 - 4.3 only
-	// Check state lost if the name is set (#11217)
-	// Support: Windows Web Apps (WWA)
-	// `name` and `type` must use .setAttribute for WWA (#14901)
-	input.setAttribute( "type", "radio" );
-	input.setAttribute( "checked", "checked" );
-	input.setAttribute( "name", "t" );
-
-	div.appendChild( input );
-
-	// Support: Android <=4.1 only
-	// Older WebKit doesn't clone checked state correctly in fragments
-	support.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked;
-
-	// Support: IE <=11 only
-	// Make sure textarea (and checkbox) defaultValue is properly cloned
-	div.innerHTML = "<textarea>x</textarea>";
-	support.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue;
-
-	// Support: IE <=9 only
-	// IE <=9 replaces <option> tags with their contents when inserted outside of
-	// the select element.
-	div.innerHTML = "<option></option>";
-	support.option = !!div.lastChild;
-} )();
-
-
-// We have to close these tags to support XHTML (#13200)
-var wrapMap = {
-
-	// XHTML parsers do not magically insert elements in the
-	// same way that tag soup parsers do. So we cannot shorten
-	// this by omitting <tbody> or other required elements.
-	thead: [ 1, "<table>", "</table>" ],
-	col: [ 2, "<table><colgroup>", "</colgroup></table>" ],
-	tr: [ 2, "<table><tbody>", "</tbody></table>" ],
-	td: [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ],
-
-	_default: [ 0, "", "" ]
-};
-
-wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;
-wrapMap.th = wrapMap.td;
-
-// Support: IE <=9 only
-if ( !support.option ) {
-	wrapMap.optgroup = wrapMap.option = [ 1, "<select multiple='multiple'>", "</select>" ];
-}
-
-
-function getAll( context, tag ) {
-
-	// Support: IE <=9 - 11 only
-	// Use typeof to avoid zero-argument method invocation on host objects (#15151)
-	var ret;
-
-	if ( typeof context.getElementsByTagName !== "undefined" ) {
-		ret = context.getElementsByTagName( tag || "*" );
-
-	} else if ( typeof context.querySelectorAll !== "undefined" ) {
-		ret = context.querySelectorAll( tag || "*" );
-
-	} else {
-		ret = [];
-	}
-
-	if ( tag === undefined || tag && nodeName( context, tag ) ) {
-		return jQuery.merge( [ context ], ret );
-	}
-
-	return ret;
-}
-
-
-// Mark scripts as having already been evaluated
-function setGlobalEval( elems, refElements ) {
-	var i = 0,
-		l = elems.length;
-
-	for ( ; i < l; i++ ) {
-		dataPriv.set(
-			elems[ i ],
-			"globalEval",
-			!refElements || dataPriv.get( refElements[ i ], "globalEval" )
-		);
-	}
-}
-
-
-var rhtml = /<|&#?\w+;/;
-
-function buildFragment( elems, context, scripts, selection, ignored ) {
-	var elem, tmp, tag, wrap, attached, j,
-		fragment = context.createDocumentFragment(),
-		nodes = [],
-		i = 0,
-		l = elems.length;
-
-	for ( ; i < l; i++ ) {
-		elem = elems[ i ];
-
-		if ( elem || elem === 0 ) {
-
-			// Add nodes directly
-			if ( toType( elem ) === "object" ) {
-
-				// Support: Android <=4.0 only, PhantomJS 1 only
-				// push.apply(_, arraylike) throws on ancient WebKit
-				jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem );
-
-			// Convert non-html into a text node
-			} else if ( !rhtml.test( elem ) ) {
-				nodes.push( context.createTextNode( elem ) );
-
-			// Convert html into DOM nodes
-			} else {
-				tmp = tmp || fragment.appendChild( context.createElement( "div" ) );
-
-				// Deserialize a standard representation
-				tag = ( rtagName.exec( elem ) || [ "", "" ] )[ 1 ].toLowerCase();
-				wrap = wrapMap[ tag ] || wrapMap._default;
-				tmp.innerHTML = wrap[ 1 ] + jQuery.htmlPrefilter( elem ) + wrap[ 2 ];
-
-				// Descend through wrappers to the right content
-				j = wrap[ 0 ];
-				while ( j-- ) {
-					tmp = tmp.lastChild;
-				}
-
-				// Support: Android <=4.0 only, PhantomJS 1 only
-				// push.apply(_, arraylike) throws on ancient WebKit
-				jQuery.merge( nodes, tmp.childNodes );
-
-				// Remember the top-level container
-				tmp = fragment.firstChild;
-
-				// Ensure the created nodes are orphaned (#12392)
-				tmp.textContent = "";
-			}
-		}
-	}
-
-	// Remove wrapper from fragment
-	fragment.textContent = "";
-
-	i = 0;
-	while ( ( elem = nodes[ i++ ] ) ) {
-
-		// Skip elements already in the context collection (trac-4087)
-		if ( selection && jQuery.inArray( elem, selection ) > -1 ) {
-			if ( ignored ) {
-				ignored.push( elem );
-			}
-			continue;
-		}
-
-		attached = isAttached( elem );
-
-		// Append to fragment
-		tmp = getAll( fragment.appendChild( elem ), "script" );
-
-		// Preserve script evaluation history
-		if ( attached ) {
-			setGlobalEval( tmp );
-		}
-
-		// Capture executables
-		if ( scripts ) {
-			j = 0;
-			while ( ( elem = tmp[ j++ ] ) ) {
-				if ( rscriptType.test( elem.type || "" ) ) {
-					scripts.push( elem );
-				}
-			}
-		}
-	}
-
-	return fragment;
-}
-
-
-var
-	rkeyEvent = /^key/,
-	rmouseEvent = /^(?:mouse|pointer|contextmenu|drag|drop)|click/,
-	rtypenamespace = /^([^.]*)(?:\.(.+)|)/;
-
-function returnTrue() {
-	return true;
-}
-
-function returnFalse() {
-	return false;
-}
-
-// Support: IE <=9 - 11+
-// focus() and blur() are asynchronous, except when they are no-op.
-// So expect focus to be synchronous when the element is already active,
-// and blur to be synchronous when the element is not already active.
-// (focus and blur are always synchronous in other supported browsers,
-// this just defines when we can count on it).
-function expectSync( elem, type ) {
-	return ( elem === safeActiveElement() ) === ( type === "focus" );
-}
-
-// Support: IE <=9 only
-// Accessing document.activeElement can throw unexpectedly
-// https://bugs.jquery.com/ticket/13393
-function safeActiveElement() {
-	try {
-		return document.activeElement;
-	} catch ( err ) { }
-}
-
-function on( elem, types, selector, data, fn, one ) {
-	var origFn, type;
-
-	// Types can be a map of types/handlers
-	if ( typeof types === "object" ) {
-
-		// ( types-Object, selector, data )
-		if ( typeof selector !== "string" ) {
-
-			// ( types-Object, data )
-			data = data || selector;
-			selector = undefined;
-		}
-		for ( type in types ) {
-			on( elem, type, selector, data, types[ type ], one );
-		}
-		return elem;
-	}
-
-	if ( data == null && fn == null ) {
-
-		// ( types, fn )
-		fn = selector;
-		data = selector = undefined;
-	} else if ( fn == null ) {
-		if ( typeof selector === "string" ) {
-
-			// ( types, selector, fn )
-			fn = data;
-			data = undefined;
-		} else {
-
-			// ( types, data, fn )
-			fn = data;
-			data = selector;
-			selector = undefined;
-		}
-	}
-	if ( fn === false ) {
-		fn = returnFalse;
-	} else if ( !fn ) {
-		return elem;
-	}
-
-	if ( one === 1 ) {
-		origFn = fn;
-		fn = function( event ) {
-
-			// Can use an empty set, since event contains the info
-			jQuery().off( event );
-			return origFn.apply( this, arguments );
-		};
-
-		// Use same guid so caller can remove using origFn
-		fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ );
-	}
-	return elem.each( function() {
-		jQuery.event.add( this, types, fn, data, selector );
-	} );
-}
-
-/*
- * Helper functions for managing events -- not part of the public interface.
- * Props to Dean Edwards' addEvent library for many of the ideas.
- */
-jQuery.event = {
-
-	global: {},
-
-	add: function( elem, types, handler, data, selector ) {
-
-		var handleObjIn, eventHandle, tmp,
-			events, t, handleObj,
-			special, handlers, type, namespaces, origType,
-			elemData = dataPriv.get( elem );
-
-		// Only attach events to objects that accept data
-		if ( !acceptData( elem ) ) {
-			return;
-		}
-
-		// Caller can pass in an object of custom data in lieu of the handler
-		if ( handler.handler ) {
-			handleObjIn = handler;
-			handler = handleObjIn.handler;
-			selector = handleObjIn.selector;
-		}
-
-		// Ensure that invalid selectors throw exceptions at attach time
-		// Evaluate against documentElement in case elem is a non-element node (e.g., document)
-		if ( selector ) {
-			jQuery.find.matchesSelector( documentElement, selector );
-		}
-
-		// Make sure that the handler has a unique ID, used to find/remove it later
-		if ( !handler.guid ) {
-			handler.guid = jQuery.guid++;
-		}
-
-		// Init the element's event structure and main handler, if this is the first
-		if ( !( events = elemData.events ) ) {
-			events = elemData.events = Object.create( null );
-		}
-		if ( !( eventHandle = elemData.handle ) ) {
-			eventHandle = elemData.handle = function( e ) {
-
-				// Discard the second event of a jQuery.event.trigger() and
-				// when an event is called after a page has unloaded
-				return typeof jQuery !== "undefined" && jQuery.event.triggered !== e.type ?
-					jQuery.event.dispatch.apply( elem, arguments ) : undefined;
-			};
-		}
-
-		// Handle multiple events separated by a space
-		types = ( types || "" ).match( rnothtmlwhite ) || [ "" ];
-		t = types.length;
-		while ( t-- ) {
-			tmp = rtypenamespace.exec( types[ t ] ) || [];
-			type = origType = tmp[ 1 ];
-			namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort();
-
-			// There *must* be a type, no attaching namespace-only handlers
-			if ( !type ) {
-				continue;
-			}
-
-			// If event changes its type, use the special event handlers for the changed type
-			special = jQuery.event.special[ type ] || {};
-
-			// If selector defined, determine special event api type, otherwise given type
-			type = ( selector ? special.delegateType : special.bindType ) || type;
-
-			// Update special based on newly reset type
-			special = jQuery.event.special[ type ] || {};
-
-			// handleObj is passed to all event handlers
-			handleObj = jQuery.extend( {
-				type: type,
-				origType: origType,
-				data: data,
-				handler: handler,
-				guid: handler.guid,
-				selector: selector,
-				needsContext: selector && jQuery.expr.match.needsContext.test( selector ),
-				namespace: namespaces.join( "." )
-			}, handleObjIn );
-
-			// Init the event handler queue if we're the first
-			if ( !( handlers = events[ type ] ) ) {
-				handlers = events[ type ] = [];
-				handlers.delegateCount = 0;
-
-				// Only use addEventListener if the special events handler returns false
-				if ( !special.setup ||
-					special.setup.call( elem, data, namespaces, eventHandle ) === false ) {
-
-					if ( elem.addEventListener ) {
-						elem.addEventListener( type, eventHandle );
-					}
-				}
-			}
-
-			if ( special.add ) {
-				special.add.call( elem, handleObj );
-
-				if ( !handleObj.handler.guid ) {
-					handleObj.handler.guid = handler.guid;
-				}
-			}
-
-			// Add to the element's handler list, delegates in front
-			if ( selector ) {
-				handlers.splice( handlers.delegateCount++, 0, handleObj );
-			} else {
-				handlers.push( handleObj );
-			}
-
-			// Keep track of which events have ever been used, for event optimization
-			jQuery.event.global[ type ] = true;
-		}
-
-	},
-
-	// Detach an event or set of events from an element
-	remove: function( elem, types, handler, selector, mappedTypes ) {
-
-		var j, origCount, tmp,
-			events, t, handleObj,
-			special, handlers, type, namespaces, origType,
-			elemData = dataPriv.hasData( elem ) && dataPriv.get( elem );
-
-		if ( !elemData || !( events = elemData.events ) ) {
-			return;
-		}
-
-		// Once for each type.namespace in types; type may be omitted
-		types = ( types || "" ).match( rnothtmlwhite ) || [ "" ];
-		t = types.length;
-		while ( t-- ) {
-			tmp = rtypenamespace.exec( types[ t ] ) || [];
-			type = origType = tmp[ 1 ];
-			namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort();
-
-			// Unbind all events (on this namespace, if provided) for the element
-			if ( !type ) {
-				for ( type in events ) {
-					jQuery.event.remove( elem, type + types[ t ], handler, selector, true );
-				}
-				continue;
-			}
-
-			special = jQuery.event.special[ type ] || {};
-			type = ( selector ? special.delegateType : special.bindType ) || type;
-			handlers = events[ type ] || [];
-			tmp = tmp[ 2 ] &&
-				new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" );
-
-			// Remove matching events
-			origCount = j = handlers.length;
-			while ( j-- ) {
-				handleObj = handlers[ j ];
-
-				if ( ( mappedTypes || origType === handleObj.origType ) &&
-					( !handler || handler.guid === handleObj.guid ) &&
-					( !tmp || tmp.test( handleObj.namespace ) ) &&
-					( !selector || selector === handleObj.selector ||
-						selector === "**" && handleObj.selector ) ) {
-					handlers.splice( j, 1 );
-
-					if ( handleObj.selector ) {
-						handlers.delegateCount--;
-					}
-					if ( special.remove ) {
-						special.remove.call( elem, handleObj );
-					}
-				}
-			}
-
-			// Remove generic event handler if we removed something and no more handlers exist
-			// (avoids potential for endless recursion during removal of special event handlers)
-			if ( origCount && !handlers.length ) {
-				if ( !special.teardown ||
-					special.teardown.call( elem, namespaces, elemData.handle ) === false ) {
-
-					jQuery.removeEvent( elem, type, elemData.handle );
-				}
-
-				delete events[ type ];
-			}
-		}
-
-		// Remove data and the expando if it's no longer used
-		if ( jQuery.isEmptyObject( events ) ) {
-			dataPriv.remove( elem, "handle events" );
-		}
-	},
-
-	dispatch: function( nativeEvent ) {
-
-		var i, j, ret, matched, handleObj, handlerQueue,
-			args = new Array( arguments.length ),
-
-			// Make a writable jQuery.Event from the native event object
-			event = jQuery.event.fix( nativeEvent ),
-
-			handlers = (
-					dataPriv.get( this, "events" ) || Object.create( null )
-				)[ event.type ] || [],
-			special = jQuery.event.special[ event.type ] || {};
-
-		// Use the fix-ed jQuery.Event rather than the (read-only) native event
-		args[ 0 ] = event;
-
-		for ( i = 1; i < arguments.length; i++ ) {
-			args[ i ] = arguments[ i ];
-		}
-
-		event.delegateTarget = this;
-
-		// Call the preDispatch hook for the mapped type, and let it bail if desired
-		if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) {
-			return;
-		}
-
-		// Determine handlers
-		handlerQueue = jQuery.event.handlers.call( this, event, handlers );
-
-		// Run delegates first; they may want to stop propagation beneath us
-		i = 0;
-		while ( ( matched = handlerQueue[ i++ ] ) && !event.isPropagationStopped() ) {
-			event.currentTarget = matched.elem;
-
-			j = 0;
-			while ( ( handleObj = matched.handlers[ j++ ] ) &&
-				!event.isImmediatePropagationStopped() ) {
-
-				// If the event is namespaced, then each handler is only invoked if it is
-				// specially universal or its namespaces are a superset of the event's.
-				if ( !event.rnamespace || handleObj.namespace === false ||
-					event.rnamespace.test( handleObj.namespace ) ) {
-
-					event.handleObj = handleObj;
-					event.data = handleObj.data;
-
-					ret = ( ( jQuery.event.special[ handleObj.origType ] || {} ).handle ||
-						handleObj.handler ).apply( matched.elem, args );
-
-					if ( ret !== undefined ) {
-						if ( ( event.result = ret ) === false ) {
-							event.preventDefault();
-							event.stopPropagation();
-						}
-					}
-				}
-			}
-		}
-
-		// Call the postDispatch hook for the mapped type
-		if ( special.postDispatch ) {
-			special.postDispatch.call( this, event );
-		}
-
-		return event.result;
-	},
-
-	handlers: function( event, handlers ) {
-		var i, handleObj, sel, matchedHandlers, matchedSelectors,
-			handlerQueue = [],
-			delegateCount = handlers.delegateCount,
-			cur = event.target;
-
-		// Find delegate handlers
-		if ( delegateCount &&
-
-			// Support: IE <=9
-			// Black-hole SVG <use> instance trees (trac-13180)
-			cur.nodeType &&
-
-			// Support: Firefox <=42
-			// Suppress spec-violating clicks indicating a non-primary pointer button (trac-3861)
-			// https://www.w3.org/TR/DOM-Level-3-Events/#event-type-click
-			// Support: IE 11 only
-			// ...but not arrow key "clicks" of radio inputs, which can have `button` -1 (gh-2343)
-			!( event.type === "click" && event.button >= 1 ) ) {
-
-			for ( ; cur !== this; cur = cur.parentNode || this ) {
-
-				// Don't check non-elements (#13208)
-				// Don't process clicks on disabled elements (#6911, #8165, #11382, #11764)
-				if ( cur.nodeType === 1 && !( event.type === "click" && cur.disabled === true ) ) {
-					matchedHandlers = [];
-					matchedSelectors = {};
-					for ( i = 0; i < delegateCount; i++ ) {
-						handleObj = handlers[ i ];
-
-						// Don't conflict with Object.prototype properties (#13203)
-						sel = handleObj.selector + " ";
-
-						if ( matchedSelectors[ sel ] === undefined ) {
-							matchedSelectors[ sel ] = handleObj.needsContext ?
-								jQuery( sel, this ).index( cur ) > -1 :
-								jQuery.find( sel, this, null, [ cur ] ).length;
-						}
-						if ( matchedSelectors[ sel ] ) {
-							matchedHandlers.push( handleObj );
-						}
-					}
-					if ( matchedHandlers.length ) {
-						handlerQueue.push( { elem: cur, handlers: matchedHandlers } );
-					}
-				}
-			}
-		}
-
-		// Add the remaining (directly-bound) handlers
-		cur = this;
-		if ( delegateCount < handlers.length ) {
-			handlerQueue.push( { elem: cur, handlers: handlers.slice( delegateCount ) } );
-		}
-
-		return handlerQueue;
-	},
-
-	addProp: function( name, hook ) {
-		Object.defineProperty( jQuery.Event.prototype, name, {
-			enumerable: true,
-			configurable: true,
-
-			get: isFunction( hook ) ?
-				function() {
-					if ( this.originalEvent ) {
-							return hook( this.originalEvent );
-					}
-				} :
-				function() {
-					if ( this.originalEvent ) {
-							return this.originalEvent[ name ];
-					}
-				},
-
-			set: function( value ) {
-				Object.defineProperty( this, name, {
-					enumerable: true,
-					configurable: true,
-					writable: true,
-					value: value
-				} );
-			}
-		} );
-	},
-
-	fix: function( originalEvent ) {
-		return originalEvent[ jQuery.expando ] ?
-			originalEvent :
-			new jQuery.Event( originalEvent );
-	},
-
-	special: {
-		load: {
-
-			// Prevent triggered image.load events from bubbling to window.load
-			noBubble: true
-		},
-		click: {
-
-			// Utilize native event to ensure correct state for checkable inputs
-			setup: function( data ) {
-
-				// For mutual compressibility with _default, replace `this` access with a local var.
-				// `|| data` is dead code meant only to preserve the variable through minification.
-				var el = this || data;
-
-				// Claim the first handler
-				if ( rcheckableType.test( el.type ) &&
-					el.click && nodeName( el, "input" ) ) {
-
-					// dataPriv.set( el, "click", ... )
-					leverageNative( el, "click", returnTrue );
-				}
-
-				// Return false to allow normal processing in the caller
-				return false;
-			},
-			trigger: function( data ) {
-
-				// For mutual compressibility with _default, replace `this` access with a local var.
-				// `|| data` is dead code meant only to preserve the variable through minification.
-				var el = this || data;
-
-				// Force setup before triggering a click
-				if ( rcheckableType.test( el.type ) &&
-					el.click && nodeName( el, "input" ) ) {
-
-					leverageNative( el, "click" );
-				}
-
-				// Return non-false to allow normal event-path propagation
-				return true;
-			},
-
-			// For cross-browser consistency, suppress native .click() on links
-			// Also prevent it if we're currently inside a leveraged native-event stack
-			_default: function( event ) {
-				var target = event.target;
-				return rcheckableType.test( target.type ) &&
-					target.click && nodeName( target, "input" ) &&
-					dataPriv.get( target, "click" ) ||
-					nodeName( target, "a" );
-			}
-		},
-
-		beforeunload: {
-			postDispatch: function( event ) {
-
-				// Support: Firefox 20+
-				// Firefox doesn't alert if the returnValue field is not set.
-				if ( event.result !== undefined && event.originalEvent ) {
-					event.originalEvent.returnValue = event.result;
-				}
-			}
-		}
-	}
-};
-
-// Ensure the presence of an event listener that handles manually-triggered
-// synthetic events by interrupting progress until reinvoked in response to
-// *native* events that it fires directly, ensuring that state changes have
-// already occurred before other listeners are invoked.
-function leverageNative( el, type, expectSync ) {
-
-	// Missing expectSync indicates a trigger call, which must force setup through jQuery.event.add
-	if ( !expectSync ) {
-		if ( dataPriv.get( el, type ) === undefined ) {
-			jQuery.event.add( el, type, returnTrue );
-		}
-		return;
-	}
-
-	// Register the controller as a special universal handler for all event namespaces
-	dataPriv.set( el, type, false );
-	jQuery.event.add( el, type, {
-		namespace: false,
-		handler: function( event ) {
-			var notAsync, result,
-				saved = dataPriv.get( this, type );
-
-			if ( ( event.isTrigger & 1 ) && this[ type ] ) {
-
-				// Interrupt processing of the outer synthetic .trigger()ed event
-				// Saved data should be false in such cases, but might be a leftover capture object
-				// from an async native handler (gh-4350)
-				if ( !saved.length ) {
-
-					// Store arguments for use when handling the inner native event
-					// There will always be at least one argument (an event object), so this array
-					// will not be confused with a leftover capture object.
-					saved = slice.call( arguments );
-					dataPriv.set( this, type, saved );
-
-					// Trigger the native event and capture its result
-					// Support: IE <=9 - 11+
-					// focus() and blur() are asynchronous
-					notAsync = expectSync( this, type );
-					this[ type ]();
-					result = dataPriv.get( this, type );
-					if ( saved !== result || notAsync ) {
-						dataPriv.set( this, type, false );
-					} else {
-						result = {};
-					}
-					if ( saved !== result ) {
-
-						// Cancel the outer synthetic event
-						event.stopImmediatePropagation();
-						event.preventDefault();
-						return result.value;
-					}
-
-				// If this is an inner synthetic event for an event with a bubbling surrogate
-				// (focus or blur), assume that the surrogate already propagated from triggering the
-				// native event and prevent that from happening again here.
-				// This technically gets the ordering wrong w.r.t. to `.trigger()` (in which the
-				// bubbling surrogate propagates *after* the non-bubbling base), but that seems
-				// less bad than duplication.
-				} else if ( ( jQuery.event.special[ type ] || {} ).delegateType ) {
-					event.stopPropagation();
-				}
-
-			// If this is a native event triggered above, everything is now in order
-			// Fire an inner synthetic event with the original arguments
-			} else if ( saved.length ) {
-
-				// ...and capture the result
-				dataPriv.set( this, type, {
-					value: jQuery.event.trigger(
-
-						// Support: IE <=9 - 11+
-						// Extend with the prototype to reset the above stopImmediatePropagation()
-						jQuery.extend( saved[ 0 ], jQuery.Event.prototype ),
-						saved.slice( 1 ),
-						this
-					)
-				} );
-
-				// Abort handling of the native event
-				event.stopImmediatePropagation();
-			}
-		}
-	} );
-}
-
-jQuery.removeEvent = function( elem, type, handle ) {
-
-	// This "if" is needed for plain objects
-	if ( elem.removeEventListener ) {
-		elem.removeEventListener( type, handle );
-	}
-};
-
-jQuery.Event = function( src, props ) {
-
-	// Allow instantiation without the 'new' keyword
-	if ( !( this instanceof jQuery.Event ) ) {
-		return new jQuery.Event( src, props );
-	}
-
-	// Event object
-	if ( src && src.type ) {
-		this.originalEvent = src;
-		this.type = src.type;
-
-		// Events bubbling up the document may have been marked as prevented
-		// by a handler lower down the tree; reflect the correct value.
-		this.isDefaultPrevented = src.defaultPrevented ||
-				src.defaultPrevented === undefined &&
-
-				// Support: Android <=2.3 only
-				src.returnValue === false ?
-			returnTrue :
-			returnFalse;
-
-		// Create target properties
-		// Support: Safari <=6 - 7 only
-		// Target should not be a text node (#504, #13143)
-		this.target = ( src.target && src.target.nodeType === 3 ) ?
-			src.target.parentNode :
-			src.target;
-
-		this.currentTarget = src.currentTarget;
-		this.relatedTarget = src.relatedTarget;
-
-	// Event type
-	} else {
-		this.type = src;
-	}
-
-	// Put explicitly provided properties onto the event object
-	if ( props ) {
-		jQuery.extend( this, props );
-	}
-
-	// Create a timestamp if incoming event doesn't have one
-	this.timeStamp = src && src.timeStamp || Date.now();
-
-	// Mark it as fixed
-	this[ jQuery.expando ] = true;
-};
-
-// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding
-// https://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html
-jQuery.Event.prototype = {
-	constructor: jQuery.Event,
-	isDefaultPrevented: returnFalse,
-	isPropagationStopped: returnFalse,
-	isImmediatePropagationStopped: returnFalse,
-	isSimulated: false,
-
-	preventDefault: function() {
-		var e = this.originalEvent;
-
-		this.isDefaultPrevented = returnTrue;
-
-		if ( e && !this.isSimulated ) {
-			e.preventDefault();
-		}
-	},
-	stopPropagation: function() {
-		var e = this.originalEvent;
-
-		this.isPropagationStopped = returnTrue;
-
-		if ( e && !this.isSimulated ) {
-			e.stopPropagation();
-		}
-	},
-	stopImmediatePropagation: function() {
-		var e = this.originalEvent;
-
-		this.isImmediatePropagationStopped = returnTrue;
-
-		if ( e && !this.isSimulated ) {
-			e.stopImmediatePropagation();
-		}
-
-		this.stopPropagation();
-	}
-};
-
-// Includes all common event props including KeyEvent and MouseEvent specific props
-jQuery.each( {
-	altKey: true,
-	bubbles: true,
-	cancelable: true,
-	changedTouches: true,
-	ctrlKey: true,
-	detail: true,
-	eventPhase: true,
-	metaKey: true,
-	pageX: true,
-	pageY: true,
-	shiftKey: true,
-	view: true,
-	"char": true,
-	code: true,
-	charCode: true,
-	key: true,
-	keyCode: true,
-	button: true,
-	buttons: true,
-	clientX: true,
-	clientY: true,
-	offsetX: true,
-	offsetY: true,
-	pointerId: true,
-	pointerType: true,
-	screenX: true,
-	screenY: true,
-	targetTouches: true,
-	toElement: true,
-	touches: true,
-
-	which: function( event ) {
-		var button = event.button;
-
-		// Add which for key events
-		if ( event.which == null && rkeyEvent.test( event.type ) ) {
-			return event.charCode != null ? event.charCode : event.keyCode;
-		}
-
-		// Add which for click: 1 === left; 2 === middle; 3 === right
-		if ( !event.which && button !== undefined && rmouseEvent.test( event.type ) ) {
-			if ( button & 1 ) {
-				return 1;
-			}
-
-			if ( button & 2 ) {
-				return 3;
-			}
-
-			if ( button & 4 ) {
-				return 2;
-			}
-
-			return 0;
-		}
-
-		return event.which;
-	}
-}, jQuery.event.addProp );
-
-jQuery.each( { focus: "focusin", blur: "focusout" }, function( type, delegateType ) {
-	jQuery.event.special[ type ] = {
-
-		// Utilize native event if possible so blur/focus sequence is correct
-		setup: function() {
-
-			// Claim the first handler
-			// dataPriv.set( this, "focus", ... )
-			// dataPriv.set( this, "blur", ... )
-			leverageNative( this, type, expectSync );
-
-			// Return false to allow normal processing in the caller
-			return false;
-		},
-		trigger: function() {
-
-			// Force setup before trigger
-			leverageNative( this, type );
-
-			// Return non-false to allow normal event-path propagation
-			return true;
-		},
-
-		delegateType: delegateType
-	};
-} );
-
-// Create mouseenter/leave events using mouseover/out and event-time checks
-// so that event delegation works in jQuery.
-// Do the same for pointerenter/pointerleave and pointerover/pointerout
-//
-// Support: Safari 7 only
-// Safari sends mouseenter too often; see:
-// https://bugs.chromium.org/p/chromium/issues/detail?id=470258
-// for the description of the bug (it existed in older Chrome versions as well).
-jQuery.each( {
-	mouseenter: "mouseover",
-	mouseleave: "mouseout",
-	pointerenter: "pointerover",
-	pointerleave: "pointerout"
-}, function( orig, fix ) {
-	jQuery.event.special[ orig ] = {
-		delegateType: fix,
-		bindType: fix,
-
-		handle: function( event ) {
-			var ret,
-				target = this,
-				related = event.relatedTarget,
-				handleObj = event.handleObj;
-
-			// For mouseenter/leave call the handler if related is outside the target.
-			// NB: No relatedTarget if the mouse left/entered the browser window
-			if ( !related || ( related !== target && !jQuery.contains( target, related ) ) ) {
-				event.type = handleObj.origType;
-				ret = handleObj.handler.apply( this, arguments );
-				event.type = fix;
-			}
-			return ret;
-		}
-	};
-} );
-
-jQuery.fn.extend( {
-
-	on: function( types, selector, data, fn ) {
-		return on( this, types, selector, data, fn );
-	},
-	one: function( types, selector, data, fn ) {
-		return on( this, types, selector, data, fn, 1 );
-	},
-	off: function( types, selector, fn ) {
-		var handleObj, type;
-		if ( types && types.preventDefault && types.handleObj ) {
-
-			// ( event )  dispatched jQuery.Event
-			handleObj = types.handleObj;
-			jQuery( types.delegateTarget ).off(
-				handleObj.namespace ?
-					handleObj.origType + "." + handleObj.namespace :
-					handleObj.origType,
-				handleObj.selector,
-				handleObj.handler
-			);
-			return this;
-		}
-		if ( typeof types === "object" ) {
-
-			// ( types-object [, selector] )
-			for ( type in types ) {
-				this.off( type, selector, types[ type ] );
-			}
-			return this;
-		}
-		if ( selector === false || typeof selector === "function" ) {
-
-			// ( types [, fn] )
-			fn = selector;
-			selector = undefined;
-		}
-		if ( fn === false ) {
-			fn = returnFalse;
-		}
-		return this.each( function() {
-			jQuery.event.remove( this, types, fn, selector );
-		} );
-	}
-} );
-
-
-var
-
-	// Support: IE <=10 - 11, Edge 12 - 13 only
-	// In IE/Edge using regex groups here causes severe slowdowns.
-	// See https://connect.microsoft.com/IE/feedback/details/1736512/
-	rnoInnerhtml = /<script|<style|<link/i,
-
-	// checked="checked" or checked
-	rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i,
-	rcleanScript = /^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g;
-
-// Prefer a tbody over its parent table for containing new rows
-function manipulationTarget( elem, content ) {
-	if ( nodeName( elem, "table" ) &&
-		nodeName( content.nodeType !== 11 ? content : content.firstChild, "tr" ) ) {
-
-		return jQuery( elem ).children( "tbody" )[ 0 ] || elem;
-	}
-
-	return elem;
-}
-
-// Replace/restore the type attribute of script elements for safe DOM manipulation
-function disableScript( elem ) {
-	elem.type = ( elem.getAttribute( "type" ) !== null ) + "/" + elem.type;
-	return elem;
-}
-function restoreScript( elem ) {
-	if ( ( elem.type || "" ).slice( 0, 5 ) === "true/" ) {
-		elem.type = elem.type.slice( 5 );
-	} else {
-		elem.removeAttribute( "type" );
-	}
-
-	return elem;
-}
-
-function cloneCopyEvent( src, dest ) {
-	var i, l, type, pdataOld, udataOld, udataCur, events;
-
-	if ( dest.nodeType !== 1 ) {
-		return;
-	}
-
-	// 1. Copy private data: events, handlers, etc.
-	if ( dataPriv.hasData( src ) ) {
-		pdataOld = dataPriv.get( src );
-		events = pdataOld.events;
-
-		if ( events ) {
-			dataPriv.remove( dest, "handle events" );
-
-			for ( type in events ) {
-				for ( i = 0, l = events[ type ].length; i < l; i++ ) {
-					jQuery.event.add( dest, type, events[ type ][ i ] );
-				}
-			}
-		}
-	}
-
-	// 2. Copy user data
-	if ( dataUser.hasData( src ) ) {
-		udataOld = dataUser.access( src );
-		udataCur = jQuery.extend( {}, udataOld );
-
-		dataUser.set( dest, udataCur );
-	}
-}
-
-// Fix IE bugs, see support tests
-function fixInput( src, dest ) {
-	var nodeName = dest.nodeName.toLowerCase();
-
-	// Fails to persist the checked state of a cloned checkbox or radio button.
-	if ( nodeName === "input" && rcheckableType.test( src.type ) ) {
-		dest.checked = src.checked;
-
-	// Fails to return the selected option to the default selected state when cloning options
-	} else if ( nodeName === "input" || nodeName === "textarea" ) {
-		dest.defaultValue = src.defaultValue;
-	}
-}
-
-function domManip( collection, args, callback, ignored ) {
-
-	// Flatten any nested arrays
-	args = flat( args );
-
-	var fragment, first, scripts, hasScripts, node, doc,
-		i = 0,
-		l = collection.length,
-		iNoClone = l - 1,
-		value = args[ 0 ],
-		valueIsFunction = isFunction( value );
-
-	// We can't cloneNode fragments that contain checked, in WebKit
-	if ( valueIsFunction ||
-			( l > 1 && typeof value === "string" &&
-				!support.checkClone && rchecked.test( value ) ) ) {
-		return collection.each( function( index ) {
-			var self = collection.eq( index );
-			if ( valueIsFunction ) {
-				args[ 0 ] = value.call( this, index, self.html() );
-			}
-			domManip( self, args, callback, ignored );
-		} );
-	}
-
-	if ( l ) {
-		fragment = buildFragment( args, collection[ 0 ].ownerDocument, false, collection, ignored );
-		first = fragment.firstChild;
-
-		if ( fragment.childNodes.length === 1 ) {
-			fragment = first;
-		}
-
-		// Require either new content or an interest in ignored elements to invoke the callback
-		if ( first || ignored ) {
-			scripts = jQuery.map( getAll( fragment, "script" ), disableScript );
-			hasScripts = scripts.length;
-
-			// Use the original fragment for the last item
-			// instead of the first because it can end up
-			// being emptied incorrectly in certain situations (#8070).
-			for ( ; i < l; i++ ) {
-				node = fragment;
-
-				if ( i !== iNoClone ) {
-					node = jQuery.clone( node, true, true );
-
-					// Keep references to cloned scripts for later restoration
-					if ( hasScripts ) {
-
-						// Support: Android <=4.0 only, PhantomJS 1 only
-						// push.apply(_, arraylike) throws on ancient WebKit
-						jQuery.merge( scripts, getAll( node, "script" ) );
-					}
-				}
-
-				callback.call( collection[ i ], node, i );
-			}
-
-			if ( hasScripts ) {
-				doc = scripts[ scripts.length - 1 ].ownerDocument;
-
-				// Reenable scripts
-				jQuery.map( scripts, restoreScript );
-
-				// Evaluate executable scripts on first document insertion
-				for ( i = 0; i < hasScripts; i++ ) {
-					node = scripts[ i ];
-					if ( rscriptType.test( node.type || "" ) &&
-						!dataPriv.access( node, "globalEval" ) &&
-						jQuery.contains( doc, node ) ) {
-
-						if ( node.src && ( node.type || "" ).toLowerCase()  !== "module" ) {
-
-							// Optional AJAX dependency, but won't run scripts if not present
-							if ( jQuery._evalUrl && !node.noModule ) {
-								jQuery._evalUrl( node.src, {
-									nonce: node.nonce || node.getAttribute( "nonce" )
-								}, doc );
-							}
-						} else {
-							DOMEval( node.textContent.replace( rcleanScript, "" ), node, doc );
-						}
-					}
-				}
-			}
-		}
-	}
-
-	return collection;
-}
-
-function remove( elem, selector, keepData ) {
-	var node,
-		nodes = selector ? jQuery.filter( selector, elem ) : elem,
-		i = 0;
-
-	for ( ; ( node = nodes[ i ] ) != null; i++ ) {
-		if ( !keepData && node.nodeType === 1 ) {
-			jQuery.cleanData( getAll( node ) );
-		}
-
-		if ( node.parentNode ) {
-			if ( keepData && isAttached( node ) ) {
-				setGlobalEval( getAll( node, "script" ) );
-			}
-			node.parentNode.removeChild( node );
-		}
-	}
-
-	return elem;
-}
-
-jQuery.extend( {
-	htmlPrefilter: function( html ) {
-		return html;
-	},
-
-	clone: function( elem, dataAndEvents, deepDataAndEvents ) {
-		var i, l, srcElements, destElements,
-			clone = elem.cloneNode( true ),
-			inPage = isAttached( elem );
-
-		// Fix IE cloning issues
-		if ( !support.noCloneChecked && ( elem.nodeType === 1 || elem.nodeType === 11 ) &&
-				!jQuery.isXMLDoc( elem ) ) {
-
-			// We eschew Sizzle here for performance reasons: https://jsperf.com/getall-vs-sizzle/2
-			destElements = getAll( clone );
-			srcElements = getAll( elem );
-
-			for ( i = 0, l = srcElements.length; i < l; i++ ) {
-				fixInput( srcElements[ i ], destElements[ i ] );
-			}
-		}
-
-		// Copy the events from the original to the clone
-		if ( dataAndEvents ) {
-			if ( deepDataAndEvents ) {
-				srcElements = srcElements || getAll( elem );
-				destElements = destElements || getAll( clone );
-
-				for ( i = 0, l = srcElements.length; i < l; i++ ) {
-					cloneCopyEvent( srcElements[ i ], destElements[ i ] );
-				}
-			} else {
-				cloneCopyEvent( elem, clone );
-			}
-		}
-
-		// Preserve script evaluation history
-		destElements = getAll( clone, "script" );
-		if ( destElements.length > 0 ) {
-			setGlobalEval( destElements, !inPage && getAll( elem, "script" ) );
-		}
-
-		// Return the cloned set
-		return clone;
-	},
-
-	cleanData: function( elems ) {
-		var data, elem, type,
-			special = jQuery.event.special,
-			i = 0;
-
-		for ( ; ( elem = elems[ i ] ) !== undefined; i++ ) {
-			if ( acceptData( elem ) ) {
-				if ( ( data = elem[ dataPriv.expando ] ) ) {
-					if ( data.events ) {
-						for ( type in data.events ) {
-							if ( special[ type ] ) {
-								jQuery.event.remove( elem, type );
-
-							// This is a shortcut to avoid jQuery.event.remove's overhead
-							} else {
-								jQuery.removeEvent( elem, type, data.handle );
-							}
-						}
-					}
-
-					// Support: Chrome <=35 - 45+
-					// Assign undefined instead of using delete, see Data#remove
-					elem[ dataPriv.expando ] = undefined;
-				}
-				if ( elem[ dataUser.expando ] ) {
-
-					// Support: Chrome <=35 - 45+
-					// Assign undefined instead of using delete, see Data#remove
-					elem[ dataUser.expando ] = undefined;
-				}
-			}
-		}
-	}
-} );
-
-jQuery.fn.extend( {
-	detach: function( selector ) {
-		return remove( this, selector, true );
-	},
-
-	remove: function( selector ) {
-		return remove( this, selector );
-	},
-
-	text: function( value ) {
-		return access( this, function( value ) {
-			return value === undefined ?
-				jQuery.text( this ) :
-				this.empty().each( function() {
-					if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
-						this.textContent = value;
-					}
-				} );
-		}, null, value, arguments.length );
-	},
-
-	append: function() {
-		return domManip( this, arguments, function( elem ) {
-			if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
-				var target = manipulationTarget( this, elem );
-				target.appendChild( elem );
-			}
-		} );
-	},
-
-	prepend: function() {
-		return domManip( this, arguments, function( elem ) {
-			if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
-				var target = manipulationTarget( this, elem );
-				target.insertBefore( elem, target.firstChild );
-			}
-		} );
-	},
-
-	before: function() {
-		return domManip( this, arguments, function( elem ) {
-			if ( this.parentNode ) {
-				this.parentNode.insertBefore( elem, this );
-			}
-		} );
-	},
-
-	after: function() {
-		return domManip( this, arguments, function( elem ) {
-			if ( this.parentNode ) {
-				this.parentNode.insertBefore( elem, this.nextSibling );
-			}
-		} );
-	},
-
-	empty: function() {
-		var elem,
-			i = 0;
-
-		for ( ; ( elem = this[ i ] ) != null; i++ ) {
-			if ( elem.nodeType === 1 ) {
-
-				// Prevent memory leaks
-				jQuery.cleanData( getAll( elem, false ) );
-
-				// Remove any remaining nodes
-				elem.textContent = "";
-			}
-		}
-
-		return this;
-	},
-
-	clone: function( dataAndEvents, deepDataAndEvents ) {
-		dataAndEvents = dataAndEvents == null ? false : dataAndEvents;
-		deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents;
-
-		return this.map( function() {
-			return jQuery.clone( this, dataAndEvents, deepDataAndEvents );
-		} );
-	},
-
-	html: function( value ) {
-		return access( this, function( value ) {
-			var elem = this[ 0 ] || {},
-				i = 0,
-				l = this.length;
-
-			if ( value === undefined && elem.nodeType === 1 ) {
-				return elem.innerHTML;
-			}
-
-			// See if we can take a shortcut and just use innerHTML
-			if ( typeof value === "string" && !rnoInnerhtml.test( value ) &&
-				!wrapMap[ ( rtagName.exec( value ) || [ "", "" ] )[ 1 ].toLowerCase() ] ) {
-
-				value = jQuery.htmlPrefilter( value );
-
-				try {
-					for ( ; i < l; i++ ) {
-						elem = this[ i ] || {};
-
-						// Remove element nodes and prevent memory leaks
-						if ( elem.nodeType === 1 ) {
-							jQuery.cleanData( getAll( elem, false ) );
-							elem.innerHTML = value;
-						}
-					}
-
-					elem = 0;
-
-				// If using innerHTML throws an exception, use the fallback method
-				} catch ( e ) {}
-			}
-
-			if ( elem ) {
-				this.empty().append( value );
-			}
-		}, null, value, arguments.length );
-	},
-
-	replaceWith: function() {
-		var ignored = [];
-
-		// Make the changes, replacing each non-ignored context element with the new content
-		return domManip( this, arguments, function( elem ) {
-			var parent = this.parentNode;
-
-			if ( jQuery.inArray( this, ignored ) < 0 ) {
-				jQuery.cleanData( getAll( this ) );
-				if ( parent ) {
-					parent.replaceChild( elem, this );
-				}
-			}
-
-		// Force callback invocation
-		}, ignored );
-	}
-} );
-
-jQuery.each( {
-	appendTo: "append",
-	prependTo: "prepend",
-	insertBefore: "before",
-	insertAfter: "after",
-	replaceAll: "replaceWith"
-}, function( name, original ) {
-	jQuery.fn[ name ] = function( selector ) {
-		var elems,
-			ret = [],
-			insert = jQuery( selector ),
-			last = insert.length - 1,
-			i = 0;
-
-		for ( ; i <= last; i++ ) {
-			elems = i === last ? this : this.clone( true );
-			jQuery( insert[ i ] )[ original ]( elems );
-
-			// Support: Android <=4.0 only, PhantomJS 1 only
-			// .get() because push.apply(_, arraylike) throws on ancient WebKit
-			push.apply( ret, elems.get() );
-		}
-
-		return this.pushStack( ret );
-	};
-} );
-var rnumnonpx = new RegExp( "^(" + pnum + ")(?!px)[a-z%]+$", "i" );
-
-var getStyles = function( elem ) {
-
-		// Support: IE <=11 only, Firefox <=30 (#15098, #14150)
-		// IE throws on elements created in popups
-		// FF meanwhile throws on frame elements through "defaultView.getComputedStyle"
-		var view = elem.ownerDocument.defaultView;
-
-		if ( !view || !view.opener ) {
-			view = window;
-		}
-
-		return view.getComputedStyle( elem );
-	};
-
-var swap = function( elem, options, callback ) {
-	var ret, name,
-		old = {};
-
-	// Remember the old values, and insert the new ones
-	for ( name in options ) {
-		old[ name ] = elem.style[ name ];
-		elem.style[ name ] = options[ name ];
-	}
-
-	ret = callback.call( elem );
-
-	// Revert the old values
-	for ( name in options ) {
-		elem.style[ name ] = old[ name ];
-	}
-
-	return ret;
-};
-
-
-var rboxStyle = new RegExp( cssExpand.join( "|" ), "i" );
-
-
-
-( function() {
-
-	// Executing both pixelPosition & boxSizingReliable tests require only one layout
-	// so they're executed at the same time to save the second computation.
-	function computeStyleTests() {
-
-		// This is a singleton, we need to execute it only once
-		if ( !div ) {
-			return;
-		}
-
-		container.style.cssText = "position:absolute;left:-11111px;width:60px;" +
-			"margin-top:1px;padding:0;border:0";
-		div.style.cssText =
-			"position:relative;display:block;box-sizing:border-box;overflow:scroll;" +
-			"margin:auto;border:1px;padding:1px;" +
-			"width:60%;top:1%";
-		documentElement.appendChild( container ).appendChild( div );
-
-		var divStyle = window.getComputedStyle( div );
-		pixelPositionVal = divStyle.top !== "1%";
-
-		// Support: Android 4.0 - 4.3 only, Firefox <=3 - 44
-		reliableMarginLeftVal = roundPixelMeasures( divStyle.marginLeft ) === 12;
-
-		// Support: Android 4.0 - 4.3 only, Safari <=9.1 - 10.1, iOS <=7.0 - 9.3
-		// Some styles come back with percentage values, even though they shouldn't
-		div.style.right = "60%";
-		pixelBoxStylesVal = roundPixelMeasures( divStyle.right ) === 36;
-
-		// Support: IE 9 - 11 only
-		// Detect misreporting of content dimensions for box-sizing:border-box elements
-		boxSizingReliableVal = roundPixelMeasures( divStyle.width ) === 36;
-
-		// Support: IE 9 only
-		// Detect overflow:scroll screwiness (gh-3699)
-		// Support: Chrome <=64
-		// Don't get tricked when zoom affects offsetWidth (gh-4029)
-		div.style.position = "absolute";
-		scrollboxSizeVal = roundPixelMeasures( div.offsetWidth / 3 ) === 12;
-
-		documentElement.removeChild( container );
-
-		// Nullify the div so it wouldn't be stored in the memory and
-		// it will also be a sign that checks already performed
-		div = null;
-	}
-
-	function roundPixelMeasures( measure ) {
-		return Math.round( parseFloat( measure ) );
-	}
-
-	var pixelPositionVal, boxSizingReliableVal, scrollboxSizeVal, pixelBoxStylesVal,
-		reliableTrDimensionsVal, reliableMarginLeftVal,
-		container = document.createElement( "div" ),
-		div = document.createElement( "div" );
-
-	// Finish early in limited (non-browser) environments
-	if ( !div.style ) {
-		return;
-	}
-
-	// Support: IE <=9 - 11 only
-	// Style of cloned element affects source element cloned (#8908)
-	div.style.backgroundClip = "content-box";
-	div.cloneNode( true ).style.backgroundClip = "";
-	support.clearCloneStyle = div.style.backgroundClip === "content-box";
-
-	jQuery.extend( support, {
-		boxSizingReliable: function() {
-			computeStyleTests();
-			return boxSizingReliableVal;
-		},
-		pixelBoxStyles: function() {
-			computeStyleTests();
-			return pixelBoxStylesVal;
-		},
-		pixelPosition: function() {
-			computeStyleTests();
-			return pixelPositionVal;
-		},
-		reliableMarginLeft: function() {
-			computeStyleTests();
-			return reliableMarginLeftVal;
-		},
-		scrollboxSize: function() {
-			computeStyleTests();
-			return scrollboxSizeVal;
-		},
-
-		// Support: IE 9 - 11+, Edge 15 - 18+
-		// IE/Edge misreport `getComputedStyle` of table rows with width/height
-		// set in CSS while `offset*` properties report correct values.
-		// Behavior in IE 9 is more subtle than in newer versions & it passes
-		// some versions of this test; make sure not to make it pass there!
-		reliableTrDimensions: function() {
-			var table, tr, trChild, trStyle;
-			if ( reliableTrDimensionsVal == null ) {
-				table = document.createElement( "table" );
-				tr = document.createElement( "tr" );
-				trChild = document.createElement( "div" );
-
-				table.style.cssText = "position:absolute;left:-11111px";
-				tr.style.height = "1px";
-				trChild.style.height = "9px";
-
-				documentElement
-					.appendChild( table )
-					.appendChild( tr )
-					.appendChild( trChild );
-
-				trStyle = window.getComputedStyle( tr );
-				reliableTrDimensionsVal = parseInt( trStyle.height ) > 3;
-
-				documentElement.removeChild( table );
-			}
-			return reliableTrDimensionsVal;
-		}
-	} );
-} )();
-
-
-function curCSS( elem, name, computed ) {
-	var width, minWidth, maxWidth, ret,
-
-		// Support: Firefox 51+
-		// Retrieving style before computed somehow
-		// fixes an issue with getting wrong values
-		// on detached elements
-		style = elem.style;
-
-	computed = computed || getStyles( elem );
-
-	// getPropertyValue is needed for:
-	//   .css('filter') (IE 9 only, #12537)
-	//   .css('--customProperty) (#3144)
-	if ( computed ) {
-		ret = computed.getPropertyValue( name ) || computed[ name ];
-
-		if ( ret === "" && !isAttached( elem ) ) {
-			ret = jQuery.style( elem, name );
-		}
-
-		// A tribute to the "awesome hack by Dean Edwards"
-		// Android Browser returns percentage for some values,
-		// but width seems to be reliably pixels.
-		// This is against the CSSOM draft spec:
-		// https://drafts.csswg.org/cssom/#resolved-values
-		if ( !support.pixelBoxStyles() && rnumnonpx.test( ret ) && rboxStyle.test( name ) ) {
-
-			// Remember the original values
-			width = style.width;
-			minWidth = style.minWidth;
-			maxWidth = style.maxWidth;
-
-			// Put in the new values to get a computed value out
-			style.minWidth = style.maxWidth = style.width = ret;
-			ret = computed.width;
-
-			// Revert the changed values
-			style.width = width;
-			style.minWidth = minWidth;
-			style.maxWidth = maxWidth;
-		}
-	}
-
-	return ret !== undefined ?
-
-		// Support: IE <=9 - 11 only
-		// IE returns zIndex value as an integer.
-		ret + "" :
-		ret;
-}
-
-
-function addGetHookIf( conditionFn, hookFn ) {
-
-	// Define the hook, we'll check on the first run if it's really needed.
-	return {
-		get: function() {
-			if ( conditionFn() ) {
-
-				// Hook not needed (or it's not possible to use it due
-				// to missing dependency), remove it.
-				delete this.get;
-				return;
-			}
-
-			// Hook needed; redefine it so that the support test is not executed again.
-			return ( this.get = hookFn ).apply( this, arguments );
-		}
-	};
-}
-
-
-var cssPrefixes = [ "Webkit", "Moz", "ms" ],
-	emptyStyle = document.createElement( "div" ).style,
-	vendorProps = {};
-
-// Return a vendor-prefixed property or undefined
-function vendorPropName( name ) {
-
-	// Check for vendor prefixed names
-	var capName = name[ 0 ].toUpperCase() + name.slice( 1 ),
-		i = cssPrefixes.length;
-
-	while ( i-- ) {
-		name = cssPrefixes[ i ] + capName;
-		if ( name in emptyStyle ) {
-			return name;
-		}
-	}
-}
-
-// Return a potentially-mapped jQuery.cssProps or vendor prefixed property
-function finalPropName( name ) {
-	var final = jQuery.cssProps[ name ] || vendorProps[ name ];
-
-	if ( final ) {
-		return final;
-	}
-	if ( name in emptyStyle ) {
-		return name;
-	}
-	return vendorProps[ name ] = vendorPropName( name ) || name;
-}
-
-
-var
-
-	// Swappable if display is none or starts with table
-	// except "table", "table-cell", or "table-caption"
-	// See here for display values: https://developer.mozilla.org/en-US/docs/CSS/display
-	rdisplayswap = /^(none|table(?!-c[ea]).+)/,
-	rcustomProp = /^--/,
-	cssShow = { position: "absolute", visibility: "hidden", display: "block" },
-	cssNormalTransform = {
-		letterSpacing: "0",
-		fontWeight: "400"
-	};
-
-function setPositiveNumber( _elem, value, subtract ) {
-
-	// Any relative (+/-) values have already been
-	// normalized at this point
-	var matches = rcssNum.exec( value );
-	return matches ?
-
-		// Guard against undefined "subtract", e.g., when used as in cssHooks
-		Math.max( 0, matches[ 2 ] - ( subtract || 0 ) ) + ( matches[ 3 ] || "px" ) :
-		value;
-}
-
-function boxModelAdjustment( elem, dimension, box, isBorderBox, styles, computedVal ) {
-	var i = dimension === "width" ? 1 : 0,
-		extra = 0,
-		delta = 0;
-
-	// Adjustment may not be necessary
-	if ( box === ( isBorderBox ? "border" : "content" ) ) {
-		return 0;
-	}
-
-	for ( ; i < 4; i += 2 ) {
-
-		// Both box models exclude margin
-		if ( box === "margin" ) {
-			delta += jQuery.css( elem, box + cssExpand[ i ], true, styles );
-		}
-
-		// If we get here with a content-box, we're seeking "padding" or "border" or "margin"
-		if ( !isBorderBox ) {
-
-			// Add padding
-			delta += jQuery.css( elem, "padding" + cssExpand[ i ], true, styles );
-
-			// For "border" or "margin", add border
-			if ( box !== "padding" ) {
-				delta += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );
-
-			// But still keep track of it otherwise
-			} else {
-				extra += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );
-			}
-
-		// If we get here with a border-box (content + padding + border), we're seeking "content" or
-		// "padding" or "margin"
-		} else {
-
-			// For "content", subtract padding
-			if ( box === "content" ) {
-				delta -= jQuery.css( elem, "padding" + cssExpand[ i ], true, styles );
-			}
-
-			// For "content" or "padding", subtract border
-			if ( box !== "margin" ) {
-				delta -= jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );
-			}
-		}
-	}
-
-	// Account for positive content-box scroll gutter when requested by providing computedVal
-	if ( !isBorderBox && computedVal >= 0 ) {
-
-		// offsetWidth/offsetHeight is a rounded sum of content, padding, scroll gutter, and border
-		// Assuming integer scroll gutter, subtract the rest and round down
-		delta += Math.max( 0, Math.ceil(
-			elem[ "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ] -
-			computedVal -
-			delta -
-			extra -
-			0.5
-
-		// If offsetWidth/offsetHeight is unknown, then we can't determine content-box scroll gutter
-		// Use an explicit zero to avoid NaN (gh-3964)
-		) ) || 0;
-	}
-
-	return delta;
-}
-
-function getWidthOrHeight( elem, dimension, extra ) {
-
-	// Start with computed style
-	var styles = getStyles( elem ),
-
-		// To avoid forcing a reflow, only fetch boxSizing if we need it (gh-4322).
-		// Fake content-box until we know it's needed to know the true value.
-		boxSizingNeeded = !support.boxSizingReliable() || extra,
-		isBorderBox = boxSizingNeeded &&
-			jQuery.css( elem, "boxSizing", false, styles ) === "border-box",
-		valueIsBorderBox = isBorderBox,
-
-		val = curCSS( elem, dimension, styles ),
-		offsetProp = "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 );
-
-	// Support: Firefox <=54
-	// Return a confounding non-pixel value or feign ignorance, as appropriate.
-	if ( rnumnonpx.test( val ) ) {
-		if ( !extra ) {
-			return val;
-		}
-		val = "auto";
-	}
-
-
-	// Support: IE 9 - 11 only
-	// Use offsetWidth/offsetHeight for when box sizing is unreliable.
-	// In those cases, the computed value can be trusted to be border-box.
-	if ( ( !support.boxSizingReliable() && isBorderBox ||
-
-		// Support: IE 10 - 11+, Edge 15 - 18+
-		// IE/Edge misreport `getComputedStyle` of table rows with width/height
-		// set in CSS while `offset*` properties report correct values.
-		// Interestingly, in some cases IE 9 doesn't suffer from this issue.
-		!support.reliableTrDimensions() && nodeName( elem, "tr" ) ||
-
-		// Fall back to offsetWidth/offsetHeight when value is "auto"
-		// This happens for inline elements with no explicit setting (gh-3571)
-		val === "auto" ||
-
-		// Support: Android <=4.1 - 4.3 only
-		// Also use offsetWidth/offsetHeight for misreported inline dimensions (gh-3602)
-		!parseFloat( val ) && jQuery.css( elem, "display", false, styles ) === "inline" ) &&
-
-		// Make sure the element is visible & connected
-		elem.getClientRects().length ) {
-
-		isBorderBox = jQuery.css( elem, "boxSizing", false, styles ) === "border-box";
-
-		// Where available, offsetWidth/offsetHeight approximate border box dimensions.
-		// Where not available (e.g., SVG), assume unreliable box-sizing and interpret the
-		// retrieved value as a content box dimension.
-		valueIsBorderBox = offsetProp in elem;
-		if ( valueIsBorderBox ) {
-			val = elem[ offsetProp ];
-		}
-	}
-
-	// Normalize "" and auto
-	val = parseFloat( val ) || 0;
-
-	// Adjust for the element's box model
-	return ( val +
-		boxModelAdjustment(
-			elem,
-			dimension,
-			extra || ( isBorderBox ? "border" : "content" ),
-			valueIsBorderBox,
-			styles,
-
-			// Provide the current computed size to request scroll gutter calculation (gh-3589)
-			val
-		)
-	) + "px";
-}
-
-jQuery.extend( {
-
-	// Add in style property hooks for overriding the default
-	// behavior of getting and setting a style property
-	cssHooks: {
-		opacity: {
-			get: function( elem, computed ) {
-				if ( computed ) {
-
-					// We should always get a number back from opacity
-					var ret = curCSS( elem, "opacity" );
-					return ret === "" ? "1" : ret;
-				}
-			}
-		}
-	},
-
-	// Don't automatically add "px" to these possibly-unitless properties
-	cssNumber: {
-		"animationIterationCount": true,
-		"columnCount": true,
-		"fillOpacity": true,
-		"flexGrow": true,
-		"flexShrink": true,
-		"fontWeight": true,
-		"gridArea": true,
-		"gridColumn": true,
-		"gridColumnEnd": true,
-		"gridColumnStart": true,
-		"gridRow": true,
-		"gridRowEnd": true,
-		"gridRowStart": true,
-		"lineHeight": true,
-		"opacity": true,
-		"order": true,
-		"orphans": true,
-		"widows": true,
-		"zIndex": true,
-		"zoom": true
-	},
-
-	// Add in properties whose names you wish to fix before
-	// setting or getting the value
-	cssProps: {},
-
-	// Get and set the style property on a DOM Node
-	style: function( elem, name, value, extra ) {
-
-		// Don't set styles on text and comment nodes
-		if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) {
-			return;
-		}
-
-		// Make sure that we're working with the right name
-		var ret, type, hooks,
-			origName = camelCase( name ),
-			isCustomProp = rcustomProp.test( name ),
-			style = elem.style;
-
-		// Make sure that we're working with the right name. We don't
-		// want to query the value if it is a CSS custom property
-		// since they are user-defined.
-		if ( !isCustomProp ) {
-			name = finalPropName( origName );
-		}
-
-		// Gets hook for the prefixed version, then unprefixed version
-		hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];
-
-		// Check if we're setting a value
-		if ( value !== undefined ) {
-			type = typeof value;
-
-			// Convert "+=" or "-=" to relative numbers (#7345)
-			if ( type === "string" && ( ret = rcssNum.exec( value ) ) && ret[ 1 ] ) {
-				value = adjustCSS( elem, name, ret );
-
-				// Fixes bug #9237
-				type = "number";
-			}
-
-			// Make sure that null and NaN values aren't set (#7116)
-			if ( value == null || value !== value ) {
-				return;
-			}
-
-			// If a number was passed in, add the unit (except for certain CSS properties)
-			// The isCustomProp check can be removed in jQuery 4.0 when we only auto-append
-			// "px" to a few hardcoded values.
-			if ( type === "number" && !isCustomProp ) {
-				value += ret && ret[ 3 ] || ( jQuery.cssNumber[ origName ] ? "" : "px" );
-			}
-
-			// background-* props affect original clone's values
-			if ( !support.clearCloneStyle && value === "" && name.indexOf( "background" ) === 0 ) {
-				style[ name ] = "inherit";
-			}
-
-			// If a hook was provided, use that value, otherwise just set the specified value
-			if ( !hooks || !( "set" in hooks ) ||
-				( value = hooks.set( elem, value, extra ) ) !== undefined ) {
-
-				if ( isCustomProp ) {
-					style.setProperty( name, value );
-				} else {
-					style[ name ] = value;
-				}
-			}
-
-		} else {
-
-			// If a hook was provided get the non-computed value from there
-			if ( hooks && "get" in hooks &&
-				( ret = hooks.get( elem, false, extra ) ) !== undefined ) {
-
-				return ret;
-			}
-
-			// Otherwise just get the value from the style object
-			return style[ name ];
-		}
-	},
-
-	css: function( elem, name, extra, styles ) {
-		var val, num, hooks,
-			origName = camelCase( name ),
-			isCustomProp = rcustomProp.test( name );
-
-		// Make sure that we're working with the right name. We don't
-		// want to modify the value if it is a CSS custom property
-		// since they are user-defined.
-		if ( !isCustomProp ) {
-			name = finalPropName( origName );
-		}
-
-		// Try prefixed name followed by the unprefixed name
-		hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];
-
-		// If a hook was provided get the computed value from there
-		if ( hooks && "get" in hooks ) {
-			val = hooks.get( elem, true, extra );
-		}
-
-		// Otherwise, if a way to get the computed value exists, use that
-		if ( val === undefined ) {
-			val = curCSS( elem, name, styles );
-		}
-
-		// Convert "normal" to computed value
-		if ( val === "normal" && name in cssNormalTransform ) {
-			val = cssNormalTransform[ name ];
-		}
-
-		// Make numeric if forced or a qualifier was provided and val looks numeric
-		if ( extra === "" || extra ) {
-			num = parseFloat( val );
-			return extra === true || isFinite( num ) ? num || 0 : val;
-		}
-
-		return val;
-	}
-} );
-
-jQuery.each( [ "height", "width" ], function( _i, dimension ) {
-	jQuery.cssHooks[ dimension ] = {
-		get: function( elem, computed, extra ) {
-			if ( computed ) {
-
-				// Certain elements can have dimension info if we invisibly show them
-				// but it must have a current display style that would benefit
-				return rdisplayswap.test( jQuery.css( elem, "display" ) ) &&
-
-					// Support: Safari 8+
-					// Table columns in Safari have non-zero offsetWidth & zero
-					// getBoundingClientRect().width unless display is changed.
-					// Support: IE <=11 only
-					// Running getBoundingClientRect on a disconnected node
-					// in IE throws an error.
-					( !elem.getClientRects().length || !elem.getBoundingClientRect().width ) ?
-						swap( elem, cssShow, function() {
-							return getWidthOrHeight( elem, dimension, extra );
-						} ) :
-						getWidthOrHeight( elem, dimension, extra );
-			}
-		},
-
-		set: function( elem, value, extra ) {
-			var matches,
-				styles = getStyles( elem ),
-
-				// Only read styles.position if the test has a chance to fail
-				// to avoid forcing a reflow.
-				scrollboxSizeBuggy = !support.scrollboxSize() &&
-					styles.position === "absolute",
-
-				// To avoid forcing a reflow, only fetch boxSizing if we need it (gh-3991)
-				boxSizingNeeded = scrollboxSizeBuggy || extra,
-				isBorderBox = boxSizingNeeded &&
-					jQuery.css( elem, "boxSizing", false, styles ) === "border-box",
-				subtract = extra ?
-					boxModelAdjustment(
-						elem,
-						dimension,
-						extra,
-						isBorderBox,
-						styles
-					) :
-					0;
-
-			// Account for unreliable border-box dimensions by comparing offset* to computed and
-			// faking a content-box to get border and padding (gh-3699)
-			if ( isBorderBox && scrollboxSizeBuggy ) {
-				subtract -= Math.ceil(
-					elem[ "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ] -
-					parseFloat( styles[ dimension ] ) -
-					boxModelAdjustment( elem, dimension, "border", false, styles ) -
-					0.5
-				);
-			}
-
-			// Convert to pixels if value adjustment is needed
-			if ( subtract && ( matches = rcssNum.exec( value ) ) &&
-				( matches[ 3 ] || "px" ) !== "px" ) {
-
-				elem.style[ dimension ] = value;
-				value = jQuery.css( elem, dimension );
-			}
-
-			return setPositiveNumber( elem, value, subtract );
-		}
-	};
-} );
-
-jQuery.cssHooks.marginLeft = addGetHookIf( support.reliableMarginLeft,
-	function( elem, computed ) {
-		if ( computed ) {
-			return ( parseFloat( curCSS( elem, "marginLeft" ) ) ||
-				elem.getBoundingClientRect().left -
-					swap( elem, { marginLeft: 0 }, function() {
-						return elem.getBoundingClientRect().left;
-					} )
-				) + "px";
-		}
-	}
-);
-
-// These hooks are used by animate to expand properties
-jQuery.each( {
-	margin: "",
-	padding: "",
-	border: "Width"
-}, function( prefix, suffix ) {
-	jQuery.cssHooks[ prefix + suffix ] = {
-		expand: function( value ) {
-			var i = 0,
-				expanded = {},
-
-				// Assumes a single number if not a string
-				parts = typeof value === "string" ? value.split( " " ) : [ value ];
-
-			for ( ; i < 4; i++ ) {
-				expanded[ prefix + cssExpand[ i ] + suffix ] =
-					parts[ i ] || parts[ i - 2 ] || parts[ 0 ];
-			}
-
-			return expanded;
-		}
-	};
-
-	if ( prefix !== "margin" ) {
-		jQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber;
-	}
-} );
-
-jQuery.fn.extend( {
-	css: function( name, value ) {
-		return access( this, function( elem, name, value ) {
-			var styles, len,
-				map = {},
-				i = 0;
-
-			if ( Array.isArray( name ) ) {
-				styles = getStyles( elem );
-				len = name.length;
-
-				for ( ; i < len; i++ ) {
-					map[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles );
-				}
-
-				return map;
-			}
-
-			return value !== undefined ?
-				jQuery.style( elem, name, value ) :
-				jQuery.css( elem, name );
-		}, name, value, arguments.length > 1 );
-	}
-} );
-
-
-function Tween( elem, options, prop, end, easing ) {
-	return new Tween.prototype.init( elem, options, prop, end, easing );
-}
-jQuery.Tween = Tween;
-
-Tween.prototype = {
-	constructor: Tween,
-	init: function( elem, options, prop, end, easing, unit ) {
-		this.elem = elem;
-		this.prop = prop;
-		this.easing = easing || jQuery.easing._default;
-		this.options = options;
-		this.start = this.now = this.cur();
-		this.end = end;
-		this.unit = unit || ( jQuery.cssNumber[ prop ] ? "" : "px" );
-	},
-	cur: function() {
-		var hooks = Tween.propHooks[ this.prop ];
-
-		return hooks && hooks.get ?
-			hooks.get( this ) :
-			Tween.propHooks._default.get( this );
-	},
-	run: function( percent ) {
-		var eased,
-			hooks = Tween.propHooks[ this.prop ];
-
-		if ( this.options.duration ) {
-			this.pos = eased = jQuery.easing[ this.easing ](
-				percent, this.options.duration * percent, 0, 1, this.options.duration
-			);
-		} else {
-			this.pos = eased = percent;
-		}
-		this.now = ( this.end - this.start ) * eased + this.start;
-
-		if ( this.options.step ) {
-			this.options.step.call( this.elem, this.now, this );
-		}
-
-		if ( hooks && hooks.set ) {
-			hooks.set( this );
-		} else {
-			Tween.propHooks._default.set( this );
-		}
-		return this;
-	}
-};
-
-Tween.prototype.init.prototype = Tween.prototype;
-
-Tween.propHooks = {
-	_default: {
-		get: function( tween ) {
-			var result;
-
-			// Use a property on the element directly when it is not a DOM element,
-			// or when there is no matching style property that exists.
-			if ( tween.elem.nodeType !== 1 ||
-				tween.elem[ tween.prop ] != null && tween.elem.style[ tween.prop ] == null ) {
-				return tween.elem[ tween.prop ];
-			}
-
-			// Passing an empty string as a 3rd parameter to .css will automatically
-			// attempt a parseFloat and fallback to a string if the parse fails.
-			// Simple values such as "10px" are parsed to Float;
-			// complex values such as "rotate(1rad)" are returned as-is.
-			result = jQuery.css( tween.elem, tween.prop, "" );
-
-			// Empty strings, null, undefined and "auto" are converted to 0.
-			return !result || result === "auto" ? 0 : result;
-		},
-		set: function( tween ) {
-
-			// Use step hook for back compat.
-			// Use cssHook if its there.
-			// Use .style if available and use plain properties where available.
-			if ( jQuery.fx.step[ tween.prop ] ) {
-				jQuery.fx.step[ tween.prop ]( tween );
-			} else if ( tween.elem.nodeType === 1 && (
-					jQuery.cssHooks[ tween.prop ] ||
-					tween.elem.style[ finalPropName( tween.prop ) ] != null ) ) {
-				jQuery.style( tween.elem, tween.prop, tween.now + tween.unit );
-			} else {
-				tween.elem[ tween.prop ] = tween.now;
-			}
-		}
-	}
-};
-
-// Support: IE <=9 only
-// Panic based approach to setting things on disconnected nodes
-Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = {
-	set: function( tween ) {
-		if ( tween.elem.nodeType && tween.elem.parentNode ) {
-			tween.elem[ tween.prop ] = tween.now;
-		}
-	}
-};
-
-jQuery.easing = {
-	linear: function( p ) {
-		return p;
-	},
-	swing: function( p ) {
-		return 0.5 - Math.cos( p * Math.PI ) / 2;
-	},
-	_default: "swing"
-};
-
-jQuery.fx = Tween.prototype.init;
-
-// Back compat <1.8 extension point
-jQuery.fx.step = {};
-
-
-
-
-var
-	fxNow, inProgress,
-	rfxtypes = /^(?:toggle|show|hide)$/,
-	rrun = /queueHooks$/;
-
-function schedule() {
-	if ( inProgress ) {
-		if ( document.hidden === false && window.requestAnimationFrame ) {
-			window.requestAnimationFrame( schedule );
-		} else {
-			window.setTimeout( schedule, jQuery.fx.interval );
-		}
-
-		jQuery.fx.tick();
-	}
-}
-
-// Animations created synchronously will run synchronously
-function createFxNow() {
-	window.setTimeout( function() {
-		fxNow = undefined;
-	} );
-	return ( fxNow = Date.now() );
-}
-
-// Generate parameters to create a standard animation
-function genFx( type, includeWidth ) {
-	var which,
-		i = 0,
-		attrs = { height: type };
-
-	// If we include width, step value is 1 to do all cssExpand values,
-	// otherwise step value is 2 to skip over Left and Right
-	includeWidth = includeWidth ? 1 : 0;
-	for ( ; i < 4; i += 2 - includeWidth ) {
-		which = cssExpand[ i ];
-		attrs[ "margin" + which ] = attrs[ "padding" + which ] = type;
-	}
-
-	if ( includeWidth ) {
-		attrs.opacity = attrs.width = type;
-	}
-
-	return attrs;
-}
-
-function createTween( value, prop, animation ) {
-	var tween,
-		collection = ( Animation.tweeners[ prop ] || [] ).concat( Animation.tweeners[ "*" ] ),
-		index = 0,
-		length = collection.length;
-	for ( ; index < length; index++ ) {
-		if ( ( tween = collection[ index ].call( animation, prop, value ) ) ) {
-
-			// We're done with this property
-			return tween;
-		}
-	}
-}
-
-function defaultPrefilter( elem, props, opts ) {
-	var prop, value, toggle, hooks, oldfire, propTween, restoreDisplay, display,
-		isBox = "width" in props || "height" in props,
-		anim = this,
-		orig = {},
-		style = elem.style,
-		hidden = elem.nodeType && isHiddenWithinTree( elem ),
-		dataShow = dataPriv.get( elem, "fxshow" );
-
-	// Queue-skipping animations hijack the fx hooks
-	if ( !opts.queue ) {
-		hooks = jQuery._queueHooks( elem, "fx" );
-		if ( hooks.unqueued == null ) {
-			hooks.unqueued = 0;
-			oldfire = hooks.empty.fire;
-			hooks.empty.fire = function() {
-				if ( !hooks.unqueued ) {
-					oldfire();
-				}
-			};
-		}
-		hooks.unqueued++;
-
-		anim.always( function() {
-
-			// Ensure the complete handler is called before this completes
-			anim.always( function() {
-				hooks.unqueued--;
-				if ( !jQuery.queue( elem, "fx" ).length ) {
-					hooks.empty.fire();
-				}
-			} );
-		} );
-	}
-
-	// Detect show/hide animations
-	for ( prop in props ) {
-		value = props[ prop ];
-		if ( rfxtypes.test( value ) ) {
-			delete props[ prop ];
-			toggle = toggle || value === "toggle";
-			if ( value === ( hidden ? "hide" : "show" ) ) {
-
-				// Pretend to be hidden if this is a "show" and
-				// there is still data from a stopped show/hide
-				if ( value === "show" && dataShow && dataShow[ prop ] !== undefined ) {
-					hidden = true;
-
-				// Ignore all other no-op show/hide data
-				} else {
-					continue;
-				}
-			}
-			orig[ prop ] = dataShow && dataShow[ prop ] || jQuery.style( elem, prop );
-		}
-	}
-
-	// Bail out if this is a no-op like .hide().hide()
-	propTween = !jQuery.isEmptyObject( props );
-	if ( !propTween && jQuery.isEmptyObject( orig ) ) {
-		return;
-	}
-
-	// Restrict "overflow" and "display" styles during box animations
-	if ( isBox && elem.nodeType === 1 ) {
-
-		// Support: IE <=9 - 11, Edge 12 - 15
-		// Record all 3 overflow attributes because IE does not infer the shorthand
-		// from identically-valued overflowX and overflowY and Edge just mirrors
-		// the overflowX value there.
-		opts.overflow = [ style.overflow, style.overflowX, style.overflowY ];
-
-		// Identify a display type, preferring old show/hide data over the CSS cascade
-		restoreDisplay = dataShow && dataShow.display;
-		if ( restoreDisplay == null ) {
-			restoreDisplay = dataPriv.get( elem, "display" );
-		}
-		display = jQuery.css( elem, "display" );
-		if ( display === "none" ) {
-			if ( restoreDisplay ) {
-				display = restoreDisplay;
-			} else {
-
-				// Get nonempty value(s) by temporarily forcing visibility
-				showHide( [ elem ], true );
-				restoreDisplay = elem.style.display || restoreDisplay;
-				display = jQuery.css( elem, "display" );
-				showHide( [ elem ] );
-			}
-		}
-
-		// Animate inline elements as inline-block
-		if ( display === "inline" || display === "inline-block" && restoreDisplay != null ) {
-			if ( jQuery.css( elem, "float" ) === "none" ) {
-
-				// Restore the original display value at the end of pure show/hide animations
-				if ( !propTween ) {
-					anim.done( function() {
-						style.display = restoreDisplay;
-					} );
-					if ( restoreDisplay == null ) {
-						display = style.display;
-						restoreDisplay = display === "none" ? "" : display;
-					}
-				}
-				style.display = "inline-block";
-			}
-		}
-	}
-
-	if ( opts.overflow ) {
-		style.overflow = "hidden";
-		anim.always( function() {
-			style.overflow = opts.overflow[ 0 ];
-			style.overflowX = opts.overflow[ 1 ];
-			style.overflowY = opts.overflow[ 2 ];
-		} );
-	}
-
-	// Implement show/hide animations
-	propTween = false;
-	for ( prop in orig ) {
-
-		// General show/hide setup for this element animation
-		if ( !propTween ) {
-			if ( dataShow ) {
-				if ( "hidden" in dataShow ) {
-					hidden = dataShow.hidden;
-				}
-			} else {
-				dataShow = dataPriv.access( elem, "fxshow", { display: restoreDisplay } );
-			}
-
-			// Store hidden/visible for toggle so `.stop().toggle()` "reverses"
-			if ( toggle ) {
-				dataShow.hidden = !hidden;
-			}
-
-			// Show elements before animating them
-			if ( hidden ) {
-				showHide( [ elem ], true );
-			}
-
-			/* eslint-disable no-loop-func */
-
-			anim.done( function() {
-
-			/* eslint-enable no-loop-func */
-
-				// The final step of a "hide" animation is actually hiding the element
-				if ( !hidden ) {
-					showHide( [ elem ] );
-				}
-				dataPriv.remove( elem, "fxshow" );
-				for ( prop in orig ) {
-					jQuery.style( elem, prop, orig[ prop ] );
-				}
-			} );
-		}
-
-		// Per-property setup
-		propTween = createTween( hidden ? dataShow[ prop ] : 0, prop, anim );
-		if ( !( prop in dataShow ) ) {
-			dataShow[ prop ] = propTween.start;
-			if ( hidden ) {
-				propTween.end = propTween.start;
-				propTween.start = 0;
-			}
-		}
-	}
-}
-
-function propFilter( props, specialEasing ) {
-	var index, name, easing, value, hooks;
-
-	// camelCase, specialEasing and expand cssHook pass
-	for ( index in props ) {
-		name = camelCase( index );
-		easing = specialEasing[ name ];
-		value = props[ index ];
-		if ( Array.isArray( value ) ) {
-			easing = value[ 1 ];
-			value = props[ index ] = value[ 0 ];
-		}
-
-		if ( index !== name ) {
-			props[ name ] = value;
-			delete props[ index ];
-		}
-
-		hooks = jQuery.cssHooks[ name ];
-		if ( hooks && "expand" in hooks ) {
-			value = hooks.expand( value );
-			delete props[ name ];
-
-			// Not quite $.extend, this won't overwrite existing keys.
-			// Reusing 'index' because we have the correct "name"
-			for ( index in value ) {
-				if ( !( index in props ) ) {
-					props[ index ] = value[ index ];
-					specialEasing[ index ] = easing;
-				}
-			}
-		} else {
-			specialEasing[ name ] = easing;
-		}
-	}
-}
-
-function Animation( elem, properties, options ) {
-	var result,
-		stopped,
-		index = 0,
-		length = Animation.prefilters.length,
-		deferred = jQuery.Deferred().always( function() {
-
-			// Don't match elem in the :animated selector
-			delete tick.elem;
-		} ),
-		tick = function() {
-			if ( stopped ) {
-				return false;
-			}
-			var currentTime = fxNow || createFxNow(),
-				remaining = Math.max( 0, animation.startTime + animation.duration - currentTime ),
-
-				// Support: Android 2.3 only
-				// Archaic crash bug won't allow us to use `1 - ( 0.5 || 0 )` (#12497)
-				temp = remaining / animation.duration || 0,
-				percent = 1 - temp,
-				index = 0,
-				length = animation.tweens.length;
-
-			for ( ; index < length; index++ ) {
-				animation.tweens[ index ].run( percent );
-			}
-
-			deferred.notifyWith( elem, [ animation, percent, remaining ] );
-
-			// If there's more to do, yield
-			if ( percent < 1 && length ) {
-				return remaining;
-			}
-
-			// If this was an empty animation, synthesize a final progress notification
-			if ( !length ) {
-				deferred.notifyWith( elem, [ animation, 1, 0 ] );
-			}
-
-			// Resolve the animation and report its conclusion
-			deferred.resolveWith( elem, [ animation ] );
-			return false;
-		},
-		animation = deferred.promise( {
-			elem: elem,
-			props: jQuery.extend( {}, properties ),
-			opts: jQuery.extend( true, {
-				specialEasing: {},
-				easing: jQuery.easing._default
-			}, options ),
-			originalProperties: properties,
-			originalOptions: options,
-			startTime: fxNow || createFxNow(),
-			duration: options.duration,
-			tweens: [],
-			createTween: function( prop, end ) {
-				var tween = jQuery.Tween( elem, animation.opts, prop, end,
-						animation.opts.specialEasing[ prop ] || animation.opts.easing );
-				animation.tweens.push( tween );
-				return tween;
-			},
-			stop: function( gotoEnd ) {
-				var index = 0,
-
-					// If we are going to the end, we want to run all the tweens
-					// otherwise we skip this part
-					length = gotoEnd ? animation.tweens.length : 0;
-				if ( stopped ) {
-					return this;
-				}
-				stopped = true;
-				for ( ; index < length; index++ ) {
-					animation.tweens[ index ].run( 1 );
-				}
-
-				// Resolve when we played the last frame; otherwise, reject
-				if ( gotoEnd ) {
-					deferred.notifyWith( elem, [ animation, 1, 0 ] );
-					deferred.resolveWith( elem, [ animation, gotoEnd ] );
-				} else {
-					deferred.rejectWith( elem, [ animation, gotoEnd ] );
-				}
-				return this;
-			}
-		} ),
-		props = animation.props;
-
-	propFilter( props, animation.opts.specialEasing );
-
-	for ( ; index < length; index++ ) {
-		result = Animation.prefilters[ index ].call( animation, elem, props, animation.opts );
-		if ( result ) {
-			if ( isFunction( result.stop ) ) {
-				jQuery._queueHooks( animation.elem, animation.opts.queue ).stop =
-					result.stop.bind( result );
-			}
-			return result;
-		}
-	}
-
-	jQuery.map( props, createTween, animation );
-
-	if ( isFunction( animation.opts.start ) ) {
-		animation.opts.start.call( elem, animation );
-	}
-
-	// Attach callbacks from options
-	animation
-		.progress( animation.opts.progress )
-		.done( animation.opts.done, animation.opts.complete )
-		.fail( animation.opts.fail )
-		.always( animation.opts.always );
-
-	jQuery.fx.timer(
-		jQuery.extend( tick, {
-			elem: elem,
-			anim: animation,
-			queue: animation.opts.queue
-		} )
-	);
-
-	return animation;
-}
-
-jQuery.Animation = jQuery.extend( Animation, {
-
-	tweeners: {
-		"*": [ function( prop, value ) {
-			var tween = this.createTween( prop, value );
-			adjustCSS( tween.elem, prop, rcssNum.exec( value ), tween );
-			return tween;
-		} ]
-	},
-
-	tweener: function( props, callback ) {
-		if ( isFunction( props ) ) {
-			callback = props;
-			props = [ "*" ];
-		} else {
-			props = props.match( rnothtmlwhite );
-		}
-
-		var prop,
-			index = 0,
-			length = props.length;
-
-		for ( ; index < length; index++ ) {
-			prop = props[ index ];
-			Animation.tweeners[ prop ] = Animation.tweeners[ prop ] || [];
-			Animation.tweeners[ prop ].unshift( callback );
-		}
-	},
-
-	prefilters: [ defaultPrefilter ],
-
-	prefilter: function( callback, prepend ) {
-		if ( prepend ) {
-			Animation.prefilters.unshift( callback );
-		} else {
-			Animation.prefilters.push( callback );
-		}
-	}
-} );
-
-jQuery.speed = function( speed, easing, fn ) {
-	var opt = speed && typeof speed === "object" ? jQuery.extend( {}, speed ) : {
-		complete: fn || !fn && easing ||
-			isFunction( speed ) && speed,
-		duration: speed,
-		easing: fn && easing || easing && !isFunction( easing ) && easing
-	};
-
-	// Go to the end state if fx are off
-	if ( jQuery.fx.off ) {
-		opt.duration = 0;
-
-	} else {
-		if ( typeof opt.duration !== "number" ) {
-			if ( opt.duration in jQuery.fx.speeds ) {
-				opt.duration = jQuery.fx.speeds[ opt.duration ];
-
-			} else {
-				opt.duration = jQuery.fx.speeds._default;
-			}
-		}
-	}
-
-	// Normalize opt.queue - true/undefined/null -> "fx"
-	if ( opt.queue == null || opt.queue === true ) {
-		opt.queue = "fx";
-	}
-
-	// Queueing
-	opt.old = opt.complete;
-
-	opt.complete = function() {
-		if ( isFunction( opt.old ) ) {
-			opt.old.call( this );
-		}
-
-		if ( opt.queue ) {
-			jQuery.dequeue( this, opt.queue );
-		}
-	};
-
-	return opt;
-};
-
-jQuery.fn.extend( {
-	fadeTo: function( speed, to, easing, callback ) {
-
-		// Show any hidden elements after setting opacity to 0
-		return this.filter( isHiddenWithinTree ).css( "opacity", 0 ).show()
-
-			// Animate to the value specified
-			.end().animate( { opacity: to }, speed, easing, callback );
-	},
-	animate: function( prop, speed, easing, callback ) {
-		var empty = jQuery.isEmptyObject( prop ),
-			optall = jQuery.speed( speed, easing, callback ),
-			doAnimation = function() {
-
-				// Operate on a copy of prop so per-property easing won't be lost
-				var anim = Animation( this, jQuery.extend( {}, prop ), optall );
-
-				// Empty animations, or finishing resolves immediately
-				if ( empty || dataPriv.get( this, "finish" ) ) {
-					anim.stop( true );
-				}
-			};
-			doAnimation.finish = doAnimation;
-
-		return empty || optall.queue === false ?
-			this.each( doAnimation ) :
-			this.queue( optall.queue, doAnimation );
-	},
-	stop: function( type, clearQueue, gotoEnd ) {
-		var stopQueue = function( hooks ) {
-			var stop = hooks.stop;
-			delete hooks.stop;
-			stop( gotoEnd );
-		};
-
-		if ( typeof type !== "string" ) {
-			gotoEnd = clearQueue;
-			clearQueue = type;
-			type = undefined;
-		}
-		if ( clearQueue ) {
-			this.queue( type || "fx", [] );
-		}
-
-		return this.each( function() {
-			var dequeue = true,
-				index = type != null && type + "queueHooks",
-				timers = jQuery.timers,
-				data = dataPriv.get( this );
-
-			if ( index ) {
-				if ( data[ index ] && data[ index ].stop ) {
-					stopQueue( data[ index ] );
-				}
-			} else {
-				for ( index in data ) {
-					if ( data[ index ] && data[ index ].stop && rrun.test( index ) ) {
-						stopQueue( data[ index ] );
-					}
-				}
-			}
-
-			for ( index = timers.length; index--; ) {
-				if ( timers[ index ].elem === this &&
-					( type == null || timers[ index ].queue === type ) ) {
-
-					timers[ index ].anim.stop( gotoEnd );
-					dequeue = false;
-					timers.splice( index, 1 );
-				}
-			}
-
-			// Start the next in the queue if the last step wasn't forced.
-			// Timers currently will call their complete callbacks, which
-			// will dequeue but only if they were gotoEnd.
-			if ( dequeue || !gotoEnd ) {
-				jQuery.dequeue( this, type );
-			}
-		} );
-	},
-	finish: function( type ) {
-		if ( type !== false ) {
-			type = type || "fx";
-		}
-		return this.each( function() {
-			var index,
-				data = dataPriv.get( this ),
-				queue = data[ type + "queue" ],
-				hooks = data[ type + "queueHooks" ],
-				timers = jQuery.timers,
-				length = queue ? queue.length : 0;
-
-			// Enable finishing flag on private data
-			data.finish = true;
-
-			// Empty the queue first
-			jQuery.queue( this, type, [] );
-
-			if ( hooks && hooks.stop ) {
-				hooks.stop.call( this, true );
-			}
-
-			// Look for any active animations, and finish them
-			for ( index = timers.length; index--; ) {
-				if ( timers[ index ].elem === this && timers[ index ].queue === type ) {
-					timers[ index ].anim.stop( true );
-					timers.splice( index, 1 );
-				}
-			}
-
-			// Look for any animations in the old queue and finish them
-			for ( index = 0; index < length; index++ ) {
-				if ( queue[ index ] && queue[ index ].finish ) {
-					queue[ index ].finish.call( this );
-				}
-			}
-
-			// Turn off finishing flag
-			delete data.finish;
-		} );
-	}
-} );
-
-jQuery.each( [ "toggle", "show", "hide" ], function( _i, name ) {
-	var cssFn = jQuery.fn[ name ];
-	jQuery.fn[ name ] = function( speed, easing, callback ) {
-		return speed == null || typeof speed === "boolean" ?
-			cssFn.apply( this, arguments ) :
-			this.animate( genFx( name, true ), speed, easing, callback );
-	};
-} );
-
-// Generate shortcuts for custom animations
-jQuery.each( {
-	slideDown: genFx( "show" ),
-	slideUp: genFx( "hide" ),
-	slideToggle: genFx( "toggle" ),
-	fadeIn: { opacity: "show" },
-	fadeOut: { opacity: "hide" },
-	fadeToggle: { opacity: "toggle" }
-}, function( name, props ) {
-	jQuery.fn[ name ] = function( speed, easing, callback ) {
-		return this.animate( props, speed, easing, callback );
-	};
-} );
-
-jQuery.timers = [];
-jQuery.fx.tick = function() {
-	var timer,
-		i = 0,
-		timers = jQuery.timers;
-
-	fxNow = Date.now();
-
-	for ( ; i < timers.length; i++ ) {
-		timer = timers[ i ];
-
-		// Run the timer and safely remove it when done (allowing for external removal)
-		if ( !timer() && timers[ i ] === timer ) {
-			timers.splice( i--, 1 );
-		}
-	}
-
-	if ( !timers.length ) {
-		jQuery.fx.stop();
-	}
-	fxNow = undefined;
-};
-
-jQuery.fx.timer = function( timer ) {
-	jQuery.timers.push( timer );
-	jQuery.fx.start();
-};
-
-jQuery.fx.interval = 13;
-jQuery.fx.start = function() {
-	if ( inProgress ) {
-		return;
-	}
-
-	inProgress = true;
-	schedule();
-};
-
-jQuery.fx.stop = function() {
-	inProgress = null;
-};
-
-jQuery.fx.speeds = {
-	slow: 600,
-	fast: 200,
-
-	// Default speed
-	_default: 400
-};
-
-
-// Based off of the plugin by Clint Helfers, with permission.
-// https://web.archive.org/web/20100324014747/http://blindsignals.com/index.php/2009/07/jquery-delay/
-jQuery.fn.delay = function( time, type ) {
-	time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time;
-	type = type || "fx";
-
-	return this.queue( type, function( next, hooks ) {
-		var timeout = window.setTimeout( next, time );
-		hooks.stop = function() {
-			window.clearTimeout( timeout );
-		};
-	} );
-};
-
-
-( function() {
-	var input = document.createElement( "input" ),
-		select = document.createElement( "select" ),
-		opt = select.appendChild( document.createElement( "option" ) );
-
-	input.type = "checkbox";
-
-	// Support: Android <=4.3 only
-	// Default value for a checkbox should be "on"
-	support.checkOn = input.value !== "";
-
-	// Support: IE <=11 only
-	// Must access selectedIndex to make default options select
-	support.optSelected = opt.selected;
-
-	// Support: IE <=11 only
-	// An input loses its value after becoming a radio
-	input = document.createElement( "input" );
-	input.value = "t";
-	input.type = "radio";
-	support.radioValue = input.value === "t";
-} )();
-
-
-var boolHook,
-	attrHandle = jQuery.expr.attrHandle;
-
-jQuery.fn.extend( {
-	attr: function( name, value ) {
-		return access( this, jQuery.attr, name, value, arguments.length > 1 );
-	},
-
-	removeAttr: function( name ) {
-		return this.each( function() {
-			jQuery.removeAttr( this, name );
-		} );
-	}
-} );
-
-jQuery.extend( {
-	attr: function( elem, name, value ) {
-		var ret, hooks,
-			nType = elem.nodeType;
-
-		// Don't get/set attributes on text, comment and attribute nodes
-		if ( nType === 3 || nType === 8 || nType === 2 ) {
-			return;
-		}
-
-		// Fallback to prop when attributes are not supported
-		if ( typeof elem.getAttribute === "undefined" ) {
-			return jQuery.prop( elem, name, value );
-		}
-
-		// Attribute hooks are determined by the lowercase version
-		// Grab necessary hook if one is defined
-		if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {
-			hooks = jQuery.attrHooks[ name.toLowerCase() ] ||
-				( jQuery.expr.match.bool.test( name ) ? boolHook : undefined );
-		}
-
-		if ( value !== undefined ) {
-			if ( value === null ) {
-				jQuery.removeAttr( elem, name );
-				return;
-			}
-
-			if ( hooks && "set" in hooks &&
-				( ret = hooks.set( elem, value, name ) ) !== undefined ) {
-				return ret;
-			}
-
-			elem.setAttribute( name, value + "" );
-			return value;
-		}
-
-		if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) {
-			return ret;
-		}
-
-		ret = jQuery.find.attr( elem, name );
-
-		// Non-existent attributes return null, we normalize to undefined
-		return ret == null ? undefined : ret;
-	},
-
-	attrHooks: {
-		type: {
-			set: function( elem, value ) {
-				if ( !support.radioValue && value === "radio" &&
-					nodeName( elem, "input" ) ) {
-					var val = elem.value;
-					elem.setAttribute( "type", value );
-					if ( val ) {
-						elem.value = val;
-					}
-					return value;
-				}
-			}
-		}
-	},
-
-	removeAttr: function( elem, value ) {
-		var name,
-			i = 0,
-
-			// Attribute names can contain non-HTML whitespace characters
-			// https://html.spec.whatwg.org/multipage/syntax.html#attributes-2
-			attrNames = value && value.match( rnothtmlwhite );
-
-		if ( attrNames && elem.nodeType === 1 ) {
-			while ( ( name = attrNames[ i++ ] ) ) {
-				elem.removeAttribute( name );
-			}
-		}
-	}
-} );
-
-// Hooks for boolean attributes
-boolHook = {
-	set: function( elem, value, name ) {
-		if ( value === false ) {
-
-			// Remove boolean attributes when set to false
-			jQuery.removeAttr( elem, name );
-		} else {
-			elem.setAttribute( name, name );
-		}
-		return name;
-	}
-};
-
-jQuery.each( jQuery.expr.match.bool.source.match( /\w+/g ), function( _i, name ) {
-	var getter = attrHandle[ name ] || jQuery.find.attr;
-
-	attrHandle[ name ] = function( elem, name, isXML ) {
-		var ret, handle,
-			lowercaseName = name.toLowerCase();
-
-		if ( !isXML ) {
-
-			// Avoid an infinite loop by temporarily removing this function from the getter
-			handle = attrHandle[ lowercaseName ];
-			attrHandle[ lowercaseName ] = ret;
-			ret = getter( elem, name, isXML ) != null ?
-				lowercaseName :
-				null;
-			attrHandle[ lowercaseName ] = handle;
-		}
-		return ret;
-	};
-} );
-
-
-
-
-var rfocusable = /^(?:input|select|textarea|button)$/i,
-	rclickable = /^(?:a|area)$/i;
-
-jQuery.fn.extend( {
-	prop: function( name, value ) {
-		return access( this, jQuery.prop, name, value, arguments.length > 1 );
-	},
-
-	removeProp: function( name ) {
-		return this.each( function() {
-			delete this[ jQuery.propFix[ name ] || name ];
-		} );
-	}
-} );
-
-jQuery.extend( {
-	prop: function( elem, name, value ) {
-		var ret, hooks,
-			nType = elem.nodeType;
-
-		// Don't get/set properties on text, comment and attribute nodes
-		if ( nType === 3 || nType === 8 || nType === 2 ) {
-			return;
-		}
-
-		if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {
-
-			// Fix name and attach hooks
-			name = jQuery.propFix[ name ] || name;
-			hooks = jQuery.propHooks[ name ];
-		}
-
-		if ( value !== undefined ) {
-			if ( hooks && "set" in hooks &&
-				( ret = hooks.set( elem, value, name ) ) !== undefined ) {
-				return ret;
-			}
-
-			return ( elem[ name ] = value );
-		}
-
-		if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) {
-			return ret;
-		}
-
-		return elem[ name ];
-	},
-
-	propHooks: {
-		tabIndex: {
-			get: function( elem ) {
-
-				// Support: IE <=9 - 11 only
-				// elem.tabIndex doesn't always return the
-				// correct value when it hasn't been explicitly set
-				// https://web.archive.org/web/20141116233347/http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/
-				// Use proper attribute retrieval(#12072)
-				var tabindex = jQuery.find.attr( elem, "tabindex" );
-
-				if ( tabindex ) {
-					return parseInt( tabindex, 10 );
-				}
-
-				if (
-					rfocusable.test( elem.nodeName ) ||
-					rclickable.test( elem.nodeName ) &&
-					elem.href
-				) {
-					return 0;
-				}
-
-				return -1;
-			}
-		}
-	},
-
-	propFix: {
-		"for": "htmlFor",
-		"class": "className"
-	}
-} );
-
-// Support: IE <=11 only
-// Accessing the selectedIndex property
-// forces the browser to respect setting selected
-// on the option
-// The getter ensures a default option is selected
-// when in an optgroup
-// eslint rule "no-unused-expressions" is disabled for this code
-// since it considers such accessions noop
-if ( !support.optSelected ) {
-	jQuery.propHooks.selected = {
-		get: function( elem ) {
-
-			/* eslint no-unused-expressions: "off" */
-
-			var parent = elem.parentNode;
-			if ( parent && parent.parentNode ) {
-				parent.parentNode.selectedIndex;
-			}
-			return null;
-		},
-		set: function( elem ) {
-
-			/* eslint no-unused-expressions: "off" */
-
-			var parent = elem.parentNode;
-			if ( parent ) {
-				parent.selectedIndex;
-
-				if ( parent.parentNode ) {
-					parent.parentNode.selectedIndex;
-				}
-			}
-		}
-	};
-}
-
-jQuery.each( [
-	"tabIndex",
-	"readOnly",
-	"maxLength",
-	"cellSpacing",
-	"cellPadding",
-	"rowSpan",
-	"colSpan",
-	"useMap",
-	"frameBorder",
-	"contentEditable"
-], function() {
-	jQuery.propFix[ this.toLowerCase() ] = this;
-} );
-
-
-
-
-	// Strip and collapse whitespace according to HTML spec
-	// https://infra.spec.whatwg.org/#strip-and-collapse-ascii-whitespace
-	function stripAndCollapse( value ) {
-		var tokens = value.match( rnothtmlwhite ) || [];
-		return tokens.join( " " );
-	}
-
-
-function getClass( elem ) {
-	return elem.getAttribute && elem.getAttribute( "class" ) || "";
-}
-
-function classesToArray( value ) {
-	if ( Array.isArray( value ) ) {
-		return value;
-	}
-	if ( typeof value === "string" ) {
-		return value.match( rnothtmlwhite ) || [];
-	}
-	return [];
-}
-
-jQuery.fn.extend( {
-	addClass: function( value ) {
-		var classes, elem, cur, curValue, clazz, j, finalValue,
-			i = 0;
-
-		if ( isFunction( value ) ) {
-			return this.each( function( j ) {
-				jQuery( this ).addClass( value.call( this, j, getClass( this ) ) );
-			} );
-		}
-
-		classes = classesToArray( value );
-
-		if ( classes.length ) {
-			while ( ( elem = this[ i++ ] ) ) {
-				curValue = getClass( elem );
-				cur = elem.nodeType === 1 && ( " " + stripAndCollapse( curValue ) + " " );
-
-				if ( cur ) {
-					j = 0;
-					while ( ( clazz = classes[ j++ ] ) ) {
-						if ( cur.indexOf( " " + clazz + " " ) < 0 ) {
-							cur += clazz + " ";
-						}
-					}
-
-					// Only assign if different to avoid unneeded rendering.
-					finalValue = stripAndCollapse( cur );
-					if ( curValue !== finalValue ) {
-						elem.setAttribute( "class", finalValue );
-					}
-				}
-			}
-		}
-
-		return this;
-	},
-
-	removeClass: function( value ) {
-		var classes, elem, cur, curValue, clazz, j, finalValue,
-			i = 0;
-
-		if ( isFunction( value ) ) {
-			return this.each( function( j ) {
-				jQuery( this ).removeClass( value.call( this, j, getClass( this ) ) );
-			} );
-		}
-
-		if ( !arguments.length ) {
-			return this.attr( "class", "" );
-		}
-
-		classes = classesToArray( value );
-
-		if ( classes.length ) {
-			while ( ( elem = this[ i++ ] ) ) {
-				curValue = getClass( elem );
-
-				// This expression is here for better compressibility (see addClass)
-				cur = elem.nodeType === 1 && ( " " + stripAndCollapse( curValue ) + " " );
-
-				if ( cur ) {
-					j = 0;
-					while ( ( clazz = classes[ j++ ] ) ) {
-
-						// Remove *all* instances
-						while ( cur.indexOf( " " + clazz + " " ) > -1 ) {
-							cur = cur.replace( " " + clazz + " ", " " );
-						}
-					}
-
-					// Only assign if different to avoid unneeded rendering.
-					finalValue = stripAndCollapse( cur );
-					if ( curValue !== finalValue ) {
-						elem.setAttribute( "class", finalValue );
-					}
-				}
-			}
-		}
-
-		return this;
-	},
-
-	toggleClass: function( value, stateVal ) {
-		var type = typeof value,
-			isValidValue = type === "string" || Array.isArray( value );
-
-		if ( typeof stateVal === "boolean" && isValidValue ) {
-			return stateVal ? this.addClass( value ) : this.removeClass( value );
-		}
-
-		if ( isFunction( value ) ) {
-			return this.each( function( i ) {
-				jQuery( this ).toggleClass(
-					value.call( this, i, getClass( this ), stateVal ),
-					stateVal
-				);
-			} );
-		}
-
-		return this.each( function() {
-			var className, i, self, classNames;
-
-			if ( isValidValue ) {
-
-				// Toggle individual class names
-				i = 0;
-				self = jQuery( this );
-				classNames = classesToArray( value );
-
-				while ( ( className = classNames[ i++ ] ) ) {
-
-					// Check each className given, space separated list
-					if ( self.hasClass( className ) ) {
-						self.removeClass( className );
-					} else {
-						self.addClass( className );
-					}
-				}
-
-			// Toggle whole class name
-			} else if ( value === undefined || type === "boolean" ) {
-				className = getClass( this );
-				if ( className ) {
-
-					// Store className if set
-					dataPriv.set( this, "__className__", className );
-				}
-
-				// If the element has a class name or if we're passed `false`,
-				// then remove the whole classname (if there was one, the above saved it).
-				// Otherwise bring back whatever was previously saved (if anything),
-				// falling back to the empty string if nothing was stored.
-				if ( this.setAttribute ) {
-					this.setAttribute( "class",
-						className || value === false ?
-						"" :
-						dataPriv.get( this, "__className__" ) || ""
-					);
-				}
-			}
-		} );
-	},
-
-	hasClass: function( selector ) {
-		var className, elem,
-			i = 0;
-
-		className = " " + selector + " ";
-		while ( ( elem = this[ i++ ] ) ) {
-			if ( elem.nodeType === 1 &&
-				( " " + stripAndCollapse( getClass( elem ) ) + " " ).indexOf( className ) > -1 ) {
-					return true;
-			}
-		}
-
-		return false;
-	}
-} );
-
-
-
-
-var rreturn = /\r/g;
-
-jQuery.fn.extend( {
-	val: function( value ) {
-		var hooks, ret, valueIsFunction,
-			elem = this[ 0 ];
-
-		if ( !arguments.length ) {
-			if ( elem ) {
-				hooks = jQuery.valHooks[ elem.type ] ||
-					jQuery.valHooks[ elem.nodeName.toLowerCase() ];
-
-				if ( hooks &&
-					"get" in hooks &&
-					( ret = hooks.get( elem, "value" ) ) !== undefined
-				) {
-					return ret;
-				}
-
-				ret = elem.value;
-
-				// Handle most common string cases
-				if ( typeof ret === "string" ) {
-					return ret.replace( rreturn, "" );
-				}
-
-				// Handle cases where value is null/undef or number
-				return ret == null ? "" : ret;
-			}
-
-			return;
-		}
-
-		valueIsFunction = isFunction( value );
-
-		return this.each( function( i ) {
-			var val;
-
-			if ( this.nodeType !== 1 ) {
-				return;
-			}
-
-			if ( valueIsFunction ) {
-				val = value.call( this, i, jQuery( this ).val() );
-			} else {
-				val = value;
-			}
-
-			// Treat null/undefined as ""; convert numbers to string
-			if ( val == null ) {
-				val = "";
-
-			} else if ( typeof val === "number" ) {
-				val += "";
-
-			} else if ( Array.isArray( val ) ) {
-				val = jQuery.map( val, function( value ) {
-					return value == null ? "" : value + "";
-				} );
-			}
-
-			hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ];
-
-			// If set returns undefined, fall back to normal setting
-			if ( !hooks || !( "set" in hooks ) || hooks.set( this, val, "value" ) === undefined ) {
-				this.value = val;
-			}
-		} );
-	}
-} );
-
-jQuery.extend( {
-	valHooks: {
-		option: {
-			get: function( elem ) {
-
-				var val = jQuery.find.attr( elem, "value" );
-				return val != null ?
-					val :
-
-					// Support: IE <=10 - 11 only
-					// option.text throws exceptions (#14686, #14858)
-					// Strip and collapse whitespace
-					// https://html.spec.whatwg.org/#strip-and-collapse-whitespace
-					stripAndCollapse( jQuery.text( elem ) );
-			}
-		},
-		select: {
-			get: function( elem ) {
-				var value, option, i,
-					options = elem.options,
-					index = elem.selectedIndex,
-					one = elem.type === "select-one",
-					values = one ? null : [],
-					max = one ? index + 1 : options.length;
-
-				if ( index < 0 ) {
-					i = max;
-
-				} else {
-					i = one ? index : 0;
-				}
-
-				// Loop through all the selected options
-				for ( ; i < max; i++ ) {
-					option = options[ i ];
-
-					// Support: IE <=9 only
-					// IE8-9 doesn't update selected after form reset (#2551)
-					if ( ( option.selected || i === index ) &&
-
-							// Don't return options that are disabled or in a disabled optgroup
-							!option.disabled &&
-							( !option.parentNode.disabled ||
-								!nodeName( option.parentNode, "optgroup" ) ) ) {
-
-						// Get the specific value for the option
-						value = jQuery( option ).val();
-
-						// We don't need an array for one selects
-						if ( one ) {
-							return value;
-						}
-
-						// Multi-Selects return an array
-						values.push( value );
-					}
-				}
-
-				return values;
-			},
-
-			set: function( elem, value ) {
-				var optionSet, option,
-					options = elem.options,
-					values = jQuery.makeArray( value ),
-					i = options.length;
-
-				while ( i-- ) {
-					option = options[ i ];
-
-					/* eslint-disable no-cond-assign */
-
-					if ( option.selected =
-						jQuery.inArray( jQuery.valHooks.option.get( option ), values ) > -1
-					) {
-						optionSet = true;
-					}
-
-					/* eslint-enable no-cond-assign */
-				}
-
-				// Force browsers to behave consistently when non-matching value is set
-				if ( !optionSet ) {
-					elem.selectedIndex = -1;
-				}
-				return values;
-			}
-		}
-	}
-} );
-
-// Radios and checkboxes getter/setter
-jQuery.each( [ "radio", "checkbox" ], function() {
-	jQuery.valHooks[ this ] = {
-		set: function( elem, value ) {
-			if ( Array.isArray( value ) ) {
-				return ( elem.checked = jQuery.inArray( jQuery( elem ).val(), value ) > -1 );
-			}
-		}
-	};
-	if ( !support.checkOn ) {
-		jQuery.valHooks[ this ].get = function( elem ) {
-			return elem.getAttribute( "value" ) === null ? "on" : elem.value;
-		};
-	}
-} );
-
-
-
-
-// Return jQuery for attributes-only inclusion
-
-
-support.focusin = "onfocusin" in window;
-
-
-var rfocusMorph = /^(?:focusinfocus|focusoutblur)$/,
-	stopPropagationCallback = function( e ) {
-		e.stopPropagation();
-	};
-
-jQuery.extend( jQuery.event, {
-
-	trigger: function( event, data, elem, onlyHandlers ) {
-
-		var i, cur, tmp, bubbleType, ontype, handle, special, lastElement,
-			eventPath = [ elem || document ],
-			type = hasOwn.call( event, "type" ) ? event.type : event,
-			namespaces = hasOwn.call( event, "namespace" ) ? event.namespace.split( "." ) : [];
-
-		cur = lastElement = tmp = elem = elem || document;
-
-		// Don't do events on text and comment nodes
-		if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
-			return;
-		}
-
-		// focus/blur morphs to focusin/out; ensure we're not firing them right now
-		if ( rfocusMorph.test( type + jQuery.event.triggered ) ) {
-			return;
-		}
-
-		if ( type.indexOf( "." ) > -1 ) {
-
-			// Namespaced trigger; create a regexp to match event type in handle()
-			namespaces = type.split( "." );
-			type = namespaces.shift();
-			namespaces.sort();
-		}
-		ontype = type.indexOf( ":" ) < 0 && "on" + type;
-
-		// Caller can pass in a jQuery.Event object, Object, or just an event type string
-		event = event[ jQuery.expando ] ?
-			event :
-			new jQuery.Event( type, typeof event === "object" && event );
-
-		// Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true)
-		event.isTrigger = onlyHandlers ? 2 : 3;
-		event.namespace = namespaces.join( "." );
-		event.rnamespace = event.namespace ?
-			new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" ) :
-			null;
-
-		// Clean up the event in case it is being reused
-		event.result = undefined;
-		if ( !event.target ) {
-			event.target = elem;
-		}
-
-		// Clone any incoming data and prepend the event, creating the handler arg list
-		data = data == null ?
-			[ event ] :
-			jQuery.makeArray( data, [ event ] );
-
-		// Allow special events to draw outside the lines
-		special = jQuery.event.special[ type ] || {};
-		if ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) {
-			return;
-		}
-
-		// Determine event propagation path in advance, per W3C events spec (#9951)
-		// Bubble up to document, then to window; watch for a global ownerDocument var (#9724)
-		if ( !onlyHandlers && !special.noBubble && !isWindow( elem ) ) {
-
-			bubbleType = special.delegateType || type;
-			if ( !rfocusMorph.test( bubbleType + type ) ) {
-				cur = cur.parentNode;
-			}
-			for ( ; cur; cur = cur.parentNode ) {
-				eventPath.push( cur );
-				tmp = cur;
-			}
-
-			// Only add window if we got to document (e.g., not plain obj or detached DOM)
-			if ( tmp === ( elem.ownerDocument || document ) ) {
-				eventPath.push( tmp.defaultView || tmp.parentWindow || window );
-			}
-		}
-
-		// Fire handlers on the event path
-		i = 0;
-		while ( ( cur = eventPath[ i++ ] ) && !event.isPropagationStopped() ) {
-			lastElement = cur;
-			event.type = i > 1 ?
-				bubbleType :
-				special.bindType || type;
-
-			// jQuery handler
-			handle = (
-					dataPriv.get( cur, "events" ) || Object.create( null )
-				)[ event.type ] &&
-				dataPriv.get( cur, "handle" );
-			if ( handle ) {
-				handle.apply( cur, data );
-			}
-
-			// Native handler
-			handle = ontype && cur[ ontype ];
-			if ( handle && handle.apply && acceptData( cur ) ) {
-				event.result = handle.apply( cur, data );
-				if ( event.result === false ) {
-					event.preventDefault();
-				}
-			}
-		}
-		event.type = type;
-
-		// If nobody prevented the default action, do it now
-		if ( !onlyHandlers && !event.isDefaultPrevented() ) {
-
-			if ( ( !special._default ||
-				special._default.apply( eventPath.pop(), data ) === false ) &&
-				acceptData( elem ) ) {
-
-				// Call a native DOM method on the target with the same name as the event.
-				// Don't do default actions on window, that's where global variables be (#6170)
-				if ( ontype && isFunction( elem[ type ] ) && !isWindow( elem ) ) {
-
-					// Don't re-trigger an onFOO event when we call its FOO() method
-					tmp = elem[ ontype ];
-
-					if ( tmp ) {
-						elem[ ontype ] = null;
-					}
-
-					// Prevent re-triggering of the same event, since we already bubbled it above
-					jQuery.event.triggered = type;
-
-					if ( event.isPropagationStopped() ) {
-						lastElement.addEventListener( type, stopPropagationCallback );
-					}
-
-					elem[ type ]();
-
-					if ( event.isPropagationStopped() ) {
-						lastElement.removeEventListener( type, stopPropagationCallback );
-					}
-
-					jQuery.event.triggered = undefined;
-
-					if ( tmp ) {
-						elem[ ontype ] = tmp;
-					}
-				}
-			}
-		}
-
-		return event.result;
-	},
-
-	// Piggyback on a donor event to simulate a different one
-	// Used only for `focus(in | out)` events
-	simulate: function( type, elem, event ) {
-		var e = jQuery.extend(
-			new jQuery.Event(),
-			event,
-			{
-				type: type,
-				isSimulated: true
-			}
-		);
-
-		jQuery.event.trigger( e, null, elem );
-	}
-
-} );
-
-jQuery.fn.extend( {
-
-	trigger: function( type, data ) {
-		return this.each( function() {
-			jQuery.event.trigger( type, data, this );
-		} );
-	},
-	triggerHandler: function( type, data ) {
-		var elem = this[ 0 ];
-		if ( elem ) {
-			return jQuery.event.trigger( type, data, elem, true );
-		}
-	}
-} );
-
-
-// Support: Firefox <=44
-// Firefox doesn't have focus(in | out) events
-// Related ticket - https://bugzilla.mozilla.org/show_bug.cgi?id=687787
-//
-// Support: Chrome <=48 - 49, Safari <=9.0 - 9.1
-// focus(in | out) events fire after focus & blur events,
-// which is spec violation - http://www.w3.org/TR/DOM-Level-3-Events/#events-focusevent-event-order
-// Related ticket - https://bugs.chromium.org/p/chromium/issues/detail?id=449857
-if ( !support.focusin ) {
-	jQuery.each( { focus: "focusin", blur: "focusout" }, function( orig, fix ) {
-
-		// Attach a single capturing handler on the document while someone wants focusin/focusout
-		var handler = function( event ) {
-			jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ) );
-		};
-
-		jQuery.event.special[ fix ] = {
-			setup: function() {
-
-				// Handle: regular nodes (via `this.ownerDocument`), window
-				// (via `this.document`) & document (via `this`).
-				var doc = this.ownerDocument || this.document || this,
-					attaches = dataPriv.access( doc, fix );
-
-				if ( !attaches ) {
-					doc.addEventListener( orig, handler, true );
-				}
-				dataPriv.access( doc, fix, ( attaches || 0 ) + 1 );
-			},
-			teardown: function() {
-				var doc = this.ownerDocument || this.document || this,
-					attaches = dataPriv.access( doc, fix ) - 1;
-
-				if ( !attaches ) {
-					doc.removeEventListener( orig, handler, true );
-					dataPriv.remove( doc, fix );
-
-				} else {
-					dataPriv.access( doc, fix, attaches );
-				}
-			}
-		};
-	} );
-}
-var location = window.location;
-
-var nonce = { guid: Date.now() };
-
-var rquery = ( /\?/ );
-
-
-
-// Cross-browser xml parsing
-jQuery.parseXML = function( data ) {
-	var xml;
-	if ( !data || typeof data !== "string" ) {
-		return null;
-	}
-
-	// Support: IE 9 - 11 only
-	// IE throws on parseFromString with invalid input.
-	try {
-		xml = ( new window.DOMParser() ).parseFromString( data, "text/xml" );
-	} catch ( e ) {
-		xml = undefined;
-	}
-
-	if ( !xml || xml.getElementsByTagName( "parsererror" ).length ) {
-		jQuery.error( "Invalid XML: " + data );
-	}
-	return xml;
-};
-
-
-var
-	rbracket = /\[\]$/,
-	rCRLF = /\r?\n/g,
-	rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i,
-	rsubmittable = /^(?:input|select|textarea|keygen)/i;
-
-function buildParams( prefix, obj, traditional, add ) {
-	var name;
-
-	if ( Array.isArray( obj ) ) {
-
-		// Serialize array item.
-		jQuery.each( obj, function( i, v ) {
-			if ( traditional || rbracket.test( prefix ) ) {
-
-				// Treat each array item as a scalar.
-				add( prefix, v );
-
-			} else {
-
-				// Item is non-scalar (array or object), encode its numeric index.
-				buildParams(
-					prefix + "[" + ( typeof v === "object" && v != null ? i : "" ) + "]",
-					v,
-					traditional,
-					add
-				);
-			}
-		} );
-
-	} else if ( !traditional && toType( obj ) === "object" ) {
-
-		// Serialize object item.
-		for ( name in obj ) {
-			buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add );
-		}
-
-	} else {
-
-		// Serialize scalar item.
-		add( prefix, obj );
-	}
-}
-
-// Serialize an array of form elements or a set of
-// key/values into a query string
-jQuery.param = function( a, traditional ) {
-	var prefix,
-		s = [],
-		add = function( key, valueOrFunction ) {
-
-			// If value is a function, invoke it and use its return value
-			var value = isFunction( valueOrFunction ) ?
-				valueOrFunction() :
-				valueOrFunction;
-
-			s[ s.length ] = encodeURIComponent( key ) + "=" +
-				encodeURIComponent( value == null ? "" : value );
-		};
-
-	if ( a == null ) {
-		return "";
-	}
-
-	// If an array was passed in, assume that it is an array of form elements.
-	if ( Array.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) {
-
-		// Serialize the form elements
-		jQuery.each( a, function() {
-			add( this.name, this.value );
-		} );
-
-	} else {
-
-		// If traditional, encode the "old" way (the way 1.3.2 or older
-		// did it), otherwise encode params recursively.
-		for ( prefix in a ) {
-			buildParams( prefix, a[ prefix ], traditional, add );
-		}
-	}
-
-	// Return the resulting serialization
-	return s.join( "&" );
-};
-
-jQuery.fn.extend( {
-	serialize: function() {
-		return jQuery.param( this.serializeArray() );
-	},
-	serializeArray: function() {
-		return this.map( function() {
-
-			// Can add propHook for "elements" to filter or add form elements
-			var elements = jQuery.prop( this, "elements" );
-			return elements ? jQuery.makeArray( elements ) : this;
-		} )
-		.filter( function() {
-			var type = this.type;
-
-			// Use .is( ":disabled" ) so that fieldset[disabled] works
-			return this.name && !jQuery( this ).is( ":disabled" ) &&
-				rsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) &&
-				( this.checked || !rcheckableType.test( type ) );
-		} )
-		.map( function( _i, elem ) {
-			var val = jQuery( this ).val();
-
-			if ( val == null ) {
-				return null;
-			}
-
-			if ( Array.isArray( val ) ) {
-				return jQuery.map( val, function( val ) {
-					return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
-				} );
-			}
-
-			return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
-		} ).get();
-	}
-} );
-
-
-var
-	r20 = /%20/g,
-	rhash = /#.*$/,
-	rantiCache = /([?&])_=[^&]*/,
-	rheaders = /^(.*?):[ \t]*([^\r\n]*)$/mg,
-
-	// #7653, #8125, #8152: local protocol detection
-	rlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/,
-	rnoContent = /^(?:GET|HEAD)$/,
-	rprotocol = /^\/\//,
-
-	/* Prefilters
-	 * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example)
-	 * 2) These are called:
-	 *    - BEFORE asking for a transport
-	 *    - AFTER param serialization (s.data is a string if s.processData is true)
-	 * 3) key is the dataType
-	 * 4) the catchall symbol "*" can be used
-	 * 5) execution will start with transport dataType and THEN continue down to "*" if needed
-	 */
-	prefilters = {},
-
-	/* Transports bindings
-	 * 1) key is the dataType
-	 * 2) the catchall symbol "*" can be used
-	 * 3) selection will start with transport dataType and THEN go to "*" if needed
-	 */
-	transports = {},
-
-	// Avoid comment-prolog char sequence (#10098); must appease lint and evade compression
-	allTypes = "*/".concat( "*" ),
-
-	// Anchor tag for parsing the document origin
-	originAnchor = document.createElement( "a" );
-	originAnchor.href = location.href;
-
-// Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport
-function addToPrefiltersOrTransports( structure ) {
-
-	// dataTypeExpression is optional and defaults to "*"
-	return function( dataTypeExpression, func ) {
-
-		if ( typeof dataTypeExpression !== "string" ) {
-			func = dataTypeExpression;
-			dataTypeExpression = "*";
-		}
-
-		var dataType,
-			i = 0,
-			dataTypes = dataTypeExpression.toLowerCase().match( rnothtmlwhite ) || [];
-
-		if ( isFunction( func ) ) {
-
-			// For each dataType in the dataTypeExpression
-			while ( ( dataType = dataTypes[ i++ ] ) ) {
-
-				// Prepend if requested
-				if ( dataType[ 0 ] === "+" ) {
-					dataType = dataType.slice( 1 ) || "*";
-					( structure[ dataType ] = structure[ dataType ] || [] ).unshift( func );
-
-				// Otherwise append
-				} else {
-					( structure[ dataType ] = structure[ dataType ] || [] ).push( func );
-				}
-			}
-		}
-	};
-}
-
-// Base inspection function for prefilters and transports
-function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR ) {
-
-	var inspected = {},
-		seekingTransport = ( structure === transports );
-
-	function inspect( dataType ) {
-		var selected;
-		inspected[ dataType ] = true;
-		jQuery.each( structure[ dataType ] || [], function( _, prefilterOrFactory ) {
-			var dataTypeOrTransport = prefilterOrFactory( options, originalOptions, jqXHR );
-			if ( typeof dataTypeOrTransport === "string" &&
-				!seekingTransport && !inspected[ dataTypeOrTransport ] ) {
-
-				options.dataTypes.unshift( dataTypeOrTransport );
-				inspect( dataTypeOrTransport );
-				return false;
-			} else if ( seekingTransport ) {
-				return !( selected = dataTypeOrTransport );
-			}
-		} );
-		return selected;
-	}
-
-	return inspect( options.dataTypes[ 0 ] ) || !inspected[ "*" ] && inspect( "*" );
-}
-
-// A special extend for ajax options
-// that takes "flat" options (not to be deep extended)
-// Fixes #9887
-function ajaxExtend( target, src ) {
-	var key, deep,
-		flatOptions = jQuery.ajaxSettings.flatOptions || {};
-
-	for ( key in src ) {
-		if ( src[ key ] !== undefined ) {
-			( flatOptions[ key ] ? target : ( deep || ( deep = {} ) ) )[ key ] = src[ key ];
-		}
-	}
-	if ( deep ) {
-		jQuery.extend( true, target, deep );
-	}
-
-	return target;
-}
-
-/* Handles responses to an ajax request:
- * - finds the right dataType (mediates between content-type and expected dataType)
- * - returns the corresponding response
- */
-function ajaxHandleResponses( s, jqXHR, responses ) {
-
-	var ct, type, finalDataType, firstDataType,
-		contents = s.contents,
-		dataTypes = s.dataTypes;
-
-	// Remove auto dataType and get content-type in the process
-	while ( dataTypes[ 0 ] === "*" ) {
-		dataTypes.shift();
-		if ( ct === undefined ) {
-			ct = s.mimeType || jqXHR.getResponseHeader( "Content-Type" );
-		}
-	}
-
-	// Check if we're dealing with a known content-type
-	if ( ct ) {
-		for ( type in contents ) {
-			if ( contents[ type ] && contents[ type ].test( ct ) ) {
-				dataTypes.unshift( type );
-				break;
-			}
-		}
-	}
-
-	// Check to see if we have a response for the expected dataType
-	if ( dataTypes[ 0 ] in responses ) {
-		finalDataType = dataTypes[ 0 ];
-	} else {
-
-		// Try convertible dataTypes
-		for ( type in responses ) {
-			if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[ 0 ] ] ) {
-				finalDataType = type;
-				break;
-			}
-			if ( !firstDataType ) {
-				firstDataType = type;
-			}
-		}
-
-		// Or just use first one
-		finalDataType = finalDataType || firstDataType;
-	}
-
-	// If we found a dataType
-	// We add the dataType to the list if needed
-	// and return the corresponding response
-	if ( finalDataType ) {
-		if ( finalDataType !== dataTypes[ 0 ] ) {
-			dataTypes.unshift( finalDataType );
-		}
-		return responses[ finalDataType ];
-	}
-}
-
-/* Chain conversions given the request and the original response
- * Also sets the responseXXX fields on the jqXHR instance
- */
-function ajaxConvert( s, response, jqXHR, isSuccess ) {
-	var conv2, current, conv, tmp, prev,
-		converters = {},
-
-		// Work with a copy of dataTypes in case we need to modify it for conversion
-		dataTypes = s.dataTypes.slice();
-
-	// Create converters map with lowercased keys
-	if ( dataTypes[ 1 ] ) {
-		for ( conv in s.converters ) {
-			converters[ conv.toLowerCase() ] = s.converters[ conv ];
-		}
-	}
-
-	current = dataTypes.shift();
-
-	// Convert to each sequential dataType
-	while ( current ) {
-
-		if ( s.responseFields[ current ] ) {
-			jqXHR[ s.responseFields[ current ] ] = response;
-		}
-
-		// Apply the dataFilter if provided
-		if ( !prev && isSuccess && s.dataFilter ) {
-			response = s.dataFilter( response, s.dataType );
-		}
-
-		prev = current;
-		current = dataTypes.shift();
-
-		if ( current ) {
-
-			// There's only work to do if current dataType is non-auto
-			if ( current === "*" ) {
-
-				current = prev;
-
-			// Convert response if prev dataType is non-auto and differs from current
-			} else if ( prev !== "*" && prev !== current ) {
-
-				// Seek a direct converter
-				conv = converters[ prev + " " + current ] || converters[ "* " + current ];
-
-				// If none found, seek a pair
-				if ( !conv ) {
-					for ( conv2 in converters ) {
-
-						// If conv2 outputs current
-						tmp = conv2.split( " " );
-						if ( tmp[ 1 ] === current ) {
-
-							// If prev can be converted to accepted input
-							conv = converters[ prev + " " + tmp[ 0 ] ] ||
-								converters[ "* " + tmp[ 0 ] ];
-							if ( conv ) {
-
-								// Condense equivalence converters
-								if ( conv === true ) {
-									conv = converters[ conv2 ];
-
-								// Otherwise, insert the intermediate dataType
-								} else if ( converters[ conv2 ] !== true ) {
-									current = tmp[ 0 ];
-									dataTypes.unshift( tmp[ 1 ] );
-								}
-								break;
-							}
-						}
-					}
-				}
-
-				// Apply converter (if not an equivalence)
-				if ( conv !== true ) {
-
-					// Unless errors are allowed to bubble, catch and return them
-					if ( conv && s.throws ) {
-						response = conv( response );
-					} else {
-						try {
-							response = conv( response );
-						} catch ( e ) {
-							return {
-								state: "parsererror",
-								error: conv ? e : "No conversion from " + prev + " to " + current
-							};
-						}
-					}
-				}
-			}
-		}
-	}
-
-	return { state: "success", data: response };
-}
-
-jQuery.extend( {
-
-	// Counter for holding the number of active queries
-	active: 0,
-
-	// Last-Modified header cache for next request
-	lastModified: {},
-	etag: {},
-
-	ajaxSettings: {
-		url: location.href,
-		type: "GET",
-		isLocal: rlocalProtocol.test( location.protocol ),
-		global: true,
-		processData: true,
-		async: true,
-		contentType: "application/x-www-form-urlencoded; charset=UTF-8",
-
-		/*
-		timeout: 0,
-		data: null,
-		dataType: null,
-		username: null,
-		password: null,
-		cache: null,
-		throws: false,
-		traditional: false,
-		headers: {},
-		*/
-
-		accepts: {
-			"*": allTypes,
-			text: "text/plain",
-			html: "text/html",
-			xml: "application/xml, text/xml",
-			json: "application/json, text/javascript"
-		},
-
-		contents: {
-			xml: /\bxml\b/,
-			html: /\bhtml/,
-			json: /\bjson\b/
-		},
-
-		responseFields: {
-			xml: "responseXML",
-			text: "responseText",
-			json: "responseJSON"
-		},
-
-		// Data converters
-		// Keys separate source (or catchall "*") and destination types with a single space
-		converters: {
-
-			// Convert anything to text
-			"* text": String,
-
-			// Text to html (true = no transformation)
-			"text html": true,
-
-			// Evaluate text as a json expression
-			"text json": JSON.parse,
-
-			// Parse text as xml
-			"text xml": jQuery.parseXML
-		},
-
-		// For options that shouldn't be deep extended:
-		// you can add your own custom options here if
-		// and when you create one that shouldn't be
-		// deep extended (see ajaxExtend)
-		flatOptions: {
-			url: true,
-			context: true
-		}
-	},
-
-	// Creates a full fledged settings object into target
-	// with both ajaxSettings and settings fields.
-	// If target is omitted, writes into ajaxSettings.
-	ajaxSetup: function( target, settings ) {
-		return settings ?
-
-			// Building a settings object
-			ajaxExtend( ajaxExtend( target, jQuery.ajaxSettings ), settings ) :
-
-			// Extending ajaxSettings
-			ajaxExtend( jQuery.ajaxSettings, target );
-	},
-
-	ajaxPrefilter: addToPrefiltersOrTransports( prefilters ),
-	ajaxTransport: addToPrefiltersOrTransports( transports ),
-
-	// Main method
-	ajax: function( url, options ) {
-
-		// If url is an object, simulate pre-1.5 signature
-		if ( typeof url === "object" ) {
-			options = url;
-			url = undefined;
-		}
-
-		// Force options to be an object
-		options = options || {};
-
-		var transport,
-
-			// URL without anti-cache param
-			cacheURL,
-
-			// Response headers
-			responseHeadersString,
-			responseHeaders,
-
-			// timeout handle
-			timeoutTimer,
-
-			// Url cleanup var
-			urlAnchor,
-
-			// Request state (becomes false upon send and true upon completion)
-			completed,
-
-			// To know if global events are to be dispatched
-			fireGlobals,
-
-			// Loop variable
-			i,
-
-			// uncached part of the url
-			uncached,
-
-			// Create the final options object
-			s = jQuery.ajaxSetup( {}, options ),
-
-			// Callbacks context
-			callbackContext = s.context || s,
-
-			// Context for global events is callbackContext if it is a DOM node or jQuery collection
-			globalEventContext = s.context &&
-				( callbackContext.nodeType || callbackContext.jquery ) ?
-					jQuery( callbackContext ) :
-					jQuery.event,
-
-			// Deferreds
-			deferred = jQuery.Deferred(),
-			completeDeferred = jQuery.Callbacks( "once memory" ),
-
-			// Status-dependent callbacks
-			statusCode = s.statusCode || {},
-
-			// Headers (they are sent all at once)
-			requestHeaders = {},
-			requestHeadersNames = {},
-
-			// Default abort message
-			strAbort = "canceled",
-
-			// Fake xhr
-			jqXHR = {
-				readyState: 0,
-
-				// Builds headers hashtable if needed
-				getResponseHeader: function( key ) {
-					var match;
-					if ( completed ) {
-						if ( !responseHeaders ) {
-							responseHeaders = {};
-							while ( ( match = rheaders.exec( responseHeadersString ) ) ) {
-								responseHeaders[ match[ 1 ].toLowerCase() + " " ] =
-									( responseHeaders[ match[ 1 ].toLowerCase() + " " ] || [] )
-										.concat( match[ 2 ] );
-							}
-						}
-						match = responseHeaders[ key.toLowerCase() + " " ];
-					}
-					return match == null ? null : match.join( ", " );
-				},
-
-				// Raw string
-				getAllResponseHeaders: function() {
-					return completed ? responseHeadersString : null;
-				},
-
-				// Caches the header
-				setRequestHeader: function( name, value ) {
-					if ( completed == null ) {
-						name = requestHeadersNames[ name.toLowerCase() ] =
-							requestHeadersNames[ name.toLowerCase() ] || name;
-						requestHeaders[ name ] = value;
-					}
-					return this;
-				},
-
-				// Overrides response content-type header
-				overrideMimeType: function( type ) {
-					if ( completed == null ) {
-						s.mimeType = type;
-					}
-					return this;
-				},
-
-				// Status-dependent callbacks
-				statusCode: function( map ) {
-					var code;
-					if ( map ) {
-						if ( completed ) {
-
-							// Execute the appropriate callbacks
-							jqXHR.always( map[ jqXHR.status ] );
-						} else {
-
-							// Lazy-add the new callbacks in a way that preserves old ones
-							for ( code in map ) {
-								statusCode[ code ] = [ statusCode[ code ], map[ code ] ];
-							}
-						}
-					}
-					return this;
-				},
-
-				// Cancel the request
-				abort: function( statusText ) {
-					var finalText = statusText || strAbort;
-					if ( transport ) {
-						transport.abort( finalText );
-					}
-					done( 0, finalText );
-					return this;
-				}
-			};
-
-		// Attach deferreds
-		deferred.promise( jqXHR );
-
-		// Add protocol if not provided (prefilters might expect it)
-		// Handle falsy url in the settings object (#10093: consistency with old signature)
-		// We also use the url parameter if available
-		s.url = ( ( url || s.url || location.href ) + "" )
-			.replace( rprotocol, location.protocol + "//" );
-
-		// Alias method option to type as per ticket #12004
-		s.type = options.method || options.type || s.method || s.type;
-
-		// Extract dataTypes list
-		s.dataTypes = ( s.dataType || "*" ).toLowerCase().match( rnothtmlwhite ) || [ "" ];
-
-		// A cross-domain request is in order when the origin doesn't match the current origin.
-		if ( s.crossDomain == null ) {
-			urlAnchor = document.createElement( "a" );
-
-			// Support: IE <=8 - 11, Edge 12 - 15
-			// IE throws exception on accessing the href property if url is malformed,
-			// e.g. http://example.com:80x/
-			try {
-				urlAnchor.href = s.url;
-
-				// Support: IE <=8 - 11 only
-				// Anchor's host property isn't correctly set when s.url is relative
-				urlAnchor.href = urlAnchor.href;
-				s.crossDomain = originAnchor.protocol + "//" + originAnchor.host !==
-					urlAnchor.protocol + "//" + urlAnchor.host;
-			} catch ( e ) {
-
-				// If there is an error parsing the URL, assume it is crossDomain,
-				// it can be rejected by the transport if it is invalid
-				s.crossDomain = true;
-			}
-		}
-
-		// Convert data if not already a string
-		if ( s.data && s.processData && typeof s.data !== "string" ) {
-			s.data = jQuery.param( s.data, s.traditional );
-		}
-
-		// Apply prefilters
-		inspectPrefiltersOrTransports( prefilters, s, options, jqXHR );
-
-		// If request was aborted inside a prefilter, stop there
-		if ( completed ) {
-			return jqXHR;
-		}
-
-		// We can fire global events as of now if asked to
-		// Don't fire events if jQuery.event is undefined in an AMD-usage scenario (#15118)
-		fireGlobals = jQuery.event && s.global;
-
-		// Watch for a new set of requests
-		if ( fireGlobals && jQuery.active++ === 0 ) {
-			jQuery.event.trigger( "ajaxStart" );
-		}
-
-		// Uppercase the type
-		s.type = s.type.toUpperCase();
-
-		// Determine if request has content
-		s.hasContent = !rnoContent.test( s.type );
-
-		// Save the URL in case we're toying with the If-Modified-Since
-		// and/or If-None-Match header later on
-		// Remove hash to simplify url manipulation
-		cacheURL = s.url.replace( rhash, "" );
-
-		// More options handling for requests with no content
-		if ( !s.hasContent ) {
-
-			// Remember the hash so we can put it back
-			uncached = s.url.slice( cacheURL.length );
-
-			// If data is available and should be processed, append data to url
-			if ( s.data && ( s.processData || typeof s.data === "string" ) ) {
-				cacheURL += ( rquery.test( cacheURL ) ? "&" : "?" ) + s.data;
-
-				// #9682: remove data so that it's not used in an eventual retry
-				delete s.data;
-			}
-
-			// Add or update anti-cache param if needed
-			if ( s.cache === false ) {
-				cacheURL = cacheURL.replace( rantiCache, "$1" );
-				uncached = ( rquery.test( cacheURL ) ? "&" : "?" ) + "_=" + ( nonce.guid++ ) +
-					uncached;
-			}
-
-			// Put hash and anti-cache on the URL that will be requested (gh-1732)
-			s.url = cacheURL + uncached;
-
-		// Change '%20' to '+' if this is encoded form body content (gh-2658)
-		} else if ( s.data && s.processData &&
-			( s.contentType || "" ).indexOf( "application/x-www-form-urlencoded" ) === 0 ) {
-			s.data = s.data.replace( r20, "+" );
-		}
-
-		// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
-		if ( s.ifModified ) {
-			if ( jQuery.lastModified[ cacheURL ] ) {
-				jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ cacheURL ] );
-			}
-			if ( jQuery.etag[ cacheURL ] ) {
-				jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ cacheURL ] );
-			}
-		}
-
-		// Set the correct header, if data is being sent
-		if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) {
-			jqXHR.setRequestHeader( "Content-Type", s.contentType );
-		}
-
-		// Set the Accepts header for the server, depending on the dataType
-		jqXHR.setRequestHeader(
-			"Accept",
-			s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[ 0 ] ] ?
-				s.accepts[ s.dataTypes[ 0 ] ] +
-					( s.dataTypes[ 0 ] !== "*" ? ", " + allTypes + "; q=0.01" : "" ) :
-				s.accepts[ "*" ]
-		);
-
-		// Check for headers option
-		for ( i in s.headers ) {
-			jqXHR.setRequestHeader( i, s.headers[ i ] );
-		}
-
-		// Allow custom headers/mimetypes and early abort
-		if ( s.beforeSend &&
-			( s.beforeSend.call( callbackContext, jqXHR, s ) === false || completed ) ) {
-
-			// Abort if not done already and return
-			return jqXHR.abort();
-		}
-
-		// Aborting is no longer a cancellation
-		strAbort = "abort";
-
-		// Install callbacks on deferreds
-		completeDeferred.add( s.complete );
-		jqXHR.done( s.success );
-		jqXHR.fail( s.error );
-
-		// Get transport
-		transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR );
-
-		// If no transport, we auto-abort
-		if ( !transport ) {
-			done( -1, "No Transport" );
-		} else {
-			jqXHR.readyState = 1;
-
-			// Send global event
-			if ( fireGlobals ) {
-				globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] );
-			}
-
-			// If request was aborted inside ajaxSend, stop there
-			if ( completed ) {
-				return jqXHR;
-			}
-
-			// Timeout
-			if ( s.async && s.timeout > 0 ) {
-				timeoutTimer = window.setTimeout( function() {
-					jqXHR.abort( "timeout" );
-				}, s.timeout );
-			}
-
-			try {
-				completed = false;
-				transport.send( requestHeaders, done );
-			} catch ( e ) {
-
-				// Rethrow post-completion exceptions
-				if ( completed ) {
-					throw e;
-				}
-
-				// Propagate others as results
-				done( -1, e );
-			}
-		}
-
-		// Callback for when everything is done
-		function done( status, nativeStatusText, responses, headers ) {
-			var isSuccess, success, error, response, modified,
-				statusText = nativeStatusText;
-
-			// Ignore repeat invocations
-			if ( completed ) {
-				return;
-			}
-
-			completed = true;
-
-			// Clear timeout if it exists
-			if ( timeoutTimer ) {
-				window.clearTimeout( timeoutTimer );
-			}
-
-			// Dereference transport for early garbage collection
-			// (no matter how long the jqXHR object will be used)
-			transport = undefined;
-
-			// Cache response headers
-			responseHeadersString = headers || "";
-
-			// Set readyState
-			jqXHR.readyState = status > 0 ? 4 : 0;
-
-			// Determine if successful
-			isSuccess = status >= 200 && status < 300 || status === 304;
-
-			// Get response data
-			if ( responses ) {
-				response = ajaxHandleResponses( s, jqXHR, responses );
-			}
-
-			// Use a noop converter for missing script
-			if ( !isSuccess && jQuery.inArray( "script", s.dataTypes ) > -1 ) {
-				s.converters[ "text script" ] = function() {};
-			}
-
-			// Convert no matter what (that way responseXXX fields are always set)
-			response = ajaxConvert( s, response, jqXHR, isSuccess );
-
-			// If successful, handle type chaining
-			if ( isSuccess ) {
-
-				// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
-				if ( s.ifModified ) {
-					modified = jqXHR.getResponseHeader( "Last-Modified" );
-					if ( modified ) {
-						jQuery.lastModified[ cacheURL ] = modified;
-					}
-					modified = jqXHR.getResponseHeader( "etag" );
-					if ( modified ) {
-						jQuery.etag[ cacheURL ] = modified;
-					}
-				}
-
-				// if no content
-				if ( status === 204 || s.type === "HEAD" ) {
-					statusText = "nocontent";
-
-				// if not modified
-				} else if ( status === 304 ) {
-					statusText = "notmodified";
-
-				// If we have data, let's convert it
-				} else {
-					statusText = response.state;
-					success = response.data;
-					error = response.error;
-					isSuccess = !error;
-				}
-			} else {
-
-				// Extract error from statusText and normalize for non-aborts
-				error = statusText;
-				if ( status || !statusText ) {
-					statusText = "error";
-					if ( status < 0 ) {
-						status = 0;
-					}
-				}
-			}
-
-			// Set data for the fake xhr object
-			jqXHR.status = status;
-			jqXHR.statusText = ( nativeStatusText || statusText ) + "";
-
-			// Success/Error
-			if ( isSuccess ) {
-				deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] );
-			} else {
-				deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] );
-			}
-
-			// Status-dependent callbacks
-			jqXHR.statusCode( statusCode );
-			statusCode = undefined;
-
-			if ( fireGlobals ) {
-				globalEventContext.trigger( isSuccess ? "ajaxSuccess" : "ajaxError",
-					[ jqXHR, s, isSuccess ? success : error ] );
-			}
-
-			// Complete
-			completeDeferred.fireWith( callbackContext, [ jqXHR, statusText ] );
-
-			if ( fireGlobals ) {
-				globalEventContext.trigger( "ajaxComplete", [ jqXHR, s ] );
-
-				// Handle the global AJAX counter
-				if ( !( --jQuery.active ) ) {
-					jQuery.event.trigger( "ajaxStop" );
-				}
-			}
-		}
-
-		return jqXHR;
-	},
-
-	getJSON: function( url, data, callback ) {
-		return jQuery.get( url, data, callback, "json" );
-	},
-
-	getScript: function( url, callback ) {
-		return jQuery.get( url, undefined, callback, "script" );
-	}
-} );
-
-jQuery.each( [ "get", "post" ], function( _i, method ) {
-	jQuery[ method ] = function( url, data, callback, type ) {
-
-		// Shift arguments if data argument was omitted
-		if ( isFunction( data ) ) {
-			type = type || callback;
-			callback = data;
-			data = undefined;
-		}
-
-		// The url can be an options object (which then must have .url)
-		return jQuery.ajax( jQuery.extend( {
-			url: url,
-			type: method,
-			dataType: type,
-			data: data,
-			success: callback
-		}, jQuery.isPlainObject( url ) && url ) );
-	};
-} );
-
-jQuery.ajaxPrefilter( function( s ) {
-	var i;
-	for ( i in s.headers ) {
-		if ( i.toLowerCase() === "content-type" ) {
-			s.contentType = s.headers[ i ] || "";
-		}
-	}
-} );
-
-
-jQuery._evalUrl = function( url, options, doc ) {
-	return jQuery.ajax( {
-		url: url,
-
-		// Make this explicit, since user can override this through ajaxSetup (#11264)
-		type: "GET",
-		dataType: "script",
-		cache: true,
-		async: false,
-		global: false,
-
-		// Only evaluate the response if it is successful (gh-4126)
-		// dataFilter is not invoked for failure responses, so using it instead
-		// of the default converter is kludgy but it works.
-		converters: {
-			"text script": function() {}
-		},
-		dataFilter: function( response ) {
-			jQuery.globalEval( response, options, doc );
-		}
-	} );
-};
-
-
-jQuery.fn.extend( {
-	wrapAll: function( html ) {
-		var wrap;
-
-		if ( this[ 0 ] ) {
-			if ( isFunction( html ) ) {
-				html = html.call( this[ 0 ] );
-			}
-
-			// The elements to wrap the target around
-			wrap = jQuery( html, this[ 0 ].ownerDocument ).eq( 0 ).clone( true );
-
-			if ( this[ 0 ].parentNode ) {
-				wrap.insertBefore( this[ 0 ] );
-			}
-
-			wrap.map( function() {
-				var elem = this;
-
-				while ( elem.firstElementChild ) {
-					elem = elem.firstElementChild;
-				}
-
-				return elem;
-			} ).append( this );
-		}
-
-		return this;
-	},
-
-	wrapInner: function( html ) {
-		if ( isFunction( html ) ) {
-			return this.each( function( i ) {
-				jQuery( this ).wrapInner( html.call( this, i ) );
-			} );
-		}
-
-		return this.each( function() {
-			var self = jQuery( this ),
-				contents = self.contents();
-
-			if ( contents.length ) {
-				contents.wrapAll( html );
-
-			} else {
-				self.append( html );
-			}
-		} );
-	},
-
-	wrap: function( html ) {
-		var htmlIsFunction = isFunction( html );
-
-		return this.each( function( i ) {
-			jQuery( this ).wrapAll( htmlIsFunction ? html.call( this, i ) : html );
-		} );
-	},
-
-	unwrap: function( selector ) {
-		this.parent( selector ).not( "body" ).each( function() {
-			jQuery( this ).replaceWith( this.childNodes );
-		} );
-		return this;
-	}
-} );
-
-
-jQuery.expr.pseudos.hidden = function( elem ) {
-	return !jQuery.expr.pseudos.visible( elem );
-};
-jQuery.expr.pseudos.visible = function( elem ) {
-	return !!( elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length );
-};
-
-
-
-
-jQuery.ajaxSettings.xhr = function() {
-	try {
-		return new window.XMLHttpRequest();
-	} catch ( e ) {}
-};
-
-var xhrSuccessStatus = {
-
-		// File protocol always yields status code 0, assume 200
-		0: 200,
-
-		// Support: IE <=9 only
-		// #1450: sometimes IE returns 1223 when it should be 204
-		1223: 204
-	},
-	xhrSupported = jQuery.ajaxSettings.xhr();
-
-support.cors = !!xhrSupported && ( "withCredentials" in xhrSupported );
-support.ajax = xhrSupported = !!xhrSupported;
-
-jQuery.ajaxTransport( function( options ) {
-	var callback, errorCallback;
-
-	// Cross domain only allowed if supported through XMLHttpRequest
-	if ( support.cors || xhrSupported && !options.crossDomain ) {
-		return {
-			send: function( headers, complete ) {
-				var i,
-					xhr = options.xhr();
-
-				xhr.open(
-					options.type,
-					options.url,
-					options.async,
-					options.username,
-					options.password
-				);
-
-				// Apply custom fields if provided
-				if ( options.xhrFields ) {
-					for ( i in options.xhrFields ) {
-						xhr[ i ] = options.xhrFields[ i ];
-					}
-				}
-
-				// Override mime type if needed
-				if ( options.mimeType && xhr.overrideMimeType ) {
-					xhr.overrideMimeType( options.mimeType );
-				}
-
-				// X-Requested-With header
-				// For cross-domain requests, seeing as conditions for a preflight are
-				// akin to a jigsaw puzzle, we simply never set it to be sure.
-				// (it can always be set on a per-request basis or even using ajaxSetup)
-				// For same-domain requests, won't change header if already provided.
-				if ( !options.crossDomain && !headers[ "X-Requested-With" ] ) {
-					headers[ "X-Requested-With" ] = "XMLHttpRequest";
-				}
-
-				// Set headers
-				for ( i in headers ) {
-					xhr.setRequestHeader( i, headers[ i ] );
-				}
-
-				// Callback
-				callback = function( type ) {
-					return function() {
-						if ( callback ) {
-							callback = errorCallback = xhr.onload =
-								xhr.onerror = xhr.onabort = xhr.ontimeout =
-									xhr.onreadystatechange = null;
-
-							if ( type === "abort" ) {
-								xhr.abort();
-							} else if ( type === "error" ) {
-
-								// Support: IE <=9 only
-								// On a manual native abort, IE9 throws
-								// errors on any property access that is not readyState
-								if ( typeof xhr.status !== "number" ) {
-									complete( 0, "error" );
-								} else {
-									complete(
-
-										// File: protocol always yields status 0; see #8605, #14207
-										xhr.status,
-										xhr.statusText
-									);
-								}
-							} else {
-								complete(
-									xhrSuccessStatus[ xhr.status ] || xhr.status,
-									xhr.statusText,
-
-									// Support: IE <=9 only
-									// IE9 has no XHR2 but throws on binary (trac-11426)
-									// For XHR2 non-text, let the caller handle it (gh-2498)
-									( xhr.responseType || "text" ) !== "text"  ||
-									typeof xhr.responseText !== "string" ?
-										{ binary: xhr.response } :
-										{ text: xhr.responseText },
-									xhr.getAllResponseHeaders()
-								);
-							}
-						}
-					};
-				};
-
-				// Listen to events
-				xhr.onload = callback();
-				errorCallback = xhr.onerror = xhr.ontimeout = callback( "error" );
-
-				// Support: IE 9 only
-				// Use onreadystatechange to replace onabort
-				// to handle uncaught aborts
-				if ( xhr.onabort !== undefined ) {
-					xhr.onabort = errorCallback;
-				} else {
-					xhr.onreadystatechange = function() {
-
-						// Check readyState before timeout as it changes
-						if ( xhr.readyState === 4 ) {
-
-							// Allow onerror to be called first,
-							// but that will not handle a native abort
-							// Also, save errorCallback to a variable
-							// as xhr.onerror cannot be accessed
-							window.setTimeout( function() {
-								if ( callback ) {
-									errorCallback();
-								}
-							} );
-						}
-					};
-				}
-
-				// Create the abort callback
-				callback = callback( "abort" );
-
-				try {
-
-					// Do send the request (this may raise an exception)
-					xhr.send( options.hasContent && options.data || null );
-				} catch ( e ) {
-
-					// #14683: Only rethrow if this hasn't been notified as an error yet
-					if ( callback ) {
-						throw e;
-					}
-				}
-			},
-
-			abort: function() {
-				if ( callback ) {
-					callback();
-				}
-			}
-		};
-	}
-} );
-
-
-
-
-// Prevent auto-execution of scripts when no explicit dataType was provided (See gh-2432)
-jQuery.ajaxPrefilter( function( s ) {
-	if ( s.crossDomain ) {
-		s.contents.script = false;
-	}
-} );
-
-// Install script dataType
-jQuery.ajaxSetup( {
-	accepts: {
-		script: "text/javascript, application/javascript, " +
-			"application/ecmascript, application/x-ecmascript"
-	},
-	contents: {
-		script: /\b(?:java|ecma)script\b/
-	},
-	converters: {
-		"text script": function( text ) {
-			jQuery.globalEval( text );
-			return text;
-		}
-	}
-} );
-
-// Handle cache's special case and crossDomain
-jQuery.ajaxPrefilter( "script", function( s ) {
-	if ( s.cache === undefined ) {
-		s.cache = false;
-	}
-	if ( s.crossDomain ) {
-		s.type = "GET";
-	}
-} );
-
-// Bind script tag hack transport
-jQuery.ajaxTransport( "script", function( s ) {
-
-	// This transport only deals with cross domain or forced-by-attrs requests
-	if ( s.crossDomain || s.scriptAttrs ) {
-		var script, callback;
-		return {
-			send: function( _, complete ) {
-				script = jQuery( "<script>" )
-					.attr( s.scriptAttrs || {} )
-					.prop( { charset: s.scriptCharset, src: s.url } )
-					.on( "load error", callback = function( evt ) {
-						script.remove();
-						callback = null;
-						if ( evt ) {
-							complete( evt.type === "error" ? 404 : 200, evt.type );
-						}
-					} );
-
-				// Use native DOM manipulation to avoid our domManip AJAX trickery
-				document.head.appendChild( script[ 0 ] );
-			},
-			abort: function() {
-				if ( callback ) {
-					callback();
-				}
-			}
-		};
-	}
-} );
-
-
-
-
-var oldCallbacks = [],
-	rjsonp = /(=)\?(?=&|$)|\?\?/;
-
-// Default jsonp settings
-jQuery.ajaxSetup( {
-	jsonp: "callback",
-	jsonpCallback: function() {
-		var callback = oldCallbacks.pop() || ( jQuery.expando + "_" + ( nonce.guid++ ) );
-		this[ callback ] = true;
-		return callback;
-	}
-} );
-
-// Detect, normalize options and install callbacks for jsonp requests
-jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR ) {
-
-	var callbackName, overwritten, responseContainer,
-		jsonProp = s.jsonp !== false && ( rjsonp.test( s.url ) ?
-			"url" :
-			typeof s.data === "string" &&
-				( s.contentType || "" )
-					.indexOf( "application/x-www-form-urlencoded" ) === 0 &&
-				rjsonp.test( s.data ) && "data"
-		);
-
-	// Handle iff the expected data type is "jsonp" or we have a parameter to set
-	if ( jsonProp || s.dataTypes[ 0 ] === "jsonp" ) {
-
-		// Get callback name, remembering preexisting value associated with it
-		callbackName = s.jsonpCallback = isFunction( s.jsonpCallback ) ?
-			s.jsonpCallback() :
-			s.jsonpCallback;
-
-		// Insert callback into url or form data
-		if ( jsonProp ) {
-			s[ jsonProp ] = s[ jsonProp ].replace( rjsonp, "$1" + callbackName );
-		} else if ( s.jsonp !== false ) {
-			s.url += ( rquery.test( s.url ) ? "&" : "?" ) + s.jsonp + "=" + callbackName;
-		}
-
-		// Use data converter to retrieve json after script execution
-		s.converters[ "script json" ] = function() {
-			if ( !responseContainer ) {
-				jQuery.error( callbackName + " was not called" );
-			}
-			return responseContainer[ 0 ];
-		};
-
-		// Force json dataType
-		s.dataTypes[ 0 ] = "json";
-
-		// Install callback
-		overwritten = window[ callbackName ];
-		window[ callbackName ] = function() {
-			responseContainer = arguments;
-		};
-
-		// Clean-up function (fires after converters)
-		jqXHR.always( function() {
-
-			// If previous value didn't exist - remove it
-			if ( overwritten === undefined ) {
-				jQuery( window ).removeProp( callbackName );
-
-			// Otherwise restore preexisting value
-			} else {
-				window[ callbackName ] = overwritten;
-			}
-
-			// Save back as free
-			if ( s[ callbackName ] ) {
-
-				// Make sure that re-using the options doesn't screw things around
-				s.jsonpCallback = originalSettings.jsonpCallback;
-
-				// Save the callback name for future use
-				oldCallbacks.push( callbackName );
-			}
-
-			// Call if it was a function and we have a response
-			if ( responseContainer && isFunction( overwritten ) ) {
-				overwritten( responseContainer[ 0 ] );
-			}
-
-			responseContainer = overwritten = undefined;
-		} );
-
-		// Delegate to script
-		return "script";
-	}
-} );
-
-
-
-
-// Support: Safari 8 only
-// In Safari 8 documents created via document.implementation.createHTMLDocument
-// collapse sibling forms: the second one becomes a child of the first one.
-// Because of that, this security measure has to be disabled in Safari 8.
-// https://bugs.webkit.org/show_bug.cgi?id=137337
-support.createHTMLDocument = ( function() {
-	var body = document.implementation.createHTMLDocument( "" ).body;
-	body.innerHTML = "<form></form><form></form>";
-	return body.childNodes.length === 2;
-} )();
-
-
-// Argument "data" should be string of html
-// context (optional): If specified, the fragment will be created in this context,
-// defaults to document
-// keepScripts (optional): If true, will include scripts passed in the html string
-jQuery.parseHTML = function( data, context, keepScripts ) {
-	if ( typeof data !== "string" ) {
-		return [];
-	}
-	if ( typeof context === "boolean" ) {
-		keepScripts = context;
-		context = false;
-	}
-
-	var base, parsed, scripts;
-
-	if ( !context ) {
-
-		// Stop scripts or inline event handlers from being executed immediately
-		// by using document.implementation
-		if ( support.createHTMLDocument ) {
-			context = document.implementation.createHTMLDocument( "" );
-
-			// Set the base href for the created document
-			// so any parsed elements with URLs
-			// are based on the document's URL (gh-2965)
-			base = context.createElement( "base" );
-			base.href = document.location.href;
-			context.head.appendChild( base );
-		} else {
-			context = document;
-		}
-	}
-
-	parsed = rsingleTag.exec( data );
-	scripts = !keepScripts && [];
-
-	// Single tag
-	if ( parsed ) {
-		return [ context.createElement( parsed[ 1 ] ) ];
-	}
-
-	parsed = buildFragment( [ data ], context, scripts );
-
-	if ( scripts && scripts.length ) {
-		jQuery( scripts ).remove();
-	}
-
-	return jQuery.merge( [], parsed.childNodes );
-};
-
-
-/**
- * Load a url into a page
- */
-jQuery.fn.load = function( url, params, callback ) {
-	var selector, type, response,
-		self = this,
-		off = url.indexOf( " " );
-
-	if ( off > -1 ) {
-		selector = stripAndCollapse( url.slice( off ) );
-		url = url.slice( 0, off );
-	}
-
-	// If it's a function
-	if ( isFunction( params ) ) {
-
-		// We assume that it's the callback
-		callback = params;
-		params = undefined;
-
-	// Otherwise, build a param string
-	} else if ( params && typeof params === "object" ) {
-		type = "POST";
-	}
-
-	// If we have elements to modify, make the request
-	if ( self.length > 0 ) {
-		jQuery.ajax( {
-			url: url,
-
-			// If "type" variable is undefined, then "GET" method will be used.
-			// Make value of this field explicit since
-			// user can override it through ajaxSetup method
-			type: type || "GET",
-			dataType: "html",
-			data: params
-		} ).done( function( responseText ) {
-
-			// Save response for use in complete callback
-			response = arguments;
-
-			self.html( selector ?
-
-				// If a selector was specified, locate the right elements in a dummy div
-				// Exclude scripts to avoid IE 'Permission Denied' errors
-				jQuery( "<div>" ).append( jQuery.parseHTML( responseText ) ).find( selector ) :
-
-				// Otherwise use the full result
-				responseText );
-
-		// If the request succeeds, this function gets "data", "status", "jqXHR"
-		// but they are ignored because response was set above.
-		// If it fails, this function gets "jqXHR", "status", "error"
-		} ).always( callback && function( jqXHR, status ) {
-			self.each( function() {
-				callback.apply( this, response || [ jqXHR.responseText, status, jqXHR ] );
-			} );
-		} );
-	}
-
-	return this;
-};
-
-
-
-
-jQuery.expr.pseudos.animated = function( elem ) {
-	return jQuery.grep( jQuery.timers, function( fn ) {
-		return elem === fn.elem;
-	} ).length;
-};
-
-
-
-
-jQuery.offset = {
-	setOffset: function( elem, options, i ) {
-		var curPosition, curLeft, curCSSTop, curTop, curOffset, curCSSLeft, calculatePosition,
-			position = jQuery.css( elem, "position" ),
-			curElem = jQuery( elem ),
-			props = {};
-
-		// Set position first, in-case top/left are set even on static elem
-		if ( position === "static" ) {
-			elem.style.position = "relative";
-		}
-
-		curOffset = curElem.offset();
-		curCSSTop = jQuery.css( elem, "top" );
-		curCSSLeft = jQuery.css( elem, "left" );
-		calculatePosition = ( position === "absolute" || position === "fixed" ) &&
-			( curCSSTop + curCSSLeft ).indexOf( "auto" ) > -1;
-
-		// Need to be able to calculate position if either
-		// top or left is auto and position is either absolute or fixed
-		if ( calculatePosition ) {
-			curPosition = curElem.position();
-			curTop = curPosition.top;
-			curLeft = curPosition.left;
-
-		} else {
-			curTop = parseFloat( curCSSTop ) || 0;
-			curLeft = parseFloat( curCSSLeft ) || 0;
-		}
-
-		if ( isFunction( options ) ) {
-
-			// Use jQuery.extend here to allow modification of coordinates argument (gh-1848)
-			options = options.call( elem, i, jQuery.extend( {}, curOffset ) );
-		}
-
-		if ( options.top != null ) {
-			props.top = ( options.top - curOffset.top ) + curTop;
-		}
-		if ( options.left != null ) {
-			props.left = ( options.left - curOffset.left ) + curLeft;
-		}
-
-		if ( "using" in options ) {
-			options.using.call( elem, props );
-
-		} else {
-			if ( typeof props.top === "number" ) {
-				props.top += "px";
-			}
-			if ( typeof props.left === "number" ) {
-				props.left += "px";
-			}
-			curElem.css( props );
-		}
-	}
-};
-
-jQuery.fn.extend( {
-
-	// offset() relates an element's border box to the document origin
-	offset: function( options ) {
-
-		// Preserve chaining for setter
-		if ( arguments.length ) {
-			return options === undefined ?
-				this :
-				this.each( function( i ) {
-					jQuery.offset.setOffset( this, options, i );
-				} );
-		}
-
-		var rect, win,
-			elem = this[ 0 ];
-
-		if ( !elem ) {
-			return;
-		}
-
-		// Return zeros for disconnected and hidden (display: none) elements (gh-2310)
-		// Support: IE <=11 only
-		// Running getBoundingClientRect on a
-		// disconnected node in IE throws an error
-		if ( !elem.getClientRects().length ) {
-			return { top: 0, left: 0 };
-		}
-
-		// Get document-relative position by adding viewport scroll to viewport-relative gBCR
-		rect = elem.getBoundingClientRect();
-		win = elem.ownerDocument.defaultView;
-		return {
-			top: rect.top + win.pageYOffset,
-			left: rect.left + win.pageXOffset
-		};
-	},
-
-	// position() relates an element's margin box to its offset parent's padding box
-	// This corresponds to the behavior of CSS absolute positioning
-	position: function() {
-		if ( !this[ 0 ] ) {
-			return;
-		}
-
-		var offsetParent, offset, doc,
-			elem = this[ 0 ],
-			parentOffset = { top: 0, left: 0 };
-
-		// position:fixed elements are offset from the viewport, which itself always has zero offset
-		if ( jQuery.css( elem, "position" ) === "fixed" ) {
-
-			// Assume position:fixed implies availability of getBoundingClientRect
-			offset = elem.getBoundingClientRect();
-
-		} else {
-			offset = this.offset();
-
-			// Account for the *real* offset parent, which can be the document or its root element
-			// when a statically positioned element is identified
-			doc = elem.ownerDocument;
-			offsetParent = elem.offsetParent || doc.documentElement;
-			while ( offsetParent &&
-				( offsetParent === doc.body || offsetParent === doc.documentElement ) &&
-				jQuery.css( offsetParent, "position" ) === "static" ) {
-
-				offsetParent = offsetParent.parentNode;
-			}
-			if ( offsetParent && offsetParent !== elem && offsetParent.nodeType === 1 ) {
-
-				// Incorporate borders into its offset, since they are outside its content origin
-				parentOffset = jQuery( offsetParent ).offset();
-				parentOffset.top += jQuery.css( offsetParent, "borderTopWidth", true );
-				parentOffset.left += jQuery.css( offsetParent, "borderLeftWidth", true );
-			}
-		}
-
-		// Subtract parent offsets and element margins
-		return {
-			top: offset.top - parentOffset.top - jQuery.css( elem, "marginTop", true ),
-			left: offset.left - parentOffset.left - jQuery.css( elem, "marginLeft", true )
-		};
-	},
-
-	// This method will return documentElement in the following cases:
-	// 1) For the element inside the iframe without offsetParent, this method will return
-	//    documentElement of the parent window
-	// 2) For the hidden or detached element
-	// 3) For body or html element, i.e. in case of the html node - it will return itself
-	//
-	// but those exceptions were never presented as a real life use-cases
-	// and might be considered as more preferable results.
-	//
-	// This logic, however, is not guaranteed and can change at any point in the future
-	offsetParent: function() {
-		return this.map( function() {
-			var offsetParent = this.offsetParent;
-
-			while ( offsetParent && jQuery.css( offsetParent, "position" ) === "static" ) {
-				offsetParent = offsetParent.offsetParent;
-			}
-
-			return offsetParent || documentElement;
-		} );
-	}
-} );
-
-// Create scrollLeft and scrollTop methods
-jQuery.each( { scrollLeft: "pageXOffset", scrollTop: "pageYOffset" }, function( method, prop ) {
-	var top = "pageYOffset" === prop;
-
-	jQuery.fn[ method ] = function( val ) {
-		return access( this, function( elem, method, val ) {
-
-			// Coalesce documents and windows
-			var win;
-			if ( isWindow( elem ) ) {
-				win = elem;
-			} else if ( elem.nodeType === 9 ) {
-				win = elem.defaultView;
-			}
-
-			if ( val === undefined ) {
-				return win ? win[ prop ] : elem[ method ];
-			}
-
-			if ( win ) {
-				win.scrollTo(
-					!top ? val : win.pageXOffset,
-					top ? val : win.pageYOffset
-				);
-
-			} else {
-				elem[ method ] = val;
-			}
-		}, method, val, arguments.length );
-	};
-} );
-
-// Support: Safari <=7 - 9.1, Chrome <=37 - 49
-// Add the top/left cssHooks using jQuery.fn.position
-// Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084
-// Blink bug: https://bugs.chromium.org/p/chromium/issues/detail?id=589347
-// getComputedStyle returns percent when specified for top/left/bottom/right;
-// rather than make the css module depend on the offset module, just check for it here
-jQuery.each( [ "top", "left" ], function( _i, prop ) {
-	jQuery.cssHooks[ prop ] = addGetHookIf( support.pixelPosition,
-		function( elem, computed ) {
-			if ( computed ) {
-				computed = curCSS( elem, prop );
-
-				// If curCSS returns percentage, fallback to offset
-				return rnumnonpx.test( computed ) ?
-					jQuery( elem ).position()[ prop ] + "px" :
-					computed;
-			}
-		}
-	);
-} );
-
-
-// Create innerHeight, innerWidth, height, width, outerHeight and outerWidth methods
-jQuery.each( { Height: "height", Width: "width" }, function( name, type ) {
-	jQuery.each( { padding: "inner" + name, content: type, "": "outer" + name },
-		function( defaultExtra, funcName ) {
-
-		// Margin is only for outerHeight, outerWidth
-		jQuery.fn[ funcName ] = function( margin, value ) {
-			var chainable = arguments.length && ( defaultExtra || typeof margin !== "boolean" ),
-				extra = defaultExtra || ( margin === true || value === true ? "margin" : "border" );
-
-			return access( this, function( elem, type, value ) {
-				var doc;
-
-				if ( isWindow( elem ) ) {
-
-					// $( window ).outerWidth/Height return w/h including scrollbars (gh-1729)
-					return funcName.indexOf( "outer" ) === 0 ?
-						elem[ "inner" + name ] :
-						elem.document.documentElement[ "client" + name ];
-				}
-
-				// Get document width or height
-				if ( elem.nodeType === 9 ) {
-					doc = elem.documentElement;
-
-					// Either scroll[Width/Height] or offset[Width/Height] or client[Width/Height],
-					// whichever is greatest
-					return Math.max(
-						elem.body[ "scroll" + name ], doc[ "scroll" + name ],
-						elem.body[ "offset" + name ], doc[ "offset" + name ],
-						doc[ "client" + name ]
-					);
-				}
-
-				return value === undefined ?
-
-					// Get width or height on the element, requesting but not forcing parseFloat
-					jQuery.css( elem, type, extra ) :
-
-					// Set width or height on the element
-					jQuery.style( elem, type, value, extra );
-			}, type, chainable ? margin : undefined, chainable );
-		};
-	} );
-} );
-
-
-jQuery.each( [
-	"ajaxStart",
-	"ajaxStop",
-	"ajaxComplete",
-	"ajaxError",
-	"ajaxSuccess",
-	"ajaxSend"
-], function( _i, type ) {
-	jQuery.fn[ type ] = function( fn ) {
-		return this.on( type, fn );
-	};
-} );
-
-
-
-
-jQuery.fn.extend( {
-
-	bind: function( types, data, fn ) {
-		return this.on( types, null, data, fn );
-	},
-	unbind: function( types, fn ) {
-		return this.off( types, null, fn );
-	},
-
-	delegate: function( selector, types, data, fn ) {
-		return this.on( types, selector, data, fn );
-	},
-	undelegate: function( selector, types, fn ) {
-
-		// ( namespace ) or ( selector, types [, fn] )
-		return arguments.length === 1 ?
-			this.off( selector, "**" ) :
-			this.off( types, selector || "**", fn );
-	},
-
-	hover: function( fnOver, fnOut ) {
-		return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver );
-	}
-} );
-
-jQuery.each( ( "blur focus focusin focusout resize scroll click dblclick " +
-	"mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " +
-	"change select submit keydown keypress keyup contextmenu" ).split( " " ),
-	function( _i, name ) {
-
-		// Handle event binding
-		jQuery.fn[ name ] = function( data, fn ) {
-			return arguments.length > 0 ?
-				this.on( name, null, data, fn ) :
-				this.trigger( name );
-		};
-	} );
-
-
-
-
-// Support: Android <=4.0 only
-// Make sure we trim BOM and NBSP
-var rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g;
-
-// Bind a function to a context, optionally partially applying any
-// arguments.
-// jQuery.proxy is deprecated to promote standards (specifically Function#bind)
-// However, it is not slated for removal any time soon
-jQuery.proxy = function( fn, context ) {
-	var tmp, args, proxy;
-
-	if ( typeof context === "string" ) {
-		tmp = fn[ context ];
-		context = fn;
-		fn = tmp;
-	}
-
-	// Quick check to determine if target is callable, in the spec
-	// this throws a TypeError, but we will just return undefined.
-	if ( !isFunction( fn ) ) {
-		return undefined;
-	}
-
-	// Simulated bind
-	args = slice.call( arguments, 2 );
-	proxy = function() {
-		return fn.apply( context || this, args.concat( slice.call( arguments ) ) );
-	};
-
-	// Set the guid of unique handler to the same of original handler, so it can be removed
-	proxy.guid = fn.guid = fn.guid || jQuery.guid++;
-
-	return proxy;
-};
-
-jQuery.holdReady = function( hold ) {
-	if ( hold ) {
-		jQuery.readyWait++;
-	} else {
-		jQuery.ready( true );
-	}
-};
-jQuery.isArray = Array.isArray;
-jQuery.parseJSON = JSON.parse;
-jQuery.nodeName = nodeName;
-jQuery.isFunction = isFunction;
-jQuery.isWindow = isWindow;
-jQuery.camelCase = camelCase;
-jQuery.type = toType;
-
-jQuery.now = Date.now;
-
-jQuery.isNumeric = function( obj ) {
-
-	// As of jQuery 3.0, isNumeric is limited to
-	// strings and numbers (primitives or objects)
-	// that can be coerced to finite numbers (gh-2662)
-	var type = jQuery.type( obj );
-	return ( type === "number" || type === "string" ) &&
-
-		// parseFloat NaNs numeric-cast false positives ("")
-		// ...but misinterprets leading-number strings, particularly hex literals ("0x...")
-		// subtraction forces infinities to NaN
-		!isNaN( obj - parseFloat( obj ) );
-};
-
-jQuery.trim = function( text ) {
-	return text == null ?
-		"" :
-		( text + "" ).replace( rtrim, "" );
-};
-
-
-
-// Register as a named AMD module, since jQuery can be concatenated with other
-// files that may use define, but not via a proper concatenation script that
-// understands anonymous AMD modules. A named AMD is safest and most robust
-// way to register. Lowercase jquery is used because AMD module names are
-// derived from file names, and jQuery is normally delivered in a lowercase
-// file name. Do this after creating the global so that if an AMD module wants
-// to call noConflict to hide this version of jQuery, it will work.
-
-// Note that for maximum portability, libraries that are not jQuery should
-// declare themselves as anonymous modules, and avoid setting a global if an
-// AMD loader is present. jQuery is a special case. For more information, see
-// https://github.com/jrburke/requirejs/wiki/Updating-existing-libraries#wiki-anon
-
-if ( typeof define === "function" && define.amd ) {
-	define( "jquery", [], function() {
-		return jQuery;
-	} );
-}
-
-
-
-
-var
-
-	// Map over jQuery in case of overwrite
-	_jQuery = window.jQuery,
-
-	// Map over the $ in case of overwrite
-	_$ = window.$;
-
-jQuery.noConflict = function( deep ) {
-	if ( window.$ === jQuery ) {
-		window.$ = _$;
-	}
-
-	if ( deep && window.jQuery === jQuery ) {
-		window.jQuery = _jQuery;
-	}
-
-	return jQuery;
-};
-
-// Expose jQuery and $ identifiers, even in AMD
-// (#7102#comment:10, https://github.com/jquery/jquery/pull/557)
-// and CommonJS for browser emulators (#13566)
-if ( typeof noGlobal === "undefined" ) {
-	window.jQuery = window.$ = jQuery;
-}
-
-
-
-
-return jQuery;
-} );
diff --git a/docs/_build/html/_static/jquery.js b/docs/_build/html/_static/jquery.js
deleted file mode 100644
index b0614034..00000000
--- a/docs/_build/html/_static/jquery.js
+++ /dev/null
@@ -1,2 +0,0 @@
-/*! jQuery v3.5.1 | (c) JS Foundation and other contributors | jquery.org/license */
-!function(e,t){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return t(e)}:t(e)}("undefined"!=typeof window?window:this,function(C,e){"use strict";var t=[],r=Object.getPrototypeOf,s=t.slice,g=t.flat?function(e){return t.flat.call(e)}:function(e){return t.concat.apply([],e)},u=t.push,i=t.indexOf,n={},o=n.toString,v=n.hasOwnProperty,a=v.toString,l=a.call(Object),y={},m=function(e){return"function"==typeof e&&"number"!=typeof e.nodeType},x=function(e){return null!=e&&e===e.window},E=C.document,c={type:!0,src:!0,nonce:!0,noModule:!0};function b(e,t,n){var r,i,o=(n=n||E).createElement("script");if(o.text=e,t)for(r in c)(i=t[r]||t.getAttribute&&t.getAttribute(r))&&o.setAttribute(r,i);n.head.appendChild(o).parentNode.removeChild(o)}function w(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?n[o.call(e)]||"object":typeof e}var f="3.5.1",S=function(e,t){return new S.fn.init(e,t)};function p(e){var t=!!e&&"length"in e&&e.length,n=w(e);return!m(e)&&!x(e)&&("array"===n||0===t||"number"==typeof t&&0<t&&t-1 in e)}S.fn=S.prototype={jquery:f,constructor:S,length:0,toArray:function(){return s.call(this)},get:function(e){return null==e?s.call(this):e<0?this[e+this.length]:this[e]},pushStack:function(e){var t=S.merge(this.constructor(),e);return t.prevObject=this,t},each:function(e){return S.each(this,e)},map:function(n){return this.pushStack(S.map(this,function(e,t){return n.call(e,t,e)}))},slice:function(){return this.pushStack(s.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},even:function(){return this.pushStack(S.grep(this,function(e,t){return(t+1)%2}))},odd:function(){return this.pushStack(S.grep(this,function(e,t){return t%2}))},eq:function(e){var t=this.length,n=+e+(e<0?t:0);return this.pushStack(0<=n&&n<t?[this[n]]:[])},end:function(){return this.prevObject||this.constructor()},push:u,sort:t.sort,splice:t.splice},S.extend=S.fn.extend=function(){var e,t,n,r,i,o,a=arguments[0]||{},s=1,u=arguments.length,l=!1;for("boolean"==typeof a&&(l=a,a=arguments[s]||{},s++),"object"==typeof a||m(a)||(a={}),s===u&&(a=this,s--);s<u;s++)if(null!=(e=arguments[s]))for(t in e)r=e[t],"__proto__"!==t&&a!==r&&(l&&r&&(S.isPlainObject(r)||(i=Array.isArray(r)))?(n=a[t],o=i&&!Array.isArray(n)?[]:i||S.isPlainObject(n)?n:{},i=!1,a[t]=S.extend(l,o,r)):void 0!==r&&(a[t]=r));return a},S.extend({expando:"jQuery"+(f+Math.random()).replace(/\D/g,""),isReady:!0,error:function(e){throw new Error(e)},noop:function(){},isPlainObject:function(e){var t,n;return!(!e||"[object Object]"!==o.call(e))&&(!(t=r(e))||"function"==typeof(n=v.call(t,"constructor")&&t.constructor)&&a.call(n)===l)},isEmptyObject:function(e){var t;for(t in e)return!1;return!0},globalEval:function(e,t,n){b(e,{nonce:t&&t.nonce},n)},each:function(e,t){var n,r=0;if(p(e)){for(n=e.length;r<n;r++)if(!1===t.call(e[r],r,e[r]))break}else for(r in e)if(!1===t.call(e[r],r,e[r]))break;return e},makeArray:function(e,t){var n=t||[];return null!=e&&(p(Object(e))?S.merge(n,"string"==typeof e?[e]:e):u.call(n,e)),n},inArray:function(e,t,n){return null==t?-1:i.call(t,e,n)},merge:function(e,t){for(var n=+t.length,r=0,i=e.length;r<n;r++)e[i++]=t[r];return e.length=i,e},grep:function(e,t,n){for(var r=[],i=0,o=e.length,a=!n;i<o;i++)!t(e[i],i)!==a&&r.push(e[i]);return r},map:function(e,t,n){var r,i,o=0,a=[];if(p(e))for(r=e.length;o<r;o++)null!=(i=t(e[o],o,n))&&a.push(i);else for(o in e)null!=(i=t(e[o],o,n))&&a.push(i);return g(a)},guid:1,support:y}),"function"==typeof Symbol&&(S.fn[Symbol.iterator]=t[Symbol.iterator]),S.each("Boolean Number String Function Array Date RegExp Object Error Symbol".split(" "),function(e,t){n["[object "+t+"]"]=t.toLowerCase()});var d=function(n){var e,d,b,o,i,h,f,g,w,u,l,T,C,a,E,v,s,c,y,S="sizzle"+1*new Date,p=n.document,k=0,r=0,m=ue(),x=ue(),A=ue(),N=ue(),D=function(e,t){return e===t&&(l=!0),0},j={}.hasOwnProperty,t=[],q=t.pop,L=t.push,H=t.push,O=t.slice,P=function(e,t){for(var n=0,r=e.length;n<r;n++)if(e[n]===t)return n;return-1},R="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",M="[\\x20\\t\\r\\n\\f]",I="(?:\\\\[\\da-fA-F]{1,6}"+M+"?|\\\\[^\\r\\n\\f]|[\\w-]|[^\0-\\x7f])+",W="\\["+M+"*("+I+")(?:"+M+"*([*^$|!~]?=)"+M+"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|("+I+"))|)"+M+"*\\]",F=":("+I+")(?:\\((('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|((?:\\\\.|[^\\\\()[\\]]|"+W+")*)|.*)\\)|)",B=new RegExp(M+"+","g"),$=new RegExp("^"+M+"+|((?:^|[^\\\\])(?:\\\\.)*)"+M+"+$","g"),_=new RegExp("^"+M+"*,"+M+"*"),z=new RegExp("^"+M+"*([>+~]|"+M+")"+M+"*"),U=new RegExp(M+"|>"),X=new RegExp(F),V=new RegExp("^"+I+"$"),G={ID:new RegExp("^#("+I+")"),CLASS:new RegExp("^\\.("+I+")"),TAG:new RegExp("^("+I+"|[*])"),ATTR:new RegExp("^"+W),PSEUDO:new RegExp("^"+F),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+M+"*(even|odd|(([+-]|)(\\d*)n|)"+M+"*(?:([+-]|)"+M+"*(\\d+)|))"+M+"*\\)|)","i"),bool:new RegExp("^(?:"+R+")$","i"),needsContext:new RegExp("^"+M+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+M+"*((?:-\\d)?\\d*)"+M+"*\\)|)(?=[^-]|$)","i")},Y=/HTML$/i,Q=/^(?:input|select|textarea|button)$/i,J=/^h\d$/i,K=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ee=/[+~]/,te=new RegExp("\\\\[\\da-fA-F]{1,6}"+M+"?|\\\\([^\\r\\n\\f])","g"),ne=function(e,t){var n="0x"+e.slice(1)-65536;return t||(n<0?String.fromCharCode(n+65536):String.fromCharCode(n>>10|55296,1023&n|56320))},re=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,ie=function(e,t){return t?"\0"===e?"\ufffd":e.slice(0,-1)+"\\"+e.charCodeAt(e.length-1).toString(16)+" ":"\\"+e},oe=function(){T()},ae=be(function(e){return!0===e.disabled&&"fieldset"===e.nodeName.toLowerCase()},{dir:"parentNode",next:"legend"});try{H.apply(t=O.call(p.childNodes),p.childNodes),t[p.childNodes.length].nodeType}catch(e){H={apply:t.length?function(e,t){L.apply(e,O.call(t))}:function(e,t){var n=e.length,r=0;while(e[n++]=t[r++]);e.length=n-1}}}function se(t,e,n,r){var i,o,a,s,u,l,c,f=e&&e.ownerDocument,p=e?e.nodeType:9;if(n=n||[],"string"!=typeof t||!t||1!==p&&9!==p&&11!==p)return n;if(!r&&(T(e),e=e||C,E)){if(11!==p&&(u=Z.exec(t)))if(i=u[1]){if(9===p){if(!(a=e.getElementById(i)))return n;if(a.id===i)return n.push(a),n}else if(f&&(a=f.getElementById(i))&&y(e,a)&&a.id===i)return n.push(a),n}else{if(u[2])return H.apply(n,e.getElementsByTagName(t)),n;if((i=u[3])&&d.getElementsByClassName&&e.getElementsByClassName)return H.apply(n,e.getElementsByClassName(i)),n}if(d.qsa&&!N[t+" "]&&(!v||!v.test(t))&&(1!==p||"object"!==e.nodeName.toLowerCase())){if(c=t,f=e,1===p&&(U.test(t)||z.test(t))){(f=ee.test(t)&&ye(e.parentNode)||e)===e&&d.scope||((s=e.getAttribute("id"))?s=s.replace(re,ie):e.setAttribute("id",s=S)),o=(l=h(t)).length;while(o--)l[o]=(s?"#"+s:":scope")+" "+xe(l[o]);c=l.join(",")}try{return H.apply(n,f.querySelectorAll(c)),n}catch(e){N(t,!0)}finally{s===S&&e.removeAttribute("id")}}}return g(t.replace($,"$1"),e,n,r)}function ue(){var r=[];return function e(t,n){return r.push(t+" ")>b.cacheLength&&delete e[r.shift()],e[t+" "]=n}}function le(e){return e[S]=!0,e}function ce(e){var t=C.createElement("fieldset");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function fe(e,t){var n=e.split("|"),r=n.length;while(r--)b.attrHandle[n[r]]=t}function pe(e,t){var n=t&&e,r=n&&1===e.nodeType&&1===t.nodeType&&e.sourceIndex-t.sourceIndex;if(r)return r;if(n)while(n=n.nextSibling)if(n===t)return-1;return e?1:-1}function de(t){return function(e){return"input"===e.nodeName.toLowerCase()&&e.type===t}}function he(n){return function(e){var t=e.nodeName.toLowerCase();return("input"===t||"button"===t)&&e.type===n}}function ge(t){return function(e){return"form"in e?e.parentNode&&!1===e.disabled?"label"in e?"label"in e.parentNode?e.parentNode.disabled===t:e.disabled===t:e.isDisabled===t||e.isDisabled!==!t&&ae(e)===t:e.disabled===t:"label"in e&&e.disabled===t}}function ve(a){return le(function(o){return o=+o,le(function(e,t){var n,r=a([],e.length,o),i=r.length;while(i--)e[n=r[i]]&&(e[n]=!(t[n]=e[n]))})})}function ye(e){return e&&"undefined"!=typeof e.getElementsByTagName&&e}for(e in d=se.support={},i=se.isXML=function(e){var t=e.namespaceURI,n=(e.ownerDocument||e).documentElement;return!Y.test(t||n&&n.nodeName||"HTML")},T=se.setDocument=function(e){var t,n,r=e?e.ownerDocument||e:p;return r!=C&&9===r.nodeType&&r.documentElement&&(a=(C=r).documentElement,E=!i(C),p!=C&&(n=C.defaultView)&&n.top!==n&&(n.addEventListener?n.addEventListener("unload",oe,!1):n.attachEvent&&n.attachEvent("onunload",oe)),d.scope=ce(function(e){return a.appendChild(e).appendChild(C.createElement("div")),"undefined"!=typeof e.querySelectorAll&&!e.querySelectorAll(":scope fieldset div").length}),d.attributes=ce(function(e){return e.className="i",!e.getAttribute("className")}),d.getElementsByTagName=ce(function(e){return e.appendChild(C.createComment("")),!e.getElementsByTagName("*").length}),d.getElementsByClassName=K.test(C.getElementsByClassName),d.getById=ce(function(e){return a.appendChild(e).id=S,!C.getElementsByName||!C.getElementsByName(S).length}),d.getById?(b.filter.ID=function(e){var t=e.replace(te,ne);return function(e){return e.getAttribute("id")===t}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n=t.getElementById(e);return n?[n]:[]}}):(b.filter.ID=function(e){var n=e.replace(te,ne);return function(e){var t="undefined"!=typeof e.getAttributeNode&&e.getAttributeNode("id");return t&&t.value===n}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n,r,i,o=t.getElementById(e);if(o){if((n=o.getAttributeNode("id"))&&n.value===e)return[o];i=t.getElementsByName(e),r=0;while(o=i[r++])if((n=o.getAttributeNode("id"))&&n.value===e)return[o]}return[]}}),b.find.TAG=d.getElementsByTagName?function(e,t){return"undefined"!=typeof t.getElementsByTagName?t.getElementsByTagName(e):d.qsa?t.querySelectorAll(e):void 0}:function(e,t){var n,r=[],i=0,o=t.getElementsByTagName(e);if("*"===e){while(n=o[i++])1===n.nodeType&&r.push(n);return r}return o},b.find.CLASS=d.getElementsByClassName&&function(e,t){if("undefined"!=typeof t.getElementsByClassName&&E)return t.getElementsByClassName(e)},s=[],v=[],(d.qsa=K.test(C.querySelectorAll))&&(ce(function(e){var t;a.appendChild(e).innerHTML="<a id='"+S+"'></a><select id='"+S+"-\r\\' msallowcapture=''><option selected=''></option></select>",e.querySelectorAll("[msallowcapture^='']").length&&v.push("[*^$]="+M+"*(?:''|\"\")"),e.querySelectorAll("[selected]").length||v.push("\\["+M+"*(?:value|"+R+")"),e.querySelectorAll("[id~="+S+"-]").length||v.push("~="),(t=C.createElement("input")).setAttribute("name",""),e.appendChild(t),e.querySelectorAll("[name='']").length||v.push("\\["+M+"*name"+M+"*="+M+"*(?:''|\"\")"),e.querySelectorAll(":checked").length||v.push(":checked"),e.querySelectorAll("a#"+S+"+*").length||v.push(".#.+[+~]"),e.querySelectorAll("\\\f"),v.push("[\\r\\n\\f]")}),ce(function(e){e.innerHTML="<a href='' disabled='disabled'></a><select disabled='disabled'><option/></select>";var t=C.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),e.querySelectorAll("[name=d]").length&&v.push("name"+M+"*[*^$|!~]?="),2!==e.querySelectorAll(":enabled").length&&v.push(":enabled",":disabled"),a.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&v.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),v.push(",.*:")})),(d.matchesSelector=K.test(c=a.matches||a.webkitMatchesSelector||a.mozMatchesSelector||a.oMatchesSelector||a.msMatchesSelector))&&ce(function(e){d.disconnectedMatch=c.call(e,"*"),c.call(e,"[s!='']:x"),s.push("!=",F)}),v=v.length&&new RegExp(v.join("|")),s=s.length&&new RegExp(s.join("|")),t=K.test(a.compareDocumentPosition),y=t||K.test(a.contains)?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)while(t=t.parentNode)if(t===e)return!0;return!1},D=t?function(e,t){if(e===t)return l=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n||(1&(n=(e.ownerDocument||e)==(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!d.sortDetached&&t.compareDocumentPosition(e)===n?e==C||e.ownerDocument==p&&y(p,e)?-1:t==C||t.ownerDocument==p&&y(p,t)?1:u?P(u,e)-P(u,t):0:4&n?-1:1)}:function(e,t){if(e===t)return l=!0,0;var n,r=0,i=e.parentNode,o=t.parentNode,a=[e],s=[t];if(!i||!o)return e==C?-1:t==C?1:i?-1:o?1:u?P(u,e)-P(u,t):0;if(i===o)return pe(e,t);n=e;while(n=n.parentNode)a.unshift(n);n=t;while(n=n.parentNode)s.unshift(n);while(a[r]===s[r])r++;return r?pe(a[r],s[r]):a[r]==p?-1:s[r]==p?1:0}),C},se.matches=function(e,t){return se(e,null,null,t)},se.matchesSelector=function(e,t){if(T(e),d.matchesSelector&&E&&!N[t+" "]&&(!s||!s.test(t))&&(!v||!v.test(t)))try{var n=c.call(e,t);if(n||d.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(e){N(t,!0)}return 0<se(t,C,null,[e]).length},se.contains=function(e,t){return(e.ownerDocument||e)!=C&&T(e),y(e,t)},se.attr=function(e,t){(e.ownerDocument||e)!=C&&T(e);var n=b.attrHandle[t.toLowerCase()],r=n&&j.call(b.attrHandle,t.toLowerCase())?n(e,t,!E):void 0;return void 0!==r?r:d.attributes||!E?e.getAttribute(t):(r=e.getAttributeNode(t))&&r.specified?r.value:null},se.escape=function(e){return(e+"").replace(re,ie)},se.error=function(e){throw new Error("Syntax error, unrecognized expression: "+e)},se.uniqueSort=function(e){var t,n=[],r=0,i=0;if(l=!d.detectDuplicates,u=!d.sortStable&&e.slice(0),e.sort(D),l){while(t=e[i++])t===e[i]&&(r=n.push(i));while(r--)e.splice(n[r],1)}return u=null,e},o=se.getText=function(e){var t,n="",r=0,i=e.nodeType;if(i){if(1===i||9===i||11===i){if("string"==typeof e.textContent)return e.textContent;for(e=e.firstChild;e;e=e.nextSibling)n+=o(e)}else if(3===i||4===i)return e.nodeValue}else while(t=e[r++])n+=o(t);return n},(b=se.selectors={cacheLength:50,createPseudo:le,match:G,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(te,ne),e[3]=(e[3]||e[4]||e[5]||"").replace(te,ne),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||se.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&se.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return G.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&X.test(n)&&(t=h(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(te,ne).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=m[e+" "];return t||(t=new RegExp("(^|"+M+")"+e+"("+M+"|$)"))&&m(e,function(e){return t.test("string"==typeof e.className&&e.className||"undefined"!=typeof e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(n,r,i){return function(e){var t=se.attr(e,n);return null==t?"!="===r:!r||(t+="","="===r?t===i:"!="===r?t!==i:"^="===r?i&&0===t.indexOf(i):"*="===r?i&&-1<t.indexOf(i):"$="===r?i&&t.slice(-i.length)===i:"~="===r?-1<(" "+t.replace(B," ")+" ").indexOf(i):"|="===r&&(t===i||t.slice(0,i.length+1)===i+"-"))}},CHILD:function(h,e,t,g,v){var y="nth"!==h.slice(0,3),m="last"!==h.slice(-4),x="of-type"===e;return 1===g&&0===v?function(e){return!!e.parentNode}:function(e,t,n){var r,i,o,a,s,u,l=y!==m?"nextSibling":"previousSibling",c=e.parentNode,f=x&&e.nodeName.toLowerCase(),p=!n&&!x,d=!1;if(c){if(y){while(l){a=e;while(a=a[l])if(x?a.nodeName.toLowerCase()===f:1===a.nodeType)return!1;u=l="only"===h&&!u&&"nextSibling"}return!0}if(u=[m?c.firstChild:c.lastChild],m&&p){d=(s=(r=(i=(o=(a=c)[S]||(a[S]={}))[a.uniqueID]||(o[a.uniqueID]={}))[h]||[])[0]===k&&r[1])&&r[2],a=s&&c.childNodes[s];while(a=++s&&a&&a[l]||(d=s=0)||u.pop())if(1===a.nodeType&&++d&&a===e){i[h]=[k,s,d];break}}else if(p&&(d=s=(r=(i=(o=(a=e)[S]||(a[S]={}))[a.uniqueID]||(o[a.uniqueID]={}))[h]||[])[0]===k&&r[1]),!1===d)while(a=++s&&a&&a[l]||(d=s=0)||u.pop())if((x?a.nodeName.toLowerCase()===f:1===a.nodeType)&&++d&&(p&&((i=(o=a[S]||(a[S]={}))[a.uniqueID]||(o[a.uniqueID]={}))[h]=[k,d]),a===e))break;return(d-=v)===g||d%g==0&&0<=d/g}}},PSEUDO:function(e,o){var t,a=b.pseudos[e]||b.setFilters[e.toLowerCase()]||se.error("unsupported pseudo: "+e);return a[S]?a(o):1<a.length?(t=[e,e,"",o],b.setFilters.hasOwnProperty(e.toLowerCase())?le(function(e,t){var n,r=a(e,o),i=r.length;while(i--)e[n=P(e,r[i])]=!(t[n]=r[i])}):function(e){return a(e,0,t)}):a}},pseudos:{not:le(function(e){var r=[],i=[],s=f(e.replace($,"$1"));return s[S]?le(function(e,t,n,r){var i,o=s(e,null,r,[]),a=e.length;while(a--)(i=o[a])&&(e[a]=!(t[a]=i))}):function(e,t,n){return r[0]=e,s(r,null,n,i),r[0]=null,!i.pop()}}),has:le(function(t){return function(e){return 0<se(t,e).length}}),contains:le(function(t){return t=t.replace(te,ne),function(e){return-1<(e.textContent||o(e)).indexOf(t)}}),lang:le(function(n){return V.test(n||"")||se.error("unsupported lang: "+n),n=n.replace(te,ne).toLowerCase(),function(e){var t;do{if(t=E?e.lang:e.getAttribute("xml:lang")||e.getAttribute("lang"))return(t=t.toLowerCase())===n||0===t.indexOf(n+"-")}while((e=e.parentNode)&&1===e.nodeType);return!1}}),target:function(e){var t=n.location&&n.location.hash;return t&&t.slice(1)===e.id},root:function(e){return e===a},focus:function(e){return e===C.activeElement&&(!C.hasFocus||C.hasFocus())&&!!(e.type||e.href||~e.tabIndex)},enabled:ge(!1),disabled:ge(!0),checked:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&!!e.checked||"option"===t&&!!e.selected},selected:function(e){return e.parentNode&&e.parentNode.selectedIndex,!0===e.selected},empty:function(e){for(e=e.firstChild;e;e=e.nextSibling)if(e.nodeType<6)return!1;return!0},parent:function(e){return!b.pseudos.empty(e)},header:function(e){return J.test(e.nodeName)},input:function(e){return Q.test(e.nodeName)},button:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&"button"===e.type||"button"===t},text:function(e){var t;return"input"===e.nodeName.toLowerCase()&&"text"===e.type&&(null==(t=e.getAttribute("type"))||"text"===t.toLowerCase())},first:ve(function(){return[0]}),last:ve(function(e,t){return[t-1]}),eq:ve(function(e,t,n){return[n<0?n+t:n]}),even:ve(function(e,t){for(var n=0;n<t;n+=2)e.push(n);return e}),odd:ve(function(e,t){for(var n=1;n<t;n+=2)e.push(n);return e}),lt:ve(function(e,t,n){for(var r=n<0?n+t:t<n?t:n;0<=--r;)e.push(r);return e}),gt:ve(function(e,t,n){for(var r=n<0?n+t:n;++r<t;)e.push(r);return e})}}).pseudos.nth=b.pseudos.eq,{radio:!0,checkbox:!0,file:!0,password:!0,image:!0})b.pseudos[e]=de(e);for(e in{submit:!0,reset:!0})b.pseudos[e]=he(e);function me(){}function xe(e){for(var t=0,n=e.length,r="";t<n;t++)r+=e[t].value;return r}function be(s,e,t){var u=e.dir,l=e.next,c=l||u,f=t&&"parentNode"===c,p=r++;return e.first?function(e,t,n){while(e=e[u])if(1===e.nodeType||f)return s(e,t,n);return!1}:function(e,t,n){var r,i,o,a=[k,p];if(n){while(e=e[u])if((1===e.nodeType||f)&&s(e,t,n))return!0}else while(e=e[u])if(1===e.nodeType||f)if(i=(o=e[S]||(e[S]={}))[e.uniqueID]||(o[e.uniqueID]={}),l&&l===e.nodeName.toLowerCase())e=e[u]||e;else{if((r=i[c])&&r[0]===k&&r[1]===p)return a[2]=r[2];if((i[c]=a)[2]=s(e,t,n))return!0}return!1}}function we(i){return 1<i.length?function(e,t,n){var r=i.length;while(r--)if(!i[r](e,t,n))return!1;return!0}:i[0]}function Te(e,t,n,r,i){for(var o,a=[],s=0,u=e.length,l=null!=t;s<u;s++)(o=e[s])&&(n&&!n(o,r,i)||(a.push(o),l&&t.push(s)));return a}function Ce(d,h,g,v,y,e){return v&&!v[S]&&(v=Ce(v)),y&&!y[S]&&(y=Ce(y,e)),le(function(e,t,n,r){var i,o,a,s=[],u=[],l=t.length,c=e||function(e,t,n){for(var r=0,i=t.length;r<i;r++)se(e,t[r],n);return n}(h||"*",n.nodeType?[n]:n,[]),f=!d||!e&&h?c:Te(c,s,d,n,r),p=g?y||(e?d:l||v)?[]:t:f;if(g&&g(f,p,n,r),v){i=Te(p,u),v(i,[],n,r),o=i.length;while(o--)(a=i[o])&&(p[u[o]]=!(f[u[o]]=a))}if(e){if(y||d){if(y){i=[],o=p.length;while(o--)(a=p[o])&&i.push(f[o]=a);y(null,p=[],i,r)}o=p.length;while(o--)(a=p[o])&&-1<(i=y?P(e,a):s[o])&&(e[i]=!(t[i]=a))}}else p=Te(p===t?p.splice(l,p.length):p),y?y(null,t,p,r):H.apply(t,p)})}function Ee(e){for(var i,t,n,r=e.length,o=b.relative[e[0].type],a=o||b.relative[" "],s=o?1:0,u=be(function(e){return e===i},a,!0),l=be(function(e){return-1<P(i,e)},a,!0),c=[function(e,t,n){var r=!o&&(n||t!==w)||((i=t).nodeType?u(e,t,n):l(e,t,n));return i=null,r}];s<r;s++)if(t=b.relative[e[s].type])c=[be(we(c),t)];else{if((t=b.filter[e[s].type].apply(null,e[s].matches))[S]){for(n=++s;n<r;n++)if(b.relative[e[n].type])break;return Ce(1<s&&we(c),1<s&&xe(e.slice(0,s-1).concat({value:" "===e[s-2].type?"*":""})).replace($,"$1"),t,s<n&&Ee(e.slice(s,n)),n<r&&Ee(e=e.slice(n)),n<r&&xe(e))}c.push(t)}return we(c)}return me.prototype=b.filters=b.pseudos,b.setFilters=new me,h=se.tokenize=function(e,t){var n,r,i,o,a,s,u,l=x[e+" "];if(l)return t?0:l.slice(0);a=e,s=[],u=b.preFilter;while(a){for(o in n&&!(r=_.exec(a))||(r&&(a=a.slice(r[0].length)||a),s.push(i=[])),n=!1,(r=z.exec(a))&&(n=r.shift(),i.push({value:n,type:r[0].replace($," ")}),a=a.slice(n.length)),b.filter)!(r=G[o].exec(a))||u[o]&&!(r=u[o](r))||(n=r.shift(),i.push({value:n,type:o,matches:r}),a=a.slice(n.length));if(!n)break}return t?a.length:a?se.error(e):x(e,s).slice(0)},f=se.compile=function(e,t){var n,v,y,m,x,r,i=[],o=[],a=A[e+" "];if(!a){t||(t=h(e)),n=t.length;while(n--)(a=Ee(t[n]))[S]?i.push(a):o.push(a);(a=A(e,(v=o,m=0<(y=i).length,x=0<v.length,r=function(e,t,n,r,i){var o,a,s,u=0,l="0",c=e&&[],f=[],p=w,d=e||x&&b.find.TAG("*",i),h=k+=null==p?1:Math.random()||.1,g=d.length;for(i&&(w=t==C||t||i);l!==g&&null!=(o=d[l]);l++){if(x&&o){a=0,t||o.ownerDocument==C||(T(o),n=!E);while(s=v[a++])if(s(o,t||C,n)){r.push(o);break}i&&(k=h)}m&&((o=!s&&o)&&u--,e&&c.push(o))}if(u+=l,m&&l!==u){a=0;while(s=y[a++])s(c,f,t,n);if(e){if(0<u)while(l--)c[l]||f[l]||(f[l]=q.call(r));f=Te(f)}H.apply(r,f),i&&!e&&0<f.length&&1<u+y.length&&se.uniqueSort(r)}return i&&(k=h,w=p),c},m?le(r):r))).selector=e}return a},g=se.select=function(e,t,n,r){var i,o,a,s,u,l="function"==typeof e&&e,c=!r&&h(e=l.selector||e);if(n=n||[],1===c.length){if(2<(o=c[0]=c[0].slice(0)).length&&"ID"===(a=o[0]).type&&9===t.nodeType&&E&&b.relative[o[1].type]){if(!(t=(b.find.ID(a.matches[0].replace(te,ne),t)||[])[0]))return n;l&&(t=t.parentNode),e=e.slice(o.shift().value.length)}i=G.needsContext.test(e)?0:o.length;while(i--){if(a=o[i],b.relative[s=a.type])break;if((u=b.find[s])&&(r=u(a.matches[0].replace(te,ne),ee.test(o[0].type)&&ye(t.parentNode)||t))){if(o.splice(i,1),!(e=r.length&&xe(o)))return H.apply(n,r),n;break}}}return(l||f(e,c))(r,t,!E,n,!t||ee.test(e)&&ye(t.parentNode)||t),n},d.sortStable=S.split("").sort(D).join("")===S,d.detectDuplicates=!!l,T(),d.sortDetached=ce(function(e){return 1&e.compareDocumentPosition(C.createElement("fieldset"))}),ce(function(e){return e.innerHTML="<a href='#'></a>","#"===e.firstChild.getAttribute("href")})||fe("type|href|height|width",function(e,t,n){if(!n)return e.getAttribute(t,"type"===t.toLowerCase()?1:2)}),d.attributes&&ce(function(e){return e.innerHTML="<input/>",e.firstChild.setAttribute("value",""),""===e.firstChild.getAttribute("value")})||fe("value",function(e,t,n){if(!n&&"input"===e.nodeName.toLowerCase())return e.defaultValue}),ce(function(e){return null==e.getAttribute("disabled")})||fe(R,function(e,t,n){var r;if(!n)return!0===e[t]?t.toLowerCase():(r=e.getAttributeNode(t))&&r.specified?r.value:null}),se}(C);S.find=d,S.expr=d.selectors,S.expr[":"]=S.expr.pseudos,S.uniqueSort=S.unique=d.uniqueSort,S.text=d.getText,S.isXMLDoc=d.isXML,S.contains=d.contains,S.escapeSelector=d.escape;var h=function(e,t,n){var r=[],i=void 0!==n;while((e=e[t])&&9!==e.nodeType)if(1===e.nodeType){if(i&&S(e).is(n))break;r.push(e)}return r},T=function(e,t){for(var n=[];e;e=e.nextSibling)1===e.nodeType&&e!==t&&n.push(e);return n},k=S.expr.match.needsContext;function A(e,t){return e.nodeName&&e.nodeName.toLowerCase()===t.toLowerCase()}var N=/^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function D(e,n,r){return m(n)?S.grep(e,function(e,t){return!!n.call(e,t,e)!==r}):n.nodeType?S.grep(e,function(e){return e===n!==r}):"string"!=typeof n?S.grep(e,function(e){return-1<i.call(n,e)!==r}):S.filter(n,e,r)}S.filter=function(e,t,n){var r=t[0];return n&&(e=":not("+e+")"),1===t.length&&1===r.nodeType?S.find.matchesSelector(r,e)?[r]:[]:S.find.matches(e,S.grep(t,function(e){return 1===e.nodeType}))},S.fn.extend({find:function(e){var t,n,r=this.length,i=this;if("string"!=typeof e)return this.pushStack(S(e).filter(function(){for(t=0;t<r;t++)if(S.contains(i[t],this))return!0}));for(n=this.pushStack([]),t=0;t<r;t++)S.find(e,i[t],n);return 1<r?S.uniqueSort(n):n},filter:function(e){return this.pushStack(D(this,e||[],!1))},not:function(e){return this.pushStack(D(this,e||[],!0))},is:function(e){return!!D(this,"string"==typeof e&&k.test(e)?S(e):e||[],!1).length}});var j,q=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/;(S.fn.init=function(e,t,n){var r,i;if(!e)return this;if(n=n||j,"string"==typeof e){if(!(r="<"===e[0]&&">"===e[e.length-1]&&3<=e.length?[null,e,null]:q.exec(e))||!r[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(r[1]){if(t=t instanceof S?t[0]:t,S.merge(this,S.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:E,!0)),N.test(r[1])&&S.isPlainObject(t))for(r in t)m(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}return(i=E.getElementById(r[2]))&&(this[0]=i,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):m(e)?void 0!==n.ready?n.ready(e):e(S):S.makeArray(e,this)}).prototype=S.fn,j=S(E);var L=/^(?:parents|prev(?:Until|All))/,H={children:!0,contents:!0,next:!0,prev:!0};function O(e,t){while((e=e[t])&&1!==e.nodeType);return e}S.fn.extend({has:function(e){var t=S(e,this),n=t.length;return this.filter(function(){for(var e=0;e<n;e++)if(S.contains(this,t[e]))return!0})},closest:function(e,t){var n,r=0,i=this.length,o=[],a="string"!=typeof e&&S(e);if(!k.test(e))for(;r<i;r++)for(n=this[r];n&&n!==t;n=n.parentNode)if(n.nodeType<11&&(a?-1<a.index(n):1===n.nodeType&&S.find.matchesSelector(n,e))){o.push(n);break}return this.pushStack(1<o.length?S.uniqueSort(o):o)},index:function(e){return e?"string"==typeof e?i.call(S(e),this[0]):i.call(this,e.jquery?e[0]:e):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(e,t){return this.pushStack(S.uniqueSort(S.merge(this.get(),S(e,t))))},addBack:function(e){return this.add(null==e?this.prevObject:this.prevObject.filter(e))}}),S.each({parent:function(e){var t=e.parentNode;return t&&11!==t.nodeType?t:null},parents:function(e){return h(e,"parentNode")},parentsUntil:function(e,t,n){return h(e,"parentNode",n)},next:function(e){return O(e,"nextSibling")},prev:function(e){return O(e,"previousSibling")},nextAll:function(e){return h(e,"nextSibling")},prevAll:function(e){return h(e,"previousSibling")},nextUntil:function(e,t,n){return h(e,"nextSibling",n)},prevUntil:function(e,t,n){return h(e,"previousSibling",n)},siblings:function(e){return T((e.parentNode||{}).firstChild,e)},children:function(e){return T(e.firstChild)},contents:function(e){return null!=e.contentDocument&&r(e.contentDocument)?e.contentDocument:(A(e,"template")&&(e=e.content||e),S.merge([],e.childNodes))}},function(r,i){S.fn[r]=function(e,t){var n=S.map(this,i,e);return"Until"!==r.slice(-5)&&(t=e),t&&"string"==typeof t&&(n=S.filter(t,n)),1<this.length&&(H[r]||S.uniqueSort(n),L.test(r)&&n.reverse()),this.pushStack(n)}});var P=/[^\x20\t\r\n\f]+/g;function R(e){return e}function M(e){throw e}function I(e,t,n,r){var i;try{e&&m(i=e.promise)?i.call(e).done(t).fail(n):e&&m(i=e.then)?i.call(e,t,n):t.apply(void 0,[e].slice(r))}catch(e){n.apply(void 0,[e])}}S.Callbacks=function(r){var e,n;r="string"==typeof r?(e=r,n={},S.each(e.match(P)||[],function(e,t){n[t]=!0}),n):S.extend({},r);var i,t,o,a,s=[],u=[],l=-1,c=function(){for(a=a||r.once,o=i=!0;u.length;l=-1){t=u.shift();while(++l<s.length)!1===s[l].apply(t[0],t[1])&&r.stopOnFalse&&(l=s.length,t=!1)}r.memory||(t=!1),i=!1,a&&(s=t?[]:"")},f={add:function(){return s&&(t&&!i&&(l=s.length-1,u.push(t)),function n(e){S.each(e,function(e,t){m(t)?r.unique&&f.has(t)||s.push(t):t&&t.length&&"string"!==w(t)&&n(t)})}(arguments),t&&!i&&c()),this},remove:function(){return S.each(arguments,function(e,t){var n;while(-1<(n=S.inArray(t,s,n)))s.splice(n,1),n<=l&&l--}),this},has:function(e){return e?-1<S.inArray(e,s):0<s.length},empty:function(){return s&&(s=[]),this},disable:function(){return a=u=[],s=t="",this},disabled:function(){return!s},lock:function(){return a=u=[],t||i||(s=t=""),this},locked:function(){return!!a},fireWith:function(e,t){return a||(t=[e,(t=t||[]).slice?t.slice():t],u.push(t),i||c()),this},fire:function(){return f.fireWith(this,arguments),this},fired:function(){return!!o}};return f},S.extend({Deferred:function(e){var o=[["notify","progress",S.Callbacks("memory"),S.Callbacks("memory"),2],["resolve","done",S.Callbacks("once memory"),S.Callbacks("once memory"),0,"resolved"],["reject","fail",S.Callbacks("once memory"),S.Callbacks("once memory"),1,"rejected"]],i="pending",a={state:function(){return i},always:function(){return s.done(arguments).fail(arguments),this},"catch":function(e){return a.then(null,e)},pipe:function(){var i=arguments;return S.Deferred(function(r){S.each(o,function(e,t){var n=m(i[t[4]])&&i[t[4]];s[t[1]](function(){var e=n&&n.apply(this,arguments);e&&m(e.promise)?e.promise().progress(r.notify).done(r.resolve).fail(r.reject):r[t[0]+"With"](this,n?[e]:arguments)})}),i=null}).promise()},then:function(t,n,r){var u=0;function l(i,o,a,s){return function(){var n=this,r=arguments,e=function(){var e,t;if(!(i<u)){if((e=a.apply(n,r))===o.promise())throw new TypeError("Thenable self-resolution");t=e&&("object"==typeof e||"function"==typeof e)&&e.then,m(t)?s?t.call(e,l(u,o,R,s),l(u,o,M,s)):(u++,t.call(e,l(u,o,R,s),l(u,o,M,s),l(u,o,R,o.notifyWith))):(a!==R&&(n=void 0,r=[e]),(s||o.resolveWith)(n,r))}},t=s?e:function(){try{e()}catch(e){S.Deferred.exceptionHook&&S.Deferred.exceptionHook(e,t.stackTrace),u<=i+1&&(a!==M&&(n=void 0,r=[e]),o.rejectWith(n,r))}};i?t():(S.Deferred.getStackHook&&(t.stackTrace=S.Deferred.getStackHook()),C.setTimeout(t))}}return S.Deferred(function(e){o[0][3].add(l(0,e,m(r)?r:R,e.notifyWith)),o[1][3].add(l(0,e,m(t)?t:R)),o[2][3].add(l(0,e,m(n)?n:M))}).promise()},promise:function(e){return null!=e?S.extend(e,a):a}},s={};return S.each(o,function(e,t){var n=t[2],r=t[5];a[t[1]]=n.add,r&&n.add(function(){i=r},o[3-e][2].disable,o[3-e][3].disable,o[0][2].lock,o[0][3].lock),n.add(t[3].fire),s[t[0]]=function(){return s[t[0]+"With"](this===s?void 0:this,arguments),this},s[t[0]+"With"]=n.fireWith}),a.promise(s),e&&e.call(s,s),s},when:function(e){var n=arguments.length,t=n,r=Array(t),i=s.call(arguments),o=S.Deferred(),a=function(t){return function(e){r[t]=this,i[t]=1<arguments.length?s.call(arguments):e,--n||o.resolveWith(r,i)}};if(n<=1&&(I(e,o.done(a(t)).resolve,o.reject,!n),"pending"===o.state()||m(i[t]&&i[t].then)))return o.then();while(t--)I(i[t],a(t),o.reject);return o.promise()}});var W=/^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/;S.Deferred.exceptionHook=function(e,t){C.console&&C.console.warn&&e&&W.test(e.name)&&C.console.warn("jQuery.Deferred exception: "+e.message,e.stack,t)},S.readyException=function(e){C.setTimeout(function(){throw e})};var F=S.Deferred();function B(){E.removeEventListener("DOMContentLoaded",B),C.removeEventListener("load",B),S.ready()}S.fn.ready=function(e){return F.then(e)["catch"](function(e){S.readyException(e)}),this},S.extend({isReady:!1,readyWait:1,ready:function(e){(!0===e?--S.readyWait:S.isReady)||(S.isReady=!0)!==e&&0<--S.readyWait||F.resolveWith(E,[S])}}),S.ready.then=F.then,"complete"===E.readyState||"loading"!==E.readyState&&!E.documentElement.doScroll?C.setTimeout(S.ready):(E.addEventListener("DOMContentLoaded",B),C.addEventListener("load",B));var $=function(e,t,n,r,i,o,a){var s=0,u=e.length,l=null==n;if("object"===w(n))for(s in i=!0,n)$(e,t,s,n[s],!0,o,a);else if(void 0!==r&&(i=!0,m(r)||(a=!0),l&&(a?(t.call(e,r),t=null):(l=t,t=function(e,t,n){return l.call(S(e),n)})),t))for(;s<u;s++)t(e[s],n,a?r:r.call(e[s],s,t(e[s],n)));return i?e:l?t.call(e):u?t(e[0],n):o},_=/^-ms-/,z=/-([a-z])/g;function U(e,t){return t.toUpperCase()}function X(e){return e.replace(_,"ms-").replace(z,U)}var V=function(e){return 1===e.nodeType||9===e.nodeType||!+e.nodeType};function G(){this.expando=S.expando+G.uid++}G.uid=1,G.prototype={cache:function(e){var t=e[this.expando];return t||(t={},V(e)&&(e.nodeType?e[this.expando]=t:Object.defineProperty(e,this.expando,{value:t,configurable:!0}))),t},set:function(e,t,n){var r,i=this.cache(e);if("string"==typeof t)i[X(t)]=n;else for(r in t)i[X(r)]=t[r];return i},get:function(e,t){return void 0===t?this.cache(e):e[this.expando]&&e[this.expando][X(t)]},access:function(e,t,n){return void 0===t||t&&"string"==typeof t&&void 0===n?this.get(e,t):(this.set(e,t,n),void 0!==n?n:t)},remove:function(e,t){var n,r=e[this.expando];if(void 0!==r){if(void 0!==t){n=(t=Array.isArray(t)?t.map(X):(t=X(t))in r?[t]:t.match(P)||[]).length;while(n--)delete r[t[n]]}(void 0===t||S.isEmptyObject(r))&&(e.nodeType?e[this.expando]=void 0:delete e[this.expando])}},hasData:function(e){var t=e[this.expando];return void 0!==t&&!S.isEmptyObject(t)}};var Y=new G,Q=new G,J=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,K=/[A-Z]/g;function Z(e,t,n){var r,i;if(void 0===n&&1===e.nodeType)if(r="data-"+t.replace(K,"-$&").toLowerCase(),"string"==typeof(n=e.getAttribute(r))){try{n="true"===(i=n)||"false"!==i&&("null"===i?null:i===+i+""?+i:J.test(i)?JSON.parse(i):i)}catch(e){}Q.set(e,t,n)}else n=void 0;return n}S.extend({hasData:function(e){return Q.hasData(e)||Y.hasData(e)},data:function(e,t,n){return Q.access(e,t,n)},removeData:function(e,t){Q.remove(e,t)},_data:function(e,t,n){return Y.access(e,t,n)},_removeData:function(e,t){Y.remove(e,t)}}),S.fn.extend({data:function(n,e){var t,r,i,o=this[0],a=o&&o.attributes;if(void 0===n){if(this.length&&(i=Q.get(o),1===o.nodeType&&!Y.get(o,"hasDataAttrs"))){t=a.length;while(t--)a[t]&&0===(r=a[t].name).indexOf("data-")&&(r=X(r.slice(5)),Z(o,r,i[r]));Y.set(o,"hasDataAttrs",!0)}return i}return"object"==typeof n?this.each(function(){Q.set(this,n)}):$(this,function(e){var t;if(o&&void 0===e)return void 0!==(t=Q.get(o,n))?t:void 0!==(t=Z(o,n))?t:void 0;this.each(function(){Q.set(this,n,e)})},null,e,1<arguments.length,null,!0)},removeData:function(e){return this.each(function(){Q.remove(this,e)})}}),S.extend({queue:function(e,t,n){var r;if(e)return t=(t||"fx")+"queue",r=Y.get(e,t),n&&(!r||Array.isArray(n)?r=Y.access(e,t,S.makeArray(n)):r.push(n)),r||[]},dequeue:function(e,t){t=t||"fx";var n=S.queue(e,t),r=n.length,i=n.shift(),o=S._queueHooks(e,t);"inprogress"===i&&(i=n.shift(),r--),i&&("fx"===t&&n.unshift("inprogress"),delete o.stop,i.call(e,function(){S.dequeue(e,t)},o)),!r&&o&&o.empty.fire()},_queueHooks:function(e,t){var n=t+"queueHooks";return Y.get(e,n)||Y.access(e,n,{empty:S.Callbacks("once memory").add(function(){Y.remove(e,[t+"queue",n])})})}}),S.fn.extend({queue:function(t,n){var e=2;return"string"!=typeof t&&(n=t,t="fx",e--),arguments.length<e?S.queue(this[0],t):void 0===n?this:this.each(function(){var e=S.queue(this,t,n);S._queueHooks(this,t),"fx"===t&&"inprogress"!==e[0]&&S.dequeue(this,t)})},dequeue:function(e){return this.each(function(){S.dequeue(this,e)})},clearQueue:function(e){return this.queue(e||"fx",[])},promise:function(e,t){var n,r=1,i=S.Deferred(),o=this,a=this.length,s=function(){--r||i.resolveWith(o,[o])};"string"!=typeof e&&(t=e,e=void 0),e=e||"fx";while(a--)(n=Y.get(o[a],e+"queueHooks"))&&n.empty&&(r++,n.empty.add(s));return s(),i.promise(t)}});var ee=/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source,te=new RegExp("^(?:([+-])=|)("+ee+")([a-z%]*)$","i"),ne=["Top","Right","Bottom","Left"],re=E.documentElement,ie=function(e){return S.contains(e.ownerDocument,e)},oe={composed:!0};re.getRootNode&&(ie=function(e){return S.contains(e.ownerDocument,e)||e.getRootNode(oe)===e.ownerDocument});var ae=function(e,t){return"none"===(e=t||e).style.display||""===e.style.display&&ie(e)&&"none"===S.css(e,"display")};function se(e,t,n,r){var i,o,a=20,s=r?function(){return r.cur()}:function(){return S.css(e,t,"")},u=s(),l=n&&n[3]||(S.cssNumber[t]?"":"px"),c=e.nodeType&&(S.cssNumber[t]||"px"!==l&&+u)&&te.exec(S.css(e,t));if(c&&c[3]!==l){u/=2,l=l||c[3],c=+u||1;while(a--)S.style(e,t,c+l),(1-o)*(1-(o=s()/u||.5))<=0&&(a=0),c/=o;c*=2,S.style(e,t,c+l),n=n||[]}return n&&(c=+c||+u||0,i=n[1]?c+(n[1]+1)*n[2]:+n[2],r&&(r.unit=l,r.start=c,r.end=i)),i}var ue={};function le(e,t){for(var n,r,i,o,a,s,u,l=[],c=0,f=e.length;c<f;c++)(r=e[c]).style&&(n=r.style.display,t?("none"===n&&(l[c]=Y.get(r,"display")||null,l[c]||(r.style.display="")),""===r.style.display&&ae(r)&&(l[c]=(u=a=o=void 0,a=(i=r).ownerDocument,s=i.nodeName,(u=ue[s])||(o=a.body.appendChild(a.createElement(s)),u=S.css(o,"display"),o.parentNode.removeChild(o),"none"===u&&(u="block"),ue[s]=u)))):"none"!==n&&(l[c]="none",Y.set(r,"display",n)));for(c=0;c<f;c++)null!=l[c]&&(e[c].style.display=l[c]);return e}S.fn.extend({show:function(){return le(this,!0)},hide:function(){return le(this)},toggle:function(e){return"boolean"==typeof e?e?this.show():this.hide():this.each(function(){ae(this)?S(this).show():S(this).hide()})}});var ce,fe,pe=/^(?:checkbox|radio)$/i,de=/<([a-z][^\/\0>\x20\t\r\n\f]*)/i,he=/^$|^module$|\/(?:java|ecma)script/i;ce=E.createDocumentFragment().appendChild(E.createElement("div")),(fe=E.createElement("input")).setAttribute("type","radio"),fe.setAttribute("checked","checked"),fe.setAttribute("name","t"),ce.appendChild(fe),y.checkClone=ce.cloneNode(!0).cloneNode(!0).lastChild.checked,ce.innerHTML="<textarea>x</textarea>",y.noCloneChecked=!!ce.cloneNode(!0).lastChild.defaultValue,ce.innerHTML="<option></option>",y.option=!!ce.lastChild;var ge={thead:[1,"<table>","</table>"],col:[2,"<table><colgroup>","</colgroup></table>"],tr:[2,"<table><tbody>","</tbody></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],_default:[0,"",""]};function ve(e,t){var n;return n="undefined"!=typeof e.getElementsByTagName?e.getElementsByTagName(t||"*"):"undefined"!=typeof e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&A(e,t)?S.merge([e],n):n}function ye(e,t){for(var n=0,r=e.length;n<r;n++)Y.set(e[n],"globalEval",!t||Y.get(t[n],"globalEval"))}ge.tbody=ge.tfoot=ge.colgroup=ge.caption=ge.thead,ge.th=ge.td,y.option||(ge.optgroup=ge.option=[1,"<select multiple='multiple'>","</select>"]);var me=/<|&#?\w+;/;function xe(e,t,n,r,i){for(var o,a,s,u,l,c,f=t.createDocumentFragment(),p=[],d=0,h=e.length;d<h;d++)if((o=e[d])||0===o)if("object"===w(o))S.merge(p,o.nodeType?[o]:o);else if(me.test(o)){a=a||f.appendChild(t.createElement("div")),s=(de.exec(o)||["",""])[1].toLowerCase(),u=ge[s]||ge._default,a.innerHTML=u[1]+S.htmlPrefilter(o)+u[2],c=u[0];while(c--)a=a.lastChild;S.merge(p,a.childNodes),(a=f.firstChild).textContent=""}else p.push(t.createTextNode(o));f.textContent="",d=0;while(o=p[d++])if(r&&-1<S.inArray(o,r))i&&i.push(o);else if(l=ie(o),a=ve(f.appendChild(o),"script"),l&&ye(a),n){c=0;while(o=a[c++])he.test(o.type||"")&&n.push(o)}return f}var be=/^key/,we=/^(?:mouse|pointer|contextmenu|drag|drop)|click/,Te=/^([^.]*)(?:\.(.+)|)/;function Ce(){return!0}function Ee(){return!1}function Se(e,t){return e===function(){try{return E.activeElement}catch(e){}}()==("focus"===t)}function ke(e,t,n,r,i,o){var a,s;if("object"==typeof t){for(s in"string"!=typeof n&&(r=r||n,n=void 0),t)ke(e,s,n,r,t[s],o);return e}if(null==r&&null==i?(i=n,r=n=void 0):null==i&&("string"==typeof n?(i=r,r=void 0):(i=r,r=n,n=void 0)),!1===i)i=Ee;else if(!i)return e;return 1===o&&(a=i,(i=function(e){return S().off(e),a.apply(this,arguments)}).guid=a.guid||(a.guid=S.guid++)),e.each(function(){S.event.add(this,t,i,r,n)})}function Ae(e,i,o){o?(Y.set(e,i,!1),S.event.add(e,i,{namespace:!1,handler:function(e){var t,n,r=Y.get(this,i);if(1&e.isTrigger&&this[i]){if(r.length)(S.event.special[i]||{}).delegateType&&e.stopPropagation();else if(r=s.call(arguments),Y.set(this,i,r),t=o(this,i),this[i](),r!==(n=Y.get(this,i))||t?Y.set(this,i,!1):n={},r!==n)return e.stopImmediatePropagation(),e.preventDefault(),n.value}else r.length&&(Y.set(this,i,{value:S.event.trigger(S.extend(r[0],S.Event.prototype),r.slice(1),this)}),e.stopImmediatePropagation())}})):void 0===Y.get(e,i)&&S.event.add(e,i,Ce)}S.event={global:{},add:function(t,e,n,r,i){var o,a,s,u,l,c,f,p,d,h,g,v=Y.get(t);if(V(t)){n.handler&&(n=(o=n).handler,i=o.selector),i&&S.find.matchesSelector(re,i),n.guid||(n.guid=S.guid++),(u=v.events)||(u=v.events=Object.create(null)),(a=v.handle)||(a=v.handle=function(e){return"undefined"!=typeof S&&S.event.triggered!==e.type?S.event.dispatch.apply(t,arguments):void 0}),l=(e=(e||"").match(P)||[""]).length;while(l--)d=g=(s=Te.exec(e[l])||[])[1],h=(s[2]||"").split(".").sort(),d&&(f=S.event.special[d]||{},d=(i?f.delegateType:f.bindType)||d,f=S.event.special[d]||{},c=S.extend({type:d,origType:g,data:r,handler:n,guid:n.guid,selector:i,needsContext:i&&S.expr.match.needsContext.test(i),namespace:h.join(".")},o),(p=u[d])||((p=u[d]=[]).delegateCount=0,f.setup&&!1!==f.setup.call(t,r,h,a)||t.addEventListener&&t.addEventListener(d,a)),f.add&&(f.add.call(t,c),c.handler.guid||(c.handler.guid=n.guid)),i?p.splice(p.delegateCount++,0,c):p.push(c),S.event.global[d]=!0)}},remove:function(e,t,n,r,i){var o,a,s,u,l,c,f,p,d,h,g,v=Y.hasData(e)&&Y.get(e);if(v&&(u=v.events)){l=(t=(t||"").match(P)||[""]).length;while(l--)if(d=g=(s=Te.exec(t[l])||[])[1],h=(s[2]||"").split(".").sort(),d){f=S.event.special[d]||{},p=u[d=(r?f.delegateType:f.bindType)||d]||[],s=s[2]&&new RegExp("(^|\\.)"+h.join("\\.(?:.*\\.|)")+"(\\.|$)"),a=o=p.length;while(o--)c=p[o],!i&&g!==c.origType||n&&n.guid!==c.guid||s&&!s.test(c.namespace)||r&&r!==c.selector&&("**"!==r||!c.selector)||(p.splice(o,1),c.selector&&p.delegateCount--,f.remove&&f.remove.call(e,c));a&&!p.length&&(f.teardown&&!1!==f.teardown.call(e,h,v.handle)||S.removeEvent(e,d,v.handle),delete u[d])}else for(d in u)S.event.remove(e,d+t[l],n,r,!0);S.isEmptyObject(u)&&Y.remove(e,"handle events")}},dispatch:function(e){var t,n,r,i,o,a,s=new Array(arguments.length),u=S.event.fix(e),l=(Y.get(this,"events")||Object.create(null))[u.type]||[],c=S.event.special[u.type]||{};for(s[0]=u,t=1;t<arguments.length;t++)s[t]=arguments[t];if(u.delegateTarget=this,!c.preDispatch||!1!==c.preDispatch.call(this,u)){a=S.event.handlers.call(this,u,l),t=0;while((i=a[t++])&&!u.isPropagationStopped()){u.currentTarget=i.elem,n=0;while((o=i.handlers[n++])&&!u.isImmediatePropagationStopped())u.rnamespace&&!1!==o.namespace&&!u.rnamespace.test(o.namespace)||(u.handleObj=o,u.data=o.data,void 0!==(r=((S.event.special[o.origType]||{}).handle||o.handler).apply(i.elem,s))&&!1===(u.result=r)&&(u.preventDefault(),u.stopPropagation()))}return c.postDispatch&&c.postDispatch.call(this,u),u.result}},handlers:function(e,t){var n,r,i,o,a,s=[],u=t.delegateCount,l=e.target;if(u&&l.nodeType&&!("click"===e.type&&1<=e.button))for(;l!==this;l=l.parentNode||this)if(1===l.nodeType&&("click"!==e.type||!0!==l.disabled)){for(o=[],a={},n=0;n<u;n++)void 0===a[i=(r=t[n]).selector+" "]&&(a[i]=r.needsContext?-1<S(i,this).index(l):S.find(i,this,null,[l]).length),a[i]&&o.push(r);o.length&&s.push({elem:l,handlers:o})}return l=this,u<t.length&&s.push({elem:l,handlers:t.slice(u)}),s},addProp:function(t,e){Object.defineProperty(S.Event.prototype,t,{enumerable:!0,configurable:!0,get:m(e)?function(){if(this.originalEvent)return e(this.originalEvent)}:function(){if(this.originalEvent)return this.originalEvent[t]},set:function(e){Object.defineProperty(this,t,{enumerable:!0,configurable:!0,writable:!0,value:e})}})},fix:function(e){return e[S.expando]?e:new S.Event(e)},special:{load:{noBubble:!0},click:{setup:function(e){var t=this||e;return pe.test(t.type)&&t.click&&A(t,"input")&&Ae(t,"click",Ce),!1},trigger:function(e){var t=this||e;return pe.test(t.type)&&t.click&&A(t,"input")&&Ae(t,"click"),!0},_default:function(e){var t=e.target;return pe.test(t.type)&&t.click&&A(t,"input")&&Y.get(t,"click")||A(t,"a")}},beforeunload:{postDispatch:function(e){void 0!==e.result&&e.originalEvent&&(e.originalEvent.returnValue=e.result)}}}},S.removeEvent=function(e,t,n){e.removeEventListener&&e.removeEventListener(t,n)},S.Event=function(e,t){if(!(this instanceof S.Event))return new S.Event(e,t);e&&e.type?(this.originalEvent=e,this.type=e.type,this.isDefaultPrevented=e.defaultPrevented||void 0===e.defaultPrevented&&!1===e.returnValue?Ce:Ee,this.target=e.target&&3===e.target.nodeType?e.target.parentNode:e.target,this.currentTarget=e.currentTarget,this.relatedTarget=e.relatedTarget):this.type=e,t&&S.extend(this,t),this.timeStamp=e&&e.timeStamp||Date.now(),this[S.expando]=!0},S.Event.prototype={constructor:S.Event,isDefaultPrevented:Ee,isPropagationStopped:Ee,isImmediatePropagationStopped:Ee,isSimulated:!1,preventDefault:function(){var e=this.originalEvent;this.isDefaultPrevented=Ce,e&&!this.isSimulated&&e.preventDefault()},stopPropagation:function(){var e=this.originalEvent;this.isPropagationStopped=Ce,e&&!this.isSimulated&&e.stopPropagation()},stopImmediatePropagation:function(){var e=this.originalEvent;this.isImmediatePropagationStopped=Ce,e&&!this.isSimulated&&e.stopImmediatePropagation(),this.stopPropagation()}},S.each({altKey:!0,bubbles:!0,cancelable:!0,changedTouches:!0,ctrlKey:!0,detail:!0,eventPhase:!0,metaKey:!0,pageX:!0,pageY:!0,shiftKey:!0,view:!0,"char":!0,code:!0,charCode:!0,key:!0,keyCode:!0,button:!0,buttons:!0,clientX:!0,clientY:!0,offsetX:!0,offsetY:!0,pointerId:!0,pointerType:!0,screenX:!0,screenY:!0,targetTouches:!0,toElement:!0,touches:!0,which:function(e){var t=e.button;return null==e.which&&be.test(e.type)?null!=e.charCode?e.charCode:e.keyCode:!e.which&&void 0!==t&&we.test(e.type)?1&t?1:2&t?3:4&t?2:0:e.which}},S.event.addProp),S.each({focus:"focusin",blur:"focusout"},function(e,t){S.event.special[e]={setup:function(){return Ae(this,e,Se),!1},trigger:function(){return Ae(this,e),!0},delegateType:t}}),S.each({mouseenter:"mouseover",mouseleave:"mouseout",pointerenter:"pointerover",pointerleave:"pointerout"},function(e,i){S.event.special[e]={delegateType:i,bindType:i,handle:function(e){var t,n=e.relatedTarget,r=e.handleObj;return n&&(n===this||S.contains(this,n))||(e.type=r.origType,t=r.handler.apply(this,arguments),e.type=i),t}}}),S.fn.extend({on:function(e,t,n,r){return ke(this,e,t,n,r)},one:function(e,t,n,r){return ke(this,e,t,n,r,1)},off:function(e,t,n){var r,i;if(e&&e.preventDefault&&e.handleObj)return r=e.handleObj,S(e.delegateTarget).off(r.namespace?r.origType+"."+r.namespace:r.origType,r.selector,r.handler),this;if("object"==typeof e){for(i in e)this.off(i,t,e[i]);return this}return!1!==t&&"function"!=typeof t||(n=t,t=void 0),!1===n&&(n=Ee),this.each(function(){S.event.remove(this,e,n,t)})}});var Ne=/<script|<style|<link/i,De=/checked\s*(?:[^=]|=\s*.checked.)/i,je=/^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g;function qe(e,t){return A(e,"table")&&A(11!==t.nodeType?t:t.firstChild,"tr")&&S(e).children("tbody")[0]||e}function Le(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function He(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function Oe(e,t){var n,r,i,o,a,s;if(1===t.nodeType){if(Y.hasData(e)&&(s=Y.get(e).events))for(i in Y.remove(t,"handle events"),s)for(n=0,r=s[i].length;n<r;n++)S.event.add(t,i,s[i][n]);Q.hasData(e)&&(o=Q.access(e),a=S.extend({},o),Q.set(t,a))}}function Pe(n,r,i,o){r=g(r);var e,t,a,s,u,l,c=0,f=n.length,p=f-1,d=r[0],h=m(d);if(h||1<f&&"string"==typeof d&&!y.checkClone&&De.test(d))return n.each(function(e){var t=n.eq(e);h&&(r[0]=d.call(this,e,t.html())),Pe(t,r,i,o)});if(f&&(t=(e=xe(r,n[0].ownerDocument,!1,n,o)).firstChild,1===e.childNodes.length&&(e=t),t||o)){for(s=(a=S.map(ve(e,"script"),Le)).length;c<f;c++)u=e,c!==p&&(u=S.clone(u,!0,!0),s&&S.merge(a,ve(u,"script"))),i.call(n[c],u,c);if(s)for(l=a[a.length-1].ownerDocument,S.map(a,He),c=0;c<s;c++)u=a[c],he.test(u.type||"")&&!Y.access(u,"globalEval")&&S.contains(l,u)&&(u.src&&"module"!==(u.type||"").toLowerCase()?S._evalUrl&&!u.noModule&&S._evalUrl(u.src,{nonce:u.nonce||u.getAttribute("nonce")},l):b(u.textContent.replace(je,""),u,l))}return n}function Re(e,t,n){for(var r,i=t?S.filter(t,e):e,o=0;null!=(r=i[o]);o++)n||1!==r.nodeType||S.cleanData(ve(r)),r.parentNode&&(n&&ie(r)&&ye(ve(r,"script")),r.parentNode.removeChild(r));return e}S.extend({htmlPrefilter:function(e){return e},clone:function(e,t,n){var r,i,o,a,s,u,l,c=e.cloneNode(!0),f=ie(e);if(!(y.noCloneChecked||1!==e.nodeType&&11!==e.nodeType||S.isXMLDoc(e)))for(a=ve(c),r=0,i=(o=ve(e)).length;r<i;r++)s=o[r],u=a[r],void 0,"input"===(l=u.nodeName.toLowerCase())&&pe.test(s.type)?u.checked=s.checked:"input"!==l&&"textarea"!==l||(u.defaultValue=s.defaultValue);if(t)if(n)for(o=o||ve(e),a=a||ve(c),r=0,i=o.length;r<i;r++)Oe(o[r],a[r]);else Oe(e,c);return 0<(a=ve(c,"script")).length&&ye(a,!f&&ve(e,"script")),c},cleanData:function(e){for(var t,n,r,i=S.event.special,o=0;void 0!==(n=e[o]);o++)if(V(n)){if(t=n[Y.expando]){if(t.events)for(r in t.events)i[r]?S.event.remove(n,r):S.removeEvent(n,r,t.handle);n[Y.expando]=void 0}n[Q.expando]&&(n[Q.expando]=void 0)}}}),S.fn.extend({detach:function(e){return Re(this,e,!0)},remove:function(e){return Re(this,e)},text:function(e){return $(this,function(e){return void 0===e?S.text(this):this.empty().each(function(){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||(this.textContent=e)})},null,e,arguments.length)},append:function(){return Pe(this,arguments,function(e){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||qe(this,e).appendChild(e)})},prepend:function(){return Pe(this,arguments,function(e){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var t=qe(this,e);t.insertBefore(e,t.firstChild)}})},before:function(){return Pe(this,arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this)})},after:function(){return Pe(this,arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this.nextSibling)})},empty:function(){for(var e,t=0;null!=(e=this[t]);t++)1===e.nodeType&&(S.cleanData(ve(e,!1)),e.textContent="");return this},clone:function(e,t){return e=null!=e&&e,t=null==t?e:t,this.map(function(){return S.clone(this,e,t)})},html:function(e){return $(this,function(e){var t=this[0]||{},n=0,r=this.length;if(void 0===e&&1===t.nodeType)return t.innerHTML;if("string"==typeof e&&!Ne.test(e)&&!ge[(de.exec(e)||["",""])[1].toLowerCase()]){e=S.htmlPrefilter(e);try{for(;n<r;n++)1===(t=this[n]||{}).nodeType&&(S.cleanData(ve(t,!1)),t.innerHTML=e);t=0}catch(e){}}t&&this.empty().append(e)},null,e,arguments.length)},replaceWith:function(){var n=[];return Pe(this,arguments,function(e){var t=this.parentNode;S.inArray(this,n)<0&&(S.cleanData(ve(this)),t&&t.replaceChild(e,this))},n)}}),S.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(e,a){S.fn[e]=function(e){for(var t,n=[],r=S(e),i=r.length-1,o=0;o<=i;o++)t=o===i?this:this.clone(!0),S(r[o])[a](t),u.apply(n,t.get());return this.pushStack(n)}});var Me=new RegExp("^("+ee+")(?!px)[a-z%]+$","i"),Ie=function(e){var t=e.ownerDocument.defaultView;return t&&t.opener||(t=C),t.getComputedStyle(e)},We=function(e,t,n){var r,i,o={};for(i in t)o[i]=e.style[i],e.style[i]=t[i];for(i in r=n.call(e),t)e.style[i]=o[i];return r},Fe=new RegExp(ne.join("|"),"i");function Be(e,t,n){var r,i,o,a,s=e.style;return(n=n||Ie(e))&&(""!==(a=n.getPropertyValue(t)||n[t])||ie(e)||(a=S.style(e,t)),!y.pixelBoxStyles()&&Me.test(a)&&Fe.test(t)&&(r=s.width,i=s.minWidth,o=s.maxWidth,s.minWidth=s.maxWidth=s.width=a,a=n.width,s.width=r,s.minWidth=i,s.maxWidth=o)),void 0!==a?a+"":a}function $e(e,t){return{get:function(){if(!e())return(this.get=t).apply(this,arguments);delete this.get}}}!function(){function e(){if(l){u.style.cssText="position:absolute;left:-11111px;width:60px;margin-top:1px;padding:0;border:0",l.style.cssText="position:relative;display:block;box-sizing:border-box;overflow:scroll;margin:auto;border:1px;padding:1px;width:60%;top:1%",re.appendChild(u).appendChild(l);var e=C.getComputedStyle(l);n="1%"!==e.top,s=12===t(e.marginLeft),l.style.right="60%",o=36===t(e.right),r=36===t(e.width),l.style.position="absolute",i=12===t(l.offsetWidth/3),re.removeChild(u),l=null}}function t(e){return Math.round(parseFloat(e))}var n,r,i,o,a,s,u=E.createElement("div"),l=E.createElement("div");l.style&&(l.style.backgroundClip="content-box",l.cloneNode(!0).style.backgroundClip="",y.clearCloneStyle="content-box"===l.style.backgroundClip,S.extend(y,{boxSizingReliable:function(){return e(),r},pixelBoxStyles:function(){return e(),o},pixelPosition:function(){return e(),n},reliableMarginLeft:function(){return e(),s},scrollboxSize:function(){return e(),i},reliableTrDimensions:function(){var e,t,n,r;return null==a&&(e=E.createElement("table"),t=E.createElement("tr"),n=E.createElement("div"),e.style.cssText="position:absolute;left:-11111px",t.style.height="1px",n.style.height="9px",re.appendChild(e).appendChild(t).appendChild(n),r=C.getComputedStyle(t),a=3<parseInt(r.height),re.removeChild(e)),a}}))}();var _e=["Webkit","Moz","ms"],ze=E.createElement("div").style,Ue={};function Xe(e){var t=S.cssProps[e]||Ue[e];return t||(e in ze?e:Ue[e]=function(e){var t=e[0].toUpperCase()+e.slice(1),n=_e.length;while(n--)if((e=_e[n]+t)in ze)return e}(e)||e)}var Ve=/^(none|table(?!-c[ea]).+)/,Ge=/^--/,Ye={position:"absolute",visibility:"hidden",display:"block"},Qe={letterSpacing:"0",fontWeight:"400"};function Je(e,t,n){var r=te.exec(t);return r?Math.max(0,r[2]-(n||0))+(r[3]||"px"):t}function Ke(e,t,n,r,i,o){var a="width"===t?1:0,s=0,u=0;if(n===(r?"border":"content"))return 0;for(;a<4;a+=2)"margin"===n&&(u+=S.css(e,n+ne[a],!0,i)),r?("content"===n&&(u-=S.css(e,"padding"+ne[a],!0,i)),"margin"!==n&&(u-=S.css(e,"border"+ne[a]+"Width",!0,i))):(u+=S.css(e,"padding"+ne[a],!0,i),"padding"!==n?u+=S.css(e,"border"+ne[a]+"Width",!0,i):s+=S.css(e,"border"+ne[a]+"Width",!0,i));return!r&&0<=o&&(u+=Math.max(0,Math.ceil(e["offset"+t[0].toUpperCase()+t.slice(1)]-o-u-s-.5))||0),u}function Ze(e,t,n){var r=Ie(e),i=(!y.boxSizingReliable()||n)&&"border-box"===S.css(e,"boxSizing",!1,r),o=i,a=Be(e,t,r),s="offset"+t[0].toUpperCase()+t.slice(1);if(Me.test(a)){if(!n)return a;a="auto"}return(!y.boxSizingReliable()&&i||!y.reliableTrDimensions()&&A(e,"tr")||"auto"===a||!parseFloat(a)&&"inline"===S.css(e,"display",!1,r))&&e.getClientRects().length&&(i="border-box"===S.css(e,"boxSizing",!1,r),(o=s in e)&&(a=e[s])),(a=parseFloat(a)||0)+Ke(e,t,n||(i?"border":"content"),o,r,a)+"px"}function et(e,t,n,r,i){return new et.prototype.init(e,t,n,r,i)}S.extend({cssHooks:{opacity:{get:function(e,t){if(t){var n=Be(e,"opacity");return""===n?"1":n}}}},cssNumber:{animationIterationCount:!0,columnCount:!0,fillOpacity:!0,flexGrow:!0,flexShrink:!0,fontWeight:!0,gridArea:!0,gridColumn:!0,gridColumnEnd:!0,gridColumnStart:!0,gridRow:!0,gridRowEnd:!0,gridRowStart:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{},style:function(e,t,n,r){if(e&&3!==e.nodeType&&8!==e.nodeType&&e.style){var i,o,a,s=X(t),u=Ge.test(t),l=e.style;if(u||(t=Xe(s)),a=S.cssHooks[t]||S.cssHooks[s],void 0===n)return a&&"get"in a&&void 0!==(i=a.get(e,!1,r))?i:l[t];"string"===(o=typeof n)&&(i=te.exec(n))&&i[1]&&(n=se(e,t,i),o="number"),null!=n&&n==n&&("number"!==o||u||(n+=i&&i[3]||(S.cssNumber[s]?"":"px")),y.clearCloneStyle||""!==n||0!==t.indexOf("background")||(l[t]="inherit"),a&&"set"in a&&void 0===(n=a.set(e,n,r))||(u?l.setProperty(t,n):l[t]=n))}},css:function(e,t,n,r){var i,o,a,s=X(t);return Ge.test(t)||(t=Xe(s)),(a=S.cssHooks[t]||S.cssHooks[s])&&"get"in a&&(i=a.get(e,!0,n)),void 0===i&&(i=Be(e,t,r)),"normal"===i&&t in Qe&&(i=Qe[t]),""===n||n?(o=parseFloat(i),!0===n||isFinite(o)?o||0:i):i}}),S.each(["height","width"],function(e,u){S.cssHooks[u]={get:function(e,t,n){if(t)return!Ve.test(S.css(e,"display"))||e.getClientRects().length&&e.getBoundingClientRect().width?Ze(e,u,n):We(e,Ye,function(){return Ze(e,u,n)})},set:function(e,t,n){var r,i=Ie(e),o=!y.scrollboxSize()&&"absolute"===i.position,a=(o||n)&&"border-box"===S.css(e,"boxSizing",!1,i),s=n?Ke(e,u,n,a,i):0;return a&&o&&(s-=Math.ceil(e["offset"+u[0].toUpperCase()+u.slice(1)]-parseFloat(i[u])-Ke(e,u,"border",!1,i)-.5)),s&&(r=te.exec(t))&&"px"!==(r[3]||"px")&&(e.style[u]=t,t=S.css(e,u)),Je(0,t,s)}}}),S.cssHooks.marginLeft=$e(y.reliableMarginLeft,function(e,t){if(t)return(parseFloat(Be(e,"marginLeft"))||e.getBoundingClientRect().left-We(e,{marginLeft:0},function(){return e.getBoundingClientRect().left}))+"px"}),S.each({margin:"",padding:"",border:"Width"},function(i,o){S.cssHooks[i+o]={expand:function(e){for(var t=0,n={},r="string"==typeof e?e.split(" "):[e];t<4;t++)n[i+ne[t]+o]=r[t]||r[t-2]||r[0];return n}},"margin"!==i&&(S.cssHooks[i+o].set=Je)}),S.fn.extend({css:function(e,t){return $(this,function(e,t,n){var r,i,o={},a=0;if(Array.isArray(t)){for(r=Ie(e),i=t.length;a<i;a++)o[t[a]]=S.css(e,t[a],!1,r);return o}return void 0!==n?S.style(e,t,n):S.css(e,t)},e,t,1<arguments.length)}}),((S.Tween=et).prototype={constructor:et,init:function(e,t,n,r,i,o){this.elem=e,this.prop=n,this.easing=i||S.easing._default,this.options=t,this.start=this.now=this.cur(),this.end=r,this.unit=o||(S.cssNumber[n]?"":"px")},cur:function(){var e=et.propHooks[this.prop];return e&&e.get?e.get(this):et.propHooks._default.get(this)},run:function(e){var t,n=et.propHooks[this.prop];return this.options.duration?this.pos=t=S.easing[this.easing](e,this.options.duration*e,0,1,this.options.duration):this.pos=t=e,this.now=(this.end-this.start)*t+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),n&&n.set?n.set(this):et.propHooks._default.set(this),this}}).init.prototype=et.prototype,(et.propHooks={_default:{get:function(e){var t;return 1!==e.elem.nodeType||null!=e.elem[e.prop]&&null==e.elem.style[e.prop]?e.elem[e.prop]:(t=S.css(e.elem,e.prop,""))&&"auto"!==t?t:0},set:function(e){S.fx.step[e.prop]?S.fx.step[e.prop](e):1!==e.elem.nodeType||!S.cssHooks[e.prop]&&null==e.elem.style[Xe(e.prop)]?e.elem[e.prop]=e.now:S.style(e.elem,e.prop,e.now+e.unit)}}}).scrollTop=et.propHooks.scrollLeft={set:function(e){e.elem.nodeType&&e.elem.parentNode&&(e.elem[e.prop]=e.now)}},S.easing={linear:function(e){return e},swing:function(e){return.5-Math.cos(e*Math.PI)/2},_default:"swing"},S.fx=et.prototype.init,S.fx.step={};var tt,nt,rt,it,ot=/^(?:toggle|show|hide)$/,at=/queueHooks$/;function st(){nt&&(!1===E.hidden&&C.requestAnimationFrame?C.requestAnimationFrame(st):C.setTimeout(st,S.fx.interval),S.fx.tick())}function ut(){return C.setTimeout(function(){tt=void 0}),tt=Date.now()}function lt(e,t){var n,r=0,i={height:e};for(t=t?1:0;r<4;r+=2-t)i["margin"+(n=ne[r])]=i["padding"+n]=e;return t&&(i.opacity=i.width=e),i}function ct(e,t,n){for(var r,i=(ft.tweeners[t]||[]).concat(ft.tweeners["*"]),o=0,a=i.length;o<a;o++)if(r=i[o].call(n,t,e))return r}function ft(o,e,t){var n,a,r=0,i=ft.prefilters.length,s=S.Deferred().always(function(){delete u.elem}),u=function(){if(a)return!1;for(var e=tt||ut(),t=Math.max(0,l.startTime+l.duration-e),n=1-(t/l.duration||0),r=0,i=l.tweens.length;r<i;r++)l.tweens[r].run(n);return s.notifyWith(o,[l,n,t]),n<1&&i?t:(i||s.notifyWith(o,[l,1,0]),s.resolveWith(o,[l]),!1)},l=s.promise({elem:o,props:S.extend({},e),opts:S.extend(!0,{specialEasing:{},easing:S.easing._default},t),originalProperties:e,originalOptions:t,startTime:tt||ut(),duration:t.duration,tweens:[],createTween:function(e,t){var n=S.Tween(o,l.opts,e,t,l.opts.specialEasing[e]||l.opts.easing);return l.tweens.push(n),n},stop:function(e){var t=0,n=e?l.tweens.length:0;if(a)return this;for(a=!0;t<n;t++)l.tweens[t].run(1);return e?(s.notifyWith(o,[l,1,0]),s.resolveWith(o,[l,e])):s.rejectWith(o,[l,e]),this}}),c=l.props;for(!function(e,t){var n,r,i,o,a;for(n in e)if(i=t[r=X(n)],o=e[n],Array.isArray(o)&&(i=o[1],o=e[n]=o[0]),n!==r&&(e[r]=o,delete e[n]),(a=S.cssHooks[r])&&"expand"in a)for(n in o=a.expand(o),delete e[r],o)n in e||(e[n]=o[n],t[n]=i);else t[r]=i}(c,l.opts.specialEasing);r<i;r++)if(n=ft.prefilters[r].call(l,o,c,l.opts))return m(n.stop)&&(S._queueHooks(l.elem,l.opts.queue).stop=n.stop.bind(n)),n;return S.map(c,ct,l),m(l.opts.start)&&l.opts.start.call(o,l),l.progress(l.opts.progress).done(l.opts.done,l.opts.complete).fail(l.opts.fail).always(l.opts.always),S.fx.timer(S.extend(u,{elem:o,anim:l,queue:l.opts.queue})),l}S.Animation=S.extend(ft,{tweeners:{"*":[function(e,t){var n=this.createTween(e,t);return se(n.elem,e,te.exec(t),n),n}]},tweener:function(e,t){m(e)?(t=e,e=["*"]):e=e.match(P);for(var n,r=0,i=e.length;r<i;r++)n=e[r],ft.tweeners[n]=ft.tweeners[n]||[],ft.tweeners[n].unshift(t)},prefilters:[function(e,t,n){var r,i,o,a,s,u,l,c,f="width"in t||"height"in t,p=this,d={},h=e.style,g=e.nodeType&&ae(e),v=Y.get(e,"fxshow");for(r in n.queue||(null==(a=S._queueHooks(e,"fx")).unqueued&&(a.unqueued=0,s=a.empty.fire,a.empty.fire=function(){a.unqueued||s()}),a.unqueued++,p.always(function(){p.always(function(){a.unqueued--,S.queue(e,"fx").length||a.empty.fire()})})),t)if(i=t[r],ot.test(i)){if(delete t[r],o=o||"toggle"===i,i===(g?"hide":"show")){if("show"!==i||!v||void 0===v[r])continue;g=!0}d[r]=v&&v[r]||S.style(e,r)}if((u=!S.isEmptyObject(t))||!S.isEmptyObject(d))for(r in f&&1===e.nodeType&&(n.overflow=[h.overflow,h.overflowX,h.overflowY],null==(l=v&&v.display)&&(l=Y.get(e,"display")),"none"===(c=S.css(e,"display"))&&(l?c=l:(le([e],!0),l=e.style.display||l,c=S.css(e,"display"),le([e]))),("inline"===c||"inline-block"===c&&null!=l)&&"none"===S.css(e,"float")&&(u||(p.done(function(){h.display=l}),null==l&&(c=h.display,l="none"===c?"":c)),h.display="inline-block")),n.overflow&&(h.overflow="hidden",p.always(function(){h.overflow=n.overflow[0],h.overflowX=n.overflow[1],h.overflowY=n.overflow[2]})),u=!1,d)u||(v?"hidden"in v&&(g=v.hidden):v=Y.access(e,"fxshow",{display:l}),o&&(v.hidden=!g),g&&le([e],!0),p.done(function(){for(r in g||le([e]),Y.remove(e,"fxshow"),d)S.style(e,r,d[r])})),u=ct(g?v[r]:0,r,p),r in v||(v[r]=u.start,g&&(u.end=u.start,u.start=0))}],prefilter:function(e,t){t?ft.prefilters.unshift(e):ft.prefilters.push(e)}}),S.speed=function(e,t,n){var r=e&&"object"==typeof e?S.extend({},e):{complete:n||!n&&t||m(e)&&e,duration:e,easing:n&&t||t&&!m(t)&&t};return S.fx.off?r.duration=0:"number"!=typeof r.duration&&(r.duration in S.fx.speeds?r.duration=S.fx.speeds[r.duration]:r.duration=S.fx.speeds._default),null!=r.queue&&!0!==r.queue||(r.queue="fx"),r.old=r.complete,r.complete=function(){m(r.old)&&r.old.call(this),r.queue&&S.dequeue(this,r.queue)},r},S.fn.extend({fadeTo:function(e,t,n,r){return this.filter(ae).css("opacity",0).show().end().animate({opacity:t},e,n,r)},animate:function(t,e,n,r){var i=S.isEmptyObject(t),o=S.speed(e,n,r),a=function(){var e=ft(this,S.extend({},t),o);(i||Y.get(this,"finish"))&&e.stop(!0)};return a.finish=a,i||!1===o.queue?this.each(a):this.queue(o.queue,a)},stop:function(i,e,o){var a=function(e){var t=e.stop;delete e.stop,t(o)};return"string"!=typeof i&&(o=e,e=i,i=void 0),e&&this.queue(i||"fx",[]),this.each(function(){var e=!0,t=null!=i&&i+"queueHooks",n=S.timers,r=Y.get(this);if(t)r[t]&&r[t].stop&&a(r[t]);else for(t in r)r[t]&&r[t].stop&&at.test(t)&&a(r[t]);for(t=n.length;t--;)n[t].elem!==this||null!=i&&n[t].queue!==i||(n[t].anim.stop(o),e=!1,n.splice(t,1));!e&&o||S.dequeue(this,i)})},finish:function(a){return!1!==a&&(a=a||"fx"),this.each(function(){var e,t=Y.get(this),n=t[a+"queue"],r=t[a+"queueHooks"],i=S.timers,o=n?n.length:0;for(t.finish=!0,S.queue(this,a,[]),r&&r.stop&&r.stop.call(this,!0),e=i.length;e--;)i[e].elem===this&&i[e].queue===a&&(i[e].anim.stop(!0),i.splice(e,1));for(e=0;e<o;e++)n[e]&&n[e].finish&&n[e].finish.call(this);delete t.finish})}}),S.each(["toggle","show","hide"],function(e,r){var i=S.fn[r];S.fn[r]=function(e,t,n){return null==e||"boolean"==typeof e?i.apply(this,arguments):this.animate(lt(r,!0),e,t,n)}}),S.each({slideDown:lt("show"),slideUp:lt("hide"),slideToggle:lt("toggle"),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(e,r){S.fn[e]=function(e,t,n){return this.animate(r,e,t,n)}}),S.timers=[],S.fx.tick=function(){var e,t=0,n=S.timers;for(tt=Date.now();t<n.length;t++)(e=n[t])()||n[t]!==e||n.splice(t--,1);n.length||S.fx.stop(),tt=void 0},S.fx.timer=function(e){S.timers.push(e),S.fx.start()},S.fx.interval=13,S.fx.start=function(){nt||(nt=!0,st())},S.fx.stop=function(){nt=null},S.fx.speeds={slow:600,fast:200,_default:400},S.fn.delay=function(r,e){return r=S.fx&&S.fx.speeds[r]||r,e=e||"fx",this.queue(e,function(e,t){var n=C.setTimeout(e,r);t.stop=function(){C.clearTimeout(n)}})},rt=E.createElement("input"),it=E.createElement("select").appendChild(E.createElement("option")),rt.type="checkbox",y.checkOn=""!==rt.value,y.optSelected=it.selected,(rt=E.createElement("input")).value="t",rt.type="radio",y.radioValue="t"===rt.value;var pt,dt=S.expr.attrHandle;S.fn.extend({attr:function(e,t){return $(this,S.attr,e,t,1<arguments.length)},removeAttr:function(e){return this.each(function(){S.removeAttr(this,e)})}}),S.extend({attr:function(e,t,n){var r,i,o=e.nodeType;if(3!==o&&8!==o&&2!==o)return"undefined"==typeof e.getAttribute?S.prop(e,t,n):(1===o&&S.isXMLDoc(e)||(i=S.attrHooks[t.toLowerCase()]||(S.expr.match.bool.test(t)?pt:void 0)),void 0!==n?null===n?void S.removeAttr(e,t):i&&"set"in i&&void 0!==(r=i.set(e,n,t))?r:(e.setAttribute(t,n+""),n):i&&"get"in i&&null!==(r=i.get(e,t))?r:null==(r=S.find.attr(e,t))?void 0:r)},attrHooks:{type:{set:function(e,t){if(!y.radioValue&&"radio"===t&&A(e,"input")){var n=e.value;return e.setAttribute("type",t),n&&(e.value=n),t}}}},removeAttr:function(e,t){var n,r=0,i=t&&t.match(P);if(i&&1===e.nodeType)while(n=i[r++])e.removeAttribute(n)}}),pt={set:function(e,t,n){return!1===t?S.removeAttr(e,n):e.setAttribute(n,n),n}},S.each(S.expr.match.bool.source.match(/\w+/g),function(e,t){var a=dt[t]||S.find.attr;dt[t]=function(e,t,n){var r,i,o=t.toLowerCase();return n||(i=dt[o],dt[o]=r,r=null!=a(e,t,n)?o:null,dt[o]=i),r}});var ht=/^(?:input|select|textarea|button)$/i,gt=/^(?:a|area)$/i;function vt(e){return(e.match(P)||[]).join(" ")}function yt(e){return e.getAttribute&&e.getAttribute("class")||""}function mt(e){return Array.isArray(e)?e:"string"==typeof e&&e.match(P)||[]}S.fn.extend({prop:function(e,t){return $(this,S.prop,e,t,1<arguments.length)},removeProp:function(e){return this.each(function(){delete this[S.propFix[e]||e]})}}),S.extend({prop:function(e,t,n){var r,i,o=e.nodeType;if(3!==o&&8!==o&&2!==o)return 1===o&&S.isXMLDoc(e)||(t=S.propFix[t]||t,i=S.propHooks[t]),void 0!==n?i&&"set"in i&&void 0!==(r=i.set(e,n,t))?r:e[t]=n:i&&"get"in i&&null!==(r=i.get(e,t))?r:e[t]},propHooks:{tabIndex:{get:function(e){var t=S.find.attr(e,"tabindex");return t?parseInt(t,10):ht.test(e.nodeName)||gt.test(e.nodeName)&&e.href?0:-1}}},propFix:{"for":"htmlFor","class":"className"}}),y.optSelected||(S.propHooks.selected={get:function(e){var t=e.parentNode;return t&&t.parentNode&&t.parentNode.selectedIndex,null},set:function(e){var t=e.parentNode;t&&(t.selectedIndex,t.parentNode&&t.parentNode.selectedIndex)}}),S.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],function(){S.propFix[this.toLowerCase()]=this}),S.fn.extend({addClass:function(t){var e,n,r,i,o,a,s,u=0;if(m(t))return this.each(function(e){S(this).addClass(t.call(this,e,yt(this)))});if((e=mt(t)).length)while(n=this[u++])if(i=yt(n),r=1===n.nodeType&&" "+vt(i)+" "){a=0;while(o=e[a++])r.indexOf(" "+o+" ")<0&&(r+=o+" ");i!==(s=vt(r))&&n.setAttribute("class",s)}return this},removeClass:function(t){var e,n,r,i,o,a,s,u=0;if(m(t))return this.each(function(e){S(this).removeClass(t.call(this,e,yt(this)))});if(!arguments.length)return this.attr("class","");if((e=mt(t)).length)while(n=this[u++])if(i=yt(n),r=1===n.nodeType&&" "+vt(i)+" "){a=0;while(o=e[a++])while(-1<r.indexOf(" "+o+" "))r=r.replace(" "+o+" "," ");i!==(s=vt(r))&&n.setAttribute("class",s)}return this},toggleClass:function(i,t){var o=typeof i,a="string"===o||Array.isArray(i);return"boolean"==typeof t&&a?t?this.addClass(i):this.removeClass(i):m(i)?this.each(function(e){S(this).toggleClass(i.call(this,e,yt(this),t),t)}):this.each(function(){var e,t,n,r;if(a){t=0,n=S(this),r=mt(i);while(e=r[t++])n.hasClass(e)?n.removeClass(e):n.addClass(e)}else void 0!==i&&"boolean"!==o||((e=yt(this))&&Y.set(this,"__className__",e),this.setAttribute&&this.setAttribute("class",e||!1===i?"":Y.get(this,"__className__")||""))})},hasClass:function(e){var t,n,r=0;t=" "+e+" ";while(n=this[r++])if(1===n.nodeType&&-1<(" "+vt(yt(n))+" ").indexOf(t))return!0;return!1}});var xt=/\r/g;S.fn.extend({val:function(n){var r,e,i,t=this[0];return arguments.length?(i=m(n),this.each(function(e){var t;1===this.nodeType&&(null==(t=i?n.call(this,e,S(this).val()):n)?t="":"number"==typeof t?t+="":Array.isArray(t)&&(t=S.map(t,function(e){return null==e?"":e+""})),(r=S.valHooks[this.type]||S.valHooks[this.nodeName.toLowerCase()])&&"set"in r&&void 0!==r.set(this,t,"value")||(this.value=t))})):t?(r=S.valHooks[t.type]||S.valHooks[t.nodeName.toLowerCase()])&&"get"in r&&void 0!==(e=r.get(t,"value"))?e:"string"==typeof(e=t.value)?e.replace(xt,""):null==e?"":e:void 0}}),S.extend({valHooks:{option:{get:function(e){var t=S.find.attr(e,"value");return null!=t?t:vt(S.text(e))}},select:{get:function(e){var t,n,r,i=e.options,o=e.selectedIndex,a="select-one"===e.type,s=a?null:[],u=a?o+1:i.length;for(r=o<0?u:a?o:0;r<u;r++)if(((n=i[r]).selected||r===o)&&!n.disabled&&(!n.parentNode.disabled||!A(n.parentNode,"optgroup"))){if(t=S(n).val(),a)return t;s.push(t)}return s},set:function(e,t){var n,r,i=e.options,o=S.makeArray(t),a=i.length;while(a--)((r=i[a]).selected=-1<S.inArray(S.valHooks.option.get(r),o))&&(n=!0);return n||(e.selectedIndex=-1),o}}}}),S.each(["radio","checkbox"],function(){S.valHooks[this]={set:function(e,t){if(Array.isArray(t))return e.checked=-1<S.inArray(S(e).val(),t)}},y.checkOn||(S.valHooks[this].get=function(e){return null===e.getAttribute("value")?"on":e.value})}),y.focusin="onfocusin"in C;var bt=/^(?:focusinfocus|focusoutblur)$/,wt=function(e){e.stopPropagation()};S.extend(S.event,{trigger:function(e,t,n,r){var i,o,a,s,u,l,c,f,p=[n||E],d=v.call(e,"type")?e.type:e,h=v.call(e,"namespace")?e.namespace.split("."):[];if(o=f=a=n=n||E,3!==n.nodeType&&8!==n.nodeType&&!bt.test(d+S.event.triggered)&&(-1<d.indexOf(".")&&(d=(h=d.split(".")).shift(),h.sort()),u=d.indexOf(":")<0&&"on"+d,(e=e[S.expando]?e:new S.Event(d,"object"==typeof e&&e)).isTrigger=r?2:3,e.namespace=h.join("."),e.rnamespace=e.namespace?new RegExp("(^|\\.)"+h.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,e.result=void 0,e.target||(e.target=n),t=null==t?[e]:S.makeArray(t,[e]),c=S.event.special[d]||{},r||!c.trigger||!1!==c.trigger.apply(n,t))){if(!r&&!c.noBubble&&!x(n)){for(s=c.delegateType||d,bt.test(s+d)||(o=o.parentNode);o;o=o.parentNode)p.push(o),a=o;a===(n.ownerDocument||E)&&p.push(a.defaultView||a.parentWindow||C)}i=0;while((o=p[i++])&&!e.isPropagationStopped())f=o,e.type=1<i?s:c.bindType||d,(l=(Y.get(o,"events")||Object.create(null))[e.type]&&Y.get(o,"handle"))&&l.apply(o,t),(l=u&&o[u])&&l.apply&&V(o)&&(e.result=l.apply(o,t),!1===e.result&&e.preventDefault());return e.type=d,r||e.isDefaultPrevented()||c._default&&!1!==c._default.apply(p.pop(),t)||!V(n)||u&&m(n[d])&&!x(n)&&((a=n[u])&&(n[u]=null),S.event.triggered=d,e.isPropagationStopped()&&f.addEventListener(d,wt),n[d](),e.isPropagationStopped()&&f.removeEventListener(d,wt),S.event.triggered=void 0,a&&(n[u]=a)),e.result}},simulate:function(e,t,n){var r=S.extend(new S.Event,n,{type:e,isSimulated:!0});S.event.trigger(r,null,t)}}),S.fn.extend({trigger:function(e,t){return this.each(function(){S.event.trigger(e,t,this)})},triggerHandler:function(e,t){var n=this[0];if(n)return S.event.trigger(e,t,n,!0)}}),y.focusin||S.each({focus:"focusin",blur:"focusout"},function(n,r){var i=function(e){S.event.simulate(r,e.target,S.event.fix(e))};S.event.special[r]={setup:function(){var e=this.ownerDocument||this.document||this,t=Y.access(e,r);t||e.addEventListener(n,i,!0),Y.access(e,r,(t||0)+1)},teardown:function(){var e=this.ownerDocument||this.document||this,t=Y.access(e,r)-1;t?Y.access(e,r,t):(e.removeEventListener(n,i,!0),Y.remove(e,r))}}});var Tt=C.location,Ct={guid:Date.now()},Et=/\?/;S.parseXML=function(e){var t;if(!e||"string"!=typeof e)return null;try{t=(new C.DOMParser).parseFromString(e,"text/xml")}catch(e){t=void 0}return t&&!t.getElementsByTagName("parsererror").length||S.error("Invalid XML: "+e),t};var St=/\[\]$/,kt=/\r?\n/g,At=/^(?:submit|button|image|reset|file)$/i,Nt=/^(?:input|select|textarea|keygen)/i;function Dt(n,e,r,i){var t;if(Array.isArray(e))S.each(e,function(e,t){r||St.test(n)?i(n,t):Dt(n+"["+("object"==typeof t&&null!=t?e:"")+"]",t,r,i)});else if(r||"object"!==w(e))i(n,e);else for(t in e)Dt(n+"["+t+"]",e[t],r,i)}S.param=function(e,t){var n,r=[],i=function(e,t){var n=m(t)?t():t;r[r.length]=encodeURIComponent(e)+"="+encodeURIComponent(null==n?"":n)};if(null==e)return"";if(Array.isArray(e)||e.jquery&&!S.isPlainObject(e))S.each(e,function(){i(this.name,this.value)});else for(n in e)Dt(n,e[n],t,i);return r.join("&")},S.fn.extend({serialize:function(){return S.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var e=S.prop(this,"elements");return e?S.makeArray(e):this}).filter(function(){var e=this.type;return this.name&&!S(this).is(":disabled")&&Nt.test(this.nodeName)&&!At.test(e)&&(this.checked||!pe.test(e))}).map(function(e,t){var n=S(this).val();return null==n?null:Array.isArray(n)?S.map(n,function(e){return{name:t.name,value:e.replace(kt,"\r\n")}}):{name:t.name,value:n.replace(kt,"\r\n")}}).get()}});var jt=/%20/g,qt=/#.*$/,Lt=/([?&])_=[^&]*/,Ht=/^(.*?):[ \t]*([^\r\n]*)$/gm,Ot=/^(?:GET|HEAD)$/,Pt=/^\/\//,Rt={},Mt={},It="*/".concat("*"),Wt=E.createElement("a");function Ft(o){return function(e,t){"string"!=typeof e&&(t=e,e="*");var n,r=0,i=e.toLowerCase().match(P)||[];if(m(t))while(n=i[r++])"+"===n[0]?(n=n.slice(1)||"*",(o[n]=o[n]||[]).unshift(t)):(o[n]=o[n]||[]).push(t)}}function Bt(t,i,o,a){var s={},u=t===Mt;function l(e){var r;return s[e]=!0,S.each(t[e]||[],function(e,t){var n=t(i,o,a);return"string"!=typeof n||u||s[n]?u?!(r=n):void 0:(i.dataTypes.unshift(n),l(n),!1)}),r}return l(i.dataTypes[0])||!s["*"]&&l("*")}function $t(e,t){var n,r,i=S.ajaxSettings.flatOptions||{};for(n in t)void 0!==t[n]&&((i[n]?e:r||(r={}))[n]=t[n]);return r&&S.extend(!0,e,r),e}Wt.href=Tt.href,S.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:Tt.href,type:"GET",isLocal:/^(?:about|app|app-storage|.+-extension|file|res|widget):$/.test(Tt.protocol),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":It,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/\bxml\b/,html:/\bhtml/,json:/\bjson\b/},responseFields:{xml:"responseXML",text:"responseText",json:"responseJSON"},converters:{"* text":String,"text html":!0,"text json":JSON.parse,"text xml":S.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(e,t){return t?$t($t(e,S.ajaxSettings),t):$t(S.ajaxSettings,e)},ajaxPrefilter:Ft(Rt),ajaxTransport:Ft(Mt),ajax:function(e,t){"object"==typeof e&&(t=e,e=void 0),t=t||{};var c,f,p,n,d,r,h,g,i,o,v=S.ajaxSetup({},t),y=v.context||v,m=v.context&&(y.nodeType||y.jquery)?S(y):S.event,x=S.Deferred(),b=S.Callbacks("once memory"),w=v.statusCode||{},a={},s={},u="canceled",T={readyState:0,getResponseHeader:function(e){var t;if(h){if(!n){n={};while(t=Ht.exec(p))n[t[1].toLowerCase()+" "]=(n[t[1].toLowerCase()+" "]||[]).concat(t[2])}t=n[e.toLowerCase()+" "]}return null==t?null:t.join(", ")},getAllResponseHeaders:function(){return h?p:null},setRequestHeader:function(e,t){return null==h&&(e=s[e.toLowerCase()]=s[e.toLowerCase()]||e,a[e]=t),this},overrideMimeType:function(e){return null==h&&(v.mimeType=e),this},statusCode:function(e){var t;if(e)if(h)T.always(e[T.status]);else for(t in e)w[t]=[w[t],e[t]];return this},abort:function(e){var t=e||u;return c&&c.abort(t),l(0,t),this}};if(x.promise(T),v.url=((e||v.url||Tt.href)+"").replace(Pt,Tt.protocol+"//"),v.type=t.method||t.type||v.method||v.type,v.dataTypes=(v.dataType||"*").toLowerCase().match(P)||[""],null==v.crossDomain){r=E.createElement("a");try{r.href=v.url,r.href=r.href,v.crossDomain=Wt.protocol+"//"+Wt.host!=r.protocol+"//"+r.host}catch(e){v.crossDomain=!0}}if(v.data&&v.processData&&"string"!=typeof v.data&&(v.data=S.param(v.data,v.traditional)),Bt(Rt,v,t,T),h)return T;for(i in(g=S.event&&v.global)&&0==S.active++&&S.event.trigger("ajaxStart"),v.type=v.type.toUpperCase(),v.hasContent=!Ot.test(v.type),f=v.url.replace(qt,""),v.hasContent?v.data&&v.processData&&0===(v.contentType||"").indexOf("application/x-www-form-urlencoded")&&(v.data=v.data.replace(jt,"+")):(o=v.url.slice(f.length),v.data&&(v.processData||"string"==typeof v.data)&&(f+=(Et.test(f)?"&":"?")+v.data,delete v.data),!1===v.cache&&(f=f.replace(Lt,"$1"),o=(Et.test(f)?"&":"?")+"_="+Ct.guid+++o),v.url=f+o),v.ifModified&&(S.lastModified[f]&&T.setRequestHeader("If-Modified-Since",S.lastModified[f]),S.etag[f]&&T.setRequestHeader("If-None-Match",S.etag[f])),(v.data&&v.hasContent&&!1!==v.contentType||t.contentType)&&T.setRequestHeader("Content-Type",v.contentType),T.setRequestHeader("Accept",v.dataTypes[0]&&v.accepts[v.dataTypes[0]]?v.accepts[v.dataTypes[0]]+("*"!==v.dataTypes[0]?", "+It+"; q=0.01":""):v.accepts["*"]),v.headers)T.setRequestHeader(i,v.headers[i]);if(v.beforeSend&&(!1===v.beforeSend.call(y,T,v)||h))return T.abort();if(u="abort",b.add(v.complete),T.done(v.success),T.fail(v.error),c=Bt(Mt,v,t,T)){if(T.readyState=1,g&&m.trigger("ajaxSend",[T,v]),h)return T;v.async&&0<v.timeout&&(d=C.setTimeout(function(){T.abort("timeout")},v.timeout));try{h=!1,c.send(a,l)}catch(e){if(h)throw e;l(-1,e)}}else l(-1,"No Transport");function l(e,t,n,r){var i,o,a,s,u,l=t;h||(h=!0,d&&C.clearTimeout(d),c=void 0,p=r||"",T.readyState=0<e?4:0,i=200<=e&&e<300||304===e,n&&(s=function(e,t,n){var r,i,o,a,s=e.contents,u=e.dataTypes;while("*"===u[0])u.shift(),void 0===r&&(r=e.mimeType||t.getResponseHeader("Content-Type"));if(r)for(i in s)if(s[i]&&s[i].test(r)){u.unshift(i);break}if(u[0]in n)o=u[0];else{for(i in n){if(!u[0]||e.converters[i+" "+u[0]]){o=i;break}a||(a=i)}o=o||a}if(o)return o!==u[0]&&u.unshift(o),n[o]}(v,T,n)),!i&&-1<S.inArray("script",v.dataTypes)&&(v.converters["text script"]=function(){}),s=function(e,t,n,r){var i,o,a,s,u,l={},c=e.dataTypes.slice();if(c[1])for(a in e.converters)l[a.toLowerCase()]=e.converters[a];o=c.shift();while(o)if(e.responseFields[o]&&(n[e.responseFields[o]]=t),!u&&r&&e.dataFilter&&(t=e.dataFilter(t,e.dataType)),u=o,o=c.shift())if("*"===o)o=u;else if("*"!==u&&u!==o){if(!(a=l[u+" "+o]||l["* "+o]))for(i in l)if((s=i.split(" "))[1]===o&&(a=l[u+" "+s[0]]||l["* "+s[0]])){!0===a?a=l[i]:!0!==l[i]&&(o=s[0],c.unshift(s[1]));break}if(!0!==a)if(a&&e["throws"])t=a(t);else try{t=a(t)}catch(e){return{state:"parsererror",error:a?e:"No conversion from "+u+" to "+o}}}return{state:"success",data:t}}(v,s,T,i),i?(v.ifModified&&((u=T.getResponseHeader("Last-Modified"))&&(S.lastModified[f]=u),(u=T.getResponseHeader("etag"))&&(S.etag[f]=u)),204===e||"HEAD"===v.type?l="nocontent":304===e?l="notmodified":(l=s.state,o=s.data,i=!(a=s.error))):(a=l,!e&&l||(l="error",e<0&&(e=0))),T.status=e,T.statusText=(t||l)+"",i?x.resolveWith(y,[o,l,T]):x.rejectWith(y,[T,l,a]),T.statusCode(w),w=void 0,g&&m.trigger(i?"ajaxSuccess":"ajaxError",[T,v,i?o:a]),b.fireWith(y,[T,l]),g&&(m.trigger("ajaxComplete",[T,v]),--S.active||S.event.trigger("ajaxStop")))}return T},getJSON:function(e,t,n){return S.get(e,t,n,"json")},getScript:function(e,t){return S.get(e,void 0,t,"script")}}),S.each(["get","post"],function(e,i){S[i]=function(e,t,n,r){return m(t)&&(r=r||n,n=t,t=void 0),S.ajax(S.extend({url:e,type:i,dataType:r,data:t,success:n},S.isPlainObject(e)&&e))}}),S.ajaxPrefilter(function(e){var t;for(t in e.headers)"content-type"===t.toLowerCase()&&(e.contentType=e.headers[t]||"")}),S._evalUrl=function(e,t,n){return S.ajax({url:e,type:"GET",dataType:"script",cache:!0,async:!1,global:!1,converters:{"text script":function(){}},dataFilter:function(e){S.globalEval(e,t,n)}})},S.fn.extend({wrapAll:function(e){var t;return this[0]&&(m(e)&&(e=e.call(this[0])),t=S(e,this[0].ownerDocument).eq(0).clone(!0),this[0].parentNode&&t.insertBefore(this[0]),t.map(function(){var e=this;while(e.firstElementChild)e=e.firstElementChild;return e}).append(this)),this},wrapInner:function(n){return m(n)?this.each(function(e){S(this).wrapInner(n.call(this,e))}):this.each(function(){var e=S(this),t=e.contents();t.length?t.wrapAll(n):e.append(n)})},wrap:function(t){var n=m(t);return this.each(function(e){S(this).wrapAll(n?t.call(this,e):t)})},unwrap:function(e){return this.parent(e).not("body").each(function(){S(this).replaceWith(this.childNodes)}),this}}),S.expr.pseudos.hidden=function(e){return!S.expr.pseudos.visible(e)},S.expr.pseudos.visible=function(e){return!!(e.offsetWidth||e.offsetHeight||e.getClientRects().length)},S.ajaxSettings.xhr=function(){try{return new C.XMLHttpRequest}catch(e){}};var _t={0:200,1223:204},zt=S.ajaxSettings.xhr();y.cors=!!zt&&"withCredentials"in zt,y.ajax=zt=!!zt,S.ajaxTransport(function(i){var o,a;if(y.cors||zt&&!i.crossDomain)return{send:function(e,t){var n,r=i.xhr();if(r.open(i.type,i.url,i.async,i.username,i.password),i.xhrFields)for(n in i.xhrFields)r[n]=i.xhrFields[n];for(n in i.mimeType&&r.overrideMimeType&&r.overrideMimeType(i.mimeType),i.crossDomain||e["X-Requested-With"]||(e["X-Requested-With"]="XMLHttpRequest"),e)r.setRequestHeader(n,e[n]);o=function(e){return function(){o&&(o=a=r.onload=r.onerror=r.onabort=r.ontimeout=r.onreadystatechange=null,"abort"===e?r.abort():"error"===e?"number"!=typeof r.status?t(0,"error"):t(r.status,r.statusText):t(_t[r.status]||r.status,r.statusText,"text"!==(r.responseType||"text")||"string"!=typeof r.responseText?{binary:r.response}:{text:r.responseText},r.getAllResponseHeaders()))}},r.onload=o(),a=r.onerror=r.ontimeout=o("error"),void 0!==r.onabort?r.onabort=a:r.onreadystatechange=function(){4===r.readyState&&C.setTimeout(function(){o&&a()})},o=o("abort");try{r.send(i.hasContent&&i.data||null)}catch(e){if(o)throw e}},abort:function(){o&&o()}}}),S.ajaxPrefilter(function(e){e.crossDomain&&(e.contents.script=!1)}),S.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/\b(?:java|ecma)script\b/},converters:{"text script":function(e){return S.globalEval(e),e}}}),S.ajaxPrefilter("script",function(e){void 0===e.cache&&(e.cache=!1),e.crossDomain&&(e.type="GET")}),S.ajaxTransport("script",function(n){var r,i;if(n.crossDomain||n.scriptAttrs)return{send:function(e,t){r=S("<script>").attr(n.scriptAttrs||{}).prop({charset:n.scriptCharset,src:n.url}).on("load error",i=function(e){r.remove(),i=null,e&&t("error"===e.type?404:200,e.type)}),E.head.appendChild(r[0])},abort:function(){i&&i()}}});var Ut,Xt=[],Vt=/(=)\?(?=&|$)|\?\?/;S.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=Xt.pop()||S.expando+"_"+Ct.guid++;return this[e]=!0,e}}),S.ajaxPrefilter("json jsonp",function(e,t,n){var r,i,o,a=!1!==e.jsonp&&(Vt.test(e.url)?"url":"string"==typeof e.data&&0===(e.contentType||"").indexOf("application/x-www-form-urlencoded")&&Vt.test(e.data)&&"data");if(a||"jsonp"===e.dataTypes[0])return r=e.jsonpCallback=m(e.jsonpCallback)?e.jsonpCallback():e.jsonpCallback,a?e[a]=e[a].replace(Vt,"$1"+r):!1!==e.jsonp&&(e.url+=(Et.test(e.url)?"&":"?")+e.jsonp+"="+r),e.converters["script json"]=function(){return o||S.error(r+" was not called"),o[0]},e.dataTypes[0]="json",i=C[r],C[r]=function(){o=arguments},n.always(function(){void 0===i?S(C).removeProp(r):C[r]=i,e[r]&&(e.jsonpCallback=t.jsonpCallback,Xt.push(r)),o&&m(i)&&i(o[0]),o=i=void 0}),"script"}),y.createHTMLDocument=((Ut=E.implementation.createHTMLDocument("").body).innerHTML="<form></form><form></form>",2===Ut.childNodes.length),S.parseHTML=function(e,t,n){return"string"!=typeof e?[]:("boolean"==typeof t&&(n=t,t=!1),t||(y.createHTMLDocument?((r=(t=E.implementation.createHTMLDocument("")).createElement("base")).href=E.location.href,t.head.appendChild(r)):t=E),o=!n&&[],(i=N.exec(e))?[t.createElement(i[1])]:(i=xe([e],t,o),o&&o.length&&S(o).remove(),S.merge([],i.childNodes)));var r,i,o},S.fn.load=function(e,t,n){var r,i,o,a=this,s=e.indexOf(" ");return-1<s&&(r=vt(e.slice(s)),e=e.slice(0,s)),m(t)?(n=t,t=void 0):t&&"object"==typeof t&&(i="POST"),0<a.length&&S.ajax({url:e,type:i||"GET",dataType:"html",data:t}).done(function(e){o=arguments,a.html(r?S("<div>").append(S.parseHTML(e)).find(r):e)}).always(n&&function(e,t){a.each(function(){n.apply(this,o||[e.responseText,t,e])})}),this},S.expr.pseudos.animated=function(t){return S.grep(S.timers,function(e){return t===e.elem}).length},S.offset={setOffset:function(e,t,n){var r,i,o,a,s,u,l=S.css(e,"position"),c=S(e),f={};"static"===l&&(e.style.position="relative"),s=c.offset(),o=S.css(e,"top"),u=S.css(e,"left"),("absolute"===l||"fixed"===l)&&-1<(o+u).indexOf("auto")?(a=(r=c.position()).top,i=r.left):(a=parseFloat(o)||0,i=parseFloat(u)||0),m(t)&&(t=t.call(e,n,S.extend({},s))),null!=t.top&&(f.top=t.top-s.top+a),null!=t.left&&(f.left=t.left-s.left+i),"using"in t?t.using.call(e,f):("number"==typeof f.top&&(f.top+="px"),"number"==typeof f.left&&(f.left+="px"),c.css(f))}},S.fn.extend({offset:function(t){if(arguments.length)return void 0===t?this:this.each(function(e){S.offset.setOffset(this,t,e)});var e,n,r=this[0];return r?r.getClientRects().length?(e=r.getBoundingClientRect(),n=r.ownerDocument.defaultView,{top:e.top+n.pageYOffset,left:e.left+n.pageXOffset}):{top:0,left:0}:void 0},position:function(){if(this[0]){var e,t,n,r=this[0],i={top:0,left:0};if("fixed"===S.css(r,"position"))t=r.getBoundingClientRect();else{t=this.offset(),n=r.ownerDocument,e=r.offsetParent||n.documentElement;while(e&&(e===n.body||e===n.documentElement)&&"static"===S.css(e,"position"))e=e.parentNode;e&&e!==r&&1===e.nodeType&&((i=S(e).offset()).top+=S.css(e,"borderTopWidth",!0),i.left+=S.css(e,"borderLeftWidth",!0))}return{top:t.top-i.top-S.css(r,"marginTop",!0),left:t.left-i.left-S.css(r,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var e=this.offsetParent;while(e&&"static"===S.css(e,"position"))e=e.offsetParent;return e||re})}}),S.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(t,i){var o="pageYOffset"===i;S.fn[t]=function(e){return $(this,function(e,t,n){var r;if(x(e)?r=e:9===e.nodeType&&(r=e.defaultView),void 0===n)return r?r[i]:e[t];r?r.scrollTo(o?r.pageXOffset:n,o?n:r.pageYOffset):e[t]=n},t,e,arguments.length)}}),S.each(["top","left"],function(e,n){S.cssHooks[n]=$e(y.pixelPosition,function(e,t){if(t)return t=Be(e,n),Me.test(t)?S(e).position()[n]+"px":t})}),S.each({Height:"height",Width:"width"},function(a,s){S.each({padding:"inner"+a,content:s,"":"outer"+a},function(r,o){S.fn[o]=function(e,t){var n=arguments.length&&(r||"boolean"!=typeof e),i=r||(!0===e||!0===t?"margin":"border");return $(this,function(e,t,n){var r;return x(e)?0===o.indexOf("outer")?e["inner"+a]:e.document.documentElement["client"+a]:9===e.nodeType?(r=e.documentElement,Math.max(e.body["scroll"+a],r["scroll"+a],e.body["offset"+a],r["offset"+a],r["client"+a])):void 0===n?S.css(e,t,i):S.style(e,t,n,i)},s,n?e:void 0,n)}})}),S.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){S.fn[t]=function(e){return this.on(t,e)}}),S.fn.extend({bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return 1===arguments.length?this.off(e,"**"):this.off(t,e||"**",n)},hover:function(e,t){return this.mouseenter(e).mouseleave(t||e)}}),S.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(e,n){S.fn[n]=function(e,t){return 0<arguments.length?this.on(n,null,e,t):this.trigger(n)}});var Gt=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g;S.proxy=function(e,t){var n,r,i;if("string"==typeof t&&(n=e[t],t=e,e=n),m(e))return r=s.call(arguments,2),(i=function(){return e.apply(t||this,r.concat(s.call(arguments)))}).guid=e.guid=e.guid||S.guid++,i},S.holdReady=function(e){e?S.readyWait++:S.ready(!0)},S.isArray=Array.isArray,S.parseJSON=JSON.parse,S.nodeName=A,S.isFunction=m,S.isWindow=x,S.camelCase=X,S.type=w,S.now=Date.now,S.isNumeric=function(e){var t=S.type(e);return("number"===t||"string"===t)&&!isNaN(e-parseFloat(e))},S.trim=function(e){return null==e?"":(e+"").replace(Gt,"")},"function"==typeof define&&define.amd&&define("jquery",[],function(){return S});var Yt=C.jQuery,Qt=C.$;return S.noConflict=function(e){return C.$===S&&(C.$=Qt),e&&C.jQuery===S&&(C.jQuery=Yt),S},"undefined"==typeof e&&(C.jQuery=C.$=S),S});
diff --git a/docs/_build/html/_static/js/badge_only.js b/docs/_build/html/_static/js/badge_only.js
deleted file mode 100644
index 526d7234..00000000
--- a/docs/_build/html/_static/js/badge_only.js
+++ /dev/null
@@ -1 +0,0 @@
-!function(e){var t={};function r(n){if(t[n])return t[n].exports;var o=t[n]={i:n,l:!1,exports:{}};return e[n].call(o.exports,o,o.exports,r),o.l=!0,o.exports}r.m=e,r.c=t,r.d=function(e,t,n){r.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:n})},r.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},r.t=function(e,t){if(1&t&&(e=r(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var n=Object.create(null);if(r.r(n),Object.defineProperty(n,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)r.d(n,o,function(t){return e[t]}.bind(null,o));return n},r.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return r.d(t,"a",t),t},r.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},r.p="",r(r.s=4)}({4:function(e,t,r){}});
\ No newline at end of file
diff --git a/docs/_build/html/_static/js/html5shiv-printshiv.min.js b/docs/_build/html/_static/js/html5shiv-printshiv.min.js
deleted file mode 100644
index 2b43bd06..00000000
--- a/docs/_build/html/_static/js/html5shiv-printshiv.min.js
+++ /dev/null
@@ -1,4 +0,0 @@
-/**
-* @preserve HTML5 Shiv 3.7.3-pre | @afarkas @jdalton @jon_neal @rem | MIT/GPL2 Licensed
-*/
-!function(a,b){function c(a,b){var c=a.createElement("p"),d=a.getElementsByTagName("head")[0]||a.documentElement;return c.innerHTML="x<style>"+b+"</style>",d.insertBefore(c.lastChild,d.firstChild)}function d(){var a=y.elements;return"string"==typeof a?a.split(" "):a}function e(a,b){var c=y.elements;"string"!=typeof c&&(c=c.join(" ")),"string"!=typeof a&&(a=a.join(" ")),y.elements=c+" "+a,j(b)}function f(a){var b=x[a[v]];return b||(b={},w++,a[v]=w,x[w]=b),b}function g(a,c,d){if(c||(c=b),q)return c.createElement(a);d||(d=f(c));var e;return e=d.cache[a]?d.cache[a].cloneNode():u.test(a)?(d.cache[a]=d.createElem(a)).cloneNode():d.createElem(a),!e.canHaveChildren||t.test(a)||e.tagUrn?e:d.frag.appendChild(e)}function h(a,c){if(a||(a=b),q)return a.createDocumentFragment();c=c||f(a);for(var e=c.frag.cloneNode(),g=0,h=d(),i=h.length;i>g;g++)e.createElement(h[g]);return e}function i(a,b){b.cache||(b.cache={},b.createElem=a.createElement,b.createFrag=a.createDocumentFragment,b.frag=b.createFrag()),a.createElement=function(c){return y.shivMethods?g(c,a,b):b.createElem(c)},a.createDocumentFragment=Function("h,f","return function(){var n=f.cloneNode(),c=n.createElement;h.shivMethods&&("+d().join().replace(/[\w\-:]+/g,function(a){return b.createElem(a),b.frag.createElement(a),'c("'+a+'")'})+");return n}")(y,b.frag)}function j(a){a||(a=b);var d=f(a);return!y.shivCSS||p||d.hasCSS||(d.hasCSS=!!c(a,"article,aside,dialog,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}mark{background:#FF0;color:#000}template{display:none}")),q||i(a,d),a}function k(a){for(var b,c=a.getElementsByTagName("*"),e=c.length,f=RegExp("^(?:"+d().join("|")+")$","i"),g=[];e--;)b=c[e],f.test(b.nodeName)&&g.push(b.applyElement(l(b)));return g}function l(a){for(var b,c=a.attributes,d=c.length,e=a.ownerDocument.createElement(A+":"+a.nodeName);d--;)b=c[d],b.specified&&e.setAttribute(b.nodeName,b.nodeValue);return e.style.cssText=a.style.cssText,e}function m(a){for(var b,c=a.split("{"),e=c.length,f=RegExp("(^|[\\s,>+~])("+d().join("|")+")(?=[[\\s,>+~#.:]|$)","gi"),g="$1"+A+"\\:$2";e--;)b=c[e]=c[e].split("}"),b[b.length-1]=b[b.length-1].replace(f,g),c[e]=b.join("}");return c.join("{")}function n(a){for(var b=a.length;b--;)a[b].removeNode()}function o(a){function b(){clearTimeout(g._removeSheetTimer),d&&d.removeNode(!0),d=null}var d,e,g=f(a),h=a.namespaces,i=a.parentWindow;return!B||a.printShived?a:("undefined"==typeof h[A]&&h.add(A),i.attachEvent("onbeforeprint",function(){b();for(var f,g,h,i=a.styleSheets,j=[],l=i.length,n=Array(l);l--;)n[l]=i[l];for(;h=n.pop();)if(!h.disabled&&z.test(h.media)){try{f=h.imports,g=f.length}catch(o){g=0}for(l=0;g>l;l++)n.push(f[l]);try{j.push(h.cssText)}catch(o){}}j=m(j.reverse().join("")),e=k(a),d=c(a,j)}),i.attachEvent("onafterprint",function(){n(e),clearTimeout(g._removeSheetTimer),g._removeSheetTimer=setTimeout(b,500)}),a.printShived=!0,a)}var p,q,r="3.7.3",s=a.html5||{},t=/^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i,u=/^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i,v="_html5shiv",w=0,x={};!function(){try{var a=b.createElement("a");a.innerHTML="<xyz></xyz>",p="hidden"in a,q=1==a.childNodes.length||function(){b.createElement("a");var a=b.createDocumentFragment();return"undefined"==typeof a.cloneNode||"undefined"==typeof a.createDocumentFragment||"undefined"==typeof a.createElement}()}catch(c){p=!0,q=!0}}();var y={elements:s.elements||"abbr article aside audio bdi canvas data datalist details dialog figcaption figure footer header hgroup main mark meter nav output picture progress section summary template time video",version:r,shivCSS:s.shivCSS!==!1,supportsUnknownElements:q,shivMethods:s.shivMethods!==!1,type:"default",shivDocument:j,createElement:g,createDocumentFragment:h,addElements:e};a.html5=y,j(b);var z=/^$|\b(?:all|print)\b/,A="html5shiv",B=!q&&function(){var c=b.documentElement;return!("undefined"==typeof b.namespaces||"undefined"==typeof b.parentWindow||"undefined"==typeof c.applyElement||"undefined"==typeof c.removeNode||"undefined"==typeof a.attachEvent)}();y.type+=" print",y.shivPrint=o,o(b),"object"==typeof module&&module.exports&&(module.exports=y)}("undefined"!=typeof window?window:this,document);
\ No newline at end of file
diff --git a/docs/_build/html/_static/js/html5shiv.min.js b/docs/_build/html/_static/js/html5shiv.min.js
deleted file mode 100644
index cd1c674f..00000000
--- a/docs/_build/html/_static/js/html5shiv.min.js
+++ /dev/null
@@ -1,4 +0,0 @@
-/**
-* @preserve HTML5 Shiv 3.7.3 | @afarkas @jdalton @jon_neal @rem | MIT/GPL2 Licensed
-*/
-!function(a,b){function c(a,b){var c=a.createElement("p"),d=a.getElementsByTagName("head")[0]||a.documentElement;return c.innerHTML="x<style>"+b+"</style>",d.insertBefore(c.lastChild,d.firstChild)}function d(){var a=t.elements;return"string"==typeof a?a.split(" "):a}function e(a,b){var c=t.elements;"string"!=typeof c&&(c=c.join(" ")),"string"!=typeof a&&(a=a.join(" ")),t.elements=c+" "+a,j(b)}function f(a){var b=s[a[q]];return b||(b={},r++,a[q]=r,s[r]=b),b}function g(a,c,d){if(c||(c=b),l)return c.createElement(a);d||(d=f(c));var e;return e=d.cache[a]?d.cache[a].cloneNode():p.test(a)?(d.cache[a]=d.createElem(a)).cloneNode():d.createElem(a),!e.canHaveChildren||o.test(a)||e.tagUrn?e:d.frag.appendChild(e)}function h(a,c){if(a||(a=b),l)return a.createDocumentFragment();c=c||f(a);for(var e=c.frag.cloneNode(),g=0,h=d(),i=h.length;i>g;g++)e.createElement(h[g]);return e}function i(a,b){b.cache||(b.cache={},b.createElem=a.createElement,b.createFrag=a.createDocumentFragment,b.frag=b.createFrag()),a.createElement=function(c){return t.shivMethods?g(c,a,b):b.createElem(c)},a.createDocumentFragment=Function("h,f","return function(){var n=f.cloneNode(),c=n.createElement;h.shivMethods&&("+d().join().replace(/[\w\-:]+/g,function(a){return b.createElem(a),b.frag.createElement(a),'c("'+a+'")'})+");return n}")(t,b.frag)}function j(a){a||(a=b);var d=f(a);return!t.shivCSS||k||d.hasCSS||(d.hasCSS=!!c(a,"article,aside,dialog,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}mark{background:#FF0;color:#000}template{display:none}")),l||i(a,d),a}var k,l,m="3.7.3-pre",n=a.html5||{},o=/^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i,p=/^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i,q="_html5shiv",r=0,s={};!function(){try{var a=b.createElement("a");a.innerHTML="<xyz></xyz>",k="hidden"in a,l=1==a.childNodes.length||function(){b.createElement("a");var a=b.createDocumentFragment();return"undefined"==typeof a.cloneNode||"undefined"==typeof a.createDocumentFragment||"undefined"==typeof a.createElement}()}catch(c){k=!0,l=!0}}();var t={elements:n.elements||"abbr article aside audio bdi canvas data datalist details dialog figcaption figure footer header hgroup main mark meter nav output picture progress section summary template time video",version:m,shivCSS:n.shivCSS!==!1,supportsUnknownElements:l,shivMethods:n.shivMethods!==!1,type:"default",shivDocument:j,createElement:g,createDocumentFragment:h,addElements:e};a.html5=t,j(b),"object"==typeof module&&module.exports&&(module.exports=t)}("undefined"!=typeof window?window:this,document);
\ No newline at end of file
diff --git a/docs/_build/html/_static/js/modernizr.min.js b/docs/_build/html/_static/js/modernizr.min.js
deleted file mode 100644
index f65d4797..00000000
--- a/docs/_build/html/_static/js/modernizr.min.js
+++ /dev/null
@@ -1,4 +0,0 @@
-/* Modernizr 2.6.2 (Custom Build) | MIT & BSD
- * Build: http://modernizr.com/download/#-fontface-backgroundsize-borderimage-borderradius-boxshadow-flexbox-hsla-multiplebgs-opacity-rgba-textshadow-cssanimations-csscolumns-generatedcontent-cssgradients-cssreflections-csstransforms-csstransforms3d-csstransitions-applicationcache-canvas-canvastext-draganddrop-hashchange-history-audio-video-indexeddb-input-inputtypes-localstorage-postmessage-sessionstorage-websockets-websqldatabase-webworkers-geolocation-inlinesvg-smil-svg-svgclippaths-touch-webgl-shiv-mq-cssclasses-addtest-prefixed-teststyles-testprop-testallprops-hasevent-prefixes-domprefixes-load
- */
-;window.Modernizr=function(a,b,c){function D(a){j.cssText=a}function E(a,b){return D(n.join(a+";")+(b||""))}function F(a,b){return typeof a===b}function G(a,b){return!!~(""+a).indexOf(b)}function H(a,b){for(var d in a){var e=a[d];if(!G(e,"-")&&j[e]!==c)return b=="pfx"?e:!0}return!1}function I(a,b,d){for(var e in a){var f=b[a[e]];if(f!==c)return d===!1?a[e]:F(f,"function")?f.bind(d||b):f}return!1}function J(a,b,c){var d=a.charAt(0).toUpperCase()+a.slice(1),e=(a+" "+p.join(d+" ")+d).split(" ");return F(b,"string")||F(b,"undefined")?H(e,b):(e=(a+" "+q.join(d+" ")+d).split(" "),I(e,b,c))}function K(){e.input=function(c){for(var d=0,e=c.length;d<e;d++)u[c[d]]=c[d]in k;return u.list&&(u.list=!!b.createElement("datalist")&&!!a.HTMLDataListElement),u}("autocomplete autofocus list placeholder max min multiple pattern required step".split(" ")),e.inputtypes=function(a){for(var d=0,e,f,h,i=a.length;d<i;d++)k.setAttribute("type",f=a[d]),e=k.type!=="text",e&&(k.value=l,k.style.cssText="position:absolute;visibility:hidden;",/^range$/.test(f)&&k.style.WebkitAppearance!==c?(g.appendChild(k),h=b.defaultView,e=h.getComputedStyle&&h.getComputedStyle(k,null).WebkitAppearance!=="textfield"&&k.offsetHeight!==0,g.removeChild(k)):/^(search|tel)$/.test(f)||(/^(url|email)$/.test(f)?e=k.checkValidity&&k.checkValidity()===!1:e=k.value!=l)),t[a[d]]=!!e;return t}("search tel url email datetime date month week time datetime-local number range color".split(" "))}var d="2.6.2",e={},f=!0,g=b.documentElement,h="modernizr",i=b.createElement(h),j=i.style,k=b.createElement("input"),l=":)",m={}.toString,n=" -webkit- -moz- -o- -ms- ".split(" "),o="Webkit Moz O ms",p=o.split(" "),q=o.toLowerCase().split(" "),r={svg:"http://www.w3.org/2000/svg"},s={},t={},u={},v=[],w=v.slice,x,y=function(a,c,d,e){var f,i,j,k,l=b.createElement("div"),m=b.body,n=m||b.createElement("body");if(parseInt(d,10))while(d--)j=b.createElement("div"),j.id=e?e[d]:h+(d+1),l.appendChild(j);return f=["&#173;",'<style id="s',h,'">',a,"</style>"].join(""),l.id=h,(m?l:n).innerHTML+=f,n.appendChild(l),m||(n.style.background="",n.style.overflow="hidden",k=g.style.overflow,g.style.overflow="hidden",g.appendChild(n)),i=c(l,a),m?l.parentNode.removeChild(l):(n.parentNode.removeChild(n),g.style.overflow=k),!!i},z=function(b){var c=a.matchMedia||a.msMatchMedia;if(c)return c(b).matches;var d;return y("@media "+b+" { #"+h+" { position: absolute; } }",function(b){d=(a.getComputedStyle?getComputedStyle(b,null):b.currentStyle)["position"]=="absolute"}),d},A=function(){function d(d,e){e=e||b.createElement(a[d]||"div"),d="on"+d;var f=d in e;return f||(e.setAttribute||(e=b.createElement("div")),e.setAttribute&&e.removeAttribute&&(e.setAttribute(d,""),f=F(e[d],"function"),F(e[d],"undefined")||(e[d]=c),e.removeAttribute(d))),e=null,f}var a={select:"input",change:"input",submit:"form",reset:"form",error:"img",load:"img",abort:"img"};return d}(),B={}.hasOwnProperty,C;!F(B,"undefined")&&!F(B.call,"undefined")?C=function(a,b){return B.call(a,b)}:C=function(a,b){return b in a&&F(a.constructor.prototype[b],"undefined")},Function.prototype.bind||(Function.prototype.bind=function(b){var c=this;if(typeof c!="function")throw new TypeError;var d=w.call(arguments,1),e=function(){if(this instanceof e){var a=function(){};a.prototype=c.prototype;var f=new a,g=c.apply(f,d.concat(w.call(arguments)));return Object(g)===g?g:f}return c.apply(b,d.concat(w.call(arguments)))};return e}),s.flexbox=function(){return J("flexWrap")},s.canvas=function(){var a=b.createElement("canvas");return!!a.getContext&&!!a.getContext("2d")},s.canvastext=function(){return!!e.canvas&&!!F(b.createElement("canvas").getContext("2d").fillText,"function")},s.webgl=function(){return!!a.WebGLRenderingContext},s.touch=function(){var c;return"ontouchstart"in a||a.DocumentTouch&&b instanceof DocumentTouch?c=!0:y(["@media (",n.join("touch-enabled),("),h,")","{#modernizr{top:9px;position:absolute}}"].join(""),function(a){c=a.offsetTop===9}),c},s.geolocation=function(){return"geolocation"in navigator},s.postmessage=function(){return!!a.postMessage},s.websqldatabase=function(){return!!a.openDatabase},s.indexedDB=function(){return!!J("indexedDB",a)},s.hashchange=function(){return A("hashchange",a)&&(b.documentMode===c||b.documentMode>7)},s.history=function(){return!!a.history&&!!history.pushState},s.draganddrop=function(){var a=b.createElement("div");return"draggable"in a||"ondragstart"in a&&"ondrop"in a},s.websockets=function(){return"WebSocket"in a||"MozWebSocket"in a},s.rgba=function(){return D("background-color:rgba(150,255,150,.5)"),G(j.backgroundColor,"rgba")},s.hsla=function(){return D("background-color:hsla(120,40%,100%,.5)"),G(j.backgroundColor,"rgba")||G(j.backgroundColor,"hsla")},s.multiplebgs=function(){return D("background:url(https://),url(https://),red url(https://)"),/(url\s*\(.*?){3}/.test(j.background)},s.backgroundsize=function(){return J("backgroundSize")},s.borderimage=function(){return J("borderImage")},s.borderradius=function(){return J("borderRadius")},s.boxshadow=function(){return J("boxShadow")},s.textshadow=function(){return b.createElement("div").style.textShadow===""},s.opacity=function(){return E("opacity:.55"),/^0.55$/.test(j.opacity)},s.cssanimations=function(){return J("animationName")},s.csscolumns=function(){return J("columnCount")},s.cssgradients=function(){var a="background-image:",b="gradient(linear,left top,right bottom,from(#9f9),to(white));",c="linear-gradient(left top,#9f9, white);";return D((a+"-webkit- ".split(" ").join(b+a)+n.join(c+a)).slice(0,-a.length)),G(j.backgroundImage,"gradient")},s.cssreflections=function(){return J("boxReflect")},s.csstransforms=function(){return!!J("transform")},s.csstransforms3d=function(){var a=!!J("perspective");return a&&"webkitPerspective"in g.style&&y("@media (transform-3d),(-webkit-transform-3d){#modernizr{left:9px;position:absolute;height:3px;}}",function(b,c){a=b.offsetLeft===9&&b.offsetHeight===3}),a},s.csstransitions=function(){return J("transition")},s.fontface=function(){var a;return y('@font-face {font-family:"font";src:url("https://")}',function(c,d){var e=b.getElementById("smodernizr"),f=e.sheet||e.styleSheet,g=f?f.cssRules&&f.cssRules[0]?f.cssRules[0].cssText:f.cssText||"":"";a=/src/i.test(g)&&g.indexOf(d.split(" ")[0])===0}),a},s.generatedcontent=function(){var a;return y(["#",h,"{font:0/0 a}#",h,':after{content:"',l,'";visibility:hidden;font:3px/1 a}'].join(""),function(b){a=b.offsetHeight>=3}),a},s.video=function(){var a=b.createElement("video"),c=!1;try{if(c=!!a.canPlayType)c=new Boolean(c),c.ogg=a.canPlayType('video/ogg; codecs="theora"').replace(/^no$/,""),c.h264=a.canPlayType('video/mp4; codecs="avc1.42E01E"').replace(/^no$/,""),c.webm=a.canPlayType('video/webm; codecs="vp8, vorbis"').replace(/^no$/,"")}catch(d){}return c},s.audio=function(){var a=b.createElement("audio"),c=!1;try{if(c=!!a.canPlayType)c=new Boolean(c),c.ogg=a.canPlayType('audio/ogg; codecs="vorbis"').replace(/^no$/,""),c.mp3=a.canPlayType("audio/mpeg;").replace(/^no$/,""),c.wav=a.canPlayType('audio/wav; codecs="1"').replace(/^no$/,""),c.m4a=(a.canPlayType("audio/x-m4a;")||a.canPlayType("audio/aac;")).replace(/^no$/,"")}catch(d){}return c},s.localstorage=function(){try{return localStorage.setItem(h,h),localStorage.removeItem(h),!0}catch(a){return!1}},s.sessionstorage=function(){try{return sessionStorage.setItem(h,h),sessionStorage.removeItem(h),!0}catch(a){return!1}},s.webworkers=function(){return!!a.Worker},s.applicationcache=function(){return!!a.applicationCache},s.svg=function(){return!!b.createElementNS&&!!b.createElementNS(r.svg,"svg").createSVGRect},s.inlinesvg=function(){var a=b.createElement("div");return a.innerHTML="<svg/>",(a.firstChild&&a.firstChild.namespaceURI)==r.svg},s.smil=function(){return!!b.createElementNS&&/SVGAnimate/.test(m.call(b.createElementNS(r.svg,"animate")))},s.svgclippaths=function(){return!!b.createElementNS&&/SVGClipPath/.test(m.call(b.createElementNS(r.svg,"clipPath")))};for(var L in s)C(s,L)&&(x=L.toLowerCase(),e[x]=s[L](),v.push((e[x]?"":"no-")+x));return e.input||K(),e.addTest=function(a,b){if(typeof a=="object")for(var d in a)C(a,d)&&e.addTest(d,a[d]);else{a=a.toLowerCase();if(e[a]!==c)return e;b=typeof b=="function"?b():b,typeof f!="undefined"&&f&&(g.className+=" "+(b?"":"no-")+a),e[a]=b}return e},D(""),i=k=null,function(a,b){function k(a,b){var c=a.createElement("p"),d=a.getElementsByTagName("head")[0]||a.documentElement;return c.innerHTML="x<style>"+b+"</style>",d.insertBefore(c.lastChild,d.firstChild)}function l(){var a=r.elements;return typeof a=="string"?a.split(" "):a}function m(a){var b=i[a[g]];return b||(b={},h++,a[g]=h,i[h]=b),b}function n(a,c,f){c||(c=b);if(j)return c.createElement(a);f||(f=m(c));var g;return f.cache[a]?g=f.cache[a].cloneNode():e.test(a)?g=(f.cache[a]=f.createElem(a)).cloneNode():g=f.createElem(a),g.canHaveChildren&&!d.test(a)?f.frag.appendChild(g):g}function o(a,c){a||(a=b);if(j)return a.createDocumentFragment();c=c||m(a);var d=c.frag.cloneNode(),e=0,f=l(),g=f.length;for(;e<g;e++)d.createElement(f[e]);return d}function p(a,b){b.cache||(b.cache={},b.createElem=a.createElement,b.createFrag=a.createDocumentFragment,b.frag=b.createFrag()),a.createElement=function(c){return r.shivMethods?n(c,a,b):b.createElem(c)},a.createDocumentFragment=Function("h,f","return function(){var n=f.cloneNode(),c=n.createElement;h.shivMethods&&("+l().join().replace(/\w+/g,function(a){return b.createElem(a),b.frag.createElement(a),'c("'+a+'")'})+");return n}")(r,b.frag)}function q(a){a||(a=b);var c=m(a);return r.shivCSS&&!f&&!c.hasCSS&&(c.hasCSS=!!k(a,"article,aside,figcaption,figure,footer,header,hgroup,nav,section{display:block}mark{background:#FF0;color:#000}")),j||p(a,c),a}var c=a.html5||{},d=/^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i,e=/^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i,f,g="_html5shiv",h=0,i={},j;(function(){try{var a=b.createElement("a");a.innerHTML="<xyz></xyz>",f="hidden"in a,j=a.childNodes.length==1||function(){b.createElement("a");var a=b.createDocumentFragment();return typeof a.cloneNode=="undefined"||typeof a.createDocumentFragment=="undefined"||typeof a.createElement=="undefined"}()}catch(c){f=!0,j=!0}})();var r={elements:c.elements||"abbr article aside audio bdi canvas data datalist details figcaption figure footer header hgroup mark meter nav output progress section summary time video",shivCSS:c.shivCSS!==!1,supportsUnknownElements:j,shivMethods:c.shivMethods!==!1,type:"default",shivDocument:q,createElement:n,createDocumentFragment:o};a.html5=r,q(b)}(this,b),e._version=d,e._prefixes=n,e._domPrefixes=q,e._cssomPrefixes=p,e.mq=z,e.hasEvent=A,e.testProp=function(a){return H([a])},e.testAllProps=J,e.testStyles=y,e.prefixed=function(a,b,c){return b?J(a,b,c):J(a,"pfx")},g.className=g.className.replace(/(^|\s)no-js(\s|$)/,"$1$2")+(f?" js "+v.join(" "):""),e}(this,this.document),function(a,b,c){function d(a){return"[object Function]"==o.call(a)}function e(a){return"string"==typeof a}function f(){}function g(a){return!a||"loaded"==a||"complete"==a||"uninitialized"==a}function h(){var a=p.shift();q=1,a?a.t?m(function(){("c"==a.t?B.injectCss:B.injectJs)(a.s,0,a.a,a.x,a.e,1)},0):(a(),h()):q=0}function i(a,c,d,e,f,i,j){function k(b){if(!o&&g(l.readyState)&&(u.r=o=1,!q&&h(),l.onload=l.onreadystatechange=null,b)){"img"!=a&&m(function(){t.removeChild(l)},50);for(var d in y[c])y[c].hasOwnProperty(d)&&y[c][d].onload()}}var j=j||B.errorTimeout,l=b.createElement(a),o=0,r=0,u={t:d,s:c,e:f,a:i,x:j};1===y[c]&&(r=1,y[c]=[]),"object"==a?l.data=c:(l.src=c,l.type=a),l.width=l.height="0",l.onerror=l.onload=l.onreadystatechange=function(){k.call(this,r)},p.splice(e,0,u),"img"!=a&&(r||2===y[c]?(t.insertBefore(l,s?null:n),m(k,j)):y[c].push(l))}function j(a,b,c,d,f){return q=0,b=b||"j",e(a)?i("c"==b?v:u,a,b,this.i++,c,d,f):(p.splice(this.i++,0,a),1==p.length&&h()),this}function k(){var a=B;return a.loader={load:j,i:0},a}var l=b.documentElement,m=a.setTimeout,n=b.getElementsByTagName("script")[0],o={}.toString,p=[],q=0,r="MozAppearance"in l.style,s=r&&!!b.createRange().compareNode,t=s?l:n.parentNode,l=a.opera&&"[object Opera]"==o.call(a.opera),l=!!b.attachEvent&&!l,u=r?"object":l?"script":"img",v=l?"script":u,w=Array.isArray||function(a){return"[object Array]"==o.call(a)},x=[],y={},z={timeout:function(a,b){return b.length&&(a.timeout=b[0]),a}},A,B;B=function(a){function b(a){var a=a.split("!"),b=x.length,c=a.pop(),d=a.length,c={url:c,origUrl:c,prefixes:a},e,f,g;for(f=0;f<d;f++)g=a[f].split("="),(e=z[g.shift()])&&(c=e(c,g));for(f=0;f<b;f++)c=x[f](c);return c}function g(a,e,f,g,h){var i=b(a),j=i.autoCallback;i.url.split(".").pop().split("?").shift(),i.bypass||(e&&(e=d(e)?e:e[a]||e[g]||e[a.split("/").pop().split("?")[0]]),i.instead?i.instead(a,e,f,g,h):(y[i.url]?i.noexec=!0:y[i.url]=1,f.load(i.url,i.forceCSS||!i.forceJS&&"css"==i.url.split(".").pop().split("?").shift()?"c":c,i.noexec,i.attrs,i.timeout),(d(e)||d(j))&&f.load(function(){k(),e&&e(i.origUrl,h,g),j&&j(i.origUrl,h,g),y[i.url]=2})))}function h(a,b){function c(a,c){if(a){if(e(a))c||(j=function(){var a=[].slice.call(arguments);k.apply(this,a),l()}),g(a,j,b,0,h);else if(Object(a)===a)for(n in m=function(){var b=0,c;for(c in a)a.hasOwnProperty(c)&&b++;return b}(),a)a.hasOwnProperty(n)&&(!c&&!--m&&(d(j)?j=function(){var a=[].slice.call(arguments);k.apply(this,a),l()}:j[n]=function(a){return function(){var b=[].slice.call(arguments);a&&a.apply(this,b),l()}}(k[n])),g(a[n],j,b,n,h))}else!c&&l()}var h=!!a.test,i=a.load||a.both,j=a.callback||f,k=j,l=a.complete||f,m,n;c(h?a.yep:a.nope,!!i),i&&c(i)}var i,j,l=this.yepnope.loader;if(e(a))g(a,0,l,0);else if(w(a))for(i=0;i<a.length;i++)j=a[i],e(j)?g(j,0,l,0):w(j)?B(j):Object(j)===j&&h(j,l);else Object(a)===a&&h(a,l)},B.addPrefix=function(a,b){z[a]=b},B.addFilter=function(a){x.push(a)},B.errorTimeout=1e4,null==b.readyState&&b.addEventListener&&(b.readyState="loading",b.addEventListener("DOMContentLoaded",A=function(){b.removeEventListener("DOMContentLoaded",A,0),b.readyState="complete"},0)),a.yepnope=k(),a.yepnope.executeStack=h,a.yepnope.injectJs=function(a,c,d,e,i,j){var k=b.createElement("script"),l,o,e=e||B.errorTimeout;k.src=a;for(o in d)k.setAttribute(o,d[o]);c=j?h:c||f,k.onreadystatechange=k.onload=function(){!l&&g(k.readyState)&&(l=1,c(),k.onload=k.onreadystatechange=null)},m(function(){l||(l=1,c(1))},e),i?k.onload():n.parentNode.insertBefore(k,n)},a.yepnope.injectCss=function(a,c,d,e,g,i){var e=b.createElement("link"),j,c=i?h:c||f;e.href=a,e.rel="stylesheet",e.type="text/css";for(j in d)e.setAttribute(j,d[j]);g||(n.parentNode.insertBefore(e,n),m(c,0))}}(this,document),Modernizr.load=function(){yepnope.apply(window,[].slice.call(arguments,0))};
diff --git a/docs/_build/html/_static/js/theme.js b/docs/_build/html/_static/js/theme.js
deleted file mode 100644
index 839d07e2..00000000
--- a/docs/_build/html/_static/js/theme.js
+++ /dev/null
@@ -1 +0,0 @@
-!function(n){var e={};function t(i){if(e[i])return e[i].exports;var o=e[i]={i:i,l:!1,exports:{}};return n[i].call(o.exports,o,o.exports,t),o.l=!0,o.exports}t.m=n,t.c=e,t.d=function(n,e,i){t.o(n,e)||Object.defineProperty(n,e,{enumerable:!0,get:i})},t.r=function(n){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(n,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(n,"__esModule",{value:!0})},t.t=function(n,e){if(1&e&&(n=t(n)),8&e)return n;if(4&e&&"object"==typeof n&&n&&n.__esModule)return n;var i=Object.create(null);if(t.r(i),Object.defineProperty(i,"default",{enumerable:!0,value:n}),2&e&&"string"!=typeof n)for(var o in n)t.d(i,o,function(e){return n[e]}.bind(null,o));return i},t.n=function(n){var e=n&&n.__esModule?function(){return n.default}:function(){return n};return t.d(e,"a",e),e},t.o=function(n,e){return Object.prototype.hasOwnProperty.call(n,e)},t.p="",t(t.s=0)}([function(n,e,t){t(1),n.exports=t(3)},function(n,e,t){(function(){var e="undefined"!=typeof window?window.jQuery:t(2);n.exports.ThemeNav={navBar:null,win:null,winScroll:!1,winResize:!1,linkScroll:!1,winPosition:0,winHeight:null,docHeight:null,isRunning:!1,enable:function(n){var t=this;void 0===n&&(n=!0),t.isRunning||(t.isRunning=!0,e((function(e){t.init(e),t.reset(),t.win.on("hashchange",t.reset),n&&t.win.on("scroll",(function(){t.linkScroll||t.winScroll||(t.winScroll=!0,requestAnimationFrame((function(){t.onScroll()})))})),t.win.on("resize",(function(){t.winResize||(t.winResize=!0,requestAnimationFrame((function(){t.onResize()})))})),t.onResize()})))},enableSticky:function(){this.enable(!0)},init:function(n){n(document);var e=this;this.navBar=n("div.wy-side-scroll:first"),this.win=n(window),n(document).on("click","[data-toggle='wy-nav-top']",(function(){n("[data-toggle='wy-nav-shift']").toggleClass("shift"),n("[data-toggle='rst-versions']").toggleClass("shift")})).on("click",".wy-menu-vertical .current ul li a",(function(){var t=n(this);n("[data-toggle='wy-nav-shift']").removeClass("shift"),n("[data-toggle='rst-versions']").toggleClass("shift"),e.toggleCurrent(t),e.hashChange()})).on("click","[data-toggle='rst-current-version']",(function(){n("[data-toggle='rst-versions']").toggleClass("shift-up")})),n("table.docutils:not(.field-list,.footnote,.citation)").wrap("<div class='wy-table-responsive'></div>"),n("table.docutils.footnote").wrap("<div class='wy-table-responsive footnote'></div>"),n("table.docutils.citation").wrap("<div class='wy-table-responsive citation'></div>"),n(".wy-menu-vertical ul").not(".simple").siblings("a").each((function(){var t=n(this);expand=n('<span class="toctree-expand"></span>'),expand.on("click",(function(n){return e.toggleCurrent(t),n.stopPropagation(),!1})),t.prepend(expand)}))},reset:function(){var n=encodeURI(window.location.hash)||"#";try{var e=$(".wy-menu-vertical"),t=e.find('[href="'+n+'"]');if(0===t.length){var i=$('.document [id="'+n.substring(1)+'"]').closest("div.section");0===(t=e.find('[href="#'+i.attr("id")+'"]')).length&&(t=e.find('[href="#"]'))}t.length>0&&($(".wy-menu-vertical .current").removeClass("current"),t.addClass("current"),t.closest("li.toctree-l1").addClass("current"),t.closest("li.toctree-l1").parent().addClass("current"),t.closest("li.toctree-l1").addClass("current"),t.closest("li.toctree-l2").addClass("current"),t.closest("li.toctree-l3").addClass("current"),t.closest("li.toctree-l4").addClass("current"),t.closest("li.toctree-l5").addClass("current"),t[0].scrollIntoView())}catch(n){console.log("Error expanding nav for anchor",n)}},onScroll:function(){this.winScroll=!1;var n=this.win.scrollTop(),e=n+this.winHeight,t=this.navBar.scrollTop()+(n-this.winPosition);n<0||e>this.docHeight||(this.navBar.scrollTop(t),this.winPosition=n)},onResize:function(){this.winResize=!1,this.winHeight=this.win.height(),this.docHeight=$(document).height()},hashChange:function(){this.linkScroll=!0,this.win.one("hashchange",(function(){this.linkScroll=!1}))},toggleCurrent:function(n){var e=n.closest("li");e.siblings("li.current").removeClass("current"),e.siblings().find("li.current").removeClass("current"),e.find("> ul li.current").removeClass("current"),e.toggleClass("current")}},"undefined"!=typeof window&&(window.SphinxRtdTheme={Navigation:n.exports.ThemeNav,StickyNav:n.exports.ThemeNav}),function(){for(var n=0,e=["ms","moz","webkit","o"],t=0;t<e.length&&!window.requestAnimationFrame;++t)window.requestAnimationFrame=window[e[t]+"RequestAnimationFrame"],window.cancelAnimationFrame=window[e[t]+"CancelAnimationFrame"]||window[e[t]+"CancelRequestAnimationFrame"];window.requestAnimationFrame||(window.requestAnimationFrame=function(e,t){var i=(new Date).getTime(),o=Math.max(0,16-(i-n)),r=window.setTimeout((function(){e(i+o)}),o);return n=i+o,r}),window.cancelAnimationFrame||(window.cancelAnimationFrame=function(n){clearTimeout(n)})}()}).call(window)},function(n,e){n.exports=jQuery},function(n,e,t){}]);
\ No newline at end of file
diff --git a/docs/_build/html/_static/language_data.js b/docs/_build/html/_static/language_data.js
deleted file mode 100644
index 70c1c294..00000000
--- a/docs/_build/html/_static/language_data.js
+++ /dev/null
@@ -1,297 +0,0 @@
-/*
- * language_data.js
- * ~~~~~~~~~~~~~~~~
- *
- * This script contains the language-specific data used by searchtools.js,
- * namely the list of stopwords, stemmer, scorer and splitter.
- *
- * :copyright: Copyright 2007-2021 by the Sphinx team, see AUTHORS.
- * :license: BSD, see LICENSE for details.
- *
- */
-
-var stopwords = ["a","and","are","as","at","be","but","by","for","if","in","into","is","it","near","no","not","of","on","or","such","that","the","their","then","there","these","they","this","to","was","will","with"];
-
-
-/* Non-minified version is copied as a separate JS file, is available */
-
-/**
- * Porter Stemmer
- */
-var Stemmer = function() {
-
-  var step2list = {
-    ational: 'ate',
-    tional: 'tion',
-    enci: 'ence',
-    anci: 'ance',
-    izer: 'ize',
-    bli: 'ble',
-    alli: 'al',
-    entli: 'ent',
-    eli: 'e',
-    ousli: 'ous',
-    ization: 'ize',
-    ation: 'ate',
-    ator: 'ate',
-    alism: 'al',
-    iveness: 'ive',
-    fulness: 'ful',
-    ousness: 'ous',
-    aliti: 'al',
-    iviti: 'ive',
-    biliti: 'ble',
-    logi: 'log'
-  };
-
-  var step3list = {
-    icate: 'ic',
-    ative: '',
-    alize: 'al',
-    iciti: 'ic',
-    ical: 'ic',
-    ful: '',
-    ness: ''
-  };
-
-  var c = "[^aeiou]";          // consonant
-  var v = "[aeiouy]";          // vowel
-  var C = c + "[^aeiouy]*";    // consonant sequence
-  var V = v + "[aeiou]*";      // vowel sequence
-
-  var mgr0 = "^(" + C + ")?" + V + C;                      // [C]VC... is m>0
-  var meq1 = "^(" + C + ")?" + V + C + "(" + V + ")?$";    // [C]VC[V] is m=1
-  var mgr1 = "^(" + C + ")?" + V + C + V + C;              // [C]VCVC... is m>1
-  var s_v   = "^(" + C + ")?" + v;                         // vowel in stem
-
-  this.stemWord = function (w) {
-    var stem;
-    var suffix;
-    var firstch;
-    var origword = w;
-
-    if (w.length < 3)
-      return w;
-
-    var re;
-    var re2;
-    var re3;
-    var re4;
-
-    firstch = w.substr(0,1);
-    if (firstch == "y")
-      w = firstch.toUpperCase() + w.substr(1);
-
-    // Step 1a
-    re = /^(.+?)(ss|i)es$/;
-    re2 = /^(.+?)([^s])s$/;
-
-    if (re.test(w))
-      w = w.replace(re,"$1$2");
-    else if (re2.test(w))
-      w = w.replace(re2,"$1$2");
-
-    // Step 1b
-    re = /^(.+?)eed$/;
-    re2 = /^(.+?)(ed|ing)$/;
-    if (re.test(w)) {
-      var fp = re.exec(w);
-      re = new RegExp(mgr0);
-      if (re.test(fp[1])) {
-        re = /.$/;
-        w = w.replace(re,"");
-      }
-    }
-    else if (re2.test(w)) {
-      var fp = re2.exec(w);
-      stem = fp[1];
-      re2 = new RegExp(s_v);
-      if (re2.test(stem)) {
-        w = stem;
-        re2 = /(at|bl|iz)$/;
-        re3 = new RegExp("([^aeiouylsz])\\1$");
-        re4 = new RegExp("^" + C + v + "[^aeiouwxy]$");
-        if (re2.test(w))
-          w = w + "e";
-        else if (re3.test(w)) {
-          re = /.$/;
-          w = w.replace(re,"");
-        }
-        else if (re4.test(w))
-          w = w + "e";
-      }
-    }
-
-    // Step 1c
-    re = /^(.+?)y$/;
-    if (re.test(w)) {
-      var fp = re.exec(w);
-      stem = fp[1];
-      re = new RegExp(s_v);
-      if (re.test(stem))
-        w = stem + "i";
-    }
-
-    // Step 2
-    re = /^(.+?)(ational|tional|enci|anci|izer|bli|alli|entli|eli|ousli|ization|ation|ator|alism|iveness|fulness|ousness|aliti|iviti|biliti|logi)$/;
-    if (re.test(w)) {
-      var fp = re.exec(w);
-      stem = fp[1];
-      suffix = fp[2];
-      re = new RegExp(mgr0);
-      if (re.test(stem))
-        w = stem + step2list[suffix];
-    }
-
-    // Step 3
-    re = /^(.+?)(icate|ative|alize|iciti|ical|ful|ness)$/;
-    if (re.test(w)) {
-      var fp = re.exec(w);
-      stem = fp[1];
-      suffix = fp[2];
-      re = new RegExp(mgr0);
-      if (re.test(stem))
-        w = stem + step3list[suffix];
-    }
-
-    // Step 4
-    re = /^(.+?)(al|ance|ence|er|ic|able|ible|ant|ement|ment|ent|ou|ism|ate|iti|ous|ive|ize)$/;
-    re2 = /^(.+?)(s|t)(ion)$/;
-    if (re.test(w)) {
-      var fp = re.exec(w);
-      stem = fp[1];
-      re = new RegExp(mgr1);
-      if (re.test(stem))
-        w = stem;
-    }
-    else if (re2.test(w)) {
-      var fp = re2.exec(w);
-      stem = fp[1] + fp[2];
-      re2 = new RegExp(mgr1);
-      if (re2.test(stem))
-        w = stem;
-    }
-
-    // Step 5
-    re = /^(.+?)e$/;
-    if (re.test(w)) {
-      var fp = re.exec(w);
-      stem = fp[1];
-      re = new RegExp(mgr1);
-      re2 = new RegExp(meq1);
-      re3 = new RegExp("^" + C + v + "[^aeiouwxy]$");
-      if (re.test(stem) || (re2.test(stem) && !(re3.test(stem))))
-        w = stem;
-    }
-    re = /ll$/;
-    re2 = new RegExp(mgr1);
-    if (re.test(w) && re2.test(w)) {
-      re = /.$/;
-      w = w.replace(re,"");
-    }
-
-    // and turn initial Y back to y
-    if (firstch == "y")
-      w = firstch.toLowerCase() + w.substr(1);
-    return w;
-  }
-}
-
-
-
-
-var splitChars = (function() {
-    var result = {};
-    var singles = [96, 180, 187, 191, 215, 247, 749, 885, 903, 907, 909, 930, 1014, 1648,
-         1748, 1809, 2416, 2473, 2481, 2526, 2601, 2609, 2612, 2615, 2653, 2702,
-         2706, 2729, 2737, 2740, 2857, 2865, 2868, 2910, 2928, 2948, 2961, 2971,
-         2973, 3085, 3089, 3113, 3124, 3213, 3217, 3241, 3252, 3295, 3341, 3345,
-         3369, 3506, 3516, 3633, 3715, 3721, 3736, 3744, 3748, 3750, 3756, 3761,
-         3781, 3912, 4239, 4347, 4681, 4695, 4697, 4745, 4785, 4799, 4801, 4823,
-         4881, 5760, 5901, 5997, 6313, 7405, 8024, 8026, 8028, 8030, 8117, 8125,
-         8133, 8181, 8468, 8485, 8487, 8489, 8494, 8527, 11311, 11359, 11687, 11695,
-         11703, 11711, 11719, 11727, 11735, 12448, 12539, 43010, 43014, 43019, 43587,
-         43696, 43713, 64286, 64297, 64311, 64317, 64319, 64322, 64325, 65141];
-    var i, j, start, end;
-    for (i = 0; i < singles.length; i++) {
-        result[singles[i]] = true;
-    }
-    var ranges = [[0, 47], [58, 64], [91, 94], [123, 169], [171, 177], [182, 184], [706, 709],
-         [722, 735], [741, 747], [751, 879], [888, 889], [894, 901], [1154, 1161],
-         [1318, 1328], [1367, 1368], [1370, 1376], [1416, 1487], [1515, 1519], [1523, 1568],
-         [1611, 1631], [1642, 1645], [1750, 1764], [1767, 1773], [1789, 1790], [1792, 1807],
-         [1840, 1868], [1958, 1968], [1970, 1983], [2027, 2035], [2038, 2041], [2043, 2047],
-         [2070, 2073], [2075, 2083], [2085, 2087], [2089, 2307], [2362, 2364], [2366, 2383],
-         [2385, 2391], [2402, 2405], [2419, 2424], [2432, 2436], [2445, 2446], [2449, 2450],
-         [2483, 2485], [2490, 2492], [2494, 2509], [2511, 2523], [2530, 2533], [2546, 2547],
-         [2554, 2564], [2571, 2574], [2577, 2578], [2618, 2648], [2655, 2661], [2672, 2673],
-         [2677, 2692], [2746, 2748], [2750, 2767], [2769, 2783], [2786, 2789], [2800, 2820],
-         [2829, 2830], [2833, 2834], [2874, 2876], [2878, 2907], [2914, 2917], [2930, 2946],
-         [2955, 2957], [2966, 2968], [2976, 2978], [2981, 2983], [2987, 2989], [3002, 3023],
-         [3025, 3045], [3059, 3076], [3130, 3132], [3134, 3159], [3162, 3167], [3170, 3173],
-         [3184, 3191], [3199, 3204], [3258, 3260], [3262, 3293], [3298, 3301], [3312, 3332],
-         [3386, 3388], [3390, 3423], [3426, 3429], [3446, 3449], [3456, 3460], [3479, 3481],
-         [3518, 3519], [3527, 3584], [3636, 3647], [3655, 3663], [3674, 3712], [3717, 3718],
-         [3723, 3724], [3726, 3731], [3752, 3753], [3764, 3772], [3774, 3775], [3783, 3791],
-         [3802, 3803], [3806, 3839], [3841, 3871], [3892, 3903], [3949, 3975], [3980, 4095],
-         [4139, 4158], [4170, 4175], [4182, 4185], [4190, 4192], [4194, 4196], [4199, 4205],
-         [4209, 4212], [4226, 4237], [4250, 4255], [4294, 4303], [4349, 4351], [4686, 4687],
-         [4702, 4703], [4750, 4751], [4790, 4791], [4806, 4807], [4886, 4887], [4955, 4968],
-         [4989, 4991], [5008, 5023], [5109, 5120], [5741, 5742], [5787, 5791], [5867, 5869],
-         [5873, 5887], [5906, 5919], [5938, 5951], [5970, 5983], [6001, 6015], [6068, 6102],
-         [6104, 6107], [6109, 6111], [6122, 6127], [6138, 6159], [6170, 6175], [6264, 6271],
-         [6315, 6319], [6390, 6399], [6429, 6469], [6510, 6511], [6517, 6527], [6572, 6592],
-         [6600, 6607], [6619, 6655], [6679, 6687], [6741, 6783], [6794, 6799], [6810, 6822],
-         [6824, 6916], [6964, 6980], [6988, 6991], [7002, 7042], [7073, 7085], [7098, 7167],
-         [7204, 7231], [7242, 7244], [7294, 7400], [7410, 7423], [7616, 7679], [7958, 7959],
-         [7966, 7967], [8006, 8007], [8014, 8015], [8062, 8063], [8127, 8129], [8141, 8143],
-         [8148, 8149], [8156, 8159], [8173, 8177], [8189, 8303], [8306, 8307], [8314, 8318],
-         [8330, 8335], [8341, 8449], [8451, 8454], [8456, 8457], [8470, 8472], [8478, 8483],
-         [8506, 8507], [8512, 8516], [8522, 8525], [8586, 9311], [9372, 9449], [9472, 10101],
-         [10132, 11263], [11493, 11498], [11503, 11516], [11518, 11519], [11558, 11567],
-         [11622, 11630], [11632, 11647], [11671, 11679], [11743, 11822], [11824, 12292],
-         [12296, 12320], [12330, 12336], [12342, 12343], [12349, 12352], [12439, 12444],
-         [12544, 12548], [12590, 12592], [12687, 12689], [12694, 12703], [12728, 12783],
-         [12800, 12831], [12842, 12880], [12896, 12927], [12938, 12976], [12992, 13311],
-         [19894, 19967], [40908, 40959], [42125, 42191], [42238, 42239], [42509, 42511],
-         [42540, 42559], [42592, 42593], [42607, 42622], [42648, 42655], [42736, 42774],
-         [42784, 42785], [42889, 42890], [42893, 43002], [43043, 43055], [43062, 43071],
-         [43124, 43137], [43188, 43215], [43226, 43249], [43256, 43258], [43260, 43263],
-         [43302, 43311], [43335, 43359], [43389, 43395], [43443, 43470], [43482, 43519],
-         [43561, 43583], [43596, 43599], [43610, 43615], [43639, 43641], [43643, 43647],
-         [43698, 43700], [43703, 43704], [43710, 43711], [43715, 43738], [43742, 43967],
-         [44003, 44015], [44026, 44031], [55204, 55215], [55239, 55242], [55292, 55295],
-         [57344, 63743], [64046, 64047], [64110, 64111], [64218, 64255], [64263, 64274],
-         [64280, 64284], [64434, 64466], [64830, 64847], [64912, 64913], [64968, 65007],
-         [65020, 65135], [65277, 65295], [65306, 65312], [65339, 65344], [65371, 65381],
-         [65471, 65473], [65480, 65481], [65488, 65489], [65496, 65497]];
-    for (i = 0; i < ranges.length; i++) {
-        start = ranges[i][0];
-        end = ranges[i][1];
-        for (j = start; j <= end; j++) {
-            result[j] = true;
-        }
-    }
-    return result;
-})();
-
-function splitQuery(query) {
-    var result = [];
-    var start = -1;
-    for (var i = 0; i < query.length; i++) {
-        if (splitChars[query.charCodeAt(i)]) {
-            if (start !== -1) {
-                result.push(query.slice(start, i));
-                start = -1;
-            }
-        } else if (start === -1) {
-            start = i;
-        }
-    }
-    if (start !== -1) {
-        result.push(query.slice(start));
-    }
-    return result;
-}
-
-
diff --git a/docs/_build/html/_static/minus.png b/docs/_build/html/_static/minus.png
deleted file mode 100644
index d96755fd..00000000
Binary files a/docs/_build/html/_static/minus.png and /dev/null differ
diff --git a/docs/_build/html/_static/plus.png b/docs/_build/html/_static/plus.png
deleted file mode 100644
index 7107cec9..00000000
Binary files a/docs/_build/html/_static/plus.png and /dev/null differ
diff --git a/docs/_build/html/_static/pygments.css b/docs/_build/html/_static/pygments.css
deleted file mode 100644
index ff153c57..00000000
--- a/docs/_build/html/_static/pygments.css
+++ /dev/null
@@ -1,74 +0,0 @@
-pre { line-height: 125%; }
-td.linenos .normal { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }
-span.linenos { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }
-td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
-span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
-.highlight .hll { background-color: #ffffcc }
-.highlight { background: #f8f8f8; }
-.highlight .c { color: #408080; font-style: italic } /* Comment */
-.highlight .err { border: 1px solid #FF0000 } /* Error */
-.highlight .k { color: #008000; font-weight: bold } /* Keyword */
-.highlight .o { color: #666666 } /* Operator */
-.highlight .ch { color: #408080; font-style: italic } /* Comment.Hashbang */
-.highlight .cm { color: #408080; font-style: italic } /* Comment.Multiline */
-.highlight .cp { color: #BC7A00 } /* Comment.Preproc */
-.highlight .cpf { color: #408080; font-style: italic } /* Comment.PreprocFile */
-.highlight .c1 { color: #408080; font-style: italic } /* Comment.Single */
-.highlight .cs { color: #408080; font-style: italic } /* Comment.Special */
-.highlight .gd { color: #A00000 } /* Generic.Deleted */
-.highlight .ge { font-style: italic } /* Generic.Emph */
-.highlight .gr { color: #FF0000 } /* Generic.Error */
-.highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */
-.highlight .gi { color: #00A000 } /* Generic.Inserted */
-.highlight .go { color: #888888 } /* Generic.Output */
-.highlight .gp { color: #000080; font-weight: bold } /* Generic.Prompt */
-.highlight .gs { font-weight: bold } /* Generic.Strong */
-.highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */
-.highlight .gt { color: #0044DD } /* Generic.Traceback */
-.highlight .kc { color: #008000; font-weight: bold } /* Keyword.Constant */
-.highlight .kd { color: #008000; font-weight: bold } /* Keyword.Declaration */
-.highlight .kn { color: #008000; font-weight: bold } /* Keyword.Namespace */
-.highlight .kp { color: #008000 } /* Keyword.Pseudo */
-.highlight .kr { color: #008000; font-weight: bold } /* Keyword.Reserved */
-.highlight .kt { color: #B00040 } /* Keyword.Type */
-.highlight .m { color: #666666 } /* Literal.Number */
-.highlight .s { color: #BA2121 } /* Literal.String */
-.highlight .na { color: #7D9029 } /* Name.Attribute */
-.highlight .nb { color: #008000 } /* Name.Builtin */
-.highlight .nc { color: #0000FF; font-weight: bold } /* Name.Class */
-.highlight .no { color: #880000 } /* Name.Constant */
-.highlight .nd { color: #AA22FF } /* Name.Decorator */
-.highlight .ni { color: #999999; font-weight: bold } /* Name.Entity */
-.highlight .ne { color: #D2413A; font-weight: bold } /* Name.Exception */
-.highlight .nf { color: #0000FF } /* Name.Function */
-.highlight .nl { color: #A0A000 } /* Name.Label */
-.highlight .nn { color: #0000FF; font-weight: bold } /* Name.Namespace */
-.highlight .nt { color: #008000; font-weight: bold } /* Name.Tag */
-.highlight .nv { color: #19177C } /* Name.Variable */
-.highlight .ow { color: #AA22FF; font-weight: bold } /* Operator.Word */
-.highlight .w { color: #bbbbbb } /* Text.Whitespace */
-.highlight .mb { color: #666666 } /* Literal.Number.Bin */
-.highlight .mf { color: #666666 } /* Literal.Number.Float */
-.highlight .mh { color: #666666 } /* Literal.Number.Hex */
-.highlight .mi { color: #666666 } /* Literal.Number.Integer */
-.highlight .mo { color: #666666 } /* Literal.Number.Oct */
-.highlight .sa { color: #BA2121 } /* Literal.String.Affix */
-.highlight .sb { color: #BA2121 } /* Literal.String.Backtick */
-.highlight .sc { color: #BA2121 } /* Literal.String.Char */
-.highlight .dl { color: #BA2121 } /* Literal.String.Delimiter */
-.highlight .sd { color: #BA2121; font-style: italic } /* Literal.String.Doc */
-.highlight .s2 { color: #BA2121 } /* Literal.String.Double */
-.highlight .se { color: #BB6622; font-weight: bold } /* Literal.String.Escape */
-.highlight .sh { color: #BA2121 } /* Literal.String.Heredoc */
-.highlight .si { color: #BB6688; font-weight: bold } /* Literal.String.Interpol */
-.highlight .sx { color: #008000 } /* Literal.String.Other */
-.highlight .sr { color: #BB6688 } /* Literal.String.Regex */
-.highlight .s1 { color: #BA2121 } /* Literal.String.Single */
-.highlight .ss { color: #19177C } /* Literal.String.Symbol */
-.highlight .bp { color: #008000 } /* Name.Builtin.Pseudo */
-.highlight .fm { color: #0000FF } /* Name.Function.Magic */
-.highlight .vc { color: #19177C } /* Name.Variable.Class */
-.highlight .vg { color: #19177C } /* Name.Variable.Global */
-.highlight .vi { color: #19177C } /* Name.Variable.Instance */
-.highlight .vm { color: #19177C } /* Name.Variable.Magic */
-.highlight .il { color: #666666 } /* Literal.Number.Integer.Long */
\ No newline at end of file
diff --git a/docs/_build/html/_static/searchtools.js b/docs/_build/html/_static/searchtools.js
deleted file mode 100644
index e09f9263..00000000
--- a/docs/_build/html/_static/searchtools.js
+++ /dev/null
@@ -1,522 +0,0 @@
-/*
- * searchtools.js
- * ~~~~~~~~~~~~~~~~
- *
- * Sphinx JavaScript utilities for the full-text search.
- *
- * :copyright: Copyright 2007-2021 by the Sphinx team, see AUTHORS.
- * :license: BSD, see LICENSE for details.
- *
- */
-
-if (!Scorer) {
-  /**
-   * Simple result scoring code.
-   */
-  var Scorer = {
-    // Implement the following function to further tweak the score for each result
-    // The function takes a result array [filename, title, anchor, descr, score]
-    // and returns the new score.
-    /*
-    score: function(result) {
-      return result[4];
-    },
-    */
-
-    // query matches the full name of an object
-    objNameMatch: 11,
-    // or matches in the last dotted part of the object name
-    objPartialMatch: 6,
-    // Additive scores depending on the priority of the object
-    objPrio: {0:  15,   // used to be importantResults
-              1:  5,   // used to be objectResults
-              2: -5},  // used to be unimportantResults
-    //  Used when the priority is not in the mapping.
-    objPrioDefault: 0,
-
-    // query found in title
-    title: 15,
-    partialTitle: 7,
-    // query found in terms
-    term: 5,
-    partialTerm: 2
-  };
-}
-
-if (!splitQuery) {
-  function splitQuery(query) {
-    return query.split(/\s+/);
-  }
-}
-
-/**
- * Search Module
- */
-var Search = {
-
-  _index : null,
-  _queued_query : null,
-  _pulse_status : -1,
-
-  htmlToText : function(htmlString) {
-      var virtualDocument = document.implementation.createHTMLDocument('virtual');
-      var htmlElement = $(htmlString, virtualDocument);
-      htmlElement.find('.headerlink').remove();
-      docContent = htmlElement.find('[role=main]')[0];
-      if(docContent === undefined) {
-          console.warn("Content block not found. Sphinx search tries to obtain it " +
-                       "via '[role=main]'. Could you check your theme or template.");
-          return "";
-      }
-      return docContent.textContent || docContent.innerText;
-  },
-
-  init : function() {
-      var params = $.getQueryParameters();
-      if (params.q) {
-          var query = params.q[0];
-          $('input[name="q"]')[0].value = query;
-          this.performSearch(query);
-      }
-  },
-
-  loadIndex : function(url) {
-    $.ajax({type: "GET", url: url, data: null,
-            dataType: "script", cache: true,
-            complete: function(jqxhr, textstatus) {
-              if (textstatus != "success") {
-                document.getElementById("searchindexloader").src = url;
-              }
-            }});
-  },
-
-  setIndex : function(index) {
-    var q;
-    this._index = index;
-    if ((q = this._queued_query) !== null) {
-      this._queued_query = null;
-      Search.query(q);
-    }
-  },
-
-  hasIndex : function() {
-      return this._index !== null;
-  },
-
-  deferQuery : function(query) {
-      this._queued_query = query;
-  },
-
-  stopPulse : function() {
-      this._pulse_status = 0;
-  },
-
-  startPulse : function() {
-    if (this._pulse_status >= 0)
-        return;
-    function pulse() {
-      var i;
-      Search._pulse_status = (Search._pulse_status + 1) % 4;
-      var dotString = '';
-      for (i = 0; i < Search._pulse_status; i++)
-        dotString += '.';
-      Search.dots.text(dotString);
-      if (Search._pulse_status > -1)
-        window.setTimeout(pulse, 500);
-    }
-    pulse();
-  },
-
-  /**
-   * perform a search for something (or wait until index is loaded)
-   */
-  performSearch : function(query) {
-    // create the required interface elements
-    this.out = $('#search-results');
-    this.title = $('<h2>' + _('Searching') + '</h2>').appendTo(this.out);
-    this.dots = $('<span></span>').appendTo(this.title);
-    this.status = $('<p class="search-summary">&nbsp;</p>').appendTo(this.out);
-    this.output = $('<ul class="search"/>').appendTo(this.out);
-
-    $('#search-progress').text(_('Preparing search...'));
-    this.startPulse();
-
-    // index already loaded, the browser was quick!
-    if (this.hasIndex())
-      this.query(query);
-    else
-      this.deferQuery(query);
-  },
-
-  /**
-   * execute search (requires search index to be loaded)
-   */
-  query : function(query) {
-    var i;
-
-    // stem the searchterms and add them to the correct list
-    var stemmer = new Stemmer();
-    var searchterms = [];
-    var excluded = [];
-    var hlterms = [];
-    var tmp = splitQuery(query);
-    var objectterms = [];
-    for (i = 0; i < tmp.length; i++) {
-      if (tmp[i] !== "") {
-          objectterms.push(tmp[i].toLowerCase());
-      }
-
-      if ($u.indexOf(stopwords, tmp[i].toLowerCase()) != -1 || tmp[i] === "") {
-        // skip this "word"
-        continue;
-      }
-      // stem the word
-      var word = stemmer.stemWord(tmp[i].toLowerCase());
-      // prevent stemmer from cutting word smaller than two chars
-      if(word.length < 3 && tmp[i].length >= 3) {
-        word = tmp[i];
-      }
-      var toAppend;
-      // select the correct list
-      if (word[0] == '-') {
-        toAppend = excluded;
-        word = word.substr(1);
-      }
-      else {
-        toAppend = searchterms;
-        hlterms.push(tmp[i].toLowerCase());
-      }
-      // only add if not already in the list
-      if (!$u.contains(toAppend, word))
-        toAppend.push(word);
-    }
-    var highlightstring = '?highlight=' + $.urlencode(hlterms.join(" "));
-
-    // console.debug('SEARCH: searching for:');
-    // console.info('required: ', searchterms);
-    // console.info('excluded: ', excluded);
-
-    // prepare search
-    var terms = this._index.terms;
-    var titleterms = this._index.titleterms;
-
-    // array of [filename, title, anchor, descr, score]
-    var results = [];
-    $('#search-progress').empty();
-
-    // lookup as object
-    for (i = 0; i < objectterms.length; i++) {
-      var others = [].concat(objectterms.slice(0, i),
-                             objectterms.slice(i+1, objectterms.length));
-      results = results.concat(this.performObjectSearch(objectterms[i], others));
-    }
-
-    // lookup as search terms in fulltext
-    results = results.concat(this.performTermsSearch(searchterms, excluded, terms, titleterms));
-
-    // let the scorer override scores with a custom scoring function
-    if (Scorer.score) {
-      for (i = 0; i < results.length; i++)
-        results[i][4] = Scorer.score(results[i]);
-    }
-
-    // now sort the results by score (in opposite order of appearance, since the
-    // display function below uses pop() to retrieve items) and then
-    // alphabetically
-    results.sort(function(a, b) {
-      var left = a[4];
-      var right = b[4];
-      if (left > right) {
-        return 1;
-      } else if (left < right) {
-        return -1;
-      } else {
-        // same score: sort alphabetically
-        left = a[1].toLowerCase();
-        right = b[1].toLowerCase();
-        return (left > right) ? -1 : ((left < right) ? 1 : 0);
-      }
-    });
-
-    // for debugging
-    //Search.lastresults = results.slice();  // a copy
-    //console.info('search results:', Search.lastresults);
-
-    // print the results
-    var resultCount = results.length;
-    function displayNextItem() {
-      // results left, load the summary and display it
-      if (results.length) {
-        var item = results.pop();
-        var listItem = $('<li></li>');
-        var requestUrl = "";
-        var linkUrl = "";
-        if (DOCUMENTATION_OPTIONS.BUILDER === 'dirhtml') {
-          // dirhtml builder
-          var dirname = item[0] + '/';
-          if (dirname.match(/\/index\/$/)) {
-            dirname = dirname.substring(0, dirname.length-6);
-          } else if (dirname == 'index/') {
-            dirname = '';
-          }
-          requestUrl = DOCUMENTATION_OPTIONS.URL_ROOT + dirname;
-          linkUrl = requestUrl;
-
-        } else {
-          // normal html builders
-          requestUrl = DOCUMENTATION_OPTIONS.URL_ROOT + item[0] + DOCUMENTATION_OPTIONS.FILE_SUFFIX;
-          linkUrl = item[0] + DOCUMENTATION_OPTIONS.LINK_SUFFIX;
-        }
-        listItem.append($('<a/>').attr('href',
-            linkUrl +
-            highlightstring + item[2]).html(item[1]));
-        if (item[3]) {
-          listItem.append($('<span> (' + item[3] + ')</span>'));
-          Search.output.append(listItem);
-          setTimeout(function() {
-            displayNextItem();
-          }, 5);
-        } else if (DOCUMENTATION_OPTIONS.HAS_SOURCE) {
-          $.ajax({url: requestUrl,
-                  dataType: "text",
-                  complete: function(jqxhr, textstatus) {
-                    var data = jqxhr.responseText;
-                    if (data !== '' && data !== undefined) {
-                      listItem.append(Search.makeSearchSummary(data, searchterms, hlterms));
-                    }
-                    Search.output.append(listItem);
-                    setTimeout(function() {
-                      displayNextItem();
-                    }, 5);
-                  }});
-        } else {
-          // no source available, just display title
-          Search.output.append(listItem);
-          setTimeout(function() {
-            displayNextItem();
-          }, 5);
-        }
-      }
-      // search finished, update title and status message
-      else {
-        Search.stopPulse();
-        Search.title.text(_('Search Results'));
-        if (!resultCount)
-          Search.status.text(_('Your search did not match any documents. Please make sure that all words are spelled correctly and that you\'ve selected enough categories.'));
-        else
-            Search.status.text(_('Search finished, found %s page(s) matching the search query.').replace('%s', resultCount));
-        Search.status.fadeIn(500);
-      }
-    }
-    displayNextItem();
-  },
-
-  /**
-   * search for object names
-   */
-  performObjectSearch : function(object, otherterms) {
-    var filenames = this._index.filenames;
-    var docnames = this._index.docnames;
-    var objects = this._index.objects;
-    var objnames = this._index.objnames;
-    var titles = this._index.titles;
-
-    var i;
-    var results = [];
-
-    for (var prefix in objects) {
-      for (var name in objects[prefix]) {
-        var fullname = (prefix ? prefix + '.' : '') + name;
-        var fullnameLower = fullname.toLowerCase()
-        if (fullnameLower.indexOf(object) > -1) {
-          var score = 0;
-          var parts = fullnameLower.split('.');
-          // check for different match types: exact matches of full name or
-          // "last name" (i.e. last dotted part)
-          if (fullnameLower == object || parts[parts.length - 1] == object) {
-            score += Scorer.objNameMatch;
-          // matches in last name
-          } else if (parts[parts.length - 1].indexOf(object) > -1) {
-            score += Scorer.objPartialMatch;
-          }
-          var match = objects[prefix][name];
-          var objname = objnames[match[1]][2];
-          var title = titles[match[0]];
-          // If more than one term searched for, we require other words to be
-          // found in the name/title/description
-          if (otherterms.length > 0) {
-            var haystack = (prefix + ' ' + name + ' ' +
-                            objname + ' ' + title).toLowerCase();
-            var allfound = true;
-            for (i = 0; i < otherterms.length; i++) {
-              if (haystack.indexOf(otherterms[i]) == -1) {
-                allfound = false;
-                break;
-              }
-            }
-            if (!allfound) {
-              continue;
-            }
-          }
-          var descr = objname + _(', in ') + title;
-
-          var anchor = match[3];
-          if (anchor === '')
-            anchor = fullname;
-          else if (anchor == '-')
-            anchor = objnames[match[1]][1] + '-' + fullname;
-          // add custom score for some objects according to scorer
-          if (Scorer.objPrio.hasOwnProperty(match[2])) {
-            score += Scorer.objPrio[match[2]];
-          } else {
-            score += Scorer.objPrioDefault;
-          }
-          results.push([docnames[match[0]], fullname, '#'+anchor, descr, score, filenames[match[0]]]);
-        }
-      }
-    }
-
-    return results;
-  },
-
-  /**
-   * See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions
-   */
-  escapeRegExp : function(string) {
-    return string.replace(/[.*+\-?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string
-  },
-
-  /**
-   * search for full-text terms in the index
-   */
-  performTermsSearch : function(searchterms, excluded, terms, titleterms) {
-    var docnames = this._index.docnames;
-    var filenames = this._index.filenames;
-    var titles = this._index.titles;
-
-    var i, j, file;
-    var fileMap = {};
-    var scoreMap = {};
-    var results = [];
-
-    // perform the search on the required terms
-    for (i = 0; i < searchterms.length; i++) {
-      var word = searchterms[i];
-      var files = [];
-      var _o = [
-        {files: terms[word], score: Scorer.term},
-        {files: titleterms[word], score: Scorer.title}
-      ];
-      // add support for partial matches
-      if (word.length > 2) {
-        var word_regex = this.escapeRegExp(word);
-        for (var w in terms) {
-          if (w.match(word_regex) && !terms[word]) {
-            _o.push({files: terms[w], score: Scorer.partialTerm})
-          }
-        }
-        for (var w in titleterms) {
-          if (w.match(word_regex) && !titleterms[word]) {
-              _o.push({files: titleterms[w], score: Scorer.partialTitle})
-          }
-        }
-      }
-
-      // no match but word was a required one
-      if ($u.every(_o, function(o){return o.files === undefined;})) {
-        break;
-      }
-      // found search word in contents
-      $u.each(_o, function(o) {
-        var _files = o.files;
-        if (_files === undefined)
-          return
-
-        if (_files.length === undefined)
-          _files = [_files];
-        files = files.concat(_files);
-
-        // set score for the word in each file to Scorer.term
-        for (j = 0; j < _files.length; j++) {
-          file = _files[j];
-          if (!(file in scoreMap))
-            scoreMap[file] = {};
-          scoreMap[file][word] = o.score;
-        }
-      });
-
-      // create the mapping
-      for (j = 0; j < files.length; j++) {
-        file = files[j];
-        if (file in fileMap && fileMap[file].indexOf(word) === -1)
-          fileMap[file].push(word);
-        else
-          fileMap[file] = [word];
-      }
-    }
-
-    // now check if the files don't contain excluded terms
-    for (file in fileMap) {
-      var valid = true;
-
-      // check if all requirements are matched
-      var filteredTermCount = // as search terms with length < 3 are discarded: ignore
-        searchterms.filter(function(term){return term.length > 2}).length
-      if (
-        fileMap[file].length != searchterms.length &&
-        fileMap[file].length != filteredTermCount
-      ) continue;
-
-      // ensure that none of the excluded terms is in the search result
-      for (i = 0; i < excluded.length; i++) {
-        if (terms[excluded[i]] == file ||
-            titleterms[excluded[i]] == file ||
-            $u.contains(terms[excluded[i]] || [], file) ||
-            $u.contains(titleterms[excluded[i]] || [], file)) {
-          valid = false;
-          break;
-        }
-      }
-
-      // if we have still a valid result we can add it to the result list
-      if (valid) {
-        // select one (max) score for the file.
-        // for better ranking, we should calculate ranking by using words statistics like basic tf-idf...
-        var score = $u.max($u.map(fileMap[file], function(w){return scoreMap[file][w]}));
-        results.push([docnames[file], titles[file], '', null, score, filenames[file]]);
-      }
-    }
-    return results;
-  },
-
-  /**
-   * helper function to return a node containing the
-   * search summary for a given text. keywords is a list
-   * of stemmed words, hlwords is the list of normal, unstemmed
-   * words. the first one is used to find the occurrence, the
-   * latter for highlighting it.
-   */
-  makeSearchSummary : function(htmlText, keywords, hlwords) {
-    var text = Search.htmlToText(htmlText);
-    var textLower = text.toLowerCase();
-    var start = 0;
-    $.each(keywords, function() {
-      var i = textLower.indexOf(this.toLowerCase());
-      if (i > -1)
-        start = i;
-    });
-    start = Math.max(start - 120, 0);
-    var excerpt = ((start > 0) ? '...' : '') +
-      $.trim(text.substr(start, 240)) +
-      ((start + 240 - text.length) ? '...' : '');
-    var rv = $('<p class="context"></p>').text(excerpt);
-    $.each(hlwords, function() {
-      rv = rv.highlightText(this, 'highlighted');
-    });
-    return rv;
-  }
-};
-
-$(document).ready(function() {
-  Search.init();
-});
diff --git a/docs/_build/html/_static/style.css b/docs/_build/html/_static/style.css
deleted file mode 100644
index feb26c88..00000000
--- a/docs/_build/html/_static/style.css
+++ /dev/null
@@ -1,1316 +0,0 @@
-/*
-This theme was created from scratch.
-Historically however, thanks to:
-- Alabaster for being a good base
-  - Which thanks Flask + KR theme
-- Sphinx Readable Theme
-  - Which also proved to be a great base
-*/
-
-/*
-  note: this CSS is "mobile first"
-  The desktop implementation is near the bottom
-*/
-
-* {
-    box-sizing: border-box;
-  }
-  
-  /* CSS variables would go here */
-  :root {
-    --font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
-    --monospace-font-family: 'Consolas', 'Menlo', 'Deja Vu Sans Mono', 'Bitstream Vera Sans Mono', monospace;
-  
-    /* palette goes here */
-    --white: #ffffff;
-    --grey-1: #f9f9fa;
-    --grey-1-8: rgba(249, 249, 250, 0.8);
-    --grey-2: #ededf0;
-    --grey-3: #d7d7db;
-    --grey-4: #b1b1b3;
-    --grey-5: #737373;
-    --grey-6: #4a4a4f;
-    --grey-7: #38383d;
-    --grey-8: #2a2a2e;
-    --black: #0c0c0d;
-  
-    --blue-1: #3399ff;
-    --blue-2: #0a84ff;
-    --blue-3: #0060df;
-    --blue-4: #003eaa;
-    --blue-5: #002275;
-    --blue-6: #000f40;
-  
-    --settings: var(--grey-1);
-    --settings-hover: var(--grey-1-8);
-    --main-background: var(--grey-1);
-    --link-text: var(--blue-2);
-    --link-hover-text: var(--blue-6);
-    --main-text: var(--black);
-    --mobile-nav-background: var(--black);
-    --mobile-nav-text: var(--white);
-    --mobile-nav-hover-text: var(--white);
-    --mobile-nav-header-text: var(--white);
-    --nav-background: var(--main-background);
-    --nav-text: var(--grey-6);
-    --nav-hover-text: var(--grey-6);
-    --nav-header-text: var(--black);
-    --sub-header-background: var(--grey-6);
-    --search-border: var(--grey-4);
-    --search-text: var(--white);
-    --search-focus: var(--blue-1);
-    --search-button: var(--grey-1);
-    --search-button-hover: var(--grey-1-8);
-    --footer-text: var(--grey-5);
-    --footer-link: var(--grey-6);
-    --hr-border: var(--grey-2);
-    --main-big-headers-text: var(--black);
-    --main-big-headers-border: var(--grey-4);
-    --main-h5-header-text: var(--black);
-    --main-h6-header-text: var(--grey-4);
-    --main-h4-header-border: var(--grey-4);
-    --header-link: var(--grey-6);
-    --header-link-hover-text: var(--white);
-    --admonition-background: var(--grey-2);
-    --note-background: var(--blue-1);
-    --note-text: var(--white);
-    --warning-background: #ffe900;
-    --warning-text: var(--black);
-    --error-background: #d70022;
-    --error-text: var(--white);
-    --helpful-background: #00c8d7;
-    --helpful-text: var(--black);
-    --codeblock-background: var(--grey-2);
-    --codeblock-border: var(--grey-4);
-    --codeblock-text: var(--grey-6);
-    --inline-code-background: var(--grey-3);
-    --xref-code-background: transparent;
-    --api-entry-background: var(--grey-2);
-    --table-header-background: var(--grey-3);
-    --table-text: var(--black);
-    --table-border: var(--grey-4);
-    --mobile-active-toc: var(--grey-7);
-    --active-toc: var(--grey-3);
-    --scrollbar: rgba(0,0,0,0.2);
-    --scrollbar-hover: rgba(0,0,0,0.4);
-    --rtd-ad-border: var(--grey-3);
-    --rtd-ad-background: var(--grey-2);
-    --rtd-ad-main-text: var(--grey-6);
-    --rtd-ad-small-text: var(--grey-4);
-    --rtd-version-background: #272525;
-    --rtd-version-main-text: #fcfcfc;
-    --attribute-table-title: var(--grey-6);
-    --attribute-table-entry-border: var(--grey-3);
-    --attribute-table-entry-text: var(--grey-5);
-    --attribute-table-entry-hover-border: var(--blue-2);
-    --attribute-table-entry-hover-background: var(--grey-2);
-    --attribute-table-entry-hover-text: var(--blue-2);
-    --attribute-table-badge: var(--grey-7);
-    --highlighted-text: rgb(252, 233, 103);
-  }
-  
-  :root[data-font="serif"] {
-    --font-family: 'Georgia', 'Yu Gothic', 'Noto Sans CJK JP Regular', serif;
-  }
-  
-  :root[data-theme="dark"] {
-    --main-background: var(--grey-7);
-    --link-text: var(--blue-1);
-    --link-hover-text: var(--blue-2);
-    --main-text: var(--white);
-    --sub-header-background: var(--grey-8);
-    --search-border: var(--grey-5);
-    --nav-background: var(--main-background);
-    --nav-text: var(--grey-1);
-    --nav-hover-text: var(--grey-2);
-    --nav-header-text: var(--white);
-    --footer-text: var(--grey-2);
-    --footer-link: var(--grey-1);
-    --hr-border: var(--grey-1);
-    --main-big-headers-text: var(--grey-1);
-    --main-big-headers-border: var(--grey-1);
-    --main-h5-header-text: var(--grey-4);
-    --main-h6-header-text: var(--grey-5);
-    --main-h4-header-border: var(--grey-2);
-    --header-link: var(--grey-2);
-    --header-link-hover-text: var(--grey-6);
-    --admonition-background: var(--grey-8);
-    --note-background: var(--blue-3);
-    --note-text: var(--white);
-    --warning-background: #d7b600;
-    --warning-text: var(--black);
-    --error-background:  #d70022;
-    --error-text: var(--white);
-    --helpful-background: #008ea4;
-    --helpful-text: var(--white);
-    --codeblock-background: var(--grey-6);
-    --codeblock-border: var(--black);
-    --codeblock-text: var(--grey-1);
-    --inline-code-background: var(--grey-8);
-    --xref-code-background: transparent;
-    --api-entry-background: var(--grey-6);
-    --table-header-background: var(--grey-6);
-    --table-text: var(--grey-1);
-    --table-border: var(--grey-4);
-    --active-toc: var(--grey-6);
-    --scrollbar: rgba(0,0,0,0.5);
-    --scrollbar-hover: rgba(0,0,0,0.7);
-    --rtd-ad-border: var(--grey-6);
-    --rtd-ad-background: var(--grey-5);
-    --rtd-ad-main-text: var(--grey-2);
-    --rtd-ad-small-text: var(--grey-1);
-    --attribute-table-title: var(--grey-3);
-    --attribute-table-entry-border: var(--grey-5);
-    --attribute-table-entry-text: var(--grey-3);
-    --attribute-table-entry-hover-border: var(--blue-1);
-    --attribute-table-entry-hover-background: var(--grey-6);
-    --attribute-table-entry-hover-text: var(--blue-1);
-    --attribute-table-badge: var(--grey-4);
-    --highlighted-text: rgba(250, 166, 26, 0.2);
-  }
-  
-  img[src$="snake_dark.svg"]  {
-    display: none;
-  }
-  :root[data-theme="dark"] img[src$="snake.svg"] {
-    display: none;
-  }
-  :root[data-theme="dark"] img[src$="snake_dark.svg"] {
-    display: inherit;
-  }
-  
-  body {
-    font-family: var(--font-family);
-    font-size: 16px;
-    margin: 0;
-    padding: 0;
-    height: 100%;
-    background-color: var(--main-background);
-    color: var(--main-text);
-  }
-  
-  
-  /* Scrollbar related */
-  
-  #sidebar::-webkit-scrollbar {
-    width: 0.5em;
-  }
-  
-  #sidebar::-webkit-scrollbar-thumb {
-    background-color: var(--scrollbar);
-    border-radius: 0.25em;
-  }
-  
-  #sidebar::-webkit-scrollbar-thumb:hover {
-    background-color: var(--scrollbar-hover);
-  }
-  
-  
-  /* grid related */
-  
-  .main-grid {
-    display: grid;
-    min-height: 100%;
-    grid-auto-rows: min-content auto min-content;
-    grid-template-areas:
-      "s"
-      "h"
-      "n"
-      "c"
-      "f";
-  }
-  
-  .grid-item {
-    max-width: 100vw;
-    padding: 0.8em;
-  }
-  
-  /* all URLs only show underline on hover */
-  a {
-    text-decoration: none;
-    color: var(--link-text);
-  }
-  
-  a:hover {
-    text-decoration: underline;
-    color: var(--link-hover-text);
-  }
-  
-  /* headers */
-  
-  header.grid-item {
-    grid-area: h;
-    color: var(--main-text);
-    position: relative;
-    z-index: 1;
-    padding: 0;
-  }
-  
-  header > nav {
-    background-color: var(--sub-header-background);
-    padding: 0.8em;
-    display: flex;
-    flex-direction: row;
-    justify-content: flex-end;
-    align-items: center;
-  }
-  
-  header > nav a {
-    color: var(--white);
-  }
-  
-  header > nav.mobile-only {
-    width: 100%;
-    position: absolute;
-    top: 0;
-    right: 0;
-    z-index: -1;
-    padding-top: 0;
-    transition: top 0.5s ease-in-out;
-  }
-  
-  header > nav.mobile-only .search {
-    width: 100%;
-  }
-  
-  header > nav.mobile-only .search-wrapper {
-    background-color: var(--sub-header-background);
-  }
-  
-  .main-heading {
-    margin-right: auto;
-  }
-  
-  header > nav a:not(.main-heading) {
-    margin: 0 0.5em;
-  }
-  
-  header > nav > a:hover {
-    color: var(--grey-1-8);
-    text-decoration: underline;
-  }
-  
-  .sub-header {
-    grid-area: n;
-    background-color: var(--sub-header-background);
-    color: var(--white);
-    display: none;
-  }
-  
-  /* these aren't shown on mobile */
-  
-  .sub-header > label {
-    display: none;
-    margin-right: 1em;
-  }
-  
-  .sub-header > select {
-    display: none;
-    background-color: transparent;
-    padding: 0.4em 0;
-    font-size: 1em;
-    width: 13.5%;
-    color: white;
-    border: none;
-    border-bottom: 1px solid var(--search-border);
-  
-    appearance: none;
-    background-image: url('/_images/drop_down_icon.svg');
-    background-repeat: no-repeat;
-    background-position-x: 100%;
-    background-position-y: 50%;
-  
-    cursor: pointer;
-  }
-  
-  .sub-header option {
-      color: black;
-  }
-  
-  .sub-header > select:focus {
-    outline: none;
-  }
-  
-  .sub-header > .settings {
-    color: var(--settings);
-    display: none;
-    margin-left: 1em;
-    margin-right: 0.5em;
-  }
-  
-  .setting h3 {
-    display: inline-block;
-    margin-left: 2em;
-  }
-  
-  .sub-header > .settings:hover {
-    color: var(--settings-hover);
-  }
-  
-  /* footer stuff */
-  footer {
-    grid-area: f;
-    font-size: 14px;
-    text-align: right;
-    color: var(--footer-text);
-  }
-  
-  footer a {
-    text-decoration: underline;
-    color: var(--footer-link);
-  }
-  
-  /* sidebar stuff */
-  
-  aside {
-    grid-area: s;
-    font-size: 14px;
-    line-height: 1.75em;
-    top: 0;
-    position: -webkit-sticky; /* safari */
-    position: sticky;
-    background-color: var(--mobile-nav-background);
-    color: var(--mobile-nav-text);
-    z-index: 2;
-    max-height: 100vh;
-    overflow-y: auto;
-    overscroll-behavior-y: contain;
-  }
-  
-  aside h3 {
-    color: var(--mobile-nav-header-text);
-    font-size: 24px;
-    font-weight: normal;
-  }
-  
-  .collapsible-arrow {
-    font-size: 1.5em!important;
-    left: -1.166em;
-    top: 0.25em;
-    user-select: none;
-    position: relative;
-    line-height: 0.5em;
-    transition: transform 0.4s;
-    transform: rotate(-90deg);
-  }
-  
-  .expanded {
-    transition: transform 0.4s;
-    transform: rotate(0deg);
-  }
-  
-  .ref-internal-padding {
-    position: relative;
-    left: -20px;
-  }
-  
-  #settings-toggle {
-    float: right;
-  }
-  
-  aside .material-icons,
-  .settings > .material-icons {
-    cursor: pointer;
-    font-size: 2em;
-  }
-  
-  .sidebar-toggle {
-    display: unset !important;
-  }
-  
-  #sidebar {
-    display: none;
-  }
-  
-  #sidebar a {
-    color: var(--mobile-nav-text);
-  }
-  
-  #sidebar a:hover {
-    color: var(--mobile-nav-hover-text);
-  }
-  
-  #sidebar h3 {
-    font-size: 24px;
-    margin: 1em 1em 0 0;
-  }
-  
-  #sidebar ul {
-    list-style: none;
-    margin: 1em 2em 2em 1em;
-    padding: 0;
-  }
-  
-  #sidebar ul ul {
-    list-style: square;
-    margin: 0em;
-    margin-left: 1.5em;
-  }
-  
-  #sidebar li.no-list-style {
-    list-style: none;
-  }
-  
-  #sidebar form {
-    margin: 1em 0;
-    display: flex;
-    align-items: baseline;
-  }
-  
-  /* search button stuff */
-  
-  .search-wrapper {
-    display: flex;
-    align-items: stretch;
-  }
-  
-  .search-wrapper > input[type=search] {
-    font-family: "Roboto", Corbel, Avenir, "Lucida Grande", "Lucida Sans", sans-serif;
-    outline: none;
-    appearance: none;
-    font-size: 1em;
-  }
-  
-  .search-wrapper > input[type=search],
-  .search-wrapper > button[type=submit] {
-    background-color: var(--sub-header-background);
-    border: none;
-    color: var(--search-text);
-    padding: 0.5em;
-    min-height: 2.5em;
-    flex: 9;
-  }
-  
-  .search-wrapper {
-    border-bottom: 1px solid var(--search-border);
-  }
-  
-  .search-wrapper:focus-within {
-    border-bottom: 1px solid var(--search-focus);
-  }
-  
-  /* .search-wrapper > input[type=search] {
-    border: 1px solid var(--search-border);
-    border-right: none;
-    border-top-left-radius: 4px;
-    border-bottom-left-radius: 4px;
-  }
-  .search-wrapper > input[type=search]:focus,
-  button[type=submit]:focus ~ input[type=search] {
-    border: 1px solid var(--search-focus);
-    border-right: none;
-  } */
-  
-  .search-wrapper > button[type=submit] {
-    color: var(--search-button);
-    /* border: 1px solid var(--search-border); */
-    /* border-left: none; */
-    /* border-bottom-right-radius: 4px; */
-    /* border-top-right-radius: 4px; */
-    cursor: pointer;
-    flex: 1;
-  }
-  
-  /* .search-wrapper > button[type=submit]:focus,
-  input[type=search]:focus ~ button[type=submit] {
-    border: 1px solid var(--search-focus);
-    border-left: none;
-  } */
-  
-  .search-wrapper > button[type=submit]:hover {
-    background-color: var(--search-border);
-    color: var(--search-button-hover);
-  }
-  
-  /* main content area */
-  
-  main {
-    grid-area: c;
-  }
-  
-  p {
-    margin-bottom: 8px;
-  }
-  
-  /* modal stuff */
-  
-  div.modal {
-    position: fixed;
-    z-index: 10;
-    left: 0;
-    top: 0;
-    width: 100%;
-    height: 100%;
-    overflow: hidden;
-    background-color: rgba(0,0,0,0.4);
-    cursor: pointer;
-    display: none;
-  }
-  
-  div.modal-content {
-    background-color: var(--main-background);
-    box-shadow: 0 2px 8px rgba(0,0,0,0.54);
-    padding: 24px;
-    border-radius: 4px;
-    max-width: 40%;
-    min-width: 350px;
-    cursor: initial;
-    flex: 1;
-    margin: auto;
-  }
-  
-  div.modal-content > span.close {
-    color: #888;
-    float: right;
-    font-weight: bold;
-    -moz-user-select: none;
-    -webkit-user-select: none;
-    cursor: pointer;
-  }
-  
-  div.modal-content > span.close:hover,
-  div.modal-content > span.close:focus {
-    color: #444;
-  }
-  
-  div.modal input {
-    cursor: pointer;
-  }
-  
-  /* scroll to top button */
-  
-  #to-top {
-    position: fixed;
-    bottom: 50px;
-    right: 20px;
-  
-    cursor: pointer;
-  }
-  
-  #to-top.is-rtd {
-    bottom: 90px;
-  }
-  
-  #to-top > span {
-    display: block;
-  
-    width: auto;
-    height: 30px;
-    padding: 0 6px;
-  
-    background-color: var(--rtd-version-background);
-    color: var(--rtd-version-main-text);
-  }
-  
-  #to-top span {
-    line-height: 30px;
-    font-size: 90%;
-    text-align: center;
-  }
-  
-  /* copy button */
-  
-  .relative-copy {
-    position: relative;
-  }
-  
-  .copy {
-    cursor: pointer;
-    position: absolute;
-    top: 0px;
-    right: 0px;
-    border: 1px solid var(--codeblock-border);
-    font-size: 0.875em;
-    padding: 0.2em 0.5em;
-    border-bottom-left-radius: 4px;
-    display: flex;
-  }
-  
-  /* -- body styles --------------------------------------------------------- */
-  
-  hr {
-    border: 1px solid var(--hr-border);
-  }
-  
-  main h1,
-  main h2,
-  main h3,
-  main h4,
-  main h5,
-  main h6 { font-weight: normal; }
-  
-  main h1,
-  main h2,
-  main h3,
-  main h4 { color: var(--main-big-headers-text); }
-  main h5 { color: var(--main-h5-header-text); }
-  main h6 { color: var(--main-h6-header-text); }
-  
-  main h1 { margin: 0 0 10px 0; }
-  main h2,
-  main h3 { margin: 10px 0px 10px 0px; }
-  main h4,
-  main h5,
-  main h6 { margin: 20px 0px 10px 0px; }
-  
-  main h1 { padding: 0 0 10px 0; }
-  main h2,
-  main h3 { padding: 10px 0 10px 0; }
-  main h4 { padding: 10px 0 10px 0; }
-  main h5,
-  main h6 { padding: 10px 0 0 0; }
-  
-  main h1,
-  main h2,
-  main h3 { border-bottom: 1px solid var(--main-big-headers-border); }
-  main h4 { border-bottom: 1px solid var(--main-h4-header-border); }
-  
-  main h1 { font-size: 2.3em; }
-  main h2 { font-size: 1.8em; }
-  main h3 { font-size: 1.3em; }
-  main h4 { font-size: 1.1em; }
-  main h5 { font-size: 1.05em; }
-  main h6 { font-size: 1em; }
-  
-  a.headerlink {
-    color: var(--header-link);
-    font-size: 0.8em;
-    padding: 0 4px 0 4px;
-    text-decoration: none;
-    visibility: hidden;
-  }
-  
-  a.headerlink:hover {
-    background-color: var(--header-link);
-    color: var(--header-link-hover-text);
-  }
-  
-  h1:hover > a.headerlink,
-  h2:hover > a.headerlink,
-  h3:hover > a.headerlink,
-  h4:hover > a.headerlink,
-  h5:hover > a.headerlink,
-  h6:hover > a.headerlink,
-  dt:hover > a.headerlink,
-  caption:hover > a.headerlink,
-  p.caption:hover > a.headerlink,
-  div.code-block-caption:hover > a.headerlink {
-      visibility: visible;
-  }
-  
-  .versionmodified {
-    font-style: italic;
-  }
-  
-  main ul {
-    list-style: disc;
-    margin: 1em 0;
-    padding-left: 1.3em;
-  }
-  
-  main ul ul, main ol ul {
-    margin: .2em 0;
-    padding-left: 1.2em;
-  }
-  
-  main ul li {
-    padding: 2px 0;
-  }
-  
-  main ul.search li {
-    padding: 5px 0 5px 20px;
-  }
-  
-  main ol {
-    counter-reset: li;
-    margin-left: 0;
-    padding-left: 0;
-  }
-  
-  main ol ol {
-    margin: .2em 0;
-  }
-  
-  main ol > li {
-    list-style: none;
-    margin: 0 0 0 1.9em;
-    padding: 2px 1px;
-    position: relative;
-  }
-  
-  main ol > li::before {
-    content: counter(li) ".";
-    counter-increment: li;
-    top: -2px;
-    left: -1.1em;
-    width: 1.1em;
-    padding: 4px 0;
-    position: absolute;
-    text-align: left;
-  }
-  
-  main p,
-  main dd,
-  main li {
-    line-height: 1.4;
-  }
-  
-  main img {
-    width: 100%;
-    max-width: 500px;
-  }
-  
-  /* weird margins */
-  li > p {
-    margin: 2px;
-  }
-  
-  li > blockquote {
-    margin: 10px;
-  }
-  
-  /* admonitions */
-  div.admonition {
-    padding: 0 0.8em;
-    padding-bottom: 0.8em;
-    margin: 0.8em 0;
-    border-radius: 2.5px;
-    border-left-width: 6px;
-    border-left-style: solid;
-    background-color: var(--admonition-background);
-  }
-  
-  p.admonition-title {
-    font-weight: bold;
-    margin: 0 -0.8rem;
-    padding: 0.4rem 0.6rem 0.4rem 2.5rem;
-    position: relative;
-    -moz-user-select: none;
-    -webkit-user-select: none;
-    -ms-user-select: none;
-    user-select: none;
-  }
-  
-  p.admonition-title::before {
-    font: normal normal normal 24px/1 'Material Icons';
-    display: inline-block;
-    width: 24px;
-    height: 24px;
-    position: absolute;
-    left: 9.6px;
-  }
-  
-  div.important, div.note, div.hint, div.tip {
-    border-left-color: var(--note-background);
-  }
-  
-  div.important > p.admonition-title,
-  div.note > p.admonition-title,
-  div.hint > p.admonition-title,
-  div.tip > p.admonition-title {
-    background-color: var(--note-background);
-    color: var(--note-text);
-  }
-  
-  div.important > p.admonition-title::before,
-  div.note > p.admonition-title::before,
-  div.hint > p.admonition-title::before,
-  div.tip > p.admonition-title::before {
-    content: '\0e88e';
-  }
-  
-  div.attention, div.warning, div.caution {
-    border-left-color: var(--warning-background);
-  }
-  
-  div.attention > p.admonition-title,
-  div.warning > p.admonition-title,
-  div.caution > p.admonition-title {
-    background-color: var(--warning-background);
-    color: var(--warning-text);
-  }
-  
-  div.attention > p.admonition-title::before,
-  div.warning > p.admonition-title::before,
-  div.caution > p.admonition-title::before {
-    content: '\0e002';
-  }
-  
-  div.danger, div.error {
-    border-left-color: var(--error-background);
-  }
-  
-  div.danger > p.admonition-title,
-  div.error > p.admonition-title {
-    background-color: var(--error-background);
-    color: var(--error-text);
-  }
-  
-  div.danger > p.admonition-title::before,
-  div.error > p.admonition-title::before {
-    content: '\0e000';
-  }
-  
-  /* helpful admonitions */
-  div.helpful {
-    border-left-color: var(--helpful-background);
-  }
-  
-  div.helpful > p.admonition-title {
-    background-color: var(--helpful-background);
-    color: var(--helpful-text);
-  }
-  
-  div.helpful > p.admonition-title::before {
-    content: '\0e873';
-  }
-  
-  dl.field-list > dd {
-    margin-top: 3px;
-    margin-bottom: 10px;
-    margin-left: 20px;
-  }
-  
-  /* no disgusting background in the FAQ */
-  div.topic {
-    background-color: transparent;
-    border: none;
-  }
-  
-  /* don't link-ify the FAQ page */
-  a.toc-backref {
-    text-decoration: none;
-    color: var(--main-text);
-  }
-  
-  /* bold and fix the Parameter, Raises, etc. */
-  dl.field-list > dt {
-    font-weight: bold;
-  }
-  
-  /* remove flex from field lists */
-  dl.field-list {
-    display: block;
-  }
-  
-  /* cross-references are forced to bold for some reason */
-  a.reference > strong {
-    font-weight: unset;
-    font-family: var(--monospace-font-family);
-  }
-  a.reference.pep > strong,
-  a.reference.rfc > strong {
-    font-family: inherit;
-  }
-  
-  /* exception hierarchy */
-  
-  .exception-hierarchy-content dd,
-  .exception-hierarchy-content dl {
-    margin: 0px 2px;
-  }
-  
-  .exception-hierarchy-content {
-    margin-left: 0.5em;
-  }
-  
-  .exception-hierarchy-content ul {
-    list-style: '»' !important;
-  }
-  
-  /* attribute tables */
-  .py-attribute-table {
-    display: flex;
-    flex-wrap: wrap;
-    flex-direction: row;
-    margin: 0 2em;
-    padding-top: 16px;
-  }
-  
-  .py-attribute-table-column {
-    flex: 1 1 auto;
-  }
-  
-  .py-attribute-table-column:not(:first-child) {
-    margin-top: 1em;
-  }
-  
-  .py-attribute-table-column > span {
-    font-weight: bold;
-    color: var(--attribute-table-title);
-  }
-  
-  main .py-attribute-table-column > ul {
-    list-style: none;
-    margin: 4px 0px;
-    padding-left: 0;
-    font-size: 0.95em;
-  }
-  
-  .py-attribute-table-entry {
-    margin: 0;
-    padding: 2px 0;
-    padding-left: 0.2em;
-    border-left: 2px solid var(--attribute-table-entry-border);
-    display: flex;
-    line-height: 1.2em;
-  }
-  
-  .py-attribute-table-entry > a {
-    padding-left: 0.5em;
-    color: var(--attribute-table-entry-text);
-    flex-grow: 1;
-  }
-  
-  .py-attribute-table-entry > a:hover {
-    color: var(--attribute-table-entry-hover-text);
-    text-decoration: none;
-  }
-  
-  .py-attribute-table-entry:hover {
-    background-color: var(--attribute-table-entry-hover-background);
-    border-left: 2px solid var(--attribute-table-entry-hover-border);
-    text-decoration: none;
-  }
-  
-  .py-attribute-table-badge {
-    flex-basis: 3em;
-    text-align: right;
-    font-size: 0.9em;
-    color: var(--attribute-table-badge);
-    -moz-user-select: none;
-    -webkit-user-select: none;
-    user-select: none;
-  }
-  
-  pre {
-    background-color: var(--codeblock-background);
-    border: 1px solid var(--codeblock-border);
-    color: var(--codeblock-text);
-    font-size: 0.75em;
-    line-height: 1.5em;
-    margin: 1.5em 0 1.5em 0;
-    padding: 10px;
-    overflow-x: auto;
-  }
-  
-  pre, code {
-    font-family: var(--monospace-font-family);
-    font-size: 0.9em;
-    overflow-wrap: break-word;
-  }
-  
-  code {
-    background-color: var(--inline-code-background);
-    padding: .15em;
-    border-radius: 3px;
-  }
-  
-  code.descname {
-    background-color: transparent;
-    font-weight: bold;
-    font-size: 0.95em;
-  }
-  
-  code.descclassname {
-    background-color: transparent;
-    padding-right: 0;
-  }
-  
-  code.descclassname + code.descname {
-    padding-left: 0;
-  }
-  
-  code.xref, a code {
-    font-weight: normal;
-    background-color: var(--xref-code-background);
-  }
-  
-  span.pre {
-    padding: 0 2px;
-  }
-  
-  dl.class {
-    margin-bottom: 50px;
-  }
-  
-  dl.data > dt,
-  dl.describe > dt,
-  dl.function > dt,
-  dl.attribute > dt,
-  dl.classmethod > dt,
-  dl.method > dt,
-  dl.class > dt,
-  dl.exception > dt {
-    background-color: var(--api-entry-background);
-    padding: 1px 10px;
-  }
-  
-  dd {
-    margin-top: 0.5em;
-    margin-bottom: 0.5em;
-    margin-left: 1.5em;
-  }
-  
-  dt:target, span.highlighted {
-      background-color: var(--highlighted-text);
-  }
-  
-  rect.highlighted {
-      fill: var(--highlighted-text);
-  }
-  
-  .container.operations {
-    padding: 10px;
-    border: 1px solid var(--codeblock-border);
-    margin-bottom: 20px;
-  }
-  
-  .container.operations::before {
-    content: 'Supported Operations';
-    color: var(--main-big-headers-text);
-    display: block;
-    padding-bottom: 0.5em;
-  }
-  
-  .container.operations > dl.describe > dt {
-    background-color: var(--api-entry-background);
-  }
-  
-  .table-wrapper {
-    overflow-x: auto;
-  }
-  
-  table.docutils {
-    width: 100%;
-    border-collapse: collapse;
-  }
-  
-  table.docutils.footnote {
-    width: auto;
-  }
-  
-  table.docutils thead,
-  table.docutils tfoot {
-    background: var(--table-header-background);
-  }
-  
-  table.docutils thead tr th {
-    color: var(--table-text);
-    font-weight: normal;
-    padding: 7px 5px;
-    vertical-align: middle;
-  }
-  
-  table.docutils tbody tr th,
-  table.docutils tbody tr td {
-    border-bottom: 0;
-    padding: 7px 5px;
-    vertical-align: top;
-  }
-  
-  table.docutils tbody tr:not(:first-child) {
-    border-top: solid 1px var(--table-border);
-  }
-  
-  table.docutils tbody tr:last-child th,
-  table.docutils tbody tr:last-child td {
-    border-bottom: solid 1px var(--table-border);
-  }
-  
-  table.docutils thead tr td p,
-  table.docutils tfoot tr td p,
-  table.docutils tbody tr td p,
-  table.docutils thead tr td ul,
-  table.docutils tfoot tr td ul,
-  table.docutils tbody tr td ul,
-  table.docutils thead tr td ol,
-  table.docutils tfoot tr td ol,
-  table.docutils tbody tr td ol {
-    margin: 0 0 .5em;
-  }
-  table.docutils thead tr td p.last,
-  table.docutils tfoot tr td p.last,
-  table.docutils tbody tr td p.last,
-  table.docutils thead tr td ul.last,
-  table.docutils tfoot tr td ul.last,
-  table.docutils tbody tr td ul.last,
-  table.docutils thead tr td ol.last,
-  table.docutils tfoot tr td ol.last,
-  table.docutils tbody tr td ol.last {
-    margin-bottom: 0;
-  }
-  
-  /* hide the welcome text */
-  section#welcome-to-discord-py > h1 {
-    display: none;
-  }
-  
-  /* make the RTD ad look a little less jarring */
-  
-  .ethical-fixedfooter {
-    background-color: var(--rtd-ad-background) !important;
-    border-top: 1px solid var(--rtd-ad-border) !important;
-  }
-  
-  .ethical-fixedfooter a {
-    color: var(--rtd-ad-main-text) !important;
-  }
-  
-  .ethical-callout > small > em > a {
-    color: var(--rtd-ad-small-text) !important;
-  }
-  
-  .active {
-    background-color: var(--mobile-active-toc);
-    border-left: 5px solid var(--mobile-active-toc);
-  }
-  
-  div.code-block-caption {
-    font-size: medium;
-    font-weight: bold;
-  }
-  
-  
-  /* desktop stuff */
-  
-  @media screen and (min-width: 600px) {
-    .grid-item {
-      max-width: unset;
-    }
-  
-    .main-grid {
-      grid-template-areas:
-        "h h h h h h"
-        "n n n n n n"
-        "s s c c c c"
-        "s s f f f f";
-    }
-  
-    .mobile-only {
-      display: none;
-    }
-  
-    header {
-      background-color: var(--black);
-    }
-  
-    header > nav {
-      background-color: unset;
-    }
-  
-    .sub-header {
-      display: flex;
-      align-items: center;
-    }
-  
-    .sub-header > label {
-      display: initial;
-    }
-  
-    .sub-header > select {
-      display: initial;
-      margin-right: auto;
-    }
-  
-    .sub-header > .settings {
-      display: initial;
-    }
-  
-    aside {
-      top: initial;
-      position: initial;
-      background-color: var(--nav-background);
-      color: var(--nav-text);
-      max-height: unset;
-      overflow-y: unset;
-      overscroll-behavior-y: unset;
-    }
-  
-    aside h3 {
-      color: var(--nav-header-text);
-    }
-  
-    #sidebar {
-      display: inline-block;
-      position: sticky;
-      top: 1em;
-      max-height: calc(100vh - 2em);
-      overflow-y: auto;
-      margin: 1em;
-    }
-  
-    #sidebar a {
-      color: var(--nav-text);
-    }
-  
-    .active {
-      background-color: transparent;
-      border-left: none;
-      position: relative;
-    }
-  
-    .active::before {
-      content: "";
-      display: inline-block;
-      background-color: var(--active-toc);
-      position: absolute;
-      top: 0;
-      bottom: 0;
-      right: 0;
-      width: calc(100% + 0.5em);
-      border-radius: 4px;
-      z-index: -1;
-    }
-  
-    #sidebar a:hover {
-      color: var(--nav-hover-text);
-    }
-  
-    #hamburger-toggle, #settings-toggle {
-      display: none;
-  
-    }
-  }
-  
-  @media screen and (min-width: 1200px) {
-    .main-grid {
-      /* 62.5% width => multiple of 5/8 content */
-      /* sidebar takes up 20% of the inner area */
-      grid-template-columns: repeat(16, 1fr);
-      grid-template-areas:
-        "h h h h h h h h h h h h h h h h"
-        "n n n n n n n n n n n n n n n n"
-        "s s s . . c c c c c c c c c . ."
-        "s s s f f f f f f f f f f f f f"
-    }
-  
-    header > nav {
-      margin-left: 18.75%;
-      margin-right: 18.75%;
-    }
-  
-    .sub-header > label {
-      margin-left: 18.75%;
-      margin-right: 1em;
-    }
-  
-    .sub-header > .settings {
-      margin-right: 18.75%;
-      margin-left: 1em;
-    }
-  
-    .sub-header > .search {
-      width: 20%;
-    }
-  
-    .py-attribute-table-column:not(:first-child) {
-      margin-top: unset;
-    }
-  
-    main img {
-      display: block;
-      margin-left: auto;
-      margin-right: auto;
-    }
-  }
\ No newline at end of file
diff --git a/docs/_build/html/_static/underscore-1.13.1.js b/docs/_build/html/_static/underscore-1.13.1.js
deleted file mode 100644
index ffd77af9..00000000
--- a/docs/_build/html/_static/underscore-1.13.1.js
+++ /dev/null
@@ -1,2042 +0,0 @@
-(function (global, factory) {
-  typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
-  typeof define === 'function' && define.amd ? define('underscore', factory) :
-  (global = typeof globalThis !== 'undefined' ? globalThis : global || self, (function () {
-    var current = global._;
-    var exports = global._ = factory();
-    exports.noConflict = function () { global._ = current; return exports; };
-  }()));
-}(this, (function () {
-  //     Underscore.js 1.13.1
-  //     https://underscorejs.org
-  //     (c) 2009-2021 Jeremy Ashkenas, Julian Gonggrijp, and DocumentCloud and Investigative Reporters & Editors
-  //     Underscore may be freely distributed under the MIT license.
-
-  // Current version.
-  var VERSION = '1.13.1';
-
-  // Establish the root object, `window` (`self`) in the browser, `global`
-  // on the server, or `this` in some virtual machines. We use `self`
-  // instead of `window` for `WebWorker` support.
-  var root = typeof self == 'object' && self.self === self && self ||
-            typeof global == 'object' && global.global === global && global ||
-            Function('return this')() ||
-            {};
-
-  // Save bytes in the minified (but not gzipped) version:
-  var ArrayProto = Array.prototype, ObjProto = Object.prototype;
-  var SymbolProto = typeof Symbol !== 'undefined' ? Symbol.prototype : null;
-
-  // Create quick reference variables for speed access to core prototypes.
-  var push = ArrayProto.push,
-      slice = ArrayProto.slice,
-      toString = ObjProto.toString,
-      hasOwnProperty = ObjProto.hasOwnProperty;
-
-  // Modern feature detection.
-  var supportsArrayBuffer = typeof ArrayBuffer !== 'undefined',
-      supportsDataView = typeof DataView !== 'undefined';
-
-  // All **ECMAScript 5+** native function implementations that we hope to use
-  // are declared here.
-  var nativeIsArray = Array.isArray,
-      nativeKeys = Object.keys,
-      nativeCreate = Object.create,
-      nativeIsView = supportsArrayBuffer && ArrayBuffer.isView;
-
-  // Create references to these builtin functions because we override them.
-  var _isNaN = isNaN,
-      _isFinite = isFinite;
-
-  // Keys in IE < 9 that won't be iterated by `for key in ...` and thus missed.
-  var hasEnumBug = !{toString: null}.propertyIsEnumerable('toString');
-  var nonEnumerableProps = ['valueOf', 'isPrototypeOf', 'toString',
-    'propertyIsEnumerable', 'hasOwnProperty', 'toLocaleString'];
-
-  // The largest integer that can be represented exactly.
-  var MAX_ARRAY_INDEX = Math.pow(2, 53) - 1;
-
-  // Some functions take a variable number of arguments, or a few expected
-  // arguments at the beginning and then a variable number of values to operate
-  // on. This helper accumulates all remaining arguments past the function’s
-  // argument length (or an explicit `startIndex`), into an array that becomes
-  // the last argument. Similar to ES6’s "rest parameter".
-  function restArguments(func, startIndex) {
-    startIndex = startIndex == null ? func.length - 1 : +startIndex;
-    return function() {
-      var length = Math.max(arguments.length - startIndex, 0),
-          rest = Array(length),
-          index = 0;
-      for (; index < length; index++) {
-        rest[index] = arguments[index + startIndex];
-      }
-      switch (startIndex) {
-        case 0: return func.call(this, rest);
-        case 1: return func.call(this, arguments[0], rest);
-        case 2: return func.call(this, arguments[0], arguments[1], rest);
-      }
-      var args = Array(startIndex + 1);
-      for (index = 0; index < startIndex; index++) {
-        args[index] = arguments[index];
-      }
-      args[startIndex] = rest;
-      return func.apply(this, args);
-    };
-  }
-
-  // Is a given variable an object?
-  function isObject(obj) {
-    var type = typeof obj;
-    return type === 'function' || type === 'object' && !!obj;
-  }
-
-  // Is a given value equal to null?
-  function isNull(obj) {
-    return obj === null;
-  }
-
-  // Is a given variable undefined?
-  function isUndefined(obj) {
-    return obj === void 0;
-  }
-
-  // Is a given value a boolean?
-  function isBoolean(obj) {
-    return obj === true || obj === false || toString.call(obj) === '[object Boolean]';
-  }
-
-  // Is a given value a DOM element?
-  function isElement(obj) {
-    return !!(obj && obj.nodeType === 1);
-  }
-
-  // Internal function for creating a `toString`-based type tester.
-  function tagTester(name) {
-    var tag = '[object ' + name + ']';
-    return function(obj) {
-      return toString.call(obj) === tag;
-    };
-  }
-
-  var isString = tagTester('String');
-
-  var isNumber = tagTester('Number');
-
-  var isDate = tagTester('Date');
-
-  var isRegExp = tagTester('RegExp');
-
-  var isError = tagTester('Error');
-
-  var isSymbol = tagTester('Symbol');
-
-  var isArrayBuffer = tagTester('ArrayBuffer');
-
-  var isFunction = tagTester('Function');
-
-  // Optimize `isFunction` if appropriate. Work around some `typeof` bugs in old
-  // v8, IE 11 (#1621), Safari 8 (#1929), and PhantomJS (#2236).
-  var nodelist = root.document && root.document.childNodes;
-  if (typeof /./ != 'function' && typeof Int8Array != 'object' && typeof nodelist != 'function') {
-    isFunction = function(obj) {
-      return typeof obj == 'function' || false;
-    };
-  }
-
-  var isFunction$1 = isFunction;
-
-  var hasObjectTag = tagTester('Object');
-
-  // In IE 10 - Edge 13, `DataView` has string tag `'[object Object]'`.
-  // In IE 11, the most common among them, this problem also applies to
-  // `Map`, `WeakMap` and `Set`.
-  var hasStringTagBug = (
-        supportsDataView && hasObjectTag(new DataView(new ArrayBuffer(8)))
-      ),
-      isIE11 = (typeof Map !== 'undefined' && hasObjectTag(new Map));
-
-  var isDataView = tagTester('DataView');
-
-  // In IE 10 - Edge 13, we need a different heuristic
-  // to determine whether an object is a `DataView`.
-  function ie10IsDataView(obj) {
-    return obj != null && isFunction$1(obj.getInt8) && isArrayBuffer(obj.buffer);
-  }
-
-  var isDataView$1 = (hasStringTagBug ? ie10IsDataView : isDataView);
-
-  // Is a given value an array?
-  // Delegates to ECMA5's native `Array.isArray`.
-  var isArray = nativeIsArray || tagTester('Array');
-
-  // Internal function to check whether `key` is an own property name of `obj`.
-  function has$1(obj, key) {
-    return obj != null && hasOwnProperty.call(obj, key);
-  }
-
-  var isArguments = tagTester('Arguments');
-
-  // Define a fallback version of the method in browsers (ahem, IE < 9), where
-  // there isn't any inspectable "Arguments" type.
-  (function() {
-    if (!isArguments(arguments)) {
-      isArguments = function(obj) {
-        return has$1(obj, 'callee');
-      };
-    }
-  }());
-
-  var isArguments$1 = isArguments;
-
-  // Is a given object a finite number?
-  function isFinite$1(obj) {
-    return !isSymbol(obj) && _isFinite(obj) && !isNaN(parseFloat(obj));
-  }
-
-  // Is the given value `NaN`?
-  function isNaN$1(obj) {
-    return isNumber(obj) && _isNaN(obj);
-  }
-
-  // Predicate-generating function. Often useful outside of Underscore.
-  function constant(value) {
-    return function() {
-      return value;
-    };
-  }
-
-  // Common internal logic for `isArrayLike` and `isBufferLike`.
-  function createSizePropertyCheck(getSizeProperty) {
-    return function(collection) {
-      var sizeProperty = getSizeProperty(collection);
-      return typeof sizeProperty == 'number' && sizeProperty >= 0 && sizeProperty <= MAX_ARRAY_INDEX;
-    }
-  }
-
-  // Internal helper to generate a function to obtain property `key` from `obj`.
-  function shallowProperty(key) {
-    return function(obj) {
-      return obj == null ? void 0 : obj[key];
-    };
-  }
-
-  // Internal helper to obtain the `byteLength` property of an object.
-  var getByteLength = shallowProperty('byteLength');
-
-  // Internal helper to determine whether we should spend extensive checks against
-  // `ArrayBuffer` et al.
-  var isBufferLike = createSizePropertyCheck(getByteLength);
-
-  // Is a given value a typed array?
-  var typedArrayPattern = /\[object ((I|Ui)nt(8|16|32)|Float(32|64)|Uint8Clamped|Big(I|Ui)nt64)Array\]/;
-  function isTypedArray(obj) {
-    // `ArrayBuffer.isView` is the most future-proof, so use it when available.
-    // Otherwise, fall back on the above regular expression.
-    return nativeIsView ? (nativeIsView(obj) && !isDataView$1(obj)) :
-                  isBufferLike(obj) && typedArrayPattern.test(toString.call(obj));
-  }
-
-  var isTypedArray$1 = supportsArrayBuffer ? isTypedArray : constant(false);
-
-  // Internal helper to obtain the `length` property of an object.
-  var getLength = shallowProperty('length');
-
-  // Internal helper to create a simple lookup structure.
-  // `collectNonEnumProps` used to depend on `_.contains`, but this led to
-  // circular imports. `emulatedSet` is a one-off solution that only works for
-  // arrays of strings.
-  function emulatedSet(keys) {
-    var hash = {};
-    for (var l = keys.length, i = 0; i < l; ++i) hash[keys[i]] = true;
-    return {
-      contains: function(key) { return hash[key]; },
-      push: function(key) {
-        hash[key] = true;
-        return keys.push(key);
-      }
-    };
-  }
-
-  // Internal helper. Checks `keys` for the presence of keys in IE < 9 that won't
-  // be iterated by `for key in ...` and thus missed. Extends `keys` in place if
-  // needed.
-  function collectNonEnumProps(obj, keys) {
-    keys = emulatedSet(keys);
-    var nonEnumIdx = nonEnumerableProps.length;
-    var constructor = obj.constructor;
-    var proto = isFunction$1(constructor) && constructor.prototype || ObjProto;
-
-    // Constructor is a special case.
-    var prop = 'constructor';
-    if (has$1(obj, prop) && !keys.contains(prop)) keys.push(prop);
-
-    while (nonEnumIdx--) {
-      prop = nonEnumerableProps[nonEnumIdx];
-      if (prop in obj && obj[prop] !== proto[prop] && !keys.contains(prop)) {
-        keys.push(prop);
-      }
-    }
-  }
-
-  // Retrieve the names of an object's own properties.
-  // Delegates to **ECMAScript 5**'s native `Object.keys`.
-  function keys(obj) {
-    if (!isObject(obj)) return [];
-    if (nativeKeys) return nativeKeys(obj);
-    var keys = [];
-    for (var key in obj) if (has$1(obj, key)) keys.push(key);
-    // Ahem, IE < 9.
-    if (hasEnumBug) collectNonEnumProps(obj, keys);
-    return keys;
-  }
-
-  // Is a given array, string, or object empty?
-  // An "empty" object has no enumerable own-properties.
-  function isEmpty(obj) {
-    if (obj == null) return true;
-    // Skip the more expensive `toString`-based type checks if `obj` has no
-    // `.length`.
-    var length = getLength(obj);
-    if (typeof length == 'number' && (
-      isArray(obj) || isString(obj) || isArguments$1(obj)
-    )) return length === 0;
-    return getLength(keys(obj)) === 0;
-  }
-
-  // Returns whether an object has a given set of `key:value` pairs.
-  function isMatch(object, attrs) {
-    var _keys = keys(attrs), length = _keys.length;
-    if (object == null) return !length;
-    var obj = Object(object);
-    for (var i = 0; i < length; i++) {
-      var key = _keys[i];
-      if (attrs[key] !== obj[key] || !(key in obj)) return false;
-    }
-    return true;
-  }
-
-  // If Underscore is called as a function, it returns a wrapped object that can
-  // be used OO-style. This wrapper holds altered versions of all functions added
-  // through `_.mixin`. Wrapped objects may be chained.
-  function _$1(obj) {
-    if (obj instanceof _$1) return obj;
-    if (!(this instanceof _$1)) return new _$1(obj);
-    this._wrapped = obj;
-  }
-
-  _$1.VERSION = VERSION;
-
-  // Extracts the result from a wrapped and chained object.
-  _$1.prototype.value = function() {
-    return this._wrapped;
-  };
-
-  // Provide unwrapping proxies for some methods used in engine operations
-  // such as arithmetic and JSON stringification.
-  _$1.prototype.valueOf = _$1.prototype.toJSON = _$1.prototype.value;
-
-  _$1.prototype.toString = function() {
-    return String(this._wrapped);
-  };
-
-  // Internal function to wrap or shallow-copy an ArrayBuffer,
-  // typed array or DataView to a new view, reusing the buffer.
-  function toBufferView(bufferSource) {
-    return new Uint8Array(
-      bufferSource.buffer || bufferSource,
-      bufferSource.byteOffset || 0,
-      getByteLength(bufferSource)
-    );
-  }
-
-  // We use this string twice, so give it a name for minification.
-  var tagDataView = '[object DataView]';
-
-  // Internal recursive comparison function for `_.isEqual`.
-  function eq(a, b, aStack, bStack) {
-    // Identical objects are equal. `0 === -0`, but they aren't identical.
-    // See the [Harmony `egal` proposal](https://wiki.ecmascript.org/doku.php?id=harmony:egal).
-    if (a === b) return a !== 0 || 1 / a === 1 / b;
-    // `null` or `undefined` only equal to itself (strict comparison).
-    if (a == null || b == null) return false;
-    // `NaN`s are equivalent, but non-reflexive.
-    if (a !== a) return b !== b;
-    // Exhaust primitive checks
-    var type = typeof a;
-    if (type !== 'function' && type !== 'object' && typeof b != 'object') return false;
-    return deepEq(a, b, aStack, bStack);
-  }
-
-  // Internal recursive comparison function for `_.isEqual`.
-  function deepEq(a, b, aStack, bStack) {
-    // Unwrap any wrapped objects.
-    if (a instanceof _$1) a = a._wrapped;
-    if (b instanceof _$1) b = b._wrapped;
-    // Compare `[[Class]]` names.
-    var className = toString.call(a);
-    if (className !== toString.call(b)) return false;
-    // Work around a bug in IE 10 - Edge 13.
-    if (hasStringTagBug && className == '[object Object]' && isDataView$1(a)) {
-      if (!isDataView$1(b)) return false;
-      className = tagDataView;
-    }
-    switch (className) {
-      // These types are compared by value.
-      case '[object RegExp]':
-        // RegExps are coerced to strings for comparison (Note: '' + /a/i === '/a/i')
-      case '[object String]':
-        // Primitives and their corresponding object wrappers are equivalent; thus, `"5"` is
-        // equivalent to `new String("5")`.
-        return '' + a === '' + b;
-      case '[object Number]':
-        // `NaN`s are equivalent, but non-reflexive.
-        // Object(NaN) is equivalent to NaN.
-        if (+a !== +a) return +b !== +b;
-        // An `egal` comparison is performed for other numeric values.
-        return +a === 0 ? 1 / +a === 1 / b : +a === +b;
-      case '[object Date]':
-      case '[object Boolean]':
-        // Coerce dates and booleans to numeric primitive values. Dates are compared by their
-        // millisecond representations. Note that invalid dates with millisecond representations
-        // of `NaN` are not equivalent.
-        return +a === +b;
-      case '[object Symbol]':
-        return SymbolProto.valueOf.call(a) === SymbolProto.valueOf.call(b);
-      case '[object ArrayBuffer]':
-      case tagDataView:
-        // Coerce to typed array so we can fall through.
-        return deepEq(toBufferView(a), toBufferView(b), aStack, bStack);
-    }
-
-    var areArrays = className === '[object Array]';
-    if (!areArrays && isTypedArray$1(a)) {
-        var byteLength = getByteLength(a);
-        if (byteLength !== getByteLength(b)) return false;
-        if (a.buffer === b.buffer && a.byteOffset === b.byteOffset) return true;
-        areArrays = true;
-    }
-    if (!areArrays) {
-      if (typeof a != 'object' || typeof b != 'object') return false;
-
-      // Objects with different constructors are not equivalent, but `Object`s or `Array`s
-      // from different frames are.
-      var aCtor = a.constructor, bCtor = b.constructor;
-      if (aCtor !== bCtor && !(isFunction$1(aCtor) && aCtor instanceof aCtor &&
-                               isFunction$1(bCtor) && bCtor instanceof bCtor)
-                          && ('constructor' in a && 'constructor' in b)) {
-        return false;
-      }
-    }
-    // Assume equality for cyclic structures. The algorithm for detecting cyclic
-    // structures is adapted from ES 5.1 section 15.12.3, abstract operation `JO`.
-
-    // Initializing stack of traversed objects.
-    // It's done here since we only need them for objects and arrays comparison.
-    aStack = aStack || [];
-    bStack = bStack || [];
-    var length = aStack.length;
-    while (length--) {
-      // Linear search. Performance is inversely proportional to the number of
-      // unique nested structures.
-      if (aStack[length] === a) return bStack[length] === b;
-    }
-
-    // Add the first object to the stack of traversed objects.
-    aStack.push(a);
-    bStack.push(b);
-
-    // Recursively compare objects and arrays.
-    if (areArrays) {
-      // Compare array lengths to determine if a deep comparison is necessary.
-      length = a.length;
-      if (length !== b.length) return false;
-      // Deep compare the contents, ignoring non-numeric properties.
-      while (length--) {
-        if (!eq(a[length], b[length], aStack, bStack)) return false;
-      }
-    } else {
-      // Deep compare objects.
-      var _keys = keys(a), key;
-      length = _keys.length;
-      // Ensure that both objects contain the same number of properties before comparing deep equality.
-      if (keys(b).length !== length) return false;
-      while (length--) {
-        // Deep compare each member
-        key = _keys[length];
-        if (!(has$1(b, key) && eq(a[key], b[key], aStack, bStack))) return false;
-      }
-    }
-    // Remove the first object from the stack of traversed objects.
-    aStack.pop();
-    bStack.pop();
-    return true;
-  }
-
-  // Perform a deep comparison to check if two objects are equal.
-  function isEqual(a, b) {
-    return eq(a, b);
-  }
-
-  // Retrieve all the enumerable property names of an object.
-  function allKeys(obj) {
-    if (!isObject(obj)) return [];
-    var keys = [];
-    for (var key in obj) keys.push(key);
-    // Ahem, IE < 9.
-    if (hasEnumBug) collectNonEnumProps(obj, keys);
-    return keys;
-  }
-
-  // Since the regular `Object.prototype.toString` type tests don't work for
-  // some types in IE 11, we use a fingerprinting heuristic instead, based
-  // on the methods. It's not great, but it's the best we got.
-  // The fingerprint method lists are defined below.
-  function ie11fingerprint(methods) {
-    var length = getLength(methods);
-    return function(obj) {
-      if (obj == null) return false;
-      // `Map`, `WeakMap` and `Set` have no enumerable keys.
-      var keys = allKeys(obj);
-      if (getLength(keys)) return false;
-      for (var i = 0; i < length; i++) {
-        if (!isFunction$1(obj[methods[i]])) return false;
-      }
-      // If we are testing against `WeakMap`, we need to ensure that
-      // `obj` doesn't have a `forEach` method in order to distinguish
-      // it from a regular `Map`.
-      return methods !== weakMapMethods || !isFunction$1(obj[forEachName]);
-    };
-  }
-
-  // In the interest of compact minification, we write
-  // each string in the fingerprints only once.
-  var forEachName = 'forEach',
-      hasName = 'has',
-      commonInit = ['clear', 'delete'],
-      mapTail = ['get', hasName, 'set'];
-
-  // `Map`, `WeakMap` and `Set` each have slightly different
-  // combinations of the above sublists.
-  var mapMethods = commonInit.concat(forEachName, mapTail),
-      weakMapMethods = commonInit.concat(mapTail),
-      setMethods = ['add'].concat(commonInit, forEachName, hasName);
-
-  var isMap = isIE11 ? ie11fingerprint(mapMethods) : tagTester('Map');
-
-  var isWeakMap = isIE11 ? ie11fingerprint(weakMapMethods) : tagTester('WeakMap');
-
-  var isSet = isIE11 ? ie11fingerprint(setMethods) : tagTester('Set');
-
-  var isWeakSet = tagTester('WeakSet');
-
-  // Retrieve the values of an object's properties.
-  function values(obj) {
-    var _keys = keys(obj);
-    var length = _keys.length;
-    var values = Array(length);
-    for (var i = 0; i < length; i++) {
-      values[i] = obj[_keys[i]];
-    }
-    return values;
-  }
-
-  // Convert an object into a list of `[key, value]` pairs.
-  // The opposite of `_.object` with one argument.
-  function pairs(obj) {
-    var _keys = keys(obj);
-    var length = _keys.length;
-    var pairs = Array(length);
-    for (var i = 0; i < length; i++) {
-      pairs[i] = [_keys[i], obj[_keys[i]]];
-    }
-    return pairs;
-  }
-
-  // Invert the keys and values of an object. The values must be serializable.
-  function invert(obj) {
-    var result = {};
-    var _keys = keys(obj);
-    for (var i = 0, length = _keys.length; i < length; i++) {
-      result[obj[_keys[i]]] = _keys[i];
-    }
-    return result;
-  }
-
-  // Return a sorted list of the function names available on the object.
-  function functions(obj) {
-    var names = [];
-    for (var key in obj) {
-      if (isFunction$1(obj[key])) names.push(key);
-    }
-    return names.sort();
-  }
-
-  // An internal function for creating assigner functions.
-  function createAssigner(keysFunc, defaults) {
-    return function(obj) {
-      var length = arguments.length;
-      if (defaults) obj = Object(obj);
-      if (length < 2 || obj == null) return obj;
-      for (var index = 1; index < length; index++) {
-        var source = arguments[index],
-            keys = keysFunc(source),
-            l = keys.length;
-        for (var i = 0; i < l; i++) {
-          var key = keys[i];
-          if (!defaults || obj[key] === void 0) obj[key] = source[key];
-        }
-      }
-      return obj;
-    };
-  }
-
-  // Extend a given object with all the properties in passed-in object(s).
-  var extend = createAssigner(allKeys);
-
-  // Assigns a given object with all the own properties in the passed-in
-  // object(s).
-  // (https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object/assign)
-  var extendOwn = createAssigner(keys);
-
-  // Fill in a given object with default properties.
-  var defaults = createAssigner(allKeys, true);
-
-  // Create a naked function reference for surrogate-prototype-swapping.
-  function ctor() {
-    return function(){};
-  }
-
-  // An internal function for creating a new object that inherits from another.
-  function baseCreate(prototype) {
-    if (!isObject(prototype)) return {};
-    if (nativeCreate) return nativeCreate(prototype);
-    var Ctor = ctor();
-    Ctor.prototype = prototype;
-    var result = new Ctor;
-    Ctor.prototype = null;
-    return result;
-  }
-
-  // Creates an object that inherits from the given prototype object.
-  // If additional properties are provided then they will be added to the
-  // created object.
-  function create(prototype, props) {
-    var result = baseCreate(prototype);
-    if (props) extendOwn(result, props);
-    return result;
-  }
-
-  // Create a (shallow-cloned) duplicate of an object.
-  function clone(obj) {
-    if (!isObject(obj)) return obj;
-    return isArray(obj) ? obj.slice() : extend({}, obj);
-  }
-
-  // Invokes `interceptor` with the `obj` and then returns `obj`.
-  // The primary purpose of this method is to "tap into" a method chain, in
-  // order to perform operations on intermediate results within the chain.
-  function tap(obj, interceptor) {
-    interceptor(obj);
-    return obj;
-  }
-
-  // Normalize a (deep) property `path` to array.
-  // Like `_.iteratee`, this function can be customized.
-  function toPath$1(path) {
-    return isArray(path) ? path : [path];
-  }
-  _$1.toPath = toPath$1;
-
-  // Internal wrapper for `_.toPath` to enable minification.
-  // Similar to `cb` for `_.iteratee`.
-  function toPath(path) {
-    return _$1.toPath(path);
-  }
-
-  // Internal function to obtain a nested property in `obj` along `path`.
-  function deepGet(obj, path) {
-    var length = path.length;
-    for (var i = 0; i < length; i++) {
-      if (obj == null) return void 0;
-      obj = obj[path[i]];
-    }
-    return length ? obj : void 0;
-  }
-
-  // Get the value of the (deep) property on `path` from `object`.
-  // If any property in `path` does not exist or if the value is
-  // `undefined`, return `defaultValue` instead.
-  // The `path` is normalized through `_.toPath`.
-  function get(object, path, defaultValue) {
-    var value = deepGet(object, toPath(path));
-    return isUndefined(value) ? defaultValue : value;
-  }
-
-  // Shortcut function for checking if an object has a given property directly on
-  // itself (in other words, not on a prototype). Unlike the internal `has`
-  // function, this public version can also traverse nested properties.
-  function has(obj, path) {
-    path = toPath(path);
-    var length = path.length;
-    for (var i = 0; i < length; i++) {
-      var key = path[i];
-      if (!has$1(obj, key)) return false;
-      obj = obj[key];
-    }
-    return !!length;
-  }
-
-  // Keep the identity function around for default iteratees.
-  function identity(value) {
-    return value;
-  }
-
-  // Returns a predicate for checking whether an object has a given set of
-  // `key:value` pairs.
-  function matcher(attrs) {
-    attrs = extendOwn({}, attrs);
-    return function(obj) {
-      return isMatch(obj, attrs);
-    };
-  }
-
-  // Creates a function that, when passed an object, will traverse that object’s
-  // properties down the given `path`, specified as an array of keys or indices.
-  function property(path) {
-    path = toPath(path);
-    return function(obj) {
-      return deepGet(obj, path);
-    };
-  }
-
-  // Internal function that returns an efficient (for current engines) version
-  // of the passed-in callback, to be repeatedly applied in other Underscore
-  // functions.
-  function optimizeCb(func, context, argCount) {
-    if (context === void 0) return func;
-    switch (argCount == null ? 3 : argCount) {
-      case 1: return function(value) {
-        return func.call(context, value);
-      };
-      // The 2-argument case is omitted because we’re not using it.
-      case 3: return function(value, index, collection) {
-        return func.call(context, value, index, collection);
-      };
-      case 4: return function(accumulator, value, index, collection) {
-        return func.call(context, accumulator, value, index, collection);
-      };
-    }
-    return function() {
-      return func.apply(context, arguments);
-    };
-  }
-
-  // An internal function to generate callbacks that can be applied to each
-  // element in a collection, returning the desired result — either `_.identity`,
-  // an arbitrary callback, a property matcher, or a property accessor.
-  function baseIteratee(value, context, argCount) {
-    if (value == null) return identity;
-    if (isFunction$1(value)) return optimizeCb(value, context, argCount);
-    if (isObject(value) && !isArray(value)) return matcher(value);
-    return property(value);
-  }
-
-  // External wrapper for our callback generator. Users may customize
-  // `_.iteratee` if they want additional predicate/iteratee shorthand styles.
-  // This abstraction hides the internal-only `argCount` argument.
-  function iteratee(value, context) {
-    return baseIteratee(value, context, Infinity);
-  }
-  _$1.iteratee = iteratee;
-
-  // The function we call internally to generate a callback. It invokes
-  // `_.iteratee` if overridden, otherwise `baseIteratee`.
-  function cb(value, context, argCount) {
-    if (_$1.iteratee !== iteratee) return _$1.iteratee(value, context);
-    return baseIteratee(value, context, argCount);
-  }
-
-  // Returns the results of applying the `iteratee` to each element of `obj`.
-  // In contrast to `_.map` it returns an object.
-  function mapObject(obj, iteratee, context) {
-    iteratee = cb(iteratee, context);
-    var _keys = keys(obj),
-        length = _keys.length,
-        results = {};
-    for (var index = 0; index < length; index++) {
-      var currentKey = _keys[index];
-      results[currentKey] = iteratee(obj[currentKey], currentKey, obj);
-    }
-    return results;
-  }
-
-  // Predicate-generating function. Often useful outside of Underscore.
-  function noop(){}
-
-  // Generates a function for a given object that returns a given property.
-  function propertyOf(obj) {
-    if (obj == null) return noop;
-    return function(path) {
-      return get(obj, path);
-    };
-  }
-
-  // Run a function **n** times.
-  function times(n, iteratee, context) {
-    var accum = Array(Math.max(0, n));
-    iteratee = optimizeCb(iteratee, context, 1);
-    for (var i = 0; i < n; i++) accum[i] = iteratee(i);
-    return accum;
-  }
-
-  // Return a random integer between `min` and `max` (inclusive).
-  function random(min, max) {
-    if (max == null) {
-      max = min;
-      min = 0;
-    }
-    return min + Math.floor(Math.random() * (max - min + 1));
-  }
-
-  // A (possibly faster) way to get the current timestamp as an integer.
-  var now = Date.now || function() {
-    return new Date().getTime();
-  };
-
-  // Internal helper to generate functions for escaping and unescaping strings
-  // to/from HTML interpolation.
-  function createEscaper(map) {
-    var escaper = function(match) {
-      return map[match];
-    };
-    // Regexes for identifying a key that needs to be escaped.
-    var source = '(?:' + keys(map).join('|') + ')';
-    var testRegexp = RegExp(source);
-    var replaceRegexp = RegExp(source, 'g');
-    return function(string) {
-      string = string == null ? '' : '' + string;
-      return testRegexp.test(string) ? string.replace(replaceRegexp, escaper) : string;
-    };
-  }
-
-  // Internal list of HTML entities for escaping.
-  var escapeMap = {
-    '&': '&amp;',
-    '<': '&lt;',
-    '>': '&gt;',
-    '"': '&quot;',
-    "'": '&#x27;',
-    '`': '&#x60;'
-  };
-
-  // Function for escaping strings to HTML interpolation.
-  var _escape = createEscaper(escapeMap);
-
-  // Internal list of HTML entities for unescaping.
-  var unescapeMap = invert(escapeMap);
-
-  // Function for unescaping strings from HTML interpolation.
-  var _unescape = createEscaper(unescapeMap);
-
-  // By default, Underscore uses ERB-style template delimiters. Change the
-  // following template settings to use alternative delimiters.
-  var templateSettings = _$1.templateSettings = {
-    evaluate: /<%([\s\S]+?)%>/g,
-    interpolate: /<%=([\s\S]+?)%>/g,
-    escape: /<%-([\s\S]+?)%>/g
-  };
-
-  // When customizing `_.templateSettings`, if you don't want to define an
-  // interpolation, evaluation or escaping regex, we need one that is
-  // guaranteed not to match.
-  var noMatch = /(.)^/;
-
-  // Certain characters need to be escaped so that they can be put into a
-  // string literal.
-  var escapes = {
-    "'": "'",
-    '\\': '\\',
-    '\r': 'r',
-    '\n': 'n',
-    '\u2028': 'u2028',
-    '\u2029': 'u2029'
-  };
-
-  var escapeRegExp = /\\|'|\r|\n|\u2028|\u2029/g;
-
-  function escapeChar(match) {
-    return '\\' + escapes[match];
-  }
-
-  // In order to prevent third-party code injection through
-  // `_.templateSettings.variable`, we test it against the following regular
-  // expression. It is intentionally a bit more liberal than just matching valid
-  // identifiers, but still prevents possible loopholes through defaults or
-  // destructuring assignment.
-  var bareIdentifier = /^\s*(\w|\$)+\s*$/;
-
-  // JavaScript micro-templating, similar to John Resig's implementation.
-  // Underscore templating handles arbitrary delimiters, preserves whitespace,
-  // and correctly escapes quotes within interpolated code.
-  // NB: `oldSettings` only exists for backwards compatibility.
-  function template(text, settings, oldSettings) {
-    if (!settings && oldSettings) settings = oldSettings;
-    settings = defaults({}, settings, _$1.templateSettings);
-
-    // Combine delimiters into one regular expression via alternation.
-    var matcher = RegExp([
-      (settings.escape || noMatch).source,
-      (settings.interpolate || noMatch).source,
-      (settings.evaluate || noMatch).source
-    ].join('|') + '|$', 'g');
-
-    // Compile the template source, escaping string literals appropriately.
-    var index = 0;
-    var source = "__p+='";
-    text.replace(matcher, function(match, escape, interpolate, evaluate, offset) {
-      source += text.slice(index, offset).replace(escapeRegExp, escapeChar);
-      index = offset + match.length;
-
-      if (escape) {
-        source += "'+\n((__t=(" + escape + "))==null?'':_.escape(__t))+\n'";
-      } else if (interpolate) {
-        source += "'+\n((__t=(" + interpolate + "))==null?'':__t)+\n'";
-      } else if (evaluate) {
-        source += "';\n" + evaluate + "\n__p+='";
-      }
-
-      // Adobe VMs need the match returned to produce the correct offset.
-      return match;
-    });
-    source += "';\n";
-
-    var argument = settings.variable;
-    if (argument) {
-      // Insure against third-party code injection. (CVE-2021-23358)
-      if (!bareIdentifier.test(argument)) throw new Error(
-        'variable is not a bare identifier: ' + argument
-      );
-    } else {
-      // If a variable is not specified, place data values in local scope.
-      source = 'with(obj||{}){\n' + source + '}\n';
-      argument = 'obj';
-    }
-
-    source = "var __t,__p='',__j=Array.prototype.join," +
-      "print=function(){__p+=__j.call(arguments,'');};\n" +
-      source + 'return __p;\n';
-
-    var render;
-    try {
-      render = new Function(argument, '_', source);
-    } catch (e) {
-      e.source = source;
-      throw e;
-    }
-
-    var template = function(data) {
-      return render.call(this, data, _$1);
-    };
-
-    // Provide the compiled source as a convenience for precompilation.
-    template.source = 'function(' + argument + '){\n' + source + '}';
-
-    return template;
-  }
-
-  // Traverses the children of `obj` along `path`. If a child is a function, it
-  // is invoked with its parent as context. Returns the value of the final
-  // child, or `fallback` if any child is undefined.
-  function result(obj, path, fallback) {
-    path = toPath(path);
-    var length = path.length;
-    if (!length) {
-      return isFunction$1(fallback) ? fallback.call(obj) : fallback;
-    }
-    for (var i = 0; i < length; i++) {
-      var prop = obj == null ? void 0 : obj[path[i]];
-      if (prop === void 0) {
-        prop = fallback;
-        i = length; // Ensure we don't continue iterating.
-      }
-      obj = isFunction$1(prop) ? prop.call(obj) : prop;
-    }
-    return obj;
-  }
-
-  // Generate a unique integer id (unique within the entire client session).
-  // Useful for temporary DOM ids.
-  var idCounter = 0;
-  function uniqueId(prefix) {
-    var id = ++idCounter + '';
-    return prefix ? prefix + id : id;
-  }
-
-  // Start chaining a wrapped Underscore object.
-  function chain(obj) {
-    var instance = _$1(obj);
-    instance._chain = true;
-    return instance;
-  }
-
-  // Internal function to execute `sourceFunc` bound to `context` with optional
-  // `args`. Determines whether to execute a function as a constructor or as a
-  // normal function.
-  function executeBound(sourceFunc, boundFunc, context, callingContext, args) {
-    if (!(callingContext instanceof boundFunc)) return sourceFunc.apply(context, args);
-    var self = baseCreate(sourceFunc.prototype);
-    var result = sourceFunc.apply(self, args);
-    if (isObject(result)) return result;
-    return self;
-  }
-
-  // Partially apply a function by creating a version that has had some of its
-  // arguments pre-filled, without changing its dynamic `this` context. `_` acts
-  // as a placeholder by default, allowing any combination of arguments to be
-  // pre-filled. Set `_.partial.placeholder` for a custom placeholder argument.
-  var partial = restArguments(function(func, boundArgs) {
-    var placeholder = partial.placeholder;
-    var bound = function() {
-      var position = 0, length = boundArgs.length;
-      var args = Array(length);
-      for (var i = 0; i < length; i++) {
-        args[i] = boundArgs[i] === placeholder ? arguments[position++] : boundArgs[i];
-      }
-      while (position < arguments.length) args.push(arguments[position++]);
-      return executeBound(func, bound, this, this, args);
-    };
-    return bound;
-  });
-
-  partial.placeholder = _$1;
-
-  // Create a function bound to a given object (assigning `this`, and arguments,
-  // optionally).
-  var bind = restArguments(function(func, context, args) {
-    if (!isFunction$1(func)) throw new TypeError('Bind must be called on a function');
-    var bound = restArguments(function(callArgs) {
-      return executeBound(func, bound, context, this, args.concat(callArgs));
-    });
-    return bound;
-  });
-
-  // Internal helper for collection methods to determine whether a collection
-  // should be iterated as an array or as an object.
-  // Related: https://people.mozilla.org/~jorendorff/es6-draft.html#sec-tolength
-  // Avoids a very nasty iOS 8 JIT bug on ARM-64. #2094
-  var isArrayLike = createSizePropertyCheck(getLength);
-
-  // Internal implementation of a recursive `flatten` function.
-  function flatten$1(input, depth, strict, output) {
-    output = output || [];
-    if (!depth && depth !== 0) {
-      depth = Infinity;
-    } else if (depth <= 0) {
-      return output.concat(input);
-    }
-    var idx = output.length;
-    for (var i = 0, length = getLength(input); i < length; i++) {
-      var value = input[i];
-      if (isArrayLike(value) && (isArray(value) || isArguments$1(value))) {
-        // Flatten current level of array or arguments object.
-        if (depth > 1) {
-          flatten$1(value, depth - 1, strict, output);
-          idx = output.length;
-        } else {
-          var j = 0, len = value.length;
-          while (j < len) output[idx++] = value[j++];
-        }
-      } else if (!strict) {
-        output[idx++] = value;
-      }
-    }
-    return output;
-  }
-
-  // Bind a number of an object's methods to that object. Remaining arguments
-  // are the method names to be bound. Useful for ensuring that all callbacks
-  // defined on an object belong to it.
-  var bindAll = restArguments(function(obj, keys) {
-    keys = flatten$1(keys, false, false);
-    var index = keys.length;
-    if (index < 1) throw new Error('bindAll must be passed function names');
-    while (index--) {
-      var key = keys[index];
-      obj[key] = bind(obj[key], obj);
-    }
-    return obj;
-  });
-
-  // Memoize an expensive function by storing its results.
-  function memoize(func, hasher) {
-    var memoize = function(key) {
-      var cache = memoize.cache;
-      var address = '' + (hasher ? hasher.apply(this, arguments) : key);
-      if (!has$1(cache, address)) cache[address] = func.apply(this, arguments);
-      return cache[address];
-    };
-    memoize.cache = {};
-    return memoize;
-  }
-
-  // Delays a function for the given number of milliseconds, and then calls
-  // it with the arguments supplied.
-  var delay = restArguments(function(func, wait, args) {
-    return setTimeout(function() {
-      return func.apply(null, args);
-    }, wait);
-  });
-
-  // Defers a function, scheduling it to run after the current call stack has
-  // cleared.
-  var defer = partial(delay, _$1, 1);
-
-  // Returns a function, that, when invoked, will only be triggered at most once
-  // during a given window of time. Normally, the throttled function will run
-  // as much as it can, without ever going more than once per `wait` duration;
-  // but if you'd like to disable the execution on the leading edge, pass
-  // `{leading: false}`. To disable execution on the trailing edge, ditto.
-  function throttle(func, wait, options) {
-    var timeout, context, args, result;
-    var previous = 0;
-    if (!options) options = {};
-
-    var later = function() {
-      previous = options.leading === false ? 0 : now();
-      timeout = null;
-      result = func.apply(context, args);
-      if (!timeout) context = args = null;
-    };
-
-    var throttled = function() {
-      var _now = now();
-      if (!previous && options.leading === false) previous = _now;
-      var remaining = wait - (_now - previous);
-      context = this;
-      args = arguments;
-      if (remaining <= 0 || remaining > wait) {
-        if (timeout) {
-          clearTimeout(timeout);
-          timeout = null;
-        }
-        previous = _now;
-        result = func.apply(context, args);
-        if (!timeout) context = args = null;
-      } else if (!timeout && options.trailing !== false) {
-        timeout = setTimeout(later, remaining);
-      }
-      return result;
-    };
-
-    throttled.cancel = function() {
-      clearTimeout(timeout);
-      previous = 0;
-      timeout = context = args = null;
-    };
-
-    return throttled;
-  }
-
-  // When a sequence of calls of the returned function ends, the argument
-  // function is triggered. The end of a sequence is defined by the `wait`
-  // parameter. If `immediate` is passed, the argument function will be
-  // triggered at the beginning of the sequence instead of at the end.
-  function debounce(func, wait, immediate) {
-    var timeout, previous, args, result, context;
-
-    var later = function() {
-      var passed = now() - previous;
-      if (wait > passed) {
-        timeout = setTimeout(later, wait - passed);
-      } else {
-        timeout = null;
-        if (!immediate) result = func.apply(context, args);
-        // This check is needed because `func` can recursively invoke `debounced`.
-        if (!timeout) args = context = null;
-      }
-    };
-
-    var debounced = restArguments(function(_args) {
-      context = this;
-      args = _args;
-      previous = now();
-      if (!timeout) {
-        timeout = setTimeout(later, wait);
-        if (immediate) result = func.apply(context, args);
-      }
-      return result;
-    });
-
-    debounced.cancel = function() {
-      clearTimeout(timeout);
-      timeout = args = context = null;
-    };
-
-    return debounced;
-  }
-
-  // Returns the first function passed as an argument to the second,
-  // allowing you to adjust arguments, run code before and after, and
-  // conditionally execute the original function.
-  function wrap(func, wrapper) {
-    return partial(wrapper, func);
-  }
-
-  // Returns a negated version of the passed-in predicate.
-  function negate(predicate) {
-    return function() {
-      return !predicate.apply(this, arguments);
-    };
-  }
-
-  // Returns a function that is the composition of a list of functions, each
-  // consuming the return value of the function that follows.
-  function compose() {
-    var args = arguments;
-    var start = args.length - 1;
-    return function() {
-      var i = start;
-      var result = args[start].apply(this, arguments);
-      while (i--) result = args[i].call(this, result);
-      return result;
-    };
-  }
-
-  // Returns a function that will only be executed on and after the Nth call.
-  function after(times, func) {
-    return function() {
-      if (--times < 1) {
-        return func.apply(this, arguments);
-      }
-    };
-  }
-
-  // Returns a function that will only be executed up to (but not including) the
-  // Nth call.
-  function before(times, func) {
-    var memo;
-    return function() {
-      if (--times > 0) {
-        memo = func.apply(this, arguments);
-      }
-      if (times <= 1) func = null;
-      return memo;
-    };
-  }
-
-  // Returns a function that will be executed at most one time, no matter how
-  // often you call it. Useful for lazy initialization.
-  var once = partial(before, 2);
-
-  // Returns the first key on an object that passes a truth test.
-  function findKey(obj, predicate, context) {
-    predicate = cb(predicate, context);
-    var _keys = keys(obj), key;
-    for (var i = 0, length = _keys.length; i < length; i++) {
-      key = _keys[i];
-      if (predicate(obj[key], key, obj)) return key;
-    }
-  }
-
-  // Internal function to generate `_.findIndex` and `_.findLastIndex`.
-  function createPredicateIndexFinder(dir) {
-    return function(array, predicate, context) {
-      predicate = cb(predicate, context);
-      var length = getLength(array);
-      var index = dir > 0 ? 0 : length - 1;
-      for (; index >= 0 && index < length; index += dir) {
-        if (predicate(array[index], index, array)) return index;
-      }
-      return -1;
-    };
-  }
-
-  // Returns the first index on an array-like that passes a truth test.
-  var findIndex = createPredicateIndexFinder(1);
-
-  // Returns the last index on an array-like that passes a truth test.
-  var findLastIndex = createPredicateIndexFinder(-1);
-
-  // Use a comparator function to figure out the smallest index at which
-  // an object should be inserted so as to maintain order. Uses binary search.
-  function sortedIndex(array, obj, iteratee, context) {
-    iteratee = cb(iteratee, context, 1);
-    var value = iteratee(obj);
-    var low = 0, high = getLength(array);
-    while (low < high) {
-      var mid = Math.floor((low + high) / 2);
-      if (iteratee(array[mid]) < value) low = mid + 1; else high = mid;
-    }
-    return low;
-  }
-
-  // Internal function to generate the `_.indexOf` and `_.lastIndexOf` functions.
-  function createIndexFinder(dir, predicateFind, sortedIndex) {
-    return function(array, item, idx) {
-      var i = 0, length = getLength(array);
-      if (typeof idx == 'number') {
-        if (dir > 0) {
-          i = idx >= 0 ? idx : Math.max(idx + length, i);
-        } else {
-          length = idx >= 0 ? Math.min(idx + 1, length) : idx + length + 1;
-        }
-      } else if (sortedIndex && idx && length) {
-        idx = sortedIndex(array, item);
-        return array[idx] === item ? idx : -1;
-      }
-      if (item !== item) {
-        idx = predicateFind(slice.call(array, i, length), isNaN$1);
-        return idx >= 0 ? idx + i : -1;
-      }
-      for (idx = dir > 0 ? i : length - 1; idx >= 0 && idx < length; idx += dir) {
-        if (array[idx] === item) return idx;
-      }
-      return -1;
-    };
-  }
-
-  // Return the position of the first occurrence of an item in an array,
-  // or -1 if the item is not included in the array.
-  // If the array is large and already in sort order, pass `true`
-  // for **isSorted** to use binary search.
-  var indexOf = createIndexFinder(1, findIndex, sortedIndex);
-
-  // Return the position of the last occurrence of an item in an array,
-  // or -1 if the item is not included in the array.
-  var lastIndexOf = createIndexFinder(-1, findLastIndex);
-
-  // Return the first value which passes a truth test.
-  function find(obj, predicate, context) {
-    var keyFinder = isArrayLike(obj) ? findIndex : findKey;
-    var key = keyFinder(obj, predicate, context);
-    if (key !== void 0 && key !== -1) return obj[key];
-  }
-
-  // Convenience version of a common use case of `_.find`: getting the first
-  // object containing specific `key:value` pairs.
-  function findWhere(obj, attrs) {
-    return find(obj, matcher(attrs));
-  }
-
-  // The cornerstone for collection functions, an `each`
-  // implementation, aka `forEach`.
-  // Handles raw objects in addition to array-likes. Treats all
-  // sparse array-likes as if they were dense.
-  function each(obj, iteratee, context) {
-    iteratee = optimizeCb(iteratee, context);
-    var i, length;
-    if (isArrayLike(obj)) {
-      for (i = 0, length = obj.length; i < length; i++) {
-        iteratee(obj[i], i, obj);
-      }
-    } else {
-      var _keys = keys(obj);
-      for (i = 0, length = _keys.length; i < length; i++) {
-        iteratee(obj[_keys[i]], _keys[i], obj);
-      }
-    }
-    return obj;
-  }
-
-  // Return the results of applying the iteratee to each element.
-  function map(obj, iteratee, context) {
-    iteratee = cb(iteratee, context);
-    var _keys = !isArrayLike(obj) && keys(obj),
-        length = (_keys || obj).length,
-        results = Array(length);
-    for (var index = 0; index < length; index++) {
-      var currentKey = _keys ? _keys[index] : index;
-      results[index] = iteratee(obj[currentKey], currentKey, obj);
-    }
-    return results;
-  }
-
-  // Internal helper to create a reducing function, iterating left or right.
-  function createReduce(dir) {
-    // Wrap code that reassigns argument variables in a separate function than
-    // the one that accesses `arguments.length` to avoid a perf hit. (#1991)
-    var reducer = function(obj, iteratee, memo, initial) {
-      var _keys = !isArrayLike(obj) && keys(obj),
-          length = (_keys || obj).length,
-          index = dir > 0 ? 0 : length - 1;
-      if (!initial) {
-        memo = obj[_keys ? _keys[index] : index];
-        index += dir;
-      }
-      for (; index >= 0 && index < length; index += dir) {
-        var currentKey = _keys ? _keys[index] : index;
-        memo = iteratee(memo, obj[currentKey], currentKey, obj);
-      }
-      return memo;
-    };
-
-    return function(obj, iteratee, memo, context) {
-      var initial = arguments.length >= 3;
-      return reducer(obj, optimizeCb(iteratee, context, 4), memo, initial);
-    };
-  }
-
-  // **Reduce** builds up a single result from a list of values, aka `inject`,
-  // or `foldl`.
-  var reduce = createReduce(1);
-
-  // The right-associative version of reduce, also known as `foldr`.
-  var reduceRight = createReduce(-1);
-
-  // Return all the elements that pass a truth test.
-  function filter(obj, predicate, context) {
-    var results = [];
-    predicate = cb(predicate, context);
-    each(obj, function(value, index, list) {
-      if (predicate(value, index, list)) results.push(value);
-    });
-    return results;
-  }
-
-  // Return all the elements for which a truth test fails.
-  function reject(obj, predicate, context) {
-    return filter(obj, negate(cb(predicate)), context);
-  }
-
-  // Determine whether all of the elements pass a truth test.
-  function every(obj, predicate, context) {
-    predicate = cb(predicate, context);
-    var _keys = !isArrayLike(obj) && keys(obj),
-        length = (_keys || obj).length;
-    for (var index = 0; index < length; index++) {
-      var currentKey = _keys ? _keys[index] : index;
-      if (!predicate(obj[currentKey], currentKey, obj)) return false;
-    }
-    return true;
-  }
-
-  // Determine if at least one element in the object passes a truth test.
-  function some(obj, predicate, context) {
-    predicate = cb(predicate, context);
-    var _keys = !isArrayLike(obj) && keys(obj),
-        length = (_keys || obj).length;
-    for (var index = 0; index < length; index++) {
-      var currentKey = _keys ? _keys[index] : index;
-      if (predicate(obj[currentKey], currentKey, obj)) return true;
-    }
-    return false;
-  }
-
-  // Determine if the array or object contains a given item (using `===`).
-  function contains(obj, item, fromIndex, guard) {
-    if (!isArrayLike(obj)) obj = values(obj);
-    if (typeof fromIndex != 'number' || guard) fromIndex = 0;
-    return indexOf(obj, item, fromIndex) >= 0;
-  }
-
-  // Invoke a method (with arguments) on every item in a collection.
-  var invoke = restArguments(function(obj, path, args) {
-    var contextPath, func;
-    if (isFunction$1(path)) {
-      func = path;
-    } else {
-      path = toPath(path);
-      contextPath = path.slice(0, -1);
-      path = path[path.length - 1];
-    }
-    return map(obj, function(context) {
-      var method = func;
-      if (!method) {
-        if (contextPath && contextPath.length) {
-          context = deepGet(context, contextPath);
-        }
-        if (context == null) return void 0;
-        method = context[path];
-      }
-      return method == null ? method : method.apply(context, args);
-    });
-  });
-
-  // Convenience version of a common use case of `_.map`: fetching a property.
-  function pluck(obj, key) {
-    return map(obj, property(key));
-  }
-
-  // Convenience version of a common use case of `_.filter`: selecting only
-  // objects containing specific `key:value` pairs.
-  function where(obj, attrs) {
-    return filter(obj, matcher(attrs));
-  }
-
-  // Return the maximum element (or element-based computation).
-  function max(obj, iteratee, context) {
-    var result = -Infinity, lastComputed = -Infinity,
-        value, computed;
-    if (iteratee == null || typeof iteratee == 'number' && typeof obj[0] != 'object' && obj != null) {
-      obj = isArrayLike(obj) ? obj : values(obj);
-      for (var i = 0, length = obj.length; i < length; i++) {
-        value = obj[i];
-        if (value != null && value > result) {
-          result = value;
-        }
-      }
-    } else {
-      iteratee = cb(iteratee, context);
-      each(obj, function(v, index, list) {
-        computed = iteratee(v, index, list);
-        if (computed > lastComputed || computed === -Infinity && result === -Infinity) {
-          result = v;
-          lastComputed = computed;
-        }
-      });
-    }
-    return result;
-  }
-
-  // Return the minimum element (or element-based computation).
-  function min(obj, iteratee, context) {
-    var result = Infinity, lastComputed = Infinity,
-        value, computed;
-    if (iteratee == null || typeof iteratee == 'number' && typeof obj[0] != 'object' && obj != null) {
-      obj = isArrayLike(obj) ? obj : values(obj);
-      for (var i = 0, length = obj.length; i < length; i++) {
-        value = obj[i];
-        if (value != null && value < result) {
-          result = value;
-        }
-      }
-    } else {
-      iteratee = cb(iteratee, context);
-      each(obj, function(v, index, list) {
-        computed = iteratee(v, index, list);
-        if (computed < lastComputed || computed === Infinity && result === Infinity) {
-          result = v;
-          lastComputed = computed;
-        }
-      });
-    }
-    return result;
-  }
-
-  // Sample **n** random values from a collection using the modern version of the
-  // [Fisher-Yates shuffle](https://en.wikipedia.org/wiki/Fisher–Yates_shuffle).
-  // If **n** is not specified, returns a single random element.
-  // The internal `guard` argument allows it to work with `_.map`.
-  function sample(obj, n, guard) {
-    if (n == null || guard) {
-      if (!isArrayLike(obj)) obj = values(obj);
-      return obj[random(obj.length - 1)];
-    }
-    var sample = isArrayLike(obj) ? clone(obj) : values(obj);
-    var length = getLength(sample);
-    n = Math.max(Math.min(n, length), 0);
-    var last = length - 1;
-    for (var index = 0; index < n; index++) {
-      var rand = random(index, last);
-      var temp = sample[index];
-      sample[index] = sample[rand];
-      sample[rand] = temp;
-    }
-    return sample.slice(0, n);
-  }
-
-  // Shuffle a collection.
-  function shuffle(obj) {
-    return sample(obj, Infinity);
-  }
-
-  // Sort the object's values by a criterion produced by an iteratee.
-  function sortBy(obj, iteratee, context) {
-    var index = 0;
-    iteratee = cb(iteratee, context);
-    return pluck(map(obj, function(value, key, list) {
-      return {
-        value: value,
-        index: index++,
-        criteria: iteratee(value, key, list)
-      };
-    }).sort(function(left, right) {
-      var a = left.criteria;
-      var b = right.criteria;
-      if (a !== b) {
-        if (a > b || a === void 0) return 1;
-        if (a < b || b === void 0) return -1;
-      }
-      return left.index - right.index;
-    }), 'value');
-  }
-
-  // An internal function used for aggregate "group by" operations.
-  function group(behavior, partition) {
-    return function(obj, iteratee, context) {
-      var result = partition ? [[], []] : {};
-      iteratee = cb(iteratee, context);
-      each(obj, function(value, index) {
-        var key = iteratee(value, index, obj);
-        behavior(result, value, key);
-      });
-      return result;
-    };
-  }
-
-  // Groups the object's values by a criterion. Pass either a string attribute
-  // to group by, or a function that returns the criterion.
-  var groupBy = group(function(result, value, key) {
-    if (has$1(result, key)) result[key].push(value); else result[key] = [value];
-  });
-
-  // Indexes the object's values by a criterion, similar to `_.groupBy`, but for
-  // when you know that your index values will be unique.
-  var indexBy = group(function(result, value, key) {
-    result[key] = value;
-  });
-
-  // Counts instances of an object that group by a certain criterion. Pass
-  // either a string attribute to count by, or a function that returns the
-  // criterion.
-  var countBy = group(function(result, value, key) {
-    if (has$1(result, key)) result[key]++; else result[key] = 1;
-  });
-
-  // Split a collection into two arrays: one whose elements all pass the given
-  // truth test, and one whose elements all do not pass the truth test.
-  var partition = group(function(result, value, pass) {
-    result[pass ? 0 : 1].push(value);
-  }, true);
-
-  // Safely create a real, live array from anything iterable.
-  var reStrSymbol = /[^\ud800-\udfff]|[\ud800-\udbff][\udc00-\udfff]|[\ud800-\udfff]/g;
-  function toArray(obj) {
-    if (!obj) return [];
-    if (isArray(obj)) return slice.call(obj);
-    if (isString(obj)) {
-      // Keep surrogate pair characters together.
-      return obj.match(reStrSymbol);
-    }
-    if (isArrayLike(obj)) return map(obj, identity);
-    return values(obj);
-  }
-
-  // Return the number of elements in a collection.
-  function size(obj) {
-    if (obj == null) return 0;
-    return isArrayLike(obj) ? obj.length : keys(obj).length;
-  }
-
-  // Internal `_.pick` helper function to determine whether `key` is an enumerable
-  // property name of `obj`.
-  function keyInObj(value, key, obj) {
-    return key in obj;
-  }
-
-  // Return a copy of the object only containing the allowed properties.
-  var pick = restArguments(function(obj, keys) {
-    var result = {}, iteratee = keys[0];
-    if (obj == null) return result;
-    if (isFunction$1(iteratee)) {
-      if (keys.length > 1) iteratee = optimizeCb(iteratee, keys[1]);
-      keys = allKeys(obj);
-    } else {
-      iteratee = keyInObj;
-      keys = flatten$1(keys, false, false);
-      obj = Object(obj);
-    }
-    for (var i = 0, length = keys.length; i < length; i++) {
-      var key = keys[i];
-      var value = obj[key];
-      if (iteratee(value, key, obj)) result[key] = value;
-    }
-    return result;
-  });
-
-  // Return a copy of the object without the disallowed properties.
-  var omit = restArguments(function(obj, keys) {
-    var iteratee = keys[0], context;
-    if (isFunction$1(iteratee)) {
-      iteratee = negate(iteratee);
-      if (keys.length > 1) context = keys[1];
-    } else {
-      keys = map(flatten$1(keys, false, false), String);
-      iteratee = function(value, key) {
-        return !contains(keys, key);
-      };
-    }
-    return pick(obj, iteratee, context);
-  });
-
-  // Returns everything but the last entry of the array. Especially useful on
-  // the arguments object. Passing **n** will return all the values in
-  // the array, excluding the last N.
-  function initial(array, n, guard) {
-    return slice.call(array, 0, Math.max(0, array.length - (n == null || guard ? 1 : n)));
-  }
-
-  // Get the first element of an array. Passing **n** will return the first N
-  // values in the array. The **guard** check allows it to work with `_.map`.
-  function first(array, n, guard) {
-    if (array == null || array.length < 1) return n == null || guard ? void 0 : [];
-    if (n == null || guard) return array[0];
-    return initial(array, array.length - n);
-  }
-
-  // Returns everything but the first entry of the `array`. Especially useful on
-  // the `arguments` object. Passing an **n** will return the rest N values in the
-  // `array`.
-  function rest(array, n, guard) {
-    return slice.call(array, n == null || guard ? 1 : n);
-  }
-
-  // Get the last element of an array. Passing **n** will return the last N
-  // values in the array.
-  function last(array, n, guard) {
-    if (array == null || array.length < 1) return n == null || guard ? void 0 : [];
-    if (n == null || guard) return array[array.length - 1];
-    return rest(array, Math.max(0, array.length - n));
-  }
-
-  // Trim out all falsy values from an array.
-  function compact(array) {
-    return filter(array, Boolean);
-  }
-
-  // Flatten out an array, either recursively (by default), or up to `depth`.
-  // Passing `true` or `false` as `depth` means `1` or `Infinity`, respectively.
-  function flatten(array, depth) {
-    return flatten$1(array, depth, false);
-  }
-
-  // Take the difference between one array and a number of other arrays.
-  // Only the elements present in just the first array will remain.
-  var difference = restArguments(function(array, rest) {
-    rest = flatten$1(rest, true, true);
-    return filter(array, function(value){
-      return !contains(rest, value);
-    });
-  });
-
-  // Return a version of the array that does not contain the specified value(s).
-  var without = restArguments(function(array, otherArrays) {
-    return difference(array, otherArrays);
-  });
-
-  // Produce a duplicate-free version of the array. If the array has already
-  // been sorted, you have the option of using a faster algorithm.
-  // The faster algorithm will not work with an iteratee if the iteratee
-  // is not a one-to-one function, so providing an iteratee will disable
-  // the faster algorithm.
-  function uniq(array, isSorted, iteratee, context) {
-    if (!isBoolean(isSorted)) {
-      context = iteratee;
-      iteratee = isSorted;
-      isSorted = false;
-    }
-    if (iteratee != null) iteratee = cb(iteratee, context);
-    var result = [];
-    var seen = [];
-    for (var i = 0, length = getLength(array); i < length; i++) {
-      var value = array[i],
-          computed = iteratee ? iteratee(value, i, array) : value;
-      if (isSorted && !iteratee) {
-        if (!i || seen !== computed) result.push(value);
-        seen = computed;
-      } else if (iteratee) {
-        if (!contains(seen, computed)) {
-          seen.push(computed);
-          result.push(value);
-        }
-      } else if (!contains(result, value)) {
-        result.push(value);
-      }
-    }
-    return result;
-  }
-
-  // Produce an array that contains the union: each distinct element from all of
-  // the passed-in arrays.
-  var union = restArguments(function(arrays) {
-    return uniq(flatten$1(arrays, true, true));
-  });
-
-  // Produce an array that contains every item shared between all the
-  // passed-in arrays.
-  function intersection(array) {
-    var result = [];
-    var argsLength = arguments.length;
-    for (var i = 0, length = getLength(array); i < length; i++) {
-      var item = array[i];
-      if (contains(result, item)) continue;
-      var j;
-      for (j = 1; j < argsLength; j++) {
-        if (!contains(arguments[j], item)) break;
-      }
-      if (j === argsLength) result.push(item);
-    }
-    return result;
-  }
-
-  // Complement of zip. Unzip accepts an array of arrays and groups
-  // each array's elements on shared indices.
-  function unzip(array) {
-    var length = array && max(array, getLength).length || 0;
-    var result = Array(length);
-
-    for (var index = 0; index < length; index++) {
-      result[index] = pluck(array, index);
-    }
-    return result;
-  }
-
-  // Zip together multiple lists into a single array -- elements that share
-  // an index go together.
-  var zip = restArguments(unzip);
-
-  // Converts lists into objects. Pass either a single array of `[key, value]`
-  // pairs, or two parallel arrays of the same length -- one of keys, and one of
-  // the corresponding values. Passing by pairs is the reverse of `_.pairs`.
-  function object(list, values) {
-    var result = {};
-    for (var i = 0, length = getLength(list); i < length; i++) {
-      if (values) {
-        result[list[i]] = values[i];
-      } else {
-        result[list[i][0]] = list[i][1];
-      }
-    }
-    return result;
-  }
-
-  // Generate an integer Array containing an arithmetic progression. A port of
-  // the native Python `range()` function. See
-  // [the Python documentation](https://docs.python.org/library/functions.html#range).
-  function range(start, stop, step) {
-    if (stop == null) {
-      stop = start || 0;
-      start = 0;
-    }
-    if (!step) {
-      step = stop < start ? -1 : 1;
-    }
-
-    var length = Math.max(Math.ceil((stop - start) / step), 0);
-    var range = Array(length);
-
-    for (var idx = 0; idx < length; idx++, start += step) {
-      range[idx] = start;
-    }
-
-    return range;
-  }
-
-  // Chunk a single array into multiple arrays, each containing `count` or fewer
-  // items.
-  function chunk(array, count) {
-    if (count == null || count < 1) return [];
-    var result = [];
-    var i = 0, length = array.length;
-    while (i < length) {
-      result.push(slice.call(array, i, i += count));
-    }
-    return result;
-  }
-
-  // Helper function to continue chaining intermediate results.
-  function chainResult(instance, obj) {
-    return instance._chain ? _$1(obj).chain() : obj;
-  }
-
-  // Add your own custom functions to the Underscore object.
-  function mixin(obj) {
-    each(functions(obj), function(name) {
-      var func = _$1[name] = obj[name];
-      _$1.prototype[name] = function() {
-        var args = [this._wrapped];
-        push.apply(args, arguments);
-        return chainResult(this, func.apply(_$1, args));
-      };
-    });
-    return _$1;
-  }
-
-  // Add all mutator `Array` functions to the wrapper.
-  each(['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'], function(name) {
-    var method = ArrayProto[name];
-    _$1.prototype[name] = function() {
-      var obj = this._wrapped;
-      if (obj != null) {
-        method.apply(obj, arguments);
-        if ((name === 'shift' || name === 'splice') && obj.length === 0) {
-          delete obj[0];
-        }
-      }
-      return chainResult(this, obj);
-    };
-  });
-
-  // Add all accessor `Array` functions to the wrapper.
-  each(['concat', 'join', 'slice'], function(name) {
-    var method = ArrayProto[name];
-    _$1.prototype[name] = function() {
-      var obj = this._wrapped;
-      if (obj != null) obj = method.apply(obj, arguments);
-      return chainResult(this, obj);
-    };
-  });
-
-  // Named Exports
-
-  var allExports = {
-    __proto__: null,
-    VERSION: VERSION,
-    restArguments: restArguments,
-    isObject: isObject,
-    isNull: isNull,
-    isUndefined: isUndefined,
-    isBoolean: isBoolean,
-    isElement: isElement,
-    isString: isString,
-    isNumber: isNumber,
-    isDate: isDate,
-    isRegExp: isRegExp,
-    isError: isError,
-    isSymbol: isSymbol,
-    isArrayBuffer: isArrayBuffer,
-    isDataView: isDataView$1,
-    isArray: isArray,
-    isFunction: isFunction$1,
-    isArguments: isArguments$1,
-    isFinite: isFinite$1,
-    isNaN: isNaN$1,
-    isTypedArray: isTypedArray$1,
-    isEmpty: isEmpty,
-    isMatch: isMatch,
-    isEqual: isEqual,
-    isMap: isMap,
-    isWeakMap: isWeakMap,
-    isSet: isSet,
-    isWeakSet: isWeakSet,
-    keys: keys,
-    allKeys: allKeys,
-    values: values,
-    pairs: pairs,
-    invert: invert,
-    functions: functions,
-    methods: functions,
-    extend: extend,
-    extendOwn: extendOwn,
-    assign: extendOwn,
-    defaults: defaults,
-    create: create,
-    clone: clone,
-    tap: tap,
-    get: get,
-    has: has,
-    mapObject: mapObject,
-    identity: identity,
-    constant: constant,
-    noop: noop,
-    toPath: toPath$1,
-    property: property,
-    propertyOf: propertyOf,
-    matcher: matcher,
-    matches: matcher,
-    times: times,
-    random: random,
-    now: now,
-    escape: _escape,
-    unescape: _unescape,
-    templateSettings: templateSettings,
-    template: template,
-    result: result,
-    uniqueId: uniqueId,
-    chain: chain,
-    iteratee: iteratee,
-    partial: partial,
-    bind: bind,
-    bindAll: bindAll,
-    memoize: memoize,
-    delay: delay,
-    defer: defer,
-    throttle: throttle,
-    debounce: debounce,
-    wrap: wrap,
-    negate: negate,
-    compose: compose,
-    after: after,
-    before: before,
-    once: once,
-    findKey: findKey,
-    findIndex: findIndex,
-    findLastIndex: findLastIndex,
-    sortedIndex: sortedIndex,
-    indexOf: indexOf,
-    lastIndexOf: lastIndexOf,
-    find: find,
-    detect: find,
-    findWhere: findWhere,
-    each: each,
-    forEach: each,
-    map: map,
-    collect: map,
-    reduce: reduce,
-    foldl: reduce,
-    inject: reduce,
-    reduceRight: reduceRight,
-    foldr: reduceRight,
-    filter: filter,
-    select: filter,
-    reject: reject,
-    every: every,
-    all: every,
-    some: some,
-    any: some,
-    contains: contains,
-    includes: contains,
-    include: contains,
-    invoke: invoke,
-    pluck: pluck,
-    where: where,
-    max: max,
-    min: min,
-    shuffle: shuffle,
-    sample: sample,
-    sortBy: sortBy,
-    groupBy: groupBy,
-    indexBy: indexBy,
-    countBy: countBy,
-    partition: partition,
-    toArray: toArray,
-    size: size,
-    pick: pick,
-    omit: omit,
-    first: first,
-    head: first,
-    take: first,
-    initial: initial,
-    last: last,
-    rest: rest,
-    tail: rest,
-    drop: rest,
-    compact: compact,
-    flatten: flatten,
-    without: without,
-    uniq: uniq,
-    unique: uniq,
-    union: union,
-    intersection: intersection,
-    difference: difference,
-    unzip: unzip,
-    transpose: unzip,
-    zip: zip,
-    object: object,
-    range: range,
-    chunk: chunk,
-    mixin: mixin,
-    'default': _$1
-  };
-
-  // Default Export
-
-  // Add all of the Underscore functions to the wrapper object.
-  var _ = mixin(allExports);
-  // Legacy Node.js API.
-  _._ = _;
-
-  return _;
-
-})));
-//# sourceMappingURL=underscore-umd.js.map
diff --git a/docs/_build/html/_static/underscore.js b/docs/_build/html/_static/underscore.js
deleted file mode 100644
index cf177d42..00000000
--- a/docs/_build/html/_static/underscore.js
+++ /dev/null
@@ -1,6 +0,0 @@
-!function(n,r){"object"==typeof exports&&"undefined"!=typeof module?module.exports=r():"function"==typeof define&&define.amd?define("underscore",r):(n="undefined"!=typeof globalThis?globalThis:n||self,function(){var t=n._,e=n._=r();e.noConflict=function(){return n._=t,e}}())}(this,(function(){
-//     Underscore.js 1.13.1
-//     https://underscorejs.org
-//     (c) 2009-2021 Jeremy Ashkenas, Julian Gonggrijp, and DocumentCloud and Investigative Reporters & Editors
-//     Underscore may be freely distributed under the MIT license.
-var n="1.13.1",r="object"==typeof self&&self.self===self&&self||"object"==typeof global&&global.global===global&&global||Function("return this")()||{},t=Array.prototype,e=Object.prototype,u="undefined"!=typeof Symbol?Symbol.prototype:null,o=t.push,i=t.slice,a=e.toString,f=e.hasOwnProperty,c="undefined"!=typeof ArrayBuffer,l="undefined"!=typeof DataView,s=Array.isArray,p=Object.keys,v=Object.create,h=c&&ArrayBuffer.isView,y=isNaN,d=isFinite,g=!{toString:null}.propertyIsEnumerable("toString"),b=["valueOf","isPrototypeOf","toString","propertyIsEnumerable","hasOwnProperty","toLocaleString"],m=Math.pow(2,53)-1;function j(n,r){return r=null==r?n.length-1:+r,function(){for(var t=Math.max(arguments.length-r,0),e=Array(t),u=0;u<t;u++)e[u]=arguments[u+r];switch(r){case 0:return n.call(this,e);case 1:return n.call(this,arguments[0],e);case 2:return n.call(this,arguments[0],arguments[1],e)}var o=Array(r+1);for(u=0;u<r;u++)o[u]=arguments[u];return o[r]=e,n.apply(this,o)}}function _(n){var r=typeof n;return"function"===r||"object"===r&&!!n}function w(n){return void 0===n}function A(n){return!0===n||!1===n||"[object Boolean]"===a.call(n)}function x(n){var r="[object "+n+"]";return function(n){return a.call(n)===r}}var S=x("String"),O=x("Number"),M=x("Date"),E=x("RegExp"),B=x("Error"),N=x("Symbol"),I=x("ArrayBuffer"),T=x("Function"),k=r.document&&r.document.childNodes;"function"!=typeof/./&&"object"!=typeof Int8Array&&"function"!=typeof k&&(T=function(n){return"function"==typeof n||!1});var D=T,R=x("Object"),F=l&&R(new DataView(new ArrayBuffer(8))),V="undefined"!=typeof Map&&R(new Map),P=x("DataView");var q=F?function(n){return null!=n&&D(n.getInt8)&&I(n.buffer)}:P,U=s||x("Array");function W(n,r){return null!=n&&f.call(n,r)}var z=x("Arguments");!function(){z(arguments)||(z=function(n){return W(n,"callee")})}();var L=z;function $(n){return O(n)&&y(n)}function C(n){return function(){return n}}function K(n){return function(r){var t=n(r);return"number"==typeof t&&t>=0&&t<=m}}function J(n){return function(r){return null==r?void 0:r[n]}}var G=J("byteLength"),H=K(G),Q=/\[object ((I|Ui)nt(8|16|32)|Float(32|64)|Uint8Clamped|Big(I|Ui)nt64)Array\]/;var X=c?function(n){return h?h(n)&&!q(n):H(n)&&Q.test(a.call(n))}:C(!1),Y=J("length");function Z(n,r){r=function(n){for(var r={},t=n.length,e=0;e<t;++e)r[n[e]]=!0;return{contains:function(n){return r[n]},push:function(t){return r[t]=!0,n.push(t)}}}(r);var t=b.length,u=n.constructor,o=D(u)&&u.prototype||e,i="constructor";for(W(n,i)&&!r.contains(i)&&r.push(i);t--;)(i=b[t])in n&&n[i]!==o[i]&&!r.contains(i)&&r.push(i)}function nn(n){if(!_(n))return[];if(p)return p(n);var r=[];for(var t in n)W(n,t)&&r.push(t);return g&&Z(n,r),r}function rn(n,r){var t=nn(r),e=t.length;if(null==n)return!e;for(var u=Object(n),o=0;o<e;o++){var i=t[o];if(r[i]!==u[i]||!(i in u))return!1}return!0}function tn(n){return n instanceof tn?n:this instanceof tn?void(this._wrapped=n):new tn(n)}function en(n){return new Uint8Array(n.buffer||n,n.byteOffset||0,G(n))}tn.VERSION=n,tn.prototype.value=function(){return this._wrapped},tn.prototype.valueOf=tn.prototype.toJSON=tn.prototype.value,tn.prototype.toString=function(){return String(this._wrapped)};var un="[object DataView]";function on(n,r,t,e){if(n===r)return 0!==n||1/n==1/r;if(null==n||null==r)return!1;if(n!=n)return r!=r;var o=typeof n;return("function"===o||"object"===o||"object"==typeof r)&&function n(r,t,e,o){r instanceof tn&&(r=r._wrapped);t instanceof tn&&(t=t._wrapped);var i=a.call(r);if(i!==a.call(t))return!1;if(F&&"[object Object]"==i&&q(r)){if(!q(t))return!1;i=un}switch(i){case"[object RegExp]":case"[object String]":return""+r==""+t;case"[object Number]":return+r!=+r?+t!=+t:0==+r?1/+r==1/t:+r==+t;case"[object Date]":case"[object Boolean]":return+r==+t;case"[object Symbol]":return u.valueOf.call(r)===u.valueOf.call(t);case"[object ArrayBuffer]":case un:return n(en(r),en(t),e,o)}var f="[object Array]"===i;if(!f&&X(r)){if(G(r)!==G(t))return!1;if(r.buffer===t.buffer&&r.byteOffset===t.byteOffset)return!0;f=!0}if(!f){if("object"!=typeof r||"object"!=typeof t)return!1;var c=r.constructor,l=t.constructor;if(c!==l&&!(D(c)&&c instanceof c&&D(l)&&l instanceof l)&&"constructor"in r&&"constructor"in t)return!1}o=o||[];var s=(e=e||[]).length;for(;s--;)if(e[s]===r)return o[s]===t;if(e.push(r),o.push(t),f){if((s=r.length)!==t.length)return!1;for(;s--;)if(!on(r[s],t[s],e,o))return!1}else{var p,v=nn(r);if(s=v.length,nn(t).length!==s)return!1;for(;s--;)if(p=v[s],!W(t,p)||!on(r[p],t[p],e,o))return!1}return e.pop(),o.pop(),!0}(n,r,t,e)}function an(n){if(!_(n))return[];var r=[];for(var t in n)r.push(t);return g&&Z(n,r),r}function fn(n){var r=Y(n);return function(t){if(null==t)return!1;var e=an(t);if(Y(e))return!1;for(var u=0;u<r;u++)if(!D(t[n[u]]))return!1;return n!==hn||!D(t[cn])}}var cn="forEach",ln="has",sn=["clear","delete"],pn=["get",ln,"set"],vn=sn.concat(cn,pn),hn=sn.concat(pn),yn=["add"].concat(sn,cn,ln),dn=V?fn(vn):x("Map"),gn=V?fn(hn):x("WeakMap"),bn=V?fn(yn):x("Set"),mn=x("WeakSet");function jn(n){for(var r=nn(n),t=r.length,e=Array(t),u=0;u<t;u++)e[u]=n[r[u]];return e}function _n(n){for(var r={},t=nn(n),e=0,u=t.length;e<u;e++)r[n[t[e]]]=t[e];return r}function wn(n){var r=[];for(var t in n)D(n[t])&&r.push(t);return r.sort()}function An(n,r){return function(t){var e=arguments.length;if(r&&(t=Object(t)),e<2||null==t)return t;for(var u=1;u<e;u++)for(var o=arguments[u],i=n(o),a=i.length,f=0;f<a;f++){var c=i[f];r&&void 0!==t[c]||(t[c]=o[c])}return t}}var xn=An(an),Sn=An(nn),On=An(an,!0);function Mn(n){if(!_(n))return{};if(v)return v(n);var r=function(){};r.prototype=n;var t=new r;return r.prototype=null,t}function En(n){return _(n)?U(n)?n.slice():xn({},n):n}function Bn(n){return U(n)?n:[n]}function Nn(n){return tn.toPath(n)}function In(n,r){for(var t=r.length,e=0;e<t;e++){if(null==n)return;n=n[r[e]]}return t?n:void 0}function Tn(n,r,t){var e=In(n,Nn(r));return w(e)?t:e}function kn(n){return n}function Dn(n){return n=Sn({},n),function(r){return rn(r,n)}}function Rn(n){return n=Nn(n),function(r){return In(r,n)}}function Fn(n,r,t){if(void 0===r)return n;switch(null==t?3:t){case 1:return function(t){return n.call(r,t)};case 3:return function(t,e,u){return n.call(r,t,e,u)};case 4:return function(t,e,u,o){return n.call(r,t,e,u,o)}}return function(){return n.apply(r,arguments)}}function Vn(n,r,t){return null==n?kn:D(n)?Fn(n,r,t):_(n)&&!U(n)?Dn(n):Rn(n)}function Pn(n,r){return Vn(n,r,1/0)}function qn(n,r,t){return tn.iteratee!==Pn?tn.iteratee(n,r):Vn(n,r,t)}function Un(){}function Wn(n,r){return null==r&&(r=n,n=0),n+Math.floor(Math.random()*(r-n+1))}tn.toPath=Bn,tn.iteratee=Pn;var zn=Date.now||function(){return(new Date).getTime()};function Ln(n){var r=function(r){return n[r]},t="(?:"+nn(n).join("|")+")",e=RegExp(t),u=RegExp(t,"g");return function(n){return n=null==n?"":""+n,e.test(n)?n.replace(u,r):n}}var $n={"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#x27;","`":"&#x60;"},Cn=Ln($n),Kn=Ln(_n($n)),Jn=tn.templateSettings={evaluate:/<%([\s\S]+?)%>/g,interpolate:/<%=([\s\S]+?)%>/g,escape:/<%-([\s\S]+?)%>/g},Gn=/(.)^/,Hn={"'":"'","\\":"\\","\r":"r","\n":"n","\u2028":"u2028","\u2029":"u2029"},Qn=/\\|'|\r|\n|\u2028|\u2029/g;function Xn(n){return"\\"+Hn[n]}var Yn=/^\s*(\w|\$)+\s*$/;var Zn=0;function nr(n,r,t,e,u){if(!(e instanceof r))return n.apply(t,u);var o=Mn(n.prototype),i=n.apply(o,u);return _(i)?i:o}var rr=j((function(n,r){var t=rr.placeholder,e=function(){for(var u=0,o=r.length,i=Array(o),a=0;a<o;a++)i[a]=r[a]===t?arguments[u++]:r[a];for(;u<arguments.length;)i.push(arguments[u++]);return nr(n,e,this,this,i)};return e}));rr.placeholder=tn;var tr=j((function(n,r,t){if(!D(n))throw new TypeError("Bind must be called on a function");var e=j((function(u){return nr(n,e,r,this,t.concat(u))}));return e})),er=K(Y);function ur(n,r,t,e){if(e=e||[],r||0===r){if(r<=0)return e.concat(n)}else r=1/0;for(var u=e.length,o=0,i=Y(n);o<i;o++){var a=n[o];if(er(a)&&(U(a)||L(a)))if(r>1)ur(a,r-1,t,e),u=e.length;else for(var f=0,c=a.length;f<c;)e[u++]=a[f++];else t||(e[u++]=a)}return e}var or=j((function(n,r){var t=(r=ur(r,!1,!1)).length;if(t<1)throw new Error("bindAll must be passed function names");for(;t--;){var e=r[t];n[e]=tr(n[e],n)}return n}));var ir=j((function(n,r,t){return setTimeout((function(){return n.apply(null,t)}),r)})),ar=rr(ir,tn,1);function fr(n){return function(){return!n.apply(this,arguments)}}function cr(n,r){var t;return function(){return--n>0&&(t=r.apply(this,arguments)),n<=1&&(r=null),t}}var lr=rr(cr,2);function sr(n,r,t){r=qn(r,t);for(var e,u=nn(n),o=0,i=u.length;o<i;o++)if(r(n[e=u[o]],e,n))return e}function pr(n){return function(r,t,e){t=qn(t,e);for(var u=Y(r),o=n>0?0:u-1;o>=0&&o<u;o+=n)if(t(r[o],o,r))return o;return-1}}var vr=pr(1),hr=pr(-1);function yr(n,r,t,e){for(var u=(t=qn(t,e,1))(r),o=0,i=Y(n);o<i;){var a=Math.floor((o+i)/2);t(n[a])<u?o=a+1:i=a}return o}function dr(n,r,t){return function(e,u,o){var a=0,f=Y(e);if("number"==typeof o)n>0?a=o>=0?o:Math.max(o+f,a):f=o>=0?Math.min(o+1,f):o+f+1;else if(t&&o&&f)return e[o=t(e,u)]===u?o:-1;if(u!=u)return(o=r(i.call(e,a,f),$))>=0?o+a:-1;for(o=n>0?a:f-1;o>=0&&o<f;o+=n)if(e[o]===u)return o;return-1}}var gr=dr(1,vr,yr),br=dr(-1,hr);function mr(n,r,t){var e=(er(n)?vr:sr)(n,r,t);if(void 0!==e&&-1!==e)return n[e]}function jr(n,r,t){var e,u;if(r=Fn(r,t),er(n))for(e=0,u=n.length;e<u;e++)r(n[e],e,n);else{var o=nn(n);for(e=0,u=o.length;e<u;e++)r(n[o[e]],o[e],n)}return n}function _r(n,r,t){r=qn(r,t);for(var e=!er(n)&&nn(n),u=(e||n).length,o=Array(u),i=0;i<u;i++){var a=e?e[i]:i;o[i]=r(n[a],a,n)}return o}function wr(n){var r=function(r,t,e,u){var o=!er(r)&&nn(r),i=(o||r).length,a=n>0?0:i-1;for(u||(e=r[o?o[a]:a],a+=n);a>=0&&a<i;a+=n){var f=o?o[a]:a;e=t(e,r[f],f,r)}return e};return function(n,t,e,u){var o=arguments.length>=3;return r(n,Fn(t,u,4),e,o)}}var Ar=wr(1),xr=wr(-1);function Sr(n,r,t){var e=[];return r=qn(r,t),jr(n,(function(n,t,u){r(n,t,u)&&e.push(n)})),e}function Or(n,r,t){r=qn(r,t);for(var e=!er(n)&&nn(n),u=(e||n).length,o=0;o<u;o++){var i=e?e[o]:o;if(!r(n[i],i,n))return!1}return!0}function Mr(n,r,t){r=qn(r,t);for(var e=!er(n)&&nn(n),u=(e||n).length,o=0;o<u;o++){var i=e?e[o]:o;if(r(n[i],i,n))return!0}return!1}function Er(n,r,t,e){return er(n)||(n=jn(n)),("number"!=typeof t||e)&&(t=0),gr(n,r,t)>=0}var Br=j((function(n,r,t){var e,u;return D(r)?u=r:(r=Nn(r),e=r.slice(0,-1),r=r[r.length-1]),_r(n,(function(n){var o=u;if(!o){if(e&&e.length&&(n=In(n,e)),null==n)return;o=n[r]}return null==o?o:o.apply(n,t)}))}));function Nr(n,r){return _r(n,Rn(r))}function Ir(n,r,t){var e,u,o=-1/0,i=-1/0;if(null==r||"number"==typeof r&&"object"!=typeof n[0]&&null!=n)for(var a=0,f=(n=er(n)?n:jn(n)).length;a<f;a++)null!=(e=n[a])&&e>o&&(o=e);else r=qn(r,t),jr(n,(function(n,t,e){((u=r(n,t,e))>i||u===-1/0&&o===-1/0)&&(o=n,i=u)}));return o}function Tr(n,r,t){if(null==r||t)return er(n)||(n=jn(n)),n[Wn(n.length-1)];var e=er(n)?En(n):jn(n),u=Y(e);r=Math.max(Math.min(r,u),0);for(var o=u-1,i=0;i<r;i++){var a=Wn(i,o),f=e[i];e[i]=e[a],e[a]=f}return e.slice(0,r)}function kr(n,r){return function(t,e,u){var o=r?[[],[]]:{};return e=qn(e,u),jr(t,(function(r,u){var i=e(r,u,t);n(o,r,i)})),o}}var Dr=kr((function(n,r,t){W(n,t)?n[t].push(r):n[t]=[r]})),Rr=kr((function(n,r,t){n[t]=r})),Fr=kr((function(n,r,t){W(n,t)?n[t]++:n[t]=1})),Vr=kr((function(n,r,t){n[t?0:1].push(r)}),!0),Pr=/[^\ud800-\udfff]|[\ud800-\udbff][\udc00-\udfff]|[\ud800-\udfff]/g;function qr(n,r,t){return r in t}var Ur=j((function(n,r){var t={},e=r[0];if(null==n)return t;D(e)?(r.length>1&&(e=Fn(e,r[1])),r=an(n)):(e=qr,r=ur(r,!1,!1),n=Object(n));for(var u=0,o=r.length;u<o;u++){var i=r[u],a=n[i];e(a,i,n)&&(t[i]=a)}return t})),Wr=j((function(n,r){var t,e=r[0];return D(e)?(e=fr(e),r.length>1&&(t=r[1])):(r=_r(ur(r,!1,!1),String),e=function(n,t){return!Er(r,t)}),Ur(n,e,t)}));function zr(n,r,t){return i.call(n,0,Math.max(0,n.length-(null==r||t?1:r)))}function Lr(n,r,t){return null==n||n.length<1?null==r||t?void 0:[]:null==r||t?n[0]:zr(n,n.length-r)}function $r(n,r,t){return i.call(n,null==r||t?1:r)}var Cr=j((function(n,r){return r=ur(r,!0,!0),Sr(n,(function(n){return!Er(r,n)}))})),Kr=j((function(n,r){return Cr(n,r)}));function Jr(n,r,t,e){A(r)||(e=t,t=r,r=!1),null!=t&&(t=qn(t,e));for(var u=[],o=[],i=0,a=Y(n);i<a;i++){var f=n[i],c=t?t(f,i,n):f;r&&!t?(i&&o===c||u.push(f),o=c):t?Er(o,c)||(o.push(c),u.push(f)):Er(u,f)||u.push(f)}return u}var Gr=j((function(n){return Jr(ur(n,!0,!0))}));function Hr(n){for(var r=n&&Ir(n,Y).length||0,t=Array(r),e=0;e<r;e++)t[e]=Nr(n,e);return t}var Qr=j(Hr);function Xr(n,r){return n._chain?tn(r).chain():r}function Yr(n){return jr(wn(n),(function(r){var t=tn[r]=n[r];tn.prototype[r]=function(){var n=[this._wrapped];return o.apply(n,arguments),Xr(this,t.apply(tn,n))}})),tn}jr(["pop","push","reverse","shift","sort","splice","unshift"],(function(n){var r=t[n];tn.prototype[n]=function(){var t=this._wrapped;return null!=t&&(r.apply(t,arguments),"shift"!==n&&"splice"!==n||0!==t.length||delete t[0]),Xr(this,t)}})),jr(["concat","join","slice"],(function(n){var r=t[n];tn.prototype[n]=function(){var n=this._wrapped;return null!=n&&(n=r.apply(n,arguments)),Xr(this,n)}}));var Zr=Yr({__proto__:null,VERSION:n,restArguments:j,isObject:_,isNull:function(n){return null===n},isUndefined:w,isBoolean:A,isElement:function(n){return!(!n||1!==n.nodeType)},isString:S,isNumber:O,isDate:M,isRegExp:E,isError:B,isSymbol:N,isArrayBuffer:I,isDataView:q,isArray:U,isFunction:D,isArguments:L,isFinite:function(n){return!N(n)&&d(n)&&!isNaN(parseFloat(n))},isNaN:$,isTypedArray:X,isEmpty:function(n){if(null==n)return!0;var r=Y(n);return"number"==typeof r&&(U(n)||S(n)||L(n))?0===r:0===Y(nn(n))},isMatch:rn,isEqual:function(n,r){return on(n,r)},isMap:dn,isWeakMap:gn,isSet:bn,isWeakSet:mn,keys:nn,allKeys:an,values:jn,pairs:function(n){for(var r=nn(n),t=r.length,e=Array(t),u=0;u<t;u++)e[u]=[r[u],n[r[u]]];return e},invert:_n,functions:wn,methods:wn,extend:xn,extendOwn:Sn,assign:Sn,defaults:On,create:function(n,r){var t=Mn(n);return r&&Sn(t,r),t},clone:En,tap:function(n,r){return r(n),n},get:Tn,has:function(n,r){for(var t=(r=Nn(r)).length,e=0;e<t;e++){var u=r[e];if(!W(n,u))return!1;n=n[u]}return!!t},mapObject:function(n,r,t){r=qn(r,t);for(var e=nn(n),u=e.length,o={},i=0;i<u;i++){var a=e[i];o[a]=r(n[a],a,n)}return o},identity:kn,constant:C,noop:Un,toPath:Bn,property:Rn,propertyOf:function(n){return null==n?Un:function(r){return Tn(n,r)}},matcher:Dn,matches:Dn,times:function(n,r,t){var e=Array(Math.max(0,n));r=Fn(r,t,1);for(var u=0;u<n;u++)e[u]=r(u);return e},random:Wn,now:zn,escape:Cn,unescape:Kn,templateSettings:Jn,template:function(n,r,t){!r&&t&&(r=t),r=On({},r,tn.templateSettings);var e=RegExp([(r.escape||Gn).source,(r.interpolate||Gn).source,(r.evaluate||Gn).source].join("|")+"|$","g"),u=0,o="__p+='";n.replace(e,(function(r,t,e,i,a){return o+=n.slice(u,a).replace(Qn,Xn),u=a+r.length,t?o+="'+\n((__t=("+t+"))==null?'':_.escape(__t))+\n'":e?o+="'+\n((__t=("+e+"))==null?'':__t)+\n'":i&&(o+="';\n"+i+"\n__p+='"),r})),o+="';\n";var i,a=r.variable;if(a){if(!Yn.test(a))throw new Error("variable is not a bare identifier: "+a)}else o="with(obj||{}){\n"+o+"}\n",a="obj";o="var __t,__p='',__j=Array.prototype.join,"+"print=function(){__p+=__j.call(arguments,'');};\n"+o+"return __p;\n";try{i=new Function(a,"_",o)}catch(n){throw n.source=o,n}var f=function(n){return i.call(this,n,tn)};return f.source="function("+a+"){\n"+o+"}",f},result:function(n,r,t){var e=(r=Nn(r)).length;if(!e)return D(t)?t.call(n):t;for(var u=0;u<e;u++){var o=null==n?void 0:n[r[u]];void 0===o&&(o=t,u=e),n=D(o)?o.call(n):o}return n},uniqueId:function(n){var r=++Zn+"";return n?n+r:r},chain:function(n){var r=tn(n);return r._chain=!0,r},iteratee:Pn,partial:rr,bind:tr,bindAll:or,memoize:function(n,r){var t=function(e){var u=t.cache,o=""+(r?r.apply(this,arguments):e);return W(u,o)||(u[o]=n.apply(this,arguments)),u[o]};return t.cache={},t},delay:ir,defer:ar,throttle:function(n,r,t){var e,u,o,i,a=0;t||(t={});var f=function(){a=!1===t.leading?0:zn(),e=null,i=n.apply(u,o),e||(u=o=null)},c=function(){var c=zn();a||!1!==t.leading||(a=c);var l=r-(c-a);return u=this,o=arguments,l<=0||l>r?(e&&(clearTimeout(e),e=null),a=c,i=n.apply(u,o),e||(u=o=null)):e||!1===t.trailing||(e=setTimeout(f,l)),i};return c.cancel=function(){clearTimeout(e),a=0,e=u=o=null},c},debounce:function(n,r,t){var e,u,o,i,a,f=function(){var c=zn()-u;r>c?e=setTimeout(f,r-c):(e=null,t||(i=n.apply(a,o)),e||(o=a=null))},c=j((function(c){return a=this,o=c,u=zn(),e||(e=setTimeout(f,r),t&&(i=n.apply(a,o))),i}));return c.cancel=function(){clearTimeout(e),e=o=a=null},c},wrap:function(n,r){return rr(r,n)},negate:fr,compose:function(){var n=arguments,r=n.length-1;return function(){for(var t=r,e=n[r].apply(this,arguments);t--;)e=n[t].call(this,e);return e}},after:function(n,r){return function(){if(--n<1)return r.apply(this,arguments)}},before:cr,once:lr,findKey:sr,findIndex:vr,findLastIndex:hr,sortedIndex:yr,indexOf:gr,lastIndexOf:br,find:mr,detect:mr,findWhere:function(n,r){return mr(n,Dn(r))},each:jr,forEach:jr,map:_r,collect:_r,reduce:Ar,foldl:Ar,inject:Ar,reduceRight:xr,foldr:xr,filter:Sr,select:Sr,reject:function(n,r,t){return Sr(n,fr(qn(r)),t)},every:Or,all:Or,some:Mr,any:Mr,contains:Er,includes:Er,include:Er,invoke:Br,pluck:Nr,where:function(n,r){return Sr(n,Dn(r))},max:Ir,min:function(n,r,t){var e,u,o=1/0,i=1/0;if(null==r||"number"==typeof r&&"object"!=typeof n[0]&&null!=n)for(var a=0,f=(n=er(n)?n:jn(n)).length;a<f;a++)null!=(e=n[a])&&e<o&&(o=e);else r=qn(r,t),jr(n,(function(n,t,e){((u=r(n,t,e))<i||u===1/0&&o===1/0)&&(o=n,i=u)}));return o},shuffle:function(n){return Tr(n,1/0)},sample:Tr,sortBy:function(n,r,t){var e=0;return r=qn(r,t),Nr(_r(n,(function(n,t,u){return{value:n,index:e++,criteria:r(n,t,u)}})).sort((function(n,r){var t=n.criteria,e=r.criteria;if(t!==e){if(t>e||void 0===t)return 1;if(t<e||void 0===e)return-1}return n.index-r.index})),"value")},groupBy:Dr,indexBy:Rr,countBy:Fr,partition:Vr,toArray:function(n){return n?U(n)?i.call(n):S(n)?n.match(Pr):er(n)?_r(n,kn):jn(n):[]},size:function(n){return null==n?0:er(n)?n.length:nn(n).length},pick:Ur,omit:Wr,first:Lr,head:Lr,take:Lr,initial:zr,last:function(n,r,t){return null==n||n.length<1?null==r||t?void 0:[]:null==r||t?n[n.length-1]:$r(n,Math.max(0,n.length-r))},rest:$r,tail:$r,drop:$r,compact:function(n){return Sr(n,Boolean)},flatten:function(n,r){return ur(n,r,!1)},without:Kr,uniq:Jr,unique:Jr,union:Gr,intersection:function(n){for(var r=[],t=arguments.length,e=0,u=Y(n);e<u;e++){var o=n[e];if(!Er(r,o)){var i;for(i=1;i<t&&Er(arguments[i],o);i++);i===t&&r.push(o)}}return r},difference:Cr,unzip:Hr,transpose:Hr,zip:Qr,object:function(n,r){for(var t={},e=0,u=Y(n);e<u;e++)r?t[n[e]]=r[e]:t[n[e][0]]=n[e][1];return t},range:function(n,r,t){null==r&&(r=n||0,n=0),t||(t=r<n?-1:1);for(var e=Math.max(Math.ceil((r-n)/t),0),u=Array(e),o=0;o<e;o++,n+=t)u[o]=n;return u},chunk:function(n,r){if(null==r||r<1)return[];for(var t=[],e=0,u=n.length;e<u;)t.push(i.call(n,e,e+=r));return t},mixin:Yr,default:tn});return Zr._=Zr,Zr}));
\ No newline at end of file
diff --git a/docs/_build/html/components.html b/docs/_build/html/components.html
deleted file mode 100644
index 90ddff4f..00000000
--- a/docs/_build/html/components.html
+++ /dev/null
@@ -1,412 +0,0 @@
-
-
-<!DOCTYPE html>
-<html class="writer-html5" lang="en" >
-<head>
-  <meta charset="utf-8" />
-  
-  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
-  
-  <title>Components &mdash; discord.py-message-components 1.7.5 documentation</title>
-  
-
-  
-  <link rel="stylesheet" href="_static/css/theme.css" type="text/css" />
-  <link rel="stylesheet" href="_static/pygments.css" type="text/css" />
-  <link rel="stylesheet" href="_static/pygments.css" type="text/css" />
-  <link rel="stylesheet" href="_static/css/theme.css" type="text/css" />
-
-  
-  
-
-  
-  
-
-  
-
-  
-  <!--[if lt IE 9]>
-    <script src="_static/js/html5shiv.min.js"></script>
-  <![endif]-->
-  
-    
-      <script type="text/javascript" id="documentation_options" data-url_root="./" src="_static/documentation_options.js"></script>
-        <script data-url_root="./" id="documentation_options" src="_static/documentation_options.js"></script>
-        <script src="_static/jquery.js"></script>
-        <script src="_static/underscore.js"></script>
-        <script src="_static/doctools.js"></script>
-    
-    <script type="text/javascript" src="_static/js/theme.js"></script>
-
-    
-    <link rel="index" title="Index" href="genindex.html" />
-    <link rel="search" title="Search" href="search.html" />
-    <link rel="next" title="Interaction" href="interaction.html" />
-    <link rel="prev" title="Welcome to discord.py-message-component’s documentation!" href="index.html" /> 
-</head>
-
-<body class="wy-body-for-nav">
-
-   
-  <div class="wy-grid-for-nav">
-    
-    <nav data-toggle="wy-nav-shift" class="wy-nav-side">
-      <div class="wy-side-scroll">
-        <div class="wy-side-nav-search" >
-          
-
-          
-            <a href="index.html" class="icon icon-home"> discord.py-message-components
-          
-
-          
-          </a>
-
-          
-            
-            
-          
-
-          
-<div role="search">
-  <form id="rtd-search-form" class="wy-form" action="search.html" method="get">
-    <input type="text" name="q" placeholder="Search docs" />
-    <input type="hidden" name="check_keywords" value="yes" />
-    <input type="hidden" name="area" value="default" />
-  </form>
-</div>
-
-          
-        </div>
-
-        
-        <div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="main navigation">
-          
-            
-            
-              
-            
-            
-              <p class="caption"><span class="caption-text">Contents:</span></p>
-<ul class="current">
-<li class="toctree-l1 current"><a class="current reference internal" href="#">Components</a></li>
-<li class="toctree-l1"><a class="reference internal" href="#discord-buttoncolor"><code class="xref py py-class docutils literal notranslate"><span class="pre">discord.ButtonColor</span></code></a></li>
-<li class="toctree-l1"><a class="reference internal" href="#discord-actionrow-args-kwargs"><code class="xref py py-class docutils literal notranslate"><span class="pre">discord.ActionRow(*args,</span> <span class="pre">**kwargs)</span></code></a><ul>
-<li class="toctree-l2"><a class="reference internal" href="#attributes">Attributes</a></li>
-<li class="toctree-l2"><a class="reference internal" href="#methodes">Methodes</a></li>
-</ul>
-</li>
-<li class="toctree-l1"><a class="reference internal" href="#discord-button-kwargs"><code class="xref py py-class docutils literal notranslate"><span class="pre">discord.Button(**kwargs)</span></code></a><ul>
-<li class="toctree-l2"><a class="reference internal" href="#button-attributes">Attributes</a></li>
-<li class="toctree-l2"><a class="reference internal" href="#button-methodes">Methodes</a><ul>
-<li class="toctree-l3"><a class="reference internal" href="#indices-and-tables">Indices and tables</a></li>
-</ul>
-</li>
-</ul>
-</li>
-<li class="toctree-l1"><a class="reference internal" href="interaction.html">Interaction</a></li>
-</ul>
-
-            
-          
-        </div>
-        
-      </div>
-    </nav>
-
-    <section data-toggle="wy-nav-shift" class="wy-nav-content-wrap">
-
-      
-      <nav class="wy-nav-top" aria-label="top navigation">
-        
-          <i data-toggle="wy-nav-top" class="fa fa-bars"></i>
-          <a href="index.html">discord.py-message-components</a>
-        
-      </nav>
-
-
-      <div class="wy-nav-content">
-        
-        <div class="rst-content">
-        
-          
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-<div role="navigation" aria-label="breadcrumbs navigation">
-
-  <ul class="wy-breadcrumbs">
-    
-      <li><a href="index.html" class="icon icon-home"></a> &raquo;</li>
-        
-      <li>Components</li>
-    
-    
-      <li class="wy-breadcrumbs-aside">
-        
-          
-            <a href="_sources/components.rst.txt" rel="nofollow"> View page source</a>
-          
-        
-      </li>
-    
-  </ul>
-
-  
-  <hr/>
-</div>
-          <div role="main" class="document" itemscope="itemscope" itemtype="http://schema.org/Article">
-           <div itemprop="articleBody">
-            
-  <div class="section" id="components">
-<h1>Components<a class="headerlink" href="#components" title="Permalink to this headline">¶</a></h1>
-</div>
-<div class="section" id="discord-buttoncolor">
-<span id="buttoncolor"></span><h1><code class="xref py py-class docutils literal notranslate"><span class="pre">discord.ButtonColor</span></code><a class="headerlink" href="#discord-buttoncolor" title="Permalink to this headline">¶</a></h1>
-<blockquote>
-<div><ul class="simple">
-<li><p><code class="docutils literal notranslate"><span class="pre">blurple</span></code> = 1</p></li>
-<li><p><code class="docutils literal notranslate"><span class="pre">grey</span></code> = 2</p></li>
-<li><p><code class="docutils literal notranslate"><span class="pre">green</span></code> = 3</p></li>
-<li><p><code class="docutils literal notranslate"><span class="pre">red</span></code> = 4</p></li>
-<li><p><code class="docutils literal notranslate"><span class="pre">grey_url</span></code> (navigates to an URL) = 5</p></li>
-</ul>
-</div></blockquote>
-</div>
-<div class="section" id="discord-actionrow-args-kwargs">
-<span id="actionrow"></span><h1><code class="xref py py-class docutils literal notranslate"><span class="pre">discord.ActionRow(*args,</span> <span class="pre">**kwargs)</span></code><a class="headerlink" href="#discord-actionrow-args-kwargs" title="Permalink to this headline">¶</a></h1>
-<p>Represents an <code class="docutils literal notranslate"><span class="pre">ActionRow</span></code>-Part for the components of an <code class="xref py py-class docutils literal notranslate"><span class="pre">discord.Message</span></code></p>
-<div class="admonition note">
-<p class="admonition-title">Note</p>
-<p>You could use an <code class="xref py py-class docutils literal notranslate"><span class="pre">list</span></code> instead of this but you dont have the functions and oarameters of this class then.</p>
-</div>
-<div class="section" id="attributes">
-<span id="actionrow-attributes"></span><h2>Attributes<a class="headerlink" href="#attributes" title="Permalink to this headline">¶</a></h2>
-<blockquote>
-<div><ul class="simple">
-<li><dl class="simple">
-<dt><code class="xref py py-attr docutils literal notranslate"><span class="pre">*args</span></code>: [Union[<code class="xref py py-class docutils literal notranslate"><span class="pre">Button</span></code>, <code class="xref py py-class docutils literal notranslate"><span class="pre">SelectionMenu</span></code>]]</dt><dd><p>An array of <code class="xref py py-class docutils literal notranslate"><span class="pre">Button</span></code>/s and/or <code class="xref py py-class docutils literal notranslate"><span class="pre">SelectionMenu</span></code>/s.</p>
-</dd>
-</dl>
-</li>
-</ul>
-<ul class="simple" id="actionrow-force">
-<li><dl class="simple">
-<dt><code class="xref py py-attr docutils literal notranslate"><span class="pre">force</span></code>: Optional[Bool]</dt><dd><p>When set to <code class="docutils literal notranslate"><span class="pre">True</span></code> an Empty <code class="xref py py-class docutils literal notranslate"><span class="pre">ActionRow</span></code> will be ignored</p>
-</dd>
-</dl>
-</li>
-</ul>
-<div class="admonition note">
-<p class="admonition-title">Note</p>
-<p>For more information about ActionRow’s visit the <a class="reference external" href="https://discord.com/developers/docs/interactions/message-components#actionrow">Discord-API Documentation</a>.</p>
-</div>
-</div></blockquote>
-</div>
-<div class="section" id="methodes">
-<span id="actionrow-methodes"></span><h2>Methodes<a class="headerlink" href="#methodes" title="Permalink to this headline">¶</a></h2>
-<blockquote>
-<div><dl class="simple" id="actionrow-sendable">
-<dt><code class="xref py py-meth docutils literal notranslate"><span class="pre">sendable()</span></code> -&gt; Dict</dt><dd><p>Makes the <code class="xref py py-class docutils literal notranslate"><span class="pre">ActionRow</span></code> sendable to discord.</p>
-</dd>
-</dl>
-<dl class="simple" id="actionrow-disable-all-buttons">
-<dt><code class="xref py py-meth docutils literal notranslate"><span class="pre">disable_all_buttons()</span></code></dt><dd><p>Disable all objects’s of type <code class="xref py py-class docutils literal notranslate"><span class="pre">discord.Button</span></code> in this <code class="xref py py-class docutils literal notranslate"><span class="pre">ActionRow</span></code>.</p>
-<dl class="field-list simple">
-<dt class="field-odd">return</dt>
-<dd class="field-odd"><p><code class="xref py py-class docutils literal notranslate"><span class="pre">discord.ActionRow</span></code></p>
-</dd>
-</dl>
-</dd>
-</dl>
-<dl id="actionrow-disable-all-buttons-if">
-<dt><code class="xref py py-meth docutils literal notranslate"><span class="pre">disable_all_buttons_if(check:</span> <span class="pre">Union[Bool,</span> <span class="pre">Callable],</span> <span class="pre">**kwargs)()</span></code></dt><dd><p>Disable all <code class="xref py py-class docutils literal notranslate"><span class="pre">discord.Button</span></code> in this <code class="xref py py-class docutils literal notranslate"><span class="pre">ActionRow</span></code> if the passed <code class="xref py py-attr docutils literal notranslate"><span class="pre">check</span></code> <code class="docutils literal notranslate"><span class="pre">True</span></code>.</p>
-<p><strong>Parameters</strong></p>
-<blockquote>
-<div><ul class="simple">
-<li><dl class="simple">
-<dt><code class="xref py py-attr docutils literal notranslate"><span class="pre">check</span></code>: Union[Bool, Callable]</dt><dd><p>could be an <code class="xref py py-class docutils literal notranslate"><span class="pre">bool</span></code> or usually any <code class="xref py py-obj docutils literal notranslate"><span class="pre">Callable</span></code> that returns an <code class="xref py py-class docutils literal notranslate"><span class="pre">bool</span></code></p>
-</dd>
-</dl>
-</li>
-<li><dl class="simple">
-<dt><code class="xref py py-attr docutils literal notranslate"><span class="pre">**kwargs</span></code></dt><dd><p><code class="xref py py-obj docutils literal notranslate"><span class="pre">kwargs</span></code> that should passed in to the <code class="xref py py-attr docutils literal notranslate"><span class="pre">check</span></code> if it is an <code class="xref py py-obj docutils literal notranslate"><span class="pre">Callable</span></code></p>
-</dd>
-</dl>
-</li>
-</ul>
-</div></blockquote>
-<dl class="field-list simple">
-<dt class="field-odd">return</dt>
-<dd class="field-odd"><p><code class="xref py py-class docutils literal notranslate"><span class="pre">ActionRow</span></code></p>
-</dd>
-</dl>
-</dd>
-</dl>
-</div></blockquote>
-</div>
-</div>
-<div class="section" id="discord-button-kwargs">
-<span id="button"></span><h1><code class="xref py py-class docutils literal notranslate"><span class="pre">discord.Button(**kwargs)</span></code><a class="headerlink" href="#discord-button-kwargs" title="Permalink to this headline">¶</a></h1>
-<p>Represents an <code class="docutils literal notranslate"><span class="pre">Discord-Button</span></code></p>
-<div class="admonition note">
-<p class="admonition-title">Note</p>
-<p>For more information Discord-Button’s visit the <a class="reference external" href="https://discord.com/developers/docs/interactions/message-components#buttons">Discord-API Documentation</a>.</p>
-</div>
-<div class="section" id="button-attributes">
-<span id="id2"></span><h2>Attributes<a class="headerlink" href="#button-attributes" title="Permalink to this headline">¶</a></h2>
-<blockquote>
-<div><dl class="simple" id="button-label">
-<dt><code class="xref py py-attr docutils literal notranslate"><span class="pre">label</span></code>: <code class="xref py py-class docutils literal notranslate"><span class="pre">str</span></code></dt><dd><p>The Text displayed in discord on the Button. Maximal lenght is 80 Chars.</p>
-</dd>
-</dl>
-<dl class="simple" id="button-custom-id">
-<dt><code class="xref py py-attr docutils literal notranslate"><span class="pre">custom_id</span></code>: Union[<code class="xref py py-class docutils literal notranslate"><span class="pre">str</span></code>, <code class="xref py py-class docutils literal notranslate"><span class="pre">int</span></code>]</dt><dd><p>The custom_id discord send us when a User press the Button. The max. lenght of this is 100.</p>
-</dd>
-</dl>
-<dl id="button-style">
-<dt><code class="xref py py-attr docutils literal notranslate"><span class="pre">style</span></code>: Union[<code class="xref py py-class docutils literal notranslate"><span class="pre">ButtonColor</span></code>, <code class="xref py py-class docutils literal notranslate"><span class="pre">ButtonStyle</span></code>, Any[1, 2, 3, 4, 5]]</dt><dd><p>The Style of the Button.</p>
-<div class="admonition note">
-<p class="admonition-title">Note</p>
-<p>To get more infos about the styles wisit
-<a class="reference external" href="https://discord.com/developers/docs/interactions/message-components#buttons-button-styles">the Discord-API Documentation</a>.</p>
-</div>
-</dd>
-</dl>
-<dl class="simple" id="button-emoji">
-<dt><code class="xref py py-attr docutils literal notranslate"><span class="pre">emoji</span></code>: Optional[Union[<code class="xref py py-class docutils literal notranslate"><span class="pre">discord.PartialEmoji</span></code>, <code class="xref py py-class docutils literal notranslate"><span class="pre">discord.Emoji</span></code>, <code class="xref py py-class docutils literal notranslate"><span class="pre">str</span></code>]]</dt><dd><p>The Emoji that will be displayed on the left side of the Button.</p>
-</dd>
-</dl>
-<dl id="button-url">
-<dt><code class="xref py py-attr docutils literal notranslate"><span class="pre">url</span></code>: Optional[<code class="xref py py-class docutils literal notranslate"><span class="pre">str</span></code>]</dt><dd><p>The URL the Button links too.</p>
-<div class="admonition note">
-<p class="admonition-title">Note</p>
-<p>if you set this, the <code class="xref py py-attr docutils literal notranslate"><span class="pre">style</span></code> will automaticly set to <code class="xref py py-class docutils literal notranslate"><span class="pre">ButtonStyle.Link_Button</span></code></p>
-</div>
-<div class="admonition warning">
-<p class="admonition-title">Warning</p>
-<p>You cant pass an <code class="xref py py-attr docutils literal notranslate"><span class="pre">custom_id</span></code> and a <code class="xref py py-attr docutils literal notranslate"><span class="pre">url</span></code> beacuse discord dont send anything when clicking on an <code class="docutils literal notranslate"><span class="pre">URL-Button</span></code> so it dont accept both; <code class="xref py py-attr docutils literal notranslate"><span class="pre">url</span></code>/ButtonStyle.Link_Button and <code class="xref py py-attr docutils literal notranslate"><span class="pre">custom_id</span></code>!</p>
-</div>
-</dd>
-</dl>
-<dl class="simple" id="button-disabled">
-<dt><code class="xref py py-attr docutils literal notranslate"><span class="pre">disabled</span></code>: <code class="xref py py-class docutils literal notranslate"><span class="pre">Bool</span></code></dt><dd><p>Whether the Button is disabled; defauld False.</p>
-</dd>
-</dl>
-</div></blockquote>
-</div>
-<div class="section" id="button-methodes">
-<span id="id3"></span><h2>Methodes<a class="headerlink" href="#button-methodes" title="Permalink to this headline">¶</a></h2>
-<blockquote>
-<div><p id="button-disable-if"><code class="xref py py-meth docutils literal notranslate"><span class="pre">disable_if()</span></code></p>
-<dl>
-<dt>Disable the <code class="xref py py-class docutils literal notranslate"><span class="pre">Button</span></code> if the passed <code class="xref py py-attr docutils literal notranslate"><span class="pre">check</span></code> returns <code class="docutils literal notranslate"><span class="pre">True</span></code>.</dt><dd><ul class="simple">
-<li><dl class="simple">
-<dt><code class="xref py py-attr docutils literal notranslate"><span class="pre">check</span></code>: typing.Union[bool, typing.Callable]</dt><dd><p>Could be an <code class="xref py py-class docutils literal notranslate"><span class="pre">bool</span></code> or usually any <code class="xref py py-class docutils literal notranslate"><span class="pre">Callable</span></code> that returns an <code class="xref py py-class docutils literal notranslate"><span class="pre">bool</span></code></p>
-</dd>
-</dl>
-</li>
-<li><dl class="simple">
-<dt><code class="xref py py-attr docutils literal notranslate"><span class="pre">**kwargs</span></code>: Any[SupportsIndex]</dt><dd><p>Arguments that should passed in to the <code class="xref py py-attr docutils literal notranslate"><span class="pre">check</span></code> if it is an <code class="xref py py-class docutils literal notranslate"><span class="pre">Callable</span></code></p>
-</dd>
-</dl>
-</li>
-</ul>
-<dl class="field-list simple">
-<dt class="field-odd">return</dt>
-<dd class="field-odd"><p><code class="xref py py-class docutils literal notranslate"><span class="pre">discord.Button</span></code></p>
-</dd>
-</dl>
-</dd>
-</dl>
-<p id="button-set-color-if"><code class="xref py py-meth docutils literal notranslate"><span class="pre">set_color_if()</span></code></p>
-<p>Sets the Color(Style) of an <code class="xref py py-class docutils literal notranslate"><span class="pre">discord.Button</span></code> to the provided <code class="xref py py-attr docutils literal notranslate"><span class="pre">color</span></code> if the passed <code class="xref py py-attr docutils literal notranslate"><span class="pre">check</span></code> returns <code class="docutils literal notranslate"><span class="pre">True</span></code>.</p>
-<blockquote>
-<div><ul class="simple">
-<li><p><code class="xref py py-attr docutils literal notranslate"><span class="pre">check</span></code>: could be an <code class="xref py py-class docutils literal notranslate"><span class="pre">bool</span></code> or usaly any <code class="xref py py-obj docutils literal notranslate"><span class="pre">Callable</span></code> that returns an <code class="xref py py-class docutils literal notranslate"><span class="pre">bool</span></code></p></li>
-<li><p><code class="xref py py-attr docutils literal notranslate"><span class="pre">color</span></code>: the Color(Style) that should set if the <code class="xref py py-attr docutils literal notranslate"><span class="pre">check</span></code> returns <code class="docutils literal notranslate"><span class="pre">True</span></code></p></li>
-<li><p><code class="xref py py-attr docutils literal notranslate"><span class="pre">**kwargs</span></code>: <code class="docutils literal notranslate"><span class="pre">kwargs</span></code> that should passed in to the <code class="xref py py-attr docutils literal notranslate"><span class="pre">check</span></code> if it is an <code class="xref py py-class docutils literal notranslate"><span class="pre">Callable</span></code></p></li>
-</ul>
-<dl class="field-list simple">
-<dt class="field-odd">return</dt>
-<dd class="field-odd"><p><code class="xref py py-class docutils literal notranslate"><span class="pre">discord.Button</span></code></p>
-</dd>
-</dl>
-</div></blockquote>
-</div></blockquote>
-<div class="toctree-wrapper compound">
-</div>
-<div class="section" id="indices-and-tables">
-<h3>Indices and tables<a class="headerlink" href="#indices-and-tables" title="Permalink to this headline">¶</a></h3>
-<ul class="simple">
-<li><p><a class="reference internal" href="genindex.html"><span class="std std-ref">Index</span></a></p></li>
-<li><p><a class="reference internal" href="py-modindex.html"><span class="std std-ref">Module Index</span></a></p></li>
-<li><p><a class="reference internal" href="search.html"><span class="std std-ref">Search Page</span></a></p></li>
-</ul>
-</div>
-</div>
-</div>
-
-
-           </div>
-           
-          </div>
-          <footer>
-    <div class="rst-footer-buttons" role="navigation" aria-label="footer navigation">
-        <a href="interaction.html" class="btn btn-neutral float-right" title="Interaction" accesskey="n" rel="next">Next <span class="fa fa-arrow-circle-right" aria-hidden="true"></span></a>
-        <a href="index.html" class="btn btn-neutral float-left" title="Welcome to discord.py-message-component’s documentation!" accesskey="p" rel="prev"><span class="fa fa-arrow-circle-left" aria-hidden="true"></span> Previous</a>
-    </div>
-
-  <hr/>
-
-  <div role="contentinfo">
-    <p>
-        &#169; Copyright 2021, Mathieu Corsham aka. mccoder.py.
-
-    </p>
-  </div>
-    
-    
-    
-    Built with <a href="https://www.sphinx-doc.org/">Sphinx</a> using a
-    
-    <a href="https://github.com/readthedocs/sphinx_rtd_theme">theme</a>
-    
-    provided by <a href="https://readthedocs.org">Read the Docs</a>. 
-
-</footer>
-        </div>
-      </div>
-
-    </section>
-
-  </div>
-  
-
-  <script type="text/javascript">
-      jQuery(function () {
-          SphinxRtdTheme.Navigation.enable(true);
-      });
-  </script>
-
-  
-  
-    
-   
-
-</body>
-</html>
\ No newline at end of file
diff --git a/docs/_build/html/genindex.html b/docs/_build/html/genindex.html
deleted file mode 100644
index cead788d..00000000
--- a/docs/_build/html/genindex.html
+++ /dev/null
@@ -1,211 +0,0 @@
-
-
-<!DOCTYPE html>
-<html class="writer-html5" lang="en" >
-<head>
-  <meta charset="utf-8" />
-  
-  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
-  
-  <title>Index &mdash; discord.py-message-components 1.7.5 documentation</title>
-  
-
-  
-  <link rel="stylesheet" href="_static/css/theme.css" type="text/css" />
-  <link rel="stylesheet" href="_static/pygments.css" type="text/css" />
-  <link rel="stylesheet" href="_static/pygments.css" type="text/css" />
-  <link rel="stylesheet" href="_static/css/theme.css" type="text/css" />
-
-  
-  
-
-  
-  
-
-  
-
-  
-  <!--[if lt IE 9]>
-    <script src="_static/js/html5shiv.min.js"></script>
-  <![endif]-->
-  
-    
-      <script type="text/javascript" id="documentation_options" data-url_root="./" src="_static/documentation_options.js"></script>
-        <script data-url_root="./" id="documentation_options" src="_static/documentation_options.js"></script>
-        <script src="_static/jquery.js"></script>
-        <script src="_static/underscore.js"></script>
-        <script src="_static/doctools.js"></script>
-    
-    <script type="text/javascript" src="_static/js/theme.js"></script>
-
-    
-    <link rel="index" title="Index" href="#" />
-    <link rel="search" title="Search" href="search.html" /> 
-</head>
-
-<body class="wy-body-for-nav">
-
-   
-  <div class="wy-grid-for-nav">
-    
-    <nav data-toggle="wy-nav-shift" class="wy-nav-side">
-      <div class="wy-side-scroll">
-        <div class="wy-side-nav-search" >
-          
-
-          
-            <a href="index.html" class="icon icon-home"> discord.py-message-components
-          
-
-          
-          </a>
-
-          
-            
-            
-          
-
-          
-<div role="search">
-  <form id="rtd-search-form" class="wy-form" action="search.html" method="get">
-    <input type="text" name="q" placeholder="Search docs" />
-    <input type="hidden" name="check_keywords" value="yes" />
-    <input type="hidden" name="area" value="default" />
-  </form>
-</div>
-
-          
-        </div>
-
-        
-        <div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="main navigation">
-          
-            
-            
-              
-            
-            
-              <p class="caption"><span class="caption-text">Contents:</span></p>
-<ul>
-<li class="toctree-l1"><a class="reference internal" href="components.html">Components</a></li>
-<li class="toctree-l1"><a class="reference internal" href="components.html#discord-buttoncolor"><code class="xref py py-class docutils literal notranslate"><span class="pre">discord.ButtonColor</span></code></a></li>
-<li class="toctree-l1"><a class="reference internal" href="components.html#discord-actionrow-args-kwargs"><code class="xref py py-class docutils literal notranslate"><span class="pre">discord.ActionRow(*args,</span> <span class="pre">**kwargs)</span></code></a></li>
-<li class="toctree-l1"><a class="reference internal" href="components.html#discord-button-kwargs"><code class="xref py py-class docutils literal notranslate"><span class="pre">discord.Button(**kwargs)</span></code></a></li>
-<li class="toctree-l1"><a class="reference internal" href="interaction.html">Interaction</a></li>
-</ul>
-
-            
-          
-        </div>
-        
-      </div>
-    </nav>
-
-    <section data-toggle="wy-nav-shift" class="wy-nav-content-wrap">
-
-      
-      <nav class="wy-nav-top" aria-label="top navigation">
-        
-          <i data-toggle="wy-nav-top" class="fa fa-bars"></i>
-          <a href="index.html">discord.py-message-components</a>
-        
-      </nav>
-
-
-      <div class="wy-nav-content">
-        
-        <div class="rst-content">
-        
-          
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-<div role="navigation" aria-label="breadcrumbs navigation">
-
-  <ul class="wy-breadcrumbs">
-    
-      <li><a href="index.html" class="icon icon-home"></a> &raquo;</li>
-        
-      <li>Index</li>
-    
-    
-      <li class="wy-breadcrumbs-aside">
-        
-          
-        
-      </li>
-    
-  </ul>
-
-  
-  <hr/>
-</div>
-          <div role="main" class="document" itemscope="itemscope" itemtype="http://schema.org/Article">
-           <div itemprop="articleBody">
-            
-
-<h1 id="index">Index</h1>
-
-<div class="genindex-jumpbox">
- 
-</div>
-
-
-           </div>
-           
-          </div>
-          <footer>
-
-  <hr/>
-
-  <div role="contentinfo">
-    <p>
-        &#169; Copyright 2021, Mathieu Corsham aka. mccoder.py.
-
-    </p>
-  </div>
-    
-    
-    
-    Built with <a href="https://www.sphinx-doc.org/">Sphinx</a> using a
-    
-    <a href="https://github.com/readthedocs/sphinx_rtd_theme">theme</a>
-    
-    provided by <a href="https://readthedocs.org">Read the Docs</a>. 
-
-</footer>
-        </div>
-      </div>
-
-    </section>
-
-  </div>
-  
-
-  <script type="text/javascript">
-      jQuery(function () {
-          SphinxRtdTheme.Navigation.enable(true);
-      });
-  </script>
-
-  
-  
-    
-   
-
-</body>
-</html>
\ No newline at end of file
diff --git a/docs/_build/html/index.html b/docs/_build/html/index.html
deleted file mode 100644
index 70d94f30..00000000
--- a/docs/_build/html/index.html
+++ /dev/null
@@ -1,364 +0,0 @@
-
-
-<!DOCTYPE html>
-<html class="writer-html5" lang="en" >
-<head>
-  <meta charset="utf-8" />
-  
-  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
-  
-  <title>Welcome to discord.py-message-component’s documentation! &mdash; discord.py-message-components 1.7.5 documentation</title>
-  
-
-  
-  <link rel="stylesheet" href="_static/css/theme.css" type="text/css" />
-  <link rel="stylesheet" href="_static/pygments.css" type="text/css" />
-  <link rel="stylesheet" href="_static/pygments.css" type="text/css" />
-  <link rel="stylesheet" href="_static/css/theme.css" type="text/css" />
-
-  
-  
-
-  
-  
-
-  
-
-  
-  <!--[if lt IE 9]>
-    <script src="_static/js/html5shiv.min.js"></script>
-  <![endif]-->
-  
-    
-      <script type="text/javascript" id="documentation_options" data-url_root="./" src="_static/documentation_options.js"></script>
-        <script data-url_root="./" id="documentation_options" src="_static/documentation_options.js"></script>
-        <script src="_static/jquery.js"></script>
-        <script src="_static/underscore.js"></script>
-        <script src="_static/doctools.js"></script>
-    
-    <script type="text/javascript" src="_static/js/theme.js"></script>
-
-    
-    <link rel="index" title="Index" href="genindex.html" />
-    <link rel="search" title="Search" href="search.html" />
-    <link rel="next" title="Components" href="components.html" /> 
-</head>
-
-<body class="wy-body-for-nav">
-
-   
-  <div class="wy-grid-for-nav">
-    
-    <nav data-toggle="wy-nav-shift" class="wy-nav-side">
-      <div class="wy-side-scroll">
-        <div class="wy-side-nav-search" >
-          
-
-          
-            <a href="#" class="icon icon-home"> discord.py-message-components
-          
-
-          
-          </a>
-
-          
-            
-            
-          
-
-          
-<div role="search">
-  <form id="rtd-search-form" class="wy-form" action="search.html" method="get">
-    <input type="text" name="q" placeholder="Search docs" />
-    <input type="hidden" name="check_keywords" value="yes" />
-    <input type="hidden" name="area" value="default" />
-  </form>
-</div>
-
-          
-        </div>
-
-        
-        <div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="main navigation">
-          
-            
-            
-              
-            
-            
-              <p class="caption"><span class="caption-text">Contents:</span></p>
-<ul>
-<li class="toctree-l1"><a class="reference internal" href="components.html">Components</a></li>
-<li class="toctree-l1"><a class="reference internal" href="components.html#discord-buttoncolor"><code class="xref py py-class docutils literal notranslate"><span class="pre">discord.ButtonColor</span></code></a></li>
-<li class="toctree-l1"><a class="reference internal" href="components.html#discord-actionrow-args-kwargs"><code class="xref py py-class docutils literal notranslate"><span class="pre">discord.ActionRow(*args,</span> <span class="pre">**kwargs)</span></code></a></li>
-<li class="toctree-l1"><a class="reference internal" href="components.html#discord-button-kwargs"><code class="xref py py-class docutils literal notranslate"><span class="pre">discord.Button(**kwargs)</span></code></a></li>
-<li class="toctree-l1"><a class="reference internal" href="interaction.html">Interaction</a></li>
-</ul>
-
-            
-          
-        </div>
-        
-      </div>
-    </nav>
-
-    <section data-toggle="wy-nav-shift" class="wy-nav-content-wrap">
-
-      
-      <nav class="wy-nav-top" aria-label="top navigation">
-        
-          <i data-toggle="wy-nav-top" class="fa fa-bars"></i>
-          <a href="#">discord.py-message-components</a>
-        
-      </nav>
-
-
-      <div class="wy-nav-content">
-        
-        <div class="rst-content">
-        
-          
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-<div role="navigation" aria-label="breadcrumbs navigation">
-
-  <ul class="wy-breadcrumbs">
-    
-      <li><a href="#" class="icon icon-home"></a> &raquo;</li>
-        
-      <li>Welcome to discord.py-message-component’s documentation!</li>
-    
-    
-      <li class="wy-breadcrumbs-aside">
-        
-          
-            <a href="_sources/index.rst.txt" rel="nofollow"> View page source</a>
-          
-        
-      </li>
-    
-  </ul>
-
-  
-  <hr/>
-</div>
-          <div role="main" class="document" itemscope="itemscope" itemtype="http://schema.org/Article">
-           <div itemprop="articleBody">
-            
-  <div class="section" id="welcome-to-discord-py-message-component-s-documentation">
-<h1>Welcome to discord.py-message-component’s documentation!<a class="headerlink" href="#welcome-to-discord-py-message-component-s-documentation" title="Permalink to this headline">¶</a></h1>
-<a class="reference external image-reference" href="https://pypi.org/project/discord.py-message-components"><img alt="Name of the project" src="https://cdn.discordapp.com/attachments/852872100073963532/854711446767796286/discord.py-message-components.png" /></a>
-<a class="reference external image-reference" href="https://discord.gg/sb69muSqsg"><img alt="Discord Server Invite" src="https://discord.com/api/guilds/852871920411475968/embed.png" /></a>
-<a class="reference external image-reference" href="https://pypi.python.org/pypi/discord.py-message-components"><img alt="PyPI version info" src="https://img.shields.io/pypi/v/discord.py-message-components.svg" /></a>
-<a class="reference external image-reference" href="https://pypi.python.org/pypi/discord.py-message-components"><img alt="PyPI supported Python versions" src="https://img.shields.io/pypi/pyversions/discord.py-message-components.svg" /></a>
-<a class="reference external image-reference" href="https://pepy.tech/project/discord.py-message-components"><img alt="Total downloads for the project" src="https://static.pepy.tech/personalized-badge/discord-py-message-components?period=total&amp;units=international_system&amp;left_color=grey&amp;right_color=green&amp;left_text=Downloads" /></a>
-<a class="reference external image-reference" href="https://discordpy-message-components.readthedocs.io/en/latest/"><img alt="Documentation Status" src="https://readthedocs.org/projects/discordpy-message-components/badge/?version=latest" /></a>
-<p>The Original <a class="reference external" href="https://pypi.org/project/discord.py">discord.py</a> Library made by <a class="reference external" href="https://github.com/Rapptz">Rapptz</a> with implementation of the <a class="reference external" href="https://discord.com/developers/docs/interactions/message-components">Discord-Message-Components</a> by <a class="reference external" href="https://github.com/mccoderpy/">mccoderpy</a></p>
-<ul class="simple">
-<li><p><a class="reference external" href="https://discordpy-message-components.readthedocs.io/en/latest/">read the docs</a></p></li>
-</ul>
-<div class="section" id="installing">
-<h2>Installing:<a class="headerlink" href="#installing" title="Permalink to this headline">¶</a></h2>
-<p><strong>Python 3.5.3 or higher is required</strong></p>
-<p>first uninstall the original <a class="reference external" href="https://pypi.org/project/discord.py">discord.py</a> Library:</p>
-<div class="highlight-sh notranslate"><div class="highlight"><pre><span></span><span class="c1"># Linux/macOS</span>
-python3 -m pip uninstall discord.py
-
-<span class="c1"># Windows</span>
-py -3 -m pip uninstall discord.py
-</pre></div>
-</div>
-<p>then install <a class="reference external" href="https://pypi.org/project/discord.py-message-components">this Library</a> using:</p>
-<div class="highlight-sh notranslate"><div class="highlight"><pre><span></span><span class="c1"># Linux/macOS</span>
-python3 -m pip install -U discord.py-message-components
-
-<span class="c1"># Windows</span>
-py -3 -m pip install -U discord.py-message-components
-</pre></div>
-</div>
-</div>
-<div class="section" id="quickstart">
-<h2>quickstart<a class="headerlink" href="#quickstart" title="Permalink to this headline">¶</a></h2>
-<div class="section" id="sending-buttons">
-<h3>sending-buttons<a class="headerlink" href="#sending-buttons" title="Permalink to this headline">¶</a></h3>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="kn">import</span> <span class="nn">discord</span>
-<span class="kn">from</span> <span class="nn">discord.ext</span> <span class="kn">import</span> <span class="n">commands</span>
-<span class="kn">from</span> <span class="nn">discord.components</span> <span class="kn">import</span> <span class="n">Button</span><span class="p">,</span> <span class="n">ButtonColor</span>
-
-
-<span class="n">client</span> <span class="o">=</span> <span class="n">commands</span><span class="o">.</span><span class="n">Bot</span><span class="p">(</span><span class="n">command_prefix</span><span class="o">=</span><span class="n">commands</span><span class="o">.</span><span class="n">when_mentioned_or</span><span class="p">(</span><span class="s1">&#39;!&#39;</span><span class="p">))</span>
-
-
-<span class="nd">@client</span><span class="o">.</span><span class="n">command</span><span class="p">()</span>
-<span class="k">async</span> <span class="k">def</span> <span class="nf">buttons</span><span class="p">(</span><span class="n">ctx</span><span class="p">):</span>
-   <span class="k">await</span> <span class="n">ctx</span><span class="o">.</span><span class="n">send</span><span class="p">(</span><span class="s1">&#39;Hey here are some Buttons&#39;</span><span class="p">,</span> <span class="n">components</span><span class="o">=</span><span class="p">[[</span>
-      <span class="n">Button</span><span class="p">(</span><span class="n">label</span><span class="o">=</span><span class="s2">&quot;Hey i</span><span class="se">\&#39;</span><span class="s2">m a red Button&quot;</span><span class="p">,</span>
-               <span class="n">custom_id</span><span class="o">=</span><span class="s2">&quot;this is an custom_id&quot;</span><span class="p">,</span>
-               <span class="n">style</span><span class="o">=</span><span class="n">ButtonColor</span><span class="o">.</span><span class="n">red</span><span class="p">),</span>
-      <span class="n">Button</span><span class="p">(</span><span class="n">label</span><span class="o">=</span><span class="s2">&quot;Hey i</span><span class="se">\&#39;</span><span class="s2">m a green Button&quot;</span><span class="p">,</span>
-               <span class="n">custom_id</span><span class="o">=</span><span class="s2">&quot;this is an custom_id&quot;</span><span class="p">,</span>
-               <span class="n">style</span><span class="o">=</span><span class="n">ButtonColor</span><span class="o">.</span><span class="n">green</span><span class="p">),</span>
-      <span class="n">Button</span><span class="p">(</span><span class="n">label</span><span class="o">=</span><span class="s2">&quot;Hey i</span><span class="se">\&#39;</span><span class="s2">m a blue Button&quot;</span><span class="p">,</span>
-               <span class="n">custom_id</span><span class="o">=</span><span class="s2">&quot;this is an custom_id&quot;</span><span class="p">,</span>
-               <span class="n">style</span><span class="o">=</span><span class="n">ButtonColor</span><span class="o">.</span><span class="n">blurple</span><span class="p">),</span>
-      <span class="n">Button</span><span class="p">(</span><span class="n">label</span><span class="o">=</span><span class="s2">&quot;Hey i</span><span class="se">\&#39;</span><span class="s2">m a grey Button&quot;</span><span class="p">,</span>
-               <span class="n">custom_id</span><span class="o">=</span><span class="s2">&quot;this is an custom_id&quot;</span><span class="p">,</span>
-               <span class="n">style</span><span class="o">=</span><span class="n">ButtonColor</span><span class="o">.</span><span class="n">grey</span><span class="p">),</span>
-      <span class="n">Button</span><span class="p">(</span><span class="n">label</span><span class="o">=</span><span class="s2">&quot;Hey i</span><span class="se">\&#39;</span><span class="s2">m a URL Button&quot;</span><span class="p">,</span>
-               <span class="n">url</span><span class="o">=</span><span class="s2">&quot;https://pypi.org/project/discord.py-message-components&quot;</span><span class="p">,</span>
-               <span class="n">style</span><span class="o">=</span><span class="n">ButtonColor</span><span class="o">.</span><span class="n">grey_url</span><span class="p">)</span>
-   <span class="p">]])</span>
-
-<span class="n">client</span><span class="o">.</span><span class="n">run</span><span class="p">(</span><span class="s1">&#39;Your Bot-Token&#39;</span><span class="p">)</span>
-</pre></div>
-</div>
-</div>
-<div class="section" id="respond-to-an-button-when-he-pressed-by-a-user">
-<h3>respond to an button when he pressed by a user<a class="headerlink" href="#respond-to-an-button-when-he-pressed-by-a-user" title="Permalink to this headline">¶</a></h3>
-<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="kn">import</span> <span class="nn">discord</span>
-<span class="kn">from</span> <span class="nn">discord.ext</span> <span class="kn">import</span> <span class="n">commands</span>
-<span class="kn">from</span> <span class="nn">discord.components</span> <span class="kn">import</span> <span class="n">Button</span><span class="p">,</span> <span class="n">ButtonColor</span>
-
-
-<span class="n">client</span> <span class="o">=</span> <span class="n">commands</span><span class="o">.</span><span class="n">Bot</span><span class="p">(</span><span class="n">command_prefix</span><span class="o">=</span><span class="n">commands</span><span class="o">.</span><span class="n">when_mentioned_or</span><span class="p">(</span><span class="s1">&#39;!&#39;</span><span class="p">))</span>
-
-
-<span class="nd">@client</span><span class="o">.</span><span class="n">command</span><span class="p">()</span>
-<span class="k">async</span> <span class="k">def</span> <span class="nf">buttons</span><span class="p">(</span><span class="n">ctx</span><span class="p">):</span>
-   <span class="n">msg_with_buttons</span> <span class="o">=</span> <span class="k">await</span> <span class="n">ctx</span><span class="o">.</span><span class="n">send</span><span class="p">(</span><span class="s1">&#39;Hey here are some Buttons&#39;</span><span class="p">,</span> <span class="n">components</span><span class="o">=</span><span class="p">[[</span>
-       <span class="n">Button</span><span class="p">(</span><span class="n">label</span><span class="o">=</span><span class="s2">&quot;Hey i</span><span class="se">\&#39;</span><span class="s2">m a red Button&quot;</span><span class="p">,</span>
-              <span class="n">custom_id</span><span class="o">=</span><span class="s2">&quot;red&quot;</span><span class="p">,</span>
-              <span class="n">style</span><span class="o">=</span><span class="n">ButtonColor</span><span class="o">.</span><span class="n">red</span><span class="p">),</span>
-       <span class="n">Button</span><span class="p">(</span><span class="n">label</span><span class="o">=</span><span class="s2">&quot;Hey i</span><span class="se">\&#39;</span><span class="s2">m a green Button&quot;</span><span class="p">,</span>
-              <span class="n">custom_id</span><span class="o">=</span><span class="s2">&quot;green&quot;</span><span class="p">,</span>
-              <span class="n">style</span><span class="o">=</span><span class="n">ButtonColor</span><span class="o">.</span><span class="n">green</span><span class="p">),</span>
-       <span class="n">Button</span><span class="p">(</span><span class="n">label</span><span class="o">=</span><span class="s2">&quot;Hey i</span><span class="se">\&#39;</span><span class="s2">m a blue Button&quot;</span><span class="p">,</span>
-              <span class="n">custom_id</span><span class="o">=</span><span class="s2">&quot;blue&quot;</span><span class="p">,</span>
-              <span class="n">style</span><span class="o">=</span><span class="n">ButtonColor</span><span class="o">.</span><span class="n">blurple</span><span class="p">),</span>
-       <span class="n">Button</span><span class="p">(</span><span class="n">label</span><span class="o">=</span><span class="s2">&quot;Hey i</span><span class="se">\&#39;</span><span class="s2">m a grey Button&quot;</span><span class="p">,</span>
-              <span class="n">custom_id</span><span class="o">=</span><span class="s2">&quot;grey&quot;</span><span class="p">,</span>
-              <span class="n">style</span><span class="o">=</span><span class="n">ButtonColor</span><span class="o">.</span><span class="n">grey</span><span class="p">)</span>
-   <span class="p">]])</span>
-
-   <span class="k">def</span> <span class="nf">check_button</span><span class="p">(</span><span class="n">i</span><span class="p">:</span> <span class="n">discord</span><span class="o">.</span><span class="n">Interaction</span><span class="p">,</span> <span class="n">b</span><span class="p">:</span> <span class="n">discord</span><span class="o">.</span><span class="n">ButtonClick</span><span class="p">):</span>
-       <span class="k">return</span> <span class="n">i</span><span class="o">.</span><span class="n">author</span> <span class="o">==</span> <span class="n">ctx</span><span class="o">.</span><span class="n">author</span> <span class="ow">and</span> <span class="n">i</span><span class="o">.</span><span class="n">message</span> <span class="o">==</span> <span class="n">msg_with_buttons</span>
-
-   <span class="n">interaction</span><span class="p">,</span> <span class="n">button</span> <span class="o">=</span> <span class="k">await</span> <span class="n">client</span><span class="o">.</span><span class="n">wait_for</span><span class="p">(</span><span class="s1">&#39;button_click&#39;</span><span class="p">,</span> <span class="n">check</span><span class="o">=</span><span class="n">check_button</span><span class="p">)</span>
-
-   <span class="n">embed</span> <span class="o">=</span> <span class="n">discord</span><span class="o">.</span><span class="n">Embed</span><span class="p">(</span><span class="n">title</span><span class="o">=</span><span class="s1">&#39;You pressed an Button&#39;</span><span class="p">,</span>
-   <span class="n">description</span><span class="o">=</span><span class="sa">f</span><span class="s1">&#39;You pressed a </span><span class="si">{</span><span class="n">button</span><span class="o">.</span><span class="n">custom_id</span><span class="si">}</span><span class="s1"> button.&#39;</span><span class="p">,</span>
-   <span class="n">color</span><span class="o">=</span><span class="n">discord</span><span class="o">.</span><span class="n">Color</span><span class="o">.</span><span class="n">random</span><span class="p">())</span>
-   <span class="k">await</span> <span class="n">interaction</span><span class="o">.</span><span class="n">respond</span><span class="p">(</span><span class="n">embed</span><span class="o">=</span><span class="n">embed</span><span class="p">)</span>
-
-<span class="n">client</span><span class="o">.</span><span class="n">run</span><span class="p">(</span><span class="s1">&#39;Your Bot-Token&#39;</span><span class="p">)</span>
-</pre></div>
-</div>
-<div class="admonition note">
-<p class="admonition-title">Note</p>
-<p>You could set the parameter <code class="xref py py-attr docutils literal notranslate"><span class="pre">hidden</span></code> in the respond to <code class="docutils literal notranslate"><span class="pre">True</span></code> to make the message ephemeral.
-Visit <a class="reference external" href="./interaction.html#interaction-respond">discord.Interaction.respond</a> for more information about <code class="xref py py-meth docutils literal notranslate"><span class="pre">respond()</span></code>.</p>
-</div>
-<div class="toctree-wrapper compound">
-<p class="caption"><span class="caption-text">Contents:</span></p>
-<ul>
-<li class="toctree-l1"><a class="reference internal" href="components.html">Components</a></li>
-<li class="toctree-l1"><a class="reference internal" href="components.html#discord-buttoncolor"><code class="xref py py-class docutils literal notranslate"><span class="pre">discord.ButtonColor</span></code></a></li>
-<li class="toctree-l1"><a class="reference internal" href="components.html#discord-actionrow-args-kwargs"><code class="xref py py-class docutils literal notranslate"><span class="pre">discord.ActionRow(*args,</span> <span class="pre">**kwargs)</span></code></a><ul>
-<li class="toctree-l2"><a class="reference internal" href="components.html#attributes">Attributes</a></li>
-<li class="toctree-l2"><a class="reference internal" href="components.html#methodes">Methodes</a></li>
-</ul>
-</li>
-<li class="toctree-l1"><a class="reference internal" href="components.html#discord-button-kwargs"><code class="xref py py-class docutils literal notranslate"><span class="pre">discord.Button(**kwargs)</span></code></a><ul>
-<li class="toctree-l2"><a class="reference internal" href="components.html#button-attributes">Attributes</a></li>
-<li class="toctree-l2"><a class="reference internal" href="components.html#button-methodes">Methodes</a><ul>
-<li class="toctree-l3"><a class="reference internal" href="components.html#indices-and-tables">Indices and tables</a></li>
-</ul>
-</li>
-</ul>
-</li>
-<li class="toctree-l1"><a class="reference internal" href="interaction.html">Interaction</a><ul>
-<li class="toctree-l2"><a class="reference internal" href="interaction.html#discord-interaction"><code class="xref py py-class docutils literal notranslate"><span class="pre">discord.Interaction</span></code></a><ul>
-<li class="toctree-l3"><a class="reference internal" href="interaction.html#attributes">Attributes</a></li>
-<li class="toctree-l3"><a class="reference internal" href="interaction.html#methodes">Methodes</a></li>
-</ul>
-</li>
-<li class="toctree-l2"><a class="reference internal" href="interaction.html#indices-and-tables">Indices and tables</a></li>
-</ul>
-</li>
-</ul>
-</div>
-</div>
-</div>
-<div class="section" id="indices-and-tables">
-<h2>Indices and tables<a class="headerlink" href="#indices-and-tables" title="Permalink to this headline">¶</a></h2>
-<ul class="simple">
-<li><p><a class="reference internal" href="genindex.html"><span class="std std-ref">Index</span></a></p></li>
-<li><p><a class="reference internal" href="py-modindex.html"><span class="std std-ref">Module Index</span></a></p></li>
-<li><p><a class="reference internal" href="search.html"><span class="std std-ref">Search Page</span></a></p></li>
-</ul>
-</div>
-</div>
-
-
-           </div>
-           
-          </div>
-          <footer>
-    <div class="rst-footer-buttons" role="navigation" aria-label="footer navigation">
-        <a href="components.html" class="btn btn-neutral float-right" title="Components" accesskey="n" rel="next">Next <span class="fa fa-arrow-circle-right" aria-hidden="true"></span></a>
-    </div>
-
-  <hr/>
-
-  <div role="contentinfo">
-    <p>
-        &#169; Copyright 2021, Mathieu Corsham aka. mccoder.py.
-
-    </p>
-  </div>
-    
-    
-    
-    Built with <a href="https://www.sphinx-doc.org/">Sphinx</a> using a
-    
-    <a href="https://github.com/readthedocs/sphinx_rtd_theme">theme</a>
-    
-    provided by <a href="https://readthedocs.org">Read the Docs</a>. 
-
-</footer>
-        </div>
-      </div>
-
-    </section>
-
-  </div>
-  
-
-  <script type="text/javascript">
-      jQuery(function () {
-          SphinxRtdTheme.Navigation.enable(true);
-      });
-  </script>
-
-  
-  
-    
-   
-
-</body>
-</html>
\ No newline at end of file
diff --git a/docs/_build/html/interaction.html b/docs/_build/html/interaction.html
deleted file mode 100644
index 79cc8898..00000000
--- a/docs/_build/html/interaction.html
+++ /dev/null
@@ -1,326 +0,0 @@
-
-
-<!DOCTYPE html>
-<html class="writer-html5" lang="en" >
-<head>
-  <meta charset="utf-8" />
-  
-  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
-  
-  <title>Interaction &mdash; discord.py-message-components 1.7.5 documentation</title>
-  
-
-  
-  <link rel="stylesheet" href="_static/css/theme.css" type="text/css" />
-  <link rel="stylesheet" href="_static/pygments.css" type="text/css" />
-  <link rel="stylesheet" href="_static/pygments.css" type="text/css" />
-  <link rel="stylesheet" href="_static/css/theme.css" type="text/css" />
-
-  
-  
-
-  
-  
-
-  
-
-  
-  <!--[if lt IE 9]>
-    <script src="_static/js/html5shiv.min.js"></script>
-  <![endif]-->
-  
-    
-      <script type="text/javascript" id="documentation_options" data-url_root="./" src="_static/documentation_options.js"></script>
-        <script data-url_root="./" id="documentation_options" src="_static/documentation_options.js"></script>
-        <script src="_static/jquery.js"></script>
-        <script src="_static/underscore.js"></script>
-        <script src="_static/doctools.js"></script>
-    
-    <script type="text/javascript" src="_static/js/theme.js"></script>
-
-    
-    <link rel="index" title="Index" href="genindex.html" />
-    <link rel="search" title="Search" href="search.html" />
-    <link rel="prev" title="Components" href="components.html" /> 
-</head>
-
-<body class="wy-body-for-nav">
-
-   
-  <div class="wy-grid-for-nav">
-    
-    <nav data-toggle="wy-nav-shift" class="wy-nav-side">
-      <div class="wy-side-scroll">
-        <div class="wy-side-nav-search" >
-          
-
-          
-            <a href="index.html" class="icon icon-home"> discord.py-message-components
-          
-
-          
-          </a>
-
-          
-            
-            
-          
-
-          
-<div role="search">
-  <form id="rtd-search-form" class="wy-form" action="search.html" method="get">
-    <input type="text" name="q" placeholder="Search docs" />
-    <input type="hidden" name="check_keywords" value="yes" />
-    <input type="hidden" name="area" value="default" />
-  </form>
-</div>
-
-          
-        </div>
-
-        
-        <div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="main navigation">
-          
-            
-            
-              
-            
-            
-              <p class="caption"><span class="caption-text">Contents:</span></p>
-<ul class="current">
-<li class="toctree-l1"><a class="reference internal" href="components.html">Components</a></li>
-<li class="toctree-l1 current"><a class="current reference internal" href="#">Interaction</a><ul>
-<li class="toctree-l2"><a class="reference internal" href="#discord-interaction"><code class="xref py py-class docutils literal notranslate"><span class="pre">discord.Interaction</span></code></a><ul>
-<li class="toctree-l3"><a class="reference internal" href="#attributes">Attributes</a></li>
-<li class="toctree-l3"><a class="reference internal" href="#methodes">Methodes</a><ul class="simple">
-</ul>
-</li>
-</ul>
-</li>
-<li class="toctree-l2"><a class="reference internal" href="#indices-and-tables">Indices and tables</a></li>
-</ul>
-</li>
-</ul>
-
-            
-          
-        </div>
-        
-      </div>
-    </nav>
-
-    <section data-toggle="wy-nav-shift" class="wy-nav-content-wrap">
-
-      
-      <nav class="wy-nav-top" aria-label="top navigation">
-        
-          <i data-toggle="wy-nav-top" class="fa fa-bars"></i>
-          <a href="index.html">discord.py-message-components</a>
-        
-      </nav>
-
-
-      <div class="wy-nav-content">
-        
-        <div class="rst-content">
-        
-          
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-<div role="navigation" aria-label="breadcrumbs navigation">
-
-  <ul class="wy-breadcrumbs">
-    
-      <li><a href="index.html" class="icon icon-home"></a> &raquo;</li>
-        
-      <li>Interaction</li>
-    
-    
-      <li class="wy-breadcrumbs-aside">
-        
-          
-            <a href="_sources/interaction.rst.txt" rel="nofollow"> View page source</a>
-          
-        
-      </li>
-    
-  </ul>
-
-  
-  <hr/>
-</div>
-          <div role="main" class="document" itemscope="itemscope" itemtype="http://schema.org/Article">
-           <div itemprop="articleBody">
-            
-  <div class="section" id="interaction">
-<h1>Interaction<a class="headerlink" href="#interaction" title="Permalink to this headline">¶</a></h1>
-<p><a class="reference internal" href="#interaction-respond"><span class="std std-ref">Hallo</span></a></p>
-<div class="section" id="discord-interaction">
-<h2><code class="xref py py-class docutils literal notranslate"><span class="pre">discord.Interaction</span></code><a class="headerlink" href="#discord-interaction" title="Permalink to this headline">¶</a></h2>
-<p>Represents an interaction createt in discord like click an <code class="xref py py-class docutils literal notranslate"><span class="pre">discord.Button</span></code> or select an option of <code class="xref py py-class docutils literal notranslate"><span class="pre">discord.SelectionMenu</span></code></p>
-<div class="admonition note">
-<p class="admonition-title">Note</p>
-<p>For more informations about Interactions visit the Documentation of the <a class="reference external" href="https://discord.com/developers/docs/interactions/slash-commands#interaction-object">Discord-API</a></p>
-</div>
-<div class="admonition warning">
-<p class="admonition-title">Warning</p>
-<p>Do not initiate this Class manually</p>
-</div>
-<div class="section" id="attributes">
-<h3>Attributes<a class="headerlink" href="#attributes" title="Permalink to this headline">¶</a></h3>
-<blockquote>
-<div><dl class="simple" id="interaction-author">
-<dt><code class="xref py py-attr docutils literal notranslate"><span class="pre">author</span></code>: <code class="xref py py-class docutils literal notranslate"><span class="pre">discord.abc.User</span></code></dt><dd><p>A <code class="xref py py-class docutils literal notranslate"><span class="pre">Member</span></code> that invoked the interaction. If <code class="xref py py-attr docutils literal notranslate"><span class="pre">channel</span></code> is a
-private channel or the user has left the guild, then it is a <code class="xref py py-class docutils literal notranslate"><span class="pre">User</span></code> instead.</p>
-</dd>
-</dl>
-<dl id="interaction-message">
-<dt><code class="xref py py-attr docutils literal notranslate"><span class="pre">message</span></code>: <code class="xref py py-class docutils literal notranslate"><span class="pre">discord.Message</span></code></dt><dd><p>The message the component was attachet to.
-This will be equal to <code class="docutils literal notranslate"><span class="pre">None</span></code> if the <code class="xref py py-attr docutils literal notranslate"><span class="pre">component_type</span></code> is <code class="docutils literal notranslate"><span class="pre">None</span></code> or the message the component is attached to is <code class="docutils literal notranslate"><span class="pre">emphemberal</span></code>.</p>
-<div class="admonition note">
-<p class="admonition-title">Note</p>
-<p>In this version, this parameter should alwasys be an object of type <code class="xref py py-class docutils literal notranslate"><span class="pre">discord.Message</span></code>
-(or <code class="docutils literal notranslate"><span class="pre">None</span></code> if the message is emphemberal) beacuse it only gets initiatet when the interaction_type is highter than 2</p>
-</div>
-</dd>
-</dl>
-<dl class="simple" id="interaction-channel">
-<dt><code class="xref py py-attr docutils literal notranslate"><span class="pre">channel</span></code>: Union[<code class="xref py py-class docutils literal notranslate"><span class="pre">discord.TextChannel</span></code>, <code class="xref py py-class docutils literal notranslate"><span class="pre">discord.DMChannel</span></code>]</dt><dd><p>The Channel the interaction was createt in this is aiter an object of <code class="xref py py-class docutils literal notranslate"><span class="pre">discord.TextChannel</span></code> if it’s
-inside a guild else it’s an object of type <code class="xref py py-class docutils literal notranslate"><span class="pre">discord.DMChannel</span></code>.</p>
-</dd>
-</dl>
-<dl class="simple" id="interaction-guild">
-<dt><code class="xref py py-attr docutils literal notranslate"><span class="pre">guild</span></code>: Union[<code class="xref py py-class docutils literal notranslate"><span class="pre">discord.Guild</span></code>, <code class="xref py py-class docutils literal notranslate"><span class="pre">None</span></code>]</dt><dd><p>The guild asotiatet with the interaction; aiter an object of type <code class="xref py py-class docutils literal notranslate"><span class="pre">discord.Guild</span></code>,
-except the interaction was inside an dm-channel then this would be equal to <code class="docutils literal notranslate"><span class="pre">None</span></code></p>
-</dd>
-</dl>
-<dl id="interaction-component">
-<dt><code class="xref py py-attr docutils literal notranslate"><span class="pre">component</span></code>: Union[<code class="xref py py-class docutils literal notranslate"><span class="pre">ButtonClick</span></code>, <code class="xref py py-class docutils literal notranslate"><span class="pre">SelectionSelect</span></code>]</dt><dd><p>The component that invoked this interaction: Aiter an object of type <code class="xref py py-class docutils literal notranslate"><span class="pre">ButtonClick</span></code> or <code class="xref py py-class docutils literal notranslate"><span class="pre">SelectionSelect</span></code></p>
-<div class="admonition note">
-<p class="admonition-title">Note</p>
-<p>If this is passed in an <code class="docutils literal notranslate"><span class="pre">[on_]button_click</span></code> or <code class="docutils literal notranslate"><span class="pre">[on_]selection_select</span></code> Event there wuild be a second parameter that includes this attribute.</p>
-</div>
-</dd>
-</dl>
-</div></blockquote>
-</div>
-<div class="section" id="methodes">
-<h3>Methodes<a class="headerlink" href="#methodes" title="Permalink to this headline">¶</a></h3>
-<blockquote>
-<div><dl id="interaction-defer">
-<dt><code class="xref py py-meth docutils literal notranslate"><span class="pre">defer()</span></code>: None</dt><dd><p>‘Defers’ the response, showing a loading state to the use.</p>
-<div class="admonition important">
-<p class="admonition-title">Important</p>
-<p>If you dont respond with an message using <code class="xref py py-meth docutils literal notranslate"><span class="pre">respond()</span></code>
-or edit the original message using <code class="xref py py-meth docutils literal notranslate"><span class="pre">edit()</span></code> within less than 3 seconds,
-discord will indicates that the interaction failed and the interaction-token will be invalidated.
-To provide this us this method</p>
-</div>
-<div class="admonition note">
-<p class="admonition-title">Note</p>
-<p>A Token will be Valid for 15 Minutes so you could edit the original <code class="xref py py-attr docutils literal notranslate"><span class="pre">message</span></code> with <code class="xref py py-meth docutils literal notranslate"><span class="pre">edit()</span></code>, <code class="xref py py-meth docutils literal notranslate"><span class="pre">respond()</span></code> or doing anything other with this interaction for 15 minutes.
-After that time you have to edit the original message with the Methode <code class="xref py py-meth docutils literal notranslate"><span class="pre">edit()</span></code> of the <code class="xref py py-attr docutils literal notranslate"><span class="pre">message</span></code> and sending new messages with the <code class="xref py py-meth docutils literal notranslate"><span class="pre">send()</span></code> Methode of <code class="xref py py-attr docutils literal notranslate"><span class="pre">channel</span></code>
-(you could not do this hidden as it isn’t an respond anymore and also you could not pass more than one <code class="xref py py-class docutils literal notranslate"><span class="pre">Embed</span></code>)</p>
-</div>
-</dd>
-</dl>
-<dl id="interaction-respond">
-<dt><code class="xref py py-meth docutils literal notranslate"><span class="pre">respond()</span></code>: Union[<code class="xref py py-class docutils literal notranslate"><span class="pre">discord.Message</span></code>, <code class="xref py py-class docutils literal notranslate"><span class="pre">discord.EphemeralMessage</span></code>]</dt><dd><p>You could pass the same Paramerts as using <code class="xref py py-meth docutils literal notranslate"><span class="pre">discord.Messageable.send()</span></code> but there are two more optional:</p>
-<ul>
-<li><dl class="simple">
-<dt><code class="xref py py-attr docutils literal notranslate"><span class="pre">embeds</span></code> Optional[List[discord.Embed]]</dt><dd><p>An <code class="xref py py-class docutils literal notranslate"><span class="pre">list</span></code> containing up to 10 Embeds that should send with the respond.</p>
-</dd>
-</dl>
-</li>
-<li><dl>
-<dt><code class="xref py py-attr docutils literal notranslate"><span class="pre">hidden</span></code> Optional[Bool]</dt><dd><p>If set to <code class="docutils literal notranslate"><span class="pre">True</span></code>, the message will be only vible for the <code class="xref py py-attr docutils literal notranslate"><span class="pre">author</span></code> of the Interaction and will disapears  if the <code class="xref py py-attr docutils literal notranslate"><span class="pre">author</span></code> click on <code class="docutils literal notranslate"><span class="pre">delete</span> <span class="pre">this</span> <span class="pre">message</span></code> or reloads the client.</p>
-<div class="admonition note">
-<p class="admonition-title">Note</p>
-<p>If you send an <code class="docutils literal notranslate"><span class="pre">hidden</span></code> (emphemberal)-respond, discord dont returns any data like an message you could edit,
-<strong>but</strong> you could resive Interactions when the Author interact with an component</p>
-</div>
-</dd>
-</dl>
-</li>
-</ul>
-<p>Responds to an interaction by sending a message that can be made visible only to the person who invoked the interaction by setting the <code class="xref py py-attr docutils literal notranslate"><span class="pre">hidden</span></code> to <code class="docutils literal notranslate"><span class="pre">True</span></code>.</p>
-</dd>
-</dl>
-</div></blockquote>
-<div class="toctree-wrapper compound">
-</div>
-</div>
-</div>
-<div class="section" id="indices-and-tables">
-<h2>Indices and tables<a class="headerlink" href="#indices-and-tables" title="Permalink to this headline">¶</a></h2>
-<ul class="simple">
-<li><p><a class="reference internal" href="genindex.html"><span class="std std-ref">Index</span></a></p></li>
-<li><p><a class="reference internal" href="py-modindex.html"><span class="std std-ref">Module Index</span></a></p></li>
-<li><p><a class="reference internal" href="search.html"><span class="std std-ref">Search Page</span></a></p></li>
-</ul>
-</div>
-</div>
-
-
-           </div>
-           
-          </div>
-          <footer>
-    <div class="rst-footer-buttons" role="navigation" aria-label="footer navigation">
-        <a href="components.html" class="btn btn-neutral float-left" title="Components" accesskey="p" rel="prev"><span class="fa fa-arrow-circle-left" aria-hidden="true"></span> Previous</a>
-    </div>
-
-  <hr/>
-
-  <div role="contentinfo">
-    <p>
-        &#169; Copyright 2021, Mathieu Corsham aka. mccoder.py.
-
-    </p>
-  </div>
-    
-    
-    
-    Built with <a href="https://www.sphinx-doc.org/">Sphinx</a> using a
-    
-    <a href="https://github.com/readthedocs/sphinx_rtd_theme">theme</a>
-    
-    provided by <a href="https://readthedocs.org">Read the Docs</a>. 
-
-</footer>
-        </div>
-      </div>
-
-    </section>
-
-  </div>
-  
-
-  <script type="text/javascript">
-      jQuery(function () {
-          SphinxRtdTheme.Navigation.enable(true);
-      });
-  </script>
-
-  
-  
-    
-   
-
-</body>
-</html>
\ No newline at end of file
diff --git a/docs/_build/html/objects.inv b/docs/_build/html/objects.inv
deleted file mode 100644
index e128315e..00000000
--- a/docs/_build/html/objects.inv
+++ /dev/null
@@ -1,5 +0,0 @@
-# Sphinx inventory version 2
-# Project: discord.py-message-components
-# Version: 
-# The remainder of this file is compressed using zlib.
-xڥ��N�0��<��X�J'�J��kߦǷ��n��Ǔ��I��I`K��ݿs͸��
�u�A�5(B�	�|��������
�r4b6��g�O��d��L�����6aM,ʜ3r]8�}a筲��\l� eJ��Ρ����
J/�N��ѩ��	6h8�u�rp[��ZֺjA����t�ء?V���ـ��֚�u��R\F#5���ֹ>�by�'>C�E!�79X4Cգ}�9.����hD���0|qha7V��i�I����ϰd��'h�|�ɚ� *?�����Q���9�8l���;ֲh�����O��a���a�����qSD{�e(+��'�:���v!�eZ��Y?��1����f�Tb$S�{$e������Q�ٕ���"8�DQ�g��sۃ��H����g�y	�+�u�}�L
\ No newline at end of file
diff --git a/docs/_build/html/search.html b/docs/_build/html/search.html
deleted file mode 100644
index 20d1a053..00000000
--- a/docs/_build/html/search.html
+++ /dev/null
@@ -1,224 +0,0 @@
-
-
-<!DOCTYPE html>
-<html class="writer-html5" lang="en" >
-<head>
-  <meta charset="utf-8" />
-  
-  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
-  
-  <title>Search &mdash; discord.py-message-components 1.7.5 documentation</title>
-  
-
-  
-  <link rel="stylesheet" href="_static/css/theme.css" type="text/css" />
-  <link rel="stylesheet" href="_static/pygments.css" type="text/css" />
-  <link rel="stylesheet" href="_static/pygments.css" type="text/css" />
-  <link rel="stylesheet" href="_static/css/theme.css" type="text/css" />
-
-  
-  
-
-  
-  
-
-  
-
-  
-    
-  <!--[if lt IE 9]>
-    <script src="_static/js/html5shiv.min.js"></script>
-  <![endif]-->
-  
-    
-      <script type="text/javascript" id="documentation_options" data-url_root="./" src="_static/documentation_options.js"></script>
-        <script data-url_root="./" id="documentation_options" src="_static/documentation_options.js"></script>
-        <script src="_static/jquery.js"></script>
-        <script src="_static/underscore.js"></script>
-        <script src="_static/doctools.js"></script>
-    
-    <script type="text/javascript" src="_static/js/theme.js"></script>
-
-    
-    <script type="text/javascript" src="_static/searchtools.js"></script>
-    <script type="text/javascript" src="_static/language_data.js"></script>
-    <link rel="index" title="Index" href="genindex.html" />
-    <link rel="search" title="Search" href="#" /> 
-</head>
-
-<body class="wy-body-for-nav">
-
-   
-  <div class="wy-grid-for-nav">
-    
-    <nav data-toggle="wy-nav-shift" class="wy-nav-side">
-      <div class="wy-side-scroll">
-        <div class="wy-side-nav-search" >
-          
-
-          
-            <a href="index.html" class="icon icon-home"> discord.py-message-components
-          
-
-          
-          </a>
-
-          
-            
-            
-          
-
-          
-<div role="search">
-  <form id="rtd-search-form" class="wy-form" action="#" method="get">
-    <input type="text" name="q" placeholder="Search docs" />
-    <input type="hidden" name="check_keywords" value="yes" />
-    <input type="hidden" name="area" value="default" />
-  </form>
-</div>
-
-          
-        </div>
-
-        
-        <div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="main navigation">
-          
-            
-            
-              
-            
-            
-              <p class="caption"><span class="caption-text">Contents:</span></p>
-<ul>
-<li class="toctree-l1"><a class="reference internal" href="components.html">Components</a></li>
-<li class="toctree-l1"><a class="reference internal" href="components.html#discord-buttoncolor"><code class="xref py py-class docutils literal notranslate"><span class="pre">discord.ButtonColor</span></code></a></li>
-<li class="toctree-l1"><a class="reference internal" href="components.html#discord-actionrow-args-kwargs"><code class="xref py py-class docutils literal notranslate"><span class="pre">discord.ActionRow(*args,</span> <span class="pre">**kwargs)</span></code></a></li>
-<li class="toctree-l1"><a class="reference internal" href="components.html#discord-button-kwargs"><code class="xref py py-class docutils literal notranslate"><span class="pre">discord.Button(**kwargs)</span></code></a></li>
-<li class="toctree-l1"><a class="reference internal" href="interaction.html">Interaction</a></li>
-</ul>
-
-            
-          
-        </div>
-        
-      </div>
-    </nav>
-
-    <section data-toggle="wy-nav-shift" class="wy-nav-content-wrap">
-
-      
-      <nav class="wy-nav-top" aria-label="top navigation">
-        
-          <i data-toggle="wy-nav-top" class="fa fa-bars"></i>
-          <a href="index.html">discord.py-message-components</a>
-        
-      </nav>
-
-
-      <div class="wy-nav-content">
-        
-        <div class="rst-content">
-        
-          
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-<div role="navigation" aria-label="breadcrumbs navigation">
-
-  <ul class="wy-breadcrumbs">
-    
-      <li><a href="index.html" class="icon icon-home"></a> &raquo;</li>
-        
-      <li>Search</li>
-    
-    
-      <li class="wy-breadcrumbs-aside">
-        
-      </li>
-    
-  </ul>
-
-  
-  <hr/>
-</div>
-          <div role="main" class="document" itemscope="itemscope" itemtype="http://schema.org/Article">
-           <div itemprop="articleBody">
-            
-  <noscript>
-  <div id="fallback" class="admonition warning">
-    <p class="last">
-      Please activate JavaScript to enable the search functionality.
-    </p>
-  </div>
-  </noscript>
-
-  
-  <div id="search-results">
-  
-  </div>
-
-           </div>
-           
-          </div>
-          <footer>
-
-  <hr/>
-
-  <div role="contentinfo">
-    <p>
-        &#169; Copyright 2021, Mathieu Corsham aka. mccoder.py.
-
-    </p>
-  </div>
-    
-    
-    
-    Built with <a href="https://www.sphinx-doc.org/">Sphinx</a> using a
-    
-    <a href="https://github.com/readthedocs/sphinx_rtd_theme">theme</a>
-    
-    provided by <a href="https://readthedocs.org">Read the Docs</a>. 
-
-</footer>
-        </div>
-      </div>
-
-    </section>
-
-  </div>
-  
-
-  <script type="text/javascript">
-      jQuery(function () {
-          SphinxRtdTheme.Navigation.enable(true);
-      });
-  </script>
-
-  
-  
-    
-  
-  <script type="text/javascript">
-    jQuery(function() { Search.loadIndex("searchindex.js"); });
-  </script>
-  
-  <script type="text/javascript" id="searchindexloader"></script>
-   
-
-
-</body>
-</html>
\ No newline at end of file
diff --git a/docs/_build/html/searchindex.js b/docs/_build/html/searchindex.js
deleted file mode 100644
index 0d2d0057..00000000
--- a/docs/_build/html/searchindex.js
+++ /dev/null
@@ -1 +0,0 @@
-Search.setIndex({docnames:["components","index","interaction"],envversion:{"sphinx.domains.c":2,"sphinx.domains.changeset":1,"sphinx.domains.citation":1,"sphinx.domains.cpp":3,"sphinx.domains.index":1,"sphinx.domains.javascript":2,"sphinx.domains.math":2,"sphinx.domains.python":3,"sphinx.domains.rst":2,"sphinx.domains.std":2,sphinx:56},filenames:["components.rst","index.rst","interaction.rst"],objects:{},objnames:{},objtypes:{},terms:{"1":0,"10":2,"100":0,"15":2,"2":[0,2],"3":[0,1,2],"4":0,"5":[0,1],"80":0,"char":0,"class":[0,2],"do":2,"function":0,"import":1,"int":0,"new":2,"return":[0,1,2],"true":[0,1,2],"var":[],A:2,For:[0,2],If:2,In:2,The:[0,1,2],To:[0,2],_:[],_respond:[],abc:2,about:[0,1,2],accept:0,actionrow:1,after:2,aiter:2,all:0,also:2,alwasi:2,an:[0,2],ani:[0,2],anymor:2,anyth:[0,2],api:[0,2],ar:[1,2],arg:1,argument:0,arrai:0,asotiatet:2,async:1,attach:2,attachet:2,attr:[],attribut:1,author:[1,2],automaticli:0,await:1,b:1,beacus:[0,2],blue:1,blurpl:[0,1],bool:[0,2],bot:1,both:0,button:2,button_click:[1,2],buttonclick:[1,2],buttoncolor:1,buttonstyl:0,callabl:0,can:2,cant:0,channel:2,check:[0,1],check_button:1,click:[0,2],client:[1,2],color:[0,1],command:1,command_prefix:1,compon:2,component_typ:2,contain:2,could:[0,1,2],createt:2,ctx:1,custom_id:[0,1],data:2,def:1,defauld:0,defer:2,delet:2,descript:1,dict:0,disabl:0,disable_all_button:0,disable_all_buttons_if:0,disable_if:0,disapear:2,discordpi:[],displai:0,dm:2,dmchannel:2,doc:1,document:[0,2],dont:[0,2],edit:2,els:2,emb:[1,2],emoji:0,emphember:2,empti:0,en:[],ephemer:1,ephemeralmessag:2,equal:2,event:2,except:2,ext:1,f:1,fail:2,fals:0,first:1,forc:0,from:1,get:[0,2],green:[0,1],grei:[0,1],grey_url:[0,1],guild:2,ha:2,hallo:2,have:[0,2],hei:1,here:1,hidden:[1,2],higher:1,highter:2,html:[],http:1,i:1,ignor:0,implement:1,includ:2,index:[0,1,2],info:0,inform:[0,1,2],initi:2,initiatet:2,insid:2,instead:[0,2],interact:1,interaction_typ:2,invalid:2,invok:2,io:[],isn:2,kwarg:1,label:[0,1],latest:[],left:[0,2],lenght:0,less:2,librari:1,like:2,link:0,link_button:0,linux:1,list:[0,2],load:2,m:1,maco:1,made:[1,2],make:[0,1],manual:2,max:0,maxim:0,mccoderpi:1,member:2,messag:[0,2],meth:[],method:1,minut:2,modul:[0,1,2],more:[0,1,2],msg_with_button:1,navig:0,none:2,oaramet:0,object:[0,2],on_:2,one:2,onli:2,option:[0,2],org:1,origin:[1,2],other:2,page:[0,1,2],paramert:2,paramet:[0,1,2],part:0,partialemoji:0,pass:[0,2],person:2,pip:1,press:0,privat:2,project:1,provid:[0,2],pypi:1,python3:1,python:1,random:1,rapptz:1,read:1,readthedoc:[],red:[0,1],ref:[],reload:2,repres:[0,2],requir:1,resiv:2,respond:2,respons:2,run:1,s:[0,2],same:2,search:[0,1,2],second:2,select:2,selection_select:2,selectionmenu:[0,2],selectionselect:2,send:[0,2],sendabl:0,set:[0,1,2],set_color_if:0,should:[0,2],show:2,side:0,so:[0,2],some:1,state:2,str:0,style:[0,1],supportsindex:0,t:2,text:0,textchannel:2,than:2,thi:[0,1,2],time:2,titl:1,token:[1,2],too:0,two:2,type:[0,2],u:1,uninstal:1,union:[0,2],up:2,url:[0,1],us:[0,1,2],usali:0,user:[0,2],usual:0,valid:2,version:2,vibl:2,visibl:2,visit:[0,1,2],wa:2,wait_for:1,when:[0,2],when_mentioned_or:1,whether:0,who:2,window:1,wisit:0,within:2,would:2,wuild:2,you:[0,1,2],your:1},titles:["Components","Welcome to discord.py-message-component\u2019s documentation!","Interaction"],titleterms:{actionrow:0,an:1,arg:0,attribut:[0,2],button:[0,1],buttoncolor:0,compon:[0,1],content:1,discord:[0,1,2],document:1,he:1,indic:[0,1,2],instal:1,interact:2,kwarg:0,messag:1,method:[0,2],press:1,py:1,quickstart:1,respond:1,s:1,send:1,tabl:[0,1,2],user:1,welcom:1,when:1}})
\ No newline at end of file
diff --git a/docs/_static/codeblocks.css b/docs/_static/codeblocks.css
index aa19bf1d..04755281 100644
--- a/docs/_static/codeblocks.css
+++ b/docs/_static/codeblocks.css
@@ -1,143 +1,143 @@
-/* light theme: default */
-.highlight .hll { background-color: #ffffcc }
-.highlight  { background: #f0f0f0; }
-.highlight .c { color: #60a0b0; font-style: italic } /* Comment */
-.highlight .err { border: 1px solid #FF0000 } /* Error */
-.highlight .k { color: #007020; font-weight: bold } /* Keyword */
-.highlight .o { color: #666666 } /* Operator */
-.highlight .ch { color: #60a0b0; font-style: italic } /* Comment.Hashbang */
-.highlight .cm { color: #60a0b0; font-style: italic } /* Comment.Multiline */
-.highlight .cp { color: #007020 } /* Comment.Preproc */
-.highlight .cpf { color: #60a0b0; font-style: italic } /* Comment.PreprocFile */
-.highlight .c1 { color: #60a0b0; font-style: italic } /* Comment.Single */
-.highlight .cs { color: #60a0b0; background-color: #fff0f0 } /* Comment.Special */
-.highlight .gd { color: #A00000 } /* Generic.Deleted */
-.highlight .ge { font-style: italic } /* Generic.Emph */
-.highlight .gr { color: #FF0000 } /* Generic.Error */
-.highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */
-.highlight .gi { color: #00A000 } /* Generic.Inserted */
-.highlight .go { color: #888888 } /* Generic.Output */
-.highlight .gp { color: #c65d09; font-weight: bold } /* Generic.Prompt */
-.highlight .gs { font-weight: bold } /* Generic.Strong */
-.highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */
-.highlight .gt { color: #0044DD } /* Generic.Traceback */
-.highlight .kc { color: #007020; font-weight: bold } /* Keyword.Constant */
-.highlight .kd { color: #007020; font-weight: bold } /* Keyword.Declaration */
-.highlight .kn { color: #007020; font-weight: bold } /* Keyword.Namespace */
-.highlight .kp { color: #007020 } /* Keyword.Pseudo */
-.highlight .kr { color: #007020; font-weight: bold } /* Keyword.Reserved */
-.highlight .kt { color: #902000 } /* Keyword.Type */
-.highlight .m { color: #40a070 } /* Literal.Number */
-.highlight .s { color: #4070a0 } /* Literal.String */
-.highlight .na { color: #4070a0 } /* Name.Attribute */
-.highlight .nb { color: #007020 } /* Name.Builtin */
-.highlight .nc { color: #0e84b5; font-weight: bold } /* Name.Class */
-.highlight .no { color: #60add5 } /* Name.Constant */
-.highlight .nd { color: #555555; font-weight: bold } /* Name.Decorator */
-.highlight .ni { color: #d55537; font-weight: bold } /* Name.Entity */
-.highlight .ne { color: #007020 } /* Name.Exception */
-.highlight .nf { color: #06287e } /* Name.Function */
-.highlight .nl { color: #002070; font-weight: bold } /* Name.Label */
-.highlight .nn { color: #0e84b5; font-weight: bold } /* Name.Namespace */
-.highlight .nt { color: #062873; font-weight: bold } /* Name.Tag */
-.highlight .nv { color: #bb60d5 } /* Name.Variable */
-.highlight .ow { color: #007020; font-weight: bold } /* Operator.Word */
-.highlight .w { color: #bbbbbb } /* Text.Whitespace */
-.highlight .mb { color: #40a070 } /* Literal.Number.Bin */
-.highlight .mf { color: #40a070 } /* Literal.Number.Float */
-.highlight .mh { color: #40a070 } /* Literal.Number.Hex */
-.highlight .mi { color: #40a070 } /* Literal.Number.Integer */
-.highlight .mo { color: #40a070 } /* Literal.Number.Oct */
-.highlight .sa { color: #4070a0 } /* Literal.String.Affix */
-.highlight .sb { color: #4070a0 } /* Literal.String.Backtick */
-.highlight .sc { color: #4070a0 } /* Literal.String.Char */
-.highlight .dl { color: #4070a0 } /* Literal.String.Delimiter */
-.highlight .sd { color: #4070a0; font-style: italic } /* Literal.String.Doc */
-.highlight .s2 { color: #4070a0 } /* Literal.String.Double */
-.highlight .se { color: #4070a0; font-weight: bold } /* Literal.String.Escape */
-.highlight .sh { color: #4070a0 } /* Literal.String.Heredoc */
-.highlight .si { color: #70a0d0; font-style: italic } /* Literal.String.Interpol */
-.highlight .sx { color: #c65d09 } /* Literal.String.Other */
-.highlight .sr { color: #235388 } /* Literal.String.Regex */
-.highlight .s1 { color: #4070a0 } /* Literal.String.Single */
-.highlight .ss { color: #517918 } /* Literal.String.Symbol */
-.highlight .bp { color: #007020 } /* Name.Builtin.Pseudo */
-.highlight .fm { color: #06287e } /* Name.Function.Magic */
-.highlight .vc { color: #bb60d5 } /* Name.Variable.Class */
-.highlight .vg { color: #bb60d5 } /* Name.Variable.Global */
-.highlight .vi { color: #bb60d5 } /* Name.Variable.Instance */
-.highlight .vm { color: #bb60d5 } /* Name.Variable.Magic */
-.highlight .il { color: #40a070 } /* Literal.Number.Integer.Long */
-
-/* dark theme: modified "native" */
-:root[data-theme="dark"] .highlight pre { background-color: #2a2a2e }
-:root[data-theme="dark"] .highlight .hll { background-color: #2a2a2e }
-:root[data-theme="dark"] .highlight .c { color: #999999; font-style: italic } /* Comment */
-:root[data-theme="dark"] .highlight .err { color: #a61717; background-color: #e3d2d2 } /* Error */
-:root[data-theme="dark"] .highlight .g { color: #d0d0d0 } /* Generic */
-:root[data-theme="dark"] .highlight .k { color: #6ab825; font-weight: bold } /* Keyword */
-:root[data-theme="dark"] .highlight .l { color: #d0d0d0 } /* Literal */
-:root[data-theme="dark"] .highlight .n { color: #d0d0d0 } /* Name */
-:root[data-theme="dark"] .highlight .o { color: #d0d0d0 } /* Operator */
-:root[data-theme="dark"] .highlight .x { color: #d0d0d0 } /* Other */
-:root[data-theme="dark"] .highlight .p { color: #d0d0d0 } /* Punctuation */
-:root[data-theme="dark"] .highlight .cm { color: #999999; font-style: italic } /* Comment.Multiline */
-:root[data-theme="dark"] .highlight .cp { color: #cd2828; font-weight: bold } /* Comment.Preproc */
-:root[data-theme="dark"] .highlight .c1 { color: #999999; font-style: italic } /* Comment.Single */
-:root[data-theme="dark"] .highlight .cs { color: #e50808; font-weight: bold; background-color: #520000 } /* Comment.Special */
-:root[data-theme="dark"] .highlight .gd { color: #d22323 } /* Generic.Deleted */
-:root[data-theme="dark"] .highlight .ge { color: #d0d0d0; font-style: italic } /* Generic.Emph */
-:root[data-theme="dark"] .highlight .gr { color: #d22323 } /* Generic.Error */
-:root[data-theme="dark"] .highlight .gh { color: #ffffff; font-weight: bold } /* Generic.Heading */
-:root[data-theme="dark"] .highlight .gi { color: #589819 } /* Generic.Inserted */
-:root[data-theme="dark"] .highlight .go { color: #cccccc } /* Generic.Output */
-:root[data-theme="dark"] .highlight .gp { color: #aaaaaa } /* Generic.Prompt */
-:root[data-theme="dark"] .highlight .gs { color: #d0d0d0; font-weight: bold } /* Generic.Strong */
-:root[data-theme="dark"] .highlight .gu { color: #ffffff; text-decoration: underline } /* Generic.Subheading */
-:root[data-theme="dark"] .highlight .gt { color: #d22323 } /* Generic.Traceback */
-:root[data-theme="dark"] .highlight .kc { color: #6ab825; font-weight: bold } /* Keyword.Constant */
-:root[data-theme="dark"] .highlight .kd { color: #6ab825; font-weight: bold } /* Keyword.Declaration */
-:root[data-theme="dark"] .highlight .kn { color: #6ab825; font-weight: bold } /* Keyword.Namespace */
-:root[data-theme="dark"] .highlight .kp { color: #6ab825 } /* Keyword.Pseudo */
-:root[data-theme="dark"] .highlight .kr { color: #6ab825; font-weight: bold } /* Keyword.Reserved */
-:root[data-theme="dark"] .highlight .kt { color: #6ab825; font-weight: bold } /* Keyword.Type */
-:root[data-theme="dark"] .highlight .ld { color: #d0d0d0 } /* Literal.Date */
-:root[data-theme="dark"] .highlight .m { color: #7fb1d7 } /* Literal.Number */
-:root[data-theme="dark"] .highlight .s { color: #ed9d13 } /* Literal.String */
-:root[data-theme="dark"] .highlight .na { color: #bbbbbb; } /* Name.Attribute */
-:root[data-theme="dark"] .highlight .nb { color: #29a5b3; } /* Name.Builtin */
-:root[data-theme="dark"] .highlight .nc { color: #6494d8;} /* Name.Class */
-:root[data-theme="dark"] .highlight .no { color: #40ffff; } /* Name.Constant */
-:root[data-theme="dark"] .highlight .nd { color: #ffa500; } /* Name.Decorator */
-:root[data-theme="dark"] .highlight .ni { color: #d0d0d0; } /* Name.Entity */
-:root[data-theme="dark"] .highlight .ne { color: #bbbbbb; } /* Name.Exception */
-:root[data-theme="dark"] .highlight .nf { color: #6494d8; } /* Name.Function */
-:root[data-theme="dark"] .highlight .fm { color: #6494d8; } /* Name.Function.Magic */
-:root[data-theme="dark"] .highlight .nl { color: #d0d0d0; } /* Name.Label */
-:root[data-theme="dark"] .highlight .nn { color: #6494d8;} /* Name.Namespace */
-:root[data-theme="dark"] .highlight .nx { color: #d0d0d0; } /* Name.Other */
-:root[data-theme="dark"] .highlight .py { color: #d0d0d0; } /* Name.Property */
-:root[data-theme="dark"] .highlight .nt { color: #6ab825; font-weight: bold } /* Name.Tag */
-:root[data-theme="dark"] .highlight .nv { color: #40ffff; } /* Name.Variable */
-:root[data-theme="dark"] .highlight .ow { color: #6ab825; font-weight: bold } /* Operator.Word */
-:root[data-theme="dark"] .highlight .w  { color: #666666; } /* Text.Whitespace */
-:root[data-theme="dark"] .highlight .mf { color: #7fb1d7; } /* Literal.Number.Float */
-:root[data-theme="dark"] .highlight .mh { color: #7fb1d7; } /* Literal.Number.Hex */
-:root[data-theme="dark"] .highlight .mi { color: #7fb1d7; } /* Literal.Number.Integer */
-:root[data-theme="dark"] .highlight .mo { color: #7fb1d7; } /* Literal.Number.Oct */
-:root[data-theme="dark"] .highlight .sb { color: #ed9d13; } /* Literal.String.Backtick */
-:root[data-theme="dark"] .highlight .sc { color: #ed9d13; } /* Literal.String.Char */
-:root[data-theme="dark"] .highlight .sd { color: #ed9d13; } /* Literal.String.Doc */
-:root[data-theme="dark"] .highlight .s2 { color: #ed9d13; } /* Literal.String.Double */
-:root[data-theme="dark"] .highlight .se { color: #ed9d13; } /* Literal.String.Escape */
-:root[data-theme="dark"] .highlight .sh { color: #ed9d13; } /* Literal.String.Heredoc */
-:root[data-theme="dark"] .highlight .si { color: #ed9d13; } /* Literal.String.Interpol */
-:root[data-theme="dark"] .highlight .sx { color: #ffa500; } /* Literal.String.Other */
-:root[data-theme="dark"] .highlight .sr { color: #ed9d13; } /* Literal.String.Regex */
-:root[data-theme="dark"] .highlight .s1 { color: #ed9d13; } /* Literal.String.Single */
-:root[data-theme="dark"] .highlight .ss { color: #ed9d13; } /* Literal.String.Symbol */
-:root[data-theme="dark"] .highlight .bp { color: #29a5b3; } /* Name.Builtin.Pseudo */
-:root[data-theme="dark"] .highlight .vc { color: #40ffff; } /* Name.Variable.Class */
-:root[data-theme="dark"] .highlight .vg { color: #40ffff; } /* Name.Variable.Global */
-:root[data-theme="dark"] .highlight .vi { color: #40ffff; } /* Name.Variable.Instance */
-:root[data-theme="dark"] .highlight .il { color: #7fb1d7; } /* Literal.Number.Integer.Long */
\ No newline at end of file
+/* light theme: default */
+.highlight .hll { background-color: #ffffcc }
+.highlight  { background: #f0f0f0; }
+.highlight .c { color: #60a0b0; font-style: italic } /* Comment */
+.highlight .err { border: 1px solid #FF0000 } /* Error */
+.highlight .k { color: #007020; font-weight: bold } /* Keyword */
+.highlight .o { color: #666666 } /* Operator */
+.highlight .ch { color: #60a0b0; font-style: italic } /* Comment.Hashbang */
+.highlight .cm { color: #60a0b0; font-style: italic } /* Comment.Multiline */
+.highlight .cp { color: #007020 } /* Comment.Preproc */
+.highlight .cpf { color: #60a0b0; font-style: italic } /* Comment.PreprocFile */
+.highlight .c1 { color: #60a0b0; font-style: italic } /* Comment.Single */
+.highlight .cs { color: #60a0b0; background-color: #fff0f0 } /* Comment.Special */
+.highlight .gd { color: #A00000 } /* Generic.Deleted */
+.highlight .ge { font-style: italic } /* Generic.Emph */
+.highlight .gr { color: #FF0000 } /* Generic.Error */
+.highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */
+.highlight .gi { color: #00A000 } /* Generic.Inserted */
+.highlight .go { color: #888888 } /* Generic.Output */
+.highlight .gp { color: #c65d09; font-weight: bold } /* Generic.Prompt */
+.highlight .gs { font-weight: bold } /* Generic.Strong */
+.highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */
+.highlight .gt { color: #0044DD } /* Generic.Traceback */
+.highlight .kc { color: #007020; font-weight: bold } /* Keyword.Constant */
+.highlight .kd { color: #007020; font-weight: bold } /* Keyword.Declaration */
+.highlight .kn { color: #007020; font-weight: bold } /* Keyword.Namespace */
+.highlight .kp { color: #007020 } /* Keyword.Pseudo */
+.highlight .kr { color: #007020; font-weight: bold } /* Keyword.Reserved */
+.highlight .kt { color: #902000 } /* Keyword.Type */
+.highlight .m { color: #40a070 } /* Literal.Number */
+.highlight .s { color: #4070a0 } /* Literal.String */
+.highlight .na { color: #4070a0 } /* Name.Attribute */
+.highlight .nb { color: #007020 } /* Name.Builtin */
+.highlight .nc { color: #0e84b5; font-weight: bold } /* Name.Class */
+.highlight .no { color: #60add5 } /* Name.Constant */
+.highlight .nd { color: #555555; font-weight: bold } /* Name.Decorator */
+.highlight .ni { color: #d55537; font-weight: bold } /* Name.Entity */
+.highlight .ne { color: #007020 } /* Name.Exception */
+.highlight .nf { color: #06287e } /* Name.Function */
+.highlight .nl { color: #002070; font-weight: bold } /* Name.Label */
+.highlight .nn { color: #0e84b5; font-weight: bold } /* Name.Namespace */
+.highlight .nt { color: #062873; font-weight: bold } /* Name.Tag */
+.highlight .nv { color: #bb60d5 } /* Name.Variable */
+.highlight .ow { color: #007020; font-weight: bold } /* Operator.Word */
+.highlight .w { color: #bbbbbb } /* Text.Whitespace */
+.highlight .mb { color: #40a070 } /* Literal.Number.Bin */
+.highlight .mf { color: #40a070 } /* Literal.Number.Float */
+.highlight .mh { color: #40a070 } /* Literal.Number.Hex */
+.highlight .mi { color: #40a070 } /* Literal.Number.Integer */
+.highlight .mo { color: #40a070 } /* Literal.Number.Oct */
+.highlight .sa { color: #4070a0 } /* Literal.String.Affix */
+.highlight .sb { color: #4070a0 } /* Literal.String.Backtick */
+.highlight .sc { color: #4070a0 } /* Literal.String.Char */
+.highlight .dl { color: #4070a0 } /* Literal.String.Delimiter */
+.highlight .sd { color: #4070a0; font-style: italic } /* Literal.String.Doc */
+.highlight .s2 { color: #4070a0 } /* Literal.String.Double */
+.highlight .se { color: #4070a0; font-weight: bold } /* Literal.String.Escape */
+.highlight .sh { color: #4070a0 } /* Literal.String.Heredoc */
+.highlight .si { color: #70a0d0; font-style: italic } /* Literal.String.Interpol */
+.highlight .sx { color: #c65d09 } /* Literal.String.Other */
+.highlight .sr { color: #235388 } /* Literal.String.Regex */
+.highlight .s1 { color: #4070a0 } /* Literal.String.Single */
+.highlight .ss { color: #517918 } /* Literal.String.Symbol */
+.highlight .bp { color: #007020 } /* Name.Builtin.Pseudo */
+.highlight .fm { color: #06287e } /* Name.Function.Magic */
+.highlight .vc { color: #bb60d5 } /* Name.Variable.Class */
+.highlight .vg { color: #bb60d5 } /* Name.Variable.Global */
+.highlight .vi { color: #bb60d5 } /* Name.Variable.Instance */
+.highlight .vm { color: #bb60d5 } /* Name.Variable.Magic */
+.highlight .il { color: #40a070 } /* Literal.Number.Integer.Long */
+
+/* dark theme: modified "native" */
+:root[data-theme="dark"] .highlight pre { background-color: #2a2a2e }
+:root[data-theme="dark"] .highlight .hll { background-color: #2a2a2e }
+:root[data-theme="dark"] .highlight .c { color: #999999; font-style: italic } /* Comment */
+:root[data-theme="dark"] .highlight .err { color: #a61717; background-color: #e3d2d2 } /* Error */
+:root[data-theme="dark"] .highlight .g { color: #d0d0d0 } /* Generic */
+:root[data-theme="dark"] .highlight .k { color: #6ab825; font-weight: bold } /* Keyword */
+:root[data-theme="dark"] .highlight .l { color: #d0d0d0 } /* Literal */
+:root[data-theme="dark"] .highlight .n { color: #d0d0d0 } /* Name */
+:root[data-theme="dark"] .highlight .o { color: #d0d0d0 } /* Operator */
+:root[data-theme="dark"] .highlight .x { color: #d0d0d0 } /* Other */
+:root[data-theme="dark"] .highlight .p { color: #d0d0d0 } /* Punctuation */
+:root[data-theme="dark"] .highlight .cm { color: #999999; font-style: italic } /* Comment.Multiline */
+:root[data-theme="dark"] .highlight .cp { color: #cd2828; font-weight: bold } /* Comment.Preproc */
+:root[data-theme="dark"] .highlight .c1 { color: #999999; font-style: italic } /* Comment.Single */
+:root[data-theme="dark"] .highlight .cs { color: #e50808; font-weight: bold; background-color: #520000 } /* Comment.Special */
+:root[data-theme="dark"] .highlight .gd { color: #d22323 } /* Generic.Deleted */
+:root[data-theme="dark"] .highlight .ge { color: #d0d0d0; font-style: italic } /* Generic.Emph */
+:root[data-theme="dark"] .highlight .gr { color: #d22323 } /* Generic.Error */
+:root[data-theme="dark"] .highlight .gh { color: #ffffff; font-weight: bold } /* Generic.Heading */
+:root[data-theme="dark"] .highlight .gi { color: #589819 } /* Generic.Inserted */
+:root[data-theme="dark"] .highlight .go { color: #cccccc } /* Generic.Output */
+:root[data-theme="dark"] .highlight .gp { color: #aaaaaa } /* Generic.Prompt */
+:root[data-theme="dark"] .highlight .gs { color: #d0d0d0; font-weight: bold } /* Generic.Strong */
+:root[data-theme="dark"] .highlight .gu { color: #ffffff; text-decoration: underline } /* Generic.Subheading */
+:root[data-theme="dark"] .highlight .gt { color: #d22323 } /* Generic.Traceback */
+:root[data-theme="dark"] .highlight .kc { color: #6ab825; font-weight: bold } /* Keyword.Constant */
+:root[data-theme="dark"] .highlight .kd { color: #6ab825; font-weight: bold } /* Keyword.Declaration */
+:root[data-theme="dark"] .highlight .kn { color: #6ab825; font-weight: bold } /* Keyword.Namespace */
+:root[data-theme="dark"] .highlight .kp { color: #6ab825 } /* Keyword.Pseudo */
+:root[data-theme="dark"] .highlight .kr { color: #6ab825; font-weight: bold } /* Keyword.Reserved */
+:root[data-theme="dark"] .highlight .kt { color: #6ab825; font-weight: bold } /* Keyword.Type */
+:root[data-theme="dark"] .highlight .ld { color: #d0d0d0 } /* Literal.Date */
+:root[data-theme="dark"] .highlight .m { color: #7fb1d7 } /* Literal.Number */
+:root[data-theme="dark"] .highlight .s { color: #ed9d13 } /* Literal.String */
+:root[data-theme="dark"] .highlight .na { color: #bbbbbb; } /* Name.Attribute */
+:root[data-theme="dark"] .highlight .nb { color: #29a5b3; } /* Name.Builtin */
+:root[data-theme="dark"] .highlight .nc { color: #6494d8;} /* Name.Class */
+:root[data-theme="dark"] .highlight .no { color: #40ffff; } /* Name.Constant */
+:root[data-theme="dark"] .highlight .nd { color: #ffa500; } /* Name.Decorator */
+:root[data-theme="dark"] .highlight .ni { color: #d0d0d0; } /* Name.Entity */
+:root[data-theme="dark"] .highlight .ne { color: #bbbbbb; } /* Name.Exception */
+:root[data-theme="dark"] .highlight .nf { color: #6494d8; } /* Name.Function */
+:root[data-theme="dark"] .highlight .fm { color: #6494d8; } /* Name.Function.Magic */
+:root[data-theme="dark"] .highlight .nl { color: #d0d0d0; } /* Name.Label */
+:root[data-theme="dark"] .highlight .nn { color: #6494d8;} /* Name.Namespace */
+:root[data-theme="dark"] .highlight .nx { color: #d0d0d0; } /* Name.Other */
+:root[data-theme="dark"] .highlight .py { color: #d0d0d0; } /* Name.Property */
+:root[data-theme="dark"] .highlight .nt { color: #6ab825; font-weight: bold } /* Name.Tag */
+:root[data-theme="dark"] .highlight .nv { color: #40ffff; } /* Name.Variable */
+:root[data-theme="dark"] .highlight .ow { color: #6ab825; font-weight: bold } /* Operator.Word */
+:root[data-theme="dark"] .highlight .w  { color: #666666; } /* Text.Whitespace */
+:root[data-theme="dark"] .highlight .mf { color: #7fb1d7; } /* Literal.Number.Float */
+:root[data-theme="dark"] .highlight .mh { color: #7fb1d7; } /* Literal.Number.Hex */
+:root[data-theme="dark"] .highlight .mi { color: #7fb1d7; } /* Literal.Number.Integer */
+:root[data-theme="dark"] .highlight .mo { color: #7fb1d7; } /* Literal.Number.Oct */
+:root[data-theme="dark"] .highlight .sb { color: #ed9d13; } /* Literal.String.Backtick */
+:root[data-theme="dark"] .highlight .sc { color: #ed9d13; } /* Literal.String.Char */
+:root[data-theme="dark"] .highlight .sd { color: #ed9d13; } /* Literal.String.Doc */
+:root[data-theme="dark"] .highlight .s2 { color: #ed9d13; } /* Literal.String.Double */
+:root[data-theme="dark"] .highlight .se { color: #ed9d13; } /* Literal.String.Escape */
+:root[data-theme="dark"] .highlight .sh { color: #ed9d13; } /* Literal.String.Heredoc */
+:root[data-theme="dark"] .highlight .si { color: #ed9d13; } /* Literal.String.Interpol */
+:root[data-theme="dark"] .highlight .sx { color: #ffa500; } /* Literal.String.Other */
+:root[data-theme="dark"] .highlight .sr { color: #ed9d13; } /* Literal.String.Regex */
+:root[data-theme="dark"] .highlight .s1 { color: #ed9d13; } /* Literal.String.Single */
+:root[data-theme="dark"] .highlight .ss { color: #ed9d13; } /* Literal.String.Symbol */
+:root[data-theme="dark"] .highlight .bp { color: #29a5b3; } /* Name.Builtin.Pseudo */
+:root[data-theme="dark"] .highlight .vc { color: #40ffff; } /* Name.Variable.Class */
+:root[data-theme="dark"] .highlight .vg { color: #40ffff; } /* Name.Variable.Global */
+:root[data-theme="dark"] .highlight .vi { color: #40ffff; } /* Name.Variable.Instance */
+:root[data-theme="dark"] .highlight .il { color: #7fb1d7; } /* Literal.Number.Integer.Long */
diff --git a/docs/_static/copy.js b/docs/_static/copy.js
new file mode 100644
index 00000000..f70e3d67
--- /dev/null
+++ b/docs/_static/copy.js
@@ -0,0 +1,34 @@
+const COPY = "content_copy";
+const COPIED = "done";
+
+const copy = async (obj) => {
+  // <span class="copy"><span class="material-icons">{{text}}</span></span>
+  await navigator.clipboard.writeText(obj.children[1].innerText).then(
+    () => {
+      let icon = obj.children[0].children[0];
+      icon.textContent = COPIED;
+      setTimeout(() => (icon.textContent = COPY), 2500);
+    },
+    (r) => alert('Could not copy codeblock:\n' + r.toString())
+  );
+};
+
+document.addEventListener("DOMContentLoaded", () => {
+  let allCodeblocks = document.querySelectorAll("div[class='highlight']");
+
+  for (let codeblock of allCodeblocks) {
+    codeblock.parentNode.className += " relative-copy";
+    let copyEl = document.createElement("span");
+    copyEl.addEventListener('click', () => copy(codeblock));
+    copyEl.className = "copy";
+    copyEl.setAttribute("aria-label", "Copy Code");
+    copyEl.setAttribute("title", "Copy Code");
+
+    let copyIcon = document.createElement("span");
+    copyIcon.className = "material-icons";
+    copyIcon.textContent = COPY;
+    copyEl.append(copyIcon);
+
+    codeblock.prepend(copyEl);
+  }
+});
diff --git a/docs/_static/custom.js b/docs/_static/custom.js
new file mode 100644
index 00000000..4cf7fe33
--- /dev/null
+++ b/docs/_static/custom.js
@@ -0,0 +1,114 @@
+'use-strict';
+
+let activeModal = null;
+let bottomHeightThreshold, sections;
+let hamburgerToggle;
+let mobileSearch;
+let sidebar;
+let toTop;
+
+class Modal {
+  constructor(element) {
+    this.element = element;
+  }
+
+  close() {
+    activeModal = null;
+    this.element.style.display = 'none'
+  }
+
+  open() {
+    if (activeModal) {
+      activeModal.close();
+    }
+    activeModal = this;
+    this.element.style.display = 'flex'
+  }
+}
+
+class SearchBar {
+
+  constructor() {
+    this.box = document.querySelector('nav.mobile-only');
+    this.bar = document.querySelector('nav.mobile-only input[type="search"]');
+    this.openButton = document.getElementById('open-search');
+    this.closeButton = document.getElementById('close-search');
+  }
+
+  open() {
+    this.openButton.hidden = true;
+    this.closeButton.hidden = false;
+    this.box.style.top = "100%";
+    this.bar.focus();
+  }
+
+  close() {
+    this.openButton.hidden = false;
+    this.closeButton.hidden = true;
+    this.box.style.top = "0";
+  }
+
+}
+
+function scrollToTop() {
+  window.scrollTo({ top: 0, behavior: 'smooth' });
+}
+
+document.addEventListener('DOMContentLoaded', () => {
+  mobileSearch = new SearchBar();
+
+  bottomHeightThreshold = document.documentElement.scrollHeight - 30;
+  sections = document.querySelectorAll('section');
+  hamburgerToggle = document.getElementById('hamburger-toggle');
+  
+  toTop = document.getElementById('to-top');
+  toTop.hidden = !(window.scrollY > 0);
+
+  if (hamburgerToggle) {
+    hamburgerToggle.addEventListener('click', (e) => {
+      sidebar.element.classList.toggle('sidebar-toggle');
+      let button = hamburgerToggle.firstElementChild;
+      if (button.textContent === 'menu') {
+        button.textContent = 'close';
+      }
+      else {
+        button.textContent = 'menu';
+      }
+    });
+  }
+
+  const tables = document.querySelectorAll('.py-attribute-table[data-move-to-id]');
+  tables.forEach(table => {
+    let element = document.getElementById(table.getAttribute('data-move-to-id'));
+    let parent = element.parentNode;
+    // insert ourselves after the element
+    parent.insertBefore(table, element.nextSibling);
+  });
+
+  window.addEventListener('scroll', () => {
+    toTop.hidden = !(window.scrollY > 0);
+  });
+});
+
+isMobile = () => {
+    return window.matchMedia("only screen and (max-width: 760px)").matches;
+}
+
+document.addEventListener('keydown', (event) => {
+  if (event.code === "Escape" && activeModal) {
+    activeModal.close();
+  }
+  else if (event.code === "KeyF" && (event.ctrlKey || event.metaKey)) {
+    event.preventDefault();
+    if (isMobile()) {
+        mobileSearch.bar.scrollIntoView();
+        mobileSearch.bar.focus();
+        mobileSearch.open();
+    }
+    else {
+      let searchInput = document.getElementById('top-bar-search-input');
+      searchInput.scrollIntoView();
+      searchInput.focus();
+    }
+  }
+});
diff --git a/docs/_static/icons.css b/docs/_static/icons.css
new file mode 100644
index 00000000..deb2c9d5
--- /dev/null
+++ b/docs/_static/icons.css
@@ -0,0 +1,10 @@
+@font-face {
+    font-family: 'Custom Icons';
+    font-style: normal;
+    font-weight: 400;
+    src: url('icons.woff') format('woff2');
+}
+
+.custom-icons {
+    font-family: 'Custom Icons' !important;
+}
\ No newline at end of file
diff --git a/docs/_static/scorer.js b/docs/_static/scorer.js
new file mode 100644
index 00000000..f9f95cfe
--- /dev/null
+++ b/docs/_static/scorer.js
@@ -0,0 +1,83 @@
+'use-strict';
+
+let queryBeingDone = null;
+let pattern = null;
+
+const escapedRegex = /[-\/\\^$*+?.()|[\]{}]/g;
+function escapeRegex(e) {
+    return e.replace(escapedRegex, '\\$&');
+}
+
+// for some reason Sphinx shows some entries twice
+// if something has been scored already I'd rather sort it to the bottom
+const beenScored = new Set();
+
+function __score(haystack, regex) {
+    let match = regex.exec(haystack);
+    if (match == null) {
+        return Number.MAX_VALUE;
+    }
+    let subLength = match[0].length;
+    let start = match.index;
+    return (subLength * 1000 + start) / 1000.0;
+}
+
+// unused for now
+function __cleanNamespaces(query) {
+    return query.replace(/(discord\.(ext\.)?)?(.+)/, '$3');
+}
+
+Scorer = {
+
+    // Implement the following function to further tweak the score for each result
+    // The function takes a result array [filename, title, anchor, descr, score]
+    // and returns the new score.
+    score: (result) => {
+        // only inflate the score of things that are actual API reference things
+        const [, title, , , score] = result;
+
+        if (pattern !== null && title.startsWith('discord.')) {
+            let _score = __score(title, pattern);
+            if (_score === Number.MAX_VALUE) {
+                return score;
+            }
+            if (beenScored.has(title)) {
+                return 0;
+            }
+            beenScored.add(title);
+            let newScore = 100 + queryBeingDone.length - _score;
+            // console.log(`${title}: ${score} -> ${newScore} (${_score})`);
+            return newScore;
+        }
+        return score;
+    },
+
+    // query matches the full name of an object
+    objNameMatch: 15,
+    // or matches in the last dotted part of the object name
+    objPartialMatch: 11,
+    // Additive scores depending on the priority of the object
+    objPrio: {
+        0: 15,  // used to be importantResults
+        1: 7,   // used to be objectResults
+        2: -5   // used to be unimportantResults
+    },
+    //  Used when the priority is not in the mapping.
+    objPrioDefault: 0,
+
+    // query found in title
+    title: 15,
+    partialTitle: 7,
+    // query found in terms
+    term: 5,
+    partialTerm: 2
+};
+
+document.addEventListener('DOMContentLoaded', () => {
+    const params = new URLSearchParams(window.location.search);
+    queryBeingDone = params.get('q');
+    if (queryBeingDone) {
+        let pattern = Array.from(queryBeingDone).map(escapeRegex).join('.*?');
+        pattern = new RegExp(pattern, 'i');
+    }
+});
diff --git a/docs/_static/settings.js b/docs/_static/settings.js
new file mode 100644
index 00000000..9023bf6e
--- /dev/null
+++ b/docs/_static/settings.js
@@ -0,0 +1,137 @@
+'use-strict';
+
+let settingsModal;
+
+class Setting {
+  constructor(name, defaultValue, setter) {
+    this.name = name;
+    this.defaultValue = defaultValue;
+    this.setValue = setter;
+  }
+
+  setElement() {
+    throw new TypeError('Abstract methods should be implemented.');
+  }
+
+  load() {
+    let value = JSON.parse(localStorage.getItem(this.name));
+    this.value = value === null ? this.defaultValue : value;
+    try {
+      this.setValue(this.value);
+    } catch (error) {
+      console.error(`Failed to apply setting "${this.name}" With value:`, this.value);
+      console.error(error);
+    }
+  }
+
+  update() {
+    throw new TypeError('Abstract methods should be implemented.');
+  }
+
+}
+
+class CheckboxSetting extends Setting {
+
+  setElement() {
+    let element = document.querySelector(`input[name=${this.name}]`);
+    element.checked = this.value;
+  }
+
+  update(element) {
+    localStorage.setItem(this.name, element.checked);
+    this.setValue(element.checked);
+  }
+
+}
+
+class RadioSetting extends Setting {
+
+  setElement() {
+    let element = document.querySelector(`input[name=${this.name}][value=${this.value}]`);
+    element.checked = true;
+  }
+
+  update(element) {
+    localStorage.setItem(this.name, `"${element.value}"`);
+    this.setValue(element.value);
+  }
+
+}
+
+function getRootAttributeToggle(attributeName, valueName) {
+  function toggleRootAttribute(set) {
+    if (set) {
+      document.documentElement.setAttribute(`data-${attributeName}`, valueName);
+    } else {
+      document.documentElement.removeAttribute(`data-${attributeName}`);
+    }
+  }
+  return toggleRootAttribute;
+}
+
+function setTheme(value) {
+  if (value === 'automatic') {
+    if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) {
+      document.documentElement.setAttribute('data-theme', 'dark');
+    } else {
+      document.documentElement.setAttribute('data-theme', 'light');
+    }
+  }
+  else {
+    document.documentElement.setAttribute('data-theme', value);
+  }
+}
+
+const settings = [
+  new CheckboxSetting('useSerifFont', false, getRootAttributeToggle('font', 'serif')),
+  new RadioSetting('setTheme', 'automatic', setTheme)
+]
+
+function updateSetting(element) {
+  let setting = settings.find((s) => s.name == element.name);
+  if (setting) {
+    setting.update(element);
+  }
+}
+
+for (const setting of settings) {
+  setting.load();
+}
+
+function sleep(s) {
+  return new Promise(resolve => setTimeout(resolve, s * 1000));
+}
+
+let gearwheel
+
+async function openModal(event, close) {
+  gearwheel.classList.remove("fa-shake");
+  gearwheel.style = `${!close ? "--fa-animation-direction: reverse; " : ""}--fa-animation-duration: 1s;`;
+  gearwheel.classList.add("fa-spin");
+  
+  sleep(0.5)
+    .then(() => (!close ? settingsModal.open() : settingsModal.close()))
+    .then(() => gearwheel.classList.remove("fa-spin"))
+    .then(() => gearwheel.style = `--fa-animation-duration: 1s;`)
+}
+
+document.addEventListener('DOMContentLoaded', () => {
+  gearwheel = document.getElementsByClassName("fa-gear")[0];
+  settingsModal = new Modal(document.querySelector('div#settings.modal'));
+  for (const setting of settings) {
+    setting.setElement();
+  }
+  gearwheel.addEventListener(
+    'mouseover',
+    (event) => {
+      gearwheel.style = "--fa-animation-direction: reverse; --fa-animation-duration: 3s;";
+      gearwheel.classList.add("fa-shake");
+    });
+  gearwheel.addEventListener(
+    'mouseout',
+    (event) => {
+      //event.target.style = "--fa-animation-duration: 20s;";
+      gearwheel.classList.remove("fa-shake");
+    });
+  gearwheel.addEventListener('click', openModal)
+});
\ No newline at end of file
diff --git a/docs/_static/sidebar.js b/docs/_static/sidebar.js
new file mode 100644
index 00000000..036b7713
--- /dev/null
+++ b/docs/_static/sidebar.js
@@ -0,0 +1,140 @@
+class Sidebar {
+  constructor(element) {
+    this.element = element;
+    this.activeLink = null;
+
+    this.element.addEventListener('click', (e) => {
+      // If we click a navigation, close the hamburger menu
+      if (e.target.tagName == 'A' && this.element.classList.contains('sidebar-toggle')) {
+        this.element.classList.remove('sidebar-toggle');
+        let button = hamburgerToggle.firstElementChild;
+        button.textContent = 'menu';
+
+        // Scroll a little up to actually see the header
+        // Note: this is generally around ~55px
+        // A proper solution is getComputedStyle but it can be slow
+        // Instead let's just rely on this quirk and call it a day
+        // This has to be done after the browser actually processes
+        // the section movement
+        setTimeout(() => window.scrollBy(0, -100), 75);
+      }
+    });
+  }
+
+  createCollapsableSections() {
+    let toc = this.element.querySelector('ul');
+    if (!toc) {
+      return
+    }
+    let allReferences = toc.querySelectorAll('a.reference.internal:not([href="#"])');
+
+    for (let ref of allReferences) {
+
+      let next = ref.nextElementSibling;
+
+      if (next && next.tagName === "UL") {
+
+        let icon = document.createElement('span');
+        icon.className = 'material-icons collapsible-arrow expanded';
+        icon.innerText = 'expand_more';
+
+        if (next.parentElement.tagName == "LI") {
+          next.parentElement.classList.add('no-list-style')
+        }
+
+        icon.addEventListener('click', () => {
+          if (icon.classList.contains('expanded')) {
+            this.collapseSection(icon);
+          } else {
+            this.expandSection(icon);
+          }
+        })
+
+        ref.classList.add('ref-internal-padding')
+        ref.parentNode.insertBefore(icon, ref);
+      }
+    }
+  }
+
+  resize() {
+    let rect = this.element.getBoundingClientRect();
+    this.element.style.height = `calc(100vh - 1em - ${rect.top + document.body.offsetTop}px)`;
+  }
+
+  collapseSection(icon) {
+    icon.classList.remove('expanded');
+    icon.classList.add('collapsed');
+    let children = icon.nextElementSibling.nextElementSibling;
+    // <arrow><heading>
+    // --> <square><children>
+    setTimeout(() => children.style.display = "none", 75)
+  }
+
+  expandSection(icon) {
+    icon.classList.remove('collapse');
+    icon.classList.add('expanded');
+    let children = icon.nextElementSibling.nextElementSibling;
+    setTimeout(() => children.style.display = "block", 75)
+  }
+
+  setActiveLink(section) {
+    let sectionSelected = this.activeLink?.href.split('#')[1] === section?.id;
+    if (this.activeLink && !sectionSelected) {
+      this.activeLink.parentElement.classList.remove('active');
+    }
+
+    if (section && !sectionSelected) {
+      this.activeLink = document.querySelector(`#sidebar a[href="#${section.id}"]`);
+      if (this.activeLink) {
+        let headingChildren = this.activeLink.parentElement.parentElement;
+        let heading = headingChildren.previousElementSibling.previousElementSibling;
+
+        if (heading && headingChildren.style.display === 'none') {
+          this.activeLink = heading;
+        }
+
+        this.activeLink.parentElement.classList.add('active');
+        //this.setTimeout = window.setTimeout.bind(window);
+        //this.clearTimeout = window.clearTimeout.bind(window);
+        let scrollToActiveLink = (activeLink) => {
+            activeLink.parentElement.scrollIntoView({ block: 'nearest', inline: 'nearest', behavior: 'auto' });
+        }
+        setTimeout(
+            scrollToActiveLink,
+            200,
+            this.activeLink
+        );
+      }
+    }
+  }
+
+}
+
+function getCurrentSection() {
+  let currentSection;
+  if (window.scrollY + window.innerHeight > bottomHeightThreshold) {
+    currentSection = sections[sections.length - 1];
+  }
+  else {
+    if (sections) {
+      sections.forEach(section => {
+        let rect = section.getBoundingClientRect();
+        if (rect.top + document.body.offsetTop < 1) {
+          currentSection = section;
+        }
+      });
+    }
+  }
+  return currentSection;
+}
+
+document.addEventListener('DOMContentLoaded', () => {
+  sidebar = new Sidebar(document.getElementById('sidebar'));
+  sidebar.resize();
+  sidebar.createCollapsableSections();
+
+  window.addEventListener('scroll', () => {
+    sidebar.setActiveLink(getCurrentSection());
+    sidebar.resize();
+  });
+});
diff --git a/docs/_static/style.css b/docs/_static/style.css
new file mode 100644
index 00000000..9c28b0d7
--- /dev/null
+++ b/docs/_static/style.css
@@ -0,0 +1,1556 @@
+/*
+This theme was created from scratch.
+Historically however, thanks to:
+- Alabaster for being a good base
+  - Which thanks Flask + KR theme
+- Sphinx Readable Theme
+  - Which also proved to be a great base
+*/
+
+/*
+  note: this CSS is "mobile first"
+  The desktop implementation is near the bottom
+*/
+
+@font-face {
+    font-family: FontAwesome;
+    src: url(fonts/fontawesome-webfont.eot?674f50d287a8c48dc19ba404d20fe713);
+    src: url(fonts/fontawesome-webfont.eot?674f50d287a8c48dc19ba404d20fe713?#iefix&v=4.7.0) format("embedded-opentype"),url(fonts/fontawesome-webfont.woff2?af7ae505a9eed503f8b8e6982036873e) format("woff2"),url(fonts/fontawesome-webfont.woff?fee66e712a8a08eef5805a46892932ad) format("woff"),url(fonts/fontawesome-webfont.ttf?b06871f281fee6b241d60582ae9369b9) format("truetype"),url(fonts/fontawesome-webfont.svg?912ec66d7572ff821749319396470bde#fontawesomeregular) format("svg");
+    font-weight: 400;
+    font-style: normal
+}
+
+* {
+  box-sizing: border-box;
+}
+
+/* CSS variables would go here */
+:root {
+  --font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
+  --monospace-font-family: 'Consolas', 'Menlo', 'Deja Vu Sans Mono', 'Bitstream Vera Sans Mono', monospace;
+
+  /* palette goes here */
+  --white: #ffffff;
+  --grey-1: #f9f9fa;
+  --grey-1-8: rgba(249, 249, 250, 0.8);
+  --grey-2: #ededf0;
+  --grey-3: #d7d7db;
+  --grey-4: #b1b1b3;
+  --grey-5: #737373;
+  --grey-6: #4a4a4f;
+  --grey-7: #38383d;
+  --grey-8: #2a2a2e;
+  --grey-9: #1c1c1e;
+  --black: #0c0c0d;
+
+  --blue-1: #3399ff;
+  --blue-2: #0a84ff;
+  --blue-3: #0060df;
+  --blue-4: #003eaa;
+  --blue-5: #002275;
+  --blue-6: #000f40;
+
+  --purple: #ac00f9;
+
+  --settings: var(--grey-1);
+  --settings-hover: var(--grey-1-8);
+  --main-background: var(--grey-1);
+  --link-text: var(--blue-2);
+  --link-hover-text: var(--blue-6);
+  --main-text: var(--black);
+  --mobile-nav-background: var(--black);
+  --mobile-nav-text: var(--white);
+  --mobile-nav-hover-text: var(--white);
+  --mobile-nav-header-text: var(--white);
+  --nav-background: var(--main-background);
+  --nav-text: var(--grey-6);
+  --nav-hover-text: var(--grey-6);
+  --nav-header-text: var(--black);
+  --sub-header-background: var(--grey-6);
+  --search-border: var(--grey-4);
+  --search-text: var(--white);
+  --search-focus: var(--blue-1);
+  --search-button: var(--grey-1);
+  --search-button-hover: var(--grey-1-8);
+  --search-sidebar-background: var(--grey-1);
+  --search-sidebar-text: var(--grey-7);
+  --footer-text: var(--grey-5);
+  --footer-link: var(--grey-6);
+  --hr-border: var(--grey-2);
+  --main-big-headers-text: var(--black);
+  --main-big-headers-border: var(--grey-4);
+  --main-h5-header-text: var(--black);
+  --main-h6-header-text: var(--grey-4);
+  --main-h4-header-border: var(--grey-4);
+  --header-link: var(--grey-6);
+  --header-link-hover-text: var(--blue-2);
+  --admonition-background: var(--grey-2);
+  --note-background: var(--blue-1);
+  --note-text: var(--white);
+  --warning-background: #ffe900;
+  --warning-text: var(--black);
+  --error-background: #d70022;
+  --error-text: var(--white);
+  --helpful-background: #00c8d7;
+  --helpful-text: var(--black);
+  --experimental-background: #304a96;
+  --experimental-text: var(--grey-2);
+  --codeblock-background: var(--grey-2);
+  --codeblock-border: var(--grey-4);
+  --codeblock-text: var(--grey-6);
+  --inline-code-background: var(--grey-3);
+  --admonition-inline-code-background: var(--grey-3);
+  --xref-code-background: transparent;
+  --api-entry-background: var(--grey-2);
+  --table-header-background: var(--grey-3);
+  --table-text: var(--black);
+  --table-border: var(--grey-4);
+  --mobile-active-toc: var(--grey-7);
+  --active-toc: var(--grey-3);
+  --scrollbar: rgba(0,0,0,0.2);
+  --scrollbar-hover: rgba(0,0,0,0.4);
+  --rtd-ad-border: var(--grey-3);
+  --rtd-ad-background: var(--grey-2);
+  --rtd-ad-main-text: var(--grey-6);
+  --rtd-ad-small-text: var(--grey-4);
+  --rtd-version-background: #272525;
+  --rtd-version-main-text: #fcfcfc;
+  --attribute-table-title: var(--grey-6);
+  --attribute-table-entry-border: var(--grey-3);
+  --attribute-table-entry-text: var(--grey-5);
+  --attribute-table-entry-hover-border: var(--blue-2);
+  --attribute-table-entry-hover-background: var(--grey-2);
+  --attribute-table-entry-hover-text: var(--blue-2);
+  --attribute-table-badge: var(--grey-7);
+  --highlighted-text: rgb(252, 233, 103);
+  --tabs--label-text: var(--main-text);
+  --tabs--label-text--hover: var(--main-text);
+  --tabs--label-text--active: var(--blue-1);
+  --tabs--label-text--active--hover: var(--blue-1);
+  --tabs--label-border--active: var(--blue-1);
+  --tabs--label-border--active--hover: var(--blue-1);
+  --key-background-color: var(--grey-1);
+  --key-border-color: var(--grey-2);
+  --key-border-color--active: var(--grey-5);
+  --key-shadow-color: var(--grey-5);
+  --key-shadow-color--active: var(--grey-4);
+  --key-content-color: var(--black);
+  --key-content-color--active: var(--grey-9);
+}
+
+:root[data-font="serif"] {
+  --font-family: 'Georgia', 'Yu Gothic', 'Noto Sans CJK JP Regular', serif;
+}
+
+:root[data-theme="dark"] {
+  --main-background: var(--grey-7);
+  --link-text: var(--blue-1);
+  --link-hover-text: var(--blue-2);
+  --main-text: var(--white);
+  --sub-header-background: var(--grey-8);
+  --search-border: var(--grey-5);
+  --nav-background: var(--main-background);
+  --nav-text: var(--grey-1);
+  --nav-hover-text: var(--grey-2);
+  --nav-header-text: var(--white);
+  --footer-text: var(--grey-2);
+  --footer-link: var(--grey-1);
+  --hr-border: var(--grey-1);
+  --main-big-headers-text: var(--grey-1);
+  --main-big-headers-border: var(--grey-1);
+  --main-h5-header-text: var(--grey-4);
+  --main-h6-header-text: var(--grey-5);
+  --main-h4-header-border: var(--grey-2);
+  --header-link: var(--grey-2);
+  --header-link-hover-text: var(--blue-2);
+  --admonition-background: var(--grey-8);
+  --note-background: var(--blue-3);
+  --note-text: var(--white);
+  --warning-background: #d7b600;
+  --warning-text: var(--black);
+  --error-background:  #d70022;
+  --error-text: var(--white);
+  --helpful-background: #008ea4;
+  --helpful-text: var(--white);
+  --experimental-background: rgba(79, 123, 253, 0.47);
+  --experimental-text: var(--white);
+  --codeblock-background: var(--grey-6);
+  --codeblock-border: var(--black);
+  --codeblock-text: var(--grey-1);
+  --inline-code-background: var(--grey-8);
+  --admonition-inline-code-background: var(--grey-7);
+  --xref-code-background: transparent;
+  --api-entry-background: var(--grey-6);
+  --table-header-background: var(--grey-6);
+  --table-text: var(--grey-1);
+  --table-border: var(--grey-4);
+  --active-toc: var(--grey-6);
+  --scrollbar: rgba(0,0,0,0.5);
+  --scrollbar-hover: rgba(0,0,0,0.7);
+  --rtd-ad-border: var(--grey-6);
+  --rtd-ad-background: var(--grey-5);
+  --rtd-ad-main-text: var(--grey-2);
+  --rtd-ad-small-text: var(--grey-1);
+  --attribute-table-title: var(--grey-3);
+  --attribute-table-entry-border: var(--grey-5);
+  --attribute-table-entry-text: var(--grey-3);
+  --attribute-table-entry-hover-border: var(--blue-1);
+  --attribute-table-entry-hover-background: var(--grey-6);
+  --attribute-table-entry-hover-text: var(--blue-1);
+  --attribute-table-badge: var(--grey-4);
+  --highlighted-text: rgba(250, 166, 26, 0.2);
+  --search-sidebar-background: var(--grey-7);
+  --search-sidebar-text: var(--search-text);
+  --key-background-color: var(--grey-7);
+  --key-border-color: var(--grey-8);
+  --key-border-color--active: var(--grey-9);
+  --key-shadow-color: var(--grey-9);
+  --key-shadow-color--active: var(--grey-3);
+  --key-content-color: var(--grey-3);
+  --key-content-color--active: var(--white);
+}
+
+img[src$="banner_light.png"]  {
+  display: none;
+}
+
+:root[data-theme="light"] figure[id$="discord-py-message-components"] > img {
+  content: url("../_images/banner_light.png");
+  display: inherit;
+}
+
+:root[data-theme="dark"] figure[id$="discord-py-message-components"] > img {
+  content: url("../_images/banner_dark.png");
+  display: inherit;
+}
+
+main img[src$="drop_down_icon.svg"]  {
+  visibility: hidden;
+  height: 0%;
+  width: 0%;
+}
+
+body {
+  font-family: var(--font-family);
+  font-size: 16px;
+  margin: 0;
+  padding: 0;
+  height: 100%;
+  background-color: var(--main-background);
+  color: var(--main-text);
+}
+
+
+/* Scrollbar related */
+
+#sidebar::-webkit-scrollbar {
+  width: 0.5em;
+}
+
+#sidebar::-webkit-scrollbar-thumb {
+  background-color: var(--scrollbar);
+  border-radius: 0.25em;
+}
+
+#sidebar::-webkit-scrollbar-thumb:hover {
+  background-color: var(--scrollbar-hover);
+}
+
+
+/* grid related */
+
+.main-grid {
+  display: grid;
+  min-height: 100%;
+  grid-auto-rows: min-content auto min-content;
+  grid-template-areas:
+    "s"
+    "h"
+    "n"
+    "c"
+    "f";
+}
+
+.grid-item {
+  max-width: 100vw;
+  padding: 0.8em;
+}
+
+/* all URLs only show underline on hover */
+a {
+  text-decoration: none;
+  color: var(--link-text);
+}
+
+a:hover {
+  text-decoration: underline;
+  color: var(--link-hover-text);
+}
+
+/*get rid of the purple text on visited links*/
+a:visited {
+  color: var(--link-text);
+}
+
+/* headers */
+
+header.grid-item {
+  grid-area: h;
+  color: var(--main-text);
+  position: relative;
+  z-index: 1;
+  padding: 0;
+}
+
+header > nav {
+  background-color: var(--sub-header-background);
+  padding: 0.8em;
+  display: flex;
+  flex-direction: row;
+  justify-content: flex-end;
+  align-items: center;
+}
+
+header > nav a {
+  color: var(--white);
+}
+
+/*get rid of the blue icons on visited links too*/
+header > nav a:visited {
+  color: var(--white);
+}
+
+header > nav.mobile-only {
+  width: 100%;
+  position: absolute;
+  top: 0;
+  right: 0;
+  z-index: -1;
+  padding-top: 0;
+  transition: top 0.5s ease-in-out;
+}
+
+header > nav.mobile-only .search {
+  width: 100%;
+}
+
+header > nav.mobile-only .search-wrapper {
+  background-color: var(--sub-header-background);
+}
+
+.main-heading {
+  margin-right: auto;
+}
+
+header > nav a:not(.main-heading) {
+  margin: 0 0.5em;
+}
+
+header > nav > a:hover {
+  color: var(--grey-1-8);
+  text-decoration: underline;
+}
+
+.sub-header {
+  grid-area: n;
+  background-color: var(--sub-header-background);
+  color: var(--white);
+  display: none;
+}
+
+/* these aren't shown on mobile */
+
+.sub-header > label {
+  display: none;
+  margin-right: 1em;
+}
+
+.sub-header > select {
+  display: none;
+  background-color: transparent;
+  padding: 0.4em 0;
+  font-size: 1em;
+  width: 13.5%;
+  color: white;
+  border: none;
+  border-bottom: 1px solid var(--search-border);
+
+  appearance: none;
+  background-image: url('../_images/drop_down_icon.svg');
+  background-repeat: no-repeat;
+  background-position-x: 100%;
+  background-position-y: 50%;
+
+  cursor: pointer;
+}
+
+.sub-header option {
+    color: black;
+}
+
+.sub-header > select:focus {
+  outline: none;
+}
+
+.sub-header > .settings {
+  color: var(--settings);
+  display: none;
+  margin-left: 1em;
+  margin-right: 0.5em;
+}
+
+.sub-header > .settings:hover {
+    cursor: pointer;
+}
+
+.setting h3 {
+  display: inline-block;
+  margin-left: 2em;
+}
+
+.sub-header > .settings:hover {
+  color: var(--settings-hover);
+}
+
+/* footer stuff */
+footer {
+  grid-area: f;
+  font-size: 14px;
+  text-align: right;
+  color: var(--footer-text);
+  margin-top: auto;
+  max-height: min-content;
+}
+
+footer a {
+  text-decoration: underline;
+  color: var(--footer-link);
+}
+
+/* sidebar stuff */
+
+aside {
+  grid-area: s;
+  font-size: 14px;
+  line-height: 1.75em;
+  top: 0;
+  position: -webkit-sticky; /* safari */
+  position: sticky;
+  background-color: var(--mobile-nav-background);
+  color: var(--mobile-nav-text);
+  z-index: 2;
+  max-height: 100vh;
+  overflow-y: auto;
+  overscroll-behavior-y: contain;
+}
+
+aside h3 {
+  color: var(--mobile-nav-header-text);
+  font-size: 24px;
+  font-weight: normal;
+}
+
+.collapsible-arrow {
+  font-size: 1.5em!important;
+  left: -1.166em;
+  top: 0.25em;
+  user-select: none;
+  position: relative;
+  line-height: 0.5em;
+  transition: transform 0.4s;
+  transform: rotate(-90deg);
+}
+
+.expanded {
+  transition: transform 0.4s;
+  transform: rotate(0deg);
+}
+
+.ref-internal-padding {
+  position: relative;
+  left: -20px;
+}
+
+#settings-toggle {
+  float: right;
+}
+
+aside .material-icons,
+.settings > .material-icons {
+  cursor: pointer;
+  font-size: 2em;
+}
+
+.sidebar-toggle {
+  display: unset !important;
+}
+
+#sidebar {
+  display: none;
+}
+
+#sidebar a {
+  color: var(--mobile-nav-text);
+}
+
+#sidebar a:hover {
+  color: var(--mobile-nav-hover-text);
+}
+
+#sidebar h3 {
+  font-size: 24px;
+  margin: 1em 1em 0 0;
+}
+
+/* TODO: Add a blurry mask to the begin and end of the first ul inside the div in the sidebar when there is overflow in this direction */
+
+#sidebar ul {
+  list-style: none;
+  margin: 1em 2em 2em 1em;
+  padding: 0;
+}
+
+#sidebar ul ul {
+  list-style: square;
+  margin: 0em;
+  margin-left: 1.5em;
+}
+
+#sidebar li.no-list-style {
+  list-style: none;
+}
+
+#sidebar form {
+  margin: 1em 0;
+  display: flex;
+  align-items: baseline;
+}
+
+/* search button stuff */
+
+.search-wrapper {
+  display: flex;
+  align-items: stretch;
+}
+
+.search-wrapper > input[type=search] {
+  font-family: "Roboto", Corbel, Avenir, "Lucida Grande", "Lucida Sans", sans-serif;
+  outline: none;
+  appearance: none;
+  font-size: 1em;
+}
+
+.search-wrapper > input[type=search],
+.search-wrapper > button[type=submit] {
+  background-color: var(--sub-header-background);
+  border: none;
+  color: var(--search-text);
+  padding: 0.5em;
+  min-height: 2.5em;
+  flex: 9;
+}
+
+.search-wrapper {
+  border-bottom: 1px solid var(--search-border);
+}
+
+.search-wrapper:focus-within {
+  border-bottom: 1px solid var(--search-focus);
+}
+
+/* .search-wrapper > input[type=search] {
+  border: 1px solid var(--search-border);
+  border-right: none;
+  border-top-left-radius: 4px;
+  border-bottom-left-radius: 4px;
+}
+
+.search-wrapper > input[type=search]:focus,
+button[type=submit]:focus ~ input[type=search] {
+  border: 1px solid var(--search-focus);
+  border-right: none;
+} */
+
+.search-wrapper > button[type=submit] {
+  color: var(--search-button);
+  /* border: 1px solid var(--search-border); */
+  /* border-left: none; */
+  /* border-bottom-right-radius: 4px; */
+  /* border-top-right-radius: 4px; */
+  cursor: pointer;
+  flex: 1;
+}
+
+/* .search-wrapper > button[type=submit]:focus,
+input[type=search]:focus ~ button[type=submit] {
+  border: 1px solid var(--search-focus);
+  border-left: none;
+} */
+
+.search-wrapper > button[type=submit]:hover {
+  background-color: var(--search-border);
+  color: var(--search-button-hover);
+}
+
+/* search sidebar */
+
+.search-sidebar > input[type=search],
+.search-sidebar > button[type=submit] {
+  background-color: var(--search-sidebar-background);
+  color: var(--search-sidebar-text);
+}
+
+.sidebar-toggle .search-sidebar > input[type=search],
+.sidebar-toggle .search-sidebar > button[type=submit] {
+  background-color: var(--mobile-nav-background);
+  color: var(--mobile-nav-text);
+}
+
+/* main content area */
+
+main {
+  grid-area: c;
+  min-height: 100%;
+  margin: 0;
+}
+
+p {
+  margin-bottom: 8px;
+}
+
+/* modal stuff */
+
+div.modal {
+  position: fixed;
+  z-index: 10;
+  left: 0;
+  top: 0;
+  width: 100%;
+  height: 100%;
+  overflow: hidden;
+  background-color: rgba(0,0,0,0.4);
+  cursor: pointer;
+  display: none;
+}
+
+div.modal-content {
+  background-color: var(--main-background);
+  box-shadow: 0 2px 8px rgba(0,0,0,0.54);
+  padding: 24px;
+  border-radius: 4px;
+  max-width: 40%;
+  min-width: 350px;
+  cursor: initial;
+  flex: 1;
+  margin: auto;
+}
+
+div.modal-content > span.close {
+  color: #888;
+  float: right;
+  font-weight: bold;
+  -moz-user-select: none;
+  -webkit-user-select: none;
+  cursor: pointer;
+  transform: rotate( 90deg );
+  transition: transform .2s ease-out,stroke-dasharray .2s ease-out,-webkit-transform .2s ease-out;
+  box-sizing: border-box;
+}
+
+div.modal-content > span.close:hover,
+div.modal-content > span.close:focus {
+  color: #fff;
+  transform: rotate(
+-90deg
+);
+  transition: transform .2s ease-out,stroke-dasharray .2s ease-out,-webkit-transform .2s ease-out;
+}
+
+div.modal input {
+  cursor: pointer;
+}
+
+/* scroll to top button */
+
+#to-top {
+  position: fixed;
+  bottom: 50px;
+  right: 20px;
+
+  cursor: pointer;
+}
+
+#to-top.is-rtd {
+  bottom: 90px;
+}
+
+#to-top > span {
+  display: block;
+
+  width: auto;
+  height: 30px;
+  padding: 0 6px;
+
+  background-color: var(--rtd-version-background);
+  color: var(--rtd-version-main-text);
+}
+
+#to-top span {
+  line-height: 30px;
+  font-size: 90%;
+  text-align: center;
+}
+
+/* copy button */
+
+.relative-copy {
+  position: relative;
+}
+
+.copy {
+  cursor: pointer;
+  position: absolute;
+  top: 0px;
+  right: 0px;
+  border: 1px solid var(--codeblock-border);
+  font-size: 0.875em;
+  padding: 0.2em 0.5em;
+  border-bottom-left-radius: 4px;
+  display: flex;
+}
+
+/* -- body styles --------------------------------------------------------- */
+
+hr {
+  border: 1px solid var(--hr-border);
+}
+
+main h1,
+main h2,
+main h3,
+main h4,
+main h5,
+main h6 { font-weight: normal; }
+
+main h1,
+main h2,
+main h3,
+main h4 { color: var(--main-big-headers-text); }
+main h5 { color: var(--main-h5-header-text); }
+main h6 { color: var(--main-h6-header-text); }
+
+main h1 { margin: 0 0 10px 0; }
+main h2,
+main h3 { margin: 10px 0px 10px 0px; }
+main h4,
+main h5,
+main h6 { margin: 20px 0px 10px 0px; }
+
+main h1 { padding: 0 0 10px 0; }
+main h2,
+main h3 { padding: 10px 0 10px 0; }
+main h4 { padding: 10px 0 10px 0; }
+main h5,
+main h6 { padding: 10px 0 0 0; }
+
+main h1,
+main h2,
+main h3 { border-bottom: 1px solid var(--main-big-headers-border); }
+main h4 { border-bottom: 1px solid var(--main-h4-header-border); }
+
+main h1 { font-size: 2.23em; }
+main h2 { font-size: 1.8em; }
+main h3 { font-size: 1.3em; }
+main h4 { font-size: 1.1em; }
+main h5 { font-size: 1.05em; }
+main h6 { font-size: 1em; }
+
+main h1 { display: block; vertical-align: middle; }
+
+a.headerlink {
+  color: var(--header-link);
+  font-size: 0.8em;
+  display: inline-block;
+  padding: 0 4px 0 4px;
+  text-decoration: none;
+  visibility: hidden;
+}
+
+a.headerlink:hover {
+  color: var(--header-link-hover-text);
+}
+
+h1:hover > a.headerlink,
+h2:hover > a.headerlink,
+h3:hover > a.headerlink,
+h4:hover > a.headerlink,
+h5:hover > a.headerlink,
+h6:hover > a.headerlink,
+dt:hover > a.headerlink,
+caption:hover > a.headerlink,
+p.caption:hover > a.headerlink,
+div.code-block-caption:hover > a.headerlink {
+    visibility: visible;
+}
+
+.versionmodified {
+  font-style: italic;
+}
+
+main ul {
+  list-style: disc;
+  margin: 1em 0;
+  padding-left: 1.3em;
+}
+
+main ul ul, main ol ul {
+  margin: .2em 0;
+  padding-left: 1.2em;
+}
+
+main ul li {
+  padding: 2px 0;
+}
+
+main ul.search li {
+  padding: 5px 0 5px 20px;
+}
+
+main
+main ol {
+  counter-reset: li;
+  margin-left: 0;
+  padding-left: 0;
+}
+
+main ol ol {
+  margin: .2em 0;
+}
+
+main ol > li {
+  margin: 0 0 0 1.9em;
+  padding: 2px 1px;
+  position: relative;
+}
+
+main ol > li::before {
+  display: none;
+  content: counter(li) ".";
+  counter-increment: li;
+  top: -2px;
+  left: -1.1em;
+  width: 1.1em;
+  padding: 4px 0;
+  position: absolute;
+  text-align: left;
+}
+
+main p,
+main dd,
+main li {
+  line-height: 1.4;
+}
+
+main img {
+  width: auto;
+  display: inline-block;
+  -ms-interpolation-mode: bicubic;
+  vertical-align: middle;
+  max-width: 100%
+}
+
+div.legend {
+  flex-direction: column;
+  align-items: center;
+  justify-content: center;
+}
+
+
+/* weird margins */
+li > p {
+  margin: 2px;
+}
+
+li > blockquote {
+  margin: 10px;
+}
+
+/* admonitions */
+div.admonition {
+  padding: 0 0.8em 0.8em 0.8em !important;
+  margin: 0.8em 0;
+  border-radius: 2.5px;
+  border-left-width: 6px;
+  border-left-style: solid;
+  background-color: var(--admonition-background);
+}
+
+p.admonition-title {
+  font-weight: bold;
+  margin: 0 -0.8rem !important;
+  padding: 0.4rem 0.6rem 0.4rem 2.5rem;
+  position: relative;
+  -moz-user-select: none;
+  -webkit-user-select: none;
+  -ms-user-select: none;
+  user-select: none;
+}
+
+p.admonition-title::before {
+  font: normal normal normal 24px/1 'Material Icons';
+  display: inline-block;
+  width: 24px;
+  height: 24px;
+  position: absolute;
+  left: 9.6px;
+}
+
+div.important, div.note, div.hint, div.tip {
+  border-left-color: var(--note-background);
+}
+
+div.important > p.admonition-title,
+div.note > p.admonition-title,
+div.hint > p.admonition-title,
+div.tip > p.admonition-title {
+  background-color: var(--note-background);
+  color: var(--note-text);
+}
+
+div.important > p.admonition-title::before,
+div.note > p.admonition-title::before,
+div.hint > p.admonition-title::before,
+div.tip > p.admonition-title::before {
+  content: '\0e88e';
+}
+
+div.attention, div.warning, div.caution {
+  border-left-color: var(--warning-background);
+}
+
+div.attention > p.admonition-title,
+div.warning > p.admonition-title,
+div.caution > p.admonition-title {
+  background-color: var(--warning-background);
+  color: var(--warning-text);
+}
+
+div.attention > p.admonition-title::before,
+div.warning > p.admonition-title::before,
+div.caution > p.admonition-title::before {
+  content: '\0e002';
+}
+
+div.danger, div.error {
+  border-left-color: var(--error-background);
+}
+
+div.danger > p.admonition-title,
+div.error > p.admonition-title {
+  background-color: var(--error-background);
+  color: var(--error-text);
+}
+
+div.danger > p.admonition-title::before,
+div.error > p.admonition-title::before {
+  content: '\0e000';
+}
+
+/* helpful admonitions */
+div.helpful {
+  border-left-color: var(--helpful-background);
+}
+
+div.helpful > p.admonition-title {
+  background-color: var(--helpful-background);
+  color: var(--helpful-text);
+}
+
+div.helpful > p.admonition-title::before {
+  content: '\0e873';
+}
+
+/* helpful admonitions */
+div.experimental {
+  border-left-color: var(--experimental-background);
+}
+
+div.experimental > p.admonition-title {
+  background-color: var(--experimental-background);
+  color: var(--experimental-text);
+}
+
+div.experimental > p.admonition-title::before {
+  font-family: FontAwesome, serif;
+  content: '\f0c3';
+}
+
+div.seealso > p.admonition-title::before {
+  content: '\e0f0';
+}
+
+dl.field-list > dd {
+  margin-top: 3px;
+  margin-bottom: 10px;
+  margin-left: 20px;
+}
+
+/* no disgusting background in the FAQ */
+div.topic {
+  background-color: transparent;
+  border: none;
+}
+
+/* don't link-ify the FAQ page */
+a.toc-backref {
+  text-decoration: none;
+  color: var(--main-text);
+}
+
+/* bold and fix the Parameter, Raises, etc. */
+dl.field-list > dt {
+  font-weight: bold;
+}
+
+/* remove flex from field lists */
+dl.field-list {
+  display: block;
+}
+
+/* cross-references are forced to bold for some reason */
+a.reference > strong {
+  font-weight: unset;
+  font-family: var(--monospace-font-family);
+}
+a.reference.pep > strong,
+a.reference.rfc > strong {
+  font-family: inherit;
+}
+
+/* exception hierarchy */
+
+.exception-hierarchy-content dd,
+.exception-hierarchy-content dl {
+  margin: 0px 2px;
+}
+
+.exception-hierarchy-content {
+  margin-left: 0.5em;
+}
+
+.exception-hierarchy-content ul {
+  list-style: '»' !important;
+}
+
+/* attribute tables */
+.py-attribute-table {
+  display: flex;
+  flex-wrap: wrap;
+  flex-direction: row;
+  margin: 0 2em;
+  padding-top: 16px;
+}
+
+.py-attribute-table-column {
+  flex: 1 1 auto;
+}
+
+.py-attribute-table-column:not(:first-child) {
+  margin-top: 1em;
+}
+
+.py-attribute-table-column > span {
+  font-weight: bold;
+  color: var(--attribute-table-title);
+}
+
+main .py-attribute-table-column > ul {
+  list-style: none;
+  margin: 4px 0px;
+  padding-left: 0;
+  font-size: 0.95em;
+}
+
+.py-attribute-table-entry {
+  margin: 0;
+  padding: 2px 0;
+  padding-left: 0.2em;
+  border-left: 2px solid var(--attribute-table-entry-border);
+  display: flex;
+  line-height: 1.2em;
+}
+
+.py-attribute-table-entry > a {
+  padding-left: 0.5em;
+  color: var(--attribute-table-entry-text);
+  flex-grow: 1;
+}
+
+.py-attribute-table-entry > a:hover {
+  color: var(--attribute-table-entry-hover-text);
+  text-decoration: none;
+}
+
+.py-attribute-table-entry:hover {
+  background-color: var(--attribute-table-entry-hover-background);
+  border-left: 2px solid var(--attribute-table-entry-hover-border);
+  text-decoration: none;
+}
+
+.py-attribute-table-badge {
+  flex-basis: 3em;
+  text-align: right;
+  font-size: 0.9em;
+  color: var(--attribute-table-badge);
+  -moz-user-select: none;
+  -webkit-user-select: none;
+  user-select: none;
+}
+
+pre {
+  background-color: var(--codeblock-background);
+  border: 1px solid var(--codeblock-border);
+  color: var(--codeblock-text);
+  font-size: 0.75em;
+  line-height: 1.5em;
+  margin: 1.5em 0 1.5em 0;
+  padding: 10px;
+  overflow-x: auto;
+}
+
+pre, code {
+  font-family: var(--monospace-font-family);
+  font-size: 0.9em;
+  overflow-wrap: break-word;
+}
+
+code {
+  background-color: var(--inline-code-background);
+  padding: .15em;
+  border-radius: 3px;
+}
+
+div.admonition code {
+  background-color: var(--admonition-inline-code-background);
+}
+
+code.descname {
+  background-color: transparent;
+  font-weight: bold;
+  font-size: 0.95em;
+}
+
+code.descclassname {
+  background-color: transparent;
+  padding-right: 0;
+}
+
+code.descclassname + code.descname {
+  padding-left: 0;
+}
+
+code.xref, a code {
+  font-weight: normal;
+  background-color: var(--xref-code-background);
+}
+
+span.pre {
+  padding: 0 2px;
+}
+
+dl.class {
+  margin-bottom: 50px;
+}
+
+dl.data > dt,
+dl.describe > dt,
+dl.function > dt,
+dl.attribute > dt,
+dl.classmethod > dt,
+dl.method > dt,
+dl.property > dt,
+dl.class > dt,
+dl.exception > dt {
+  background-color: var(--api-entry-background);
+  padding: 1px 10px;
+}
+
+/* bug in sphinx: https://github.com/sphinx-doc/sphinx/issues/9384 */
+dl.property > dt > span.descname + em.property {
+  display: none;
+}
+
+dd {
+  margin-top: 0.5em;
+  margin-bottom: 0.5em;
+  margin-left: 1.5em;
+}
+
+dt:target, span.highlighted {
+    background-color: var(--highlighted-text);
+}
+
+rect.highlighted {
+    fill: var(--highlighted-text);
+}
+
+.container.operations {
+  padding: 10px;
+  border: 1px solid var(--codeblock-border);
+  margin-bottom: 20px;
+}
+
+.container.operations::before {
+  content: 'Supported Operations';
+  color: var(--main-big-headers-text);
+  display: block;
+  padding-bottom: 0.5em;
+}
+
+.container.operations > dl.describe > dt {
+  background-color: var(--api-entry-background);
+}
+
+.table-wrapper {
+  overflow-x: auto;
+  width: fit-content;
+}
+
+table.docutils {
+  width: 100%;
+  border-collapse: collapse;
+}
+
+table.docutils.footnote {
+  width: auto;
+}
+
+table.docutils thead,
+table.docutils tfoot {
+  background: var(--table-header-background);
+}
+
+table.docutils thead tr th {
+  color: var(--table-text);
+  font-weight: normal;
+  padding: 7px 5px;
+  vertical-align: middle;
+}
+
+table.docutils tbody tr th,
+table.docutils tbody tr td {
+  border-bottom: 0;
+  padding: 7px 5px;
+  vertical-align: top;
+}
+
+table.docutils tbody tr:not(:first-child) {
+  border-top: solid 1px var(--table-border);
+}
+
+table.docutils tbody tr:last-child th,
+table.docutils tbody tr:last-child td {
+  border-bottom: solid 1px var(--table-border);
+}
+
+table.docutils thead tr td p,
+table.docutils tfoot tr td p,
+/*table.docutils tbody tr td p/*/
+table.docutils thead tr td ul,
+table.docutils tfoot tr td ul,
+table.docutils tbody tr td ul,
+table.docutils thead tr td ol,
+table.docutils tfoot tr td ol,
+table.docutils tbody tr td ol {
+  margin: 0 0 .5em;
+}
+table.docutils thead tr td p.last,
+table.docutils tfoot tr td p.last,
+table.docutils tbody tr td p.last,
+table.docutils thead tr td ul.last,
+table.docutils tfoot tr td ul.last,
+table.docutils tbody tr td ul.last,
+table.docutils thead tr td ol.last,
+table.docutils tfoot tr td ol.last,
+table.docutils tbody tr td ol.last {
+  margin-bottom: 0;
+}
+
+/* added when the `align` attribute is specified in the `image` directive */
+main img.align-left {
+  margin-left: .5em;
+}
+
+main img.align-right {
+  margin-right: .5em;
+}
+
+.align-default {
+  text-align: left !important;
+}
+
+/* hide the welcome text */
+section#welcome-to-discord-py-message-components > h1 {
+  display: none;
+}
+
+/* make the RTD ad look a little less jarring */
+
+.ethical-fixedfooter {
+  background-color: var(--rtd-ad-background) !important;
+  border-top: 1px solid var(--rtd-ad-border) !important;
+}
+
+.ethical-fixedfooter a {
+  color: var(--rtd-ad-main-text) !important;
+}
+
+.ethical-callout > small > em > a {
+  color: var(--rtd-ad-small-text) !important;
+}
+
+.active {
+  background-color: var(--mobile-active-toc);
+  border-left: 5px solid var(--mobile-active-toc);
+}
+
+div.code-block-caption {
+  font-size: medium;
+  font-weight: bold;
+}
+
+.key-combo {
+    font-size: 12px;
+    line-height: 12px;
+    /*text-transform: uppercase;*/
+    font-weight: 600;
+    display: -webkit-box;
+    display: -ms-flexbox;
+    display: inline-flex;
+}
+
+.key {
+    background-color: var(--key-background-color);
+    border: 1px solid var(--key-border-color);
+    display: inline-table; /* For very small phone screens that require line wrapping */
+    padding: 3px 6px 4px;
+    border-radius: 4px;
+    cursor: default;
+    min-width: 14px;
+    min-height: 14px;
+    text-align: center;
+    word-break-wrap: break-word;
+}
+
+.key-combo, .key {
+    -webkit-box-sizing: border-box;
+    box-sizing: border-box;
+    position: relative;
+    height: 23px;
+    -webkit-user-select: none;
+    -moz-user-select: none;
+    -ms-user-select: none;
+    user-select: none;
+}
+
+.key-combo .key {
+    color: var(--key-content-color);
+    -webkit-box-shadow: inset 0 -4px 0 var(--key-shadow-color);
+    box-shadow: inset 0 -4px 0 var(--key-shadow-color);
+}
+
+.key:not(:last-child) {
+    margin-right: 3px;
+}
+
+/*.key-combo .key:hover {*/
+/*    color: var(--key-content-color--active);*/
+/*}*/
+
+.key-combo .key:active {
+    color: var(--key-content-color--active);
+    -webkit-box-shadow: inset 0 -2px 0 var(--key-shadow-color--active);
+    box-shadow: inset 0 -2px 0 var(--key-shadow-color--active);
+    border: 1px solid var(--key-border-color--active);
+}
+
+.key:active {
+    -webkit-transform: translateY(2px);
+    transform: translateY(2px);
+    height: 21px;
+    padding-bottom: 2px;
+}
+
+/*Let the keys go back to normal on phone when you release the key*/
+@media (hover: none) {
+    .key-combo .key:active {
+        -webkit-transform: translateY(0);
+        transform: translateY(0);
+        height: 23px;
+        padding-bottom: 0;
+    }
+}
+
+/*The following styles should only be applied when it is not a touch device*/
+@media (hover: hover) {
+    .key-combo .key:hover {
+        -webkit-box-shadow: inset 0 -2px 0 var(--key-shadow-color--active);
+        box-shadow: inset 0 -2px 0 var(--key-shadow-color--active);
+        border: 1px solid var(--key-border-color--active);
+    }
+
+    li > p:hover span.key-combo .key {
+        color: var(--key-content-color--active);
+        box-shadow: inset 0 -2px 0 var(--key-shadow-color--active);
+        border: 1px solid var(--key-border-color--active);
+        -webkit-transform: translateY(2px);
+        transform: translateY(2px);
+        height: 21px;
+        padding-bottom: 2px;
+    }
+
+}
+
+/* desktop stuff */
+
+@media screen and (min-width: 600px) {
+  .grid-item {
+    max-width: unset;
+  }
+
+  .main-grid {
+    grid-template-areas:
+      "h h h h h h"
+      "n n n n n n"
+      "s s c c c c"
+      "s s f f f f";
+  }
+
+  .mobile-only {
+    display: none;
+  }
+
+  header {
+    background-color: var(--black);
+  }
+
+  header > nav {
+    background-color: unset;
+  }
+
+  .sub-header {
+    display: flex;
+    align-items: center;
+  }
+
+  .sub-header > label {
+    display: initial;
+  }
+
+  .sub-header > select {
+    display: initial;
+    margin-right: auto;
+  }
+
+  .sub-header > .settings {
+    display: initial;
+  }
+
+  aside {
+    top: initial;
+    position: initial;
+    background-color: var(--nav-background);
+    color: var(--nav-text);
+    max-height: unset;
+    overflow-y: unset;
+    display: flex; /**/
+    overscroll-behavior-y: unset;
+  }
+
+  aside h3 {
+    color: var(--nav-header-text);
+  }
+
+  #sidebar {
+    display: grid;
+    position: sticky;
+    top: 1em;
+    max-height: calc(100vh - 2em);
+    overflow-y: auto;
+    margin: 1em;
+    width: auto;
+  }
+
+  #sidebar a {
+    color: var(--nav-text);
+  }
+
+  .active {
+    background-color: transparent;
+    border-left: none;
+    position: relative;
+  }
+
+  .active::before {
+    content: "";
+    display: inline-block;
+    background-color: var(--active-toc);
+    position: absolute;
+    top: 0;
+    bottom: 0;
+    right: 0;
+    width: calc(100% + 0.5em);
+    border-radius: 4px;
+    z-index: -1;
+  }
+
+  #sidebar a:hover {
+    color: var(--nav-hover-text);
+  }
+
+  #hamburger-toggle, #settings-toggle {
+    display: none;
+
+  }
+}
+
+@media screen and (min-width: 1200px) {
+  .main-grid {
+    /* 62.5% width => multiple of 5/8 content */
+    /* sidebar takes up 20% of the inner area */
+    grid-template-columns: repeat(16, 1fr);
+    grid-template-areas:
+      "h h h h h h h h h h h h h h h h"
+      "n n n n n n n n n n n n n n n n"
+      "s s s s . c c c c c c c c c c ."
+      "s s s s f f f f f f f f f f f f"
+  }
+
+  header > nav {
+    margin-left: 18.75%;
+    margin-right: 18.75%;
+  }
+
+  .sub-header > label {
+    margin-left: 18.75%;
+    margin-right: 1em;
+  }
+
+  .sub-header > .settings {
+    margin-right: 18.75%;
+    margin-left: 1em;
+  }
+
+  .sub-header > .search {
+    width: 20%;
+  }
+
+  .py-attribute-table-column:not(:first-child) {
+    margin-top: unset;
+  }
+
+  main img {
+    margin-left: auto;
+    margin-right: auto;
+  }
+}
\ No newline at end of file
diff --git a/docs/_templates/genindex.html b/docs/_templates/genindex.html
new file mode 100644
index 00000000..a5f2262f
--- /dev/null
+++ b/docs/_templates/genindex.html
@@ -0,0 +1,27 @@
+{%- extends "basic/genindex.html" %}
+
+{% block body %}
+  {{ super() }}
+  <!-- Inject some JavaScript to convert the index names into something useful. -->
+  <script>
+    let elements = document.querySelectorAll("table.indextable a");
+
+    // this is pretty finicky but it should work.
+    for(let el of elements) {
+      let key = el.getAttribute('href').split('#', 2)[1]
+      if(!key.startsWith('discord.')) {
+        continue;
+      }
+
+      if(key.startsWith('discord.ext.')) {
+        key = key.substr(12); // discord.ext.
+      }
+
+      if(el.textContent.indexOf('()') !== -1) {
+        key = key + '()'
+      }
+      el.textContent = key;
+    }
+    document.querySelectorAll("td").forEach(el => el.style.width = 'auto');
+  </script>
+{% endblock %}
diff --git a/docs/_templates/layout.html b/docs/_templates/layout.html
new file mode 100644
index 00000000..631d4d47
--- /dev/null
+++ b/docs/_templates/layout.html
@@ -0,0 +1,198 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <meta charset="utf-8">
+  <meta name="viewport" content="width=device-width, initial-scale=1.0">
+  <meta name="theme-color" content="#5865F2">
+  <title>{{ title|striptags|e }}{{ titlesuffix }}</title>
+  {%- block extrahead %} {% endblock %}
+  <!-- end extra head -->
+  <link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
+  <script src="https://kit.fontawesome.com/1c42fd883f.js" crossorigin="anonymous"></script>
+  <link rel="stylesheet" href="{{ pathto('_static/style.css', 1)|e }}" type="text/css" />
+  <link rel="stylesheet" href="{{ pathto('_static/codeblocks.css', 1) }}" type="text/css" />
+  <link rel="stylesheet" href="{{ pathto('_static/icons.css', 1)|e }}" type="text/css" />
+  {%- block css %}
+  {%- for css in css_files %}
+    {%- if css|attr("filename") %}
+  {{ css_tag(css) }}
+    {%- else %}
+  <link rel="stylesheet" href="{{ pathto(css, 1)|e }}" type="text/css" />
+    {%- endif %}
+  {%- endfor %}
+  {%- endblock %}
+  {%- block scripts %}
+  <script id="documentation_options" data-url_root="{{ pathto('', 1) }}" src="{{ pathto('_static/documentation_options.js', 1) }}"></script>
+  {%- for js in script_files %}
+  {{ js_tag(js) }}
+  {%- endfor %}
+  {%- endblock %}
+  {%- if pageurl %}
+  <link rel="canonical" href="{{ pageurl|e }}" />
+  {%- endif %}
+  {%- if favicon %}
+  <link rel="shortcut icon" href="{{ pathto('_static/' + favicon, 1)|e }}"/>
+  {%- endif %}
+  {%- block linktags %}
+  {%- if hasdoc('about') %}
+  <link rel="author" title="{{ _('About these documents') }}" href="{{ pathto('about') }}" />
+  {%- endif %}
+  {%- if hasdoc('genindex') %}
+  <link rel="index" title="{{ _('Index') }}" href="{{ pathto('genindex') }}" />
+  {%- endif %}
+  {%- if hasdoc('search') %}
+  <link rel="search" title="{{ _('Search') }}" href="{{ pathto('search') }}" />
+  {%- endif %}
+  {%- if hasdoc('copyright') %}
+  <link rel="copyright" title="{{ _('Copyright') }}" href="{{ pathto('copyright') }}" />
+  {%- endif %}
+  {%- if next %}
+  <link rel="next" title="{{ next.title|striptags|e }}" href="{{ next.link|e }}" />
+  {%- endif %}
+  {%- if prev %}
+  <link rel="prev" title="{{ prev.title|striptags|e }}" href="{{ prev.link|e }}" />
+  {%- endif %}
+  {%- endblock %}
+</head>
+<body>
+{%- block header %}{% endblock %}
+  <div class="main-grid">
+    {#- The main navigation header #}
+    <header class="grid-item">
+      <nav>
+        <a href="{{ pathto(master_doc)|e }}" class="main-heading">discord.py-message-components</a>
+        <a href="{{ github_url }}" title="GitHub"><span class="fa-1x fa-brands fa-github" aria-hidden="true"></span></a>
+        <a href="{{ discord_invite }}" title="{{ _('Discord') }}"><span class="fa-1x fa-brands fa-discord" aria-hidden="true"></span></a>
+        <a href="{{ pathto('faq') }}" title="FAQ"><span class="material-icons" aria-hidden="true">help_center</span></a>
+        {#- If we have more links we can put them here #}
+        <a onclick="mobileSearch.open();" title="{{ _('Search') }}" id="open-search" class="mobile-only"><span class="material-icons" aria-hidden="true">search</span></a>
+        <a onclick="mobileSearch.close();" title="{{ _('Close') }}" id="close-search" class="mobile-only" hidden><span class="material-icons" aria-hidden="true">close</span></a>
+      </nav>
+      <nav class="mobile-only">
+        <form role="search" class="search" action="{{ pathto('search') }}" method="get">
+          <div class="search-wrapper">
+            <input type="search" id="top-bar-search-input-mobile" name="q" placeholder="{{ _('Search documentation') }}" />
+            <button type="submit">
+              <span class="material-icons" aria-hidden="true">search</span>
+            </button>
+          </div>
+        </form>
+      </nav>
+    </header>
+    {#- The sub-header with search and extension related selection #}
+    <div class="sub-header grid-item">
+      <label for="documentation_select">{{ _('View Documentation For') }}</label>
+      <select id="documentation_select" onchange="window.location = this.value;">
+        {%- if pagename is prefixedwith(('ext/', 'oauth2')) %}
+        <option value="{{ pathto(master_doc)|e }}">discord</option>
+        {%- else %}
+        <option value="{{ pathto(pagename) }}" selected>discord</option>
+        {%- endif %}
+        {%- for ext, p in discord_extensions %}
+        <option value="{{ pathto(p + '/index')|e }}" {% if pagename is prefixedwith p %}selected{% endif %}>{{ ext }}</option>
+        {%- endfor %}
+      </select>
+      <form role="search" class="search" action="{{ pathto('search') }}" method="get">
+        <div class="search-wrapper">
+          <input type="search" id="top-bar-search-input" name="q" placeholder="{{ _('Search documentation') }}" />
+          <button type="submit">
+            <span class="material-icons">search</span>
+          </button>
+        </div>
+      </form>
+      <a accesskey="s" class="settings"><span class="fa-1x fa-solid fa-gear"></span></a>
+    </div>
+    {#- The sidebar component #}
+    <aside class="grid-item">
+      {%- if display_toc %}
+      <span id="hamburger-toggle">
+        <span class="material-icons">menu</span>
+      </span>
+      {%- endif %}
+      <span id="settings-toggle" class="settings" onclick="openModal(this, false);">
+        <span class="fa-1x fa-solid fa-gear"></span>
+      </span>
+      <div id="sidebar">
+        {%- include "localtoc.html" %}
+      </div>
+    </aside>
+    {#- The actual body of the contents #}
+    <main class="grid-item" role="main">
+      {% block body %} {% endblock %}
+    </main>
+{%- block footer %}
+    <footer class="grid-item">
+    {%- if show_copyright %}
+      {%- if hasdoc('copyright') %}
+        {% trans path=pathto('copyright'), copyright=copyright|e %}&#169; <a href="{{ path }}">Copyright</a> {{ copyright }}.{% endtrans %}
+      {%- else %}
+        {% trans copyright=copyright|e %}&#169; Copyright {{ copyright }}.{% endtrans %}
+      {%- endif %}
+    {%- endif %}
+    {%- if last_updated %}
+      {% trans last_updated=last_updated|e %}Last updated on {{ last_updated }}.{% endtrans %}
+    {%- endif %}
+    {%- if show_sphinx %}
+      {% trans sphinx_version=sphinx_version|e %}Created using <a href="https://www.sphinx-doc.org/">Sphinx</a> {{ sphinx_version }}.{% endtrans %}
+    {%- endif %}
+    </footer>
+{%- endblock %}
+  </div>
+  {%- if READTHEDOCS %}
+  <script>
+    if (typeof READTHEDOCS_DATA !== "undefined") {
+        if (!READTHEDOCS_DATA.features) {
+          READTHEDOCS_DATA.features = {};
+        }
+        READTHEDOCS_DATA.features.docsearch_disabled = true;
+      }
+  </script>
+  {%- endif %}
+
+  <div id="settings" class="modal" accesskey="s" onclick="if (event.target === this){ openModal(event, true); }" hidden>
+    <div class="modal-content">
+      <span class="close material-icons" onclick="openModal(event, true);" title="Close">close</span>
+      <h1>{{ _('Settings') }}</h1>
+
+      <h2>{{ _('Font') }}</h2>
+      <div class="setting">
+        <h3>{{ _('Use a serif font:') }}
+          <label class="toggle"
+            title="{{ _('Use a serif font? Your system font will be used, falling back to serif.')}}">
+            <input type="checkbox" name="useSerifFont" onclick="updateSetting(this);">
+            <span class="toggle-slider"></span>
+          </label>
+        </h3>
+      </div>
+
+      <h2>{{ _('Theme') }}</h2>
+      <div class="setting">
+        <h3>
+          <label class="toggle" title="{{ _('Set your theme based on your system preferences') }}">
+            <input type="radio" name="setTheme" onclick="updateSetting(this);" value="automatic" checked>
+          </label>
+          {{ _('Automatic') }}
+        </h3>
+        <h3>
+          <label class="toggle" title="{{ _('Set your theme to light theme') }}">
+            <input type="radio" name="setTheme" onclick="updateSetting(this);" value="light">
+          </label>
+          {{ _('Light') }}
+        </h3>
+        <h3>
+          <label class="toggle" title="{{ _('Set your theme to dark theme') }}">
+            <input type="radio" name="setTheme" onclick="updateSetting(this);" value="dark">
+          </label>
+          {{ _('Dark') }}
+        </h3>
+      </div>
+
+    </div>
+  </div>
+
+  <div id="to-top" onclick="scrollToTop()" {%- if READTHEDOCS %} class="is-rtd"{%- endif %} hidden>
+    <span><span class="material-icons">arrow_upward</span> to top</span>
+  </div>
+
+</body>
+</html>
diff --git a/docs/_templates/relations.html b/docs/_templates/relations.html
new file mode 100644
index 00000000..db904e8c
--- /dev/null
+++ b/docs/_templates/relations.html
@@ -0,0 +1 @@
+<!-- purposefully empty -->
diff --git a/docs/additions.rst b/docs/additions.rst
deleted file mode 100644
index 009b0750..00000000
--- a/docs/additions.rst
+++ /dev/null
@@ -1,371 +0,0 @@
-Additions and adjustments to discord.py builtin-functions
-=========================================================
-
-.. class:: discord.Client
-
-
-    .. decorator:: on_click(custom_id=None)
-
-        A decorator with which you can assign a function to a specific :class:`Button` (or its custom_id).
-
-        .. important::
-            The Function this decorator attached to must be an coroutine (means an awaitable) and take the same parameters as a :class:`on_raw_button_click`
-
-        .. _button_click-parameters:
-
-        :param custom_id: If the :attr:`custom_id` of the Button could not use as an function name or you want to give the function a different name then the custom_id use this one to set the custom_id.
-        :type custom_id: Optional[:class:`str`]
-
-        .. _button_click-example:
-
-        **Example**
-
-        .. code-block:: python
-
-            # the Button
-            Button(label='Hey im a cool blue Button',
-                    custom_id='cool blue Button',
-                    style=ButtonColor.blurple)
-
-            # function that's called when the Button pressed
-            @client.on_click(custom_id='cool blue Button')
-            async def cool_blue_button(i: discord.Interaction, button):
-                await i.respond('Hey you pressed a `cool blue Button`!', hidden=True)
-
-
-        :raise TypeError: The coroutine passed is not actually a coroutine.
-
-
-    .. decorator:: on_select(custom_id=None)
-
-        A decorator with which you can assign a function to a specific :class:`SelectMenu` (or its custom_id).
-
-        .. important::
-            The Function this decorator attached to must be an coroutine(means an awaitable) and take the same parameters as a :class:`on_raw_selection_select`!
-
-        .. _on_select-parameters:
-
-        :param custom_id: If the :attr:`custom_id` of the :class:`SelectMenu` could not use as an function name or you want to give the function a different name then the custom_id use this one to set the custom_id.
-        :type custom_id: Optional[:class:`str`]
-
-        .. _on_select-example:
-
-        **Example**
-
-        .. code-block:: python
-
-            # the SelectMenu
-            SelectMenu(custom_id='choose_your_gender',
-                       options=[
-                            select_option(label='Female', value='Female', emoji='♀️'),
-                            select_option(label='Male', value='Male', emoji='♂️'),
-                            select_option(label='Trans/Non Binary', value='Trans/Non Binary', emoji='⚧')
-                            ], placeholder='Choose your Gender')
-
-            # function that's called when the SelectMenu is used
-            @client.on_select()
-            async def choose_your_gender(i: discord.Interaction, select_menu):
-                await i.respond(f'You selected `{select_menu.values[0]}`!', hidden=True)
-
-
-        :raise TypeError: The coroutine passed is not actually a coroutine.
-
-
-.. _events:
-
-Events
-~~~~~~
-
-
-.. function:: on_button_click(interaction, button)
-
-    This Event will be triggered if a Button, that is attached to a Message wich is in the internal Cache, is pressed.
-
-    :param interaction: The `Interaction <./interaction.html#Interaction>`_-object with all his attributes and methods to respond to the interaction
-    :type interaction: :class:`discord.Interaction`
-    :param button: The `ButtonClick <./interaction.html#ButtonClick>`_ if the message is ephemeral else `Button <./components.html#Button>`_. (this is also in the first parameter under ``component``).
-    :type button: Union[:class:`Button`, :class:`ButtonClick`]
-
-    .. _on_button_click-example:
-
-    **Example**
-
-    .. code-block:: python
-
-        @client.event
-        async def on_button_click(interaction: discord.Interaction, button):
-            await interaction.respond('Hey you pressed an Button!', delete_after=10)
-
-
-________________________________________________
-
-
-.. function:: on_raw_button_click(interaction, button)
-
-    This Event will be triggered if a Button, that is attached to **any** Message of this Bot is pressed.
-
-    :param interaction: The :class:`discord.Interaction` that contains all information about the Interaction.
-    :type interaction: :class:`discord.Interaction`
-    :param button: The `ButtonClick <./interaction.html#ButtonClick>`_ if the message is ephemeral else `Button <./components.html#Button>`_. (this is also in the first parameter under ``component``).
-    :type button: Union[:class:`Button`, :class:`ButtonClick`]
-
-    .. _on_raw_button_click-example:
-
-    **Example**
-
-    .. code-block:: python
-
-        @client.event
-        async def on_raw_button_click(interaction: discord.Interaction, button):
-            await interaction.respond('Hey you pressed an Button!', delete_after=10)
-
-
-
---------------------------------------------------
-
-.. function:: on_selection_select(interaction, select_menu)
-
-    This Event will be triggered if a :class:`SelectMenu`, that is attached to a Message of this Bot wich is in the internal Cache, is used.
-
-
-    .. _on_selection_select-example:
-
-    **Example**
-
-    .. code-block:: python
-
-        @client.event
-        async def on_selection_select(interaction: discord.Interaction, select_menu):
-            await interaction.respond(f'Hey {interaction.author.mention} you select {", ".join(select_menu.values)}!', hidden=True)
-
-
-
-________________________________________________
-
-
-.. function:: on_raw_selection_select(interaction, select_menu)
-
-    This Event will be triggered if a :class:`SelectMenu`, that is attached to **any** Message of this Bot is used.
-    
-    :param interaction: The `Interaction <./interaction.html#Interaction>`_ that contains all information about the Interaction.
-    :type interaction: :class:`discord.Interaction`
-    :param select: The `SelectionSelect <./interaction.html#SelectionSelect>`_ if the message is ephemeral else `SelectMenu <./components.html#SelectMenu>`_  but with the :attr:`values` wich contains a list of the selected options. (this is also in the first parameter under ``component``).
-    :type select: Union[:class:`SelectMenu`, :class:`SelectionSelect`]
-
-    .. _on_raw_selection_select-example:
-
-    **Example**
-
-    .. code-block:: python
-
-        @client.event
-        async def on_raw_selection_select(interaction: discord.Interaction, select_menu):
-            await interaction.edit(f'Hey {interaction.author.mention} you select {", ".join(select_menu.values)}!', hidden=True)
-
-
-_______________________________________
-
-.. _abc-messageable:
-
-.. class:: abc.Messageable
-
-    This has the same methods as a normal message as well except for a change to the :meth:`send` method.
-
-    .. _abc-messageable-send:
-
-    .. classmethod:: send(**kwargs)
-
-        .. _abc-messageable-send-parameters:
-
-        These are the parameters that have been added by this, the others are still present and can be seen in the docs of discord.py
-
-        :param components: A List of components that should send with the Message these can be either in `ActionRow <./components.html#actionrow>`_'s or in :class:`list`'s.
-        :type components: Optional[List[Union[List[Button, SelectionSelect], ActionRow[Button, SelectionSelect]]]]
-        :param embeds: A List of up to 10 :class:`discord.Embed`'s that should send with the Message.
-        :type embeds:  Optional[List[discord.Embed]]
-
-_____________________________
-
-.. class:: ext.commands.Cog
-
-    This class has also the decorators for custom_id's as the normal :class:`discord.Client` Class.
-
-    .. decorator:: commands.Cog.on_click(custom_id=None)
-
-        This works like the :meth:`discord.Client.on_click` decorator of the :class:`discord.Client` but it give ``self`` (The Cog-Class) as the 1. Parameter.
-
-        **Example**
-
-        .. code-block:: python
-
-            # The Button
-            Button(label='Hello', custom_id='my_button')
-
-            #The decorator
-            @commands.Cog.on_click()
-            async def my_button(i: discord.Interaction, button):
-                await i.respond('Hey you pressed a Button!')
-
-    .. decorator:: commands.Cog.on_select(custom_id=None)
-
-        This works like the :meth:`discord.Client.on_select` decorator of the :class:`discord.Client` but it give ``self`` (The Cog-Class) as the 1. Parameter.
-
-        **Example**
-
-        .. code-block:: python
-
-            # The SelectMenu
-            SelectMenu(custom_id='select_decorator_example',
-                       options=[
-                           SelectOption('The 1. Option', '1', 'The first option you have', '1️⃣'),
-                           SelectOption('The 2. Option', '2', 'The second option you have', '2️⃣')
-                       ], placeholder='Select a Option')
-
-            #The decorator
-            @commands.Cog.on_select()
-            async def select_decorator_example(i: discord.Interaction, select_menu):
-                await i.edit(content=f'You choice was the {select_menu.values[0]}. Option. 😀')
-
-----------------------------------
-
-.. _discord-message:
-
-.. class:: discord.Message
-
-and
-
-.. class:: discord.PartialMessage
-
-    .. _discord-message-attributes:
-
-
-    This has the same attributes as a normal message but one is added in addition
-
-    .. attribute:: components
-
-        A Optional[List[:class:`ActionRow`]] containing the components of the message.
-
-    .. attribute:: all_components
-
-        Returns all :class:`Button`'s and :class:`SelectMenu`'s that are contained in the message
-
-        .. note::
-            This is equal to:
-            
-            .. code-block:: python
-
-                for action_row in self.components:
-                    for component in action_row:
-                        yield component
-
-        :yields: Union[:class:`Button`, :class:`SelectMenu`]
-
-    .. attribute:: all_buttons
-
-        Returns all :class:`Button`'s that are contained in the message
-
-        .. note::
-            This is equal to:
-            
-            .. code-block:: python
-
-                for action_row in self.components:
-                    for component in action_row:
-                        yield component
-
-        :yields: :class:`Button`
-
-    .. attribute:: all_select_menus
-
-        Returns all :class:`SelectMenu`'s that are contained in the message
-
-        .. note::
-            This is equal to:
-            
-            .. code-block:: python
-
-                for action_row in self.components:
-                    for component in action_row:
-                        if isinstance(component, SelectMenu):
-                            yield component
-
-        :yields: :class:`SelectMenu`
-
-    This has the same methods as a normal message but one is added in addition.
-
-    .. _discord-message-edit:
-
-    .. method:: edit(**kwargs)
-
-        This takes the same parameters as the normal :func:`edit` function except for two added parameters.
-
-        .. _discord-message-edit-parameters:
-
-        :param components: A List of components that should replace the previous ones these can be either in `ActionRow <./components.html#actionrow>`_'s or in :class:`list`'s.
-        :type components: Optional[List[Union[List[:class:`Button`, :class:`SelectMenu`], ActionRow[:class:`Button`, :class:`SelectMenu`]]]]
-        :param embeds: A list of up to 10 :class:`discord.Embed`'s to replace the previous ones(This is also usable for normal Messages).
-        :type embeds: Optional[List[:class:`discord.Embed`]]
-
-utils
-~~~~~
-
-.. function:: styled_timestamp(timestamp, style)
-
-    A small function that returns a styled timestamp for discord, this will be displayed accordingly in the Discord client depending on the :attr:`style` specified.
-
-    Timestamps will display the given timestamp in the user's timezone and locale.
-
-    :param timestamp: Union[`datetime.datetime <https://docs.python.org/3/library/datetime.html#datetime.datetime>`_, :class:`int`]
-        The timestamp; A :class:`datetime.datetime` object or an already completed timestamp.
-
-    :param style: Optional[Union[:class:`TimestampStyle`, :class:`str`]]
-        How the timestamp should be displayed in Discord; this can either be a :class:`TimestampStyle` or directly the associated value.
-
-        :default: :class:`TimestampStyle.short`
-
-    **Example**
-
-    .. code-block:: python
-
-        @client.command()
-        async def time(ctx):
-            await ctx.send(discord.utils.styled_timestamp(datetime.now(), discord.TimestampStyle.long))
-
-.. class:: TimestampStyle
-
-    .. note::
-        This is located in discord.enums but i place it here
-
-    The Styles you could use for the :attr:`style` of a :class:`styled_timestamp`
-
-    See also in the `Discord-Documentation <https://discord.com/developers/docs/reference#message-formatting-timestamp-styles>`_
-
-    +----------------------------------+-------+-----------------+--------------------------------+
-    | NAME                             | VALUE | DESCRIPTION     | EXAMPLE                        |
-    +==================================+=======+=================+================================+
-    | .. attribute:: short_time        |  't'  | Short Time      | .. image:: imgs/short_time.png |
-    +----------------------------------+-------+-----------------+--------------------------------+
-    | .. attribute:: long_time         |  'T'  | Long Time       | .. image:: imgs/long_time.png  |
-    +----------------------------------+-------+-----------------+--------------------------------+
-    | .. attribute:: short_date        |  'd'  | Short Date      | .. image:: imgs/short_date.png |
-    +----------------------------------+-------+-----------------+--------------------------------+
-    | .. attribute:: long_date         |  'D'  | Long Date       | .. image:: imgs/long_date.png  |
-    +----------------------------------+-------+-----------------+--------------------------------+
-    | .. attribute:: short             |  'f'  | Short Date/Time | .. image:: imgs/short.png      |
-    +----------------------------------+-------+-----------------+--------------------------------+
-    | .. attribute:: long              |  'F'  | Long Date/Time  | .. image:: imgs/long.png       |
-    +----------------------------------+-------+-----------------+--------------------------------+
-    | .. attribute:: relative          |  'R'  | Relative Time   | .. image:: imgs/relative.png   |
-    +----------------------------------+-------+-----------------+--------------------------------+
-
-.. toctree::
-   :maxdepth: 3
-   :caption: Contents: 
-
-
-Indices and tables
-~~~~~~~~~~~~~~~~~~
-
-* :ref:`genindex`
-* :ref:`modindex`
-* :ref:`search`
diff --git a/docs/api/abcs.rst b/docs/api/abcs.rst
new file mode 100644
index 00000000..a41e309f
--- /dev/null
+++ b/docs/api/abcs.rst
@@ -0,0 +1,68 @@
+.. currentmodule:: discord
+
+.. _discord_api_abcs:
+
+Abstract Base Classes
+-----------------------
+
+An :term:`py:abstract base class` (also known as an ``abc``) is a class that models can inherit
+to get their behaviour. The Python implementation of an :doc:`abc <py:library/abc>` is
+slightly different in that you can register them at run-time. **Abstract base classes cannot be instantiated**.
+They are mainly there for usage with :func:`py:isinstance` and :func:`py:issubclass`\.
+
+This library has a module related to abstract base classes, some of which are actually from the :doc:`abc <py:library/abc>` standard
+module, others which are not.
+
+Snowflake
+~~~~~~~~~~
+
+.. attributetable:: discord.abc.Snowflake
+
+.. autoclass:: discord.abc.Snowflake
+    :members:
+
+User
+~~~~~
+
+.. attributetable:: discord.abc.User
+
+.. autoclass:: discord.abc.User
+    :members:
+
+PrivateChannel
+~~~~~~~~~~~~~~~
+
+.. attributetable:: discord.abc.PrivateChannel
+
+.. autoclass:: discord.abc.PrivateChannel
+    :members:
+
+GuildChannel
+~~~~~~~~~~~~~
+
+.. attributetable:: discord.abc.GuildChannel
+
+.. autoclass:: discord.abc.GuildChannel
+    :members:
+
+Messageable
+~~~~~~~~~~~~
+
+.. attributetable:: discord.abc.Messageable
+
+.. autoclass:: discord.abc.Messageable
+    :members:
+    :exclude-members: history, typing
+
+    .. automethod:: discord.abc.Messageable.history
+        :async-for:
+
+    .. automethod:: discord.abc.Messageable.typing
+        :async-with:
+
+Connectable
+~~~~~~~~~~~~
+
+.. attributetable:: discord.abc.Connectable
+
+.. autoclass:: discord.abc.Connectable
diff --git a/docs/api/application-info.rst b/docs/api/application-info.rst
new file mode 100644
index 00000000..f0eff419
--- /dev/null
+++ b/docs/api/application-info.rst
@@ -0,0 +1,28 @@
+.. currentmodule:: discord
+
+Application Info
+------------------
+
+AppInfo
+~~~~~~~~
+
+.. attributetable:: AppInfo
+
+.. autoclass:: AppInfo()
+    :members:
+
+Team
+~~~~~
+
+.. attributetable:: Team
+
+.. autoclass:: Team()
+    :members:
+
+TeamMember
+~~~~~~~~~~~
+
+.. attributetable:: TeamMember
+
+.. autoclass:: TeamMember()
+    :members:
diff --git a/docs/api/async-iterator.rst b/docs/api/async-iterator.rst
new file mode 100644
index 00000000..c1bd002b
--- /dev/null
+++ b/docs/api/async-iterator.rst
@@ -0,0 +1,130 @@
+.. currentmodule:: discord
+
+Async Iterator
+----------------
+
+Some API functions return an "async iterator". An async iterator is something that is
+capable of being used in an :ref:`async for statement <py:async for>`.
+
+These async iterators can be used as follows: ::
+
+    async for elem in channel.history():
+        # do stuff with elem here
+
+Certain utilities make working with async iterators easier, detailed below.
+
+.. class:: AsyncIterator
+
+    Represents the "AsyncIterator" concept. Note that no such class exists,
+    it is purely abstract.
+
+    .. container:: operations
+
+        .. describe:: async for x in y
+
+            Iterates over the contents of the async iterator.
+
+
+    .. method:: next()
+        :async:
+
+        |coro|
+
+        Advances the iterator by one, if possible. If no more items are found
+        then this raises :exc:`NoMoreItems`.
+
+    .. method:: get(**attrs)
+        :async:
+
+        |coro|
+
+        Similar to :func:`utils.get` except run over the async iterator.
+
+        Getting the last message by a user named 'Dave' or ``None``: ::
+
+            msg = await channel.history().get(author__name='Dave')
+
+    .. method:: find(predicate)
+        :async:
+
+        |coro|
+
+        Similar to :func:`utils.find` except run over the async iterator.
+
+        Unlike :func:`utils.find`\, the predicate provided can be a
+        |coroutine_link|_.
+
+        Getting the last audit log with a reason or ``None``: ::
+
+            def predicate(event):
+                return event.reason is not None
+
+            event = await guild.audit_logs().find(predicate)
+
+        :param predicate: The predicate to use. Could be a |coroutine_link|_.
+        :return: The first element that returns ``True`` for the predicate or ``None``.
+
+    .. method:: flatten()
+        :async:
+
+        |coro|
+
+        Flattens the async iterator into a :class:`list` with all the elements.
+
+        :return: A list of every element in the async iterator.
+        :rtype: list
+
+    .. method:: chunk(max_size)
+
+        Collects items into chunks of up to a given maximum size.
+        Another :class:`AsyncIterator` is returned which collects items into
+        :class:`list`\s of a given size. The maximum chunk size must be a positive integer.
+
+        .. versionadded:: 1.6
+
+        Collecting groups of users: ::
+
+            async for leader, *users in reaction.users().chunk(3):
+                ...
+
+        .. warning::
+
+            The last chunk collected may not be as large as ``max_size``.
+
+        :param max_size: The size of individual chunks.
+        :rtype: :class:`AsyncIterator`
+
+    .. method:: map(func)
+
+        This is similar to the built-in :func:`map <py:map>` function. Another
+        :class:`AsyncIterator` is returned that executes the function on
+        every element it is iterating over. This function can either be a
+        regular function or a |coroutine_link|_.
+
+        Creating a content iterator: ::
+
+            def transform(message):
+                return message.content
+
+            async for content in channel.history().map(transform):
+                message_length = len(content)
+
+        :param func: The function to call on every element. Could be a |coroutine_link|_.
+        :rtype: :class:`AsyncIterator`
+
+    .. method:: filter(predicate)
+
+        This is similar to the built-in :func:`filter <py:filter>` function. Another
+        :class:`AsyncIterator` is returned that filters over the original
+        async iterator. This predicate can be a regular function or a |coroutine_link|_.
+
+        Getting messages by non-bot accounts: ::
+
+            def predicate(message):
+                return not message.author.bot
+
+            async for elem in channel.history().filter(predicate):
+                ...
+
+        :param predicate: The predicate to call on every element. Could be a |coroutine_link|_.
+        :rtype: :class:`AsyncIterator`
diff --git a/docs/api/audit-logs.rst b/docs/api/audit-logs.rst
new file mode 100644
index 00000000..1b4c04d1
--- /dev/null
+++ b/docs/api/audit-logs.rst
@@ -0,0 +1,412 @@
+.. currentmodule:: discord
+
+.. _discord-api-audit-logs:
+
+Audit Log Data
+----------------
+
+Working with :meth:`Guild.audit_logs` is a complicated process with a lot of machinery
+involved. The library attempts to make it easy to use and friendly. In order to accomplish
+this goal, it must make use of a couple of data classes that aid in this goal.
+
+AuditLogEntry
+~~~~~~~~~~~~~~~
+
+.. attributetable:: AuditLogEntry
+
+.. autoclass:: AuditLogEntry
+    :members:
+
+AuditLogChanges
+~~~~~~~~~~~~~~~~~
+
+.. attributetable:: AuditLogChanges
+
+.. class:: AuditLogChanges
+
+    An audit log change set.
+
+    .. attribute:: before
+
+        The old value. The attribute has the type of :class:`AuditLogDiff`.
+
+        Depending on the :class:`AuditLogActionCategory` retrieved by
+        :attr:`~AuditLogEntry.category`\, the data retrieved by this
+        attribute differs:
+
+        +----------------------------------------+---------------------------------------------------+
+        |                Category                |                    Description                    |
+        +----------------------------------------+---------------------------------------------------+
+        | :attr:`~AuditLogActionCategory.create` | All attributes are set to ``None``.               |
+        +----------------------------------------+---------------------------------------------------+
+        | :attr:`~AuditLogActionCategory.delete` | All attributes are set the value before deletion. |
+        +----------------------------------------+---------------------------------------------------+
+        | :attr:`~AuditLogActionCategory.update` | All attributes are set the value before updating. |
+        +----------------------------------------+---------------------------------------------------+
+        | ``None``                               | No attributes are set.                            |
+        +----------------------------------------+---------------------------------------------------+
+
+    .. attribute:: after
+
+        The new value. The attribute has the type of :class:`AuditLogDiff`.
+
+        Depending on the :class:`AuditLogActionCategory` retrieved by
+        :attr:`~AuditLogEntry.category`\, the data retrieved by this
+        attribute differs:
+
+        +----------------------------------------+--------------------------------------------------+
+        |                Category                |                   Description                    |
+        +----------------------------------------+--------------------------------------------------+
+        | :attr:`~AuditLogActionCategory.create` | All attributes are set to the created value      |
+        +----------------------------------------+--------------------------------------------------+
+        | :attr:`~AuditLogActionCategory.delete` | All attributes are set to ``None``               |
+        +----------------------------------------+--------------------------------------------------+
+        | :attr:`~AuditLogActionCategory.update` | All attributes are set the value after updating. |
+        +----------------------------------------+--------------------------------------------------+
+        | ``None``                               | No attributes are set.                           |
+        +----------------------------------------+--------------------------------------------------+
+
+AuditLogDiff
+~~~~~~~~~~~~~
+
+.. attributetable:: AuditLogDiff
+
+.. class:: AuditLogDiff
+
+    Represents an audit log "change" object. A change object has dynamic
+    attributes that depend on the type of action being done. Certain actions
+    map to certain attributes being set.
+
+    Note that accessing an attribute that does not match the specified action
+    will lead to an attribute error.
+
+    To get a list of attributes that have been set, you can iterate over
+    them. To see a list of all possible attributes that could be set based
+    on the action being done, check the documentation for :class:`AuditLogAction`,
+    otherwise check the documentation below for all attributes that are possible.
+
+    .. container:: operations
+
+        .. describe:: iter(diff)
+
+            Returns an iterator over (attribute, value) tuple of this diff.
+
+    .. attribute:: name
+
+        A name of something.
+
+        :type: :class:`str`
+
+    .. attribute:: icon
+
+        A guild's icon hash. See also :attr:`Guild.icon`.
+
+        :type: :class:`str`
+
+    .. attribute:: splash
+
+        The guild's invite splash hash. See also :attr:`Guild.splash`.
+
+        :type: :class:`str`
+
+    .. attribute:: owner
+
+        The guild's owner. See also :attr:`Guild.owner`
+
+        :type: Union[:class:`Member`, :class:`User`]
+
+    .. attribute:: region
+
+        The guild's voice region. See also :attr:`Guild.region`.
+
+        :type: :class:`VoiceRegion`
+
+    .. attribute:: afk_channel
+
+        The guild's AFK channel.
+
+        If this could not be found, then it falls back to a :class:`Object`
+        with the ID being set.
+
+        See :attr:`Guild.afk_channel`.
+
+        :type: Union[:class:`VoiceChannel`, :class:`Object`]
+
+    .. attribute:: system_channel
+
+        The guild's system channel.
+
+        If this could not be found, then it falls back to a :class:`Object`
+        with the ID being set.
+
+        See :attr:`Guild.system_channel`.
+
+        :type: Union[:class:`TextChannel`, :class:`Object`]
+
+    .. attribute:: afk_timeout
+
+        The guild's AFK timeout. See :attr:`Guild.afk_timeout`.
+
+        :type: :class:`int`
+
+    .. attribute:: mfa_level
+
+        The guild's MFA level. See :attr:`Guild.mfa_level`.
+
+        :type: :class:`int`
+
+    .. attribute:: widget_enabled
+
+        The guild's widget has been enabled or disabled.
+
+        :type: :class:`bool`
+
+    .. attribute:: widget_channel
+
+        The widget's channel.
+
+        If this could not be found then it falls back to a :class:`Object`
+        with the ID being set.
+
+        :type: Union[:class:`TextChannel`, :class:`Object`]
+
+    .. attribute:: verification_level
+
+        The guild's verification level.
+
+        See also :attr:`Guild.verification_level`.
+
+        :type: :class:`VerificationLevel`
+
+    .. attribute:: default_notifications
+
+        The guild's default notification level.
+
+        See also :attr:`Guild.default_notifications`.
+
+        :type: :class:`NotificationLevel`
+
+    .. attribute:: explicit_content_filter
+
+        The guild's content filter.
+
+        See also :attr:`Guild.explicit_content_filter`.
+
+        :type: :class:`ContentFilter`
+
+    .. attribute:: default_message_notifications
+
+        The guild's default message notification setting.
+
+        :type: :class:`int`
+
+    .. attribute:: vanity_url_code
+
+        The guild's vanity URL.
+
+        See also :meth:`Guild.vanity_invite` and :meth:`Guild.edit`.
+
+        :type: :class:`str`
+
+    .. attribute:: position
+
+        The position of a :class:`Role` or :class:`abc.GuildChannel`.
+
+        :type: :class:`int`
+
+    .. attribute:: type
+
+        The type of channel or channel permission overwrite.
+
+        If the type is an :class:`int`, then it is a type of channel which can be either
+        ``0`` to indicate a text channel or ``1`` to indicate a voice channel.
+
+        If the type is a :class:`str`, then it is a type of permission overwrite which
+        can be either ``'role'`` or ``'member'``.
+
+        :type: Union[:class:`int`, :class:`str`]
+
+    .. attribute:: topic
+
+        The topic of a :class:`TextChannel`.
+
+        See also :attr:`TextChannel.topic`.
+
+        :type: :class:`str`
+
+    .. attribute:: bitrate
+
+        The bitrate of a :class:`VoiceChannel`.
+
+        See also :attr:`VoiceChannel.bitrate`.
+
+        :type: :class:`int`
+
+    .. attribute:: overwrites
+
+        A list of permission overwrite tuples that represents a target and a
+        :class:`PermissionOverwrite` for said target.
+
+        The first element is the object being targeted, which can either
+        be a :class:`Member` or :class:`User` or :class:`Role`. If this object
+        is not found then it is a :class:`Object` with an ID being filled and
+        a ``type`` attribute set to either ``'role'`` or ``'member'`` to help
+        decide what type of ID it is.
+
+        :type: List[Tuple[target, :class:`PermissionOverwrite`]]
+
+    .. attribute:: roles
+
+        A list of roles being added or removed from a member.
+
+        If a role is not found then it is a :class:`Object` with the ID and name being
+        filled in.
+
+        :type: List[Union[:class:`Role`, :class:`Object`]]
+
+    .. attribute:: nick
+
+        The nickname of a member.
+
+        See also :attr:`Member.nick`
+
+        :type: Optional[:class:`str`]
+
+    .. attribute:: deaf
+
+        Whether the member is being server deafened.
+
+        See also :attr:`VoiceState.deaf`.
+
+        :type: :class:`bool`
+
+    .. attribute:: mute
+
+        Whether the member is being server muted.
+
+        See also :attr:`VoiceState.mute`.
+
+        :type: :class:`bool`
+
+    .. attribute:: permissions
+
+        The permissions of a role.
+
+        See also :attr:`Role.permissions`.
+
+        :type: :class:`Permissions`
+
+    .. attribute:: colour
+                   color
+
+        The colour of a role.
+
+        See also :attr:`Role.colour`
+
+        :type: :class:`Colour`
+
+    .. attribute:: hoist
+
+        Whether the role is being hoisted or not.
+
+        See also :attr:`Role.hoist`
+
+        :type: :class:`bool`
+
+    .. attribute:: mentionable
+
+        Whether the role is mentionable or not.
+
+        See also :attr:`Role.mentionable`
+
+        :type: :class:`bool`
+
+    .. attribute:: code
+
+        The invite's code.
+
+        See also :attr:`Invite.code`
+
+        :type: :class:`str`
+
+    .. attribute:: channel
+
+        A guild channel.
+
+        If the channel is not found then it is a :class:`Object` with the ID
+        being set. In some cases the channel name is also set.
+
+        :type: Union[:class:`abc.GuildChannel`, :class:`Object`]
+
+    .. attribute:: inviter
+
+        The user who created the invite.
+
+        See also :attr:`Invite.inviter`.
+
+        :type: :class:`User`
+
+    .. attribute:: max_uses
+
+        The invite's max uses.
+
+        See also :attr:`Invite.max_uses`.
+
+        :type: :class:`int`
+
+    .. attribute:: uses
+
+        The invite's current uses.
+
+        See also :attr:`Invite.uses`.
+
+        :type: :class:`int`
+
+    .. attribute:: max_age
+
+        The invite's max age in seconds.
+
+        See also :attr:`Invite.max_age`.
+
+        :type: :class:`int`
+
+    .. attribute:: temporary
+
+        If the invite is a temporary invite.
+
+        See also :attr:`Invite.temporary`.
+
+        :type: :class:`bool`
+
+    .. attribute:: allow
+                   deny
+
+        The permissions being allowed or denied.
+
+        :type: :class:`Permissions`
+
+    .. attribute:: id
+
+        The ID of the object being changed.
+
+        :type: :class:`int`
+
+    .. attribute:: avatar
+
+        The avatar hash of a member.
+
+        See also :attr:`User.avatar`.
+
+        :type: :class:`str`
+
+    .. attribute:: slowmode_delay
+
+        The number of seconds members have to wait before
+        sending another message in the channel.
+
+        See also :attr:`TextChannel.slowmode_delay`.
+
+        :type: :class:`int`
+
+.. this is currently missing the following keys: reason and application_id
+   I'm not sure how to about porting these
\ No newline at end of file
diff --git a/docs/api/clients.rst b/docs/api/clients.rst
new file mode 100644
index 00000000..8c2a22be
--- /dev/null
+++ b/docs/api/clients.rst
@@ -0,0 +1,49 @@
+.. currentmodule:: discord
+
+Clients
+--------
+
+Client
+~~~~~~~
+
+.. attributetable:: Client
+
+.. autoclass:: Client
+    :members:
+    :exclude-members: fetch_guilds, event, once, slash_command, message_command, user_command, on_click, on_select, on_submit
+
+    .. automethod:: Client.event()
+        :decorator:
+
+    .. automethod:: Client.once(name=None, check=None)
+        :decorator:
+
+    .. automethod:: Client.fetch_guilds
+        :async-for:
+
+    .. automethod:: Client.slash_command
+        :decorator:
+
+    .. automethod:: Client.message_command
+        :decorator:
+
+    .. automethod:: Client.user_command
+        :decorator:
+
+    .. automethod:: Client.on_click
+        :decorator:
+
+    .. automethod:: Client.on_select
+        :decorator:
+
+    .. automethod:: Client.on_submit
+        :decorator:
+
+
+AutoShardedClient
+~~~~~~~~~~~~~~~~~~
+
+.. attributetable:: AutoShardedClient
+
+.. autoclass:: AutoShardedClient
+    :members:
diff --git a/docs/api/constants.rst b/docs/api/constants.rst
new file mode 100644
index 00000000..bbc5081b
--- /dev/null
+++ b/docs/api/constants.rst
@@ -0,0 +1,11 @@
+.. currentmodule:: discord
+
+
+Constants
+---------
+
+.. data:: MISSING
+
+    The ``MISSING`` object is a special object that is (mostly) used as default value in places where :obj:`None`
+    cant be used as it is a valid value too.
+    For example in the most ``edit`` functions.
\ No newline at end of file
diff --git a/docs/api/data-classes.rst b/docs/api/data-classes.rst
new file mode 100644
index 00000000..0cb58f5c
--- /dev/null
+++ b/docs/api/data-classes.rst
@@ -0,0 +1,218 @@
+.. currentmodule:: discord
+
+.. _discord_api_data:
+
+Data Classes
+--------------
+
+Some classes are just there to be data containers, this lists them.
+
+Unlike :ref:`models <discord_api_models>` you are allowed to create
+most of these yourself, even if they can also be used to hold attributes.
+
+Nearly all classes here have :ref:`py:slots` defined which means that it is
+impossible to have dynamic attributes to the data classes.
+
+The only exception to this rule is :class:`abc.Snowflake`, which is made with
+dynamic attributes in mind.
+
+
+Object
+~~~~~~~
+
+.. attributetable:: Object
+
+.. autoclass:: Object
+    :members:
+
+Embed
+~~~~~~
+
+.. attributetable:: Embed
+
+.. autoclass:: Embed
+    :members:
+
+AllowedMentions
+~~~~~~~~~~~~~~~~~
+
+.. attributetable:: AllowedMentions
+
+.. autoclass:: AllowedMentions
+    :members:
+
+MessageReference
+~~~~~~~~~~~~~~~~~
+
+.. attributetable:: MessageReference
+
+.. autoclass:: MessageReference
+    :members:
+
+PartialMessage
+~~~~~~~~~~~~~~~~~
+
+.. attributetable:: PartialMessage
+
+.. autoclass:: PartialMessage
+    :members:
+
+Intents
+~~~~~~~~~~
+
+.. attributetable:: Intents
+
+.. autoclass:: Intents
+    :members:
+
+MemberCacheFlags
+~~~~~~~~~~~~~~~~~~
+
+.. attributetable:: MemberCacheFlags
+
+.. autoclass:: MemberCacheFlags
+    :members:
+
+File
+~~~~~
+
+.. attributetable:: File
+
+.. autoclass:: File
+    :members:
+
+ForumTag
+~~~~~~~~~
+
+.. attributetable:: ForumTag
+
+.. autoclass:: ForumTag()
+    :members:
+
+Colour
+~~~~~~
+
+.. attributetable:: Colour
+
+.. autoclass:: Colour
+    :members:
+
+BaseActivity
+~~~~~~~~~~~~~~
+
+.. attributetable:: BaseActivity
+
+.. autoclass:: BaseActivity
+    :members:
+
+Activity
+~~~~~~~~~
+
+.. attributetable:: Activity
+
+.. autoclass:: Activity
+    :members:
+
+Game
+~~~~~
+
+.. attributetable:: Game
+
+.. autoclass:: Game
+    :members:
+
+Streaming
+~~~~~~~~~~~
+
+.. attributetable:: Streaming
+
+.. autoclass:: Streaming
+    :members:
+
+CustomActivity
+~~~~~~~~~~~~~~~
+
+.. attributetable:: CustomActivity
+
+.. autoclass:: CustomActivity
+    :members:
+
+Permissions
+~~~~~~~~~~~~
+
+.. attributetable:: Permissions
+
+.. autoclass:: Permissions
+    :members:
+
+PermissionOverwrite
+~~~~~~~~~~~~~~~~~~~~
+
+.. attributetable:: PermissionOverwrite
+
+.. autoclass:: PermissionOverwrite
+    :members:
+
+ShardInfo
+~~~~~~~~~~~
+
+.. attributetable:: ShardInfo
+
+.. autoclass:: ShardInfo()
+    :members:
+
+SystemChannelFlags
+~~~~~~~~~~~~~~~~~~~~
+
+.. attributetable:: SystemChannelFlags
+
+.. autoclass:: SystemChannelFlags()
+    :members:
+
+ChannelFlags
+~~~~~~~~~~~~~
+
+.. attributetable:: ChannelFlags
+
+.. autoclass:: ChannelFlags()
+    :members:
+
+MessageFlags
+~~~~~~~~~~~~
+
+.. attributetable:: MessageFlags
+
+.. autoclass:: MessageFlags()
+    :members:
+
+PublicUserFlags
+~~~~~~~~~~~~~~~
+
+.. attributetable:: PublicUserFlags
+
+.. autoclass:: PublicUserFlags()
+    :members:
+
+AutoModAction
+~~~~~~~~~~~~~~
+
+.. attributetable:: AutoModAction()
+
+.. autoclass:: AutoModAction()
+    :members:
+
+AutoModTriggerMetadata
+~~~~~~~~~~~~~~~~~~~~~~~
+
+.. attributetable:: AutoModTriggerMetadata
+
+.. autoclass:: AutoModTriggerMetadata()
+    :members:
+
+WelcomeScreenChannel
+~~~~~~~~~~~~~~~~~~~~~
+
+.. attributetable:: WelcomeScreenChannel
+
+.. autoclass:: WelcomeScreenChannel()
+    :members:
diff --git a/docs/api/enums.rst b/docs/api/enums.rst
new file mode 100644
index 00000000..3351db8e
--- /dev/null
+++ b/docs/api/enums.rst
@@ -0,0 +1,1812 @@
+.. currentmodule:: discord
+
+.. _discord-api-enums:
+
+Enumerations
+-------------
+
+The API provides some enumerations for certain types of strings to avoid the API
+from being stringly typed in case the strings change in the future.
+
+All enumerations are subclasses of an internal class which mimics the behaviour
+of :class:`enum.Enum`.
+
+.. hint::
+    You can use any of the enum classe members as an attribute of an instance of it to get a :class:`bool`
+    whether the instance has this value.
+
+    Example:
+
+    .. code-block:: python3
+
+        # channel could be any channel like object
+        if channel.type.private:  # True if channel is a DMChannel
+            ...
+
+        # This is the same as
+        if channel.type == discord.ChannelType.private:
+            ...
+
+
+.. class:: ChannelType
+
+    Specifies the type of channel.
+
+    .. attribute:: text
+
+        A text channel.
+    .. attribute:: voice
+
+        A voice channel.
+    .. attribute:: private
+
+        A private text channel. Also called a direct message.
+    .. attribute:: group
+
+        A private group text channel.
+    .. attribute:: category
+
+        A category channel.
+    .. attribute:: news
+
+        A guild news channel.
+
+    .. attribute:: store
+
+        A guild store channel.
+
+    .. attribute:: stage_voice
+
+        A guild stage voice channel.
+
+        .. versionadded:: 1.7
+
+.. class:: MessageType
+
+    Specifies the type of :class:`Message`. This is used to denote if a message
+    is to be interpreted as a system message or a regular message.
+
+    .. container:: operations
+
+      .. describe:: x == y
+
+          Checks if two messages are equal.
+      .. describe:: x != y
+
+          Checks if two messages are not equal.
+
+    .. attribute:: default
+
+        The default message type. This is the same as regular messages.
+    .. attribute:: recipient_add
+
+        The system message when a recipient is added to a group private
+        message, i.e. a private channel of type :attr:`ChannelType.group`.
+    .. attribute:: recipient_remove
+
+        The system message when a recipient is removed from a group private
+        message, i.e. a private channel of type :attr:`ChannelType.group`.
+    .. attribute:: call
+
+        The system message denoting call state, e.g. missed call, started call,
+        etc.
+    .. attribute:: channel_name_change
+
+        The system message denoting that a channel's name has been changed.
+    .. attribute:: channel_icon_change
+
+        The system message denoting that a channel's icon has been changed.
+    .. attribute:: pins_add
+
+        The system message denoting that a pinned message has been added to a channel.
+    .. attribute:: new_member
+
+        The system message denoting that a new member has joined a Guild.
+
+    .. attribute:: premium_guild_subscription
+
+        The system message denoting that a member has "nitro boosted" a guild.
+    .. attribute:: premium_guild_tier_1
+
+        The system message denoting that a member has "nitro boosted" a guild
+        and it achieved level 1.
+    .. attribute:: premium_guild_tier_2
+
+        The system message denoting that a member has "nitro boosted" a guild
+        and it achieved level 2.
+    .. attribute:: premium_guild_tier_3
+
+        The system message denoting that a member has "nitro boosted" a guild
+        and it achieved level 3.
+    .. attribute:: channel_follow_add
+
+        The system message denoting that an announcement channel has been followed.
+
+        .. versionadded:: 1.3
+    .. attribute:: guild_stream
+
+        The system message denoting that a member is streaming in the guild.
+
+        .. versionadded:: 1.7
+    .. attribute:: guild_discovery_disqualified
+
+        The system message denoting that the guild is no longer eligible for Server
+        Discovery.
+
+        .. versionadded:: 1.7
+    .. attribute:: guild_discovery_requalified
+
+        The system message denoting that the guild has become eligible again for Server
+        Discovery.
+
+        .. versionadded:: 1.7
+    .. attribute:: guild_discovery_grace_period_initial_warning
+
+        The system message denoting that the guild has failed to meet the Server
+        Discovery requirements for one week.
+
+        .. versionadded:: 1.7
+    .. attribute:: guild_discovery_grace_period_final_warning
+
+        The system message denoting that the guild has failed to meet the Server
+        Discovery requirements for 3 weeks in a row.
+
+        .. versionadded:: 1.7
+    .. attribute:: thread_created
+
+        The system message denoting that a thread has been created.
+
+        .. versionadded:: 2.0
+    .. attribute:: reply
+
+        A message that is a reply to another message.
+
+        .. versionadded:: 2.0
+    .. attribute::  chat_input_command
+
+        A message that is a slash command.
+
+        .. versionadded:: 2.0
+    .. attribute::  thread_starter_message
+
+        A message that is the first message in a thread.
+
+        .. versionadded:: 2.0
+    .. attribute:: guild_invite_reminder
+
+        The system message denoting that a guild invite reminder has been sent.
+
+        .. versionadded:: 2.0
+    .. attribute:: context_menu_command
+
+        A message that is a context menu command.
+
+        .. versionadded:: 2.0
+    .. attribute:: automoderation_action
+
+        A log message from discords auto moderation system.
+
+        .. versionadded:: 2.0
+    .. attribute:: role_subscription_purchase
+
+        A message informing about a role subscription purchase.
+
+        .. versionadded:: 2.0
+    .. attribute:: interaction_premium_upsell
+
+        A message informing about a premium upsell.
+
+        .. versionadded:: 2.0
+    .. attribute:: stage_start
+
+        A message informing about a stage starting.
+
+        .. versionadded:: 2.0
+    .. attribute:: stage_end
+
+        A message informing about a stage ending.
+
+        .. versionadded:: 2.0
+    .. attribute:: stage_speaker_change
+
+        A message informing about a stage having a new speaker.
+
+        .. versionadded:: 2.0
+    .. attribute:: stage_raise_hand
+
+        A message informing about someone raising their hand in a stage.
+
+        .. versionadded:: 2.0
+    .. attribute:: stage_topic_change
+
+        A message informing about the topic of a stage been changed.
+
+        .. versionadded:: 2.0
+    .. attribute:: guild_application_premium_subscription
+
+        The system message denoting that a member has subscribed to a guild application.
+
+        .. versionadded:: 2.4
+
+.. class:: ReactionType
+
+    The type of a :class:`Reaction`.
+
+    .. versionadded:: 2.0
+
+    .. attribute:: normal
+
+        A normal reaction
+
+    .. attribute:: burst
+
+        A :dis-gd:`burst reaction <super-reactions>`.
+
+.. class:: ComponentType
+
+    .. attribute:: ActionRow
+
+        Container for other components
+
+    .. attribute:: Button
+
+        Button object
+
+    .. attribute:: StringSelect
+
+        Select menu for picking from defined text options
+
+    .. attribute:: TextInput
+
+        Text input object
+
+    .. attribute:: UserSelect
+
+        Select menu for users
+
+    .. attribute:: RoleSelect
+
+        Select menu for roles
+
+    .. attribute:: MentionableSelect
+
+        Select menu for mentionables (users and roles)
+
+    .. attribute:: ChannelSelect
+
+        Select menu for channels
+
+.. class:: SelectDefaultValueType
+
+    .. attribute:: user
+
+        The :attr:`~DefaultSelectValue.id` represents a user, only valid for :class:`UserSelect` and :class:`MentionableSelect`
+
+    .. attribute:: role
+
+        The :attr:`~DefaultSelectValue.id` represents a role, only valid for :class:`RoleSelect` and :class:`MentionableSelect`
+
+    .. attribute:: channel
+
+        The :attr:`~DefaultSelectValue.id` represents a channel, only valid for :class:`ChannelSelect`
+
+.. class:: ButtonStyle
+
+   The possible styles for a :class:`~discord.Button`
+
+   +------------------------+-------+----------------+---------------------------------+
+   | NAME                   | VALUE | ALIASES        | EXAMPLE                         |
+   +========================+=======+================+=================================+
+   | .. attribute:: blurple |   1   |                | .. image:: /imgs/blurple.png    |
+   |                        |       | ``Primary``    |    :alt: Blurple Button Picture |
+   |                        |       |                |                                 |
+   +------------------------+-------+----------------+---------------------------------+
+   | .. attribute:: grey    |   2   | ``gray``,      | .. image:: /imgs/grey.png       |
+   |                        |       | ``Secondary``  |    :alt: Grey Button Picture    |
+   |                        |       |                |                                 |
+   +------------------------+-------+----------------+---------------------------------+
+   | .. attribute:: green   |   3   | ``Success``    | .. image:: /imgs/green.png      |
+   |                        |       |                |    :alt: Green Button Picture   |
+   |                        |       |                |                                 |
+   +------------------------+-------+----------------+---------------------------------+
+   | .. attribute:: red     |   4   | ``Danger``     | .. image:: /imgs/red.png        |
+   |                        |       |                |    :alt: Red Button Picture     |
+   |                        |       |                |                                 |
+   +------------------------+-------+----------------+---------------------------------+
+   | .. attribute:: url     |   5   | ``link``,      | .. image:: /imgs/url.png        |
+   |                        |       | ``grey_url``,  |    :alt: URL Button Picture     |
+   |                        |       | ``Link_Button``|                                 |
+   +------------------------+-------+----------------+---------------------------------+
+   | .. attribute:: Premium |   6   |                | .. image:: /imgs/premium.png    |
+   |                        |       |                |    :alt: Premium Button Picture |
+   +------------------------+-------+----------------+---------------------------------+
+
+
+.. class:: InteractionType
+
+    Specifies the type of an interaction received from discord.
+
+    .. attribute:: PingAck
+
+        A ping interaction, those are only used for
+        `http-only interactions <https://discord.com/developers/docs/interactions/receiving-and-responding#receiving-an-interaction>`_
+        which are currently not supported by discord4py.
+
+    .. attribute:: ApplicationCommand
+
+        A user invoked a slash, user or message command.
+
+    .. attribute:: Component
+
+        A user pressed a button, or submitted a select menu.
+
+    .. attribute:: ApplicationCommandAutocomplete
+
+        Sent regularly when a user is filling out a slash-command option, that has autocomplete enabled.
+
+    .. attribute:: ModalSubmit
+
+        A user submitted a modal.
+
+.. _defer: :meth:`discord.BaseInteraction.defer`
+
+.. class:: InteractionCallbackType
+
+   InteractionCallbackType to react to an :class:`~discor.BaseInteraction`
+
+   +-----------------------------------------+-------+--------------------------------------------------+-----------------------------+--------------------------------------------+
+   | NAME                                    | VALUE | DESCRIPTION                                      | USAGE                       | EXAMPLE                                    |
+   +=========================================+=======+==================================================+=============================+============================================+
+   | .. attribute:: pong                     |   1   | ACK a ``Ping``                                   | ACK a Ping to Discord       |                     ~                      |
+   +-----------------------------------------+-------+--------------------------------------------------+-----------------------------+--------------------------------------------+
+   | .. attribute:: msg_with_source          |   4   | respond to an interaction with a message         | :class:`Interaction.respond`| .. toggle-header::                         |
+   |                                         |       |                                                  |                             |    :header: **Click to view example**      |
+   |                                         |       |                                                  |                             |                                            |
+   |                                         |       |                                                  |                             |    .. image:: /imgs/ict4example.gif        |
+   |                                         |       |                                                  |                             |       :alt: Example for msg_with_source    |
+   +-----------------------------------------+-------+--------------------------------------------------+-----------------------------+--------------------------------------------+
+   |                                         |       |                                                  |                             | .. toggle-header::                         |
+   | .. attribute:: deferred_msg_with_source |   5   | ACK an interaction and edit a response later,    | Possible                    |    :header: **Click to view example**      |
+   |                                         |       | the user sees a loading state                    | :attr:`response_type`       |                                            |
+   |                                         |       |                                                  | for _defer                  |    .. image:: /imgs/ict5example.gif        |
+   |                                         |       |                                                  |                             |       :alt: Example for                    |
+   |                                         |       |                                                  |                             |             deferred_msg_with_source       |
+   +-----------------------------------------+-------+--------------------------------------------------+-----------------------------+--------------------------------------------+
+   | .. attribute:: deferred_update_msg      |   6   | for components, ACK an interaction and edit      | Possible                    | .. toggle-header::                         |
+   |                                         |       | the original message later;                      | :attr:`response_type`       |    :header: **Click to view example**      |
+   |                                         |       | the user does not see a loading state            | for _defer                  |                                            |
+   |                                         |       |                                                  |                             |    .. image:: /imgs/ict6example.gif        |
+   |                                         |       |                                                  |                             |       :alt: Example for deferred_update_msg|
+   +-----------------------------------------+-------+--------------------------------------------------+-----------------------------+--------------------------------------------+
+   | .. attribute:: update_msg               |   7   | for components,                                  | :class:`Interaction.edit`   | .. toggle-header::                         |
+   |                                         |       | edit the message the component was attached to   |                             |    :header: **Click to view example**      |
+   |                                         |       |                                                  |                             |                                            |
+   |                                         |       |                                                  |                             |    .. image:: /imgs/ict7example.gif        |
+   |                                         |       |                                                  |                             |       :alt: Example for update_msg         |
+   +-----------------------------------------+-------+--------------------------------------------------+-----------------------------+--------------------------------------------+
+
+   (Autocomplete and Modal are missing here)
+
+.. class:: InteractionContextType
+
+    Context in Discord where an interaction can be used, or where it was triggered from.
+
+    .. versionadded:: 2.0
+
+    .. attribute:: guild
+
+        The interaction can be used within a guild (server)
+
+    .. attribute:: bot_dm
+
+        The interaction can be used within DMs with the app's bot user
+
+    .. attribute:: private_channel
+
+        The interaction can be used within Group DMs and DMs other than the app's bot user
+
+    .. seealso::
+
+        - :attr:`~discord.ApplicationCommandInteraction.context` to check where the interaction was triggered from
+        - ``context`` parameter in :func:`~discord.Client.slash_command`, :func:`~discord.Client.user_command` and
+          :func:`~discord.Client.message_command` as well as their respective :ref:`Cog methods <ext_commands_api_cogs>`
+
+
+.. class:: AppIntegrationType
+
+    Where an app can be installed :ddocs:`More info <resources/application#installation-context>`.
+    Also used in app-commands to specify in which present context the command can be used.
+
+    .. versionadded:: 2.0
+
+    .. attribute:: guild_install
+
+        The app can be installed in a guild (server)
+
+    .. attribute:: user_install
+
+        The app can be installed to a User - making it usable everywhere across discord
+
+
+.. class:: EntryPointHandlerType
+
+    How a :class:`~discord.PrimaryEntryPointCommand` is handled.
+
+    .. versionadded:: 2.0
+
+    .. attribute:: app_handler
+
+        The command is handled by the app itself so you can decide how to respond.
+
+    .. attribute:: discord_launch_activity
+
+        Discord handles the interaction by launching your apps activity and sending a follow-up message without
+        coordinating with the app.
+
+    .. attribute:: self
+
+        An alias for :attr:`app_handler`
+
+    .. attribute:: discord
+
+        An alias for :attr:`discord_launch_activity`
+
+.. class:: Locale
+
+    Valid locals that are used at different places in the discord api.
+
+    .. note::
+        Usually you can use the lowercase ``Language Name`` (spaces replaced with underscores) as a valid locale too.
+
+    ==================== ==========================  =====================
+    Locale               Language Name               Native Name
+    ==================== ==========================  =====================
+    .. attribute:: da    Danish                        Dansk
+    .. attribute:: de    German                        Deutsch
+    .. attribute:: en_GB English, UK                   English, UK
+    .. attribute:: en_US English, US                   English, US
+    .. attribute:: es_ES Spanish                       Español
+    .. attribute:: fr    French                        Français
+    .. attribute:: hr    Croatian                      Hrvatski
+    .. attribute:: it    Italian                       Italiano
+    .. attribute:: lt    Lithuanian                    Lietuviškai
+    .. attribute:: hu    Hungarian                     Magyar
+    .. attribute:: nl    Dutch                         Nederlands
+    .. attribute:: no    Norwegian                     Norsk
+    .. attribute:: pl    Polish                        Polski
+    .. attribute:: pt_BR Portuguese/Brazilian          Português do Brasil
+    .. attribute:: ro    Romanian, Romania             Română
+    .. attribute:: fi    Finnish                       Suomi
+    .. attribute:: sv_SE Swedish                       Svenska
+    .. attribute:: vi    Vietnamese                    Tiếng Việt
+    .. attribute:: tr    Turkish                       Türkçe
+    .. attribute:: cs    Czech                         Čeština
+    .. attribute:: el    Greek                         Ελληνικά
+    .. attribute:: bg    Bulgarian                     български
+    .. attribute:: ru    Russian                       Pусский
+    .. attribute:: uk    Ukrainian                     Українська
+    .. attribute:: hi    Hindi                         हिन्दी
+    .. attribute:: th    Thai                          ไทย
+    .. attribute:: zh_CN Chinese, China                中文
+    .. attribute:: ja    Japanese                      日本語
+    .. attribute:: zh_TW Chinese, Taiwan               繁體中文
+    .. attribute:: ko    Korean                        한국어
+    ==================== ==========================  =====================
+
+.. class:: ActivityType
+
+    Specifies the type of :class:`Activity`. This is used to check how to
+    interpret the activity itself.
+
+    .. attribute:: unknown
+
+        An unknown activity type. This should generally not happen.
+    .. attribute:: playing
+
+        A "Playing" activity type.
+    .. attribute:: streaming
+
+        A "Streaming" activity type.
+    .. attribute:: listening
+
+        A "Listening" activity type.
+    .. attribute:: watching
+
+        A "Watching" activity type.
+    .. attribute:: custom
+
+        A custom activity type.
+    .. attribute:: competing
+
+        A competing activity type.
+
+        .. versionadded:: 1.5
+
+.. class:: HypeSquadHouse
+
+    Specifies the HypeSquad house a user belongs to.
+
+    .. attribute:: bravery
+
+        The "Bravery" house.
+    .. attribute:: brilliance
+
+        The "Brilliance" house.
+    .. attribute:: balance
+
+        The "Balance" house.
+
+.. class:: VoiceRegion
+
+    Specifies the region a voice server belongs to.
+
+    .. note::
+        If you wan\'t to fetch all currently available voice regions, consider using :meth:`Client.fetch_voice_regions`.
+
+    .. attribute:: amsterdam
+
+        The Amsterdam region.
+    .. attribute:: brazil
+
+        The Brazil region.
+    .. attribute:: dubai
+
+        The Dubai region.
+
+        .. versionadded:: 1.3
+
+    .. attribute:: eu_central
+
+        The EU Central region.
+    .. attribute:: eu_west
+
+        The EU West region.
+    .. attribute:: europe
+
+        The Europe region.
+
+        .. versionadded:: 1.3
+
+    .. attribute:: frankfurt
+
+        The Frankfurt region.
+    .. attribute:: hongkong
+
+        The Hong Kong region.
+    .. attribute:: india
+
+        The India region.
+
+        .. versionadded:: 1.2
+
+    .. attribute:: japan
+
+        The Japan region.
+    .. attribute:: london
+
+        The London region.
+    .. attribute:: russia
+
+        The Russia region.
+    .. attribute:: singapore
+
+        The Singapore region.
+    .. attribute:: southafrica
+
+        The South Africa region.
+    .. attribute:: south_korea
+
+        The South Korea region.
+    .. attribute:: sydney
+
+        The Sydney region.
+    .. attribute:: us_central
+
+        The US Central region.
+    .. attribute:: us_east
+
+        The US East region.
+    .. attribute:: us_south
+
+        The US South region.
+    .. attribute:: us_west
+
+        The US West region.
+    .. attribute:: vip_amsterdam
+
+        The Amsterdam region for VIP guilds.
+    .. attribute:: vip_us_east
+
+        The US East region for VIP guilds.
+    .. attribute:: vip_us_west
+
+        The US West region for VIP guilds.
+
+.. class:: VideoQualityMode
+
+    Specifies the camera video quality for all channel participants in a :class:`VoiceChannel` / :class:`StageChannel`.
+
+    .. attribute:: auto
+         Automatic set per-user for optimal performance.
+
+    .. attribute:: full
+
+        The quality is enforced to 720p for all participants.
+
+    .. attribute:: 720p
+        An aliase to :attr:`.full`
+
+
+.. class:: VerificationLevel
+
+    Specifies a :class:`Guild`\'s verification level, which is the criteria in
+    which a member must meet before being able to send messages to the guild.
+
+    .. container:: operations
+
+        .. describe:: x == y
+
+            Checks if two verification levels are equal.
+        .. describe:: x != y
+
+            Checks if two verification levels are not equal.
+        .. describe:: x > y
+
+            Checks if a verification level is higher than another.
+        .. describe:: x < y
+
+            Checks if a verification level is lower than another.
+        .. describe:: x >= y
+
+            Checks if a verification level is higher or equal to another.
+        .. describe:: x <= y
+
+            Checks if a verification level is lower or equal to another.
+
+    .. attribute:: none
+
+        No criteria set.
+    .. attribute:: low
+
+        Member must have a verified email on their Discord account.
+    .. attribute:: medium
+
+        Member must have a verified email and be registered on Discord for more
+        than five minutes.
+    .. attribute:: high
+
+        Member must have a verified email, be registered on Discord for more
+        than five minutes, and be a member of the guild itself for more than
+        ten minutes.
+    .. attribute:: table_flip
+
+        An alias for :attr:`high`.
+    .. attribute:: extreme
+
+        Member must have a verified phone on their Discord account.
+
+    .. attribute:: double_table_flip
+
+        An alias for :attr:`extreme`.
+
+    .. attribute:: very_high
+
+        An alias for :attr:`extreme`.
+
+        .. versionadded:: 1.4
+
+.. class:: NotificationLevel
+
+    Specifies whether a :class:`Guild` has notifications on for all messages or mentions only by default.
+
+    .. attribute:: all_messages
+
+        Members receive notifications for every message regardless of them being mentioned.
+    .. attribute:: only_mentions
+
+        Members receive notifications for messages they are mentioned in.
+
+.. class:: ContentFilter
+
+    Specifies a :class:`Guild`\'s explicit content filter, which is the machine
+    learning algorithms that Discord uses to detect if an image contains
+    pornography or otherwise explicit content.
+
+    .. container:: operations
+
+        .. describe:: x == y
+
+            Checks if two content filter levels are equal.
+        .. describe:: x != y
+
+            Checks if two content filter levels are not equal.
+        .. describe:: x > y
+
+            Checks if a content filter level is higher than another.
+        .. describe:: x < y
+
+            Checks if a content filter level is lower than another.
+        .. describe:: x >= y
+
+            Checks if a content filter level is higher or equal to another.
+        .. describe:: x <= y
+
+            Checks if a content filter level is lower or equal to another.
+
+    .. attribute:: disabled
+
+        The guild does not have the content filter enabled.
+    .. attribute:: no_role
+
+        The guild has the content filter enabled for members without a role.
+    .. attribute:: all_members
+
+        The guild has the content filter enabled for every member.
+
+.. class:: Status
+
+    Specifies a :class:`Member` 's status.
+
+    .. attribute:: online
+
+        The member is online.
+    .. attribute:: offline
+
+        The member is offline.
+    .. attribute:: idle
+
+        The member is idle.
+    .. attribute:: dnd
+
+        The member is "Do Not Disturb".
+    .. attribute:: do_not_disturb
+
+        An alias for :attr:`dnd`.
+    .. attribute:: invisible
+
+        The member is "invisible". In reality, this is only used in sending
+        a presence a la :meth:`Client.change_presence`. When you receive a
+        user's presence this will be :attr:`offline` instead.
+
+
+.. class:: AuditLogAction
+
+    Represents the type of action being done for a :class:`AuditLogEntry`\,
+    which is retrievable via :meth:`Guild.audit_logs`.
+
+    .. attribute:: guild_update
+
+        The guild has updated. Things that trigger this include:
+
+        - Changing the guild vanity URL
+        - Changing the guild invite splash
+        - Changing the guild AFK channel or timeout
+        - Changing the guild voice server region
+        - Changing the guild icon
+        - Changing the guild moderation settings
+        - Changing things related to the guild widget
+
+        When this is the action, the type of :attr:`~AuditLogEntry.target` is
+        the :class:`Guild`.
+
+        Possible attributes for :class:`AuditLogDiff`:
+
+        - :attr:`~AuditLogDiff.afk_channel`
+        - :attr:`~AuditLogDiff.system_channel`
+        - :attr:`~AuditLogDiff.afk_timeout`
+        - :attr:`~AuditLogDiff.default_message_notifications`
+        - :attr:`~AuditLogDiff.explicit_content_filter`
+        - :attr:`~AuditLogDiff.mfa_level`
+        - :attr:`~AuditLogDiff.name`
+        - :attr:`~AuditLogDiff.owner`
+        - :attr:`~AuditLogDiff.splash`
+        - :attr:`~AuditLogDiff.vanity_url_code`
+
+    .. attribute:: channel_create
+
+        A new channel was created.
+
+        When this is the action, the type of :attr:`~AuditLogEntry.target` is
+        either a :class:`abc.GuildChannel` or :class:`Object` with an ID.
+
+        A more filled out object in the :class:`Object` case can be found
+        by using :attr:`~AuditLogEntry.after`.
+
+        Possible attributes for :class:`AuditLogDiff`:
+
+        - :attr:`~AuditLogDiff.name`
+        - :attr:`~AuditLogDiff.type`
+        - :attr:`~AuditLogDiff.overwrites`
+
+    .. attribute:: channel_update
+
+        A channel was updated. Things that trigger this include:
+
+        - The channel name or topic was changed
+        - The channel bitrate was changed
+
+        When this is the action, the type of :attr:`~AuditLogEntry.target` is
+        the :class:`abc.GuildChannel` or :class:`Object` with an ID.
+
+        A more filled out object in the :class:`Object` case can be found
+        by using :attr:`~AuditLogEntry.after` or :attr:`~AuditLogEntry.before`.
+
+        Possible attributes for :class:`AuditLogDiff`:
+
+        - :attr:`~AuditLogDiff.name`
+        - :attr:`~AuditLogDiff.type`
+        - :attr:`~AuditLogDiff.position`
+        - :attr:`~AuditLogDiff.overwrites`
+        - :attr:`~AuditLogDiff.topic`
+        - :attr:`~AuditLogDiff.bitrate`
+
+    .. attribute:: channel_delete
+
+        A channel was deleted.
+
+        When this is the action, the type of :attr:`~AuditLogEntry.target` is
+        an :class:`Object` with an ID.
+
+        A more filled out object can be found by using the
+        :attr:`~AuditLogEntry.before` object.
+
+        Possible attributes for :class:`AuditLogDiff`:
+
+        - :attr:`~AuditLogDiff.name`
+        - :attr:`~AuditLogDiff.type`
+        - :attr:`~AuditLogDiff.overwrites`
+
+    .. attribute:: overwrite_create
+
+        A channel permission overwrite was created.
+
+        When this is the action, the type of :attr:`~AuditLogEntry.target` is
+        the :class:`abc.GuildChannel` or :class:`Object` with an ID.
+
+        When this is the action, the type of :attr:`~AuditLogEntry.extra` is
+        either a :class:`Role` or :class:`Member`. If the object is not found
+        then it is a :class:`Object` with an ID being filled, a name, and a
+        ``type`` attribute set to either ``'role'`` or ``'member'`` to help
+        dictate what type of ID it is.
+
+        Possible attributes for :class:`AuditLogDiff`:
+
+        - :attr:`~AuditLogDiff.deny`
+        - :attr:`~AuditLogDiff.allow`
+        - :attr:`~AuditLogDiff.id`
+        - :attr:`~AuditLogDiff.type`
+
+    .. attribute:: overwrite_update
+
+        A channel permission overwrite was changed, this is typically
+        when the permission values change.
+
+        See :attr:`overwrite_create` for more information on how the
+        :attr:`~AuditLogEntry.target` and :attr:`~AuditLogEntry.extra` fields
+        are set.
+
+        Possible attributes for :class:`AuditLogDiff`:
+
+        - :attr:`~AuditLogDiff.deny`
+        - :attr:`~AuditLogDiff.allow`
+        - :attr:`~AuditLogDiff.id`
+        - :attr:`~AuditLogDiff.type`
+
+    .. attribute:: overwrite_delete
+
+        A channel permission overwrite was deleted.
+
+        See :attr:`overwrite_create` for more information on how the
+        :attr:`~AuditLogEntry.target` and :attr:`~AuditLogEntry.extra` fields
+        are set.
+
+        Possible attributes for :class:`AuditLogDiff`:
+
+        - :attr:`~AuditLogDiff.deny`
+        - :attr:`~AuditLogDiff.allow`
+        - :attr:`~AuditLogDiff.id`
+        - :attr:`~AuditLogDiff.type`
+
+    .. attribute:: kick
+
+        A member was kicked.
+
+        When this is the action, the type of :attr:`~AuditLogEntry.target` is
+        the :class:`User` who got kicked.
+
+        When this is the action, :attr:`~AuditLogEntry.changes` is empty.
+
+    .. attribute:: member_prune
+
+        A member prune was triggered.
+
+        When this is the action, the type of :attr:`~AuditLogEntry.target` is
+        set to ``None``.
+
+        When this is the action, the type of :attr:`~AuditLogEntry.extra` is
+        set to an unspecified proxy object with two attributes:
+
+        - ``delete_members_days``: An integer specifying how far the prune was.
+        - ``members_removed``: An integer specifying how many members were removed.
+
+        When this is the action, :attr:`~AuditLogEntry.changes` is empty.
+
+    .. attribute:: ban
+
+        A member was banned.
+
+        When this is the action, the type of :attr:`~AuditLogEntry.target` is
+        the :class:`User` who got banned.
+
+        When this is the action, :attr:`~AuditLogEntry.changes` is empty.
+
+    .. attribute:: unban
+
+        A member was unbanned.
+
+        When this is the action, the type of :attr:`~AuditLogEntry.target` is
+        the :class:`User` who got unbanned.
+
+        When this is the action, :attr:`~AuditLogEntry.changes` is empty.
+
+    .. attribute:: member_update
+
+        A member has updated. This triggers in the following situations:
+
+        - A nickname was changed
+        - They were server muted or deafened (or it was undo'd)
+
+        When this is the action, the type of :attr:`~AuditLogEntry.target` is
+        the :class:`Member` or :class:`User` who got updated.
+
+        Possible attributes for :class:`AuditLogDiff`:
+
+        - :attr:`~AuditLogDiff.nick`
+        - :attr:`~AuditLogDiff.mute`
+        - :attr:`~AuditLogDiff.deaf`
+
+    .. attribute:: member_role_update
+
+        A member's role has been updated. This triggers when a member
+        either gains a role or losses a role.
+
+        When this is the action, the type of :attr:`~AuditLogEntry.target` is
+        the :class:`Member` or :class:`User` who got the role.
+
+        Possible attributes for :class:`AuditLogDiff`:
+
+        - :attr:`~AuditLogDiff.roles`
+
+    .. attribute:: member_move
+
+        A member's voice channel has been updated. This triggers when a
+        member is moved to a different voice channel.
+
+        When this is the action, the type of :attr:`~AuditLogEntry.extra` is
+        set to an unspecified proxy object with two attributes:
+
+        - ``channel``: A :class:`TextChannel` or :class:`Object` with the channel ID where the members were moved.
+        - ``count``: An integer specifying how many members were moved.
+
+        .. versionadded:: 1.3
+
+    .. attribute:: member_disconnect
+
+        A member's voice state has changed. This triggers when a
+        member is force disconnected from voice.
+
+        When this is the action, the type of :attr:`~AuditLogEntry.extra` is
+        set to an unspecified proxy object with one attribute:
+
+        - ``count``: An integer specifying how many members were disconnected.
+
+        .. versionadded:: 1.3
+
+    .. attribute:: bot_add
+
+        A bot was added to the guild.
+
+        When this is the action, the type of :attr:`~AuditLogEntry.target` is
+        the :class:`Member` or :class:`User` which was added to the guild.
+
+        .. versionadded:: 1.3
+
+    .. attribute:: role_create
+
+        A new role was created.
+
+        When this is the action, the type of :attr:`~AuditLogEntry.target` is
+        the :class:`Role` or a :class:`Object` with the ID.
+
+        Possible attributes for :class:`AuditLogDiff`:
+
+        - :attr:`~AuditLogDiff.colour`
+        - :attr:`~AuditLogDiff.mentionable`
+        - :attr:`~AuditLogDiff.hoist`
+        - :attr:`~AuditLogDiff.name`
+        - :attr:`~AuditLogDiff.permissions`
+
+    .. attribute:: role_update
+
+        A role was updated. This triggers in the following situations:
+
+        - The name has changed
+        - The permissions have changed
+        - The colour has changed
+        - Its hoist/mentionable state has changed
+
+        When this is the action, the type of :attr:`~AuditLogEntry.target` is
+        the :class:`Role` or a :class:`Object` with the ID.
+
+        Possible attributes for :class:`AuditLogDiff`:
+
+        - :attr:`~AuditLogDiff.colour`
+        - :attr:`~AuditLogDiff.mentionable`
+        - :attr:`~AuditLogDiff.hoist`
+        - :attr:`~AuditLogDiff.name`
+        - :attr:`~AuditLogDiff.permissions`
+
+    .. attribute:: role_delete
+
+        A role was deleted.
+
+        When this is the action, the type of :attr:`~AuditLogEntry.target` is
+        the :class:`Role` or a :class:`Object` with the ID.
+
+        Possible attributes for :class:`AuditLogDiff`:
+
+        - :attr:`~AuditLogDiff.colour`
+        - :attr:`~AuditLogDiff.mentionable`
+        - :attr:`~AuditLogDiff.hoist`
+        - :attr:`~AuditLogDiff.name`
+        - :attr:`~AuditLogDiff.permissions`
+
+    .. attribute:: invite_create
+
+        An invite was created.
+
+        When this is the action, the type of :attr:`~AuditLogEntry.target` is
+        the :class:`Invite` that was created.
+
+        Possible attributes for :class:`AuditLogDiff`:
+
+        - :attr:`~AuditLogDiff.max_age`
+        - :attr:`~AuditLogDiff.code`
+        - :attr:`~AuditLogDiff.temporary`
+        - :attr:`~AuditLogDiff.inviter`
+        - :attr:`~AuditLogDiff.channel`
+        - :attr:`~AuditLogDiff.uses`
+        - :attr:`~AuditLogDiff.max_uses`
+
+    .. attribute:: invite_update
+
+        An invite was updated.
+
+        When this is the action, the type of :attr:`~AuditLogEntry.target` is
+        the :class:`Invite` that was updated.
+
+    .. attribute:: invite_delete
+
+        An invite was deleted.
+
+        When this is the action, the type of :attr:`~AuditLogEntry.target` is
+        the :class:`Invite` that was deleted.
+
+        Possible attributes for :class:`AuditLogDiff`:
+
+        - :attr:`~AuditLogDiff.max_age`
+        - :attr:`~AuditLogDiff.code`
+        - :attr:`~AuditLogDiff.temporary`
+        - :attr:`~AuditLogDiff.inviter`
+        - :attr:`~AuditLogDiff.channel`
+        - :attr:`~AuditLogDiff.uses`
+        - :attr:`~AuditLogDiff.max_uses`
+
+    .. attribute:: webhook_create
+
+        A webhook was created.
+
+        When this is the action, the type of :attr:`~AuditLogEntry.target` is
+        the :class:`Object` with the webhook ID.
+
+        Possible attributes for :class:`AuditLogDiff`:
+
+        - :attr:`~AuditLogDiff.channel`
+        - :attr:`~AuditLogDiff.name`
+        - :attr:`~AuditLogDiff.type` (always set to ``1`` if so)
+
+    .. attribute:: webhook_update
+
+        A webhook was updated. This trigger in the following situations:
+
+        - The webhook name changed
+        - The webhook channel changed
+
+        When this is the action, the type of :attr:`~AuditLogEntry.target` is
+        the :class:`Object` with the webhook ID.
+
+        Possible attributes for :class:`AuditLogDiff`:
+
+        - :attr:`~AuditLogDiff.channel`
+        - :attr:`~AuditLogDiff.name`
+
+    .. attribute:: webhook_delete
+
+        A webhook was deleted.
+
+        When this is the action, the type of :attr:`~AuditLogEntry.target` is
+        the :class:`Object` with the webhook ID.
+
+        Possible attributes for :class:`AuditLogDiff`:
+
+        - :attr:`~AuditLogDiff.channel`
+        - :attr:`~AuditLogDiff.name`
+        - :attr:`~AuditLogDiff.type` (always set to ``1`` if so)
+
+    .. attribute:: emoji_create
+
+        An emoji was created.
+
+        When this is the action, the type of :attr:`~AuditLogEntry.target` is
+        the :class:`Emoji` or :class:`Object` with the emoji ID.
+
+        Possible attributes for :class:`AuditLogDiff`:
+
+        - :attr:`~AuditLogDiff.name`
+
+    .. attribute:: emoji_update
+
+        An emoji was updated. This triggers when the name has changed.
+
+        When this is the action, the type of :attr:`~AuditLogEntry.target` is
+        the :class:`Emoji` or :class:`Object` with the emoji ID.
+
+        Possible attributes for :class:`AuditLogDiff`:
+
+        - :attr:`~AuditLogDiff.name`
+
+    .. attribute:: emoji_delete
+
+        An emoji was deleted.
+
+        When this is the action, the type of :attr:`~AuditLogEntry.target` is
+        the :class:`Object` with the emoji ID.
+
+        Possible attributes for :class:`AuditLogDiff`:
+
+        - :attr:`~AuditLogDiff.name`
+
+    .. attribute:: message_delete
+
+        A message was deleted by a moderator. Note that this
+        only triggers if the message was deleted by someone other than the author.
+
+        When this is the action, the type of :attr:`~AuditLogEntry.target` is
+        the :class:`Member` or :class:`User` who had their message deleted.
+
+        When this is the action, the type of :attr:`~AuditLogEntry.extra` is
+        set to an unspecified proxy object with two attributes:
+
+        - ``count``: An integer specifying how many messages were deleted.
+        - ``channel``: A :class:`TextChannel` or :class:`Object` with the channel ID where the message got deleted.
+
+    .. attribute:: message_bulk_delete
+
+        Messages were bulk deleted by a moderator.
+
+        When this is the action, the type of :attr:`~AuditLogEntry.target` is
+        the :class:`TextChannel` or :class:`Object` with the ID of the channel that was purged.
+
+        When this is the action, the type of :attr:`~AuditLogEntry.extra` is
+        set to an unspecified proxy object with one attribute:
+
+        - ``count``: An integer specifying how many messages were deleted.
+
+        .. versionadded:: 1.3
+
+    .. attribute:: message_pin
+
+        A message was pinned in a channel.
+
+        When this is the action, the type of :attr:`~AuditLogEntry.target` is
+        the :class:`Member` or :class:`User` who had their message pinned.
+
+        When this is the action, the type of :attr:`~AuditLogEntry.extra` is
+        set to an unspecified proxy object with two attributes:
+
+        - ``channel``: A :class:`TextChannel` or :class:`Object` with the channel ID where the message was pinned.
+        - ``message_id``: the ID of the message which was pinned.
+
+        .. versionadded:: 1.3
+
+    .. attribute:: message_unpin
+
+        A message was unpinned in a channel.
+
+        When this is the action, the type of :attr:`~AuditLogEntry.target` is
+        the :class:`Member` or :class:`User` who had their message unpinned.
+
+        When this is the action, the type of :attr:`~AuditLogEntry.extra` is
+        set to an unspecified proxy object with two attributes:
+
+        - ``channel``: A :class:`TextChannel` or :class:`Object` with the channel ID where the message was unpinned.
+        - ``message_id``: the ID of the message which was unpinned.
+
+        .. versionadded:: 1.3
+
+    .. attribute:: integration_create
+
+        A guild integration was created.
+
+        When this is the action, the type of :attr:`~AuditLogEntry.target` is
+        the :class:`Object` with the integration ID of the integration which was created.
+
+        .. versionadded:: 1.3
+
+    .. attribute:: integration_update
+
+        A guild integration was updated.
+
+        When this is the action, the type of :attr:`~AuditLogEntry.target` is
+        the :class:`Object` with the integration ID of the integration which was updated.
+
+        .. versionadded:: 1.3
+
+    .. attribute:: integration_delete
+
+        A guild integration was deleted.
+
+        When this is the action, the type of :attr:`~AuditLogEntry.target` is
+        the :class:`Object` with the integration ID of the integration which was deleted.
+
+        .. versionadded:: 1.3
+
+
+.. class:: AuditLogActionCategory
+
+    Represents the category that the :class:`AuditLogAction` belongs to.
+
+    This can be retrieved via :attr:`AuditLogEntry.category`.
+
+    .. attribute:: create
+
+        The action is the creation of something.
+
+    .. attribute:: delete
+
+        The action is the deletion of something.
+
+    .. attribute:: update
+
+        The action is the update of something.
+
+.. class:: PremiumType
+
+    Represents the user's Discord Nitro subscription type.
+
+    .. deprecated:: 1.7
+
+    .. note::
+
+        This only applies to users, *not* bots.
+
+    .. attribute:: nitro
+
+        Represents the Discord Nitro with Nitro-exclusive games.
+
+    .. attribute:: nitro_classic
+
+        Represents the Discord Nitro with no Nitro-exclusive games.
+
+
+.. class:: Theme
+
+    Represents the theme synced across all Discord clients.
+
+    .. deprecated:: 1.7
+
+    .. note::
+
+        This only applies to users, *not* bots.
+
+    .. attribute:: light
+
+        Represents the Light theme on Discord.
+
+    .. attribute:: dark
+
+        Represents the Dark theme on Discord.
+
+
+.. class:: TeamMembershipState
+
+    Represents the membership state of a team member retrieved through :func:`Bot.application_info`.
+
+    .. versionadded:: 1.3
+
+    .. attribute:: invited
+
+        Represents an invited member.
+
+    .. attribute:: accepted
+
+        Represents a member currently in the team.
+
+.. class:: TeamRole:
+
+    A :class:`TeamMember` can be one of four roles (owner, admin, developer, and read-only),
+    and each role inherits the access of those below it.
+    Represents the role of a team member retrieved through :func:`Bot.application_info`.
+
+    .. versionadded:: 2.0
+
+    .. attribute:: owner
+
+        Owners are the most permissiable role, and can take destructive, irreversible actions like deleting team-owned
+        apps or the team itself. Teams are limited to 1 owner.
+
+    .. attribute:: admin
+
+        Admins have similar access as an :attr:`~TeamRole.owner`,
+        except they cannot take destructive actions on the team or team-owned apps.
+
+    .. attribute:: developer
+
+        Developers can access information about team-owned apps, like the client secret or public key.
+        They can also take limited actions on team-owned apps,
+        like configuring interaction endpoints or resetting the bot token.
+        Members with the Developer role cannot manage the team or its members,
+        or take destructive actions on team-owned apps.
+
+    .. attribute:: read_only
+
+        Read-only members can access information about a team and any team-owned apps.
+        Some examples include getting the IDs of applications and exporting payout records.
+
+.. class:: WebhookType
+
+    Represents the type of webhook that can be received.
+
+    .. versionadded:: 1.3
+
+    .. attribute:: incoming
+
+        Represents a webhook that can post messages to channels with a token.
+
+    .. attribute:: channel_follower
+
+        Represents a webhook that is internally managed by Discord, used for following channels.
+
+.. class:: TimestampStyle
+
+    The Styles you could use for the :attr:`style` of a :meth:`discord.utils.styled_timestamp`
+
+    See also in the `Discord-Documentation <https://discord.com/developers/docs/reference#message-formatting-timestamp-styles>`_
+
+    +----------------------------------+-------+-----------------+---------------------------------+
+    | NAME                             | VALUE | DESCRIPTION     | EXAMPLE                         |
+    +==================================+=======+=================+=================================+
+    | .. attribute:: short_time        |  't'  | Short Time      | .. image:: /imgs/short_time.png |
+    +----------------------------------+-------+-----------------+---------------------------------+
+    | .. attribute:: long_time         |  'T'  | Long Time       | .. image:: /imgs/long_time.png  |
+    +----------------------------------+-------+-----------------+---------------------------------+
+    | .. attribute:: short_date        |  'd'  | Short Date      | .. image:: /imgs/short_date.png |
+    +----------------------------------+-------+-----------------+---------------------------------+
+    | .. attribute:: long_date         |  'D'  | Long Date       | .. image:: /imgs/long_date.png  |
+    +----------------------------------+-------+-----------------+---------------------------------+
+    | .. attribute:: short             |  'f'  | Short Date/Time | .. image:: /imgs/short.png      |
+    +----------------------------------+-------+-----------------+---------------------------------+
+    | .. attribute:: long              |  'F'  | Long Date/Time  | .. image:: /imgs/long.png       |
+    +----------------------------------+-------+-----------------+---------------------------------+
+    | .. attribute:: relative          |  'R'  | Relative Time   | .. image:: /imgs/relative.png   |
+    +----------------------------------+-------+-----------------+---------------------------------+
+
+.. class:: ExpireBehaviour
+
+    Represents the behaviour the :class:`Integration` should perform
+    when a user's subscription has finished.
+
+    There is an alias for this called ``ExpireBehavior``.
+
+    .. versionadded:: 1.4
+
+    .. attribute:: remove_role
+
+        This will remove the :attr:`Integration.role` from the user
+        when their subscription is finished.
+
+    .. attribute:: kick
+
+        This will kick the user when their subscription is finished.
+
+.. class:: DefaultAvatar
+
+    Represents the default avatar of a Discord :class:`User`
+
+    .. attribute:: blurple
+
+        Represents the default avatar with the color blurple.
+        See also :attr:`Colour.blurple`
+    .. attribute:: grey
+
+        Represents the default avatar with the color grey.
+        See also :attr:`Colour.greyple`
+    .. attribute:: gray
+
+        An alias for :attr:`grey`.
+    .. attribute:: green
+
+        Represents the default avatar with the color green.
+        See also :attr:`Colour.green`
+    .. attribute:: orange
+
+        Represents the default avatar with the color orange.
+        See also :attr:`Colour.orange`
+    .. attribute:: red
+
+        Represents the default avatar with the color red.
+        See also :attr:`Colour.red`
+    .. attribute:: pink
+
+        Represents the default avatar with the color pink.
+
+
+.. class:: StickerType
+
+    Represents the type of sticker images.
+
+    .. versionadded:: 1.6
+
+    .. attribute:: png
+
+        Represents a sticker with a png image.
+
+    .. attribute:: apng
+
+        Represents a sticker with an apng image.
+
+    .. attribute:: lottie
+
+        Represents a sticker with a lottie image.
+
+    .. attribute:: gif
+
+        Represents a sticker with a gif image.
+
+
+.. class:: EventEntityType
+
+    The location where a :class:`GuildScheduledEvent` will be scheduled at
+
+    .. attribute:: stage
+
+        The event wil be in a stage channel
+
+    .. attribute:: voice
+
+        The event wil be in a voice channel
+
+    .. attribute:: external
+
+        The event wil be outside of discord, like on a website or in the real world
+
+.. class:: EventStatus
+
+    The status of a :class:`GuildScheduledEvent`
+
+    .. attribute:: scheduled
+
+        The event hasn't startet yet
+
+    .. attribute:: active
+
+        The event is currently active
+
+    .. attribute:: completed
+
+        The event is over
+
+    .. attribute:: canceled
+
+        The scheduled event was canceled
+
+    .. note::
+
+        \* Once :attr:`~GuildScheduledEvent.status` is set to ``completed`` or ``canceled``, the ``status`` can no longer be updated
+
+    Valid Guild Scheduled Event Status Transitions
+
+        - ``scheduled`` --> ``active``
+
+        - ``active`` --------> ``completed``
+
+        - ``scheduled`` --> ``canceled``
+
+
+.. class:: AutoModEventType
+
+    Indicates in what event context a :class:`AutoModRule` should be checked.
+
+    .. attribute:: message_send
+
+        When a member sends or edits a message (in the guild the rule belongs to)
+
+    .. attribute:: member_update
+
+        When a member updates their profile
+
+
+.. class:: AutoModKeywordPresetType
+
+    .. attribute:: profanity
+
+        Words that may be considered forms of swearing or cursing
+
+    .. attribute:: sexual_content
+
+        Words that refer to sexually explicit behavior or activity
+
+    .. attribute:: slurs
+
+        Personal insults or words that may be considered hate speech
+
+.. class:: AutoModTriggerType
+
+    Characterizes the type of content which can trigger the rule.
+
+    .. attribute:: keyword
+
+        Check if content contains words from a user defined list of keywords
+
+    .. attribute:: spam
+
+        Check if content represents generic spam
+
+    .. attribute:: keyword_preset
+
+        Check if content contains words from internal pre-defined wordsets
+
+    .. attribute:: mention_spam
+
+        Check if content contains more unique mentions than allowed
+
+    .. attribute:: member_profile
+
+        Check if a members' profile contains words from a user defined list of keywords
+
+
+.. class:: AutoModActionType
+
+    The type of action that should be taken in an :class:`AutoModAction`.
+
+    .. attribute:: block_message
+
+        Blocks the content of a message according to the rule
+
+    .. attribute:: send_alert_message
+
+        Logs user content to a specified channel
+
+    .. attribute:: timeout_user
+
+        Timeout the user for a specific duration
+
+        .. note::
+
+            This can only be used when the :attr:`~AutoModRule.trigger_type` is ``keyword`` or ``mention_spam``
+
+    .. attribute:: block_member_interaction
+
+        Prevents a member from using text, voice, or other interactions
+
+.. class:: TextInputStyle
+
+    The style a :class:`TextInput` should have
+
+    .. attribute:: short
+
+        A single-line input
+
+    .. attribute:: singleline
+
+        An aliase for :attr:`~TextInputStyle.short`
+
+    .. attribute:: paragraph
+
+        A multi-line input
+
+    .. attribute:: multiline
+
+        An aliase for :attr:`~TextInputStyle.paragraph`
+
+.. class:: OptionType
+
+    Option types for :class:`SlashCommandOption`
+
+    .. attribute:: sub_command
+
+        A sub command. Internal use only.
+
+    .. attribute:: sub_command_group
+
+        A sub command group. Internal use only.
+
+    .. attribute:: string
+
+        A string (:class:`str`)
+
+    .. attribute:: integer
+
+       	Any integer between -2^53 and 2^53 (:class:`int`)
+
+    .. attribute:: boolean
+
+        A boolean (:class:`bool`)
+
+    .. attribute:: user
+
+        A user/member (:class:`~discord.User`/:class:`Member`)
+
+    .. attribute:: channel
+
+        Includes all channel types + categories
+
+        .. note::
+
+            To only accept specific channel types use :attr:`SlashCommandOption.channel_types`
+
+    .. attribute:: role
+
+        A role (:class:`Role`)
+
+    .. attribute:: mentionable
+
+        Includes user and roles (:class:`~discord.User`/:class:`Member` & :class:`Role`)
+
+    .. attribute:: number
+
+        Any double between -2^53 and 2^53 (:class:`float`)
+
+    .. attribute:: attachment
+
+        An :class:`Attachment`
+
+.. class:: PostSortOrder
+
+    Type used to order posts in :class:`ForumChannel` channels.
+
+    .. attribute:: latest_activity
+
+        Sort forum posts by activity
+
+    .. attribute:: creation_date
+
+        Sort forum posts by creation time (from most recent to oldest)
+
+.. class:: ForumLayout
+
+    Type used to display posts in `ForumChannel` channels.
+
+    .. attribute:: not_set
+
+        No default has been set for forum channel
+
+    .. attribute:: list_view
+
+        Display posts as a list
+
+    .. attribute:: gallery_view
+
+        Display posts as a collection of tiles (grid)
+
+.. class:: OnboardingMode
+
+    Defines the criteria used to satisfy Onboarding constraints that are required for enabling.
+
+    .. attribute:: default
+
+        Counts only Default Channels towards constraints
+
+    .. attribute:: advanced
+
+        Counts Default Channels and Questions towards constraints
+
+.. class:: OnboardingPromptType
+
+        Defines the way a prompts' options are displayed.
+
+        .. attribute:: multiple_choice
+
+            The options are displayed as a grid of buttons
+
+        .. attribute:: dropdown
+
+            The options are displayed in a dropdown menu
+
+
+.. class:: SKUType
+
+    Represents the type of a :class:`SKU`.
+
+    .. attribute:: application
+        An application SKU
+
+    .. attribute:: durable
+
+        Durable one-time purchase
+
+    .. attribute:: consumable
+
+        Consumable one-time purchase
+
+    .. attribute:: bundle
+
+        A bundle SKU
+
+    .. attribute:: subscription
+
+        Represents a recurring subscription
+
+    .. attribute:: subscription_group
+
+        System-generated group for each :attr:`.subscription` SKU created
+
+
+.. class:: EntitlementType
+
+    Represents the type of a :class:`Entitlement`.
+
+    .. attribute:: purchase
+
+        Entitlement was purchased by user
+
+    .. attribute:: premium_subscription
+
+        Entitlement for Discord Nitro subscription
+
+    .. attribute:: developer_gift
+
+        Entitlement was gifted by developer
+
+    .. attribute:: test_mode_purchase
+
+        Entitlement was purchased by a developer in application test mode
+
+    .. attribute:: free_purchase
+
+        Entitlement was granted when the SKU was free
+
+    .. attribute:: user_gift
+
+        Entitlement was gifted by another user
+
+    .. attribute:: premium_purchase
+
+        Entitlement was claimed by user for free as a Nitro Subscriber
+
+    .. attribute:: application_subscription
+
+        Entitlement was purchased as an app subscription
+
+
+.. class:: SubscriptionStatus
+
+    Represent the :attr:`~discord.Subscription.status` of a subscription.
+
+    .. note::
+
+        Subscription status should not be used to grant perks.
+        Use :class:`~discord.Entitlement`s as an indication of whether a user should have access to a specific SKU.
+        See discords guid on :docs:`Implementing App Subscriptions <monetization/implementing-app-subscriptions> for more information.
+
+    .. attribute:: active
+
+        Subscription is active and scheduled to renew.
+
+    .. attribute:: ending
+
+        Subscription is active but will not renew.
+
+    .. attribute:: inactive
+
+        Subscription is inactive and not being charged.
\ No newline at end of file
diff --git a/docs/api/events.rst b/docs/api/events.rst
new file mode 100644
index 00000000..fe52c04f
--- /dev/null
+++ b/docs/api/events.rst
@@ -0,0 +1,1031 @@
+.. currentmodule:: discord
+
+.. _discord-api-events:
+
+Event Reference
+---------------
+
+This section outlines the different types of events listened by :class:`Client`.
+
+There are three ways to register an event, the first way is through the use of
+:meth:`Client.event`. The second way is through subclassing :class:`Client` and
+overriding the specific events. For example: ::
+
+    import discord
+
+    class MyClient(discord.Client):
+        async def on_message(self, message):
+            if message.author == self.user:
+                return
+
+            # Note that for commands you should consider using the ext.commands framework or just slash commands
+            if message.content.startswith("$hello"):
+                await message.channel.send("Hello World!")
+
+The third way is to use the :meth:`Client.once` decorator. Which servers as a one-time event listener. For example: ::
+
+    import discord
+
+    client = discord.Client()
+
+    @client.once()
+    async def ready():
+        print("Hey there, I'm online!")
+
+.. hint::
+
+    If you are using :ref:`ext_commands_cogs` of the :ref:`(prefix)-commands framework <discord_ext_commands>`, then
+    – in addition to the above – you can use the :meth:`commands.Cog.listener <ext.commands.Cog.listener>`
+    decorator in them to listen to events.
+
+If an event handler raises an exception, :func:`on_error` will be called
+to handle it, which defaults to print a traceback and ignoring the exception.
+
+.. warning::
+
+    All the events must be a |coroutine_link|_. If they aren't, then you might get unexpected
+    errors. In order to turn a function into a coroutine they must be ``async def``
+    functions.
+
+.. function:: on_connect()
+
+    Called when the client has successfully connected to Discord. This is not
+    the same as the client being fully prepared, see :func:`on_ready` for that.
+
+    The warnings on :func:`on_ready` also apply.
+
+.. function:: on_shard_connect(shard_id)
+
+    Similar to :func:`on_connect` except used by :class:`AutoShardedClient`
+    to denote when a particular shard ID has connected to Discord.
+
+    .. versionadded:: 1.4
+
+    :param shard_id: The shard ID that has connected.
+    :type shard_id: :class:`int`
+
+.. function:: on_disconnect()
+
+    Called when the client has disconnected from Discord, or a connection attempt to Discord has failed.
+    This could happen either through the internet being disconnected, explicit calls to close,
+    or Discord terminating the connection one way or the other.
+
+    This function can be called many times without a corresponding :func:`on_connect` call.
+
+.. function:: on_shard_disconnect(shard_id)
+
+    Similar to :func:`on_disconnect` except used by :class:`AutoShardedClient`
+    to denote when a particular shard ID has disconnected from Discord.
+
+    .. versionadded:: 1.4
+
+    :param shard_id: The shard ID that has disconnected.
+    :type shard_id: :class:`int`
+
+.. function:: on_ready()
+
+    Called when the client is done preparing the data received from Discord. Usually after login is successful
+    and the :attr:`Client.guilds` and co. are filled up.
+
+    .. warning::
+
+        This function is not guaranteed to be the first event called.
+        Likewise, this function is **not** guaranteed to only be called
+        once. This library implements reconnection logic and thus will
+        end up calling this event whenever a RESUME request fails.
+
+.. function:: on_shard_ready(shard_id)
+
+    Similar to :func:`on_ready` except used by :class:`AutoShardedClient`
+    to denote when a particular shard ID has become ready.
+
+    :param shard_id: The shard ID that is ready.
+    :type shard_id: :class:`int`
+
+.. function:: on_resumed()
+
+    Called when the client has resumed a session.
+
+.. function:: on_shard_resumed(shard_id)
+
+    Similar to :func:`on_resumed` except used by :class:`AutoShardedClient`
+    to denote when a particular shard ID has resumed a session.
+
+    .. versionadded:: 1.4
+
+    :param shard_id: The shard ID that has resumed.
+    :type shard_id: :class:`int`
+
+.. function:: on_error(event, *args, **kwargs)
+
+    Usually when an event raises an uncaught exception, a traceback is
+    printed to stderr and the exception is ignored. If you want to
+    change this behaviour and handle the exception for whatever reason
+    yourself, this event can be overridden. Which, when done, will
+    suppress the default action of printing the traceback.
+
+    The information of the exception raised and the exception itself can
+    be retrieved with a standard call to :func:`sys.exc_info`.
+
+    If you want exception to propagate out of the :class:`Client` class
+    you can define an ``on_error`` handler consisting of a single empty
+    :ref:`raise statement <py:raise>`. Exceptions raised by ``on_error`` will not be
+    handled in any way by :class:`Client`.
+
+    .. note::
+
+        ``on_error`` will only be dispatched to :meth:`Client.event`.
+
+        It will not be received by :meth:`Client.wait_for`, or, if used,
+        :ref:`ext_commands_api_bot` listeners such as
+        :meth:`~ext.commands.Bot.listen` or :meth:`~ext.commands.Cog.listener`.
+
+    :param event: The name of the event that raised the exception.
+    :type event: :class:`str`
+
+    :param args: The positional arguments for the event that raised the
+        exception.
+    :param kwargs: The keyword arguments for the event that raised the
+        exception.
+
+.. function:: on_entitlement_create(entitlement)
+
+    Called when a user subscribes to a SKU.
+
+    .. versionadded:: 2.0
+
+    :param entitlement: The entitlement that was created.
+    :type entitlement: :class:`Entitlement`
+
+.. function:: on_entitlement_update(entitlement)
+
+   Sent when an entitlement is updated.
+
+    .. attention::
+        If a user's subscription is cancelled, you will **not** receive an :meth:`on_entitlement_delete` event.
+        When a user cancels, you will receive an `ENTITLEMENT_UPDATE` events with a valid :attr:`~discord.Entitlement.ends_at` value reflecting when their subscription ends
+
+    .. versionadded:: 2.0
+
+    :param entitlement: The entitlement that was updated.
+    :type entitlement: :class:`Entitlement`
+
+.. function:: on_entitlement_delete(entitlement)
+
+    Called when a user's entitlement is deleted.
+
+    Entitlement deletions are infrequent, and occur when:
+
+        - Discord issues a refund for a subscription
+        - Discord removes an entitlement from a user via internal tooling
+        - Discord deletes an app-managed entitlement they created via the API
+
+    .. attention::
+        Entitlements are not deleted when they expire.
+
+    .. versionadded:: 2.0
+
+    :param entitlement: The entitlement that was deleted.
+    :type entitlement: :class:`Entitlement`
+
+.. function:: on_subscription_create(subscription)
+
+    Called when a user subscribes to a SKU.
+
+    .. note::
+        A Subscription's `status` can be either **inactive** or **active** when this event is received.
+        You will receive subsequent :func:`on_subscription_update` events if the status is updated to **active**.
+
+        As a best practice, you should not grant any perks to users until the entitlements are created.
+
+    .. versionadded:: 2.0
+
+    :param subscription: The subscription that was created.
+    :type subscription: :class:`Subscription`
+
+.. function:: on_subscription_update(subscription)
+
+        Sent when a subscription is updated.
+
+        .. versionadded:: 2.0
+
+        :param subscription: The subscription that was updated.
+        :type subscription: :class:`Subscription`
+
+.. function:: on_subscription_delete(subscription)
+
+        Called when a user's subscription is deleted.
+
+        .. versionadded:: 2.0
+
+        :param subscription: The subscription that was deleted.
+        :type subscription: :class:`Subscription`
+
+.. function:: on_application_command_error(command, interaction, exception)
+
+    The default error handler when an exception was raised while invoking an `application-command <./Interactions/>`_ .
+
+    .. note::
+        This includes when a :meth:`~ext.commands.check` fails
+
+    By default, this prints to :data:`sys.stderr` however it could be
+    overridden to have a different implementation.
+
+    :param command: The :class:`SlashCommand`/:class:`SubCommand`, :class:`MessageCommand` or :class:`UserCommand` in which invocation the exception was raised.
+    :type command: :class:`ApplicationCommand`
+    :param interaction: The interaction that was invoked
+    :type interaction: :class:`ApplicationCommandInteraction`
+    :param exception: The exception that was raised
+    :type exception: :class:`Exception`
+
+.. function:: on_audit_log_entry_create(guild, entry)
+
+    Called whenever a guild audit log entry is created.
+
+    .. note::
+        This event is only sent to bots with the :attr:`~Permissions.view_audit_log` permission.
+
+    .. versionadded:: 2.0
+
+    :param guild: The guild that the audit log entry was created in.
+    :type guild: :class:`Guild`
+    :param entry: The audit log entry that was created.
+    :type entry: :class:`AuditLogEntry`
+
+.. function:: on_socket_raw_receive(msg)
+
+    Called whenever a message is received from the WebSocket, before
+    it's processed. This event is always dispatched when a message is
+    received and the passed data is not processed in any way.
+
+    This is only really useful for grabbing the WebSocket stream and
+    debugging purposes.
+
+    .. note::
+
+        This is only for the messages received from the client
+        WebSocket. The voice WebSocket will not trigger this event.
+
+    :param msg: The message passed in from the WebSocket library.
+                Could be :class:`bytes` for a binary message or :class:`str`
+                for a regular message.
+    :type msg: Union[:class:`bytes`, :class:`str`]
+
+.. function:: on_socket_raw_send(payload)
+
+    Called whenever a send operation is done on the WebSocket before the
+    message is sent. The passed parameter is the message that is being
+    sent to the WebSocket.
+
+    This is only really useful for grabbing the WebSocket stream and
+    debugging purposes.
+
+    .. note::
+
+        This is only for the messages sent from the client
+        WebSocket. The voice WebSocket will not trigger this event.
+
+    :param payload: The message that is about to be passed on to the
+                    WebSocket library. It can be :class:`bytes` to denote a binary
+                    message or :class:`str` to denote a regular text message.
+
+.. function:: on_typing(channel, user, when)
+
+    Called when someone begins typing a message.
+
+    The ``channel`` parameter can be a :class:`abc.Messageable` instance.
+    Which could either be :class:`TextChannel`, :class:`GroupChannel`, or
+    :class:`DMChannel`.
+
+    If the ``channel`` is a :class:`TextChannel` then the ``user`` parameter
+    is a :class:`Member`, otherwise it is a :class:`User`.
+
+    This requires :attr:`Intents.typing` to be enabled.
+
+    :param channel: The location where the typing originated from.
+    :type channel: :class:`abc.Messageable`
+    :param user: The user that started typing.
+    :type user: Union[:class:`User`, :class:`Member`]
+    :param when: When the typing started as a naive datetime in UTC.
+    :type when: :class:`datetime.datetime`
+
+.. function:: on_message(message)
+
+    Called when a :class:`Message` is created and sent.
+
+    This requires :attr:`Intents.messages` to be enabled.
+
+    .. warning::
+
+        Your bot's own messages and private messages are sent through this
+        event. This can lead cases of 'recursion' depending on how your bot was
+        programmed. If you want the bot to not reply to itself, consider
+        checking the user IDs. Note that :class:`~ext.commands.Bot` does not
+        have this problem.
+
+    :param message: The current message.
+    :type message: :class:`Message`
+
+.. function:: on_message_delete(message)
+
+    Called when a message is deleted. If the message is not found in the
+    internal message cache, then this event will not be called.
+    Messages might not be in cache if the message is too old
+    or the client is participating in high traffic guilds.
+
+    If this occurs increase the :attr:`Client.max_messages` attribute
+    or use the :func:`on_raw_message_delete` event instead.
+
+    This requires :attr:`Intents.messages` to be enabled.
+
+    :param message: The deleted message.
+    :type message: :class:`Message`
+
+.. function:: on_bulk_message_delete(messages)
+
+    Called when messages are bulk deleted. If none of the messages deleted
+    are found in the internal message cache, then this event will not be called.
+    If individual messages were not found in the internal message cache,
+    this event will still be called, but the messages not found will not be included in
+    the messages list. Messages might not be in cache if the message is too old
+    or the client is participating in high traffic guilds.
+
+    If this occurs increase the :attr:`Client.max_messages` attribute
+    or use the :func:`on_raw_bulk_message_delete` event instead.
+
+    This requires :attr:`Intents.messages` to be enabled.
+
+    :param messages: The messages that have been deleted.
+    :type messages: List[:class:`Message`]
+
+.. function:: on_raw_message_delete(payload)
+
+    Called when a message is deleted. Unlike :func:`on_message_delete`, this is
+    called regardless of the message being in the internal message cache or not.
+
+    If the message is found in the message cache,
+    it can be accessed via :attr:`RawMessageDeleteEvent.cached_message`
+
+    This requires :attr:`Intents.messages` to be enabled.
+
+    :param payload: The raw event payload data.
+    :type payload: :class:`RawMessageDeleteEvent`
+
+.. function:: on_raw_bulk_message_delete(payload)
+
+    Called when a bulk delete is triggered. Unlike :func:`on_bulk_message_delete`, this is
+    called regardless of the messages being in the internal message cache or not.
+
+    If the messages are found in the message cache,
+    they can be accessed via :attr:`RawBulkMessageDeleteEvent.cached_messages`
+
+    This requires :attr:`Intents.messages` to be enabled.
+
+    :param payload: The raw event payload data.
+    :type payload: :class:`RawBulkMessageDeleteEvent`
+
+.. function:: on_message_edit(before, after)
+
+    Called when a :class:`Message` receives an update event. If the message is not found
+    in the internal message cache, then these events will not be called.
+    Messages might not be in cache if the message is too old
+    or the client is participating in high traffic guilds.
+
+    If this occurs increase the :attr:`Client.max_messages` attribute
+    or use the :func:`on_raw_message_edit` event instead.
+
+    The following non-exhaustive cases trigger this event:
+
+    - A message has been pinned or unpinned.
+    - The message content has been changed.
+    - The message has received an embed.
+
+        - For performance reasons, the embed server does not do this in a "consistent" manner.
+
+    - The message's embeds were suppressed or unsuppressed.
+    - A call message has received an update to its participants or ending time.
+
+    This requires :attr:`Intents.messages` to be enabled.
+
+    :param before: The previous version of the message.
+    :type before: :class:`Message`
+    :param after: The current version of the message.
+    :type after: :class:`Message`
+
+.. function:: on_raw_message_edit(payload)
+
+    Called when a message is edited. Unlike :func:`on_message_edit`, this is called
+    regardless of the state of the internal message cache.
+
+    If the message is found in the message cache,
+    it can be accessed via :attr:`RawMessageUpdateEvent.cached_message`. The cached message represents
+    the message before it has been edited. For example, if the content of a message is modified and
+    triggers the :func:`on_raw_message_edit` coroutine, the :attr:`RawMessageUpdateEvent.cached_message`
+    will return a :class:`Message` object that represents the message before the content was modified.
+
+    Due to the inherently raw nature of this event, the data parameter coincides with
+    the raw data given by the `gateway <https://discord.com/developers/docs/topics/gateway#message-update>`_.
+
+    Since the data payload can be partial, care must be taken when accessing stuff in the dictionary.
+    One example of a common case of partial data is when the ``'content'`` key is inaccessible. This
+    denotes an "embed" only edit, which is an edit in which only the embeds are updated by the Discord
+    embed server.
+
+    This requires :attr:`Intents.messages` to be enabled.
+
+    :param payload: The raw event payload data.
+    :type payload: :class:`RawMessageUpdateEvent`
+
+.. function:: on_reaction_add(reaction, user)
+
+    Called when a message has a reaction added to it. Similar to :func:`on_message_edit`,
+    if the message is not found in the internal message cache, then this
+    event will not be called. Consider using :func:`on_raw_reaction_add` instead.
+
+    .. note::
+
+        To get the :class:`Message` being reacted, access it via :attr:`Reaction.message`.
+
+    This requires :attr:`Intents.reactions` to be enabled.
+
+    .. note::
+
+        This doesn't require :attr:`Intents.members` within a guild context,
+        but due to Discord not providing updated user information in a direct message
+        it's required for direct messages to receive this event.
+        Consider using :func:`on_raw_reaction_add` if you need this and do not otherwise want
+        to enable the members intent.
+
+    :param reaction: The current state of the reaction.
+    :type reaction: :class:`Reaction`
+    :param user: The user who added the reaction.
+    :type user: Union[:class:`Member`, :class:`User`]
+
+.. function:: on_raw_reaction_add(payload)
+
+    Called when a message has a reaction added. Unlike :func:`on_reaction_add`, this is
+    called regardless of the state of the internal message cache.
+
+    This requires :attr:`Intents.reactions` to be enabled.
+
+    :param payload: The raw event payload data.
+    :type payload: :class:`RawReactionActionEvent`
+
+.. function:: on_reaction_remove(reaction, user)
+
+    Called when a message has a reaction removed from it. Similar to on_message_edit,
+    if the message is not found in the internal message cache, then this event
+    will not be called.
+
+    .. note::
+
+        To get the message being reacted, access it via :attr:`Reaction.message`.
+
+    This requires both :attr:`Intents.reactions` and :attr:`Intents.members` to be enabled.
+
+    .. note::
+
+        Consider using :func:`on_raw_reaction_remove` if you need this and do not want
+        to enable the members intent.
+
+    :param reaction: The current state of the reaction.
+    :type reaction: :class:`Reaction`
+    :param user: The user who added the reaction.
+    :type user: Union[:class:`Member`, :class:`User`]
+
+.. function:: on_raw_reaction_remove(payload)
+
+    Called when a message has a reaction removed. Unlike :func:`on_reaction_remove`, this is
+    called regardless of the state of the internal message cache.
+
+    This requires :attr:`Intents.reactions` to be enabled.
+
+    :param payload: The raw event payload data.
+    :type payload: :class:`RawReactionActionEvent`
+
+.. function:: on_reaction_clear(message, reactions)
+
+    Called when a message has all its reactions removed from it. Similar to :func:`on_message_edit`,
+    if the message is not found in the internal message cache, then this event
+    will not be called. Consider using :func:`on_raw_reaction_clear` instead.
+
+    This requires :attr:`Intents.reactions` to be enabled.
+
+    :param message: The message that had its reactions cleared.
+    :type message: :class:`Message`
+    :param reactions: The reactions that were removed.
+    :type reactions: List[:class:`Reaction`]
+
+.. function:: on_raw_reaction_clear(payload)
+
+    Called when a message has all its reactions removed. Unlike :func:`on_reaction_clear`,
+    this is called regardless of the state of the internal message cache.
+
+    This requires :attr:`Intents.reactions` to be enabled.
+
+    :param payload: The raw event payload data.
+    :type payload: :class:`RawReactionClearEvent`
+
+.. function:: on_reaction_clear_emoji(reaction)
+
+    Called when a message has a specific reaction removed from it. Similar to :func:`on_message_edit`,
+    if the message is not found in the internal message cache, then this event
+    will not be called. Consider using :func:`on_raw_reaction_clear_emoji` instead.
+
+    This requires :attr:`Intents.reactions` to be enabled.
+
+    .. versionadded:: 1.3
+
+    :param reaction: The reaction that got cleared.
+    :type reaction: :class:`Reaction`
+
+.. function:: on_raw_reaction_clear_emoji(payload)
+
+    Called when a message has a specific reaction removed from it. Unlike :func:`on_reaction_clear_emoji` this is called
+    regardless of the state of the internal message cache.
+
+    This requires :attr:`Intents.reactions` to be enabled.
+
+    .. versionadded:: 1.3
+
+    :param payload: The raw event payload data.
+    :type payload: :class:`RawReactionClearEmojiEvent`
+
+.. function:: on_private_channel_delete(channel)
+              on_private_channel_create(channel)
+
+    Called whenever a private channel is deleted or created.
+
+    This requires :attr:`Intents.messages` to be enabled.
+
+    :param channel: The private channel that got created or deleted.
+    :type channel: :class:`abc.PrivateChannel`
+
+.. function:: on_private_channel_update(before, after)
+
+    Called whenever a private group DM is updated. e.g. changed name or topic.
+
+    This requires :attr:`Intents.messages` to be enabled.
+
+    :param before: The updated group channel's old info.
+    :type before: :class:`GroupChannel`
+    :param after: The updated group channel's new info.
+    :type after: :class:`GroupChannel`
+
+.. function:: on_private_channel_pins_update(channel, last_pin)
+
+    Called whenever a message is pinned or unpinned from a private channel.
+
+    :param channel: The private channel that had its pins updated.
+    :type channel: :class:`abc.PrivateChannel`
+    :param last_pin: The latest message that was pinned as a naive datetime in UTC. Could be ``None``.
+    :type last_pin: Optional[:class:`datetime.datetime`]
+
+.. function:: on_guild_channel_delete(channel)
+              on_guild_channel_create(channel)
+
+    Called whenever a guild channel is deleted or created.
+
+    Note that you can get the guild from :attr:`~abc.GuildChannel.guild`.
+
+    This requires :attr:`Intents.guilds` to be enabled.
+
+    :param channel: The guild channel that got created or deleted.
+    :type channel: :class:`abc.GuildChannel`
+
+.. function:: on_guild_channel_update(before, after)
+
+    Called whenever a guild channel is updated. e.g. changed name, topic, permissions.
+
+    This requires :attr:`Intents.guilds` to be enabled.
+
+    :param before: The updated guild channel's old info.
+    :type before: :class:`abc.GuildChannel`
+    :param after: The updated guild channel's new info.
+    :type after: :class:`abc.GuildChannel`
+
+.. function:: on_guild_channel_pins_update(channel, last_pin)
+
+    Called whenever a message is pinned or unpinned from a guild channel.
+
+    This requires :attr:`Intents.guilds` to be enabled.
+
+    :param channel: The guild channel that had its pins updated.
+    :type channel: :class:`abc.GuildChannel`
+    :param last_pin: The latest message that was pinned as a naive datetime in UTC. Could be ``None``.
+    :type last_pin: Optional[:class:`datetime.datetime`]
+
+.. function:: on_guild_integrations_update(guild)
+
+    .. versionadded:: 1.4
+
+    Called whenever an integration is created, modified, or removed from a guild.
+
+    This requires :attr:`Intents.integrations` to be enabled.
+
+    :param guild: The guild that had its integrations updated.
+    :type guild: :class:`Guild`
+
+.. function:: on_webhooks_update(channel)
+
+    Called whenever a webhook is created, modified, or removed from a guild channel.
+
+    This requires :attr:`Intents.webhooks` to be enabled.
+
+    :param channel: The channel that had its webhooks updated.
+    :type channel: :class:`abc.GuildChannel`
+
+.. function:: on_member_join(member)
+              on_member_remove(member)
+
+    Called when a :class:`Member` leaves or joins a :class:`Guild`.
+
+    This requires :attr:`Intents.members` to be enabled.
+
+    :param member: The member who joined or left.
+    :type member: :class:`Member`
+
+.. function:: on_member_update(before, after)
+
+    Called when a :class:`Member` updates their profile.
+
+    This is called when one or more of the following things change:
+
+    - status
+    - activity
+    - nickname
+    - roles
+    - pending
+
+    This requires :attr:`Intents.members` to be enabled.
+
+    :param before: The updated member's old info.
+    :type before: :class:`Member`
+    :param after: The updated member's updated info.
+    :type after: :class:`Member`
+
+.. function:: on_user_update(before, after)
+
+    Called when a :class:`User` updates their profile.
+
+    This is called when one or more of the following things change:
+
+    - avatar
+    - username
+    - discriminator
+
+    This requires :attr:`Intents.members` to be enabled.
+
+    :param before: The updated user's old info.
+    :type before: :class:`User`
+    :param after: The updated user's updated info.
+    :type after: :class:`User`
+
+.. function:: on_guild_join(guild)
+
+    Called when a :class:`Guild` is either created by the :class:`Client` or when the
+    :class:`Client` joins a guild.
+
+    This requires :attr:`Intents.guilds` to be enabled.
+
+    :param guild: The guild that was joined.
+    :type guild: :class:`Guild`
+
+.. function:: on_guild_remove(guild)
+
+    Called when a :class:`Guild` is removed from the :class:`Client`.
+
+    This happens through, but not limited to, these circumstances:
+
+    - The client got banned.
+    - The client got kicked.
+    - The client left the guild.
+    - The client or the guild owner deleted the guild.
+
+    In order for this event to be invoked then the :class:`Client` must have
+    been part of the guild to begin with. (i.e. it is part of :attr:`Client.guilds`)
+
+    This requires :attr:`Intents.guilds` to be enabled.
+
+    :param guild: The guild that got removed.
+    :type guild: :class:`Guild`
+
+.. function:: on_guild_update(before, after)
+
+    Called when a :class:`Guild` updates, for example:
+
+    - Changed name
+    - Changed AFK channel
+    - Changed AFK timeout
+    - etc
+
+    This requires :attr:`Intents.guilds` to be enabled.
+
+    :param before: The guild prior to being updated.
+    :type before: :class:`Guild`
+    :param after: The guild after being updated.
+    :type after: :class:`Guild`
+
+.. function:: on_guild_role_create(role)
+              on_guild_role_delete(role)
+
+    Called when a :class:`Guild` creates or deletes a new :class:`Role`.
+
+    To get the guild it belongs to, use :attr:`Role.guild`.
+
+    This requires :attr:`Intents.guilds` to be enabled.
+
+    :param role: The role that was created or deleted.
+    :type role: :class:`Role`
+
+.. function:: on_guild_role_update(before, after)
+
+    Called when a :class:`Role` is changed guild-wide.
+
+    This requires :attr:`Intents.guilds` to be enabled.
+
+    :param before: The updated role's old info.
+    :type before: :class:`Role`
+    :param after: The updated role's updated info.
+    :type after: :class:`Role`
+
+.. function:: on_guild_emojis_update(guild, before, after)
+
+    Called when a :class:`Guild` adds or removes :class:`Emoji`.
+
+    This requires :attr:`Intents.emojis` to be enabled.
+
+    :param guild: The guild who got their emojis updated.
+    :type guild: :class:`Guild`
+    :param before: A list of emojis before the update.
+    :type before: Sequence[:class:`Emoji`]
+    :param after: A list of emojis after the update.
+    :type after: Sequence[:class:`Emoji`]
+
+.. function:: on_guild_available(guild)
+              on_guild_unavailable(guild)
+
+    Called when a guild becomes available or unavailable. The guild must have
+    existed in the :attr:`Client.guilds` cache.
+
+    This requires :attr:`Intents.guilds` to be enabled.
+
+    :param guild: The :class:`Guild` that has changed availability.
+
+.. function:: on_voice_state_update(member, before, after)
+
+    Called when a :class:`Member` changes their :class:`VoiceState`.
+
+    The following, but not limited to, examples illustrate when this event is called:
+
+    - A member joins a voice channel.
+    - A member leaves a voice channel.
+    - A member is muted or deafened by their own accord.
+    - A member is muted or deafened by a guild administrator.
+
+    This requires :attr:`Intents.voice_states` to be enabled.
+
+    :param member: The member whose voice states changed.
+    :type member: :class:`Member`
+    :param before: The voice state prior to the changes.
+    :type before: :class:`VoiceState`
+    :param after: The voice state after the changes.
+    :type after: :class:`VoiceState`
+
+.. function:: on_voice_channel_status_update(channel, before, after)
+
+    Called when the :attr:`~discord.VoiceChannel.status` gets changed by a member or cleared by discord automatically.
+
+    .. versionadded:: 2.0
+
+    :param channel: The voice channel that had its status updated.
+    :type channel: :class:`VoiceChannel`
+    :param before: The voice channel's old status.
+    :type before: :class:`str`
+    :param after: The voice channel's new status.
+    :type after: :class:`str`
+
+.. function:: on_member_ban(guild, user)
+
+    Called when user gets banned from a :class:`Guild`.
+
+    This requires :attr:`Intents.bans` to be enabled.
+
+    :param guild: The guild the user got banned from.
+    :type guild: :class:`Guild`
+    :param user: The user that got banned.
+                 Can be either :class:`User` or :class:`Member` depending if
+                 the user was in the guild or not at the time of removal.
+    :type user: Union[:class:`User`, :class:`Member`]
+
+.. function:: on_member_unban(guild, user)
+
+    Called when a :class:`User` gets unbanned from a :class:`Guild`.
+
+    This requires :attr:`Intents.bans` to be enabled.
+
+    :param guild: The guild the user got unbanned from.
+    :type guild: :class:`Guild`
+    :param user: The user that got unbanned.
+    :type user: :class:`User`
+
+.. function:: on_invite_create(invite)
+
+    Called when an :class:`Invite` is created.
+    You must have the :attr:`~Permissions.manage_channels` permission to receive this.
+
+    .. versionadded:: 1.3
+
+    .. note::
+
+        There is a rare possibility that the :attr:`Invite.guild` and :attr:`Invite.channel`
+        attributes will be of :class:`Object` rather than the respective models.
+
+    This requires :attr:`Intents.invites` to be enabled.
+
+    :param invite: The invite that was created.
+    :type invite: :class:`Invite`
+
+.. function:: on_invite_delete(invite)
+
+    Called when an :class:`Invite` is deleted.
+    You must have the :attr:`~Permissions.manage_channels` permission to receive this.
+
+    .. versionadded:: 1.3
+
+    .. note::
+
+        There is a rare possibility that the :attr:`Invite.guild` and :attr:`Invite.channel`
+        attributes will be of :class:`Object` rather than the respective models.
+
+        Outside of those two attributes, the only other attribute guaranteed to be
+        filled by the Discord gateway for this event is :attr:`Invite.code`.
+
+    This requires :attr:`Intents.invites` to be enabled.
+
+    :param invite: The invite that was deleted.
+    :type invite: :class:`Invite`
+
+.. function:: on_group_join(channel, user)
+              on_group_remove(channel, user)
+
+    Called when someone joins or leaves a :class:`GroupChannel`.
+
+    :param channel: The group that the user joined or left.
+    :type channel: :class:`GroupChannel`
+    :param user: The user that joined or left.
+    :type user: :class:`User`
+
+.. function:: on_automod_rule_create(rule)
+
+    Called when a auto moderation rule is created.
+
+    :param rule: The rule that was created.
+    :type rule: :class:`AutoModRule`
+
+.. function:: on_automod_rule_update(before, after)
+
+    Called when a auto moderation rule is updated.
+
+    :param before: The old rule.
+    :type before: :class:`AutoModRule`
+    :param after: The updated rule.
+    :type after: :class:`AutoModRule`
+
+.. function:: on_automod_rule_delete(rule)
+
+    Called when a auto moderation rule is deleted.
+
+    :param rule: The rule that was deleted.
+    :type rule: :class:`AutoModRule`
+
+.. function:: on_automod_action(payload)
+
+    Called when a :class:`AutoModRule` was triggered by a user
+
+    :param payload: The payload containing all the information
+    :type payload: :class:`AutoModActionPayload`
+
+.. function:: on_button_click(interaction, button)
+
+    Called when a :class:`Button`, that is attached to a :class:`Message` **which is in the internal cache**, is pressed.
+
+    .. note::
+        In general it is more efficient to use :func:`~Client.on_click`/:func:`ext.commands.Cog.on_click` instead of this and :func:`on_raw_button_click` to make a callback for buttons
+
+    :param interaction: The Interaction-object with all his attributes and methods to respond to the interaction
+    :type interaction: :class:`~discord.ComponentInteraction`
+    :param button: The button that was pressed. (this is also available under :attr:`discord.ComponentInteraction.component`).
+    :type button: :class:`Button`
+
+.. function:: on_raw_button_click(interaction, button)
+
+    Called when a :class:`Button`, that is attached to **any** :class:`Message` of the bot, is pressed.
+
+    .. warning::
+        This may be removed and be included in :func:`on_button_click` in a future release
+
+    :param interaction: The Interaction-object with all his attributes and methods to respond to the interaction
+    :type interaction: :class:`~discord.ComponentInteraction`
+    :param button: The button that was pressed. (this is also available under :attr:`discord.ComponentInteraction.component`).
+    :type button: :class:`Button`
+
+.. function:: on_selection_select(interaction, select_menu)
+
+    Called when a :class:`SelectMenu`, that is attached to a :class:`Message` **which is in the internal cache**, is used.
+
+    .. note::
+        In general it is more efficient to use :func:`~Client.on_select`/:func:`ext.commands.Cog.on_select` instead of this and :func:`on_raw_selection_select` to make a callback for select menus
+
+    :param interaction: The Interaction-object with all his attributes and methods to respond to the interaction
+    :type interaction: :class:`~discord.ComponentInteraction`
+    :param select_menu: The :class:`SelectMenu` but with the :attr:`SelectMenu.values` set which contains a list of the selected :attr:`~SelectMenu.options`. (this is also available under :attr:`discord.ComponentInteraction.component`).
+    :type select_menu: :class:`SelectMenu`
+
+.. function:: on_raw_selection_select(interaction, select_menu)
+
+    Called when a :class:`SelectMenu`, that is attached to **any** :class:`Message` of the bot, is used.
+
+    .. warning::
+        This may be removed and be included in :func:`on_selection_select` in a future release
+
+    :param interaction: The Interaction-object with all his attributes and methods to respond to the interaction
+    :type interaction: :class:`~discord.ComponentInteraction`
+    :param select_menu: The :class:`SelectMenu` but with the :attr:`SelectMenu.values` set which contains a list of the selected :attr:`~SelectMenu.options`. (this is also available under :attr:`discord.ComponentInteraction.component`).
+    :type select_menu: :class:`SelectMenu`
+
+.. function:: on_modal_submit(interaction)
+
+    Called when a user press the ``Submit`` button in a :class:`Modal`.
+
+    .. note::
+        In general it is more efficient to use :func:`~Client.on_submit`/:func:`ext.commands.Cog.on_submit` instead of this to make a callback for modals
+
+    :param interaction: he Interaction-object with all his attributes and methods to respond to the interaction
+    :type interaction: :class:`~discord.ModalSubmitInteraction`
+
+.. function:: on_application_command_permissions_update(guild, command, new_permissions):
+
+        Called when the permissions for an application command are updated.
+
+        :param guild: The guild where the permissions were updated.
+        :type guild: :class:`Guild`
+        :param command: The command that was updated.
+        :type command: :class:`ApplicationCommand`
+        :param new_permissions: The new permissions for the command.
+        :type new_permissions: :class:`ApplicationCommandPermissions`
+
+.. function:: on_scheduled_event_create(event)
+
+    Called when a :class:`GuildScheduledEvent` is created.
+
+    :param event: The event that was created.
+    :type event: :class:`GuildScheduledEvent`
+
+.. function:: on_scheduled_event_update(before, after)
+
+    Called when a :class:`GuildScheduledEvent` is updated.
+
+    :param before: The old event.
+    :type before: :class:`GuildScheduledEvent`
+    :param after: The updated event.
+    :type after: :class:`GuildScheduledEvent`
+
+.. function:: on_scheduled_event_delete(event)
+
+    Called when a :class:`GuildScheduledEvent` is deleted.
+
+    :param event: The event that was deleted.
+    :type event: :class:`GuildScheduledEvent`
+
+.. function:: on_stage_instance_create(stage_instance)
+
+    Called when a :class:`StageInstance` is created.
+
+    :param stage_instance: The stage instance that was created.
+    :type stage_instance: :class:`StageInstance`
+
+.. function:: on_stage_instance_update(before, after)
+
+        Called when a :class:`StageInstance` is updated.
+
+        :param before: The old stage instance.
+        :type before: :class:`StageInstance`
+        :param after: The updated stage instance.
+        :type after: :class:`StageInstance`
+
+.. function:: on_stage_instance_delete(stage_instance)
+
+        Called when a :class:`StageInstance` is deleted.
+
+        :param stage_instance: The stage instance that was deleted.
+        :type stage_instance: :class:`StageInstance`
+
+.. function:: on_voice_channel_effect_send(channel, payload):
+
+        Called when a user uses a voice effect in a :class:`VoiceChannel`.
+
+        :param channel: The voice channel in which the effect was used.
+        :type channel: :class:`VoiceChannel`
+        :param payload: The payload containing info about the effect.
+        :type payload: :class:`VoiceChannelEffectSendEvent`
diff --git a/docs/api/exceptions.rst b/docs/api/exceptions.rst
new file mode 100644
index 00000000..80b595ef
--- /dev/null
+++ b/docs/api/exceptions.rst
@@ -0,0 +1,70 @@
+.. currentmodule:: discord
+
+Exceptions
+------------
+
+The following exceptions are thrown by the library.
+
+.. autoexception:: DiscordException
+
+.. autoexception:: ClientException
+
+.. autoexception:: LoginFailure
+
+.. autoexception:: NoMoreItems
+
+.. autoexception:: HTTPException
+    :members:
+
+.. autoexception:: Unauthorized
+
+.. autoexception:: Forbidden
+
+.. autoexception:: NotFound
+
+.. autoexception:: DiscordServerError
+
+.. autoexception:: InvalidData
+
+.. autoexception:: InvalidArgument
+
+.. autoexception:: GatewayNotFound
+
+.. autoexception:: ConnectionClosed
+
+.. autoexception:: PrivilegedIntentsRequired
+
+.. autoexception:: AlreadyResponded
+
+.. autoexception:: discord.opus.OpusError
+
+.. autoexception:: discord.opus.OpusNotLoaded
+
+.. autoexception:: DiscordWarning
+
+.. autoexception:: UnknownInteraction
+
+Exception Hierarchy
+~~~~~~~~~~~~~~~~~~~~~
+
+.. exception_hierarchy::
+
+    - :exc:`Exception`
+        - :exc:`DiscordException`
+            - :exc:`ClientException`
+                - :exc:`InvalidData`
+                - :exc:`InvalidArgument`
+                - :exc:`LoginFailure`
+                - :exc:`ConnectionClosed`
+                - :exc:`PrivilegedIntentsRequired`
+            - :exc:`NoMoreItems`
+            - :exc:`GatewayNotFound`
+            - :exc:`HTTPException`
+                - :exc:`Unauthorized`
+                - :exc:`Forbidden`
+                - :exc:`NotFound`
+                - :exc:`DiscordServerError`
+            - :exc:`AlreadyResponded`
+    - :exc:`Warning`
+        - :exc:`DiscordWarning`
+            - :exc:`UnknownInteraction`
\ No newline at end of file
diff --git a/docs/api/index.rst b/docs/api/index.rst
new file mode 100644
index 00000000..42754214
--- /dev/null
+++ b/docs/api/index.rst
@@ -0,0 +1,54 @@
+.. currentmodule:: discord
+
+API Reference
+===============
+
+The following section outlines the API of discord.py-message-components.
+
+.. note::
+
+    This module uses the Python :mod:`logging` to log diagnostic and errors
+    in an output independent way.
+    By default the logs will be printed in :attr:`sys.stdout` (aka the console).
+    See :ref:`logging_setup` for
+    more information on how to use the logging module with
+    discord.py-message-components.
+
+Version Related Info
+---------------------
+
+There are two main ways to query version information about the library. For guarantees, check :ref:`version_guarantees`.
+
+.. data:: version_info
+
+    A named tuple that is similar to :obj:`py:sys.version_info`.
+
+    Just like :obj:`py:sys.version_info` the valid values for ``releaselevel`` are
+    'alpha', 'beta', 'candidate' and 'final'.
+
+.. data:: __version__
+
+    A string representation of the version. e.g. ``'1.0.0rc1'``. This is based
+    off of :pep:`440`.
+
+
+The rest of the API documentation is split in to their respective sections, which are:
+
+.. toctree::
+    :maxdepth: 1
+
+    Clients <clients.rst>
+    Application Info <application-info.rst>
+    Monetization <monetization.rst>
+    Audit Logs <audit-logs.rst>
+    Enum Types <enums.rst>
+    Constants <constants.rst>
+    Voice <voice.rst>
+    Event Reference <events.rst>
+    Exceptions <exceptions.rst>
+    Utility Functions <utils.rst>
+    Webhooks <webhooks.rst>
+    API Models <models.rst>
+    ABCs <abcs.rst>
+    Async Iterator <async-iterator.rst>
+    Data Classes <data-classes.rst>
diff --git a/docs/api/models.rst b/docs/api/models.rst
new file mode 100644
index 00000000..7543bf79
--- /dev/null
+++ b/docs/api/models.rst
@@ -0,0 +1,579 @@
+.. currentmodule:: discord
+
+.. _discord_api_models:
+
+Discord Models
+---------------
+
+Models are classes that are received from Discord and are not meant to be created by
+the user of the library.
+
+.. danger::
+
+    The classes listed below are **not intended to be created by users** and are also
+    **read-only**.
+
+    For example, this means that you should not make your own :class:`User` instances
+    nor should you modify the :class:`User` instance yourself.
+
+    If you want to get one of these model classes instances they'd have to be through
+    the cache, and a common way of doing so is through the :func:`utils.find` function
+    or attributes of model classes that you receive from the events specified in the
+    :ref:`discord-api-events`.
+
+.. note::
+
+    Nearly all classes here have :ref:`py:slots` defined which means that it is
+    impossible to have dynamic attributes to the data classes.
+
+
+ClientUser
+~~~~~~~~~~~~
+
+.. attributetable:: ClientUser
+
+.. autoclass:: ClientUser()
+    :members:
+    :inherited-members:
+
+User
+~~~~~
+
+.. attributetable:: User
+
+.. autoclass:: User()
+    :members:
+    :inherited-members:
+    :exclude-members: history, typing
+
+    .. automethod:: history
+        :async-for:
+
+    .. automethod:: typing
+        :async-with:
+
+Attachment
+~~~~~~~~~~~
+
+.. attributetable:: Attachment
+
+.. autoclass:: Attachment()
+    :members:
+
+Asset
+~~~~~
+
+.. attributetable:: Asset
+
+.. autoclass:: Asset()
+    :members:
+
+Message
+~~~~~~~
+
+.. attributetable:: Message
+
+.. autoclass:: Message()
+    :members:
+
+EphemeralMessage
+~~~~~~~~~~~~~~~~~
+
+.. attributetable:: EphemeralMessage
+
+.. autoclass:: EphemeralMessage()
+    :members:
+
+MessageInteraction
+~~~~~~~~~~~~~~~~~~~
+
+.. attributetable:: MessageInteraction
+
+.. autoclass:: MessageInteraction()
+    :members:
+
+RoleSubscriptionInfo
+~~~~~~~~~~~~~~~~~~~~
+
+.. attributetable:: RoleSubscriptionInfo
+
+.. autoclass:: RoleSubscriptionInfo()
+    :members:
+
+DeletedReferencedMessage
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. attributetable:: DeletedReferencedMessage
+
+.. autoclass:: DeletedReferencedMessage()
+    :members:
+
+
+Reaction
+~~~~~~~~~
+
+.. attributetable:: Reaction
+
+.. autoclass:: Reaction()
+    :members:
+    :exclude-members: users
+
+    .. automethod:: users
+        :async-for:
+
+Guild
+~~~~~~
+
+.. attributetable:: Guild
+
+.. autoclass:: Guild()
+    :members:
+    :exclude-members: fetch_members, audit_logs
+
+    .. automethod:: fetch_members
+        :async-for:
+
+    .. automethod:: audit_logs
+        :async-for:
+
+.. autoclass:: GuildFeatures()
+    :members:
+
+.. class:: BanEntry
+
+    A namedtuple which represents a ban returned from :meth:`~Guild.bans`.
+
+    .. attribute:: reason
+
+        The reason this user was banned.
+
+        :type: Optional[:class:`str`]
+    .. attribute:: user
+
+        The :class:`User` that was banned.
+
+        :type: :class:`User`
+
+GuildScheduledEvent
+~~~~~~~~~~~~~~~~~~~~
+
+.. attributetable:: GuildScheduledEvent
+
+.. autoclass:: GuildScheduledEvent()
+    :members:
+    :exclude-members: users
+
+    .. automethod:: users
+        :async-for:
+
+AutoModRule
+~~~~~~~~~~~~
+
+.. attributetable:: AutoModRule
+
+.. autoclass:: AutoModRule()
+    :members:
+
+AutoModActionPayload
+~~~~~~~~~~~~~~~~~~~~~
+
+.. attributetable:: AutoModActionPayload
+
+.. autoclass:: AutoModActionPayload()
+    :members:
+
+WelcomeScreen
+~~~~~~~~~~~~~~
+
+.. attributetable:: WelcomeScreen
+
+.. autoclass:: WelcomeScreen()
+    :members:
+
+Integration
+~~~~~~~~~~~~
+
+.. autoclass:: Integration()
+    :members:
+
+.. autoclass:: IntegrationAccount()
+    :members:
+
+Member
+~~~~~~
+
+.. attributetable:: Member
+
+.. autoclass:: Member()
+    :members:
+    :inherited-members:
+    :exclude-members: history, typing
+
+    .. automethod:: history
+        :async-for:
+
+    .. automethod:: typing
+        :async-with:
+
+GuildMemberFlags
+~~~~~~~~~~~~~~~~
+
+.. attributetable:: GuildMemberFlags
+
+.. autoclass:: GuildMemberFlags()
+    :members:
+
+Spotify
+~~~~~~~~
+
+.. attributetable:: Spotify
+
+.. autoclass:: Spotify()
+    :members:
+
+VoiceState
+~~~~~~~~~~~
+
+.. attributetable:: VoiceState
+
+.. autoclass:: VoiceState()
+    :members:
+
+Emoji
+~~~~~
+
+.. attributetable:: Emoji
+
+.. autoclass:: Emoji()
+    :members:
+
+PartialEmoji
+~~~~~~~~~~~~~~~~~~~~~~
+
+.. attributetable:: PartialEmoji
+
+.. autoclass:: PartialEmoji()
+    :members:
+
+Role
+~~~~~
+
+.. attributetable:: Role
+
+.. autoclass:: Role()
+    :members:
+
+RoleTags
+~~~~~~~~~~
+
+.. attributetable:: RoleTags
+
+.. autoclass:: RoleTags()
+    :members:
+
+
+PartialMessageable
+~~~~~~~~~~~~~~~~~~~
+
+.. attributetable:: PartialMessageable
+
+.. autoclass:: PartialMessageable()
+    :members:
+    :inherited-members:
+    :exclude-members: history, typing
+
+        .. automethod:: history
+            :async-for:
+
+        .. automethod:: typing
+            :async-with:
+
+TextChannel
+~~~~~~~~~~~~
+
+.. attributetable:: TextChannel
+
+.. autoclass:: TextChannel()
+    :members:
+    :inherited-members:
+    :exclude-members: history, typing, archived_threads
+
+    .. automethod:: archived_threads
+        :async-for:
+
+    .. automethod:: history
+        :async-for:
+
+    .. automethod:: typing
+        :async-with:
+
+ThreadChannel
+~~~~~~~~~~~~~~
+
+.. attributetable:: ThreadChannel
+
+.. autoclass:: ThreadChannel()
+    :members:
+    :inherited-members:
+    :exclude-members: history, typing, fetch_members
+
+    .. automethod:: history
+        :async-for:
+
+    .. automethod:: typing
+        :async-with:
+
+    .. automethod:: fetch_members
+        :async-for:
+
+ThreadMember
+~~~~~~~~~~~~~~
+
+.. attributetable:: ThreadMember
+
+.. autoclass:: ThreadMember()
+    :members:
+    :inherited-members:
+
+VoiceChannel
+~~~~~~~~~~~~~
+
+.. attributetable:: VoiceChannel
+
+.. autoclass:: VoiceChannel()
+    :members:
+    :inherited-members:
+    :exclude-members: history, typing
+
+    .. automethod:: history
+        :async-for:
+
+    .. automethod:: typing
+        :async-with:
+
+StageChannel
+~~~~~~~~~~~~~
+
+.. attributetable:: StageChannel
+
+.. autoclass:: StageChannel()
+    :members:
+    :inherited-members:
+
+ForumChannel
+~~~~~~~~~~~~~
+
+.. attributetable:: ForumChannel
+
+
+.. autoclass:: ForumChannel()
+    :members:
+    :inherited-members:
+    :exclude-members: archived_posts
+
+    .. automethod:: archived_posts
+        :async-for:
+
+ForumPost
+~~~~~~~~~~
+
+.. attributetable:: ForumPost
+
+.. autoclass:: ForumPost()
+    :members:
+    :inherited-members:
+    :exclude-members: history, typing, fetch_members
+
+    .. automethod:: history
+        :async-for:
+
+    .. automethod:: typing
+        :async-with:
+
+    .. automethod:: fetch_members
+        :async-for:
+
+CategoryChannel
+~~~~~~~~~~~~~~~~~
+
+.. attributetable:: CategoryChannel
+
+.. autoclass:: CategoryChannel()
+    :members:
+    :inherited-members:
+
+DMChannel
+~~~~~~~~~
+
+.. attributetable:: DMChannel
+
+.. autoclass:: DMChannel()
+    :members:
+    :inherited-members:
+    :exclude-members: history, typing
+
+    .. automethod:: history
+        :async-for:
+
+    .. automethod:: typing
+        :async-with:
+
+GroupChannel
+~~~~~~~~~~~~
+
+.. attributetable:: GroupChannel
+
+.. autoclass:: GroupChannel()
+    :members:
+    :inherited-members:
+    :exclude-members: history, typing
+
+    .. automethod:: history
+        :async-for:
+
+    .. automethod:: typing
+        :async-with:
+
+PartialInviteGuild
+~~~~~~~~~~~~~~~~~~~
+
+.. attributetable:: PartialInviteGuild
+
+.. autoclass:: PartialInviteGuild()
+    :members:
+
+PartialInviteChannel
+~~~~~~~~~~~~~~~~~~~~~
+
+.. attributetable:: PartialInviteChannel
+
+.. autoclass:: PartialInviteChannel()
+    :members:
+
+Invite
+~~~~~~~
+
+.. attributetable:: Invite
+
+.. autoclass:: Invite()
+    :members:
+
+Template
+~~~~~~~~~
+
+.. attributetable:: Template
+
+.. autoclass:: Template()
+    :members:
+
+WidgetChannel
+~~~~~~~~~~~~~~~
+
+.. attributetable:: WidgetChannel
+
+.. autoclass:: WidgetChannel()
+    :members:
+
+WidgetMember
+~~~~~~~~~~~~~
+
+.. attributetable:: WidgetMember
+
+.. autoclass:: WidgetMember()
+    :members:
+    :inherited-members:
+
+Widget
+~~~~~~~
+
+.. attributetable:: Widget
+
+.. autoclass:: Widget()
+    :members:
+
+StickerPack
+~~~~~~~~~~~~
+
+.. attributetable:: StickerPack
+
+.. autoclass:: StickerPack()
+    :members:
+
+Sticker
+~~~~~~~~
+
+.. attributetable:: Sticker
+
+.. autoclass:: Sticker()
+    :members:
+
+.. attributetable:: GuildSticker
+
+.. autoclass:: GuildSticker()
+    :inherited-members:
+    :members:
+    :exclude-members: pack, pack_id, sort_value
+
+VoiceRegionInfo
+~~~~~~~~~~~~~~~~
+
+.. attributetable:: VoiceRegionInfo
+
+.. autoclass:: VoiceRegionInfo()
+    :members:
+
+RawMessageDeleteEvent
+~~~~~~~~~~~~~~~~~~~~~~~
+
+.. attributetable:: RawMessageDeleteEvent
+
+.. autoclass:: RawMessageDeleteEvent()
+    :members:
+
+RawBulkMessageDeleteEvent
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. attributetable:: RawBulkMessageDeleteEvent
+
+.. autoclass:: RawBulkMessageDeleteEvent()
+    :members:
+
+RawMessageUpdateEvent
+~~~~~~~~~~~~~~~~~~~~~~
+
+.. attributetable:: RawMessageUpdateEvent
+
+.. autoclass:: RawMessageUpdateEvent()
+    :members:
+
+RawReactionActionEvent
+~~~~~~~~~~~~~~~~~~~~~~~
+
+.. attributetable:: RawReactionActionEvent
+
+.. autoclass:: RawReactionActionEvent()
+    :members:
+
+RawReactionClearEvent
+~~~~~~~~~~~~~~~~~~~~~~
+
+.. attributetable:: RawReactionClearEvent
+
+.. autoclass:: RawReactionClearEvent()
+    :members:
+
+RawReactionClearEmojiEvent
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. attributetable:: RawReactionClearEmojiEvent
+
+.. autoclass:: RawReactionClearEmojiEvent()
+    :members:
+
+VoiceChannelEffectSendEvent
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. attributetable:: VoiceChannelEffectSendEvent
+
+.. autoclass:: VoiceChannelEffectSendEvent()
+    :members:
diff --git a/docs/api/monetization.rst b/docs/api/monetization.rst
new file mode 100644
index 00000000..6378f01a
--- /dev/null
+++ b/docs/api/monetization.rst
@@ -0,0 +1,45 @@
+.. currentmodule:: discord
+
+Monetization Related
+---------------------
+
+.. seealso:: More about app monetization
+
+    - :dev-sup-art:`What Are Premium Apps? <17709085688727-What-Are-Premium-Apps->`
+    - :sup-art:`Premium App Subscriptions FAQ <9359445233303-Premium-App-Subscriptions-FAQ>`
+    - :ddocs:`Discord API Docs <monetization/overview>`
+    - :attr:`BaseInteraction.entitlements`
+    - :meth:`API-Events <discord.on_entitlement_create>`
+
+
+SKU (Stock Keeping Unit)
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. attributetable:: SKU
+
+.. autoclass:: SKU()
+    :members:
+
+SKUFlags
+~~~~~~~~
+
+.. attributetable:: SKUFlags
+
+.. autoclass:: SKUFlags()
+    :members:
+
+Entitlement
+~~~~~~~~~~~~
+
+.. attributetable:: Entitlement
+
+.. autoclass:: Entitlement()
+    :members:
+
+Subscription
+~~~~~~~~~~~~
+
+.. attributetable:: Subscription
+
+.. autoclass:: Subscription()
+    :members:
diff --git a/docs/api/utils.rst b/docs/api/utils.rst
new file mode 100644
index 00000000..de9ddf06
--- /dev/null
+++ b/docs/api/utils.rst
@@ -0,0 +1,32 @@
+.. currentmodule:: discord
+
+.. _discord-api-utils:
+
+Utility Functions
+-----------------
+
+.. autofunction:: discord.utils.find
+
+.. autofunction:: discord.utils.get
+
+.. autofunction:: discord.utils.snowflake_time
+
+.. autofunction:: discord.utils.oauth_url
+
+.. autofunction:: discord.utils.remove_markdown
+
+.. autofunction:: discord.utils.escape_markdown
+
+.. autofunction:: discord.utils.escape_mentions
+
+.. autofunction:: discord.utils.resolve_invite
+
+.. autofunction:: discord.utils.resolve_template
+
+.. autofunction:: discord.utils.sleep_until
+
+.. autofunction:: discord.utils.styled_timestamp
+
+.. data:: discord.utils.SupportsStr
+
+    The ``SupportsStr`` object is a special annotation that means that this can any object that is already a :class:`str` or has a :meth:`~object.__str__`  method.
diff --git a/docs/api/voice.rst b/docs/api/voice.rst
new file mode 100644
index 00000000..4a758dcb
--- /dev/null
+++ b/docs/api/voice.rst
@@ -0,0 +1,79 @@
+.. currentmodule:: discord
+
+Voice Related
+---------------
+
+VoiceClient
+~~~~~~~~~~~~
+
+.. attributetable:: VoiceClient
+
+.. autoclass:: VoiceClient()
+    :members:
+
+VoiceProtocol
+~~~~~~~~~~~~~~~
+
+.. attributetable:: VoiceProtocol
+
+.. autoclass:: VoiceProtocol
+    :members:
+
+AudioSource
+~~~~~~~~~~~~
+
+.. attributetable:: AudioSource
+
+.. autoclass:: AudioSource
+    :members:
+
+PCMAudio
+~~~~~~~~~
+
+.. attributetable:: PCMAudio
+
+.. autoclass:: PCMAudio
+    :members:
+
+FFmpegAudio
+~~~~~~~~~~~~
+
+.. attributetable:: FFmpegAudio
+
+.. autoclass:: FFmpegAudio
+    :members:
+
+FFmpegPCMAudio
+~~~~~~~~~~~~~~~
+
+.. attributetable:: FFmpegPCMAudio
+
+.. autoclass:: FFmpegPCMAudio
+    :members:
+
+FFmpegOpusAudio
+~~~~~~~~~~~~~~~~
+
+.. attributetable:: FFmpegOpusAudio
+
+.. autoclass:: FFmpegOpusAudio
+    :members:
+
+PCMVolumeTransformer
+~~~~~~~~~~~~~~~~~~~~~
+
+.. attributetable:: PCMVolumeTransformer
+
+.. autoclass:: PCMVolumeTransformer
+    :members:
+
+Opus Library
+~~~~~~~~~~~~~
+
+.. autofunction:: discord.opus.load_opus
+
+.. autofunction:: discord.opus.is_loaded
+
+
+.. toctree::
+    :maxdepth: 2
\ No newline at end of file
diff --git a/docs/api/webhooks.rst b/docs/api/webhooks.rst
new file mode 100644
index 00000000..51541598
--- /dev/null
+++ b/docs/api/webhooks.rst
@@ -0,0 +1,37 @@
+.. currentmodule:: discord
+
+Webhook Support
+------------------
+
+discord.py-message-components offers support for creating, editing, and executing webhooks through the :class:`Webhook` class.
+
+Webhook
+~~~~~~~~~
+
+.. attributetable:: Webhook
+
+.. autoclass:: Webhook
+    :members:
+
+WebhookMessage
+~~~~~~~~~~~~~~~~
+
+.. attributetable:: WebhookMessage
+
+.. autoclass:: WebhookMessage
+    :members:
+
+Adapters
+~~~~~~~~~
+
+Adapters allow you to change how the request should be handled. They all build on a single
+interface, :meth:`WebhookAdapter.request`.
+
+.. autoclass:: WebhookAdapter
+    :members:
+
+.. autoclass:: AsyncWebhookAdapter
+    :members:
+
+.. autoclass:: RequestsWebhookAdapter
+    :members:
diff --git a/docs/components.rst b/docs/components.rst
deleted file mode 100644
index 794f1aab..00000000
--- a/docs/components.rst
+++ /dev/null
@@ -1,325 +0,0 @@
-.. discord.py-message-components documentation master file, created by
-   sphinx-quickstart on Sat Jun 26 14:55:47 2021.
-   You can adapt this file completely to your liking, but it should at least
-   contain the root `toctree` directive.
-
-Components
-==========
-
-.. class:: ButtonStyle
-
-   This is located in discord.enums but i place it here.
-
-   The possible styles for a :class:`Button`
-
-   +------------------------+-------+----------------+--------------------------------+
-   | NAME                   | VALUE | ALIASES        | EXAMPLE                        |
-   +========================+=======+================+================================+
-   | .. attribute:: blurple |   1   |                | .. image:: imgs/blurple.png    |
-   |                        |       | ``Primary``    |    :alt: Blurple Button Picture|
-   |                        |       |                |                                |
-   +------------------------+-------+----------------+--------------------------------+
-   | .. attribute:: grey    |   2   | ``gray``,      | .. image:: imgs/grey.png       |
-   |                        |       | ``Secondary``  |    :alt: Grey Button Picture   |
-   |                        |       |                |                                |
-   +------------------------+-------+----------------+--------------------------------+
-   | .. attribute:: green   |   3   | ``Success``    | .. image:: imgs/green.png      |
-   |                        |       |                |    :alt: Green Button Picture  |
-   |                        |       |                |                                |
-   +------------------------+-------+----------------+--------------------------------+
-   | .. attribute:: red     |   4   | ``Danger``     | .. image:: imgs/red.png        |
-   |                        |       |                |    :alt: Red Button Picture    |
-   |                        |       |                |                                |
-   +------------------------+-------+----------------+--------------------------------+
-   | .. attribute:: url     |   5   | ``link``,      | .. image:: imgs/url.png        |
-   |                        |       | ``grey_url``,  |    :alt: URL Button Picture    |
-   |                        |       | ``Link_Button``|                                |
-   +------------------------+-------+----------------+--------------------------------+
-
-___________________________________________
-
-
-.. class:: ActionRow(*components)
-
-   Represents an :class:`ActionRow`-Part for the components of a :class:`discord.Message`.
-
-   .. note::
-      For general information about ActionRow's visit the `Discord-APIMethodes Documentation <https://discord.com/developers/docs/interactions/message-components#actionrow>`_.
-
-   .. note::
-       You could use a :class:`list` instead of this but you don't have the functions and parameters of this class then.
-
-   .. _actionrow-parameters:
-
-   :param components: Union[:class:`Button`, :class:`SelectMenu`]
-      The components the :class:`ActionRow` should have. It could contain at least 5 :class:`Button` or 1 :class:`SelectMenu`.
-
-   .. classmethod:: from_dict(data)
-
-      Converts a dict (e.g. created with :meth:`to_dict`) into an ActionRow, provided it is in the format Discord expects.
-
-      You can read about this format in the `official Discord documentation <https://discord.com/developers/docs/interactions/message-components#action-rows>`_.
-
-      :param dict: :class:`dict`
-         The dictionary to convert into an ActionRow.
-
-      :return: :class:`ActionRow`
-
-   .. method:: to_dict()
-
-      Convert this :class:`ActionRow` in to a dict.
-
-      :return: :class:`dict`
-
-   .. method:: disable_all_buttons()
-
-      Disable all object's of type :class:`Button` in this :class:`ActionRow`.
-        
-      :return: :class:`ActionRow`
-
-   .. method:: disable_all_buttons_if(check, *args)
-
-      Disable all :class:`Button` (s) in this :class:`ActionRow` if the passed :attr:`check` returns ``True``.
-
-      :param check: Union[Bool, Callable]
-         Could be a :class:`bool` or usually any :obj:`Callable` that returns a :class:`bool`
-            
-      :param \*args: Any
-         Arguments that should passed in to the :attr:`check` if it is a :obj:`Callable`.
-
-      :return: :class:`ActionRow`
-
-
-   .. method:: disable_all_select_menus_if(check, *args)
-
-      Disables all :class:`SelectMenu` (s) in this :class:`ActionRow` if the passed :attr:`check` returns ``True``.
-
-      :param check: Union[:class:`bool`, Callable]
-         Could be a :class:`bool` or usually any :obj:`Callable` that returns a :class:`bool`.
-
-      :param \*args: Any
-         Arguments that should passed in to the :attr:`check` if it is a :obj:`Callable`.
-
-      :return: :class:`ActionRow`
-
-   .. method:: add_component(component)
-
-      Adds a component to the :class:`ActionRow`.
-
-      This function returns the class instance to allow for fluent-style
-      chaining.
-
-
-      :param component: Union[:class:`Button`, :class:`SelectMenu`, :class:`dict`]
-         The component to add to the :class:`ActionRow`.
-
-      :return: :class:`ActionRow`
-
-   .. method:: add_components(*components)
-
-      Add multiple components to the :class:`ActionRow`.
-
-      This function returns the class instance to allow for fluent-style
-      chaining.
-
-
-      :param \*components: \*Union[:class:`Button`, :class:`SelectMenu`, :class:`dict`]
-         The components to add to the :class:`ActionRow`.
-
-      :return: :class:`ActionRow`
-
-   .. method:: insert_component_at(index, component)
-
-      Inserts a component before a specified index to the :class:`ActionRow`.
-
-      :param index: :class:`int`
-         The index of where to insert the component.
-      :param component: Union[:class:`Button`, :class:`SelectMenu`, :class:`dict`]
-         The component to insert at the specified index of the :class:`ActionRow`.
-
-      :return: :class:`ActionRow`
-
-   .. method:: set_component_at(index, component)
-
-      Modifies a component to the ActionRow object.
-
-      The index **must** point to a valid pre-existing component.
-
-      This function returns the class instance to allow for fluent-style
-      chaining.
-
-      :param index: :class:`int`
-         The index of the component to modify.
-      :param component: Union[:class:`Button`, :class:`SelectMenu`, :class:`dict`]
-         The component to replace the old one with.
-
-      :raise IndexError: An invalid index was provided.
-
-      :return: :class:`ActionRow`
-
-________________________________________
-
-.. class:: Button(label, custom_id, style, emoji, url, disabled)
-
-   Represents a ``Discord-Button``
-
-   .. note::
-       For general information about Discord-Button's visit the `Documentation <https://discord.com/developers/docs/interactions/message-components#buttons>`_ of the discord-api.
-
-   .. _button-parameters:
-
-   :param label: :class:`str`
-      The Text displayed in discord on the Button. Maximal length is 80 Chars.
-   :param custom_id: Union[:class:`str`, :class:`int`]
-        The custom_id discord send us when a User press the Button. The max. length of this is 100.
-   :param style: :class:`ButtonStyle`
-        The Style the Button should have.
-
-        .. note::
-            To get more infos about the styles visit
-            `the Discord-APIMethodes Documentation <https://discord.com/developers/docs/interactions/message-components#buttons-button-styles>`_.
-
-   :param emoji: Optional[Union[:class:`discord.PartialEmoji`, :class:`discord.Emoji`, :class:`str`]]
-        The Emoji that will be displayed on the left side of the Button.
-   :param url: Optional[:class:`str`]
-      The URL the Button links too.
-
-      .. note::
-         If you set this, the :attr:`style` will automatic set to :class:`ButtonStyle.url`
-
-      .. warning::
-         You can't pass a :attr:`custom_id` and a :attr:`url` because discord don't send anything when clicking on an ``URL-Button`` so it don't accept both; :attr:`url`/:class:`ButtonStyle.url` and :attr:`custom_id`!
-
-   :param disabled: :class:`bool`
-      Whether the Button is disabled; default False.
-
-   .. _button-methods:
-
-   .. method:: disable_if(check, *args)
-    
-      Disable the :class:`Button` if the passed :attr:`check` returns ``True``.
-
-      :param check: typing.Union[:class:`bool`, Callable]
-         Could be a :class:`bool` or usually any :class:`Callable` that returns a :class:`bool`.
-      :param \*args: Any
-         Arguments that should passed in to the :attr:`check` if it is a :class:`Callable`
-
-      :return: :class:`Button`
-
-   .. method:: set_style_if(check, style, *args)
-
-      Sets the style of the :class:`Button` to the specified one if the specified check returns True.
-
-      :param check: Union[:class:`bool`, :obj:`typing.Callable`]
-            The check could be an :class:`bool` or usually any :obj:`Callable` that returns an :class:`bool`
-      :param style: discord.ButtonStyle
-            The style the :class:`Button` should have when the :attr:`check` returns True
-      :param \*args: Any
-            Arguments that should passed in to the :attr:`check` if it is an :obj:`Callable`.
-
-      :return: :class:`Button`
-
-________________________________________
-
-.. class:: SelectOption(label, value, description, emoji, default)
-
-   Represents a option for a :class:`SelectMenu`.
-
-   .. _select-option-parameters:
-
-   :param label: :class:`str`
-      The user-facing name of the option, max 25 characters.
-    
-   :param value: :class:`str`
-      The dev-define value of the option, max 100 characters.
-
-   :param description: Optional[:class:`str`]
-      An additional description of the option, max 50 characters.
-    
-   :param emoji: Optional[Union[:class:`PartialEmoji`, :class:`Emoji`, :class:`str`]]
-      An Emoji that will be displayed on the left side of the option.
-    
-   :param default: Optional[:class:`bool`]
-       Whether this option is selected by default.
-
-________________________________________
-
-.. class:: SelectMenu(custom_id, options, placeholder, min_values, max_values, disabled)
-
-
-   Represents a ``Discord-Select-Menu``
-
-   .. note::
-       For general information about Select-Menus visit the `Discord-APIMethodes-Documentation <https://discord.com/developers/docs/interactions/message-components#select-menus>`_.
-
-   .. _select-menu-parameters:
-
-   :param custom_id: Union[:class:`str`, :class:`int`]
-      A developer-defined identifier for the :class:`SelectMenu`, max. 100 characters.
-
-   :param options: List[:class:`SelectOption`]
-      A :class:`list` of choices(:class:`SelectOption`) the :class:`SelectMenu` should have, max. 25.
-
-   :param placeholder: Optional[:class:`str`]
-        Custom placeholder text if nothing is selected, max. 100 characters.
-
-   :param min_values: Optional[::class:`int`]
-        The minimum number of items that must be chosen; default 1, min. 0, max. 25.
-
-   :param max_values: Optional[:class:`int`]
-        The maximum number of items that can be chosen; default 1, max. 25.
-
-   :param disabled: Optional[:class:`bool`]
-        Whether the SelectMenu is disabled or not. ``False`` by default.
-
-   :attr:`all_option_values`: Generator[Union[:class:`str`, :class:`int`]]
-      Returns a generator with all `values` of the `options` of the :class:`SelectMenu`.
-
-      If the value is a number it is returned as an integer, otherwise a string
-
-      .. note::
-         This is equal to
-
-         .. code-block:: python
-
-           for option in select.options:
-               if option.value.isdigit():
-                   yield int(option.value)
-               else:
-                   yield option.value
-
-      :yield: Union[:class:`str`, :class:`int`]
-
-   .. method:: disable_if(check, *args)
-
-      Disables the :class:`SelectMenu` if the passed :attr:`check` returns ``True``.
-
-      :param check: Union[:class:`bool`, Callable]
-         The check could be an :class:`bool` or usually any :obj:`Callable` that returns an :class:`bool`.
-      :param \*args: Any
-         Arguments that should passed in to the :attr:`check` if it is an :obj:`Callable`.
-
-      :return: :class:`SelectMenu`
-
-   .. method:: set_custom_id(custom_id)
-
-      Set the custom_id of the :class:`SelectMenu`
-
-      :param custom_id: Union[:class:`str`, :class:`int`]
-         The custom_id to replace the old one with
-
-      :return: :class:`SelectMenu`
-
-________________________________________
-
-.. toctree::   
-   :maxdepth: 3
-   :caption: Contents:
-
-
-Indices and tables
-~~~~~~~~~~~~~~~~~~
-
-* :ref:`genindex`
-* :ref:`modindex`
-* :ref:`search`
diff --git a/docs/conf.py b/docs/conf.py
index 74d913cf..6c82fb2f 100644
--- a/docs/conf.py
+++ b/docs/conf.py
@@ -1,62 +1,221 @@
-# Configuration file for the Sphinx documentation builder.
-#
-# This file only contains a selection of the most common options. For a full
-# list see the documentation:
-# https://www.sphinx-doc.org/en/master/usage/configuration.html
-
-# -- Path setup --------------------------------------------------------------
-
-# If extensions (or modules to document with autodoc) are in another directory,
-# add these directories to sys.path here. If the directory is relative to the
-# documentation root, use os.path.abspath to make it absolute, like shown here.
-#
-# import os
-# import sys
-# sys.path.insert(0, os.path.abspath('.'))
-
-
-# -- Project information -----------------------------------------------------
-
-import sys
-sys.setrecursionlimit(1500)
-import sphinx_rtd_theme
-
-project = 'discord.py-message-components'
-copyright = '2021, Mathieu Corsham aka. mccoder.py'
-author = 'Mathieu Corsham aka. mccoder.py'
-
-# The full version, including alpha/beta/rc tags
-release = '1.7.5.4'
-
-
-# -- General configuration ---------------------------------------------------
-
-# Add any Sphinx extension module names here, as strings. They can be
-# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
-# ones.
-extensions = [
-        'sphinx_rtd_theme',
-        'sphinxcontrib.contentui',
-
-]
-
-# Add any paths that contain templates here, relative to this directory.
-templates_path = ['_templates']
-
-# List of patterns, relative to source directory, that match files and
-# directories to ignore when looking for source files.
-# This pattern also affects html_static_path and html_extra_path.
-exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store']
-
-
-# -- Options for HTML output -------------------------------------------------
-
-# The theme to use for HTML and HTML Help pages.  See the documentation for
-# a list of builtin themes.
-#
-html_theme = 'sphinx_rtd_theme'
-
-# Add any paths that contain custom static files (such as style sheets) here,
-# relative to this directory. They are copied after the builtin static files,
-# so a file named "default.css" will overwrite the builtin "default.css".
-html_static_path = ['_static']
\ No newline at end of file
+# Configuration file for the Sphinx documentation builder.
+#
+# This file only contains a selection of the most common options. For a full
+# list see the documentation:
+# https://www.sphinx-doc.org/en/master/usage/configuration.html
+
+# -- Path setup --------------------------------------------------------------
+
+# If extensions (or modules to document with autodoc) are in another directory,
+# add these directories to sys.path here. If the directory is relative to the
+# documentation root, use os.path.abspath to make it absolute, like shown here.
+#
+from __future__ import annotations
+
+import os
+import re
+import sys
+
+from typing import TYPE_CHECKING
+
+if TYPE_CHECKING:
+    from sphinx.application import Sphinx as App
+
+sys.setrecursionlimit(15000)
+
+sys.path.insert(0, os.path.abspath('..'))
+sys.path.append(os.path.abspath('extensions'))
+
+# -- Project information -----------------------------------------------------
+
+
+project = 'discord.py-message-components'
+copyright = '2023, Mathieu C. aka. mccoder.py'
+author = 'Mathieu C. aka. mccoder.py'
+
+version = ''
+with open('../discord/__init__.py') as f:
+    version += re.search(r'^__version__\s*=\s*[\'"]([^\'"]*)[\'"]', f.read(), re.MULTILINE).group(1)
+
+# The full version, including alpha/beta/rc tags.
+release = version
+
+# This assumes a tag is available for final releases
+branch = 'developer' if version.endswith('a') else 'v' + version
+
+
+# -- General configuration ---------------------------------------------------
+
+# Add any Sphinx extension module names here, as strings. They can be
+# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
+# ones.
+
+extensions = [
+    'builder',
+    'sphinx.ext.autodoc',
+    'sphinx.ext.extlinks',
+    'sphinx.ext.intersphinx',
+    'sphinxcontrib.contentui',
+    'sphinx.ext.napoleon',
+    'sphinxext.opengraph',
+    'sphinx_inline_tabs',
+    'sphinxcontrib_trio',
+    'details',
+    'exception_hierarchy',
+    'attributetable',
+    'experimental_feature',
+    'keyboard_buttons',
+    'operations',
+    'resourcelinks',
+]
+
+# The language for content autogenerated by Sphinx. Refer to documentation
+# for a list of supported languages.
+#
+# This is also used if you do content translation via gettext catalogs.
+# Usually you set "language" from the command line for these cases.
+language = 'en'
+
+autodoc_member_order = 'bysource'
+autodoc_default_flags = ['members']
+autodoc_default_options = {
+    'members': True,
+    'show-inheritance': True,
+}
+autodoc_typehints = 'none'
+autodoc_typehints_format = 'short'
+# autodoc_preserve_defaults = True
+autoclass_content = 'both'  # document class docstring and __init__ docstring
+
+
+# Links used for cross-referencing stuff in other documentation
+intersphinx_mapping = {
+    'py': ('https://docs.python.org/3', None),
+    'aio': ('https://docs.aiohttp.org/en/stable/', None),
+    'req': ('https://docs.python-requests.org/en/latest/', 'requests.inv')
+}
+
+html_context = {
+    'discord_invite': 'https://discord.gg/sb69muSqsg',
+    'discord_extensions': [
+        ('discord.ext.commands', 'ext/commands'),
+        ('discord.ext.tasks', 'ext/tasks'),
+        ('discord.oauth2', 'oauth2')
+    ],
+    'github_url': 'https://github.com/mccoderpy/discord.py-message-components'
+}
+
+resource_links = {
+    'discord': 'https://discord.gg/sb69muSqsg',
+    'issues': f'{html_context["github_url"]}/issues',
+    'discussions': f'{html_context["github_url"]}/discussions',
+    'examples': f'{html_context["github_url"]}/tree/%s/examples' % branch,
+}
+
+ogp_site_url = 'https://docs.discord4py.dev/'
+ogp_image = f'https://docs.discord4py.dev/en/{branch}/_images/discord4py-logo.png'
+ogp_site_name = 'docs.discord4py.dev'
+
+ogp_custom_meta_tags = [
+    '<meta name="theme-color" content="#5865F2">'
+]
+ogp_enable_meta_description = True
+
+show_authors = True
+html_last_updated_fmt = '%b %d %Y'
+html_permalinks_icon = '<span class="fa fa-link" aria-hidden="true"></span>'
+# Theme options are theme-specific and customize the look and feel of a theme
+# further.  For a list of options available for each theme, see the
+# documentation.
+# html_theme_options = {
+# }
+
+# Add any paths that contain custom themes here, relative to this directory.
+# html_theme_path = []
+
+# The name for this set of Sphinx documents.  If None, it defaults to
+# "<project> v<release> documentation".
+# html_title = None
+
+# A shorter title for the navigation bar.  Default is the same as html_title.
+# html_short_title = None
+
+# The name of an image file (relative to this directory) to place at the top
+# of the sidebar.
+html_logo = '../images/Banner_Konturen.png'
+
+# The name of an image file (within the static path) to use as favicon of the
+# docs.  This file should be a Windows icon file (.ico) being 16x16 or 32x32
+# pixels large.
+html_favicon = './images/favicon.ico'
+
+extlinks = {
+    'issue': ('https://github.com/mccoderpy/discord.py-message-components/issues/%s', 'GH-%s'),
+    'old-issue': ('https://github.com/Rapptz/discord.py/issues/%s', 'GH-%s'),
+    'dis-gd': ('https://dis.gd/%s', 'GH-%s'),
+    'ddocs': ('https://discord.com/developers/docs/%s', 'GH-%s'),
+    'sup-art': ('https://support.discord.com/hc/en-us/articles/%s', 'GH-%s'),
+    'dev-sup-art': ('https://support-dev.discord.com/hc/en-us/articles/%s', 'GH-%s'),
+}
+
+rst_prolog = """
+:tocdepth: 3
+
+.. |coro| replace:: This function is a |coroutine_link|_.
+.. |maybecoro| replace:: This function *could be a* |coroutine_link|_.
+.. |coroutine_link| replace:: *coroutine*
+.. _coroutine_link: https://docs.python.org/3/library/asyncio-task.html#coroutine
+.. |bugreport| replace:: |bugreport_link|_
+.. |bugreport_link| replace:: *bug report*
+.. _bugreport_link: https://discord4py.dev/bugreport
+.. |match_object| replace:: |match_object_link|_
+.. |match_object_link| replace:: Match
+.. _match_object_link: https://docs.python.org/3/library/re.html#match-objects
+.. |pattern_object| replace:: |pattern_object_link|_
+.. |pattern_object_link| replace:: Pattern
+.. _pattern_object_link: https://docs.python.org/3/library/re.html#regular-expression-objects
+"""
+
+# Add any paths that contain templates here, relative to this directory.
+templates_path = ['_templates']
+
+# List of patterns, relative to source directory, that match files and
+# directories to ignore when looking for source files.
+# This pattern also affects html_static_path and html_extra_path.
+exclude_patterns = ['_build']
+
+
+# -- Options for HTML output -------------------------------------------------
+
+# The theme to use for HTML and HTML Help pages.  See the documentation for
+# a list of builtin themes.
+#
+html_theme = 'basic'
+html_style = 'style.css'
+
+# The name of a javascript file (relative to the configuration directory) that
+# implements a search results scorer. If empty, the default will be used.
+html_search_scorer = '_static/scorer.js'
+
+# The name of the Pygments (syntax highlighting) style to use.
+pygments_style = 'friendly'
+
+html_js_files = [
+    'custom.js',
+    'settings.js',
+    'copy.js',
+    'sidebar.js',
+]
+
+# The master toctree document.
+master_doc = 'index'
+
+# Add any paths that contain custom static files (such as style sheets) here,
+# relative to this directory. They are copied after the builtin static files,
+# so a file named "default.css" will overwrite the builtin "default.css".
+html_static_path = ['_static', 'images']
+
+
+def setup(app: App):
+    app.setup_extension("sphinxext.opengraph")
+    app.add_css_file('style.css')
diff --git a/docs/discord.rst b/docs/discord.rst
new file mode 100644
index 00000000..27412d51
--- /dev/null
+++ b/docs/discord.rst
@@ -0,0 +1,94 @@
+.. _discord-intro:
+
+Creating a Bot Account
+========================
+
+In order to work with the library and the Discord API in general, we must first create a Discord Bot account.
+
+Creating a Bot account is a pretty straightforward process.
+
+1. Make sure you're logged on to the `Discord website <https://discord.com>`_.
+2. Navigate to the `application page <https://discord.com/developers/applications>`_
+3. Click on the `New Application <https://discord.com/developers/applications?new_application=true>`_ button.
+
+    .. image:: /images/discord_create_app_button.png
+        :alt: The new application button.
+
+4. Give the application a name and click "Create".
+
+    .. image:: /images/discord_create_app_form.png
+        :alt: The new application form filled in.
+
+5. Create a Bot User by navigating to the "Bot" tab and clicking "Add Bot".
+
+    - Click "Yes, do it!" to continue.
+
+    .. image:: /images/discord_create_bot_user.png
+        :alt: The Add Bot button.
+6. Make sure that **Public Bot** is ticked if you want others to invite your bot.
+
+    - You should also make sure that **Require OAuth2 Code Grant** is unchecked unless you
+      are developing a service that needs it. If you're unsure, then **leave it unchecked**.
+
+    .. image:: /images/discord_bot_user_options.png
+        :alt: How the Bot User options should look like for most people.
+
+7. Copy the token using the "Copy" button.
+
+    - **This is not the Client Secret at the General Information page.**
+
+    .. warning::
+
+        It should be worth noting that this token is essentially your bot's
+        password. You should **never** share this to someone else. In doing so,
+        someone can log in to your bot and do malicious things, such as leaving
+        servers, ban all members inside a server, or pinging everyone maliciously.
+
+        The possibilities are endless, so **do not share this token.**
+
+        If you accidentally leaked your token, click the "Regenerate" button as soon
+        as possible. This revokes your old token and re-generates a new one.
+        Now you need to use the new token to login.
+
+And that's it. You now have a bot account and you can login with that token.
+
+.. _discord_invite_bot:
+
+Inviting Your Bot
+-------------------
+
+So you've made a Bot User but it's not actually in any server.
+
+If you want to invite your bot you must create an invite URL for it.
+
+1. Make sure you're logged on to the `Discord website <https://discord.com>`_.
+2. Navigate to the `application page <https://discord.com/developers/applications>`_
+3. Click on your bot's page.
+4. Go to the "OAuth2" tab.
+
+    .. image:: /images/discord_oauth2.png
+        :alt: How the OAuth2 page should look like.
+
+5. Tick the "bot" checkbox under "scopes".
+
+    .. image:: /images/discord_oauth2_scope.png
+        :alt: The scopes checkbox with "bot" ticked.
+
+6. Tick the permissions required for your bot to function under "Bot Permissions".
+
+    - Please be aware of the consequences of requiring your bot to have the "Administrator" permission.
+
+    - Bot owners must have 2FA enabled for certain actions and permissions when added in servers that have Server-Wide 2FA enabled. Check the `2FA support page <https://support.discord.com/hc/en-us/articles/219576828-Setting-up-Two-Factor-Authentication>`_ for more information.
+
+    .. image:: /images/discord_oauth2_perms.png
+        :alt: The permission checkboxes with some permissions checked.
+
+7. Now the resulting URL can be used to add your bot to a server. Copy and paste the URL into your browser, choose a server to invite the bot to, and click "Authorize".
+
+
+.. note::
+
+    The person adding the bot needs "Manage Server" permissions to do so.
+
+If you want to generate this URL dynamically at run-time inside your bot and using the
+:class:`discord.Permissions` interface, you can use :func:`discord.utils.oauth_url`.
diff --git a/docs/ext/commands/api.rst b/docs/ext/commands/api.rst
new file mode 100644
index 00000000..b26b09da
--- /dev/null
+++ b/docs/ext/commands/api.rst
@@ -0,0 +1,619 @@
+.. currentmodule:: discord
+
+API Reference
+===============
+
+The following section outlines the API of discord.py's command extension module.
+
+.. _ext_commands_api_bot:
+
+Bots
+------
+
+Bot
+~~~~
+
+.. attributetable:: discord.ext.commands.Bot
+
+.. autoclass:: discord.ext.commands.Bot
+    :members:
+    :inherited-members:
+    :exclude-members: after_invoke, before_invoke, check, check_once, command, event, group, listen, once
+
+    .. automethod:: Bot.after_invoke()
+        :decorator:
+
+    .. automethod:: Bot.before_invoke()
+        :decorator:
+
+    .. automethod:: Bot.check()
+        :decorator:
+
+    .. automethod:: Bot.check_once()
+        :decorator:
+
+    .. automethod:: Bot.command(*args, **kwargs)
+        :decorator:
+
+    .. automethod:: Bot.event()
+        :decorator:
+
+    .. automethod:: Bot.group(*args, **kwargs)
+        :decorator:
+
+    .. automethod:: Bot.listen(name=None)
+        :decorator:
+
+    .. automethod:: Bot.once(name=None, check=None)
+        :decorator:
+
+    .. automethod:: Bot.fetch_guilds
+        :async-for:
+
+    .. automethod:: Bot.slash_command
+        :decorator:
+
+    .. automethod:: Bot.message_command
+        :decorator:
+
+    .. automethod:: Bot.user_command
+        :decorator:
+
+    .. automethod:: Bot.on_click
+        :decorator:
+
+    .. automethod:: Bot.on_select
+        :decorator:
+
+    .. automethod:: Bot.on_submit
+        :decorator:
+
+AutoShardedBot
+~~~~~~~~~~~~~~~~
+
+.. attributetable:: discord.ext.commands.AutoShardedBot
+
+.. autoclass:: discord.ext.commands.AutoShardedBot
+    :members:
+
+Prefix Helpers
+----------------
+
+.. autofunction:: discord.ext.commands.when_mentioned
+
+.. autofunction:: discord.ext.commands.when_mentioned_or
+
+.. _ext_commands_api_events:
+
+Event Reference
+-----------------
+
+These events function similar to :ref:`the regular events <discord-api-events>`, except they
+are custom to the command extension module.
+
+.. function:: on_command_error(ctx, error)
+
+    An error handler that is called when an error is raised
+    inside a command either through user input error, check
+    failure, or an error in your own code.
+
+    A default one is provided (:meth:`.Bot.on_command_error`).
+
+    :param ctx: The invocation context.
+    :type ctx: :class:`.Context`
+    :param error: The error that was raised.
+    :type error: :class:`.CommandError` derived
+
+.. function:: on_command(ctx)
+
+    An event that is called when a command is found and is about to be invoked.
+
+    This event is called regardless of whether the command itself succeeds via
+    error or completes.
+
+    :param ctx: The invocation context.
+    :type ctx: :class:`.Context`
+
+.. function:: on_command_completion(ctx)
+
+    An event that is called when a command has completed its invocation.
+
+    This event is called only if the command succeeded, i.e. all checks have
+    passed and the user input it correctly.
+
+    :param ctx: The invocation context.
+    :type ctx: :class:`.Context`
+
+.. _ext_commands_api_command:
+
+Commands
+----------
+
+Decorators
+~~~~~~~~~~~~
+
+.. autofunction:: discord.ext.commands.command
+
+.. autofunction:: discord.ext.commands.group
+
+Command
+~~~~~~~~~
+
+.. attributetable:: discord.ext.commands.Command
+
+.. autoclass:: discord.ext.commands.Command
+    :members:
+    :special-members: __call__
+
+Group
+~~~~~~
+
+.. attributetable:: discord.ext.commands.Group
+
+.. autoclass:: discord.ext.commands.Group
+    :members:
+    :inherited-members:
+
+GroupMixin
+~~~~~~~~~~~
+
+.. attributetable:: discord.ext.commands.GroupMixin
+
+.. autoclass:: discord.ext.commands.GroupMixin
+    :members:
+
+.. _ext_commands_api_cogs:
+
+Cogs
+------
+
+Cog
+~~~~
+
+.. attributetable:: discord.ext.commands.Cog
+
+.. autoclass:: discord.ext.commands.Cog
+    :members:
+    :exclude-members: listener, slash_command, message_command, user_command, on_click, on_select, on_submit
+
+    .. automethod:: Cog.listener
+        :decorator:
+
+    .. automethod:: Cog.slash_command
+        :decorator:
+
+    .. automethod:: Cog.message_command
+        :decorator:
+
+    .. automethod:: Cog.user_command
+        :decorator:
+
+    .. automethod:: Cog.on_click
+        :decorator:
+
+    .. automethod:: Cog.on_select
+        :decorator:
+
+    .. automethod:: Cog.on_submit
+        :decorator:
+
+CogMeta
+~~~~~~~~
+
+.. attributetable:: discord.ext.commands.CogMeta
+
+.. autoclass:: discord.ext.commands.CogMeta
+    :members:
+
+.. _ext_commands_help_command:
+
+Help Commands
+---------------
+
+HelpCommand
+~~~~~~~~~~~~
+
+.. attributetable:: discord.ext.commands.HelpCommand
+
+.. autoclass:: discord.ext.commands.HelpCommand
+    :members:
+
+DefaultHelpCommand
+~~~~~~~~~~~~~~~~~~~
+
+.. attributetable:: discord.ext.commands.DefaultHelpCommand
+
+.. autoclass:: discord.ext.commands.DefaultHelpCommand
+    :members:
+    :exclude-members: send_bot_help, send_cog_help, send_group_help, send_command_help, prepare_help_command
+
+MinimalHelpCommand
+~~~~~~~~~~~~~~~~~~~
+
+.. attributetable:: discord.ext.commands.MinimalHelpCommand
+
+.. autoclass:: discord.ext.commands.MinimalHelpCommand
+    :members:
+    :exclude-members: send_bot_help, send_cog_help, send_group_help, send_command_help, prepare_help_command
+
+Paginator
+~~~~~~~~~~
+
+.. attributetable:: discord.ext.commands.Paginator
+
+.. autoclass:: discord.ext.commands.Paginator
+    :members:
+
+Enums
+------
+
+.. class:: BucketType
+    :module: discord.ext.commands
+
+    Specifies a type of bucket for, e.g. a cooldown.
+
+    .. attribute:: default
+
+        The default bucket operates on a global basis.
+    .. attribute:: user
+
+        The user bucket operates on a per-user basis.
+    .. attribute:: guild
+
+        The guild bucket operates on a per-guild basis.
+    .. attribute:: channel
+
+        The channel bucket operates on a per-channel basis.
+    .. attribute:: member
+
+        The member bucket operates on a per-member basis.
+    .. attribute:: category
+
+        The category bucket operates on a per-category basis.
+    .. attribute:: role
+
+        The role bucket operates on a per-role basis.
+
+        .. versionadded:: 1.3
+
+
+.. _ext_commands_api_checks:
+
+Checks
+-------
+
+.. autofunction:: discord.ext.commands.check
+
+.. autofunction:: discord.ext.commands.check_any
+
+.. autofunction:: discord.ext.commands.has_role
+
+.. autofunction:: discord.ext.commands.has_permissions
+
+.. autofunction:: discord.ext.commands.has_guild_permissions
+
+.. autofunction:: discord.ext.commands.has_any_role
+
+.. autofunction:: discord.ext.commands.bot_has_role
+
+.. autofunction:: discord.ext.commands.bot_has_permissions
+
+.. autofunction:: discord.ext.commands.bot_has_guild_permissions
+
+.. autofunction:: discord.ext.commands.bot_has_any_role
+
+.. autofunction:: discord.ext.commands.cooldown
+
+.. autofunction:: discord.ext.commands.max_concurrency
+
+.. autofunction:: discord.ext.commands.before_invoke
+
+.. autofunction:: discord.ext.commands.after_invoke
+
+.. autofunction:: discord.ext.commands.guild_only
+
+.. autofunction:: discord.ext.commands.dm_only
+
+.. autofunction:: discord.ext.commands.is_owner
+
+.. autofunction:: discord.ext.commands.is_nsfw
+
+.. _ext_commands_api_context:
+
+Context
+--------
+
+.. attributetable:: discord.ext.commands.Context
+
+.. autoclass:: discord.ext.commands.Context
+    :members:
+    :inherited-members:
+    :exclude-members: history, typing
+
+    .. automethod:: discord.ext.commands.Context.history
+        :async-for:
+
+    .. automethod:: discord.ext.commands.Context.typing
+        :async-with:
+
+.. _ext_commands_api_converters:
+
+Converters
+------------
+
+.. autoclass:: discord.ext.commands.Converter
+    :members:
+
+.. autoclass:: discord.ext.commands.MemberConverter
+    :members:
+
+.. autoclass:: discord.ext.commands.UserConverter
+    :members:
+
+.. autoclass:: discord.ext.commands.MessageConverter
+    :members:
+
+.. autoclass:: discord.ext.commands.PartialMessageConverter
+    :members:
+
+.. autoclass:: discord.ext.commands.TextChannelConverter
+    :members:
+
+.. autoclass:: discord.ext.commands.VoiceChannelConverter
+    :members:
+
+.. autoclass:: discord.ext.commands.StoreChannelConverter
+    :members:
+
+.. autoclass:: discord.ext.commands.StageChannelConverter
+    :members:
+
+.. autoclass:: discord.ext.commands.CategoryChannelConverter
+    :members:
+
+.. autoclass:: discord.ext.commands.InviteConverter
+    :members:
+
+.. autoclass:: discord.ext.commands.GuildConverter
+    :members:
+
+.. autoclass:: discord.ext.commands.RoleConverter
+    :members:
+
+.. autoclass:: discord.ext.commands.GameConverter
+    :members:
+
+.. autoclass:: discord.ext.commands.ColourConverter
+    :members:
+
+.. autoclass:: discord.ext.commands.EmojiConverter
+    :members:
+
+.. autoclass:: discord.ext.commands.PartialEmojiConverter
+    :members:
+
+.. autoclass:: discord.ext.commands.clean_content
+    :members:
+
+.. data:: ext.commands.Greedy
+
+    A special converter that greedily consumes arguments until it can't.
+    As a consequence of this behaviour, most input errors are silently discarded,
+    since it is used as an indicator of when to stop parsing.
+
+    When a parser error is met the greedy converter stops converting, undoes the
+    internal string parsing routine, and continues parsing regularly.
+
+    For example, in the following code:
+
+    .. code-block:: python3
+
+        @commands.command()
+        async def test(ctx, numbers: Greedy[int], reason: str):
+            await ctx.send("numbers: {}, reason: {}".format(numbers, reason))
+
+    An invocation of ``[p]test 1 2 3 4 5 6 hello`` would pass ``numbers`` with
+    ``[1, 2, 3, 4, 5, 6]`` and ``reason`` with ``hello``\.
+
+    For more information, check :ref:`ext_commands_special_converters`.
+
+.. _ext_commands_api_errors:
+
+Exceptions
+-----------
+
+.. autoexception:: discord.ext.commands.CommandError
+    :members:
+
+.. autoexception:: discord.ext.commands.ConversionError
+    :members:
+
+.. autoexception:: discord.ext.commands.MissingRequiredArgument
+    :members:
+
+.. autoexception:: discord.ext.commands.ArgumentParsingError
+    :members:
+
+.. autoexception:: discord.ext.commands.UnexpectedQuoteError
+    :members:
+
+.. autoexception:: discord.ext.commands.InvalidEndOfQuotedStringError
+    :members:
+
+.. autoexception:: discord.ext.commands.ExpectedClosingQuoteError
+    :members:
+
+.. autoexception:: discord.ext.commands.BadArgument
+    :members:
+
+.. autoexception:: discord.ext.commands.BadUnionArgument
+    :members:
+
+.. autoexception:: discord.ext.commands.PrivateMessageOnly
+    :members:
+
+.. autoexception:: discord.ext.commands.NoPrivateMessage
+    :members:
+
+.. autoexception:: discord.ext.commands.CheckFailure
+    :members:
+
+.. autoexception:: discord.ext.commands.CheckAnyFailure
+    :members:
+
+.. autoexception:: discord.ext.commands.CommandNotFound
+    :members:
+
+.. autoexception:: discord.ext.commands.DisabledCommand
+    :members:
+
+.. autoexception:: discord.ext.commands.CommandInvokeError
+    :members:
+
+.. autoexception:: discord.ext.commands.TooManyArguments
+    :members:
+
+.. autoexception:: discord.ext.commands.UserInputError
+    :members:
+
+.. autoexception:: discord.ext.commands.CommandOnCooldown
+    :members:
+
+.. autoexception:: discord.ext.commands.MaxConcurrencyReached
+    :members:
+
+.. autoexception:: discord.ext.commands.NotOwner
+    :members:
+
+.. autoexception:: discord.ext.commands.MessageNotFound
+    :members:
+
+.. autoexception:: discord.ext.commands.MemberNotFound
+    :members:
+
+.. autoexception:: discord.ext.commands.GuildNotFound
+    :members:
+
+.. autoexception:: discord.ext.commands.UserNotFound
+    :members:
+
+.. autoexception:: discord.ext.commands.ChannelNotFound
+    :members:
+
+.. autoexception:: discord.ext.commands.ChannelNotReadable
+    :members:
+
+.. autoexception:: discord.ext.commands.BadColourArgument
+    :members:
+
+.. autoexception:: discord.ext.commands.RoleNotFound
+    :members:
+
+.. autoexception:: discord.ext.commands.BadInviteArgument
+    :members:
+
+.. autoexception:: discord.ext.commands.EmojiNotFound
+    :members:
+
+.. autoexception:: discord.ext.commands.PartialEmojiConversionFailure
+    :members:
+
+.. autoexception:: discord.ext.commands.BadBoolArgument
+    :members:
+
+.. autoexception:: discord.ext.commands.MissingPermissions
+    :members:
+
+.. autoexception:: discord.ext.commands.BotMissingPermissions
+    :members:
+
+.. autoexception:: discord.ext.commands.MissingRole
+    :members:
+
+.. autoexception:: discord.ext.commands.BotMissingRole
+    :members:
+
+.. autoexception:: discord.ext.commands.MissingAnyRole
+    :members:
+
+.. autoexception:: discord.ext.commands.BotMissingAnyRole
+    :members:
+
+.. autoexception:: discord.ext.commands.NSFWChannelRequired
+    :members:
+
+.. autoexception:: discord.ext.commands.ExtensionError
+    :members:
+
+.. autoexception:: discord.ext.commands.ExtensionAlreadyLoaded
+    :members:
+
+.. autoexception:: discord.ext.commands.ExtensionNotLoaded
+    :members:
+
+.. autoexception:: discord.ext.commands.NoEntryPointError
+    :members:
+
+.. autoexception:: discord.ext.commands.ExtensionFailed
+    :members:
+
+.. autoexception:: discord.ext.commands.ExtensionNotFound
+    :members:
+
+.. autoexception:: discord.ext.commands.CommandRegistrationError
+    :members:
+
+
+Exception Hierarchy
+~~~~~~~~~~~~~~~~~~~~~
+
+.. exception_hierarchy::
+
+    - :exc:`~.DiscordException`
+        - :exc:`~.commands.CommandError`
+            - :exc:`~.commands.ConversionError`
+            - :exc:`~.commands.UserInputError`
+                - :exc:`~.commands.MissingRequiredArgument`
+                - :exc:`~.commands.TooManyArguments`
+                - :exc:`~.commands.BadArgument`
+                    - :exc:`~.commands.MessageNotFound`
+                    - :exc:`~.commands.MemberNotFound`
+                    - :exc:`~.commands.UserNotFound`
+                    - :exc:`~.commands.ChannelNotFound`
+                    - :exc:`~.commands.ChannelNotReadable`
+                    - :exc:`~.commands.BadColourArgument`
+                    - :exc:`~.commands.RoleNotFound`
+                    - :exc:`~.commands.BadInviteArgument`
+                    - :exc:`~.commands.EmojiNotFound`
+                    - :exc:`~.commands.PartialEmojiConversionFailure`
+                    - :exc:`~.commands.BadBoolArgument`
+                - :exc:`~.commands.BadUnionArgument`
+                - :exc:`~.commands.ArgumentParsingError`
+                    - :exc:`~.commands.UnexpectedQuoteError`
+                    - :exc:`~.commands.InvalidEndOfQuotedStringError`
+                    - :exc:`~.commands.ExpectedClosingQuoteError`
+            - :exc:`~.commands.CommandNotFound`
+            - :exc:`~.commands.CheckFailure`
+                - :exc:`~.commands.CheckAnyFailure`
+                - :exc:`~.commands.PrivateMessageOnly`
+                - :exc:`~.commands.NoPrivateMessage`
+                - :exc:`~.commands.NotOwner`
+                - :exc:`~.commands.MissingPermissions`
+                - :exc:`~.commands.BotMissingPermissions`
+                - :exc:`~.commands.MissingRole`
+                - :exc:`~.commands.BotMissingRole`
+                - :exc:`~.commands.MissingAnyRole`
+                - :exc:`~.commands.BotMissingAnyRole`
+                - :exc:`~.commands.NSFWChannelRequired`
+            - :exc:`~.commands.DisabledCommand`
+            - :exc:`~.commands.CommandInvokeError`
+            - :exc:`~.commands.CommandOnCooldown`
+            - :exc:`~.commands.MaxConcurrencyReached`
+        - :exc:`~.commands.ExtensionError`
+            - :exc:`~.commands.ExtensionAlreadyLoaded`
+            - :exc:`~.commands.ExtensionNotLoaded`
+            - :exc:`~.commands.NoEntryPointError`
+            - :exc:`~.commands.ExtensionFailed`
+            - :exc:`~.commands.ExtensionNotFound`
+    - :exc:`~.ClientException`
+        - :exc:`~.commands.CommandRegistrationError`
diff --git a/docs/ext/commands/cogs.rst b/docs/ext/commands/cogs.rst
new file mode 100644
index 00000000..589a94c2
--- /dev/null
+++ b/docs/ext/commands/cogs.rst
@@ -0,0 +1,159 @@
+.. currentmodule:: discord
+
+.. _ext_commands_cogs:
+
+Cogs
+======
+
+There comes a point in your bot's development when you want to organize a collection of commands, listeners, and some state into one class. Cogs allow you to do just that.
+
+The gist:
+
+- Each cog is a Python class that subclasses :class:`.commands.Cog`.
+- Every command is marked with the :func:`.commands.command` decorator.
+- Every listener is marked with the :meth:`.commands.Cog.listener` decorator.
+- Cogs are then registered with the :meth:`.Bot.add_cog` call.
+- Cogs are subsequently removed with the :meth:`.Bot.remove_cog` call.
+
+It should be noted that cogs are typically used alongside with :ref:`ext_commands_extensions`.
+
+Quick Example
+---------------
+
+This example cog defines a ``Greetings`` category for your commands, with a single :ref:`command <ext_commands_commands>` named ``hello`` as well as a listener to listen to an :ref:`Event <discord-api-events>`.
+
+.. code-block:: python3
+
+    class Greetings(commands.Cog):
+        def __init__(self, bot):
+            self.bot = bot
+            self._last_member = None
+
+        @commands.Cog.listener()
+        async def on_member_join(self, member):
+            channel = member.guild.system_channel
+            if channel is not None:
+                await channel.send('Welcome {0.mention}.'.format(member))
+
+        @commands.command()
+        async def hello(self, ctx, *, member: discord.Member = None):
+            """Says hello"""
+            member = member or ctx.author
+            if self._last_member is None or self._last_member.id != member.id:
+                await ctx.send('Hello {0.name}~'.format(member))
+            else:
+                await ctx.send('Hello {0.name}... This feels familiar.'.format(member))
+            self._last_member = member
+
+A couple of technical notes to take into consideration:
+
+- All listeners must be explicitly marked via decorator, :meth:`~.commands.Cog.listener`.
+- The name of the cog is automatically derived from the class name but can be overridden. See :ref:`ext_commands_cogs_meta_options`.
+- All commands must now take a ``self`` parameter to allow usage of instance attributes that can be used to maintain state.
+
+Cog Registration
+-------------------
+
+Once you have defined your cogs, you need to tell the bot to register the cogs to be used. We do this via the :meth:`~.commands.Bot.add_cog` method.
+
+.. code-block:: python3
+
+    bot.add_cog(Greetings(bot))
+
+This binds the cog to the bot, adding all commands and listeners to the bot automatically.
+
+Note that we reference the cog by name, which we can override through :ref:`ext_commands_cogs_meta_options`. So if we ever want to remove the cog eventually, we would have to do the following.
+
+.. code-block:: python3
+
+    bot.remove_cog('Greetings')
+
+Using Cogs
+-------------
+
+Just as we remove a cog by its name, we can also retrieve it by its name as well. This allows us to use a cog as an inter-command communication protocol to share data. For example:
+
+.. code-block:: python3
+    :emphasize-lines: 22,24
+
+    class Economy(commands.Cog):
+        ...
+
+        async def withdraw_money(self, member, money):
+            # implementation here
+            ...
+
+        async def deposit_money(self, member, money):
+            # implementation here
+            ...
+
+    class Gambling(commands.Cog):
+        def __init__(self, bot):
+            self.bot = bot
+
+        def coinflip(self):
+            return random.randint(0, 1)
+
+        @commands.command()
+        async def gamble(self, ctx, money: int):
+            """Gambles some money."""
+            economy = self.bot.get_cog('Economy')
+            if economy is not None:
+                await economy.withdraw_money(ctx.author, money)
+                if self.coinflip() == 1:
+                    await economy.deposit_money(ctx.author, money * 1.5)
+
+.. _ext_commands_cogs_special_methods:
+
+Special Methods
+-----------------
+
+As cogs get more complicated and have more commands, there comes a point where we want to customise the behaviour of the entire cog or bot.
+
+They are as follows:
+
+- :meth:`.Cog.cog_unload`
+- :meth:`.Cog.cog_check`
+- :meth:`.Cog.cog_command_error`
+- :meth:`.Cog.cog_before_invoke`
+- :meth:`.Cog.cog_after_invoke`
+- :meth:`.Cog.bot_check`
+- :meth:`.Cog.bot_check_once`
+
+You can visit the reference to get more detail.
+
+.. _ext_commands_cogs_meta_options:
+
+Meta Options
+--------------
+
+At the heart of a cog resides a metaclass, :class:`.commands.CogMeta`, which can take various options to customise some of the behaviour. To do this, we pass keyword arguments to the class definition line. For example, to change the cog name we can pass the ``name`` keyword argument as follows:
+
+.. code-block:: python3
+
+    class MyCog(commands.Cog, name='My Cog'):
+        pass
+
+To see more options that you can set, see the documentation of :class:`.commands.CogMeta`.
+
+Inspection
+------------
+
+Since cogs ultimately are classes, we have some tools to help us inspect certain properties of the cog.
+
+
+To get a :class:`list` of commands, we can use :meth:`.Cog.get_commands`. ::
+
+    >>> cog = bot.get_cog('Greetings')
+    >>> commands = cog.get_commands()
+    >>> print([c.name for c in commands])
+
+If we want to get the subcommands as well, we can use the :meth:`.Cog.walk_commands` generator. ::
+
+    >>> print([c.qualified_name for c in cog.walk_commands()])
+
+To do the same with listeners, we can query them with :meth:`.Cog.get_listeners`. This returns a list of tuples -- the first element being the listener name and the second one being the actual function itself. ::
+
+    >>> for name, func in cog.get_listeners():
+    ...     print(name, '->', func)
+
diff --git a/docs/ext/commands/commands.rst b/docs/ext/commands/commands.rst
new file mode 100644
index 00000000..b5435413
--- /dev/null
+++ b/docs/ext/commands/commands.rst
@@ -0,0 +1,744 @@
+.. currentmodule:: discord
+
+.. _ext_commands_commands:
+
+Commands
+==========
+
+One of the most appealing aspect of the command extension is how easy it is to define commands and
+how you can arbitrarily nest groups and commands to have a rich sub-command system.
+
+Commands are defined by attaching it to a regular Python function. The command is then invoked by the user using a similar
+signature to the Python function.
+
+For example, in the given command definition:
+
+.. code-block:: python3
+
+    @bot.command()
+    async def foo(ctx, arg):
+        await ctx.send(arg)
+
+With the following prefix (``$``), it would be invoked by the user via:
+
+.. code-block:: none
+
+    $foo abc
+
+A command must always have at least one parameter, ``ctx``, which is the :class:`.Context` as the first one.
+
+There are two ways of registering a command. The first one is by using :meth:`.Bot.command` decorator,
+as seen in the example above. The second is using the :func:`~ext.commands.command` decorator followed by
+:meth:`.Bot.add_command` on the instance.
+
+Essentially, these two are equivalent: ::
+
+    from discord.ext import commands
+
+    bot = commands.Bot(command_prefix='$')
+
+    @bot.command()
+    async def test(ctx):
+        pass
+
+    # or:
+
+    @commands.command()
+    async def test(ctx):
+        pass
+
+    bot.add_command(test)
+
+Since the :meth:`.Bot.command` decorator is shorter and easier to comprehend, it will be the one used throughout the
+documentation here.
+
+Any parameter that is accepted by the :class:`.Command` constructor can be passed into the decorator. For example, to change
+the name to something other than the function would be as simple as doing this:
+
+.. code-block:: python3
+
+    @bot.command(name='list')
+    async def _list(ctx, arg):
+        pass
+
+Parameters
+------------
+
+Since we define commands by making Python functions, we also define the argument passing behaviour by the function
+parameters.
+
+Certain parameter types do different things in the user side and most forms of parameter types are supported.
+
+Positional
+++++++++++++
+
+The most basic form of parameter passing is the positional parameter. This is where we pass a parameter as-is:
+
+.. code-block:: python3
+
+    @bot.command()
+    async def test(ctx, arg):
+        await ctx.send(arg)
+
+
+On the bot using side, you can provide positional arguments by just passing a regular string:
+
+.. image:: /images/commands/positional1.png
+
+To make use of a word with spaces in between, you should quote it:
+
+.. image:: /images/commands/positional2.png
+
+As a note of warning, if you omit the quotes, you will only get the first word:
+
+.. image:: /images/commands/positional3.png
+
+Since positional arguments are just regular Python arguments, you can have as many as you want:
+
+.. code-block:: python3
+
+    @bot.command()
+    async def test(ctx, arg1, arg2):
+        await ctx.send('You passed {} and {}'.format(arg1, arg2))
+
+Variable
+++++++++++
+
+Sometimes you want users to pass in an undetermined number of parameters. The library supports this
+similar to how variable list parameters are done in Python:
+
+.. code-block:: python3
+
+    @bot.command()
+    async def test(ctx, *args):
+        await ctx.send('{} arguments: {}'.format(len(args), ', '.join(args)))
+
+This allows our user to accept either one or many arguments as they please. This works similar to positional arguments,
+so multi-word parameters should be quoted.
+
+For example, on the bot side:
+
+.. image:: /images/commands/variable1.png
+
+If the user wants to input a multi-word argument, they have to quote it like earlier:
+
+.. image:: /images/commands/variable2.png
+
+Do note that similar to the Python function behaviour, a user can technically pass no arguments
+at all:
+
+.. image:: /images/commands/variable3.png
+
+Since the ``args`` variable is a :class:`py:tuple`,
+you can do anything you would usually do with one.
+
+Keyword-Only Arguments
+++++++++++++++++++++++++
+
+When you want to handle parsing of the argument yourself or do not feel like you want to wrap multi-word user input into
+quotes, you can ask the library to give you the rest as a single argument. We do this by using a **keyword-only argument**,
+seen below:
+
+.. code-block:: python3
+
+    @bot.command()
+    async def test(ctx, *, arg):
+        await ctx.send(arg)
+
+.. warning::
+
+    You can only have one keyword-only argument due to parsing ambiguities.
+
+On the bot side, we do not need to quote input with spaces:
+
+.. image:: /images/commands/keyword1.png
+
+Do keep in mind that wrapping it in quotes leaves it as-is:
+
+.. image:: /images/commands/keyword2.png
+
+By default, the keyword-only arguments are stripped of white space to make it easier to work with. This behaviour can be
+toggled by the :attr:`.Command.rest_is_raw` argument in the decorator.
+
+.. _ext_commands_context:
+
+Invocation Context
+-------------------
+
+As seen earlier, every command must take at least a single parameter, called the :class:`~ext.commands.Context`.
+
+This parameter gives you access to something called the "invocation context". Essentially all the information you need to
+know how the command was executed. It contains a lot of useful information:
+
+- :attr:`.Context.guild` to fetch the :class:`Guild` of the command, if any.
+- :attr:`.Context.message` to fetch the :class:`Message` of the command.
+- :attr:`.Context.author` to fetch the :class:`Member` or :class:`User` that called the command.
+- :meth:`.Context.send` to send a message to the channel the command was used in.
+
+The context implements the :class:`abc.Messageable` interface, so anything you can do on a :class:`abc.Messageable` you
+can do on the :class:`~ext.commands.Context`.
+
+Converters
+------------
+
+Adding bot arguments with function parameters is only the first step in defining your bot's command interface. To actually
+make use of the arguments, we usually want to convert the data into a target type. We call these
+:ref:`ext_commands_api_converters`.
+
+Converters come in a few flavours:
+
+- A regular callable object that takes an argument as a sole parameter and returns a different type.
+
+    - These range from your own function, to something like :class:`bool` or :class:`int`.
+
+- A custom class that inherits from :class:`~ext.commands.Converter`.
+
+.. _ext_commands_basic_converters:
+
+Basic Converters
+++++++++++++++++++
+
+At its core, a basic converter is a callable that takes in an argument and turns it into something else.
+
+For example, if we wanted to add two numbers together, we could request that they are turned into integers
+for us by specifying the converter:
+
+.. code-block:: python3
+
+    @bot.command()
+    async def add(ctx, a: int, b: int):
+        await ctx.send(a + b)
+
+We specify converters by using something called a **function annotation**. This is a Python 3 exclusive feature that was
+introduced in :pep:`3107`.
+
+This works with any callable, such as a function that would convert a string to all upper-case:
+
+.. code-block:: python3
+
+    def to_upper(argument):
+        return argument.upper()
+
+    @bot.command()
+    async def up(ctx, *, content: to_upper):
+        await ctx.send(content)
+
+bool
+^^^^^^
+
+Unlike the other basic converters, the :class:`bool` converter is treated slightly different. Instead of casting directly to the :class:`bool` type, which would result in any non-empty argument returning ``True``, it instead evaluates the argument as ``True`` or ``False`` based on its given content:
+
+.. code-block:: python3
+
+    if lowered in ('yes', 'y', 'true', 't', '1', 'enable', 'on'):
+        return True
+    elif lowered in ('no', 'n', 'false', 'f', '0', 'disable', 'off'):
+        return False
+
+.. _ext_commands_adv_converters:
+
+Advanced Converters
++++++++++++++++++++++
+
+Sometimes a basic converter doesn't have enough information that we need. For example, sometimes we want to get some
+information from the :class:`Message` that called the command or we want to do some asynchronous processing.
+
+For this, the library provides the :class:`~ext.commands.Converter` interface. This allows you to have access to the
+:class:`.Context` and have the callable be asynchronous. Defining a custom converter using this interface requires
+overriding a single method, :meth:`.Converter.convert`.
+
+An example converter:
+
+.. code-block:: python3
+
+    import random
+
+    class Slapper(commands.Converter):
+        async def convert(self, ctx, argument):
+            to_slap = random.choice(ctx.guild.members)
+            return '{0.author} slapped {1} because *{2}*'.format(ctx, to_slap, argument)
+
+    @bot.command()
+    async def slap(ctx, *, reason: Slapper):
+        await ctx.send(reason)
+
+The converter provided can either be constructed or not. Essentially these two are equivalent:
+
+.. code-block:: python3
+
+    @bot.command()
+    async def slap(ctx, *, reason: Slapper):
+        await ctx.send(reason)
+
+    # is the same as...
+
+    @bot.command()
+    async def slap(ctx, *, reason: Slapper()):
+        await ctx.send(reason)
+
+Having the possibility of the converter be constructed allows you to set up some state in the converter's ``__init__`` for
+fine tuning the converter. An example of this is actually in the library, :class:`~ext.commands.clean_content`.
+
+.. code-block:: python3
+
+    @bot.command()
+    async def clean(ctx, *, content: commands.clean_content):
+        await ctx.send(content)
+
+    # or for fine-tuning
+
+    @bot.command()
+    async def clean(ctx, *, content: commands.clean_content(use_nicknames=False)):
+        await ctx.send(content)
+
+
+If a converter fails to convert an argument to its designated target type, the :exc:`.BadArgument` exception must be
+raised.
+
+Inline Advanced Converters
++++++++++++++++++++++++++++++
+
+If we don't want to inherit from :class:`~ext.commands.Converter`, we can still provide a converter that has the
+advanced functionalities of an advanced converter and save us from specifying two types.
+
+For example, a common idiom would be to have a class and a converter for that class:
+
+.. code-block:: python3
+
+    class JoinDistance:
+        def __init__(self, joined, created):
+            self.joined = joined
+            self.created = created
+
+        @property
+        def delta(self):
+            return self.joined - self.created
+
+    class JoinDistanceConverter(commands.MemberConverter):
+        async def convert(self, ctx, argument):
+            member = await super().convert(ctx, argument)
+            return JoinDistance(member.joined_at, member.created_at)
+
+    @bot.command()
+    async def delta(ctx, *, member: JoinDistanceConverter):
+        is_new = member.delta.days < 100
+        if is_new:
+            await ctx.send("Hey you're pretty new!")
+        else:
+            await ctx.send("Hm you're not so new.")
+
+This can get tedious, so an inline advanced converter is possible through a :func:`classmethod` inside the type:
+
+.. code-block:: python3
+
+    class JoinDistance:
+        def __init__(self, joined, created):
+            self.joined = joined
+            self.created = created
+
+        @classmethod
+        async def convert(cls, ctx, argument):
+            member = await commands.MemberConverter().convert(ctx, argument)
+            return cls(member.joined_at, member.created_at)
+
+        @property
+        def delta(self):
+            return self.joined - self.created
+
+    @bot.command()
+    async def delta(ctx, *, member: JoinDistance):
+        is_new = member.delta.days < 100
+        if is_new:
+            await ctx.send("Hey you're pretty new!")
+        else:
+            await ctx.send("Hm you're not so new.")
+
+Discord Converters
+++++++++++++++++++++
+
+Working with :ref:`discord_api_models` is a fairly common thing when defining commands, as a result the library makes
+working with them easy.
+
+For example, to receive a :class:`Member` you can just pass it as a converter:
+
+.. code-block:: python3
+
+    @bot.command()
+    async def joined(ctx, *, member: discord.Member):
+        await ctx.send('{0} joined on {0.joined_at}'.format(member))
+
+When this command is executed, it attempts to convert the string given into a :class:`Member` and then passes it as a
+parameter for the function. This works by checking if the string is a mention, an ID, a nickname, a username + discriminator,
+or just a regular username. The default set of converters have been written to be as easy to use as possible.
+
+A lot of discord models work out of the gate as a parameter:
+
+- :class:`Member`
+- :class:`User`
+- :class:`Message` (since v1.1)
+- :class:`PartialMessage` (since v1.7)
+- :class:`TextChannel`
+- :class:`VoiceChannel`
+- :class:`StageChannel` (since v1.7)
+- :class:`StoreChannel` (since v1.7)
+- :class:`CategoryChannel`
+- :class:`Invite`
+- :class:`Guild` (since v1.7)
+- :class:`Role`
+- :class:`Game`
+- :class:`Colour`
+- :class:`Emoji`
+- :class:`PartialEmoji`
+
+Having any of these set as the converter will intelligently convert the argument to the appropriate target type you
+specify.
+
+Under the hood, these are implemented by the :ref:`ext_commands_adv_converters` interface. A table of the equivalent
+converter is given below:
+
++--------------------------+-------------------------------------------------+
+|     Discord Class        |                    Converter                    |
++--------------------------+-------------------------------------------------+
+| :class:`Member`          | :class:`~ext.commands.MemberConverter`          |
++--------------------------+-------------------------------------------------+
+| :class:`User`            | :class:`~ext.commands.UserConverter`            |
++--------------------------+-------------------------------------------------+
+| :class:`Message`         | :class:`~ext.commands.MessageConverter`         |
++--------------------------+-------------------------------------------------+
+| :class:`PartialMessage`  | :class:`~ext.commands.PartialMessageConverter`  |
++--------------------------+-------------------------------------------------+
+| :class:`TextChannel`     | :class:`~ext.commands.TextChannelConverter`     |
++--------------------------+-------------------------------------------------+
+| :class:`VoiceChannel`    | :class:`~ext.commands.VoiceChannelConverter`    |
++--------------------------+-------------------------------------------------+
+| :class:`StageChannel`    | :class:`~ext.commands.StageChannelConverter`    |
++--------------------------+-------------------------------------------------+
+| :class:`StoreChannel`    | :class:`~ext.commands.StoreChannelConverter`    |
++--------------------------+-------------------------------------------------+
+| :class:`CategoryChannel` | :class:`~ext.commands.CategoryChannelConverter` |
++--------------------------+-------------------------------------------------+
+| :class:`Invite`          | :class:`~ext.commands.InviteConverter`          |
++--------------------------+-------------------------------------------------+
+| :class:`Guild`           | :class:`~ext.commands.GuildConverter`           |
++--------------------------+-------------------------------------------------+
+| :class:`Role`            | :class:`~ext.commands.RoleConverter`            |
++--------------------------+-------------------------------------------------+
+| :class:`Game`            | :class:`~ext.commands.GameConverter`            |
++--------------------------+-------------------------------------------------+
+| :class:`Colour`          | :class:`~ext.commands.ColourConverter`          |
++--------------------------+-------------------------------------------------+
+| :class:`Emoji`           | :class:`~ext.commands.EmojiConverter`           |
++--------------------------+-------------------------------------------------+
+| :class:`PartialEmoji`    | :class:`~ext.commands.PartialEmojiConverter`    |
++--------------------------+-------------------------------------------------+
+
+By providing the converter it allows us to use them as building blocks for another converter:
+
+.. code-block:: python3
+
+    class MemberRoles(commands.MemberConverter):
+        async def convert(self, ctx, argument):
+            member = await super().convert(ctx, argument)
+            return [role.name for role in member.roles[1:]] # Remove everyone role!
+
+    @bot.command()
+    async def roles(ctx, *, member: MemberRoles):
+        """Tells you a member's roles."""
+        await ctx.send('I see the following roles: ' + ', '.join(member))
+
+.. _ext_commands_special_converters:
+
+Special Converters
+++++++++++++++++++++
+
+The command extension also has support for certain converters to allow for more advanced and intricate use cases that go
+beyond the generic linear parsing. These converters allow you to introduce some more relaxed and dynamic grammar to your
+commands in an easy to use manner.
+
+typing.Union
+^^^^^^^^^^^^^^
+
+A :data:`typing.Union` is a special type hint that allows for the command to take in any of the specific types instead of
+a singular type. For example, given the following:
+
+.. code-block:: python3
+
+    import typing
+
+    @bot.command()
+    async def union(ctx, what: typing.Union[discord.TextChannel, discord.Member]):
+        await ctx.send(what)
+
+
+The ``what`` parameter would either take a :class:`discord.TextChannel` converter or a :class:`discord.Member` converter.
+The way this works is through a left-to-right order. It first attempts to convert the input to a
+:class:`discord.TextChannel`, and if it fails it tries to convert it to a :class:`discord.Member`. If all converters fail,
+then a special error is raised, :exc:`~ext.commands.BadUnionArgument`.
+
+Note that any valid converter discussed above can be passed in to the argument list of a :data:`typing.Union`.
+
+typing.Optional
+^^^^^^^^^^^^^^^^^
+
+A :data:`typing.Optional` is a special type hint that allows for "back-referencing" behaviour. If the converter fails to
+parse into the specified type, the parser will skip the parameter and then either ``None`` or the specified default will be
+passed into the parameter instead. The parser will then continue on to the next parameters and converters, if any.
+
+Consider the following example:
+
+.. code-block:: python3
+
+    import typing
+
+    @bot.command()
+    async def bottles(ctx, amount: typing.Optional[int] = 99, *, liquid="beer"):
+        await ctx.send('{} bottles of {} on the wall!'.format(amount, liquid))
+
+
+.. image:: /images/commands/optional1.png
+
+In this example, since the argument could not be converted into an ``int``, the default of ``99`` is passed and the parser
+resumes handling, which in this case would be to pass it into the ``liquid`` parameter.
+
+.. note::
+
+    This converter only works in regular positional parameters, not variable parameters or keyword-only parameters.
+
+Greedy
+^^^^^^^^
+
+The :data:`~ext.commands.Greedy` converter is a generalisation of the :data:`typing.Optional` converter, except applied
+to a list of arguments. In simple terms, this means that it tries to convert as much as it can until it can't convert
+any further.
+
+Consider the following example:
+
+.. code-block:: python3
+
+    @bot.command()
+    async def slap(ctx, members: commands.Greedy[discord.Member], *, reason='no reason'):
+        slapped = ", ".join(x.name for x in members)
+        await ctx.send('{} just got slapped for {}'.format(slapped, reason))
+
+When invoked, it allows for any number of members to be passed in:
+
+.. image:: /images/commands/greedy1.png
+
+The type passed when using this converter depends on the parameter type that it is being attached to:
+
+- Positional parameter types will receive either the default parameter or a :class:`list` of the converted values.
+- Variable parameter types will be a :class:`tuple` as usual.
+- Keyword-only parameter types will be the same as if :data:`~ext.commands.Greedy` was not passed at all.
+
+:data:`~ext.commands.Greedy` parameters can also be made optional by specifying an optional value.
+
+When mixed with the :data:`typing.Optional` converter you can provide simple and expressive command invocation syntaxes:
+
+.. code-block:: python3
+
+    import typing
+
+    @bot.command()
+    async def ban(ctx, members: commands.Greedy[discord.Member],
+                       delete_days: typing.Optional[int] = 0, *,
+                       reason: str):
+        """Mass bans members with an optional delete_days parameter"""
+        for member in members:
+            await member.ban(delete_message_days=delete_days, reason=reason)
+
+
+This command can be invoked any of the following ways:
+
+.. code-block:: none
+
+    $ban @Member @Member2 spam bot
+    $ban @Member @Member2 7 spam bot
+    $ban @Member spam
+
+.. warning::
+
+    The usage of :data:`~ext.commands.Greedy` and :data:`typing.Optional` are powerful and useful, however as a
+    price, they open you up to some parsing ambiguities that might surprise some people.
+
+    For example, a signature expecting a :data:`typing.Optional` of a :class:`discord.Member` followed by a
+    :class:`int` could catch a member named after a number due to the different ways a
+    :class:`~ext.commands.MemberConverter` decides to fetch members. You should take care to not introduce
+    unintended parsing ambiguities in your code. One technique would be to clamp down the expected syntaxes
+    allowed through custom converters or reordering the parameters to minimise clashes.
+
+    To help aid with some parsing ambiguities, :class:`str`, ``None``, :data:`typing.Optional` and
+    :data:`~ext.commands.Greedy` are forbidden as parameters for the :data:`~ext.commands.Greedy` converter.
+
+.. _ext_commands_error_handler:
+
+Error Handling
+----------------
+
+When our commands fail to parse we will, by default, receive a noisy error in ``stderr`` of our console that tells us
+that an error has happened and has been silently ignored.
+
+In order to handle our errors, we must use something called an error handler. There is a global error handler, called
+:func:`on_command_error` which works like any other event in the :ref:`discord-api-events`. This global error handler is
+called for every error reached.
+
+Most of the time however, we want to handle an error local to the command itself. Luckily, commands come with local error
+handlers that allow us to do just that. First we decorate an error handler function with :meth:`.Command.error`:
+
+.. code-block:: python3
+
+    @bot.command()
+    async def info(ctx, *, member: discord.Member):
+        """Tells you some info about the member."""
+        fmt = '{0} joined on {0.joined_at} and has {1} roles.'
+        await ctx.send(fmt.format(member, len(member.roles)))
+
+    @info.error
+    async def info_error(ctx, error):
+        if isinstance(error, commands.BadArgument):
+            await ctx.send('I could not find that member...')
+
+The first parameter of the error handler is the :class:`.Context` while the second one is an exception that is derived from
+:exc:`~ext.commands.CommandError`. A list of errors is found in the :ref:`ext_commands_api_errors` page of the documentation.
+
+Checks
+-------
+
+There are cases when we don't want a user to use our commands. They don't have permissions to do so or maybe we blocked
+them from using our bot earlier. The commands extension comes with full support for these things in a concept called a
+:ref:`ext_commands_api_checks`.
+
+A check is a basic predicate that can take in a :class:`.Context` as its sole parameter. Within it, you have the following
+options:
+
+- Return ``True`` to signal that the person can run the command.
+- Return ``False`` to signal that the person cannot run the command.
+- Raise a :exc:`~ext.commands.CommandError` derived exception to signal the person cannot run the command.
+
+    - This allows you to have custom error messages for you to handle in the
+      :ref:`error handlers <ext_commands_error_handler>`.
+
+To register a check for a command, we would have two ways of doing so. The first is using the :meth:`~ext.commands.check`
+decorator. For example:
+
+.. code-block:: python3
+
+    async def is_owner(ctx):
+        return ctx.author.id == 316026178463072268
+
+    @bot.command(name='eval')
+    @commands.check(is_owner)
+    async def _eval(ctx, *, code):
+        """A bad example of an eval command"""
+        await ctx.send(eval(code))
+
+This would only evaluate the command if the function ``is_owner`` returns ``True``. Sometimes we re-use a check often and
+want to split it into its own decorator. To do that we can just add another level of depth:
+
+.. code-block:: python3
+
+    def is_owner():
+        async def predicate(ctx):
+            return ctx.author.id == 316026178463072268
+        return commands.check(predicate)
+
+    @bot.command(name='eval')
+    @is_owner()
+    async def _eval(ctx, *, code):
+        """A bad example of an eval command"""
+        await ctx.send(eval(code))
+
+
+Since an owner check is so common, the library provides it for you (:func:`~ext.commands.is_owner`):
+
+.. code-block:: python3
+
+    @bot.command(name='eval')
+    @commands.is_owner()
+    async def _eval(ctx, *, code):
+        """A bad example of an eval command"""
+        await ctx.send(eval(code))
+
+When multiple checks are specified, **all** of them must be ``True``:
+
+.. code-block:: python3
+
+    def is_in_guild(guild_id):
+        async def predicate(ctx):
+            return ctx.guild and ctx.guild.id == guild_id
+        return commands.check(predicate)
+
+    @bot.command()
+    @commands.is_owner()
+    @is_in_guild(41771983423143937)
+    async def secretguilddata(ctx):
+        """super secret stuff"""
+        await ctx.send('secret stuff')
+
+If any of those checks fail in the example above, then the command will not be run.
+
+When an error happens, the error is propagated to the :ref:`error handlers <ext_commands_error_handler>`. If you do not
+raise a custom :exc:`~ext.commands.CommandError` derived exception, then it will get wrapped up into a
+:exc:`~ext.commands.CheckFailure` exception as so:
+
+.. code-block:: python3
+
+    @bot.command()
+    @commands.is_owner()
+    @is_in_guild(41771983423143937)
+    async def secretguilddata(ctx):
+        """super secret stuff"""
+        await ctx.send('secret stuff')
+
+    @secretguilddata.error
+    async def secretguilddata_error(ctx, error):
+        if isinstance(error, commands.CheckFailure):
+            await ctx.send('nothing to see here comrade.')
+
+If you want a more robust error system, you can derive from the exception and raise it instead of returning ``False``:
+
+.. code-block:: python3
+
+    class NoPrivateMessages(commands.CheckFailure):
+        pass
+
+    def guild_only():
+        async def predicate(ctx):
+            if ctx.guild is None:
+                raise NoPrivateMessages('Hey no DMs!')
+            return True
+        return commands.check(predicate)
+
+    @guild_only()
+    async def test(ctx):
+        await ctx.send('Hey this is not a DM! Nice.')
+
+    @test.error
+    async def test_error(ctx, error):
+        if isinstance(error, NoPrivateMessages):
+            await ctx.send(error)
+
+.. note::
+
+    Since having a ``guild_only`` decorator is pretty common, it comes built-in via :func:`~ext.commands.guild_only`.
+
+Global Checks
+++++++++++++++
+
+Sometimes we want to apply a check to **every** command, not just certain commands. The library supports this as well
+using the global check concept.
+
+Global checks work similarly to regular checks except they are registered with the :meth:`.Bot.check` decorator.
+
+For example, to block all DMs we could do the following:
+
+.. code-block:: python3
+
+    @bot.check
+    async def globally_block_dms(ctx):
+        return ctx.guild is not None
+
+.. warning::
+
+    Be careful on how you write your global checks, as it could also lock you out of your own bot.
+
+.. need a note on global check once here I think
diff --git a/docs/ext/commands/extensions.rst b/docs/ext/commands/extensions.rst
new file mode 100644
index 00000000..db17103d
--- /dev/null
+++ b/docs/ext/commands/extensions.rst
@@ -0,0 +1,64 @@
+.. currentmodule:: discord
+
+.. _ext_commands_extensions:
+
+Extensions
+=============
+
+There comes a time in the bot development when you want to extend the bot functionality at run-time and quickly unload and reload code (also called hot-reloading). The command framework comes with this ability built-in, with a concept called **extensions**.
+
+Primer
+--------
+
+An extension at its core is a python file with an entry point called ``setup``. This setup must be a plain Python function (not a coroutine). It takes a single parameter -- the :class:`~.commands.Bot` that loads the extension.
+
+An example extension looks like this:
+
+.. code-block:: python3
+    :caption: hello.py
+    :emphasize-lines: 7,8
+
+    from discord.ext import commands
+
+    @commands.command()
+    async def hello(ctx):
+        await ctx.send('Hello {0.display_name}.'.format(ctx.author))
+
+    def setup(bot):
+        bot.add_command(hello)
+
+In this example we define a simple command, and when the extension is loaded this command is added to the bot. Now the final step to this is loading the extension, which we do by calling :meth:`.Bot.load_extension`. To load this extension we call ``bot.load_extension('hello')``.
+
+.. admonition:: Cogs
+    :class: helpful
+
+    Extensions are usually used in conjunction with cogs. To read more about them, check out the documentation, :ref:`ext_commands_cogs`.
+
+.. note::
+
+    Extension paths are ultimately similar to the import mechanism. What this means is that if there is a folder, then it must be dot-qualified. For example to load an extension in ``plugins/hello.py`` then we use the string ``plugins.hello``.
+
+Reloading
+-----------
+
+When you make a change to the extension and want to reload the references, the library comes with a function to do this for you, :meth:`.Bot.reload_extension`.
+
+.. code-block:: python3
+
+    >>> bot.reload_extension('hello')
+
+Once the extension reloads, any changes that we did will be applied. This is useful if we want to add or remove functionality without restarting our bot. If an error occurred during the reloading process, the bot will pretend as if the reload never happened.
+
+Cleaning Up
+-------------
+
+Although rare, sometimes an extension needs to clean-up or know when it's being unloaded. For cases like these, there is another entry point named ``teardown`` which is similar to ``setup`` except called when the extension is unloaded.
+
+.. code-block:: python3
+    :caption: basic_ext.py
+
+    def setup(bot):
+        print('I am being loaded!')
+
+    def teardown(bot):
+        print('I am being unloaded!')
diff --git a/docs/ext/commands/index.rst b/docs/ext/commands/index.rst
new file mode 100644
index 00000000..f6238548
--- /dev/null
+++ b/docs/ext/commands/index.rst
@@ -0,0 +1,18 @@
+.. _discord_ext_commands:
+
+``discord.ext.commands`` -- Bot commands framework
+====================================================
+
+``discord.py-message-components`` offers a lower level aspect on interacting with Discord. Often times, the library is used for the creation of
+bots. However this task can be daunting and confusing to get correctly the first time. Many times there comes a repetition in
+creating a bot command framework that is extensible, flexible, and powerful. For this reason, ``discord.py-message-components`` comes with an
+extension library that handles this for you.
+
+
+.. toctree::
+    :maxdepth: 2
+
+    commands
+    cogs
+    extensions
+    api
diff --git a/docs/ext/tasks/index.rst b/docs/ext/tasks/index.rst
new file mode 100644
index 00000000..55f60932
--- /dev/null
+++ b/docs/ext/tasks/index.rst
@@ -0,0 +1,144 @@
+.. _discord_ext_tasks:
+
+``discord.ext.tasks`` -- asyncio.Task helpers
+====================================================
+
+.. versionadded:: 1.1.0
+
+One of the most common operations when making a bot is having a loop run in the background at a specified interval. This pattern is very common but has a lot of things you need to look out for:
+
+- How do I handle :exc:`asyncio.CancelledError`?
+- What do I do if the internet goes out?
+- What is the maximum number of seconds I can sleep anyway?
+
+The goal of this discord.py extension is to abstract all these worries away from you.
+
+Recipes
+---------
+
+A simple background task in a :class:`~discord.ext.commands.Cog`:
+
+.. code-block:: python3
+
+    from discord.ext import tasks, commands
+
+    class MyCog(commands.Cog):
+        def __init__(self):
+            self.index = 0
+            self.printer.start()
+
+        def cog_unload(self):
+            self.printer.cancel()
+
+        @tasks.loop(seconds=5.0)
+        async def printer(self):
+            print(self.index)
+            self.index += 1
+
+Adding an exception to handle during reconnect:
+
+.. code-block:: python3
+
+    import asyncpg
+    from discord.ext import tasks, commands
+
+    class MyCog(commands.Cog):
+        def __init__(self, bot):
+            self.bot = bot
+            self.data = []
+            self.batch_update.add_exception_type(asyncpg.PostgresConnectionError)
+            self.batch_update.start()
+
+        def cog_unload(self):
+            self.batch_update.cancel()
+
+        @tasks.loop(minutes=5.0)
+        async def batch_update(self):
+            async with self.bot.pool.acquire() as con:
+                # batch update here...
+                pass
+
+Looping a certain amount of times before exiting:
+
+.. code-block:: python3
+
+    from discord.ext import tasks
+
+    @tasks.loop(seconds=5.0, count=5)
+    async def slow_count():
+        print(slow_count.current_loop)
+
+    @slow_count.after_loop
+    async def after_slow_count():
+        print('done!')
+
+    slow_count.start()
+
+Waiting until the bot is ready before the loop starts:
+
+.. code-block:: python3
+
+    from discord.ext import tasks, commands
+
+    class MyCog(commands.Cog):
+        def __init__(self, bot):
+            self.index = 0
+            self.bot = bot
+            self.printer.start()
+
+        def cog_unload(self):
+            self.printer.cancel()
+
+        @tasks.loop(seconds=5.0)
+        async def printer(self):
+            print(self.index)
+            self.index += 1
+
+        @printer.before_loop
+        async def before_printer(self):
+            print('waiting...')
+            await self.bot.wait_until_ready()
+
+Doing something during cancellation:
+
+.. code-block:: python3
+
+    from discord.ext import tasks, commands
+    import asyncio
+
+    class MyCog(commands.Cog):
+        def __init__(self, bot):
+            self.bot= bot
+            self._batch = []
+            self.lock = asyncio.Lock()
+            self.bulker.start()
+
+        async def do_bulk(self):
+            # bulk insert data here
+            ...
+
+        @tasks.loop(seconds=10.0)
+        async def bulker(self):
+            async with self.lock:
+                await self.do_bulk()
+
+        @bulker.after_loop
+        async def on_bulker_cancel(self):
+            if self.bulker.is_being_cancelled() and len(self._batch) != 0:
+                # if we're cancelled and we have some data left...
+                # let's insert it to our database
+                await self.do_bulk()
+
+
+.. _ext_tasks_api:
+
+API Reference
+---------------
+
+.. attributetable:: discord.ext.tasks.Loop
+
+.. autoclass:: discord.ext.tasks.Loop()
+    :members:
+    :special-members: __call__
+
+.. autofunction:: discord.ext.tasks.loop
diff --git a/docs/extensions/attributetable.py b/docs/extensions/attributetable.py
new file mode 100644
index 00000000..5df93389
--- /dev/null
+++ b/docs/extensions/attributetable.py
@@ -0,0 +1,241 @@
+from sphinx.util.docutils import SphinxDirective
+from sphinx.locale import _
+from docutils import nodes
+from sphinx import addnodes
+
+from collections import OrderedDict, namedtuple
+import importlib
+import inspect
+import os
+import re
+
+class attributetable(nodes.General, nodes.Element):
+    pass
+
+class attributetablecolumn(nodes.General, nodes.Element):
+    pass
+
+class attributetabletitle(nodes.TextElement):
+    pass
+
+class attributetableplaceholder(nodes.General, nodes.Element):
+    pass
+
+class attributetablebadge(nodes.TextElement):
+    pass
+
+class attributetable_item(nodes.Part, nodes.Element):
+    pass
+
+def visit_attributetable_node(self, node):
+    self.body.append('<div class="py-attribute-table" data-move-to-id="%s">' % node['python-class'])
+
+def visit_attributetablecolumn_node(self, node):
+    self.body.append(self.starttag(node, 'div', CLASS='py-attribute-table-column'))
+
+def visit_attributetabletitle_node(self, node):
+    self.body.append(self.starttag(node, 'span'))
+
+def visit_attributetablebadge_node(self, node):
+    attributes = {
+        'class': 'py-attribute-table-badge',
+        'title': node['badge-type'],
+    }
+    self.body.append(self.starttag(node, 'span', **attributes))
+
+def visit_attributetable_item_node(self, node):
+    self.body.append(self.starttag(node, 'li', CLASS='py-attribute-table-entry'))
+
+def depart_attributetable_node(self, node):
+    self.body.append('</div>')
+
+def depart_attributetablecolumn_node(self, node):
+    self.body.append('</div>')
+
+def depart_attributetabletitle_node(self, node):
+    self.body.append('</span>')
+
+def depart_attributetablebadge_node(self, node):
+    self.body.append('</span>')
+
+def depart_attributetable_item_node(self, node):
+    self.body.append('</li>')
+
+_name_parser_regex = re.compile(r'(?P<module>[\w.]+\.)?(?P<name>\w+)')
+
+class PyAttributeTable(SphinxDirective):
+    has_content = False
+    required_arguments = 1
+    optional_arguments = 0
+    final_argument_whitespace = False
+    option_spec = {}
+
+    def parse_name(self, content):
+        path, name = _name_parser_regex.match(content).groups()
+        if path:
+            modulename = path.rstrip('.')
+        else:
+            modulename = self.env.temp_data.get('autodoc:module')
+            if not modulename:
+                modulename = self.env.ref_context.get('py:module')
+        if modulename is None:
+            raise RuntimeError('modulename somehow None for %s in %s.' % (content, self.env.docname))
+
+        return modulename, name
+
+    def run(self):
+        """If you're curious on the HTML this is meant to generate:
+
+        <div class="py-attribute-table">
+            <div class="py-attribute-table-column">
+                <span>_('Attributes')</span>
+                <ul>
+                    <li>
+                        <a href="...">
+                    </li>
+                </ul>
+            </div>
+            <div class="py-attribute-table-column">
+                <span>_('Methods')</span>
+                <ul>
+                    <li>
+                        <a href="..."></a>
+                        <span class="py-attribute-badge" title="decorator">D</span>
+                    </li>
+                </ul>
+            </div>
+        </div>
+
+        However, since this requires the tree to be complete
+        and parsed, it'll need to be done at a different stage and then
+        replaced.
+        """
+        content = self.arguments[0].strip()
+        node = attributetableplaceholder('')
+        modulename, name = self.parse_name(content)
+        node['python-module'] = modulename
+        node['python-class'] = name
+        node['python-full-name'] = '%s.%s' % (modulename, name)
+        return [node]
+
+def build_lookup_table(env):
+    # Given an environment, load up a lookup table of
+    # full-class-name: objects
+    result = {}
+    domain = env.domains['py']
+
+    ignored = {
+        'data', 'exception', 'module', 'class',
+    }
+
+    for (fullname, _, objtype, docname, _, _) in domain.get_objects():
+        if objtype in ignored:
+            continue
+
+        classname, _, child = fullname.rpartition('.')
+        try:
+            result[classname].append(child)
+        except KeyError:
+            result[classname] = [child]
+
+    return result
+
+
+TableElement = namedtuple('TableElement', 'fullname label badge')
+
+def process_attributetable(app, doctree, fromdocname):
+    env = app.builder.env
+
+    lookup = build_lookup_table(env)
+    for node in doctree.traverse(attributetableplaceholder):
+        modulename, classname, fullname = node['python-module'], node['python-class'], node['python-full-name']
+        groups = get_class_results(lookup, modulename, classname, fullname)
+        table = attributetable('')
+        for label, subitems in groups.items():
+            if not subitems:
+                continue
+            table.append(class_results_to_node(label, sorted(subitems, key=lambda c: c.label)))
+
+        table['python-class'] = fullname
+
+        if not table:
+            node.replace_self([])
+        else:
+            node.replace_self([table])
+
+def get_class_results(lookup, modulename, name, fullname):
+    module = importlib.import_module(modulename)
+    cls = getattr(module, name)
+
+    groups = OrderedDict([
+        (_('Attributes'), []),
+        (_('Methods'), []),
+    ])
+
+    try:
+        members = lookup[fullname]
+    except KeyError:
+        return groups
+
+    for attr in members:
+        attrlookup = '%s.%s' % (fullname, attr)
+        key = _('Attributes')
+        badge = None
+        label = attr
+
+        for base in cls.__mro__:
+            value = base.__dict__.get(attr)
+            if value is not None:
+                break
+
+        if value is not None:
+            doc = (value.__doc__ or '').lstrip()
+            if inspect.iscoroutinefunction(value) or doc.startswith('|coro|'):
+                key = _('Methods')
+                badge = attributetablebadge('async', 'async')
+                badge['badge-type'] = _('coroutine')
+            elif isinstance(value, classmethod):
+                key = _('Methods')
+                label = '%s.%s' % (name, attr)
+                badge = attributetablebadge('cls', 'cls')
+                badge['badge-type'] = _('classmethod')
+            elif inspect.isfunction(value):
+                if doc.startswith(('A decorator', 'A shortcut decorator')):
+                    # finicky but surprisingly consistent
+                    badge = attributetablebadge('@', '@')
+                    badge['badge-type'] = _('decorator')
+                    key = _('Methods')
+                else:
+                    key = _('Methods')
+                    badge = attributetablebadge('def', 'def')
+                    badge['badge-type'] = _('method')
+
+        groups[key].append(TableElement(fullname=attrlookup, label=label, badge=badge))
+
+    return groups
+
+def class_results_to_node(key, elements):
+    title = attributetabletitle(key, key)
+    ul = nodes.bullet_list('')
+    for element in elements:
+        ref = nodes.reference('', '', internal=True,
+                                      refuri='#' + element.fullname,
+                                      anchorname='',
+                                      *[nodes.Text(element.label)])
+        para = addnodes.compact_paragraph('', '', ref)
+        if element.badge is not None:
+            ul.append(attributetable_item('', element.badge, para))
+        else:
+            ul.append(attributetable_item('', para))
+
+    return attributetablecolumn('', title, ul)
+
+def setup(app):
+    app.add_directive('attributetable', PyAttributeTable)
+    app.add_node(attributetable, html=(visit_attributetable_node, depart_attributetable_node))
+    app.add_node(attributetablecolumn, html=(visit_attributetablecolumn_node, depart_attributetablecolumn_node))
+    app.add_node(attributetabletitle, html=(visit_attributetabletitle_node, depart_attributetabletitle_node))
+    app.add_node(attributetablebadge, html=(visit_attributetablebadge_node, depart_attributetablebadge_node))
+    app.add_node(attributetable_item, html=(visit_attributetable_item_node, depart_attributetable_item_node))
+    app.add_node(attributetableplaceholder)
+    app.connect('doctree-resolved', process_attributetable)
diff --git a/docs/extensions/builder.py b/docs/extensions/builder.py
new file mode 100644
index 00000000..3f2b2594
--- /dev/null
+++ b/docs/extensions/builder.py
@@ -0,0 +1,77 @@
+from sphinx.builders.html import StandaloneHTMLBuilder
+from sphinx.environment.adapters.indexentries import IndexEntries
+from sphinx.writers.html5 import HTML5Translator
+
+class DPYHTML5Translator(HTML5Translator):
+    def visit_section(self, node):
+        self.section_level += 1
+        self.body.append(
+            self.starttag(node, 'section'))
+
+    def depart_section(self, node):
+        self.section_level -= 1
+        self.body.append('</section>\n')
+
+    def visit_table(self, node):
+        self.body.append('<div class="table-wrapper">')
+        super().visit_table(node)
+
+    def depart_table(self, node):
+        super().depart_table(node)
+        self.body.append('</div>')
+
+class DPYStandaloneHTMLBuilder(StandaloneHTMLBuilder):
+    # This is mostly copy pasted from Sphinx.
+    def write_genindex(self) -> None:
+        # the total count of lines for each index letter, used to distribute
+        # the entries into two columns
+        genindex = IndexEntries(self.env).create_index(self, group_entries=False)
+        indexcounts = []
+        for _k, entries in genindex:
+            indexcounts.append(sum(1 + len(subitems)
+                                   for _, (_, subitems, _) in entries))
+
+        genindexcontext = {
+            'genindexentries': genindex,
+            'genindexcounts': indexcounts,
+            'split_index': self.config.html_split_index,
+        }
+
+        if self.config.html_split_index:
+            self.handle_page('genindex', genindexcontext,
+                             'genindex-split.html')
+            self.handle_page('genindex-all', genindexcontext,
+                             'genindex.html')
+            for (key, entries), count in zip(genindex, indexcounts):
+                ctx = {'key': key, 'entries': entries, 'count': count,
+                       'genindexentries': genindex}
+                self.handle_page('genindex-' + key, ctx,
+                                 'genindex-single.html')
+        else:
+            self.handle_page('genindex', genindexcontext, 'genindex.html')
+
+
+def add_custom_jinja2(app):
+    env = app.builder.templates.environment
+    env.tests['prefixedwith'] = str.startswith
+    env.tests['suffixedwith'] = str.endswith
+
+def add_builders(app):
+    """This is necessary because RTD injects their own for some reason."""
+    app.set_translator('html', DPYHTML5Translator, override=True)
+    app.add_builder(DPYStandaloneHTMLBuilder, override=True)
+
+    try:
+        original = app.registry.builders['readthedocs']
+    except KeyError:
+        pass
+    else:
+        injected_mro = tuple(base if base is not StandaloneHTMLBuilder else DPYStandaloneHTMLBuilder
+                             for base in original.mro()[1:])
+        new_builder = type(original.__name__, injected_mro, {'name': 'readthedocs'})
+        app.set_translator('readthedocs', DPYHTML5Translator, override=True)
+        app.add_builder(new_builder, override=True)
+
+def setup(app):
+    add_builders(app)
+    app.connect('builder-inited', add_custom_jinja2)
diff --git a/docs/extensions/details.py b/docs/extensions/details.py
new file mode 100644
index 00000000..96f39d5b
--- /dev/null
+++ b/docs/extensions/details.py
@@ -0,0 +1,55 @@
+from docutils.parsers.rst import Directive
+from docutils.parsers.rst import states, directives
+from docutils.parsers.rst.roles import set_classes
+from docutils import nodes
+
+class details(nodes.General, nodes.Element):
+    pass
+
+class summary(nodes.General, nodes.Element):
+    pass
+
+def visit_details_node(self, node):
+    self.body.append(self.starttag(node, 'details', CLASS=node.attributes.get('class', '')))
+
+def visit_summary_node(self, node):
+    self.body.append(self.starttag(node, 'summary', CLASS=node.attributes.get('summary-class', '')))
+    self.body.append(node.rawsource)
+
+def depart_details_node(self, node):
+    self.body.append('</details>\n')
+
+def depart_summary_node(self, node):
+    self.body.append('</summary>')
+
+class DetailsDirective(Directive):
+    final_argument_whitespace = True
+    optional_arguments = 1
+
+    option_spec = {
+        'class': directives.class_option,
+        'summary-class': directives.class_option,
+    }
+
+    has_content = True
+
+    def run(self):
+        set_classes(self.options)
+        self.assert_has_content()
+
+        text = '\n'.join(self.content)
+        node = details(text, **self.options)
+
+        if self.arguments:
+            summary_node = summary(self.arguments[0], **self.options)
+            summary_node.source, summary_node.line = self.state_machine.get_source_and_line(self.lineno)
+            node += summary_node
+
+        self.state.nested_parse(self.content, self.content_offset, node)
+        return [node]
+
+def setup(app):
+    app.add_node(details, html=(visit_details_node, depart_details_node))
+    app.add_node(summary, html=(visit_summary_node, depart_summary_node))
+    app.add_directive('details', DetailsDirective)
+
diff --git a/docs/extensions/exception_hierarchy.py b/docs/extensions/exception_hierarchy.py
new file mode 100644
index 00000000..cc69a7ce
--- /dev/null
+++ b/docs/extensions/exception_hierarchy.py
@@ -0,0 +1,27 @@
+from docutils.parsers.rst import Directive
+from docutils.parsers.rst import states, directives
+from docutils.parsers.rst.roles import set_classes
+from docutils import nodes
+from sphinx.locale import _
+
+class exception_hierarchy(nodes.General, nodes.Element):
+    pass
+
+def visit_exception_hierarchy_node(self, node):
+    self.body.append(self.starttag(node, 'div', CLASS='exception-hierarchy-content'))
+
+def depart_exception_hierarchy_node(self, node):
+    self.body.append('</div>\n')
+
+class ExceptionHierarchyDirective(Directive):
+    has_content = True
+
+    def run(self):
+        self.assert_has_content()
+        node = exception_hierarchy('\n'.join(self.content))
+        self.state.nested_parse(self.content, self.content_offset, node)
+        return [node]
+
+def setup(app):
+    app.add_node(exception_hierarchy, html=(visit_exception_hierarchy_node, depart_exception_hierarchy_node))
+    app.add_directive('exception_hierarchy', ExceptionHierarchyDirective)
diff --git a/docs/extensions/experimental_feature.py b/docs/extensions/experimental_feature.py
new file mode 100644
index 00000000..78ffd9c4
--- /dev/null
+++ b/docs/extensions/experimental_feature.py
@@ -0,0 +1,52 @@
+from __future__ import annotations
+
+from typing import TYPE_CHECKING
+
+if TYPE_CHECKING:
+    from sphinx.application import Sphinx as SphinxApp
+
+from sphinx.util.docutils import SphinxDirective
+from sphinx.locale import _
+from docutils import nodes
+from sphinx import addnodes
+
+
+# A custom rst directive for sphinx that adds an admonition info, that this is an experimental discord feature and may be removed at any time
+# This can also take an optional link to the support article for the feature that will be added to the warning
+# Usage:
+# .. experiment:: [title]
+#    :article: [link-or-article-id]
+
+class ExperimentalFeatureDirective(SphinxDirective):
+    has_content = False
+    required_arguments = 0
+    optional_arguments = 40
+    option_spec = {
+        'article': str,
+    }
+
+    def run(self):
+        title = ' '.join(self.arguments) if self.arguments else None
+        title = f'Experimental Discord Feature - {title}' if title else 'Experimental Discord Feature'
+        link_or_article_id = self.options.get('article', None)
+        if link_or_article_id and not link_or_article_id.startswith('https://'):
+            link = f'https://support.discord.com/hc/en-us/articles/{link_or_article_id}'
+        else:
+            link = link_or_article_id
+
+        node = nodes.admonition(classes=['admonition', 'experimental'])
+        node.document = self.state.document
+        node += nodes.title(title, title)
+        node += nodes.paragraph(text=_('This is an experimental feature and may be removed at any time.'))
+        if link:
+            ref = nodes.reference('', '', internal=False, refuri=link, anchorname='sus', *[nodes.Text(_('support article'))])
+            node += nodes.paragraph(
+                '',
+                _('For more information, take a look at the '),
+                *[addnodes.compact_paragraph('', '', ref)]
+            )
+
+        return [node]
+
+def setup(app: SphinxApp):
+    app.add_directive('experiment', ExperimentalFeatureDirective)
diff --git a/docs/extensions/keyboard_buttons.py b/docs/extensions/keyboard_buttons.py
new file mode 100644
index 00000000..2a57ca1d
--- /dev/null
+++ b/docs/extensions/keyboard_buttons.py
@@ -0,0 +1,63 @@
+#  The MIT License (MIT)
+#
+#  Copyright (c) 2015-2021 Rapptz & (c) 2021-present mccoderpy
+#
+#  Permission is hereby granted, free of charge, to any person obtaining a
+#  copy of this software and associated documentation files (the "Software"),
+#  to deal in the Software without restriction, including without limitation
+#  the rights to use, copy, modify, merge, publish, distribute, sublicense,
+#  and/or sell copies of the Software, and to permit persons to whom the
+#  Software is furnished to do so, subject to the following conditions:
+#
+#  The above copyright notice and this permission notice shall be included in
+#  all copies or substantial portions of the Software.
+#
+#  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+#  OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+#  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+#  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+#  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+#  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+#  DEALINGS IN THE SOFTWARE.
+
+# Credit to sphinx.ext.extlinks for being a good starter
+# Copyright 2007-2020 by the Sphinx team
+# Licensed under BSD.
+
+from typing import Any, Dict, List, Tuple
+
+from docutils import nodes, utils
+from docutils.nodes import Node, system_message
+from docutils.parsers.rst.states import Inliner
+
+import sphinx
+from sphinx.application import Sphinx
+from sphinx.util.nodes import split_explicit_title
+from sphinx.util.typing import RoleFunction
+
+
+# A custom sphinx role that renders as a html element for a keyboard button using the "key" class
+# Usage:
+# :key:`<title>`
+
+def make_key_role(
+        typ: str,
+        rawtext: str,
+        text: str,
+        lineno: int,
+        inliner: Inliner,
+        options: Dict = {},
+        content: List[str] = []
+    ) -> Tuple[List[Node], List[system_message]]:
+
+        text = utils.unescape(text)
+        has_explicit_title, title, key = split_explicit_title(text)
+        # TODO: Add support for multiple keys in one role (e.g. :key:`Ctrl`+`C`)
+        # TODO: Add support for keys that work as an button
+        pnode = nodes.inline('', '', nodes.inline(title, title, classes=['key']), classes=['key-combo'])
+        return [pnode], []
+
+
+def setup(app: Sphinx) -> Dict[str, Any]:
+    app.add_role('key', make_key_role)
+    return {'version': sphinx.__display_version__, 'parallel_read_safe': True}
\ No newline at end of file
diff --git a/docs/extensions/operations.py b/docs/extensions/operations.py
new file mode 100644
index 00000000..778f427d
--- /dev/null
+++ b/docs/extensions/operations.py
@@ -0,0 +1,139 @@
+# A Sphinx extension that looks up for operation implementations like __iter__, __lt__, __eq__, etc.
+# and adds them to the class documentation as a container table
+from __future__ import annotations
+
+import inspect
+from typing import Any, List, Dict, TYPE_CHECKING
+
+
+if TYPE_CHECKING:
+    from sphinx.application import Sphinx as SphinxApp
+
+# This is a mapping of all the magic methods to a string that will be used to display them in the table
+method_operator_map = {
+    '__lt__': 'x < y',
+    '__le__': 'x <= y',
+    '__eq__': 'x == y',
+    '__ne__': 'x != y',
+    '__gt__': 'x > y',
+    '__ge__': 'x >= y',
+    '__add__': 'x + y',
+    '__sub__': 'x - y',
+    '__mul__': 'x * y',
+    '__matmul__': 'x @ y',
+    '__truediv__': 'x / y',
+    '__floordiv__': 'x // y',
+    '__mod__': 'x % y',
+    '__divmod__': 'divmod(x, y)',
+    '__pow__': 'x ** y',
+    '__lshift__': 'x << y',
+    '__rshift__': 'x >> y',
+    '__and__': 'x & y',
+    '__xor__': 'x ^ y',
+    '__or__': 'x | y',
+    '__radd__': 'y + x',
+    '__rsub__': 'y - x',
+    '__rmul__': 'y * x',
+    '__rmatmul__': 'y @ x',
+    '__rtruediv__': 'y / x',
+    '__rfloordiv__': 'y // x',
+    '__rmod__': 'y % x',
+    '__rdivmod__': 'divmod(y, x)',
+    '__rpow__': 'y ** x',
+    '__rlshift__': 'y << x',
+    '__rrshift__': 'y >> x',
+    '__rand__': 'y & x',
+    '__rxor__': 'y ^ x',
+    '__ror__': 'y | x',
+    '__iadd__': 'x += y',
+    '__isub__': 'x -= y',
+    '__imul__': 'x *= y',
+    '__imatmul__': 'x @= y',
+    '__itruediv__': 'x /= y',
+    '__ifloordiv__': 'x //= y',
+    '__imod__': 'x %= y',
+    '__ipow__': 'x **= y',
+    '__ilshift__': 'x <<= y',
+    '__irshift__': 'x >>= y',
+    '__iand__': 'x &= y',
+    '__ixor__': 'x ^= y',
+    '__ior__': 'x |= y',
+    '__neg__': '-x',
+    '__pos__': '+x',
+    '__abs__': 'abs(x)',
+    '__invert__': '~x',
+    '__complex__': 'complex(x)',
+    '__int__': 'int(x)',
+    '__float__': 'float(x)',
+    '__round__': 'round(x)',
+    '__index__': 'operator.index(x)',
+    '__trunc__': 'math.trunc(x)',
+    '__floor__': 'math.floor(x)',
+    '__ceil__': 'math.ceil(x)',
+    '__enter__': 'with x as y: ...',
+    '__await__': 'await x',
+    '__aiter__': 'aiter(x) - (async for ... in x: ...)',
+    '__anext__': 'await next(x)',
+    '__aenter__': 'async with x as y: ...',
+    '__call__': 'x()',
+    '__len__': 'len(x)',
+    '__length_hint__': 'operator.length_hint(x)',
+    '__getitem__': 'x[y]',
+    '__missing__': 'x[y]',
+    '__setitem__': 'x[y] = z',
+    '__delitem__': 'del x[y]',
+    '__contains__': 'y in x',
+    '__iter__': 'iter(x) - (for ... in x: ...)',
+    '__reversed__': 'reversed(x)',
+    '__next__': 'next(x)',
+}
+
+
+def handle_processed_docstring(
+        app: SphinxApp,
+        what: str,
+        name: str,
+        obj: object,
+        options: Dict[str, Any],
+        lines: List[str]
+) -> List[str]:
+    if what != 'class':
+        return lines
+
+    container_items = []
+    if container_not_present := ('.. container:: operations' not in lines):
+        # operations container not present yet? So we don't need to check for duplicates
+        check = lambda n, v: v.__doc__ and inspect.isfunction(v) and n in method_operator_map
+    else:
+        check = lambda n, v: v.__doc__ and inspect.isfunction(v) and n in method_operator_map \
+                          and f'    .. describe:: {method_operator_map[n]}' not in lines
+
+    for f_name, special_method in (
+            special_methods := sorted(
+                filter(
+                    lambda x: check(x[0], x[1]),
+                    inspect.getmembers(obj)
+                ),
+                key=lambda x: list(method_operator_map).index(x[0]) if x[0] in method_operator_map else -1
+            )):
+        container_items.extend(
+            [
+                f'    .. describe:: {method_operator_map[f_name]}',
+                '',
+                *[f'        {line.lstrip()}' for line in special_method.__doc__.lstrip().splitlines()]
+            ]
+        )
+
+    if container_items:
+        if container_not_present:
+            print(f'Creating supported operations container with {len(special_methods)} entries for class {name}')
+            lines.extend(['', '.. container:: operations', ''])
+        else:
+            print(f'Updating supported operations container with {len(special_methods)} entries for class {name}')
+        lines.extend(container_items)
+
+    return lines
+
+
+def setup(app: SphinxApp):
+    app.connect('autodoc-process-docstring', handle_processed_docstring)
diff --git a/docs/extensions/resourcelinks.py b/docs/extensions/resourcelinks.py
new file mode 100644
index 00000000..f2e13298
--- /dev/null
+++ b/docs/extensions/resourcelinks.py
@@ -0,0 +1,44 @@
+# Credit to sphinx.ext.extlinks for being a good starter
+# Copyright 2007-2020 by the Sphinx team
+# Licensed under BSD.
+
+from typing import Any, Dict, List, Tuple
+
+from docutils import nodes, utils
+from docutils.nodes import Node, system_message
+from docutils.parsers.rst.states import Inliner
+
+import sphinx
+from sphinx.application import Sphinx
+from sphinx.util.nodes import split_explicit_title
+from sphinx.util.typing import RoleFunction
+
+
+def make_link_role(resource_links: Dict[str, str]) -> RoleFunction:
+    def role(
+        typ: str,
+        rawtext: str,
+        text: str,
+        lineno: int,
+        inliner: Inliner,
+        options: Dict = {},
+        content: List[str] = []
+    ) -> Tuple[List[Node], List[system_message]]:
+
+        text = utils.unescape(text)
+        has_explicit_title, title, key = split_explicit_title(text)
+        full_url = resource_links[key]
+        if not has_explicit_title:
+            title = full_url
+        pnode = nodes.reference(title, title, internal=False, refuri=full_url)
+        return [pnode], []
+    return role
+
+
+def add_link_role(app: Sphinx) -> None:
+    app.add_role('resource', make_link_role(app.config.resource_links))
+
+def setup(app: Sphinx) -> Dict[str, Any]:
+    app.add_config_value('resource_links', {}, 'env')
+    app.connect('builder-inited', add_link_role)
+    return {'version': sphinx.__display_version__, 'parallel_read_safe': True}
diff --git a/docs/faq.rst b/docs/faq.rst
new file mode 100644
index 00000000..869635bd
--- /dev/null
+++ b/docs/faq.rst
@@ -0,0 +1,410 @@
+.. currentmodule:: discord
+.. _faq:
+
+Frequently Asked Questions
+===========================
+
+This is a list of Frequently Asked Questions regarding using ``discord.py`` and its extension modules. Feel free to suggest a
+new question or submit one via pull requests.
+
+.. contents:: Questions
+    :local:
+
+Coroutines
+------------
+
+Questions regarding coroutines and asyncio belong here.
+
+What is a coroutine?
+~~~~~~~~~~~~~~~~~~~~~~
+
+A |coroutine_link|_ is a function that must be invoked with ``await`` or ``yield from``. When Python encounters an ``await`` it stops
+the function's execution at that point and works on other things until it comes back to that point and finishes off its work.
+This allows for your program to be doing multiple things at the same time without using threads or complicated
+multiprocessing.
+
+**If you forget to await a coroutine then the coroutine will not run. Never forget to await a coroutine.**
+
+Where can I use ``await``\?
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can only use ``await`` inside ``async def`` functions and nowhere else.
+
+What does "blocking" mean?
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+In asynchronous programming a blocking call is essentially all the parts of the function that are not ``await``. Do not
+despair however, because not all forms of blocking are bad! Using blocking calls is inevitable, but you must work to make
+sure that you don't excessively block functions. Remember, if you block for too long then your bot will freeze since it has
+not stopped the function's execution at that point to do other things.
+
+If logging is enabled, this library will attempt to warn you that blocking is occurring with the message:
+``Heartbeat blocked for more than N seconds.``
+See :ref:`logging_setup` for details on enabling logging.
+
+A common source of blocking for too long is something like :func:`time.sleep`. Don't do that. Use :func:`asyncio.sleep`
+instead. Similar to this example: ::
+
+    # bad
+    time.sleep(10)
+
+    # good
+    await asyncio.sleep(10)
+
+Another common source of blocking for too long is using HTTP requests with the famous module :doc:`req:index`.
+While :doc:`req:index` is an amazing module for non-asynchronous programming, it is not a good choice for
+:mod:`asyncio` because certain requests can block the event loop too long. Instead, use the :doc:`aiohttp <aio:index>` library which
+is installed on the side with this library.
+
+Consider the following example: ::
+
+    # bad
+    r = requests.get('http://aws.random.cat/meow')
+    if r.status_code == 200:
+        js = r.json()
+        await channel.send(js['file'])
+
+    # good
+    async with aiohttp.ClientSession() as session:
+        async with session.get('http://aws.random.cat/meow') as r:
+            if r.status == 200:
+                js = await r.json()
+                await channel.send(js['file'])
+
+General
+---------
+
+General questions regarding library usage belong here.
+
+Where can I find usage examples?
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Example code can be found in the `examples folder <https://github.com/mccoderpy/discord.py-message-components/tree/developer/examples>`_
+in the repository.
+
+How do I set the "Playing" status?
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The ``activity`` keyword argument may be passed in the :class:`Client` constructor or :meth:`Client.change_presence`, given an :class:`Activity` object.
+
+The constructor may be used for static activities, while :meth:`Client.change_presence` may be used to update the activity at runtime.
+
+.. warning::
+
+    It is highly discouraged to use :meth:`Client.change_presence` or API calls in :func:`on_ready` as this event may be called many times while running, not just once.
+
+    There is a high chance of disconnecting if presences are changed right after connecting.
+
+The status type (playing, listening, streaming, watching) can be set using the :class:`ActivityType` enum.
+For memory optimisation purposes, some activities are offered in slimmed down versions:
+
+- :class:`Game`
+- :class:`Streaming`
+
+Putting both of these pieces of info together, you get the following: ::
+
+    client = discord.Client(activity=discord.Game(name='my game'))
+
+    # or, for watching:
+    activity = discord.Activity(name='my activity', type=discord.ActivityType.watching)
+    client = discord.Client(activity=activity)
+
+How do I send a message to a specific channel?
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You must fetch the channel directly and then call the appropriate method. Example: ::
+
+    channel = client.get_channel(12324234183172)
+    await channel.send('hello')
+
+How do I send a DM?
+~~~~~~~~~~~~~~~~~~~
+
+Get the :class:`User` or :class:`Member` object and call :meth:`abc.Messageable.send`. For example: ::
+
+    user = client.get_user(381870129706958858)
+    await user.send('👀')
+
+If you are responding to an event, such as :func:`on_message`, you already have the :class:`User` object via :attr:`Message.author`: ::
+
+    await message.author.send('👋')
+
+How do I get the ID of a sent message?
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+:meth:`abc.Messageable.send` returns the :class:`Message` that was sent.
+The ID of a message can be accessed via :attr:`Message.id`: ::
+
+    message = await channel.send('hmm…')
+    message_id = message.id
+
+How do I upload an image?
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+To upload something to Discord you have to use the :class:`File` object.
+
+A :class:`File` accepts two parameters, the file-like object (or file path) and the filename
+to pass to Discord when uploading.
+
+If you want to upload an image it's as simple as: ::
+
+    await channel.send(file=discord.File('my_file.png'))
+
+If you have a file-like object you can do as follows: ::
+
+    with open('my_file.png', 'rb') as fp:
+        await channel.send(file=discord.File(fp, 'new_filename.png'))
+
+To upload multiple files, you can use the ``files`` keyword argument instead of ``file``\: ::
+
+    my_files = [
+        discord.File('result.zip'),
+        discord.File('teaser_graph.png'),
+    ]
+    await channel.send(files=my_files)
+
+If you want to upload something from a URL, you will have to use an HTTP request using :doc:`aiohttp <aio:index>`
+and then pass an :class:`io.BytesIO` instance to :class:`File` like so:
+
+.. code-block:: python3
+
+    import io
+    import aiohttp
+
+    async with aiohttp.ClientSession() as session:
+        async with session.get(my_url) as resp:
+            if resp.status != 200:
+                return await channel.send('Could not download file...')
+            data = io.BytesIO(await resp.read())
+            await channel.send(file=discord.File(data, 'cool_image.png'))
+
+
+How can I add a reaction to a message?
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You use the :meth:`Message.add_reaction` method.
+
+If you want to use unicode emoji, you must pass a valid unicode code point in a string. In your code, you can write this in a few different ways:
+
+- ``'👍'``
+- ``'\U0001F44D'``
+- ``'\N{THUMBS UP SIGN}'``
+
+Quick example: ::
+
+    emoji = '\N{THUMBS UP SIGN}'
+    # or '\U0001f44d' or '👍'
+    await message.add_reaction(emoji)
+
+In case you want to use emoji that come from a message, you already get their code points in the content without needing
+to do anything special. You **cannot** send ``':thumbsup:'`` style shorthands.
+
+For custom emoji, you should pass an instance of :class:`Emoji`. You can also pass a ``'<:name:id>'`` string, but if you
+can use said emoji, you should be able to use :meth:`Client.get_emoji` to get an emoji via ID or use :func:`utils.find`/
+:func:`utils.get` on :attr:`Client.emojis` or :attr:`Guild.emojis` collections.
+
+The name and ID of a custom emoji can be found with the client by prefixing ``:custom_emoji:`` with a backslash.
+For example, sending the message ``\:python3:`` with the client will result in ``<:python3:232720527448342530>``.
+
+Quick example: ::
+
+
+    # if you have the ID already
+    emoji = client.get_emoji(310177266011340803)
+    await message.add_reaction(emoji)
+
+    # no ID, do a lookup
+    emoji = discord.utils.get(guild.emojis, name='LUL')
+    if emoji:
+        await message.add_reaction(emoji)
+
+    # if you have the name and ID of a custom emoji:
+    emoji = '<:python3:232720527448342530>'
+    await message.add_reaction(emoji)
+
+How do I pass a coroutine to the player's "after" function?
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The library's music player launches on a separate thread, ergo it does not execute inside a coroutine.
+This does not mean that it is not possible to call a coroutine in the ``after`` parameter. To do so you must pass a callable
+that wraps up a couple of aspects.
+
+The first gotcha that you must be aware of is that calling a coroutine is not a thread-safe operation. Since we are
+technically in another thread, we must take caution in calling thread-safe operations so things do not bug out. Luckily for
+us, :mod:`asyncio` comes with a :func:`asyncio.run_coroutine_threadsafe` function that allows us to call
+a coroutine from another thread.
+
+However, this function returns a :class:`~concurrent.futures.Future` and to actually call it we have to fetch its result. Putting all of
+this together we can do the following: ::
+
+    def my_after(error):
+        coro = some_channel.send('Song is done!')
+        fut = asyncio.run_coroutine_threadsafe(coro, client.loop)
+        try:
+            fut.result()
+        except:
+            # an error happened sending the message
+            pass
+
+    voice.play(discord.FFmpegPCMAudio(url), after=my_after)
+
+How do I run something in the background?
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`Check the background_task.py example. <https://github.com/Rapptz/discord.py/blob/master/examples/background_task.py>`_
+
+How do I get a specific model?
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+There are multiple ways of doing this. If you have a specific model's ID then you can use
+one of the following functions:
+
+- :meth:`Client.get_channel`
+- :meth:`Client.get_guild`
+- :meth:`Client.get_user`
+- :meth:`Client.get_emoji`
+- :meth:`Guild.get_member`
+- :meth:`Guild.get_channel`
+- :meth:`Guild.get_role`
+
+The following use an HTTP request:
+
+- :meth:`abc.Messageable.fetch_message`
+- :meth:`Client.fetch_user`
+- :meth:`Client.fetch_guilds`
+- :meth:`Client.fetch_guild`
+- :meth:`Guild.fetch_emoji`
+- :meth:`Guild.fetch_emojis`
+- :meth:`Guild.fetch_member`
+
+
+If the functions above do not help you, then use of :func:`utils.find` or :func:`utils.get` would serve some use in finding
+specific models.
+
+Quick example: ::
+
+    # find a guild by name
+    guild = discord.utils.get(client.guilds, name='My Server')
+
+    # make sure to check if it's found
+    if guild is not None:
+        # find a channel by name
+        channel = discord.utils.get(guild.text_channels, name='cool-channel')
+
+How do I make a web request?
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+To make a request, you should use a non-blocking library.
+This library already uses and requires a 3rd party library for making requests, :doc:`aiohttp <aio:index>`.
+
+Quick example: ::
+
+    async with aiohttp.ClientSession() as session:
+        async with session.get('http://aws.random.cat/meow') as r:
+            if r.status == 200:
+                js = await r.json()
+
+See `aiohttp's full documentation <http://aiohttp.readthedocs.io/en/stable/>`_ for more information.
+
+How do I use a local image file for an embed image?
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Discord special-cases uploading an image attachment and using it within an embed so that it will not
+display separately, but instead in the embed's thumbnail, image, footer or author icon.
+
+To do so, upload the image normally with :meth:`abc.Messageable.send`,
+and set the embed's image URL to ``attachment://image.png``,
+where ``image.png`` is the filename of the image you will send.
+
+
+Quick example: ::
+
+    file = discord.File("path/to/my/image.png", filename="image.png")
+    embed = discord.Embed()
+    embed.set_image(url="attachment://image.png")
+    await channel.send(file=file, embed=embed)
+
+.. note ::
+
+    Due to a Discord limitation, filenames may not include underscores.
+
+Is there an event for audit log entries being created?
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Since Discord does not dispatch this information in the gateway, the library cannot provide this information.
+This is currently a Discord limitation.
+
+Commands Extension
+-------------------
+
+Questions regarding ``discord.ext.commands`` belong here.
+
+Why does ``on_message`` make my commands stop working?
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Overriding the default provided ``on_message`` forbids any extra commands from running. To fix this, add a
+``bot.process_commands(message)`` line at the end of your ``on_message``. For example: ::
+
+    @bot.event
+    async def on_message(message):
+        # do some extra stuff here
+
+        await bot.process_commands(message)
+
+Alternatively, you can place your ``on_message`` logic into a **listener**. In this setup, you should not
+manually call ``bot.process_commands()``. This also allows you to do multiple things asynchronously in response
+to a message. Example::
+
+    @bot.listen('on_message')
+    async def whatever_you_want_to_call_it(message):
+        # do stuff here
+        # do not process commands here
+
+Why do my arguments require quotes?
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+In a simple command defined as: ::
+
+    @bot.command()
+    async def echo(ctx, message: str):
+        await ctx.send(message)
+
+Calling it via ``?echo a b c`` will only fetch the first argument and disregard the rest. To fix this you should either call
+it via ``?echo "a b c"`` or change the signature to have "consume rest" behaviour. Example: ::
+
+    @bot.command()
+    async def echo(ctx, *, message: str):
+        await ctx.send(message)
+
+This will allow you to use ``?echo a b c`` without needing the quotes.
+
+How do I get the original ``message``\?
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The :class:`~ext.commands.Context` contains an attribute, :attr:`~.Context.message` to get the original
+message.
+
+Example: ::
+
+    @bot.command()
+    async def length(ctx):
+        await ctx.send('Your message is {} characters long.'.format(len(ctx.message.content)))
+
+How do I make a subcommand?
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Use the :func:`~ext.commands.group` decorator. This will transform the callback into a :class:`~ext.commands.Group` which will allow you to add commands into
+the group operating as "subcommands". These groups can be arbitrarily nested as well.
+
+Example: ::
+
+    @bot.group()
+    async def git(ctx):
+        if ctx.invoked_subcommand is None:
+            await ctx.send('Invalid git command passed...')
+
+    @git.command()
+    async def push(ctx, remote: str, branch: str):
+        await ctx.send('Pushing to {} {}'.format(remote, branch))
+
+This could then be used as ``?git push origin master``.
diff --git a/docs/images/banner_dark.png b/docs/images/banner_dark.png
new file mode 100644
index 00000000..4e2c1e73
Binary files /dev/null and b/docs/images/banner_dark.png differ
diff --git a/docs/images/banner_light.png b/docs/images/banner_light.png
new file mode 100644
index 00000000..ac70720b
Binary files /dev/null and b/docs/images/banner_light.png differ
diff --git a/docs/images/commands/greedy1.png b/docs/images/commands/greedy1.png
new file mode 100644
index 00000000..dcad81a5
Binary files /dev/null and b/docs/images/commands/greedy1.png differ
diff --git a/docs/images/commands/keyword1.png b/docs/images/commands/keyword1.png
new file mode 100644
index 00000000..d9f95234
Binary files /dev/null and b/docs/images/commands/keyword1.png differ
diff --git a/docs/images/commands/keyword2.png b/docs/images/commands/keyword2.png
new file mode 100644
index 00000000..40ce6764
Binary files /dev/null and b/docs/images/commands/keyword2.png differ
diff --git a/docs/images/commands/optional1.png b/docs/images/commands/optional1.png
new file mode 100644
index 00000000..7ae5b7a6
Binary files /dev/null and b/docs/images/commands/optional1.png differ
diff --git a/docs/images/commands/positional1.png b/docs/images/commands/positional1.png
new file mode 100644
index 00000000..a911be79
Binary files /dev/null and b/docs/images/commands/positional1.png differ
diff --git a/docs/images/commands/positional2.png b/docs/images/commands/positional2.png
new file mode 100644
index 00000000..7e1099fc
Binary files /dev/null and b/docs/images/commands/positional2.png differ
diff --git a/docs/images/commands/positional3.png b/docs/images/commands/positional3.png
new file mode 100644
index 00000000..8da621e4
Binary files /dev/null and b/docs/images/commands/positional3.png differ
diff --git a/docs/images/commands/variable1.png b/docs/images/commands/variable1.png
new file mode 100644
index 00000000..4738368d
Binary files /dev/null and b/docs/images/commands/variable1.png differ
diff --git a/docs/images/commands/variable2.png b/docs/images/commands/variable2.png
new file mode 100644
index 00000000..512cc6d3
Binary files /dev/null and b/docs/images/commands/variable2.png differ
diff --git a/docs/images/commands/variable3.png b/docs/images/commands/variable3.png
new file mode 100644
index 00000000..0b740c4e
Binary files /dev/null and b/docs/images/commands/variable3.png differ
diff --git a/docs/images/discord4py-logo.png b/docs/images/discord4py-logo.png
new file mode 100644
index 00000000..1a26f7f4
Binary files /dev/null and b/docs/images/discord4py-logo.png differ
diff --git a/docs/images/discord_bot_tab.png b/docs/images/discord_bot_tab.png
new file mode 100644
index 00000000..83568244
Binary files /dev/null and b/docs/images/discord_bot_tab.png differ
diff --git a/docs/images/discord_bot_user_options.png b/docs/images/discord_bot_user_options.png
new file mode 100644
index 00000000..4091bd88
Binary files /dev/null and b/docs/images/discord_bot_user_options.png differ
diff --git a/docs/images/discord_create_app_button.png b/docs/images/discord_create_app_button.png
new file mode 100644
index 00000000..ddbef4e6
Binary files /dev/null and b/docs/images/discord_create_app_button.png differ
diff --git a/docs/images/discord_create_app_form.png b/docs/images/discord_create_app_form.png
new file mode 100644
index 00000000..e7f8510c
Binary files /dev/null and b/docs/images/discord_create_app_form.png differ
diff --git a/docs/images/discord_create_bot_user.png b/docs/images/discord_create_bot_user.png
new file mode 100644
index 00000000..2d0a3a03
Binary files /dev/null and b/docs/images/discord_create_bot_user.png differ
diff --git a/docs/images/discord_oauth2.png b/docs/images/discord_oauth2.png
new file mode 100644
index 00000000..f32fcc7b
Binary files /dev/null and b/docs/images/discord_oauth2.png differ
diff --git a/docs/images/discord_oauth2_perms.png b/docs/images/discord_oauth2_perms.png
new file mode 100644
index 00000000..0e6df51b
Binary files /dev/null and b/docs/images/discord_oauth2_perms.png differ
diff --git a/docs/images/discord_oauth2_scope.png b/docs/images/discord_oauth2_scope.png
new file mode 100644
index 00000000..9e2cdeff
Binary files /dev/null and b/docs/images/discord_oauth2_scope.png differ
diff --git a/docs/images/discord_privileged_intents.png b/docs/images/discord_privileged_intents.png
new file mode 100644
index 00000000..297eabbb
Binary files /dev/null and b/docs/images/discord_privileged_intents.png differ
diff --git a/docs/images/discord_py_message_components_logo.ico b/docs/images/discord_py_message_components_logo.ico
new file mode 100644
index 00000000..bc6bff1c
Binary files /dev/null and b/docs/images/discord_py_message_components_logo.ico differ
diff --git a/docs/images/drop_down_icon.svg b/docs/images/drop_down_icon.svg
new file mode 100644
index 00000000..e7edbba3
--- /dev/null
+++ b/docs/images/drop_down_icon.svg
@@ -0,0 +1,4 @@
+<svg fill='white' height='24' viewBox='0 0 24 24' width='24' xmlns='http://www.w3.org/2000/svg'>
+    <path d='M7 10l5 5 5-5z'/>
+    <path d='M0 0h24v24H0z' fill='none'/>
+</svg>
diff --git a/docs/images/favicon.ico b/docs/images/favicon.ico
new file mode 100644
index 00000000..d247ec05
Binary files /dev/null and b/docs/images/favicon.ico differ
diff --git a/docs/images/flag_ua.png b/docs/images/flag_ua.png
new file mode 100644
index 00000000..67a8b431
Binary files /dev/null and b/docs/images/flag_ua.png differ
diff --git a/docs/images/snake.svg b/docs/images/snake.svg
new file mode 100644
index 00000000..aa741440
--- /dev/null
+++ b/docs/images/snake.svg
@@ -0,0 +1,17 @@
+<svg style="width: 100%; height: 100%" 
+    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1036 597.33331" height="597.333" width="1036">
+    <path d="M498.46 84.248c-1.6 1.665-2.4 3.597-2.4 5.93 0 2.333.8 4.265 2.4 5.863 1.667 1.67 3.6 2.47 5.932 2.47 2.332 0 4.265-.8 5.864-2.46 1.665-1.59 2.465-3.53 2.465-5.86 0-2.33-.8-4.26-2.46-5.93-1.6-1.6-3.53-2.4-5.86-2.4s-4.26.8-5.93 2.4m-9.06 5.93c0-2.33-.8-4.26-2.46-5.93-1.6-1.6-3.53-2.4-5.862-2.4s-4.265.8-5.93 2.4c-1.6 1.67-2.4 3.6-2.4 5.93 0 2.33.8 4.27 2.4 5.86 1.665 1.67 3.598 2.47 5.93 2.47s4.265-.8 5.864-2.46c1.663-1.593 2.463-3.53 2.463-5.86m46.647 0c0-2.333-.8-4.27-2.467-5.93-1.6-1.6-3.53-2.4-5.86-2.4s-4.265.8-5.93 2.4c-1.6 1.665-2.4 3.597-2.4 5.93 0 2.333.8 4.265 2.4 5.863 1.665 1.67 3.598 2.467 5.93 2.467s4.265-.8 5.864-2.468c1.667-1.598 2.467-3.53 2.467-5.86" fill="#e0e0e0"/>
+    <path d="M2748.2-850.22H155.382c-76.964 0-115.447-48.474-115.447-144.932V-4303.65c0-96.45 38.483-144.93 115.447-144.93H6321.57c76.97 0 115.45 48.48 115.45 144.93v3308.498c0 96.458-38.48 144.933-115.45 144.933H3737.75" fill="none" stroke="#e0e0e0" stroke-width="79.964" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" transform="matrix(.13334 0 0 .13333 0 597.333)"/>
+    <path d="M4177.05-3798.87v2178.5H998.996v-2178.5c0-133.44 66.474-199.91 199.914-199.91h2778.23c133.44 0 199.91 66.47 199.91 199.91z" fill="none" stroke="#e0e0e0" stroke-width="79.964" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" transform="matrix(.13334 0 0 .13333 0 597.333)"/>
+    <path d="M6274.1-4181.2v2844.7c0 82.97-36.49 124.45-108.95 124.45H322.307c-72.47 0-108.952-41.48-108.952-124.45v-2844.7c0-82.96 36.483-124.44 108.952-124.44H6165.15c72.46 0 108.95 41.48 108.95 124.44zM449.25-41.084h147.43m182.418 0h339.842m1407.86 0c0-91.458 46.98-151.43 140.94-179.92 23.99-7.497 50.97-12.493 80.46-15.993m0 0c24.49-2.497 51.48-3.997 79.96-3.997h820.63c32.49 0 61.97 2 88.96 5.497M1348.84-41.084H2526.8m221.4-195.913V-850.22m989.55 614.723c26.49 3 49.98 7.996 71.47 14.493 93.96 28.49 140.93 88.462 140.93 179.92m2024.08 0h50.98m-468.28 0h219.89m-1826.67 0h1416.86M3737.75-235.497V-850.22m212.4 809.136H2526.8M3737.75-850.22H2748.2" fill="none" stroke="#e0e0e0" stroke-width="79.964" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" transform="matrix(.13334 0 0 .13333 0 597.333)"/>
+    <path d="M2126.79-2789.58c-38.13 38.49-57.37 85.01-57.37 139.59 0 54.22 19.24 100.75 57.37 139.23 38.48 38.48 85.01 57.73 139.59 57.73 54.22 0 100.75-19.25 139.23-57.73 38.49-38.48 57.73-85.01 57.73-139.23 0-54.58-19.24-101.1-57.73-139.59-38.48-38.13-85.01-57.37-139.23-57.37-54.58 0-101.11 19.24-139.59 57.37z" fill="none" stroke="#e0e0e0" stroke-width="69.967" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" transform="matrix(.13334 0 0 .13333 0 597.333)"/>
+    <path d="M2640.7-3448.32c-286.51-11.2-546.09 38.83-778.73 150.43 143.08-106.7 307.5-172.47 493.27-197.66-6.3-14.34-18.9-29.04-38.13-43.73h-62.98c-210.25 36.73-380.62 103.9-511.11 201.16-197.66 325.7-291.76 678.68-281.62 1058.6 142.39 189.97 349.49 279.53 621.31 267.98l122.45-129.44c-148.68-52.82-255.03-123.49-318.7-212 214.1 133.99 465.63 199.41 754.24 196.26" fill="none" stroke="#e0e0e0" stroke-width="69.967" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" transform="matrix(.13334 0 0 .13333 0 597.333)"/>
+    <path d="M-3149.74-2789.58c-38.13 38.49-57.37 85.01-57.37 139.59 0 54.22 19.24 100.75 57.37 139.23 38.49 38.48 85.01 57.73 139.59 57.73 54.22 0 100.75-19.25 139.23-57.73 38.49-38.48 57.73-85.01 57.73-139.23 0-54.58-19.24-101.1-57.73-139.59-38.48-38.13-85.01-57.37-139.23-57.37-54.58 0-101.1 19.24-139.59 57.37z" fill="none" stroke="#e0e0e0" stroke-width="69.967" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" transform="matrix(-.13334 0 0 .13333 0 597.333)"/>
+    <path d="M-2635.83-3448.32c-286.51-11.2-546.09 38.83-778.73 150.43 143.08-106.7 307.5-172.47 493.27-197.66-6.3-14.34-18.89-29.04-38.13-43.73h-62.98c-210.25 36.73-380.62 103.9-511.11 201.16-197.66 325.7-291.76 678.68-281.62 1058.6 142.39 189.97 349.49 279.53 621.32 267.98l122.44-129.44c-148.68-52.82-255.03-123.49-318.7-212 214.1 133.99 465.63 199.41 754.24 196.26" fill="none" stroke="#e0e0e0" stroke-width="69.967" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" transform="matrix(-.13334 0 0 .13333 0 597.333)"/>
+    <path d="M474.47 230.785c-17.793 0-26.655 8.863-26.655 26.654v261.2-23.99H207.912h47.98v-58.9 34.91h143.94-47.98v23.99h95.963v-94.88c-.534-16.73-9.396-25.06-26.656-25.06H186.58c-17.792 0-26.656 8.86-26.656 26.65v163.85c0 17.26 8.33 26.12 25.057 26.65h333.8c16.66-.53 24.99-9.39 24.99-26.65V326.74h-34.65c-16.66.667-24.65-7.33-23.99-23.987h300.28c4.2-7.13 6.27-15.126 6.27-23.99v-21.32c0-17.792-8.86-26.655-26.65-26.655zm-13.327 311.842l23.99 22.588-23.99-22.588" fill="#eadc62"/>
+    <path d="M777.616 312.677c3.132-3.132 5.73-6.397 7.796-9.928h-300.28c-.665 16.65 7.33 24.65 23.992 23.98h234.572c13.26 0 24.523-4.67 33.92-14.06" fill="#f2edc8"/>
+    <path d="M3890.68-40.99H1387.32m1971.1-1440.85v-1067.51c0-133.44 66.47-199.91 199.91-199.91h2179.01c133.44 0 199.91 66.47 199.91 199.91v159.93c0 66.47-15.49 126.44-46.98 179.92" fill="none" stroke="#000" stroke-width="79.964" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" transform="matrix(.13334 0 0 .13333 0 597.333)"/>
+    <path d="M5890.27-2209.5c-15.49 26.48-34.98 50.97-58.47 74.46-70.47 70.47-154.93 105.45-254.39 105.45H4078.1M3358.42-590.243V-770.16m719.68-1259.43h-259.88m-459.8 1259.43v-711.68M3638.3-240.9l-179.92-169.423M4449.93-40.99h-559.25m187.42-1988.6V-240.9c0 129.44-62.48 195.91-187.42 199.91m1007.04 0H4717.8M1559.24-770.16h359.84m4777.83-1259.43l-179.92-179.91m0 0l179.92-179.92M949.022-40.99h438.298M6516.99-2209.5h-626.72m-3971.19 997.54v261.88m0 0v179.92m1079.51-179.92h-359.84m0 0v179.92m-719.67-179.92h719.67m0 179.92h-719.67M1387.32-40.99c-125.44-4-187.91-70.47-187.91-199.91v-1228.94c0-133.44 66.47-199.91 199.9-199.91h1759.2c129.45 0 195.92 62.47 199.91 187.91m-719.67 711.68h719.67" fill="none" stroke="#000" stroke-width="79.964" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" transform="matrix(.13334 0 0 .13333 0 597.333)"/>
+    <path d="M7716.44-2209.5H7356.6m0 539.75l-179.92-179.92m179.92-899.59l-179.92 179.92" fill="none" stroke="#e0e0e0" stroke-width="99.954" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" transform="matrix(.13334 0 0 .13333 0 597.333)"/>
+    <path d="M769.485 258.24c-2.332-2.333-5.13-3.467-8.462-3.467s-6.198 1.134-8.53 3.466c-2.333 2.33-3.466 5.19-3.466 8.52s1.133 6.13 3.466 8.46c2.332 2.33 5.198 3.53 8.53 3.53 3.332 0 6.13-1.2 8.462-3.53 2.334-2.34 3.532-5.13 3.532-8.47 0-3.33-1.198-6.2-3.532-8.53"/>
+</svg>
diff --git a/docs/images/snake_dark.svg b/docs/images/snake_dark.svg
new file mode 100644
index 00000000..12022af4
--- /dev/null
+++ b/docs/images/snake_dark.svg
@@ -0,0 +1,17 @@
+<svg style="width: 100%; height: 100%"
+	xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1036 597.33331" height="597.333" width="1036">
+	<path d="M498.46 84.248c-1.6 1.665-2.4 3.597-2.4 5.93 0 2.333.8 4.265 2.4 5.863 1.667 1.67 3.6 2.47 5.932 2.47 2.332 0 4.265-.8 5.864-2.46 1.665-1.59 2.465-3.53 2.465-5.86 0-2.33-.8-4.26-2.46-5.93-1.6-1.6-3.53-2.4-5.86-2.4s-4.26.8-5.93 2.4m-9.06 5.93c0-2.33-.8-4.26-2.46-5.93-1.6-1.6-3.53-2.4-5.862-2.4s-4.265.8-5.93 2.4c-1.6 1.67-2.4 3.6-2.4 5.93 0 2.33.8 4.27 2.4 5.86 1.665 1.67 3.598 2.47 5.93 2.47s4.265-.8 5.864-2.46c1.663-1.593 2.463-3.53 2.463-5.86m46.647 0c0-2.333-.8-4.27-2.467-5.93-1.6-1.6-3.53-2.4-5.86-2.4s-4.265.8-5.93 2.4c-1.6 1.665-2.4 3.597-2.4 5.93 0 2.333.8 4.265 2.4 5.863 1.665 1.67 3.598 2.467 5.93 2.467s4.265-.8 5.864-2.468c1.667-1.598 2.467-3.53 2.467-5.86" fill="#161616"/>
+	<path d="M2748.2-850.22H155.382c-76.964 0-115.447-48.474-115.447-144.932V-4303.65c0-96.45 38.483-144.93 115.447-144.93H6321.57c76.97 0 115.45 48.48 115.45 144.93v3308.498c0 96.458-38.48 144.933-115.45 144.933H3737.75" fill="none" stroke="#161616" stroke-width="79.964" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" transform="matrix(.13334 0 0 .13333 0 597.333)"/>
+	<path d="M4177.05-3798.87v2178.5H998.996v-2178.5c0-133.44 66.474-199.91 199.914-199.91h2778.23c133.44 0 199.91 66.47 199.91 199.91z" fill="none" stroke="#161616" stroke-width="79.964" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" transform="matrix(.13334 0 0 .13333 0 597.333)"/>
+	<path d="M6274.1-4181.2v2844.7c0 82.97-36.49 124.45-108.95 124.45H322.307c-72.47 0-108.952-41.48-108.952-124.45v-2844.7c0-82.96 36.483-124.44 108.952-124.44H6165.15c72.46 0 108.95 41.48 108.95 124.44zM449.25-41.084h147.43m182.418 0h339.842m1407.86 0c0-91.458 46.98-151.43 140.94-179.92 23.99-7.497 50.97-12.493 80.46-15.993m0 0c24.49-2.497 51.48-3.997 79.96-3.997h820.63c32.49 0 61.97 2 88.96 5.497M1348.84-41.084H2526.8m221.4-195.913V-850.22m989.55 614.723c26.49 3 49.98 7.996 71.47 14.493 93.96 28.49 140.93 88.462 140.93 179.92m2024.08 0h50.98m-468.28 0h219.89m-1826.67 0h1416.86M3737.75-235.497V-850.22m212.4 809.136H2526.8M3737.75-850.22H2748.2" fill="none" stroke="#161616" stroke-width="79.964" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" transform="matrix(.13334 0 0 .13333 0 597.333)"/>
+	<path d="M2126.79-2789.58c-38.13 38.49-57.37 85.01-57.37 139.59 0 54.22 19.24 100.75 57.37 139.23 38.48 38.48 85.01 57.73 139.59 57.73 54.22 0 100.75-19.25 139.23-57.73 38.49-38.48 57.73-85.01 57.73-139.23 0-54.58-19.24-101.1-57.73-139.59-38.48-38.13-85.01-57.37-139.23-57.37-54.58 0-101.11 19.24-139.59 57.37z" fill="none" stroke="#161616" stroke-width="69.967" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" transform="matrix(.13334 0 0 .13333 0 597.333)"/>
+	<path d="M2640.7-3448.32c-286.51-11.2-546.09 38.83-778.73 150.43 143.08-106.7 307.5-172.47 493.27-197.66-6.3-14.34-18.9-29.04-38.13-43.73h-62.98c-210.25 36.73-380.62 103.9-511.11 201.16-197.66 325.7-291.76 678.68-281.62 1058.6 142.39 189.97 349.49 279.53 621.31 267.98l122.45-129.44c-148.68-52.82-255.03-123.49-318.7-212 214.1 133.99 465.63 199.41 754.24 196.26" fill="none" stroke="#161616" stroke-width="69.967" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" transform="matrix(.13334 0 0 .13333 0 597.333)"/>
+	<path d="M-3149.74-2789.58c-38.13 38.49-57.37 85.01-57.37 139.59 0 54.22 19.24 100.75 57.37 139.23 38.49 38.48 85.01 57.73 139.59 57.73 54.22 0 100.75-19.25 139.23-57.73 38.49-38.48 57.73-85.01 57.73-139.23 0-54.58-19.24-101.1-57.73-139.59-38.48-38.13-85.01-57.37-139.23-57.37-54.58 0-101.1 19.24-139.59 57.37z" fill="none" stroke="#161616" stroke-width="69.967" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" transform="matrix(-.13334 0 0 .13333 0 597.333)"/>
+	<path d="M-2635.83-3448.32c-286.51-11.2-546.09 38.83-778.73 150.43 143.08-106.7 307.5-172.47 493.27-197.66-6.3-14.34-18.89-29.04-38.13-43.73h-62.98c-210.25 36.73-380.62 103.9-511.11 201.16-197.66 325.7-291.76 678.68-281.62 1058.6 142.39 189.97 349.49 279.53 621.32 267.98l122.44-129.44c-148.68-52.82-255.03-123.49-318.7-212 214.1 133.99 465.63 199.41 754.24 196.26" fill="none" stroke="#161616" stroke-width="69.967" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" transform="matrix(-.13334 0 0 .13333 0 597.333)"/>
+	<path d="M474.47 230.785c-17.793 0-26.655 8.863-26.655 26.654v261.2-23.99H207.912h47.98v-58.9 34.91h143.94-47.98v23.99h95.963v-94.88c-.534-16.73-9.396-25.06-26.656-25.06H186.58c-17.792 0-26.656 8.86-26.656 26.65v163.85c0 17.26 8.33 26.12 25.057 26.65h333.8c16.66-.53 24.99-9.39 24.99-26.65V326.74h-34.65c-16.66.667-24.65-7.33-23.99-23.987h300.28c4.2-7.13 6.27-15.126 6.27-23.99v-21.32c0-17.792-8.86-26.655-26.65-26.655zm-13.327 311.842l23.99 22.588-23.99-22.588" fill="#376fa1"/>
+	<path d="M777.616 312.677c3.132-3.132 5.73-6.397 7.796-9.928h-300.28c-.665 16.65 7.33 24.65 23.992 23.98h234.572c13.26 0 24.523-4.67 33.92-14.06" fill="#578fc1"/>
+	<path d="M3890.68-40.99H1387.32m1971.1-1440.85v-1067.51c0-133.44 66.47-199.91 199.91-199.91h2179.01c133.44 0 199.91 66.47 199.91 199.91v159.93c0 66.47-15.49 126.44-46.98 179.92" fill="none" stroke="#000" stroke-width="79.964" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" transform="matrix(.13334 0 0 .13333 0 597.333)"/>
+	<path d="M5890.27-2209.5c-15.49 26.48-34.98 50.97-58.47 74.46-70.47 70.47-154.93 105.45-254.39 105.45H4078.1M3358.42-590.243V-770.16m719.68-1259.43h-259.88m-459.8 1259.43v-711.68M3638.3-240.9l-179.92-169.423M4449.93-40.99h-559.25m187.42-1988.6V-240.9c0 129.44-62.48 195.91-187.42 199.91m1007.04 0H4717.8M1559.24-770.16h359.84m4777.83-1259.43l-179.92-179.91m0 0l179.92-179.92M949.022-40.99h438.298M6516.99-2209.5h-626.72m-3971.19 997.54v261.88m0 0v179.92m1079.51-179.92h-359.84m0 0v179.92m-719.67-179.92h719.67m0 179.92h-719.67M1387.32-40.99c-125.44-4-187.91-70.47-187.91-199.91v-1228.94c0-133.44 66.47-199.91 199.9-199.91h1759.2c129.45 0 195.92 62.47 199.91 187.91m-719.67 711.68h719.67" fill="none" stroke="#000" stroke-width="79.964" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" transform="matrix(.13334 0 0 .13333 0 597.333)"/>
+	<path d="M7716.44-2209.5H7356.6m0 539.75l-179.92-179.92m179.92-899.59l-179.92 179.92" fill="none" stroke="#161616" stroke-width="99.954" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" transform="matrix(.13334 0 0 .13333 0 597.333)"/>
+	<path d="M769.485 258.24c-2.332-2.333-5.13-3.467-8.462-3.467s-6.198 1.134-8.53 3.466c-2.333 2.33-3.466 5.19-3.466 8.52s1.133 6.13 3.466 8.46c2.332 2.33 5.198 3.53 8.53 3.53 3.332 0 6.13-1.2 8.462-3.53 2.334-2.34 3.532-5.13 3.532-8.47 0-3.33-1.198-6.2-3.532-8.53"/>
+</svg>
diff --git a/docs/index.rst b/docs/index.rst
index 655afa3e..849f0405 100644
--- a/docs/index.rst
+++ b/docs/index.rst
@@ -1,246 +1,131 @@
-.. discord.py-message-components documentation master file, created by
-   sphinx-quickstart on Sat Jun 26 14:55:47 2021.
-   You can adapt this file completely to your liking, but it should at least
-   contain the root `toctree` directive.
-
-Welcome to discord\.py-message-components' documentation!
-=========================================================
-
-.. figure:: https://cdn.discordapp.com/attachments/852872100073963532/854711446767796286/discord.py-message-components.png
-   :name: discord.py-message-components
-   :align: center
-   :alt: Name of the Project (discord.py-message-components)
-
-   ..
-   .. image:: https://discord.com/api/guilds/852871920411475968/embed.png
-      :target: https://discord.gg/sb69muSqsg
-      :alt: Discord Server Invite
-
-   .. image:: https://img.shields.io/pypi/v/discord.py-message-components.svg
-      :target: https://pypi.python.org/pypi/discord.py-message-components
-      :alt: PyPI version info
-
-   .. image:: https://img.shields.io/pypi/pyversions/discord.py-message-components.svg
-      :target: https://pypi.python.org/pypi/discord.py-message-components
-      :alt: PyPI supported Python versions
-
-   .. image:: https://static.pepy.tech/personalized-badge/discord-py-message-components?period=total&units=international_system&left_color=grey&right_color=green&left_text=Downloads
-      :target: https://pepy.tech/project/discord.py-message-components
-      :alt: Total downloads for the project
-
-   .. image:: https://readthedocs.org/projects/discordpy-message-components/badge/?version=latest
-      :target: https://discordpy-message-components.readthedocs.io/en/latest/
-      :alt: Documentation Status
-
-   A "fork" of `discord.py <https://pypi.org/project/discord.py/1.7.3>`_ library made by `Rapptz <https://github.com/Rapptz>`_ with implemation of the `Discord-Message-Components <https://discord.com/developers/docs/interactions/message-components>`_ by `mccoderpy <https://github.com/mccoderpy/>`_ 
-
-+---------------------------------------------------------------------------------------------------------------------------------------------------+
-|                                                              **❗ℹIMPORTANTℹ❗**                                                                    |
-+===================================================================================================================================================+
-| This branch represents only the `PyPI <https://pypi.org>`_ version of this library,                                                               |
-| which is currently **not up to date** due to some (privat) issues                                                                                 |
-| (as soon as we have documented the new features and the developer branch is stable enough, this will be updated).                                 |
-|                                                                                                                                                   |
-| **To get the latest version with the newest features and bug(-fixes) please take a look at the** `developer <../../tree/developer>`_ **branch**   |
-+---------------------------------------------------------------------------------------------------------------------------------------------------+
-
-**NOTE:** 
-     This library will be further developed independently of discord.py.
-     New features are also implemented. It's not an extension!
-     The name only comes from the fact that the original purpose of the library was to add support for message components and we haven't found a better one yet.
-
-.. |PyPI| image:: https://cdn.discordapp.com/emojis/854380926548967444.png?v=1
-   :alt: PyPI Logo
-   :width: 30px
-   :target: https://discordpy-message-components.readthedocs.io/en/latest/
-
-.. centered::
-   **Visit on** |PyPI| **PyPI** `here <https://pypi.org/project/discord.py-message-components>`_
-
-You need help? Or have ideas/feedback?
-______________________________________
-
-Open a `issue <../../issues>`_/`pull request <../../pulls>`_, join the `support-server <https://discord.gg/sb69muSqsg>`_ or send me a direct-message on `Discord <https://discord.com/channels/@me>`_: ``mccuber04#2960``
-
-
-Installing:
-___________
-
-**Python 3.5.3 or higher is required**
-
-This Library overwrite the original discord.py Library so to be sure all will work fine
-first uninstall the original `discord.py <https://pypi.org/project/discord.py/1.7.3>`_ Library if it is installed:
-
-.. code:: sh
-
-    # Linux/macOS
-    python3 -m pip uninstall discord.py
-
-    # Windows
-    py -3 -m pip uninstall discord.py
-
-Then install `this Library <https://pypi.org/project/discord.py-message-components>`_ using:
-
-.. code:: sh
-
-    # Linux/macOS
-    python3 -m pip install -U discord.py-message-components
-
-    # Windows
-    py -3 -m pip install -U discord.py-message-components
-
-________________________________________
-
-quickstart
-__________
-
-Sending-buttons
-~~~~~~~~~~~~~~~~
-
-.. code-block:: python
-
-   import discord
-   from discord.ext import commands
-   from discord import Button, ButtonStyle
-
-
-   client = commands.Bot(command_prefix=commands.when_mentioned_or('!'))
-
-
-   @client.command()
-   async def buttons(ctx):
-      await ctx.send('Hey here are some Buttons', components=[[
-         Button(label="Hey i\'m a red Button",
-                  custom_id="this is an custom_id",
-                  style=ButtonStyle.red),
-         Button(label="Hey i\'m a green Button",
-                  custom_id="this is an custom_id",
-                  style=ButtonStyle.green),
-         Button(label="Hey i\'m a blue Button",
-                  custom_id="this is an custom_id",
-                  style=ButtonStyle.blurple),
-         Button(label="Hey i\'m a grey Button",
-                  custom_id="this is an custom_id",
-                  style=ButtonStyle.grey),
-         Button(label="Hey i\'m a URL Button",
-                  url="https://pypi.org/project/discord.py-message-components",
-                  style=ButtonStyle.url)
-      ]])
-
-   client.run('Your Bot-Token')
-
-________________________________________
-
-Interact when a button was pressed
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-         
-.. code-block:: python
-
-   import discord
-   from discord.ext import commands
-   from discord import Button, ButtonStyle
-
-
-   client = commands.Bot(command_prefix=commands.when_mentioned_or('!'))
-
-
-   @client.command()
-   async def buttons(ctx):
-      msg_with_buttons = await ctx.send('Hey here are some Buttons', components=[[
-          Button(label="Hey i\'m a red Button",
-                 custom_id="red",
-                 style=ButtonStyle.red),
-          Button(label="Hey i\'m a green Button",
-                 custom_id="green",
-                 style=ButtonStyle.green),
-          Button(label="Hey i\'m a blue Button",
-                 custom_id="blue",
-                 style=ButtonStyle.blurple),
-          Button(label="Hey i\'m a grey Button",
-                 custom_id="grey",
-                 style=ButtonStyle.grey)
-      ]])
-      
-      def check_button(i: discord.Interaction, button):
-          return i.author == ctx.author and i.message == msg_with_buttons
-      
-      interaction, button = await client.wait_for('button_click', check=check_button)
-
-      embed = discord.Embed(title='You pressed an Button',
-      description=f'You pressed a {button.custom_id} button.',
-      color=discord.Color.random()) 
-      await interaction.respond(embed=embed)
-      
-   client.run('Your Bot-Token')
-
-.. note:: 
-
-   You could set the parameter :attr:`hidden` in the response to ``True`` to make the message ephemeral.
-   See `discord.Interaction.respond <./interaction.html#Interaction.respond>`_ for more information about :meth:`respond()`.
-
-________________________________________
-
-Sending-SelectMenu's and respond to them
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-.. code-block:: python
-
-   import discord
-   from discord.ext import commands
-   from discord import Button, SelectMenu, SelectOption
-
-
-   client = commands.Bot(command_prefix=commands.when_mentioned_or('!'))
-
-
-   @client.command()
-   async def select(ctx):
-      msg_with_selects = await ctx.send('Hey here is an nice Select-Menu', components=[
-         [
-               SelectMenu(custom_id='_select_it', options=[
-                  SelectOption(emoji='1️⃣', label='Option Nr° 1', value='1', description='The first option'),
-                  SelectOption(emoji='2️⃣', label='Option Nr° 2', value='2', description='The second option'),
-                  SelectOption(emoji='3️⃣', label='Option Nr° 3', value='3', description='The third option'),
-                  SelectOption(emoji='4️⃣', label='Option Nr° 4', value='4', description='The fourth option')],
-                        placeholder='Select some Options', max_values=3)
-            ]])
-
-      def check_selection(i: discord.Interaction, select_menu):
-         return i.author == ctx.author and i.message == msg_with_selects
-
-      interaction, select_menu = await client.wait_for('selection_select', check=check_selection)
-
-      embed = discord.Embed(title='You have chosen:',
-                           description=f"You have chosen "+'\n'.join([f'\nOption Nr° {o}' for o in select_menu.values]),
-                           color=discord.Color.random())
-      await interaction.respond(embed=embed)
-
-   client.run('Your Bot-Token')
-
-________________________________________
-
-coro
-~~~~
-
-A `coroutine <https://docs.python.org/3/library/asyncio-task.html#coroutine>`_ is a function that must be invoked with ``await`` or ``yield from``.
-When Python encounters an ``await`` it stops the function’s execution at that point and works on other things until it comes back to that point and finishes off its work.
-This allows for your program to be doing multiple things at the same time without using threads or complicated multiprocessing.
-
-**If you forget to await a coroutine then the coroutine will not run. Never forget to await a coroutine.**
-
-
-.. toctree:: 
-   :maxdepth: 3
-   :caption: Contents: 
-
-   additions.rst
-   components.rst
-   interaction.rst
-
-
-Indices and tables
-~~~~~~~~~~~~~~~~~~
-
-* :ref:`genindex`
-* :ref:`modindex`
-* :ref:`search`
+:og:title: discord4py documentation
+:og:description: Welcome to the documentation for the discord4py api-wrapper
+
+.. |flag_ua| image:: ./images/flag_ua.png
+   :alt: Ukraine
+   :width: 30px
+   :height: 30px
+   :scale: 100%
+
+.. image:: ./images/drop_down_icon.svg
+
+|flag_ua| Welcome to discord\.py-message-components |flag_ua|
+==============================================================
+
+.. image:: ./images/banner_light.png
+
+.. figure:: ./images/banner_dark.png
+   :name: discord.py-message-components
+   :align: center
+   :alt: Name of the Project (discord.py-message-components)
+
+   ..
+   .. image:: https://discord.com/api/guilds/852871920411475968/embed.png
+      :target: https://discord.gg/sb69muSqsg
+      :alt: Discord Server Invite
+
+   .. image:: https://img.shields.io/pypi/v/discord.py-message-components.svg
+      :target: https://pypi.python.org/pypi/discord.py-message-components
+      :alt: PyPI version info
+
+   .. image:: https://img.shields.io/pypi/pyversions/discord.py-message-components.svg
+      :target: https://pypi.python.org/pypi/discord.py-message-components
+      :alt: PyPI supported Python versions
+
+   .. image:: https://static.pepy.tech/personalized-badge/discord-py-message-components?period=total&units=international_system&left_color=grey&right_color=green&left_text=Downloads
+      :target: https://pepy.tech/project/discord.py-message-components
+      :alt: Total downloads for the project
+
+   .. image:: https://readthedocs.org/projects/discordpy-message-components/badge/?version=developer
+      :target: https://discordpy-message-components.readthedocs.io/en/developer/
+      :alt: Documentation Status
+
+   .. image:: https://img.shields.io/static/v1?label=Sponsor&message=%E2%9D%A4&logo=GitHub&color=%23fe8e86
+       :target: https://github.com/sponsors/mccoderpy
+       :alt: Sponsor button
+
+   A "fork" of `discord.py <https://pypi.org/project/discord.py/1.7.3>`_ library made by `Rapptz <https://github.com/Rapptz>`_ with implementation of the `Discord-Message-Components <https://discord.com/developers/docs/interactions/message-components>`_ & many other features by `mccoderpy <https://github.com/mccoderpy/>`_
+
+.. important::
+
+     This library will be further developed independently of discord.py.
+     New features are also implemented. It's not an extension!
+     The name only comes from the fact that the original purpose of the library was to add support for message components and we haven't found a better one yet.
+
+.. |PyPI| image:: https://cdn.discordapp.com/emojis/854380926548967444.png?v=1
+   :alt: PyPI Logo
+   :width: 30px
+   :target: https://pypi.org
+
+.. centered::
+    **Visit on** |PyPI| **PyPI** `here <https://pypi.org/project/discord.py-message-components>`_
+
+
+discord.py-message-components is a modern, easy to use, feature-rich, and async ready API wrapper
+for Discord.
+
+**Features:**
+
+- Modern Pythonic API using ``async``\/``await`` syntax
+- Sane rate limit handling that prevents 429s
+- Implements the entire Discord API
+- Command extension to aid with bot creation
+- Easy to use with an object oriented design
+- Optimised for both speed and memory
+
+Getting started
+-----------------
+
+Is this your first time using the library? This is the place to get started!
+
+- **First steps:** :doc:`intro` | :doc:`quickstart` | :doc:`logging`
+- **Working with Discord:** :doc:`discord` | :doc:`intents`
+- **Examples:** Many examples are available in the :resource:`repository <examples>`.
+
+Getting help
+--------------
+
+If you're having trouble with something, these resources might help.
+
+- Try the :doc:`faq` first, it's got answers to all common questions.
+- Ask us and hang out with us in our :resource:`Discord <discord>` server.
+- If you're looking for something specific, try the :ref:`index <genindex>` or :ref:`searching <search>`.
+- Report bugs in the :resource:`issue tracker <issues>`.
+- Ask in our :resource:`GitHub discussions page <discussions>`.
+
+Extensions
+------------
+
+These extensions help you during development when it comes to common tasks.
+
+.. toctree::
+  :maxdepth: 1
+
+  ext/commands/index.rst
+  ext/tasks/index.rst
+
+Manuals
+---------
+
+These pages go into great detail about everything the API can do.
+
+.. toctree::
+  :maxdepth: 1
+
+  API Reference </api/index.rst>
+  Interactions <Interactions/index.rst>
+  OAuth2 <oauth2/index.rst>
+  discord.ext.commands API Reference <ext/commands/api.rst>
+  discord.ext.tasks API Reference <ext/tasks/index.rst>
+
+Meta
+------
+
+If you're looking for something related to the project itself, it's here.
+
+.. toctree::
+    :maxdepth: 1
+
+    whats_new
+    version_guarantees
+    migrating
diff --git a/docs/intents.rst b/docs/intents.rst
new file mode 100644
index 00000000..f0ce207d
--- /dev/null
+++ b/docs/intents.rst
@@ -0,0 +1,225 @@
+.. currentmodule:: discord
+.. versionadded:: 1.5
+.. _intents_primer:
+
+A Primer to Gateway Intents
+=============================
+
+In version 1.5 comes the introduction of :class:`Intents`. This is a radical change in how bots are written. An intent basically allows a bot to subscribe to specific buckets of events. The events that correspond to each intent is documented in the individual attribute of the :class:`Intents` documentation.
+
+These intents are passed to the constructor of :class:`Client` or its subclasses (:class:`AutoShardedClient`, :class:`~.AutoShardedBot`, :class:`~.Bot`) with the ``intents`` argument.
+
+If intents are not passed, then the library defaults to every intent being enabled except the privileged intents, currently :attr:`Intents.members` and :attr:`Intents.presences`.
+
+What intents are needed?
+--------------------------
+
+The intents that are necessary for your bot can only be dictated by yourself. Each attribute in the :class:`Intents` class documents what :ref:`events <discord-api-events>` it corresponds to and what kind of cache it enables.
+
+For example, if you want a bot that functions without spammy events like presences or typing then we could do the following:
+
+.. code-block:: python3
+   :emphasize-lines: 7,9,10
+
+    import discord
+    intents = discord.Intents.default()
+    intents.typing = False
+    intents.presences = False
+
+    # Somewhere else:
+    # client = discord.Client(intents=intents)
+    # or
+    # from discord.ext import commands
+    # bot = commands.Bot(command_prefix='!', intents=intents)
+
+Note that this doesn't enable :attr:`Intents.members` since it's a privileged intent.
+
+Another example showing a bot that only deals with messages and guild information:
+
+.. code-block:: python3
+   :emphasize-lines: 7,9,10
+
+    import discord
+    intents = discord.Intents(messages=True, guilds=True)
+    # If you also want reaction events enable the following:
+    # intents.reactions = True
+
+    # Somewhere else:
+    # client = discord.Client(intents=intents)
+    # or
+    # from discord.ext import commands
+    # bot = commands.Bot(command_prefix='!', intents=intents)
+
+.. _privileged_intents:
+
+Privileged Intents
+---------------------
+
+With the API change requiring bot authors to specify intents, some intents were restricted further and require more manual steps. These intents are called **privileged intents**.
+
+A privileged intent is one that requires you to go to the developer portal and manually enable it. To enable privileged intents do the following:
+
+1. Make sure you're logged on to the `Discord website <https://discord.com>`_.
+2. Navigate to the `application page <https://discord.com/developers/applications>`_.
+3. Click on the bot you want to enable privileged intents for.
+4. Navigate to the bot tab on the left side of the screen.
+
+    .. image:: /images/discord_bot_tab.png
+        :alt: The bot tab in the application page.
+
+5. Scroll down to the "Privileged Gateway Intents" section and enable the ones you want.
+
+    .. image:: /images/discord_privileged_intents.png
+        :alt: The privileged gateway intents selector.
+
+.. warning::
+
+    Enabling privileged intents when your bot is in over 100 guilds requires going through `bot verification <https://support.discord.com/hc/en-us/articles/360040720412>`_. If your bot is already verified and you would like to enable a privileged intent you must go through `Discord support <https://dis.gd/contact>`_ and talk to them about it.
+
+.. note::
+
+    Even if you enable intents through the developer portal, you still have to enable the intents
+    through code as well.
+
+Do I need privileged intents?
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+This is a quick checklist to see if you need specific privileged intents.
+
+.. _need_presence_intent:
+
+Presence Intent
++++++++++++++++++
+
+- Whether you use :attr:`Member.status` at all to track member statuses.
+- Whether you use :attr:`Member.activity` or :attr:`Member.activities` to check member's activities.
+
+.. _need_members_intent:
+
+Member Intent
++++++++++++++++
+
+- Whether you track member joins or member leaves, corresponds to :func:`on_member_join` and :func:`on_member_remove` events.
+- Whether you want to track member updates such as nickname or role changes.
+- Whether you want to track user updates such as usernames, avatars, discriminators, etc.
+- Whether you want to request the guild member list through :meth:`Guild.chunk` or :meth:`Guild.fetch_members`.
+- Whether you want high accuracy member cache under :attr:`Guild.members`.
+
+.. _need_message_content_intent:
+
+Message Content
++++++++++++++++++
+
+Whether you use anything that needs the content of a message.
+Including :ref:`ext.commands <discord_ext_commands>` (when using a prefix, that is not a bot mention)
+
+.. note::
+
+    The bot will still receive these fields when the message is in a privat chat with the bot,
+    or the bot is mentioned in the message.
+
+This corresponds to the following events:
+
+- :func:`on_message` (content, embeds, attachments, components)
+- :func:`on_message_edit` (content, embeds, attachments, components)
+- :func:`on_raw_message_edit` (cached_message)
+- :func:`on_message_delete` (content, embeds, attachments, components)
+- :func:`on_raw_message_delete` (cached_message)
+- :func:`on_bulk_message_delete` (content, embeds, attachments, components)
+- :func:`on_raw_bulk_message_delete` (cached_messages)
+
+This also corresponds to the following attributes and classes:
+
+- :attr:`Message.content`
+- :attr:`Message.embeds`
+- :attr:`Message.attachments`
+- :attr:`Message.components`
+
+.. warning::
+    Until August 31, 2022 you only need to enable the intent when using api v10 (What is the default).
+    Ofter this day you must enable the indent on any version in order to receive this fields.
+    See also the official `faq <https://support-dev.discord.com/hc/en-us/articles/4404772028055>`_
+
+.. _intents_member_cache:
+
+Member Cache
+-------------
+
+Along with intents, Discord now further restricts the ability to cache members and expects bot authors to cache as little as is necessary. However, to properly maintain a cache the :attr:`Intents.members` intent is required in order to track the members who left and properly evict them.
+
+To aid with member cache where we don't need members to be cached, the library now has a :class:`MemberCacheFlags` flag to control the member cache. The documentation page for the class goes over the specific policies that are possible.
+
+It should be noted that certain things do not need a member cache since Discord will provide full member information if possible. For example:
+
+- :func:`on_message` will have :attr:`Message.author` be a member even if cache is disabled.
+- :func:`on_voice_state_update` will have the ``member`` parameter be a member even if cache is disabled.
+- :func:`on_reaction_add` will have the ``user`` parameter be a member when in a guild even if cache is disabled.
+- :func:`on_raw_reaction_add` will have :attr:`RawReactionActionEvent.member` be a member when in a guild even if cache is disabled.
+- The reaction add events do not contain additional information when in direct messages. This is a Discord limitation.
+- The reaction removal events do not have member information. This is a Discord limitation.
+
+Other events that take a :class:`Member` will require the use of the member cache. If absolute accuracy over the member cache is desirable, then it is advisable to have the :attr:`Intents.members` intent enabled.
+
+.. _retrieving_members:
+
+Retrieving Members
+--------------------
+
+If the cache is disabled or you disable chunking guilds at startup, we might still need a way to load members. The library offers a few ways to do this:
+
+- :meth:`Guild.query_members`
+    - Used to query members by a prefix matching nickname or username.
+    - This can also be used to query members by their user ID.
+    - This uses the gateway and not the HTTP.
+- :meth:`Guild.chunk`
+    - This can be used to fetch the entire member list through the gateway.
+- :meth:`Guild.fetch_member`
+    - Used to fetch a member by ID through the HTTP API.
+- :meth:`Guild.fetch_members`
+    - used to fetch a large number of members through the HTTP API.
+
+It should be noted that the gateway has a strict rate limit of 120 requests per 60 seconds.
+
+Troubleshooting
+------------------
+
+Some common issues relating to the mandatory intent change.
+
+Where'd my members go?
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+Due to an :ref:`API change <intents_member_cache>` Discord is now forcing developers who want member caching to explicitly opt-in to it. This is a Discord mandated change and there is no way to bypass it. In order to get members back you have to explicitly enable the :ref:`members privileged intent <privileged_intents>` and change the :attr:`Intents.members` attribute to true.
+
+For example:
+
+.. code-block:: python3
+   :emphasize-lines: 3,6,8,9
+
+    import discord
+    intents = discord.Intents.default()
+    intents.members = True
+
+    # Somewhere else:
+    # client = discord.Client(intents=intents)
+    # or
+    # from discord.ext import commands
+    # bot = commands.Bot(command_prefix='!', intents=intents)
+
+Why does ``on_ready`` take so long to fire?
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+As part of the API change regarding intents, Discord also changed how members are loaded in the beginning. Originally the library could request 75 guilds at once and only request members from guilds that have the :attr:`Guild.large` attribute set to ``True``. With the new intent changes, Discord mandates that we can only send 1 guild per request. This causes a 75x slowdown which is further compounded by the fact that *all* guilds, not just large guilds are being requested.
+
+There are a few solutions to fix this.
+
+The first solution is to request the privileged presences intent along with the privileged members intent and enable both of them. This allows the initial member list to contain online members just like the old gateway. Note that we're still limited to 1 guild per request but the number of guilds we request is significantly reduced.
+
+The second solution is to disable member chunking by setting ``chunk_guilds_at_startup`` to ``False`` when constructing a client. Then, when chunking for a guild is necessary you can use the various techniques to :ref:`retrieve members <retrieving_members>`.
+
+To illustrate the slowdown caused by the API change, take a bot who is in 840 guilds and 95 of these guilds are "large" (over 250 members).
+
+Under the original system this would result in 2 requests to fetch the member list (75 guilds, 20 guilds) roughly taking 60 seconds. With :attr:`Intents.members` but not :attr:`Intents.presences` this requires 840 requests, with a rate limit of 120 requests per 60 seconds means that due to waiting for the rate limit it totals to around 7 minutes of waiting for the rate limit to fetch all the members. With both :attr:`Intents.members` and :attr:`Intents.presences` we mostly get the old behaviour so we're only required to request for the 95 guilds that are large, this is slightly less than our rate limit so it's close to the original timing to fetch the member list.
+
+Unfortunately due to this change being required from Discord there is nothing that the library can do to mitigate this.
+
+If you truly dislike the direction Discord is going with their API, you can contact them via `support <https://dis.gd/contact>`_.
diff --git a/docs/interaction.rst b/docs/interaction.rst
deleted file mode 100644
index 34a92850..00000000
--- a/docs/interaction.rst
+++ /dev/null
@@ -1,202 +0,0 @@
-Interaction
-===========
-
-.. _respond: ./interaction.html#Interaction.respond
-.. _defer:  ./interaction.html#Interaction.defer
-.. _edit:  ./interaction.html#Interaction.edit
-
-.. class:: InteractionCallbackType
-
-   This is located in discord.enums but i place it here.
-
-   InteractionCallbackType to react to an :class:`Interaction`
-
-   +-----------------------------------------+-------+--------------------------------------------------+-----------------------------+--------------------------------------------+
-   | NAME                                    | VALUE | DESCRIPTION                                      | USAGE                       | EXAMPLE                                    |
-   +=========================================+=======+==================================================+=============================+============================================+
-   | .. attribute:: pong                     |   1   | ACK a ``Ping``                                   | ACK a Ping to Discord       |                     ~                      |
-   +-----------------------------------------+-------+--------------------------------------------------+-----------------------------+--------------------------------------------+
-   | .. attribute:: msg_with_source          |   4   | respond to an interaction with a message         | :class:`Interaction.respond`| .. toggle-header::                         |
-   |                                         |       |                                                  |                             |    :header: **Click for example**          |
-   |                                         |       |                                                  |                             |                                            |
-   |                                         |       |                                                  |                             |    .. image:: imgs/ict4example.gif         |
-   |                                         |       |                                                  |                             |       :alt: Example for msg_with_source    |
-   +-----------------------------------------+-------+--------------------------------------------------+-----------------------------+--------------------------------------------+
-   |                                         |       |                                                  |                             | .. toggle-header::                         |
-   | .. attribute:: deferred_msg_with_source |   5   | ACK an interaction and edit a response later,    | Possible                    |    :header: **Click for example**          |
-   |                                         |       | the user sees a loading state                    | :attr:`response_type`       |                                            |
-   |                                         |       |                                                  | for defer_                  |    .. image:: imgs/ict5example.gif         |
-   |                                         |       |                                                  |                             |       :alt: Example for                    |
-   |                                         |       |                                                  |                             |             deferred_msg_with_source       |
-   +-----------------------------------------+-------+--------------------------------------------------+-----------------------------+--------------------------------------------+
-   | .. attribute:: deferred_update_msg      |   6   | for components, ACK an interaction and edit      | Possible                    | .. toggle-header::                         |
-   |                                         |       | the original message later;                      | :attr:`response_type`       |    :header: **Click for example**          |
-   |                                         |       | the user does not see a loading state            | for defer_                  |                                            |
-   |                                         |       |                                                  |                             |    .. image:: imgs/ict6example.gif         |
-   |                                         |       |                                                  |                             |       :alt: Example for deferred_update_msg|
-   +-----------------------------------------+-------+--------------------------------------------------+-----------------------------+--------------------------------------------+
-   | .. attribute:: update_msg               |   7   | for components,                                  | :class:`Interaction.edit`   | .. toggle-header::                         |
-   |                                         |       | edit the message the component was attached to   |                             |    :header: **Click for example**          |
-   |                                         |       |                                                  |                             |                                            |
-   |                                         |       |                                                  |                             |    .. image:: imgs/ict7example.gif         |
-   |                                         |       |                                                  |                             |       :alt: Example for update_msg         |
-   +-----------------------------------------+-------+--------------------------------------------------+-----------------------------+--------------------------------------------+
-
-.. class:: Interaction
-
-   .. warning::
-      Do not initiate this Class manually
-
-   Represents an interaction created in discord like click an :class:`Button` or select an option of :class:`SelectMenu`
-
-   .. note::
-      For general information's about Interactions visit the `Discord-API-Documentation <https://discord.com/developers/docs/interactions/slash-commands#interaction-object>`_ of the discord-api.
-
-   .. attribute:: author
-
-         A :class:`Member` that invoked the interaction. If :attr:`channel` is a
-         private channel or the user has left the guild, then it is a :class:`User` instead.
-
-   .. attribute:: message
-
-         The message the component was attached to.
-         This will be :class:`EphemeralMessage` if the :attr:`component_type` is not ``None`` or the message the component is attached to is ``ephemeral``.
-
-         .. note::
-            In this version, this parameter should always be an object of type :class:`discord.Message`
-            (or :class:`EphemeralMessage` if the message is ephemeral) because it only gets initiated when the interaction_type is higher than 2.
-
-   .. attribute:: channel
-
-      The Channel the interaction was created in this is aiter an object of :class:`discord.TextChannel` if it's
-      inside a guild else it's an object of type :class:`discord.DMChannel`.
-
-   .. attribute:: guild
-
-      The guild associated with the interaction; aiter an object of type :class:`discord.Guild`,
-      except the interaction was inside an dm-channel then this would be equal to ``None``
-
-   .. attribute:: component
-
-      The component that invoked this interaction:
-      Aiter an object of type :class:`Button` or :class:`SelectMenu` if the message is **not** ephemeral
-      else type :class:`ButtonClick` or :class:`SelectionSelect`
-
-      .. note::
-         If this is passed in an ``[on_][raw_]button_click`` or ``[on_][raw_]selection_select`` Event there would be a second parameter that includes this attribute.
-
-   .. attribute:: created_at
-
-         Returns the Interaction’s creation time in UTC.
-
-         **Type**
-            `datetime.datetime <https://docs.python.org/3/library/datetime.html#datetime.datetime>`_
-
-   .. method:: defer(response_type: typing.Literal[5, 6] = InteractionCallbackType.deferred_update_msg, hidden: bool = False)
-
-      `|coro| <./index.html#coro>`_
-
-      'Defers' the response.
-
-      If :attr:`response_type` is :class:`InteractionCallbackType.deferred_msg_with_source` it shows a loading state to the user.
-
-      :param response_type: Optional[typing.Literal[5, 6]]
-         The type to response with, aiter :class:`InteractionCallbackType.deferred_msg_with_source` or :class:`InteractionCallbackType.deferred_update_msg` (e.g. 5 or 6)
-
-      :param hidden: Optional[bool]
-          Whether to defer ephemerally(only the :attr:`author` of the interaction can see the message)
-
-          .. note::
-              Only for :class:`InteractionCallbackType.deferred_msg_with_source`.
-
-      .. important::
-         If you doesn't respond with an message using :meth:`respond`
-         or edit the original message using :meth:`edit` within less than 3 seconds,
-         discord will indicates that the interaction failed and the interaction-token will be invalidated.
-         To provide this us this method
-
-      .. note::
-         A Token will be Valid for 15 Minutes so you could edit the original :attr:`message` with :meth:`edit`, :meth:`respond` or doing anything other with this interaction for 15 minutes.
-         after that time you have to edit the original message with the Methode ``edit`` of the :attr:`message` and sending new messages with the ``send`` Methode of :attr:`channel`
-         (you could not do this hidden as it isn't an interaction-response anymore)
-
-   .. method:: edit(**fields)
-
-      `|coro| <./index.html#coro>`_
-
-      Edit the :class:`Message` the component is attached to, if the interaction is not deferred it will defer automatic.
-
-      .. note::
-         If you have not yet deferred or deferred with type :class:`InteractionCallbackType.deferred_update_msg`, edit the message to which the component is attached, otherwise edit the callback message.
-
-      :param \**fields: The fields of the original message to replace. You could pass the same Parameters as using :meth:`discord.Message.edit`
-
-   .. method:: respond(**kwargs)
-
-      `|coro| <./index.html#coro>`_
-
-      You could pass the same Parameters as using :meth:`discord.Messageable.send` but there are one more optional:
-      Responds to an interaction by sending a message that can be made visible only to the person who invoked the interaction by setting the :attr:`hidden` to ``True``.
-
-      :param hidden: Optional[:class:`bool`]
-         If set to ``True``, the message will be only visible(e.g. ephemeral) for the :attr:`author` of the Interaction and will disappears
-         if the :attr:`author` click on ``delete this message``, the message go out of his view or he reloads the client.
-
-         .. note::
-            If you send an ``hidden`` (ephemeral)-respond, discord don't returns any data like an message you could edit,
-            **but** you could receive Interactions when the Author interact with an component in the message.
-
-      :return:  Union[:class:`discord.Message`, :class:`EphemeralMessage`]
-
-________________________________________
-
-.. class:: ButtonClick
-
-   The object that contains a :class:`Interaction.component`
-   if it is of type 2 and the message is ephemeral.
-
-   .. attribute:: custom_id
-
-      Union[:class:`str`, :class:`int`]
-
-      The :attr:`custom_id` of the :class:`Button`.
-      If the :attr:`custom_id` is a number it is returned as an integer, otherwise a string.
-
-__________________________________________
-
-.. class:: SelectionSelect
-
-   The object containing a :class:`Interaction.component` contains, if it is of type 3 and the message is ephemeral.
-
-   .. attribute:: custom_id
-
-      Union[:class:`str`, :class:`int`]
-
-      The :attr:`custom_id` of the :class:`SelectMenu`.
-      If the :attr:`custom_id` is a number it is returned as an integer, otherwise a string.
-
-
-   .. attribute:: values
-
-      List[Union[:class:`str`, :class:`int`]]
-      A list of the options that have been selected.
-      If the :attr:`value` is a number it is returned as an integer, otherwise a string
-
-________________________________________
-
-.. class:: EphemeralMessage
-
-    Since Discord doesn't return anything when we send a ephemeral message,
-    this class has no attributes and you can't do anything with it.
-
-.. toctree:: 
-   :maxdepth: 2
-   :caption: Contents: 
-
-Indices and tables
-~~~~~~~~~~~~~~~~~~
-
-* :ref:`genindex`
-* :ref:`modindex`
-* :ref:`search`
-
diff --git a/docs/intro.rst b/docs/intro.rst
new file mode 100644
index 00000000..2957a691
--- /dev/null
+++ b/docs/intro.rst
@@ -0,0 +1,201 @@
+.. currentmodule:: discord
+
+.. _intro:
+
+Introduction
+==============
+
+This is the documentation for discord.py-message-components, a library for Python to aid
+in creating applications that utilise the Discord API.
+
+Prerequisites
+---------------
+
+discord.py-message-components works with **Python 3.8 or higher**.
+Support for earlier versions of Python is not provided. Python 2.7 or lower is not supported.
+Any version prior to 3.8 will no longer be supported as of **v2.0** due to decisions regarding the quality of our codebase.
+
+
+.. _installing:
+
+Installing
+-----------
+
+To install the library from PyPI using ``pip``:
+
+.. tab:: Linux/macOS
+
+    .. code-block:: shell
+
+        python3 -m pip install -U discord.py-message-components
+
+.. tab:: Windows
+
+    .. code-block:: shell
+
+        py -m pip install -U discord.py-message-components
+
+Voice support (e.g. playing audio in voice channels) is not enabled by default and can be enabled by installing ``discord.py-message-components[voice]`` instead of ``discord.py-message-components``.:
+
+.. tab:: Linux/macOS
+
+    .. code-block:: shell
+
+        python3 -m pip install -U discord.py-message-components[voice]
+
+    .. note::
+        On Linux environments, installing voice requires getting the following dependencies using your favourite package manager (e.g. ``apt``, ``yum``):
+
+        - `libffi <https://github.com/libffi/libffi>`_
+        - `libnacl <https://github.com/saltstack/libnacl>`_
+        - `python3-dev <https://packages.debian.org/python3-dev>`_
+
+        For a Debian-based system, the following command will get these dependencies:
+
+        .. code-block:: shell
+
+            $ apt install libffi-dev libnacl-dev python3-dev
+
+        **Remember to check your permissions!**
+
+.. tab:: Windows
+
+    .. code-block:: shell
+
+        py -m pip install -U discord.py-message-components[voice]
+
+    .. note::
+        On Windows, you need to install the `FFmpeg <https://www.ffmpeg.org/>`_ binary yourself.
+        You can download it `here <https://www.ffmpeg.org/download.html/>`_.
+
+        Save/extract the files somewhere where you won't accidentally delete them, e.g. ``C:\\ffmpeg`` or ``C:\\Program Files\ffmpeg``.
+
+        You then need to add the directory containing the binary(s) (should be a folder named ``bin``)
+        to your system's ``PATH`` environment variable.
+
+        The procedure for doing this varies depending on which version of Windows you are using.
+
+        .. tab:: Windows 10/11
+
+            1. Open the Start Menu.
+            2. Search for ``environment``.
+            3. Click :key:`Edit the system environment variables`
+            4. Click the :key:`Environment Variables...` button.
+            5. Select the `Path` variable under **System variables**.
+            6. Click the :key:`Edit...` button.
+            7. Click the :key:`New` button.
+            8. Paste the path to the directory containing the FFmpeg binary.
+            9. Click :key:`OK` to close all the windows you have opened.
+
+Installing the developer version
+---------------------------------
+
+You can install the developer (alpha/beta) version from the `developer-branch <https://github.com/mccoderpy/discord.py-message-components/tree/developer>`_
+from GitHub. This version is not guaranteed to be stable and may have bugs. But it may have a lot of new features already implemented.
+
+.. warning::
+    In order to "clone" and install the repository of this library from GitHub you need to have git installed on your system.
+    If you need help with this take a look **→** `here <https://github.com/git-guides/install-git>`_ **←**
+
+.. tab:: Linux/macOS
+
+    .. code-block:: shell
+
+        python3 -m pip install -U git+https://github.com/mccoderpy/discord.py-message-components.git@developer
+
+.. tab:: Windows
+
+    .. code-block:: shell
+
+        py -m pip install -U git+https://github.com/mccoderpy/discord.py-message-components.git@developer
+
+Virtual Environments
+~~~~~~~~~~~~~~~~~~~~~
+
+Sometimes you want to keep libraries from polluting system installs or use a different version of
+libraries than the ones installed on the system. You might also not have permissions to install libraries system-wide.
+For this purpose, Pythons standard library comes with a concept called "Virtual Environment"s (often abbreviated to "venv").
+
+A more in-depth tutorial is found on :doc:`py:tutorial/venv`.
+
+However, for the quick and dirty:
+
+.. tab:: Linux/macOS
+
+    1. Go to your project's working directory:
+
+        .. code-block:: shell
+
+            $ cd your-bot-source
+            $ python3 -m venv bot-env
+
+    2. Activate the virtual environment:
+
+        .. code-block:: shell
+
+            $ source bot-env/bin/activate
+
+    3. Use pip like usual:
+
+        .. code-block:: shell
+
+            $ pip install -U discord.py-message-components
+
+
+.. tab:: Windows
+
+        1. Go to your project's working directory:
+
+            .. code-block:: shell
+
+                $ cd your-bot-source
+                $ py -m venv bot-env
+
+        2. Activate the virtual environment:
+
+            .. code-block:: shell
+
+                $ .\bot-env\Scripts\activate
+
+            .. note::
+                This might show you show an error that tells you that you are not allowed to run scripts on your system.
+                To fix this you need to run the following command in an **elevated** PowerShell:
+
+                .. code-block:: powershell
+
+                    Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser
+
+                `More information about PowerShell execution policies <https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_execution_policies>`_
+
+
+        3. Use pip like usual:
+
+            .. code-block:: shell
+
+                $ pip install -U discord.py-message-components
+
+Congratulations. You now have a virtual environment all set up.
+
+Basic Concepts
+---------------
+
+discord.py-message-components revolves around the concept of :ref:`events <discord-api-events>`.
+An event is something you listen to and then respond to. For example, when a message
+happens, you will receive an event about it that you can respond to.
+
+A quick example to showcase how events work:
+
+.. code-block:: python3
+
+    import discord
+
+    class MyClient(discord.Client):
+        async def on_ready(self):
+            print('Logged on as {0}!'.format(self.user))
+
+        async def on_message(self, message):
+            print('Message from {0.author}: {0.content}'.format(message))
+
+    client = MyClient()
+    client.run('my token goes here')
+
diff --git a/docs/logging.rst b/docs/logging.rst
new file mode 100644
index 00000000..1b2dbbf7
--- /dev/null
+++ b/docs/logging.rst
@@ -0,0 +1,48 @@
+.. versionadded:: 0.6.0
+.. _logging_setup:
+
+Setting Up Logging
+===================
+
+.. note::
+
+    Since version 2.0 logging will be set up by default in the :meth:`discord.Client.run` call.
+
+*discord4py* logs errors and debug information via the :mod:`logging` python
+module. It is strongly recommended that the logging module is
+configured, as no errors or warnings will be output if it is not set up.
+Configuration of the ``logging`` module can be as simple as::
+
+    import logging
+
+    logging.basicConfig(level=logging.INFO)
+
+Placed at the start of the application. This will output the logs from
+discord as well as other libraries that use the ``logging`` module
+directly to the console.
+
+The optional ``level`` argument specifies what level of events to log
+out and can be any of ``CRITICAL``, ``ERROR``, ``WARNING``, ``INFO``, and
+``DEBUG`` and if not specified defaults to ``WARNING``.
+
+More advanced setups are possible with the :mod:`logging` module. For
+example to write the logs to a file called ``discord.log`` instead of
+outputting them to the console the following snippet can be used::
+
+    import discord
+    import logging
+
+    logger = logging.getLogger('discord')
+    logger.setLevel(logging.DEBUG)
+    handler = logging.FileHandler(filename='discord.log', encoding='utf-8', mode='w')
+    handler.setFormatter(logging.Formatter('%(asctime)s:%(levelname)s:%(name)s: %(message)s'))
+    logger.addHandler(handler)
+
+This is recommended, especially at verbose levels such as ``INFO``
+and ``DEBUG``, as there are a lot of events logged and it would clog the
+stdout of your program.
+
+
+
+For more information, check the documentation and tutorial of the
+:mod:`logging` module.
diff --git a/docs/make.bat b/docs/make.bat
index 2119f510..859b6195 100644
--- a/docs/make.bat
+++ b/docs/make.bat
@@ -1,35 +1,45 @@
-@ECHO OFF
-
-pushd %~dp0
-
-REM Command file for Sphinx documentation
-
-if "%SPHINXBUILD%" == "" (
-	set SPHINXBUILD=sphinx-build
-)
-set SOURCEDIR=.
-set BUILDDIR=_build
-
-if "%1" == "" goto help
-
-%SPHINXBUILD% >NUL 2>NUL
-if errorlevel 9009 (
-	echo.
-	echo.The 'sphinx-build' command was not found. Make sure you have Sphinx
-	echo.installed, then set the SPHINXBUILD environment variable to point
-	echo.to the full path of the 'sphinx-build' executable. Alternatively you
-	echo.may add the Sphinx directory to PATH.
-	echo.
-	echo.If you don't have Sphinx installed, grab it from
-	echo.http://sphinx-doc.org/
-	exit /b 1
-)
-
-%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
-goto end
-
-:help
-%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
-
-:end
-popd
+@ECHO OFF
+
+pushd %~dp0
+
+REM Command file for Sphinx documentation
+
+if "%SPHINXBUILD%" == "" (
+	set SPHINXBUILD=sphinx-build
+)
+
+set SOURCEDIR=.
+set BUILDDIR=_build
+
+if "%1" == "" goto help
+
+%SPHINXBUILD% >NUL 2>NUL
+if errorlevel 9009 (
+	echo.
+	echo.The 'sphinx-build' command was not found. Make sure you have Sphinx
+	echo.installed, then set the SPHINXBUILD environment variable to point
+	echo.to the full path of the 'sphinx-build' executable. Alternatively you
+	echo.may add the Sphinx directory to PATH.
+	echo.
+	echo.If you don't have Sphinx installed, grab it from
+	echo.http://sphinx-doc.org/
+	exit /b 1
+)
+
+if "%1" == "--show" (
+    if "%2" == "" (
+       sphinx-autobuild --port=0 --watch=%SOURCEDIR% --open-browser --delay=2 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
+    ) else (
+       sphinx-autobuild --port=0 --watch=%SOURCEDIR% --open-browser --delay=2 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% -b %2
+    )
+    goto end
+)
+
+%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
+goto end
+
+:help
+%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
+
+:end
+popd
diff --git a/docs/migrating.rst b/docs/migrating.rst
new file mode 100644
index 00000000..baf97160
--- /dev/null
+++ b/docs/migrating.rst
@@ -0,0 +1,1172 @@
+.. currentmodule:: discord
+
+.. _migrating_1_0:
+
+Migrating to v1.0
+======================
+
+v1.0 is one of the biggest breaking changes in the library due to a complete
+redesign.
+
+The amount of changes are so massive and long that for all intents and purposes, it is a completely
+new library.
+
+Part of the redesign involves making things more easy to use and natural. Things are done on the
+:ref:`models <discord_api_models>` instead of requiring a :class:`Client` instance to do any work.
+
+Python Version Change
+-----------------------
+
+In order to make development easier and also to allow for our dependencies to upgrade to allow usage of 3.7 or higher,
+the library had to remove support for Python versions lower than 3.5.3, which essentially means that **support for Python 3.4
+is dropped**.
+
+Major Model Changes
+---------------------
+
+Below are major model changes that have happened in v1.0
+
+Snowflakes are int
+~~~~~~~~~~~~~~~~~~~~
+
+Before v1.0, all snowflakes (the ``id`` attribute) were strings. This has been changed to :class:`int`.
+
+Quick example: ::
+
+    # before
+    ch = client.get_channel('84319995256905728')
+    if message.author.id == '80528701850124288':
+        ...
+
+    # after
+    ch = client.get_channel(84319995256905728)
+    if message.author.id == 80528701850124288:
+        ...
+
+This change allows for fewer errors when using the Copy ID feature in the official client since you no longer have
+to wrap it in quotes and allows for optimisation opportunities by allowing ETF to be used instead of JSON internally.
+
+Server is now Guild
+~~~~~~~~~~~~~~~~~~~~~
+
+The official API documentation calls the "Server" concept a "Guild" instead. In order to be more consistent with the
+API documentation when necessary, the model has been renamed to :class:`Guild` and all instances referring to it has
+been changed as well.
+
+A list of changes is as follows:
+
++-------------------------------+----------------------------------+
+|             Before            |              After               |
++-------------------------------+----------------------------------+
+| ``Message.server``            | :attr:`Message.guild`            |
++-------------------------------+----------------------------------+
+| ``Channel.server``            | :attr:`.GuildChannel.guild`      |
++-------------------------------+----------------------------------+
+| ``Client.servers``            | :attr:`Client.guilds`            |
++-------------------------------+----------------------------------+
+| ``Client.get_server``         | :meth:`Client.get_guild`         |
++-------------------------------+----------------------------------+
+| ``Emoji.server``              | :attr:`Emoji.guild`              |
++-------------------------------+----------------------------------+
+| ``Role.server``               | :attr:`Role.guild`               |
++-------------------------------+----------------------------------+
+| ``Invite.server``             | :attr:`Invite.guild`             |
++-------------------------------+----------------------------------+
+| ``Member.server``             | :attr:`Member.guild`             |
++-------------------------------+----------------------------------+
+| ``Permissions.manage_server`` | :attr:`Permissions.manage_guild` |
++-------------------------------+----------------------------------+
+| ``VoiceClient.server``        | :attr:`VoiceClient.guild`        |
++-------------------------------+----------------------------------+
+| ``Client.create_server``      | :meth:`Client.create_guild`      |
++-------------------------------+----------------------------------+
+
+.. _migrating_1_0_model_state:
+
+Models are Stateful
+~~~~~~~~~~~~~~~~~~~~~
+
+As mentioned earlier, a lot of functionality was moved out of :class:`Client` and
+put into their respective :ref:`model <discord_api_models>`.
+
+A list of these changes is enumerated below.
+
++---------------------------------------+------------------------------------------------------------------------------+
+|                 Before                |                                    After                                     |
++---------------------------------------+------------------------------------------------------------------------------+
+| ``Client.add_reaction``               | :meth:`Message.add_reaction`                                                 |
++---------------------------------------+------------------------------------------------------------------------------+
+| ``Client.add_roles``                  | :meth:`Member.add_roles`                                                     |
++---------------------------------------+------------------------------------------------------------------------------+
+| ``Client.ban``                        | :meth:`Member.ban` or :meth:`Guild.ban`                                      |
++---------------------------------------+------------------------------------------------------------------------------+
+| ``Client.change_nickname``            | :meth:`Member.edit`                                                          |
++---------------------------------------+------------------------------------------------------------------------------+
+| ``Client.clear_reactions``            | :meth:`Message.clear_reactions`                                              |
++---------------------------------------+------------------------------------------------------------------------------+
+| ``Client.create_channel``             | :meth:`Guild.create_text_channel` and :meth:`Guild.create_voice_channel`     |
++---------------------------------------+------------------------------------------------------------------------------+
+| ``Client.create_custom_emoji``        | :meth:`Guild.create_custom_emoji`                                            |
++---------------------------------------+------------------------------------------------------------------------------+
+| ``Client.create_invite``              | :meth:`abc.GuildChannel.create_invite`                                       |
++---------------------------------------+------------------------------------------------------------------------------+
+| ``Client.create_role``                | :meth:`Guild.create_role`                                                    |
++---------------------------------------+------------------------------------------------------------------------------+
+| ``Client.delete_channel``             | :meth:`abc.GuildChannel.delete`                                              |
++---------------------------------------+------------------------------------------------------------------------------+
+| ``Client.delete_channel_permissions`` | :meth:`abc.GuildChannel.set_permissions` with ``overwrite`` set to ``None``  |
++---------------------------------------+------------------------------------------------------------------------------+
+| ``Client.delete_custom_emoji``        | :meth:`Emoji.delete`                                                         |
++---------------------------------------+------------------------------------------------------------------------------+
+| ``Client.delete_invite``              | :meth:`Invite.delete` or :meth:`Client.delete_invite`                        |
++---------------------------------------+------------------------------------------------------------------------------+
+| ``Client.delete_message``             | :meth:`Message.delete`                                                       |
++---------------------------------------+------------------------------------------------------------------------------+
+| ``Client.delete_messages``            | :meth:`TextChannel.delete_messages`                                          |
++---------------------------------------+------------------------------------------------------------------------------+
+| ``Client.delete_role``                | :meth:`Role.delete`                                                          |
++---------------------------------------+------------------------------------------------------------------------------+
+| ``Client.delete_server``              | :meth:`Guild.delete`                                                         |
++---------------------------------------+------------------------------------------------------------------------------+
+| ``Client.edit_channel``               | :meth:`TextChannel.edit` or :meth:`VoiceChannel.edit`                        |
++---------------------------------------+------------------------------------------------------------------------------+
+| ``Client.edit_channel_permissions``   | :meth:`abc.GuildChannel.set_permissions`                                     |
++---------------------------------------+------------------------------------------------------------------------------+
+| ``Client.edit_custom_emoji``          | :meth:`Emoji.edit`                                                           |
++---------------------------------------+------------------------------------------------------------------------------+
+| ``Client.edit_message``               | :meth:`Message.edit`                                                         |
++---------------------------------------+------------------------------------------------------------------------------+
+| ``Client.edit_profile``               | :meth:`ClientUser.edit` (you get this from :attr:`Client.user`)              |
++---------------------------------------+------------------------------------------------------------------------------+
+| ``Client.edit_role``                  | :meth:`Role.edit`                                                            |
++---------------------------------------+------------------------------------------------------------------------------+
+| ``Client.edit_server``                | :meth:`Guild.edit`                                                           |
++---------------------------------------+------------------------------------------------------------------------------+
+| ``Client.estimate_pruned_members``    | :meth:`Guild.estimate_pruned_members`                                        |
++---------------------------------------+------------------------------------------------------------------------------+
+| ``Client.get_all_emojis``             | :attr:`Client.emojis`                                                        |
++---------------------------------------+------------------------------------------------------------------------------+
+| ``Client.get_bans``                   | :meth:`Guild.bans`                                                           |
++---------------------------------------+------------------------------------------------------------------------------+
+| ``Client.get_invite``                 | :meth:`Client.fetch_invite`                                                  |
++---------------------------------------+------------------------------------------------------------------------------+
+| ``Client.get_message``                | :meth:`abc.Messageable.fetch_message`                                        |
++---------------------------------------+------------------------------------------------------------------------------+
+| ``Client.get_reaction_users``         | :meth:`Reaction.users`                                                       |
++---------------------------------------+------------------------------------------------------------------------------+
+| ``Client.get_user_info``              | :meth:`Client.fetch_user`                                                    |
++---------------------------------------+------------------------------------------------------------------------------+
+| ``Client.invites_from``               | :meth:`abc.GuildChannel.invites` or :meth:`Guild.invites`                    |
++---------------------------------------+------------------------------------------------------------------------------+
+| ``Client.join_voice_channel``         | :meth:`VoiceChannel.connect` (see :ref:`migrating_1_0_voice`)                |
++---------------------------------------+------------------------------------------------------------------------------+
+| ``Client.kick``                       | :meth:`Guild.kick` or :meth:`Member.kick`                                    |
++---------------------------------------+------------------------------------------------------------------------------+
+| ``Client.leave_server``               | :meth:`Guild.leave`                                                          |
++---------------------------------------+------------------------------------------------------------------------------+
+| ``Client.logs_from``                  | :meth:`abc.Messageable.history` (see :ref:`migrating_1_0_async_iter`)        |
++---------------------------------------+------------------------------------------------------------------------------+
+| ``Client.move_channel``               | :meth:`TextChannel.edit` or :meth:`VoiceChannel.edit`                        |
++---------------------------------------+------------------------------------------------------------------------------+
+| ``Client.move_member``                | :meth:`Member.edit`                                                          |
++---------------------------------------+------------------------------------------------------------------------------+
+| ``Client.move_role``                  | :meth:`Role.edit`                                                            |
++---------------------------------------+------------------------------------------------------------------------------+
+| ``Client.pin_message``                | :meth:`Message.pin`                                                          |
++---------------------------------------+------------------------------------------------------------------------------+
+| ``Client.pins_from``                  | :meth:`abc.Messageable.pins`                                                 |
++---------------------------------------+------------------------------------------------------------------------------+
+| ``Client.prune_members``              | :meth:`Guild.prune_members`                                                  |
++---------------------------------------+------------------------------------------------------------------------------+
+| ``Client.purge_from``                 | :meth:`TextChannel.purge`                                                    |
++---------------------------------------+------------------------------------------------------------------------------+
+| ``Client.remove_reaction``            | :meth:`Message.remove_reaction`                                              |
++---------------------------------------+------------------------------------------------------------------------------+
+| ``Client.remove_roles``               | :meth:`Member.remove_roles`                                                  |
++---------------------------------------+------------------------------------------------------------------------------+
+| ``Client.replace_roles``              | :meth:`Member.edit`                                                          |
++---------------------------------------+------------------------------------------------------------------------------+
+| ``Client.send_file``                  | :meth:`abc.Messageable.send` (see :ref:`migrating_1_0_sending_messages`)     |
++---------------------------------------+------------------------------------------------------------------------------+
+| ``Client.send_message``               | :meth:`abc.Messageable.send` (see :ref:`migrating_1_0_sending_messages`)     |
++---------------------------------------+------------------------------------------------------------------------------+
+| ``Client.send_typing``                | :meth:`abc.Messageable.trigger_typing` (use :meth:`abc.Messageable.typing`)  |
++---------------------------------------+------------------------------------------------------------------------------+
+| ``Client.server_voice_state``         | :meth:`Member.edit`                                                          |
++---------------------------------------+------------------------------------------------------------------------------+
+| ``Client.start_private_message``      | :meth:`User.create_dm`                                                       |
++---------------------------------------+------------------------------------------------------------------------------+
+| ``Client.unban``                      | :meth:`Guild.unban` or :meth:`Member.unban`                                  |
++---------------------------------------+------------------------------------------------------------------------------+
+| ``Client.unpin_message``              | :meth:`Message.unpin`                                                        |
++---------------------------------------+------------------------------------------------------------------------------+
+| ``Client.wait_for_message``           | :meth:`Client.wait_for` (see :ref:`migrating_1_0_wait_for`)                  |
++---------------------------------------+------------------------------------------------------------------------------+
+| ``Client.wait_for_reaction``          | :meth:`Client.wait_for` (see :ref:`migrating_1_0_wait_for`)                  |
++---------------------------------------+------------------------------------------------------------------------------+
+| ``Client.wait_until_login``           | Removed                                                                      |
++---------------------------------------+------------------------------------------------------------------------------+
+| ``Client.wait_until_ready``           | No change                                                                    |
++---------------------------------------+------------------------------------------------------------------------------+
+
+Property Changes
+~~~~~~~~~~~~~~~~~~
+
+In order to be a bit more consistent, certain things that were properties were changed to methods instead.
+
+The following are now methods instead of properties (requires parentheses):
+
+- :meth:`Role.is_default`
+- :meth:`Client.is_ready`
+- :meth:`Client.is_closed`
+
+Dict Value Change
+~~~~~~~~~~~~~~~~~~~~~
+
+Prior to v1.0 some aggregating properties that retrieved models would return "dict view" objects.
+
+As a consequence, when the dict would change size while you would iterate over it, a RuntimeError would
+be raised and crash the task. To alleviate this, the "dict view" objects were changed into lists.
+
+The following views were changed to a list:
+
+- :attr:`Client.guilds`
+- :attr:`Client.users` (new in v1.0)
+- :attr:`Client.emojis` (new in v1.0)
+- :attr:`Guild.channels`
+- :attr:`Guild.text_channels` (new in v1.0)
+- :attr:`Guild.voice_channels` (new in v1.0)
+- :attr:`Guild.emojis`
+- :attr:`Guild.members`
+
+Voice State Changes
+~~~~~~~~~~~~~~~~~~~~~
+
+Earlier, in v0.11.0 a :class:`VoiceState` class was added to refer to voice states along with a
+:attr:`Member.voice` attribute to refer to it.
+
+However, it was transparent to the user. In an effort to make the library save more memory, the
+voice state change is now more visible.
+
+The only way to access voice attributes is via the :attr:`Member.voice` attribute. Note that if
+the member does not have a voice state this attribute can be ``None``.
+
+Quick example: ::
+
+    # before
+    member.deaf
+    member.voice.voice_channel
+
+    # after
+    if member.voice: # can be None
+        member.voice.deaf
+        member.voice.channel
+
+
+User and Member Type Split
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+In v1.0 to save memory, :class:`User` and :class:`Member` are no longer inherited. Instead, they are "flattened"
+by having equivalent properties that map out to the functional underlying :class:`User`. Thus, there is no functional
+change in how they are used. However this breaks :func:`isinstance` checks and thus is something to keep in mind.
+
+These memory savings were accomplished by having a global :class:`User` cache, and as a positive consequence you
+can now easily fetch a :class:`User` by their ID by using the new :meth:`Client.get_user`. You can also get a list
+of all :class:`User` your client can see with :attr:`Client.users`.
+
+.. _migrating_1_0_channel_split:
+
+Channel Type Split
+~~~~~~~~~~~~~~~~~~~~~
+
+Prior to v1.0, channels were two different types, ``Channel`` and ``PrivateChannel`` with a ``is_private``
+property to help differentiate between them.
+
+In order to save memory the channels have been split into 4 different types:
+
+- :class:`TextChannel` for guild text channels.
+- :class:`VoiceChannel` for guild voice channels.
+- :class:`DMChannel` for DM channels with members.
+- :class:`GroupChannel` for Group DM channels with members.
+
+With this split came the removal of the ``is_private`` attribute. You should now use :func:`isinstance`.
+
+The types are split into two different :ref:`discord_api_abcs`:
+
+- :class:`abc.GuildChannel` for guild channels.
+- :class:`abc.PrivateChannel` for private channels (DMs and group DMs).
+
+So to check if something is a guild channel you would do: ::
+
+    isinstance(channel, discord.abc.GuildChannel)
+
+And to check if it's a private channel you would do: ::
+
+    isinstance(channel, discord.abc.PrivateChannel)
+
+Of course, if you're looking for only a specific type you can pass that too, e.g. ::
+
+    isinstance(channel, discord.TextChannel)
+
+With this type split also came event changes, which are enumerated in :ref:`migrating_1_0_event_changes`.
+
+
+Miscellaneous Model Changes
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+There were lots of other things added or removed in the models in general.
+
+They will be enumerated here.
+
+**Removed**
+
+- :meth:`Client.login` no longer accepts email and password logins.
+
+    - Use a token and ``bot=False``.
+
+- ``Client.get_all_emojis``
+
+    - Use :attr:`Client.emojis` instead.
+
+- ``Client.messages``
+
+    - Use read-only :attr:`Client.cached_messages` instead.
+
+- ``Client.wait_for_message`` and ``Client.wait_for_reaction`` are gone.
+
+    - Use :meth:`Client.wait_for` instead.
+
+- ``Channel.voice_members``
+
+    - Use :attr:`VoiceChannel.members` instead.
+
+- ``Channel.is_private``
+
+    - Use ``isinstance`` instead with one of the :ref:`discord_api_abcs` instead.
+    - e.g. ``isinstance(channel, discord.abc.GuildChannel)`` will check if it isn't a private channel.
+
+- ``Client.accept_invite``
+
+    - There is no replacement for this one. This functionality is deprecated API wise.
+
+- ``Guild.default_channel`` / ``Server.default_channel`` and ``Channel.is_default``
+
+    - The concept of a default channel was removed from Discord.
+      See `#329 <https://github.com/hammerandchisel/discord-api-docs/pull/329>`_.
+
+- ``Message.edited_timestamp``
+
+    - Use :attr:`Message.edited_at` instead.
+
+- ``Message.timestamp``
+
+    - Use :attr:`Message.created_at` instead.
+
+- ``Colour.to_tuple()``
+
+    - Use :meth:`Colour.to_rgb` instead.
+
+- ``Permissions.view_audit_logs``
+
+    - Use :attr:`Permissions.view_audit_log` instead.
+
+- ``Member.game``
+
+    - Use :attr:`Member.activities` instead.
+
+- ``Guild.role_hierarchy`` / ``Server.role_hierarchy``
+
+    - Use :attr:`Guild.roles` instead. Note that while sorted, it is in the opposite order
+      of what the old ``Guild.role_hierarchy`` used to be.
+
+**Changed**
+
+- :attr:`Member.avatar_url` and :attr:`User.avatar_url` now return the default avatar if a custom one is not set.
+- :attr:`Message.embeds` is now a list of :class:`Embed` instead of :class:`dict` objects.
+- :attr:`Message.attachments` is now a list of :class:`Attachment` instead of :class:`dict` object.
+- :attr:`Guild.roles` is now sorted through hierarchy. The first element is always the ``@everyone`` role.
+
+**Added**
+
+- :class:`Attachment` to represent a discord attachment.
+- :class:`CategoryChannel` to represent a channel category.
+- :attr:`VoiceChannel.members` for fetching members connected to a voice channel.
+- :attr:`TextChannel.members` for fetching members that can see the channel.
+- :attr:`Role.members` for fetching members that have the role.
+- :attr:`Guild.text_channels` for fetching text channels only.
+- :attr:`Guild.voice_channels` for fetching voice channels only.
+- :attr:`Guild.categories` for fetching channel categories only.
+- :attr:`TextChannel.category` and :attr:`VoiceChannel.category` to get the category a channel belongs to.
+- :meth:`Guild.by_category` to get channels grouped by their category.
+- :attr:`Guild.chunked` to check member chunking status.
+- :attr:`Guild.explicit_content_filter` to fetch the content filter.
+- :attr:`Guild.shard_id` to get a guild's Shard ID if you're sharding.
+- :attr:`Client.users` to get all visible :class:`User` instances.
+- :meth:`Client.get_user` to get a :class:`User` by ID.
+- :meth:`User.avatar_url_as` to get an avatar in a specific size or format.
+- :meth:`Guild.vanity_invite` to fetch the guild's vanity invite.
+- :meth:`Guild.audit_logs` to fetch the guild's audit logs.
+- :attr:`Message.webhook_id` to fetch the message's webhook ID.
+- :attr:`Message.activity` and :attr:`Message.application` for Rich Presence related information.
+- :meth:`TextChannel.is_nsfw` to check if a text channel is NSFW.
+- :meth:`Colour.from_rgb` to construct a :class:`Colour` from RGB tuple.
+- :meth:`Guild.get_role` to get a role by its ID.
+
+.. _migrating_1_0_sending_messages:
+
+Sending Messages
+------------------
+
+One of the changes that were done was the merger of the previous ``Client.send_message`` and ``Client.send_file``
+functionality into a single method, :meth:`~abc.Messageable.send`.
+
+Basically: ::
+
+    # before
+    await client.send_message(channel, 'Hello')
+
+    # after
+    await channel.send('Hello')
+
+This supports everything that the old ``send_message`` supported such as embeds: ::
+
+    e = discord.Embed(title='foo')
+    await channel.send('Hello', embed=e)
+
+There is a caveat with sending files however, as this functionality was expanded to support multiple
+file attachments, you must now use a :class:`File` pseudo-namedtuple to upload a single file. ::
+
+    # before
+    await client.send_file(channel, 'cool.png', filename='testing.png', content='Hello')
+
+    # after
+    await channel.send('Hello', file=discord.File('cool.png', 'testing.png'))
+
+This change was to facilitate multiple file uploads: ::
+
+    my_files = [
+        discord.File('cool.png', 'testing.png'),
+        discord.File(some_fp, 'cool_filename.png'),
+    ]
+
+    await channel.send('Your images:', files=my_files)
+
+.. _migrating_1_0_async_iter:
+
+Asynchronous Iterators
+------------------------
+
+Prior to v1.0, certain functions like ``Client.logs_from`` would return a different type if done in Python 3.4 or 3.5+.
+
+In v1.0, this change has been reverted and will now return a singular type meeting an abstract concept called
+:class:`AsyncIterator`.
+
+This allows you to iterate over it like normal: ::
+
+    async for message in channel.history():
+        print(message)
+
+Or turn it into a list: ::
+
+    messages = await channel.history().flatten()
+    for message in messages:
+        print(message)
+
+A handy aspect of returning :class:`AsyncIterator` is that it allows you to chain functions together such as
+:meth:`AsyncIterator.map` or :meth:`AsyncIterator.filter`: ::
+
+    async for m_id in channel.history().filter(lambda m: m.author == client.user).map(lambda m: m.id):
+        print(m_id)
+
+The functions passed to :meth:`AsyncIterator.map` or :meth:`AsyncIterator.filter` can be either coroutines or regular
+functions.
+
+You can also get single elements a la :func:`discord.utils.find` or :func:`discord.utils.get` via
+:meth:`AsyncIterator.get` or :meth:`AsyncIterator.find`: ::
+
+    my_last_message = await channel.history().get(author=client.user)
+
+The following return :class:`AsyncIterator`:
+
+- :meth:`abc.Messageable.history`
+- :meth:`Guild.audit_logs`
+- :meth:`Reaction.users`
+
+.. _migrating_1_0_event_changes:
+
+Event Changes
+--------------
+
+A lot of events have gone through some changes.
+
+Many events with ``server`` in the name were changed to use ``guild`` instead.
+
+Before:
+
+- ``on_server_join``
+- ``on_server_remove``
+- ``on_server_update``
+- ``on_server_role_create``
+- ``on_server_role_delete``
+- ``on_server_role_update``
+- ``on_server_emojis_update``
+- ``on_server_available``
+- ``on_server_unavailable``
+
+After:
+
+- :func:`on_guild_join`
+- :func:`on_guild_remove`
+- :func:`on_guild_update`
+- :func:`on_guild_role_create`
+- :func:`on_guild_role_delete`
+- :func:`on_guild_role_update`
+- :func:`on_guild_emojis_update`
+- :func:`on_guild_available`
+- :func:`on_guild_unavailable`
+
+
+The :func:`on_voice_state_update` event has received an argument change.
+
+Before: ::
+
+    async def on_voice_state_update(before, after)
+
+After: ::
+
+    async def on_voice_state_update(member, before, after)
+
+Instead of two :class:`Member` objects, the new event takes one :class:`Member` object and two :class:`VoiceState` objects.
+
+The :func:`on_guild_emojis_update` event has received an argument change.
+
+Before: ::
+
+    async def on_guild_emojis_update(before, after)
+
+After: ::
+
+    async def on_guild_emojis_update(guild, before, after)
+
+The first argument is now the :class:`Guild` that the emojis were updated from.
+
+The :func:`on_member_ban` event has received an argument change as well:
+
+Before: ::
+
+    async def on_member_ban(member)
+
+After: ::
+
+    async def on_member_ban(guild, user)
+
+As part of the change, the event can either receive a :class:`User` or :class:`Member`. To help in the cases that have
+:class:`User`, the :class:`Guild` is provided as the first parameter.
+
+The ``on_channel_`` events have received a type level split (see :ref:`migrating_1_0_channel_split`).
+
+Before:
+
+- ``on_channel_delete``
+- ``on_channel_create``
+- ``on_channel_update``
+
+After:
+
+- :func:`on_guild_channel_delete`
+- :func:`on_guild_channel_create`
+- :func:`on_guild_channel_update`
+- :func:`on_private_channel_delete`
+- :func:`on_private_channel_create`
+- :func:`on_private_channel_update`
+
+The ``on_guild_channel_`` events correspond to :class:`abc.GuildChannel` being updated (i.e. :class:`TextChannel`
+and :class:`VoiceChannel`) and the ``on_private_channel_`` events correspond to :class:`abc.PrivateChannel` being
+updated (i.e. :class:`DMChannel` and :class:`GroupChannel`).
+
+.. _migrating_1_0_voice:
+
+Voice Changes
+---------------
+
+Voice sending has gone through a complete redesign.
+
+In particular:
+
+- Connection is done through :meth:`VoiceChannel.connect` instead of ``Client.join_voice_channel``.
+- You no longer create players and operate on them (you no longer store them).
+- You instead request :class:`VoiceClient` to play an :class:`AudioSource` via :meth:`VoiceClient.play`.
+- There are different built-in :class:`AudioSource`\s.
+
+  - :class:`FFmpegPCMAudio` is the equivalent of ``create_ffmpeg_player``
+
+- create_ffmpeg_player/create_stream_player/create_ytdl_player have all been removed.
+
+  - The goal is to create :class:`AudioSource` instead.
+
+- Using :meth:`VoiceClient.play` will not return an ``AudioPlayer``.
+
+  - Instead, it's "flattened" like :class:`User` -> :class:`Member` is.
+
+- The ``after`` parameter now takes a single parameter (the error).
+
+Basically:
+
+Before: ::
+
+    vc = await client.join_voice_channel(channel)
+    player = vc.create_ffmpeg_player('testing.mp3', after=lambda: print('done'))
+    player.start()
+
+    player.is_playing()
+    player.pause()
+    player.resume()
+    player.stop()
+    # ...
+
+After: ::
+
+    vc = await channel.connect()
+    vc.play(discord.FFmpegPCMAudio('testing.mp3'), after=lambda e: print('done', e))
+    vc.is_playing()
+    vc.pause()
+    vc.resume()
+    vc.stop()
+    # ...
+
+With the changed :class:`AudioSource` design, you can now change the source that the :class:`VoiceClient` is
+playing at runtime via :attr:`VoiceClient.source`.
+
+For example, you can add a :class:`PCMVolumeTransformer` to allow changing the volume: ::
+
+    vc.source = discord.PCMVolumeTransformer(vc.source)
+    vc.source.volume = 0.6
+
+An added benefit of the redesign is that it will be much more resilient towards reconnections:
+
+- The voice websocket will now automatically re-connect and re-do the handshake when disconnected.
+- The initial connect handshake will now retry up to 5 times so you no longer get as many ``asyncio.TimeoutError``.
+- Audio will now stop and resume when a disconnect is found.
+
+  - This includes changing voice regions etc.
+
+
+.. _migrating_1_0_wait_for:
+
+Waiting For Events
+--------------------
+
+Prior to v1.0, the machinery for waiting for an event outside of the event itself was done through two different
+functions, ``Client.wait_for_message`` and ``Client.wait_for_reaction``. One problem with one such approach is that it did
+not allow you to wait for events outside of the ones provided by the library.
+
+In v1.0 the concept of waiting for another event has been generalised to work with any event as :meth:`Client.wait_for`.
+
+For example, to wait for a message: ::
+
+    # before
+    msg = await client.wait_for_message(author=message.author, channel=message.channel)
+
+    # after
+    def pred(m):
+        return m.author == message.author and m.channel == message.channel
+
+    msg = await client.wait_for('message', check=pred)
+
+To facilitate multiple returns, :meth:`Client.wait_for` returns either a single argument, no arguments, or a tuple of
+arguments.
+
+For example, to wait for a reaction: ::
+
+    reaction, user = await client.wait_for('reaction_add', check=lambda r, u: u.id == 176995180300206080)
+
+    # use user and reaction
+
+Since this function now can return multiple arguments, the ``timeout`` parameter will now raise a :exc:`asyncio.TimeoutError`
+when reached instead of setting the return to ``None``. For example:
+
+.. code-block:: python3
+
+    def pred(m):
+        return m.author == message.author and m.channel == message.channel
+
+    try:
+
+        msg = await client.wait_for('message', check=pred, timeout=60.0)
+    except asyncio.TimeoutError:
+        await channel.send('You took too long...')
+    else:
+        await channel.send('You said {0.content}, {0.author}.'.format(msg))
+
+Upgraded Dependencies
+-----------------------
+
+Following v1.0 of the library, we've updated our requirements to :doc:`aiohttp <aio:index>` v2.0 or higher.
+
+Since this is a backwards incompatible change, it is recommended that you see the
+`changes <http://aiohttp.readthedocs.io/en/stable/changes.html#rc1-2017-03-15>`_
+and the :doc:`aio:migration_to_2xx` pages for details on the breaking changes in
+:doc:`aiohttp <aio:index>`.
+
+Of the most significant for common users is the removal of helper functions such as:
+
+- ``aiohttp.get``
+- ``aiohttp.post``
+- ``aiohttp.delete``
+- ``aiohttp.patch``
+- ``aiohttp.head``
+- ``aiohttp.put``
+- ``aiohttp.request``
+
+It is recommended that you create a session instead: ::
+
+    async with aiohttp.ClientSession() as sess:
+        async with sess.get('url') as resp:
+            # work with resp
+
+Since it is better to not create a session for every request, you should store it in a variable and then call
+``session.close`` on it when it needs to be disposed.
+
+Sharding
+----------
+
+The library has received significant changes on how it handles sharding and now has sharding as a first-class citizen.
+
+If using a Bot account and you want to shard your bot in a single process then you can use the :class:`AutoShardedClient`.
+
+This class allows you to use sharding without having to launch multiple processes or deal with complicated IPC.
+
+It should be noted that **the sharded client does not support user accounts**. This is due to the changes in connection
+logic and state handling.
+
+Usage is as simple as doing: ::
+
+    client = discord.AutoShardedClient()
+
+instead of using :class:`Client`.
+
+This will launch as many shards as your bot needs using the ``/gateway/bot`` endpoint, which allocates about 1000 guilds
+per shard.
+
+If you want more control over the sharding you can specify ``shard_count`` and ``shard_ids``. ::
+
+    # launch 10 shards regardless
+    client = discord.AutoShardedClient(shard_count=10)
+
+    # launch specific shard IDs in this process
+    client = discord.AutoShardedClient(shard_count=10, shard_ids=(1, 2, 5, 6))
+
+For users of the command extension, there is also :class:`~ext.commands.AutoShardedBot` which behaves similarly.
+
+Connection Improvements
+-------------------------
+
+In v1.0, the auto reconnection logic has been powered up significantly.
+
+:meth:`Client.connect` has gained a new keyword argument, ``reconnect`` that defaults to ``True`` which controls
+the reconnect logic. When enabled, the client will automatically reconnect in all instances of your internet going
+offline or Discord going offline with exponential back-off.
+
+:meth:`Client.run` and :meth:`Client.start` gains this keyword argument as well, but for most cases you will not
+need to specify it unless turning it off.
+
+.. _migrating_1_0_commands:
+
+Command Extension Changes
+--------------------------
+
+Due to the :ref:`migrating_1_0_model_state` changes, some of the design of the extension module had to
+undergo some design changes as well.
+
+Context Changes
+~~~~~~~~~~~~~~~~~
+
+In v1.0, the :class:`.Context` has received a lot of changes with how it's retrieved and used.
+
+The biggest change is that ``pass_context=True`` no longer exists, :class:`.Context` is always passed. Ergo:
+
+.. code-block:: python3
+
+    # before
+    @bot.command()
+    async def foo():
+        await bot.say('Hello')
+
+    # after
+    @bot.command()
+    async def foo(ctx):
+        await ctx.send('Hello')
+
+The reason for this is because :class:`~ext.commands.Context` now meets the requirements of :class:`abc.Messageable`. This
+makes it have similar functionality to :class:`TextChannel` or :class:`DMChannel`. Using :meth:`~.Context.send`
+will either DM the user in a DM context or send a message in the channel it was in, similar to the old ``bot.say``
+functionality. The old helpers have been removed in favour of the new :class:`abc.Messageable` interface. See
+:ref:`migrating_1_0_removed_helpers` for more information.
+
+Since the :class:`~ext.commands.Context` is now passed by default, several shortcuts have been added:
+
+**New Shortcuts**
+
+- :attr:`ctx.author <ext.commands.Context.author>` is a shortcut for ``ctx.message.author``.
+- :attr:`ctx.guild <ext.commands.Context.guild>` is a shortcut for ``ctx.message.guild``.
+- :attr:`ctx.channel <ext.commands.Context.channel>` is a shortcut for ``ctx.message.channel``.
+- :attr:`ctx.me <ext.commands.Context.me>` is a shortcut for ``ctx.message.guild.me`` or ``ctx.bot.user``.
+- :attr:`ctx.voice_client <ext.commands.Context.voice_client>` is a shortcut for ``ctx.message.guild.voice_client``.
+
+**New Functionality**
+
+- :meth:`.Context.reinvoke` to invoke a command again.
+
+    - This is useful for bypassing cooldowns.
+- :attr:`.Context.valid` to check if a context can be invoked with :meth:`.Bot.invoke`.
+- :meth:`.Context.send_help` to show the help command for an entity using the new :class:`~.ext.commands.HelpCommand` system.
+
+    - This is useful if you want to show the user help if they misused a command.
+
+Subclassing Context
+++++++++++++++++++++
+
+In v1.0, there is now the ability to subclass :class:`~ext.commands.Context` and use it instead of the default
+provided one.
+
+For example, if you want to add some functionality to the context:
+
+.. code-block:: python3
+
+    class MyContext(commands.Context):
+        @property
+        def secret(self):
+            return 'my secret here'
+
+Then you can use :meth:`~ext.commands.Bot.get_context` inside :func:`on_message` with combination with
+:meth:`~ext.commands.Bot.invoke` to use your custom context:
+
+.. code-block:: python3
+
+    class MyBot(commands.Bot):
+        async def on_message(self, message):
+            ctx = await self.get_context(message, cls=MyContext)
+            await self.invoke(ctx)
+
+Now inside your commands you will have access to your custom context:
+
+.. code-block:: python3
+
+    @bot.command()
+    async def secret(ctx):
+        await ctx.send(ctx.secret)
+
+.. _migrating_1_0_removed_helpers:
+
+Removed Helpers
++++++++++++++++++
+
+With the new :class:`.Context` changes, a lot of message sending helpers have been removed.
+
+For a full list of changes, see below:
+
++-----------------+------------------------------------------------------------+
+|      Before     |                           After                            |
++-----------------+------------------------------------------------------------+
+| ``Bot.say``     | :meth:`.Context.send`                                      |
++-----------------+------------------------------------------------------------+
+| ``Bot.upload``  | :meth:`.Context.send`                                      |
++-----------------+------------------------------------------------------------+
+| ``Bot.whisper`` | ``ctx.author.send``                                        |
++-----------------+------------------------------------------------------------+
+| ``Bot.type``    | :meth:`.Context.typing` or :meth:`.Context.trigger_typing` |
++-----------------+------------------------------------------------------------+
+| ``Bot.reply``   | No replacement.                                            |
++-----------------+------------------------------------------------------------+
+
+Command Changes
+~~~~~~~~~~~~~~~~~
+
+As mentioned earlier, the first command change is that ``pass_context=True`` no longer
+exists, so there is no need to pass this as a parameter.
+
+Another change is the removal of ``no_pm=True``. Instead, use the new :func:`~ext.commands.guild_only` built-in
+check.
+
+The ``commands`` attribute of :class:`~ext.commands.Bot` and :class:`~ext.commands.Group` have been changed from a
+dictionary to a set that does not have aliases. To retrieve the previous dictionary behaviour, use ``all_commands`` instead.
+
+Command instances have gained new attributes and properties:
+
+1. :attr:`~ext.commands.Command.signature` to get the signature of the command.
+2. :attr:`~.Command.usage`, an attribute to override the default signature.
+3. :attr:`~.Command.root_parent` to get the root parent group of a subcommand.
+
+For :class:`~ext.commands.Group` and :class:`~ext.commands.Bot` the following changed:
+
+- Changed :attr:`~.GroupMixin.commands` to be a :class:`set` without aliases.
+
+    - Use :attr:`~.GroupMixin.all_commands` to get the old :class:`dict` with all commands.
+
+Check Changes
+~~~~~~~~~~~~~~~
+
+Prior to v1.0, :func:`~ext.commands.check`\s could only be synchronous. As of v1.0 checks can now be coroutines.
+
+Along with this change, a couple new checks were added.
+
+- :func:`~ext.commands.guild_only` replaces the old ``no_pm=True`` functionality.
+- :func:`~ext.commands.is_owner` uses the :meth:`Client.application_info` endpoint by default to fetch owner ID.
+
+    - This is actually powered by a different function, :meth:`~ext.commands.Bot.is_owner`.
+    - You can set the owner ID yourself by setting :attr:`.Bot.owner_id`.
+
+- :func:`~ext.commands.is_nsfw` checks if the channel the command is in is a NSFW channel.
+
+    - This is powered by the new :meth:`TextChannel.is_nsfw` method.
+
+Event Changes
+~~~~~~~~~~~~~~~
+
+All command extension events have changed.
+
+Before: ::
+
+    on_command(command, ctx)
+    on_command_completion(command, ctx)
+    on_command_error(error, ctx)
+
+After: ::
+
+    on_command(ctx)
+    on_command_completion(ctx)
+    on_command_error(ctx, error)
+
+The extraneous ``command`` parameter in :func:`.on_command` and :func:`.on_command_completion`
+have been removed. The :class:`~ext.commands.Command` instance was not kept up-to date so it was incorrect. In order to get
+the up to date :class:`~ext.commands.Command` instance, use the :attr:`.Context.command`
+attribute.
+
+The error handlers, either :meth:`.Command.error` or :func:`.on_command_error`,
+have been re-ordered to use the :class:`~ext.commands.Context` as its first parameter to be consistent with other events
+and commands.
+
+HelpFormatter and Help Command Changes
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The ``HelpFormatter`` class has been removed. It has been replaced with a :class:`~.commands.HelpCommand` class. This class now stores all the command handling and processing of the help command.
+
+The help command is now stored in the :attr:`.Bot.help_command` attribute. As an added extension, you can disable the help command completely by assigning the attribute to ``None`` or passing it at ``__init__`` as ``help_command=None``.
+
+The new interface allows the help command to be customised through special methods that can be overridden.
+
+- :meth:`.HelpCommand.send_bot_help`
+    - Called when the user requested for help with the entire bot.
+- :meth:`.HelpCommand.send_cog_help`
+    - Called when the user requested for help with a specific cog.
+- :meth:`.HelpCommand.send_group_help`
+    - Called when the user requested for help with a :class:`~.commands.Group`
+- :meth:`.HelpCommand.send_command_help`
+    - Called when the user requested for help with a :class:`~.commands.Command`
+- :meth:`.HelpCommand.get_destination`
+    - Called to know where to send the help messages. Useful for deciding whether to DM or not.
+- :meth:`.HelpCommand.command_not_found`
+    - A function (or coroutine) that returns a presentable no command found string.
+- :meth:`.HelpCommand.subcommand_not_found`
+    - A function (or coroutine) that returns a string when a subcommand is not found.
+- :meth:`.HelpCommand.send_error_message`
+    - A coroutine that gets passed the result of :meth:`.HelpCommand.command_not_found` and :meth:`.HelpCommand.subcommand_not_found`.
+    - By default it just sends the message. But you can, for example, override it to put it in an embed.
+- :meth:`.HelpCommand.on_help_command_error`
+    - The :ref:`error handler <ext_commands_error_handler>` for the help command if you want to add one.
+- :meth:`.HelpCommand.prepare_help_command`
+    - A coroutine that is called right before the help command processing is done.
+
+Certain subclasses can implement more customisable methods.
+
+The old ``HelpFormatter`` was replaced with :class:`~.commands.DefaultHelpCommand`\, which implements all of the logic of the old help command. The customisable methods can be found in the accompanying documentation.
+
+The library now provides a new more minimalistic :class:`~.commands.HelpCommand` implementation that doesn't take as much space, :class:`~.commands.MinimalHelpCommand`. The customisable methods can also be found in the accompanying documentation.
+
+A frequent request was if you could associate a help command with a cog. The new design allows for dynamically changing of cog through binding it to the :attr:`.HelpCommand.cog` attribute. After this assignment the help command will pretend to be part of the cog and everything should work as expected. When the cog is unloaded then the help command will be "unbound" from the cog.
+
+For example, to implement a :class:`~.commands.HelpCommand` in a cog, the following snippet can be used.
+
+.. code-block:: python3
+
+    class MyHelpCommand(commands.MinimalHelpCommand):
+        def get_command_signature(self, command):
+            return '{0.clean_prefix}{1.qualified_name} {1.signature}'.format(self, command)
+
+    class MyCog(commands.Cog):
+        def __init__(self, bot):
+            self._original_help_command = bot.help_command
+            bot.help_command = MyHelpCommand()
+            bot.help_command.cog = self
+
+        def cog_unload(self):
+            self.bot.help_command = self._original_help_command
+
+For more information, check out the relevant :ref:`documentation <ext_commands_help_command>`.
+
+Cog Changes
+~~~~~~~~~~~~~
+
+Cogs have completely been revamped. They are documented in :ref:`ext_commands_cogs` as well.
+
+Cogs are now required to have a base class, :class:`~.commands.Cog` for future proofing purposes. This comes with special methods to customise some behaviour.
+
+* :meth:`.Cog.cog_unload`
+    - This is called when a cog needs to do some cleanup, such as cancelling a task.
+* :meth:`.Cog.bot_check_once`
+    - This registers a :meth:`.Bot.check_once` check.
+* :meth:`.Cog.bot_check`
+    - This registers a regular :meth:`.Bot.check` check.
+* :meth:`.Cog.cog_check`
+    - This registers a check that applies to every command in the cog.
+* :meth:`.Cog.cog_command_error`
+    - This is a special error handler that is called whenever an error happens inside the cog.
+* :meth:`.Cog.cog_before_invoke` and :meth:`.Cog.cog_after_invoke`
+    - A special method that registers a cog before and after invoke hook. More information can be found in :ref:`migrating_1_0_before_after_hook`.
+
+Those that were using listeners, such as ``on_message`` inside a cog will now have to explicitly mark them as such using the :meth:`.commands.Cog.listener` decorator.
+
+Along with that, cogs have gained the ability to have custom names through specifying it in the class definition line. More options can be found in the metaclass that facilitates all this, :class:`.commands.CogMeta`.
+
+An example cog with every special method registered and a custom name is as follows:
+
+.. code-block:: python3
+
+    class MyCog(commands.Cog, name='Example Cog'):
+        def cog_unload(self):
+            print('cleanup goes here')
+
+        def bot_check(self, ctx):
+            print('bot check')
+            return True
+
+        def bot_check_once(self, ctx):
+            print('bot check once')
+            return True
+
+        async def cog_check(self, ctx):
+            print('cog local check')
+            return await ctx.bot.is_owner(ctx.author)
+
+        async def cog_command_error(self, ctx, error):
+            print('Error in {0.command.qualified_name}: {1}'.format(ctx, error))
+
+        async def cog_before_invoke(self, ctx):
+            print('cog local before: {0.command.qualified_name}'.format(ctx))
+
+        async def cog_after_invoke(self, ctx):
+            print('cog local after: {0.command.qualified_name}'.format(ctx))
+
+        @commands.Cog.listener()
+        async def on_message(self, message):
+            pass
+
+
+.. _migrating_1_0_before_after_hook:
+
+Before and After Invocation Hooks
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Commands have gained new before and after invocation hooks that allow you to do an action before and after a command is
+run.
+
+They take a single parameter, :class:`~ext.commands.Context` and they must be a coroutine.
+
+They are on a global, per-cog, or per-command basis.
+
+Basically: ::
+
+
+    # global hooks:
+
+    @bot.before_invoke
+    async def before_any_command(ctx):
+        # do something before a command is called
+        pass
+
+    @bot.after_invoke
+    async def after_any_command(ctx):
+        # do something after a command is called
+        pass
+
+The after invocation is hook always called, **regardless of an error in the command**. This makes it ideal for some error
+handling or clean up of certain resources such a database connection.
+
+The per-command registration is as follows: ::
+
+    @bot.command()
+    async def foo(ctx):
+        await ctx.send('foo')
+
+    @foo.before_invoke
+    async def before_foo_command(ctx):
+        # do something before the foo command is called
+        pass
+
+    @foo.after_invoke
+    async def after_foo_command(ctx):
+        # do something after the foo command is called
+        pass
+
+The special cog method for these is :meth:`.Cog.cog_before_invoke` and :meth:`.Cog.cog_after_invoke`, e.g.:
+
+.. code-block:: python3
+
+    class MyCog(commands.Cog):
+        async def cog_before_invoke(self, ctx):
+            ctx.secret_cog_data = 'foo'
+
+        async def cog_after_invoke(self, ctx):
+            print('{0.command} is done...'.format(ctx))
+
+        @commands.command()
+        async def foo(self, ctx):
+            await ctx.send(ctx.secret_cog_data)
+
+To check if a command failed in the after invocation hook, you can use
+:attr:`.Context.command_failed`.
+
+The invocation order is as follows:
+
+1. Command local before invocation hook
+2. Cog local before invocation hook
+3. Global before invocation hook
+4. The actual command
+5. Command local after invocation hook
+6. Cog local after invocation hook
+7. Global after invocation hook
+
+Converter Changes
+~~~~~~~~~~~~~~~~~~~
+
+Prior to v1.0, a converter was a type hint that could be a callable that could be invoked
+with a singular argument denoting the argument passed by the user as a string.
+
+This system was eventually expanded to support a :class:`~ext.commands.Converter` system to
+allow plugging in the :class:`~ext.commands.Context` and do more complicated conversions such
+as the built-in "discord" converters.
+
+In v1.0 this converter system was revamped to allow instances of :class:`~ext.commands.Converter` derived
+classes to be passed. For consistency, the :meth:`~ext.commands.Converter.convert` method was changed to
+always be a coroutine and will now take the two arguments as parameters.
+
+Essentially, before: ::
+
+    class MyConverter(commands.Converter):
+        def convert(self):
+            return self.ctx.message.server.me
+
+After: ::
+
+    class MyConverter(commands.Converter):
+        async def convert(self, ctx, argument):
+            return ctx.me
+
+The command framework also got a couple new converters:
+
+- :class:`~ext.commands.clean_content` this is akin to :attr:`Message.clean_content` which scrubs mentions.
+- :class:`~ext.commands.UserConverter` will now appropriately convert :class:`User` only.
+- ``ChannelConverter`` is now split into two different converters.
+
+    - :class:`~ext.commands.TextChannelConverter` for :class:`TextChannel`.
+    - :class:`~ext.commands.VoiceChannelConverter` for :class:`VoiceChannel`.
diff --git a/docs/migrating_to_async.rst b/docs/migrating_to_async.rst
new file mode 100644
index 00000000..5c3f4bdf
--- /dev/null
+++ b/docs/migrating_to_async.rst
@@ -0,0 +1,322 @@
+:orphan:
+
+.. currentmodule:: discord
+
+.. _migrating-to-async:
+
+Migrating to v0.10.0
+======================
+
+v0.10.0 is one of the biggest breaking changes in the library due to massive
+fundamental changes in how the library operates.
+
+The biggest major change is that the library has dropped support to all versions prior to
+Python 3.4.2. This was made to support :mod:`asyncio`, in which more detail can be seen
+:old-issue:`in the corresponding issue <50>`. To reiterate this, the implication is that
+**python version 2.7 and 3.3 are no longer supported**.
+
+Below are all the other major changes from v0.9.0 to v0.10.0.
+
+Event Registration
+--------------------
+
+All events before were registered using :meth:`Client.event`. While this is still
+possible, the events must be decorated with ``@asyncio.coroutine``.
+
+Before:
+
+.. code-block:: python3
+
+    @client.event
+    def on_message(message):
+        pass
+
+After:
+
+.. code-block:: python3
+
+    @client.event
+    @asyncio.coroutine
+    def on_message(message):
+        pass
+
+Or in Python 3.5+:
+
+.. code-block:: python3
+
+    @client.event
+    async def on_message(message):
+        pass
+
+Because there is a lot of typing, a utility decorator (:meth:`Client.async_event`) is provided
+for easier registration. For example:
+
+.. code-block:: python3
+
+    @client.async_event
+    def on_message(message):
+        pass
+
+
+Be aware however, that this is still a coroutine and your other functions that are coroutines must
+be decorated with ``@asyncio.coroutine`` or be ``async def``.
+
+Event Changes
+--------------
+
+Some events in v0.9.0 were considered pretty useless due to having no separate states. The main
+events that were changed were the ``_update`` events since previously they had no context on what
+was changed.
+
+Before:
+
+.. code-block:: python3
+
+    def on_channel_update(channel): pass
+    def on_member_update(member): pass
+    def on_status(member): pass
+    def on_server_role_update(role): pass
+    def on_voice_state_update(member): pass
+    def on_socket_raw_send(payload, is_binary): pass
+
+
+After:
+
+.. code-block:: python3
+
+    def on_channel_update(before, after): pass
+    def on_member_update(before, after): pass
+    def on_server_role_update(before, after): pass
+    def on_voice_state_update(before, after): pass
+    def on_socket_raw_send(payload): pass
+
+Note that ``on_status`` was removed. If you want its functionality, use :func:`on_member_update`.
+See :ref:`discord-api-events` for more information. Other removed events include ``on_socket_closed``, ``on_socket_receive``, and ``on_socket_opened``.
+
+
+Coroutines
+-----------
+
+The biggest change that the library went through is that almost every function in :class:`Client`
+was changed to be a `coroutine <py:library/asyncio-task.html>`_. Functions
+that are marked as a coroutine in the documentation must be awaited from or yielded from in order
+for the computation to be done. For example...
+
+Before:
+
+.. code-block:: python3
+
+    client.send_message(message.channel, 'Hello')
+
+After:
+
+.. code-block:: python3
+
+    yield from client.send_message(message.channel, 'Hello')
+
+    # or in python 3.5+
+    await client.send_message(message.channel, 'Hello')
+
+In order for you to ``yield from`` or ``await`` a coroutine then your function must be decorated
+with ``@asyncio.coroutine`` or ``async def``.
+
+Iterables
+----------
+
+For performance reasons, many of the internal data structures were changed into a dictionary to support faster
+lookup. As a consequence, this meant that some lists that were exposed via the API have changed into iterables
+and not sequences. In short, this means that certain attributes now only support iteration and not any of the
+sequence functions.
+
+The affected attributes are as follows:
+
+- :attr:`Client.servers`
+- :attr:`Client.private_channels`
+- :attr:`Server.channels`
+- :attr:`Server.members`
+
+Some examples of previously valid behaviour that is now invalid
+
+.. code-block:: python3
+
+    if client.servers[0].name == "test":
+        # do something
+
+Since they are no longer :obj:`list`\s, they no longer support indexing or any operation other than iterating.
+In order to get the old behaviour you should explicitly cast it to a list.
+
+.. code-block:: python3
+
+    servers = list(client.servers)
+    # work with servers
+
+.. warning::
+
+    Due to internal changes of the structure, the order you receive the data in
+    is not in a guaranteed order.
+
+Enumerations
+------------
+
+Due to dropping support for versions lower than Python 3.4.2, the library can now use
+:doc:`py:library/enum` in places where it makes sense.
+
+The common places where this was changed was in the server region, member status, and channel type.
+
+Before:
+
+.. code-block:: python3
+
+    server.region == 'us-west'
+    member.status == 'online'
+    channel.type == 'text'
+
+After:
+
+.. code-block:: python3
+
+    server.region == discord.ServerRegion.us_west
+    member.status = discord.Status.online
+    channel.type == discord.ChannelType.text
+
+The main reason for this change was to reduce the use of finicky strings in the API as this
+could give users a false sense of power. More information can be found in the :ref:`discord-api-enums` page.
+
+Properties
+-----------
+
+A lot of function calls that returned constant values were changed into Python properties for ease of use
+in format strings.
+
+The following functions were changed into properties:
+
++----------------------------------------+--------------------------------------+
+|                 Before                 |                After                 |
++----------------------------------------+--------------------------------------+
+| ``User.avatar_url()``                  | :attr:`User.avatar_url`              |
++----------------------------------------+--------------------------------------+
+| ``User.mention()``                     | :attr:`User.mention`                 |
++----------------------------------------+--------------------------------------+
+| ``Channel.mention()``                  | :attr:`Channel.mention`              |
++----------------------------------------+--------------------------------------+
+| ``Channel.is_default_channel()``       | :attr:`Channel.is_default`           |
++----------------------------------------+--------------------------------------+
+| ``Role.is_everyone()``                 | :attr:`Role.is_everyone`             |
++----------------------------------------+--------------------------------------+
+| ``Server.get_default_role()``          | :attr:`Server.default_role`          |
++----------------------------------------+--------------------------------------+
+| ``Server.icon_url()``                  | :attr:`Server.icon_url`              |
++----------------------------------------+--------------------------------------+
+| ``Server.get_default_channel()``       | :attr:`Server.default_channel`       |
++----------------------------------------+--------------------------------------+
+| ``Message.get_raw_mentions()``         | :attr:`Message.raw_mentions`         |
++----------------------------------------+--------------------------------------+
+| ``Message.get_raw_channel_mentions()`` | :attr:`Message.raw_channel_mentions` |
++----------------------------------------+--------------------------------------+
+
+Member Management
+-------------------
+
+Functions that involved banning and kicking were changed.
+
++--------------------------------+--------------------------+
+| Before                         | After                    |
++--------------------------------+--------------------------+
+| ``Client.ban(server, user)``   | ``Client.ban(member)``   |
++--------------------------------+--------------------------+
+| ``Client.kick(server, user)``  | ``Client.kick(member)``  |
++--------------------------------+--------------------------+
+
+.. migrating-renames:
+
+Renamed Functions
+-------------------
+
+Functions have been renamed.
+
++------------------------------------+-------------------------------------------+
+| Before                             | After                                     |
++------------------------------------+-------------------------------------------+
+| ``Client.set_channel_permissions`` | :meth:`Client.edit_channel_permissions`   |
++------------------------------------+-------------------------------------------+
+
+All the :class:`Permissions` related attributes have been renamed and the `can_` prefix has been
+dropped. So for example, ``can_manage_messages`` has become ``manage_messages``.
+
+Forced Keyword Arguments
+-------------------------
+
+Since 3.0+ of Python, we can now force questions to take in forced keyword arguments. A keyword argument is when you
+explicitly specify the name of the variable and assign to it, for example: ``foo(name='test')``. Due to this support,
+some functions in the library were changed to force things to take said keyword arguments. This is to reduce errors of
+knowing the argument order and the issues that could arise from them.
+
+The following parameters are now exclusively keyword arguments:
+
+- :meth:`Client.send_message`
+    - ``tts``
+- :meth:`Client.logs_from`
+    - ``before``
+    - ``after``
+- :meth:`Client.edit_channel_permissions`
+    - ``allow``
+    - ``deny``
+
+In the documentation you can tell if a function parameter is a forced keyword argument if it is after ``\*,``
+in the function signature.
+
+.. _migrating-running:
+
+Running the Client
+--------------------
+
+In earlier versions of discord.py, ``client.run()`` was a blocking call to the main thread
+that called it. In v0.10.0 it is still a blocking call but it handles the event loop for you.
+However, in order to do that you must pass in your credentials to :meth:`Client.run`.
+
+Basically, before:
+
+.. code-block:: python3
+
+    client.login('token')
+    client.run()
+
+After:
+
+.. code-block:: python3
+
+    client.run('token')
+
+.. warning::
+
+    Like in the older ``Client.run`` function, the newer one must be the one of
+    the last functions to call. This is because the function is **blocking**. Registering
+    events or doing anything after :meth:`Client.run` will not execute until the function
+    returns.
+
+This is a utility function that abstracts the event loop for you. There's no need for
+the run call to be blocking and out of your control. Indeed, if you want control of the
+event loop then doing so is quite straightforward:
+
+.. code-block:: python3
+
+    import discord
+    import asyncio
+
+    client = discord.Client()
+
+    @asyncio.coroutine
+    def main_task():
+        yield from client.login('token')
+        yield from client.connect()
+
+    loop = asyncio.get_event_loop()
+    try:
+        loop.run_until_complete(main_task())
+    except:
+        loop.run_until_complete(client.logout())
+    finally:
+        loop.close()
+
+
+
diff --git a/docs/oauth2/api.rst b/docs/oauth2/api.rst
new file mode 100644
index 00000000..228180ab
--- /dev/null
+++ b/docs/oauth2/api.rst
@@ -0,0 +1,158 @@
+:og:title: discord4py OAuth2 API Reference
+:og:description: This section outlines the OAuth2 API of discord4py
+
+.. meta::
+    :description: This section outlines the OAuth2 API of discord4py
+
+.. currentmodule:: discord.oauth2
+
+
+OAuth2 API Reference
+====================
+
+.. _client:
+
+The following section outlines the OAuth2 API of discord4py
+
+OAuth2 Client
+~~~~~~~~~~~~~
+
+.. attributetable:: OAuth2Client
+
+.. autoclass:: OAuth2Client()
+    :members:
+
+Access Token Store
+~~~~~~~~~~~~~~~~~~
+
+.. attributetable:: AccessTokenStore
+
+.. autoclass:: AccessTokenStore()
+    :members:
+
+.. _models:
+
+Models
+------
+
+Access Token
+~~~~~~~~~~~~
+
+.. attributetable:: AccessToken
+
+.. autoclass:: AccessToken()
+    :members:
+
+Access Token Info
+~~~~~~~~~~~~~~~~~
+
+.. attributetable:: AccessTokenInfo
+
+.. autoclass:: AccessTokenInfo()
+    :members:
+
+.. autoclass:: PartialAppInfo()
+    :members:
+
+Connection
+~~~~~~~~~~
+
+.. attributetable:: Connection
+
+.. autoclass:: Connection()
+    :members:
+
+Role Connection
+~~~~~~~~~~~~~~~
+
+.. attributetable:: RoleConnection
+
+.. autoclass:: RoleConnection()
+    :members:
+
+Partial Guild
+~~~~~~~~~~~~~
+
+.. attributetable:: PartialGuild
+
+.. autoclass:: PartialGuild()
+    :members:
+    :inherited-members:
+
+Guild Member
+~~~~~~~~~~~~
+
+.. attributetable:: GuildMember
+
+.. autoclass:: GuildMember
+    :members:
+    :inherited-members:
+
+Partial Guild Integration
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. attributetable:: PartialGuildIntegration
+
+.. autoclass:: PartialGuildIntegration()
+    :members:
+    :inherited-members:
+
+User
+~~~~
+
+.. autoclass:: User()
+    :members:
+    :inherited-members:
+
+Partial User
+~~~~~~~~~~~~
+
+.. attributetable:: PartialUser
+
+.. autoclass:: PartialUser()
+    :members:
+    :inherited-members:
+
+.. _enumerations:
+
+Enumerations
+------------
+
+.. autoclass:: OAuth2Scope()
+
+.. autoclass:: ConnectionService()
+
+Exceptions
+----------
+The following exceptions are thrown by the oauth2 sub-package
+
+.. _exceptions:
+
+.. autoexception:: OAuth2Exception
+
+.. autoexception:: AccessTokenExpired
+    :members:
+
+.. autoexception:: AccessTokenNotRefreshable
+
+.. autoexception:: InvalidAccessToken
+
+.. autoexception:: InvalidRefreshToken
+
+.. autoexception:: InvalidAuthorizationCode
+
+.. autoexception:: UserIsAtGuildLimit
+
+Exception Hierarchy
+~~~~~~~~~~~~~~~~~~~~~
+
+.. exception_hierarchy::
+
+    - :exc:`discord.DiscordException`
+        - :exc:`OAuth2Exception`
+            - :exc:`AccessTokenExpired`
+            - :exc:`AccessTokenNotRefreshable`
+            - :exc:`InvalidAccessToken`
+            - :exc:`InvalidRefreshToken`
+            - :exc:`InvalidAuthorizationCode`
+            - :exc:`UserIsAtGuildLimit`
diff --git a/docs/oauth2/index.rst b/docs/oauth2/index.rst
new file mode 100644
index 00000000..a775380a
--- /dev/null
+++ b/docs/oauth2/index.rst
@@ -0,0 +1,39 @@
+:og:title: discord4py OAuth2 documentation
+:og:description: Use discord4pys build-in oauth2 package to interact with discords OAuth2 API
+
+.. currentmodule:: discord.oauth2
+
+OAuth2
+=======
+
+.. warning::
+
+    **This feature is new in the library and may miss some parts.**
+
+    If you find anything that looks wrong whether it is a bug/missing feature or something in the documentation, please fill out a |bugreport|
+
+    *PS: As always, feel free to contribute and help us improve.*
+
+OAuth2 enables application developers to build applications that utilize authentication and data from the Discord API.
+Discord supports multiple types of OAuth2 authentication:
+
+    - the authorization code grant
+    - the implicit grant
+    - client credentials
+
+and some modified special-for-Discord flows for Bots and Webhooks.
+
+.. code-block:: python3
+
+    import discord.oauth2 as oauth2
+
+Manuals
+-------
+
+These pages go into great detail about everything the API can do.
+
+
+.. toctree::
+    :maxdepth: 1
+
+    Main Oauth2 API <api.rst>
\ No newline at end of file
diff --git a/docs/quickstart.rst b/docs/quickstart.rst
new file mode 100644
index 00000000..d5c214ab
--- /dev/null
+++ b/docs/quickstart.rst
@@ -0,0 +1,71 @@
+.. _quickstart:
+
+.. currentmodule:: discord
+
+Quickstart
+============
+
+This page gives a brief introduction to the library. It assumes you have the library installed,
+if you don't check the :ref:`installing` portion.
+
+A Minimal Bot
+---------------
+
+Let's make a bot that responds to a specific message and walk you through it.
+
+It looks something like this:
+
+.. code-block:: python3
+
+    import discord
+
+    client = discord.Client()
+
+    @client.event
+    async def on_ready():
+        print('We have logged in as {0.user}'.format(client))
+
+    @client.event
+    async def on_message(message):
+        if message.author == client.user:
+            return
+
+        if message.content.startswith('$hello'):
+            await message.channel.send('Hello!')
+
+    client.run('your token here')
+
+Let's name this file ``example_bot.py``. Make sure not to name it ``discord.py-message-components`` or ``discord`` as that'll conflict
+with the library.
+
+There's a lot going on here, so let's walk you through it step by step.
+
+1. The first line just imports the library, if this raises a :exc:`ModuleNotFoundError` or :exc:`ImportError` then head on over to :ref:`installing` section to properly install.
+
+2. Next, we create an instance of a :class:`Client`. This client is our connection to Discord.
+
+3. We then use the :meth:`Client.event` decorator to register an event. This library has many events. Since this library is asynchronous, we do things in a "callback" style manner. A callback is essentially a function that is called when something happens. In our case, the :func:`on_ready` event is called when the bot has finished logging in and setting things up and the :func:`on_message` event is called when the bot has received a message.
+
+4. Since the :func:`on_message` event triggers for *every* message received, we have to make sure that we ignore messages from ourselves. We do this by checking if the :attr:`Message.author` is the same as the :attr:`Client.user`.
+
+5. Afterwards, we check if the :attr:`Message.content` starts with ``'$hello'``. If it does, then we send a message in the channel it was used in with ``'Hello!'``. This is a basic way of handling commands, which can be later automated with the :ref:`ext.commands <discord_ext_commands>` framework.
+
+6. Finally, we run the bot with our login token. If you need help getting your token or creating a bot, look in the :ref:`discord-intro` section.
+
+
+Now that we've made a bot, we have to *run* the bot. Luckily, this is simple since this is just a
+Python script, we can run it directly.
+
+On Windows:
+
+.. code-block:: shell
+
+    $ py -3 example_bot.py
+
+On other systems:
+
+.. code-block:: shell
+
+    $ python3 example_bot.py
+
+Now you can try playing around with your basic bot.
diff --git a/docs/requests.inv b/docs/requests.inv
new file mode 100644
index 00000000..7deac0ce
Binary files /dev/null and b/docs/requests.inv differ
diff --git a/docs/requirements.txt b/docs/requirements.txt
index 0d94cbb0..5c9af9f9 100644
--- a/docs/requirements.txt
+++ b/docs/requirements.txt
@@ -1,3 +1,13 @@
-sphinx-rtd-theme==0.5.2
-sphinxcontrib-contentui==0.2.5
-aiohttp>=3.9.2,<4
+sphinx
+sphinx-autobuild
+sphinxcontrib-contentui==0.2.5
+sphinxcontrib-websupport
+sphinxcontrib-trio
+sphinxext-opengraph
+sphinx_inline_tabs
+Jinja2>0.3
+pygments
+typing-extensions
+aiohttp>=3.9.1,<4
+colorama
+color-pprint
diff --git a/docs/version_guarantees.rst b/docs/version_guarantees.rst
new file mode 100644
index 00000000..7909bd6b
--- /dev/null
+++ b/docs/version_guarantees.rst
@@ -0,0 +1,30 @@
+.. _version_guarantees:
+
+Version Guarantees
+=====================
+
+The library follows a `semantic versioning principle <https://semver.org/>`_ which means that the major version is updated every time there is an incompatible API change. However due to the lack of guarantees on the Discord side when it comes to breaking changes along with the fairly dynamic nature of Python it can be hard to discern what can be considered a breaking change and what isn't.
+
+The first thing to keep in mind is that breaking changes only apply to **publicly documented functions and classes**. If it's not listed in the documentation here then it is not part of the public API and is thus bound to change. This includes attributes that start with an underscore or functions without an underscore that are not documented.
+
+.. note::
+
+    The examples below are non-exhaustive.
+
+Examples of Breaking Changes
+------------------------------
+
+- Changing the default parameter value to something else.
+- Renaming a function without an alias to an old function.
+- Adding or removing parameters to an event.
+
+Examples of Non-Breaking Changes
+----------------------------------
+
+- Adding or removing private underscored attributes.
+- Adding an element into the ``__slots__`` of a data class.
+- Changing the behaviour of a function to fix a bug.
+- Changes in the documentation.
+- Modifying the internal HTTP handling.
+- Upgrading the dependencies to a new version, major or otherwise.
+
diff --git a/docs/whats_new.rst b/docs/whats_new.rst
new file mode 100644
index 00000000..74040d7c
--- /dev/null
+++ b/docs/whats_new.rst
@@ -0,0 +1,1187 @@
+.. currentmodule:: discord
+
+.. |commands| replace:: [:ref:`ext.commands <discord_ext_commands>`]
+.. |tasks| replace:: [:ref:`ext.tasks <discord_ext_tasks>`]
+
+.. _whats_new:
+
+Changelog
+============
+
+This page keeps a detailed human friendly rendering of what's new and changed
+in specific versions.
+
+.. _vp1p7p3:
+
+v1.7.3
+--------
+
+Bug Fixes
+~~~~~~~~~~
+
+- Fix a crash involving guild uploaded stickers
+- Fix :meth:`DMChannel.permissions_for` not having :attr:`Permissions.read_messages` set.
+
+.. _vp1p7p2:
+
+v1.7.2
+-------
+
+Bug Fixes
+~~~~~~~~~~~
+
+- Fix ``fail_if_not_exists`` causing certain message references to not be usable within :meth:`abc.Messageable.send` and :meth:`Message.reply` (:old-issue:`6726`)
+- Fix :meth:`Guild.chunk` hanging when the user left the guild. (:old-issue:`6730`)
+- Fix loop sleeping after final iteration rather than before (:old-issue:`6744`)
+
+.. _vp1p7p1:
+
+v1.7.1
+-------
+
+Bug Fixes
+~~~~~~~~~~~
+
+- |commands| Fix :meth:`Cog.has_error_handler <ext.commands.Cog.has_error_handler>` not working as intended.
+
+.. _vp1p7p0:
+
+v1.7.0
+--------
+
+This version is mainly for improvements and bug fixes. This is more than likely the last major version in the 1.x series.
+Work after this will be spent on v2.0. As a result, **this is the last version to support Python 3.5**.
+Likewise, **this is the last version to support user bots**.
+
+Development of v2.0 will have breaking changes and support for newer API features.
+
+New Features
+~~~~~~~~~~~~~~
+
+- Add support for stage channels via :class:`StageChannel` (:old-issue:`6602`, :old-issue:`6608`)
+- Add support for :attr:`MessageReference.fail_if_not_exists` (:old-issue:`6484`)
+    - By default, if the message you're replying to doesn't exist then the API errors out.
+      This attribute tells the Discord API that it's okay for that message to be missing.
+
+- Add support for Discord's new permission serialisation scheme.
+- Add an easier way to move channels using :meth:`abc.GuildChannel.move`
+- Add :attr:`Permissions.use_slash_commands`
+- Add :attr:`Permissions.request_to_speak`
+- Add support for voice regions in voice channels via :attr:`VoiceChannel.rtc_region` (:old-issue:`6606`)
+- Add support for :meth:`PartialEmoji.url_as` (:old-issue:`6341`)
+- Add :attr:`MessageReference.jump_url` (:old-issue:`6318`)
+- Add :attr:`File.spoiler` (:old-issue:`6317`)
+- Add support for passing ``roles`` to :meth:`Guild.estimate_pruned_members` (:old-issue:`6538`)
+- Allow callable class factories to be used in :meth:`abc.Connectable.play` (:old-issue:`6478`)
+- Add a way to get mutual guilds from the client's cache via :attr:`User.mutual_guilds` (:old-issue:`2539`, :old-issue:`6444`)
+- :meth:`PartialMessage.edit` now returns a full :class:`Message` upon success (:old-issue:`6309`)
+- Add :attr:`RawMessageUpdateEvent.guild_id` (:old-issue:`6489`)
+- :class:`AuditLogEntry` is now hashable (:old-issue:`6495`)
+- :class:`Attachment` is now hashable
+- Add :attr:`Attachment.content_type` attribute (:old-issue:`6618`)
+- Add support for casting :class:`Attachment` to :class:`str` to get the URL.
+- Add ``seed`` parameter for :class:`Colour.random` (:old-issue:`6562`)
+    - This only seeds it for one call. If seeding for multiple calls is desirable, use :func:`random.seed`.
+
+- Add a :func:`utils.remove_markdown` helper function (:old-issue:`6573`)
+- Add support for passing scopes to :func:`utils.oauth_url` (:old-issue:`6568`)
+- |commands| Add support for ``rgb`` CSS function as a parameter to :class:`ColourConverter <ext.commands.ColourConverter>` (:old-issue:`6374`)
+- |commands| Add support for converting :class:`StoreChannel` via :class:`StoreChannelConverter <ext.commands.StoreChannelConverter>` (:old-issue:`6603`)
+- |commands| Add support for stripping whitespace after the prefix is encountered using the ``strip_after_prefix`` :class:`~ext.commands.Bot` constructor parameter.
+- |commands| Add :attr:`Context.invoked_parents <ext.commands.Context.invoked_parents>` to get the aliases a command's parent was invoked with (:old-issue:`1874`, :old-issue:`6462`)
+- |commands| Add a converter for :class:`PartialMessage` under :class:`ext.commands.PartialMessageConverter` (:old-issue:`6308`)
+- |commands| Add a converter for :class:`Guild` under :class:`ext.commands.GuildConverter` (:old-issue:`6016`, :old-issue:`6365`)
+- |commands| Add :meth:`Command.has_error_handler <ext.commands.Command.has_error_handler>`
+    - This is also adds :meth:`Cog.has_error_handler <ext.commands.Cog.has_error_handler>`
+- |commands| Allow callable types to act as a bucket key for cooldowns (:old-issue:`6563`)
+- |commands| Add ``linesep`` keyword argument to :class:`Paginator <ext.commands.Paginator>` (:old-issue:`5975`)
+- |commands| Allow ``None`` to be passed to :attr:`HelpCommand.verify_checks <ext.commands.HelpCommand.verify_checks>` to only verify in a guild context (:old-issue:`2008`, :old-issue:`6446`)
+- |commands| Allow relative paths when loading extensions via a ``package`` keyword argument (:old-issue:`2465`, :old-issue:`6445`)
+
+Bug Fixes
+~~~~~~~~~~
+
+- Fix mentions not working if ``mention_author`` is passed in :meth:`abc.Messageable.send` without :attr:`Client.allowed_mentions` set (:old-issue:`6192`, :old-issue:`6458`)
+- Fix user created instances of :class:`CustomActivity` triggering an error (:old-issue:`4049`)
+    - Note that currently, bot users still cannot set a custom activity due to a Discord limitation.
+- Fix :exc:`ZeroDivisionError` being raised from :attr:`VoiceClient.average_latency` (:old-issue:`6430`, :old-issue:`6436`)
+- Fix :attr:`User.public_flags` not updating upon edit (:old-issue:`6315`)
+- Fix :attr:`Message.call` sometimes causing attribute errors (:old-issue:`6390`)
+- Fix issue resending a file during request retries on newer versions of ``aiohttp`` (:old-issue:`6531`)
+- Raise an error when ``user_ids`` is empty in :meth:`Guild.query_members`
+- Fix ``__str__`` magic method raising when a :class:`Guild` is unavailable.
+- Fix potential :exc:`AttributeError` when accessing :attr:`VoiceChannel.members` (:old-issue:`6602`)
+- :class:`Embed` constructor parameters now implicitly convert to :class:`str` (:old-issue:`6574`)
+- Ensure ``discord`` package is only run if executed as a script (:old-issue:`6483`)
+- |commands| Fix irrelevant commands potentially being unloaded during cog unload due to failure.
+- |commands| Fix attribute errors when setting a cog to :class:`~.ext.commands.HelpCommand` (:old-issue:`5154`)
+- |commands| Fix :attr:`Context.invoked_with <ext.commands.Context.invoked_with>` being improperly reassigned during a :meth:`~ext.commands.Context.reinvoke` (:old-issue:`6451`, :old-issue:`6462`)
+- |commands| Remove duplicates from :meth:`HelpCommand.get_bot_mapping <ext.commands.HelpCommand.get_bot_mapping>` (:old-issue:`6316`)
+- |commands| Properly handle positional-only parameters in bot command signatures (:old-issue:`6431`)
+- |commands| Group signatures now properly show up in :attr:`Command.signature <ext.commands.Command.signature>` (:old-issue:`6529`, :old-issue:`6530`)
+
+Miscellaneous
+~~~~~~~~~~~~~~
+
+- User endpoints and all userbot related functionality has been deprecated and will be removed in the next major version of the library.
+- :class:`Permission` class methods were updated to match the UI of the Discord client (:old-issue:`6476`)
+- ``_`` and ``-`` characters are now stripped when making a new cog using the ``discord`` package (:old-issue:`6313`)
+
+.. _vp1p6p0:
+
+v1.6.0
+--------
+
+This version comes with support for replies and stickers.
+
+New Features
+~~~~~~~~~~~~~~
+
+- An entirely redesigned documentation. This was the cumulation of multiple months of effort.
+    - There's now a dark theme, feel free to navigate to the cog on the screen to change your setting, though this should be automatic.
+- Add support for :meth:`AppInfo.icon_url_as` and :meth:`AppInfo.cover_image_url_as` (:old-issue:`5888`)
+- Add :meth:`Colour.random` to get a random colour (:old-issue:`6067`)
+- Add support for stickers via :class:`Sticker` (:old-issue:`5946`)
+- Add support for replying via :meth:`Message.reply` (:old-issue:`6061`)
+    - This also comes with the :attr:`AllowedMentions.replied_user` setting.
+    - :meth:`abc.Messageable.send` can now accept a :class:`MessageReference`.
+    - :class:`MessageReference` can now be constructed by users.
+    - :meth:`Message.to_reference` can now convert a message to a :class:`MessageReference`.
+- Add support for getting the replied to resolved message through :attr:`MessageReference.resolved`.
+- Add support for role tags.
+    - :attr:`Guild.premium_subscriber_role` to get the "Nitro Booster" role (if available).
+    - :attr:`Guild.self_role` to get the bot's own role (if available).
+    - :attr:`Role.tags` to get the role's tags.
+    - :meth:`Role.is_premium_subscriber` to check if a role is the "Nitro Booster" role.
+    - :meth:`Role.is_bot_managed` to check if a role is a bot role (i.e. the automatically created role for bots).
+    - :meth:`Role.is_integration` to check if a role is role created by an integration.
+- Add :meth:`Client.is_ws_ratelimited` to check if the websocket is rate limited.
+    - :meth:`ShardInfo.is_ws_ratelimited` is the equivalent for checking a specific shard.
+- Add support for chunking an :class:`AsyncIterator` through :meth:`AsyncIterator.chunk` (:old-issue:`6100`, :old-issue:`6082`)
+- Add :attr:`PartialEmoji.created_at` (:old-issue:`6128`)
+- Add support for editing and deleting webhook sent messages (:old-issue:`6058`)
+    - This adds :class:`WebhookMessage` as well to power this behaviour.
+- Add :class:`PartialMessage` to allow working with a message via channel objects and just a message_id (:old-issue:`5905`)
+    - This is useful if you don't want to incur an extra API call to fetch the message.
+- Add :meth:`Emoji.url_as` (:old-issue:`6162`)
+- Add support for :attr:`Member.pending` for the membership gating feature.
+- Allow ``colour`` parameter to take ``int`` in :meth:`Guild.create_role` (:old-issue:`6195`)
+- Add support for ``presences`` in :meth:`Guild.query_members` (:old-issue:`2354`)
+- |commands| Add support for ``description`` keyword argument in :class:`commands.Cog <ext.commands.Cog>` (:old-issue:`6028`)
+- |tasks| Add support for calling the wrapped coroutine as a function via ``__call__``.
+
+
+Bug Fixes
+~~~~~~~~~~~
+
+- Raise :exc:`DiscordServerError` when reaching 503s repeatedly (:old-issue:`6044`)
+- Fix :exc:`AttributeError` when :meth:`Client.fetch_template` is called (:old-issue:`5986`)
+- Fix errors when playing audio and moving to another channel (:old-issue:`5953`)
+- Fix :exc:`AttributeError` when voice channels disconnect too fast (:old-issue:`6039`)
+- Fix stale :class:`User` references when the members intent is off.
+- Fix :func:`on_user_update` not dispatching in certain cases when a member is not cached but the user somehow is.
+- Fix :attr:`Message.author` being overwritten in certain cases during message update.
+    - This would previously make it so :attr:`Message.author` is a :class:`User`.
+- Fix :exc:`UnboundLocalError` for editing ``public_updates_channel`` in :meth:`Guild.edit` (:old-issue:`6093`)
+- Fix uninitialised :attr:`CustomActivity.created_at` (:old-issue:`6095`)
+- |commands| Errors during cog unload no longer stops module cleanup (:old-issue:`6113`)
+- |commands| Properly cleanup lingering commands when a conflicting alias is found when adding commands (:old-issue:`6217`)
+
+Miscellaneous
+~~~~~~~~~~~~~~~
+
+- ``ffmpeg`` spawned processes no longer open a window in Windows (:old-issue:`6038`)
+- Update dependencies to allow the library to work on Python 3.9+ without requiring build tools. (:old-issue:`5984`, :old-issue:`5970`)
+- Fix docstring issue leading to a SyntaxError in 3.9 (:old-issue:`6153`)
+- Update Windows opus binaries from 1.2.1 to 1.3.1 (:old-issue:`6161`)
+- Allow :meth:`Guild.create_role` to accept :class:`int` as the ``colour`` parameter (:old-issue:`6195`)
+- |commands| :class:`MessageConverter <ext.commands.MessageConverter>` regex got updated to support ``www.`` prefixes (:old-issue:`6002`)
+- |commands| :class:`UserConverter <ext.commands.UserConverter>` now fetches the API if an ID is passed and the user is not cached.
+- |commands| :func:`max_concurrency <ext.commands.max_concurrency>` is now called before cooldowns (:old-issue:`6172`)
+
+.. _vp1p5p1:
+
+v1.5.1
+-------
+
+Bug Fixes
+~~~~~~~~~~~
+
+- Fix :func:`utils.escape_markdown` not escaping quotes properly (:old-issue:`5897`)
+- Fix :class:`Message` not being hashable (:old-issue:`5901`, :old-issue:`5866`)
+- Fix moving channels to the end of the channel list (:old-issue:`5923`)
+- Fix seemingly strange behaviour in ``__eq__`` for :class:`PermissionOverwrite` (:old-issue:`5929`)
+- Fix aliases showing up in ``__iter__`` for :class:`Intents` (:old-issue:`5945`)
+- Fix the bot disconnecting from voice when moving them to another channel (:old-issue:`5904`)
+- Fix attribute errors when chunking times out sometimes during delayed on_ready dispatching.
+- Ensure that the bot's own member is not evicted from the cache (:old-issue:`5949`)
+
+Miscellaneous
+~~~~~~~~~~~~~~
+
+- Members are now loaded during ``GUILD_MEMBER_UPDATE`` events if :attr:`MemberCacheFlags.joined` is set. (:old-issue:`5930`)
+- |commands| :class:`MemberConverter <ext.commands.MemberConverter>` now properly lazily fetches members if not available from cache.
+    - This is the same as having ``discord.Member`` as the type-hint.
+- :meth:`Guild.chunk` now allows concurrent calls without spamming the gateway with requests.
+
+.. _vp1p5p0:
+
+v1.5.0
+--------
+
+This version came with forced breaking changes that Discord is requiring all bots to go through on October 7th. It is highly recommended to read the documentation on intents, :ref:`intents_primer`.
+
+API Changes
+~~~~~~~~~~~~~
+
+- Members and presences will no longer be retrieved due to an API change. See :ref:`privileged_intents` for more info.
+- As a consequence, fetching offline members is disabled if the members intent is not enabled.
+
+New Features
+~~~~~~~~~~~~~~
+
+- Support for gateway intents, passed via ``intents`` in :class:`Client` using :class:`Intents`.
+- Add :attr:`VoiceRegion.south_korea` (:old-issue:`5233`)
+- Add support for ``__eq__`` for :class:`Message` (:old-issue:`5789`)
+- Add :meth:`Colour.dark_theme` factory method (:old-issue:`1584`)
+- Add :meth:`AllowedMentions.none` and :meth:`AllowedMentions.all` (:old-issue:`5785`)
+- Add more concrete exceptions for 500 class errors under :class:`DiscordServerError` (:old-issue:`5797`)
+- Implement :class:`VoiceProtocol` to better intersect the voice flow.
+- Add :meth:`Guild.chunk` to fully chunk a guild.
+- Add :class:`MemberCacheFlags` to better control member cache. See :ref:`intents_member_cache` for more info.
+- Add support for :attr:`ActivityType.competing` (:old-issue:`5823`)
+    - This seems currently unused API wise.
+
+- Add support for message references, :attr:`Message.reference` (:old-issue:`5754`, :old-issue:`5832`)
+- Add alias for :class:`ColourConverter` under ``ColorConverter`` (:old-issue:`5773`)
+- Add alias for :attr:`PublicUserFlags.verified_bot_developer` under :attr:`PublicUserFlags.early_verified_bot_developer` (:old-issue:`5849`)
+- |commands| Add support for ``require_var_positional`` for :class:`Command` (:old-issue:`5793`)
+
+Bug Fixes
+~~~~~~~~~~
+
+- Fix issue with :meth:`Guild.by_category` not showing certain channels.
+- Fix :attr:`abc.GuildChannel.permissions_synced` always being ``False`` (:old-issue:`5772`)
+- Fix handling of cloudflare bans on webhook related requests (:old-issue:`5221`)
+- Fix cases where a keep-alive thread would ack despite already dying (:old-issue:`5800`)
+- Fix cases where a :class:`Member` reference would be stale when cache is disabled in message events (:old-issue:`5819`)
+- Fix ``allowed_mentions`` not being sent when sending a single file (:old-issue:`5835`)
+- Fix ``overwrites`` being ignored in :meth:`abc.GuildChannel.edit` if ``{}`` is passed (:old-issue:`5756`, :old-issue:`5757`)
+- |commands| Fix exceptions being raised improperly in command invoke hooks (:old-issue:`5799`)
+- |commands| Fix commands not being properly ejected during errors in a cog injection (:old-issue:`5804`)
+- |commands| Fix cooldown timing ignoring edited timestamps.
+- |tasks| Fix tasks extending the next iteration on handled exceptions (:old-issue:`5762`, :old-issue:`5763`)
+
+Miscellaneous
+~~~~~~~~~~~~~~~
+
+- Webhook requests are now logged (:old-issue:`5798`)
+- Remove caching layer from :attr:`AutoShardedClient.shards`. This was causing issues if queried before launching shards.
+- Gateway rate limits are now handled.
+- Warnings logged due to missed caches are now changed to DEBUG log level.
+- Some strings are now explicitly interned to reduce memory usage.
+- Usage of namedtuples has been reduced to avoid potential breaking changes in the future (:old-issue:`5834`)
+- |commands| All :class:`BadArgument` exceptions from the built-in converters now raise concrete exceptions to better tell them apart (:old-issue:`5748`)
+- |tasks| Lazily fetch the event loop to prevent surprises when changing event loop policy (:old-issue:`5808`)
+
+.. _vp1p4p2:
+
+v1.4.2
+--------
+
+This is a maintenance release with backports from :ref:`vp1p5p0`.
+
+Bug Fixes
+~~~~~~~~~~~
+
+- Fix issue with :meth:`Guild.by_category` not showing certain channels.
+- Fix :attr:`abc.GuildChannel.permissions_synced` always being ``False`` (:old-issue:`5772`)
+- Fix handling of cloudflare bans on webhook related requests (:old-issue:`5221`)
+- Fix cases where a keep-alive thread would ack despite already dying (:old-issue:`5800`)
+- Fix cases where a :class:`Member` reference would be stale when cache is disabled in message events (:old-issue:`5819`)
+- Fix ``allowed_mentions`` not being sent when sending a single file (:old-issue:`5835`)
+- Fix ``overwrites`` being ignored in :meth:`abc.GuildChannel.edit` if ``{}`` is passed (:old-issue:`5756`, :old-issue:`5757`)
+- |commands| Fix exceptions being raised improperly in command invoke hooks (:old-issue:`5799`)
+- |commands| Fix commands not being properly ejected during errors in a cog injection (:old-issue:`5804`)
+- |commands| Fix cooldown timing ignoring edited timestamps.
+- |tasks| Fix tasks extending the next iteration on handled exceptions (:old-issue:`5762`, :old-issue:`5763`)
+
+Miscellaneous
+~~~~~~~~~~~~~~~
+
+- Remove caching layer from :attr:`AutoShardedClient.shards`. This was causing issues if queried before launching shards.
+- |tasks| Lazily fetch the event loop to prevent surprises when changing event loop policy (:old-issue:`5808`)
+
+.. _vp1p4p1:
+
+v1.4.1
+--------
+
+Bug Fixes
+~~~~~~~~~~~
+
+- Properly terminate the connection when :meth:`Client.close` is called (:old-issue:`5207`)
+- Fix error being raised when clearing embed author or image when it was already cleared (:old-issue:`5210`, :old-issue:`5212`)
+- Fix ``__path__`` to allow editable extensions (:old-issue:`5213`)
+
+.. _vp1p4p0:
+
+v1.4.0
+--------
+
+Another version with a long development time. Features like Intents are slated to be released in a v1.5 release. Thank you for your patience!
+
+New Features
+~~~~~~~~~~~~~~
+
+- Add support for :class:`AllowedMentions` to have more control over what gets mentioned.
+    - This can be set globally through :attr:`Client.allowed_mentions`
+    - This can also be set on a per message basis via :meth:`abc.Messageable.send`
+
+- :class:`AutoShardedClient` has been completely redesigned from the ground up to better suit multi-process clusters (:old-issue:`2654`)
+    - Add :class:`ShardInfo` which allows fetching specific information about a shard.
+    - The :class:`ShardInfo` allows for reconnecting and disconnecting of a specific shard as well.
+    - Add :meth:`AutoShardedClient.get_shard` and :attr:`AutoShardedClient.shards` to get information about shards.
+    - Rework the entire connection flow to better facilitate the ``IDENTIFY`` rate limits.
+    - Add a hook :meth:`Client.before_identify_hook` to have better control over what happens before an ``IDENTIFY`` is done.
+    - Add more shard related events such as :func:`on_shard_connect`, :func:`on_shard_disconnect` and :func:`on_shard_resumed`.
+
+- Add support for guild templates (:old-issue:`2652`)
+    - This adds :class:`Template` to read a template's information.
+    - :meth:`Client.fetch_template` can be used to fetch a template's information from the API.
+    - :meth:`Client.create_guild` can now take an optional template to base the creation from.
+    - Note that fetching a guild's template is currently restricted for bot accounts.
+
+- Add support for guild integrations (:old-issue:`2051`, :old-issue:`1083`)
+    - :class:`Integration` is used to read integration information.
+    - :class:`IntegrationAccount` is used to read integration account information.
+    - :meth:`Guild.integrations` will fetch all integrations in a guild.
+    - :meth:`Guild.create_integration` will create an integration.
+    - :meth:`Integration.edit` will edit an existing integration.
+    - :meth:`Integration.delete` will delete an integration.
+    - :meth:`Integration.sync` will sync an integration.
+    - There is currently no support in the audit log for this.
+
+- Add an alias for :attr:`VerificationLevel.extreme` under :attr:`VerificationLevel.very_high` (:old-issue:`2650`)
+- Add various grey to gray aliases for :class:`Colour` (:old-issue:`5130`)
+- Added :attr:`VoiceClient.latency` and :attr:`VoiceClient.average_latency` (:old-issue:`2535`)
+- Add ``use_cached`` and ``spoiler`` parameters to :meth:`Attachment.to_file` (:old-issue:`2577`, :old-issue:`4095`)
+- Add ``position`` parameter support to :meth:`Guild.create_category` (:old-issue:`2623`)
+- Allow passing ``int`` for the colour in :meth:`Role.edit` (:old-issue:`4057`)
+- Add :meth:`Embed.remove_author` to clear author information from an embed (:old-issue:`4068`)
+- Add the ability to clear images and thumbnails in embeds using :attr:`Embed.Empty` (:old-issue:`4053`)
+- Add :attr:`Guild.max_video_channel_users` (:old-issue:`4120`)
+- Add :attr:`Guild.public_updates_channel` (:old-issue:`4120`)
+- Add ``guild_ready_timeout`` parameter to :class:`Client` and subclasses to control timeouts when the ``GUILD_CREATE`` stream takes too long (:old-issue:`4112`)
+- Add support for public user flags via :attr:`User.public_flags` and :class:`PublicUserFlags` (:old-issue:`3999`)
+- Allow changing of channel types via :meth:`TextChannel.edit` to and from a news channel (:old-issue:`4121`)
+- Add :meth:`Guild.edit_role_positions` to bulk edit role positions in a single API call (:old-issue:`2501`, :old-issue:`2143`)
+- Add :meth:`Guild.change_voice_state` to change your voice state in a guild (:old-issue:`5088`)
+- Add :meth:`PartialInviteGuild.is_icon_animated` for checking if the invite guild has animated icon (:old-issue:`4180`, :old-issue:`4181`)
+- Add :meth:`PartialInviteGuild.icon_url_as` now supports ``static_format`` for consistency (:old-issue:`4180`, :old-issue:`4181`)
+- Add support for ``user_ids`` in :meth:`Guild.query_members`
+- Add support for pruning members by roles in :meth:`Guild.prune_members` (:old-issue:`4043`)
+- |commands| Implement :func:`~ext.commands.before_invoke` and :func:`~ext.commands.after_invoke` decorators (:old-issue:`1986`, :old-issue:`2502`)
+- |commands| Add a way to retrieve ``retry_after`` from a cooldown in a command via :meth:`Command.get_cooldown_retry_after <.ext.commands.Command.get_cooldown_retry_after>` (:old-issue:`5195`)
+- |commands| Add a way to dynamically add and remove checks from a :class:`HelpCommand <.ext.commands.HelpCommand>` (:old-issue:`5197`)
+- |tasks| Add :meth:`Loop.is_running <.ext.tasks.Loop.is_running>` method to the task objects (:old-issue:`2540`)
+- |tasks| Allow usage of custom error handlers similar to the command extensions to tasks using :meth:`Loop.error <.ext.tasks.Loop.error>` decorator (:old-issue:`2621`)
+
+
+Bug Fixes
+~~~~~~~~~~~~
+
+- Fix issue with :attr:`PartialEmoji.url` reads leading to a failure (:old-issue:`4015`, :old-issue:`4016`)
+- Allow :meth:`abc.Messageable.history` to take a limit of ``1`` even if ``around`` is passed (:old-issue:`4019`)
+- Fix :attr:`Guild.member_count` not updating in certain cases when a member has left the guild (:old-issue:`4021`)
+- Fix the type of :attr:`Object.id` not being validated. For backwards compatibility ``str`` is still allowed but is converted to ``int`` (:old-issue:`4002`)
+- Fix :meth:`Guild.edit` not allowing editing of notification settings (:old-issue:`4074`, :old-issue:`4047`)
+- Fix crash when the guild widget contains channels that aren't in the payload (:old-issue:`4114`, :old-issue:`4115`)
+- Close ffmpeg stdin handling from spawned processes with :class:`FFmpegOpusAudio` and :class:`FFmpegPCMAudio` (:old-issue:`4036`)
+- Fix :func:`utils.escape_markdown` not escaping masked links (:old-issue:`4206`, :old-issue:`4207`)
+- Fix reconnect loop due to failed handshake on region change (:old-issue:`4210`, :old-issue:`3996`)
+- Fix :meth:`Guild.by_category` not returning empty categories (:old-issue:`4186`)
+- Fix certain JPEG images not being identified as JPEG (:old-issue:`5143`)
+- Fix a crash when an incomplete guild object is used when fetching reaction information (:old-issue:`5181`)
+- Fix a timeout issue when fetching members using :meth:`Guild.query_members`
+- Fix an issue with domain resolution in voice (:old-issue:`5188`, :old-issue:`5191`)
+- Fix an issue where :attr:`PartialEmoji.id` could be a string (:old-issue:`4153`, :old-issue:`4152`)
+- Fix regression where :attr:`Member.activities` would not clear.
+- |commands| A :exc:`TypeError` is now raised when :obj:`typing.Optional` is used within :data:`commands.Greedy <.ext.commands.Greedy>` (:old-issue:`2253`, :old-issue:`5068`)
+- |commands| :meth:`Bot.walk_commands <.ext.commands.Bot.walk_commands>` no longer yields duplicate commands due to aliases (:old-issue:`2591`)
+- |commands| Fix regex characters not being escaped in :attr:`HelpCommand.clean_prefix <.ext.commands.HelpCommand.clean_prefix>` (:old-issue:`4058`, :old-issue:`4071`)
+- |commands| Fix :meth:`Bot.get_command <.ext.commands.Bot.get_command>` from raising errors when a name only has whitespace (:old-issue:`5124`)
+- |commands| Fix issue with :attr:`Context.subcommand_passed <.ext.commands.Context.subcommand_passed>` not functioning as expected (:old-issue:`5198`)
+- |tasks| Task objects are no longer stored globally so two class instances can now start two separate tasks (:old-issue:`2294`)
+- |tasks| Allow cancelling the loop within :meth:`before_loop <.ext.tasks.Loop.before_loop>` (:old-issue:`4082`)
+
+
+Miscellaneous
+~~~~~~~~~~~~~~~
+
+- The :attr:`Member.roles` cache introduced in v1.3 was reverted due to issues caused (:old-issue:`4087`, :old-issue:`4157`)
+- :class:`Webhook` objects are now comparable and hashable (:old-issue:`4182`)
+- Some more API requests got a ``reason`` parameter for audit logs (:old-issue:`5086`)
+    - :meth:`TextChannel.follow`
+    - :meth:`Message.pin` and :meth:`Message.unpin`
+    - :meth:`Webhook.delete` and :meth:`Webhook.edit`
+
+- For performance reasons ``websockets`` has been dropped in favour of ``aiohttp.ws``.
+- The blocking logging message now shows the stack trace of where the main thread was blocking
+- The domain name was changed from ``discordapp.com`` to ``discord.com`` to prepare for the required domain migration
+- Reduce memory usage when reconnecting due to stale references being held by the message cache (:old-issue:`5133`)
+- Optimize :meth:`abc.GuildChannel.permissions_for` by not creating as many temporary objects (20-32% savings).
+- |commands| Raise :exc:`~ext.commands.CommandRegistrationError` instead of :exc:`ClientException` when a duplicate error is registered (:old-issue:`4217`)
+- |tasks| No longer handle :exc:`HTTPException` by default in the task reconnect loop (:old-issue:`5193`)
+
+.. _vp1p3p4:
+
+v1.3.4
+--------
+
+Bug Fixes
+~~~~~~~~~~~
+
+- Fix an issue with channel overwrites causing multiple issues including crashes (:old-issue:`5109`)
+
+.. _vp1p3p3:
+
+v1.3.3
+--------
+
+Bug Fixes
+~~~~~~~~~~~~
+
+- Change default WS close to 4000 instead of 1000.
+    - The previous close code caused sessions to be invalidated at a higher frequency than desired.
+
+- Fix ``None`` appearing in ``Member.activities``. (:old-issue:`2619`)
+
+.. _vp1p3p2:
+
+v1.3.2
+---------
+
+Another minor bug fix release.
+
+Bug Fixes
+~~~~~~~~~~~
+
+- Higher the wait time during the ``GUILD_CREATE`` stream before ``on_ready`` is fired for :class:`AutoShardedClient`.
+- :func:`on_voice_state_update` now uses the inner ``member`` payload which should make it more reliable.
+- Fix various Cloudflare handling errors (:old-issue:`2572`, :old-issue:`2544`)
+- Fix crashes if :attr:`Message.guild` is :class:`Object` instead of :class:`Guild`.
+- Fix :meth:`Webhook.send` returning an empty string instead of ``None`` when ``wait=False``.
+- Fix invalid format specifier in webhook state (:old-issue:`2570`)
+- |commands| Passing invalid permissions to permission related checks now raises ``TypeError``.
+
+.. _vp1p3p1:
+
+v1.3.1
+--------
+
+Minor bug fix release.
+
+Bug Fixes
+~~~~~~~~~~~
+
+- Fix fetching invites in guilds that the user is not in.
+- Fix the channel returned from :meth:`Client.fetch_channel` raising when sending messages. (:old-issue:`2531`)
+
+Miscellaneous
+~~~~~~~~~~~~~~
+
+- Fix compatibility warnings when using the Python 3.9 alpha.
+- Change the unknown event logging from WARNING to DEBUG to reduce noise.
+
+.. _vp1p3p0:
+
+v1.3.0
+--------
+
+This version comes with a lot of bug fixes and new features. It's been in development for a lot longer than was anticipated!
+
+New Features
+~~~~~~~~~~~~~~
+
+- Add :meth:`Guild.fetch_members` to fetch members from the HTTP API. (:old-issue:`2204`)
+- Add :meth:`Guild.fetch_roles` to fetch roles from the HTTP API. (:old-issue:`2208`)
+- Add support for teams via :class:`Team` when fetching with :meth:`Client.application_info`. (:old-issue:`2239`)
+- Add support for suppressing embeds via :meth:`Message.edit`
+- Add support for guild subscriptions. See the :class:`Client` documentation for more details.
+- Add :attr:`VoiceChannel.voice_states` to get voice states without relying on member cache.
+- Add :meth:`Guild.query_members` to request members from the gateway.
+- Add :class:`FFmpegOpusAudio` and other voice improvements. (:old-issue:`2258`)
+- Add :attr:`RawMessageUpdateEvent.channel_id` for retrieving channel IDs during raw message updates. (:old-issue:`2301`)
+- Add :attr:`RawReactionActionEvent.event_type` to disambiguate between reaction addition and removal in reaction events.
+- Add :attr:`abc.GuildChannel.permissions_synced` to query whether permissions are synced with the category. (:old-issue:`2300`, :old-issue:`2324`)
+- Add :attr:`MessageType.channel_follow_add` message type for announcement channels being followed. (:old-issue:`2314`)
+- Add :meth:`Message.is_system` to allow for quickly filtering through system messages.
+- Add :attr:`VoiceState.self_stream` to indicate whether someone is streaming via Go Live. (:old-issue:`2343`)
+- Add :meth:`Emoji.is_usable` to check if the client user can use an emoji. (:old-issue:`2349`)
+- Add :attr:`VoiceRegion.europe` and :attr:`VoiceRegion.dubai`. (:old-issue:`2358`, :old-issue:`2490`)
+- Add :meth:`TextChannel.follow` to follow a news channel. (:old-issue:`2367`)
+- Add :attr:`Permissions.view_guild_insights` permission. (:old-issue:`2415`)
+- Add support for new audit log types. See :ref:`discord-api-audit-logs` for more information. (:old-issue:`2427`)
+    - Note that integration support is not finalized.
+
+- Add :attr:`Webhook.type` to query the type of webhook (:class:`WebhookType`). (:old-issue:`2441`)
+- Allow bulk editing of channel overwrites through :meth:`abc.GuildChannel.edit`. (:old-issue:`2198`)
+- Add :class:`Activity.created_at` to see when an activity was started. (:old-issue:`2446`)
+- Add support for ``xsalsa20_poly1305_lite`` encryption mode for voice. (:old-issue:`2463`)
+- Add :attr:`RawReactionActionEvent.member` to get the member who did the reaction. (:old-issue:`2443`)
+- Add support for new YouTube streaming via :attr:`Streaming.platform` and :attr:`Streaming.game`. (:old-issue:`2445`)
+- Add :attr:`Guild.discovery_splash_url` to get the discovery splash image asset. (:old-issue:`2482`)
+- Add :attr:`Guild.rules_channel` to get the rules channel of public guilds. (:old-issue:`2482`)
+    - It should be noted that this feature is restricted to those who are either in Server Discovery or planning to be there.
+
+- Add support for message flags via :attr:`Message.flags` and :class:`MessageFlags`. (:old-issue:`2433`)
+- Add :attr:`User.system` and :attr:`Profile.system` to know whether a user is an official Discord Trust and Safety account.
+- Add :attr:`Profile.team_user` to check whether a user is a member of a team.
+- Add :meth:`Attachment.to_file` to easily convert attachments to :class:`File` for sending.
+- Add certain aliases to :class:`Permissions` to match the UI better. (:old-issue:`2496`)
+    - :attr:`Permissions.manage_permissions`
+    - :attr:`Permissions.view_channel`
+    - :attr:`Permissions.use_external_emojis`
+
+- Add support for passing keyword arguments when creating :class:`Permissions`.
+- Add support for custom activities via :class:`CustomActivity`. (:old-issue:`2400`)
+    - Note that as of now, bots cannot send custom activities yet.
+
+- Add support for :func:`on_invite_create` and :func:`on_invite_delete` events.
+- Add support for clearing a specific reaction emoji from a message.
+    - :meth:`Message.clear_reaction` and :meth:`Reaction.clear` methods.
+    - :func:`on_raw_reaction_clear_emoji` and :func:`on_reaction_clear_emoji` events.
+
+- Add :func:`utils.sleep_until` helper to sleep until a specific datetime. (:old-issue:`2517`, :old-issue:`2519`)
+- |commands| Add support for teams and :attr:`Bot.owner_ids <.ext.commands.Bot.owner_ids>` to have multiple bot owners. (:old-issue:`2239`)
+- |commands| Add new :attr:`BucketType.role <.ext.commands.BucketType.role>` bucket type. (:old-issue:`2201`)
+- |commands| Expose :attr:`Command.cog <.ext.commands.Command.cog>` property publicly. (:old-issue:`2360`)
+- |commands| Add non-decorator interface for adding checks to commands via :meth:`Command.add_check <.ext.commands.Command.add_check>` and :meth:`Command.remove_check <.ext.commands.Command.remove_check>`. (:old-issue:`2411`)
+- |commands| Add :func:`has_guild_permissions <.ext.commands.has_guild_permissions>` check. (:old-issue:`2460`)
+- |commands| Add :func:`bot_has_guild_permissions <.ext.commands.bot_has_guild_permissions>` check. (:old-issue:`2460`)
+- |commands| Add ``predicate`` attribute to checks decorated with :func:`~.ext.commands.check`.
+- |commands| Add :func:`~.ext.commands.check_any` check to logical OR multiple checks.
+- |commands| Add :func:`~.ext.commands.max_concurrency` to allow only a certain amount of users to use a command concurrently before waiting or erroring.
+- |commands| Add support for calling a :class:`~.ext.commands.Command` as a regular function.
+- |tasks| :meth:`Loop.add_exception_type <.ext.tasks.Loop.add_exception_type>` now allows multiple exceptions to be set. (:old-issue:`2333`)
+- |tasks| Add :attr:`Loop.next_iteration <.ext.tasks.Loop.next_iteration>` property. (:old-issue:`2305`)
+
+Bug Fixes
+~~~~~~~~~~
+
+- Fix issue with permission resolution sometimes failing for guilds with no owner.
+- Tokens are now stripped upon use. (:old-issue:`2135`)
+- Passing in a ``name`` is no longer required for :meth:`Emoji.edit`. (:old-issue:`2368`)
+- Fix issue with webhooks not re-raising after retries have run out. (:old-issue:`2272`, :old-issue:`2380`)
+- Fix mismatch in URL handling in :func:`utils.escape_markdown`. (:old-issue:`2420`)
+- Fix issue with ports being read in little endian when they should be big endian in voice connections. (:old-issue:`2470`)
+- Fix :meth:`Member.mentioned_in` not taking into consideration the message's guild.
+- Fix bug with moving channels when there are gaps in positions due to channel deletion and creation.
+- Fix :func:`on_shard_ready` not triggering when ``fetch_offline_members`` is disabled. (:old-issue:`2504`)
+- Fix issue with large sharded bots taking too long to actually dispatch :func:`on_ready`.
+- Fix issue with fetching group DM based invites in :meth:`Client.fetch_invite`.
+- Fix out of order files being sent in webhooks when there are 10 files.
+- |commands| Extensions that fail internally due to ImportError will no longer raise :exc:`~.ext.commands.ExtensionNotFound`. (:old-issue:`2244`, :old-issue:`2275`, :old-issue:`2291`)
+- |commands| Updating the :attr:`Paginator.suffix <.ext.commands.Paginator.suffix>` will not cause out of date calculations. (:old-issue:`2251`)
+- |commands| Allow converters from custom extension packages. (:old-issue:`2369`, :old-issue:`2374`)
+- |commands| Fix issue with paginator prefix being ``None`` causing empty pages. (:old-issue:`2471`)
+- |commands| :class:`~.commands.Greedy` now ignores parsing errors rather than propagating them.
+- |commands| :meth:`Command.can_run <.ext.commands.Command.can_run>` now checks whether a command is disabled.
+- |commands| :attr:`HelpCommand.clean_prefix <.ext.commands.HelpCommand.clean_prefix>` now takes into consideration nickname mentions. (:old-issue:`2489`)
+- |commands| :meth:`Context.send_help <.ext.commands.Context.send_help>` now properly propagates to the :meth:`HelpCommand.on_help_command_error <.ext.commands.HelpCommand.on_help_command_error>` handler.
+
+Miscellaneous
+~~~~~~~~~~~~~~~
+
+- The library now fully supports Python 3.8 without warnings.
+- Bump the dependency of ``websockets`` to 8.0 for those who can use it. (:old-issue:`2453`)
+- Due to Discord providing :class:`Member` data in mentions, users will now be upgraded to :class:`Member` more often if mentioned.
+- :func:`utils.escape_markdown` now properly escapes new quote markdown.
+- The message cache can now be disabled by passing ``None`` to ``max_messages`` in :class:`Client`.
+- The default message cache size has changed from 5000 to 1000 to accommodate small bots.
+- Lower memory usage by only creating certain objects as needed in :class:`Role`.
+- There is now a sleep of 5 seconds before re-IDENTIFYing during a reconnect to prevent long loops of session invalidation.
+- The rate limiting code now uses millisecond precision to have more granular rate limit handling.
+    - Along with that, the rate limiting code now uses Discord's response to wait. If you need to use the system clock again for whatever reason, consider passing ``assume_synced_clock`` in :class:`Client`.
+
+- The performance of :attr:`Guild.default_role` has been improved from O(N) to O(1). (:old-issue:`2375`)
+- The performance of :attr:`Member.roles` has improved due to usage of caching to avoid surprising performance traps.
+- The GC is manually triggered during things that cause large deallocations (such as guild removal) to prevent memory fragmentation.
+- There have been many changes to the documentation for fixes both for usability, correctness, and to fix some linter errors. Thanks to everyone who contributed to those.
+- The loading of the opus module has been delayed which would make the result of :func:`opus.is_loaded` somewhat surprising.
+- |commands| Usernames prefixed with @ inside DMs will properly convert using the :class:`User` converter. (:old-issue:`2498`)
+- |tasks| The task sleeping time will now take into consideration the amount of time the task body has taken before sleeping. (:old-issue:`2516`)
+
+.. _vp1p2p5:
+
+v1.2.5
+--------
+
+Bug Fixes
+~~~~~~~~~~~
+
+- Fix a bug that caused crashes due to missing ``animated`` field in Emoji structures in reactions.
+
+.. _vp1p2p4:
+
+v1.2.4
+--------
+
+Bug Fixes
+~~~~~~~~~~~
+
+- Fix a regression when :attr:`Message.channel` would be ``None``.
+- Fix a regression where :attr:`Message.edited_at` would not update during edits.
+- Fix a crash that would trigger during message updates (:old-issue:`2265`, :old-issue:`2287`).
+- Fix a bug when :meth:`VoiceChannel.connect` would not return (:old-issue:`2274`, :old-issue:`2372`, :old-issue:`2373`, :old-issue:`2377`).
+- Fix a crash relating to token-less webhooks (:old-issue:`2364`).
+- Fix issue where :attr:`Guild.premium_subscription_count` would be ``None`` due to a Discord bug. (:old-issue:`2331`, :old-issue:`2376`).
+
+.. _vp1p2p3:
+
+v1.2.3
+--------
+
+Bug Fixes
+~~~~~~~~~~~
+
+- Fix an AttributeError when accessing :attr:`Member.premium_since` in :func:`on_member_update`. (:old-issue:`2213`)
+- Handle :exc:`asyncio.CancelledError` in :meth:`abc.Messageable.typing` context manager. (:old-issue:`2218`)
+- Raise the max encoder bitrate to 512kbps to account for nitro boosting. (:old-issue:`2232`)
+- Properly propagate exceptions in :meth:`Client.run`. (:old-issue:`2237`)
+- |commands| Ensure cooldowns are properly copied when used in cog level ``command_attrs``.
+
+.. _vp1p2p2:
+
+v1.2.2
+--------
+
+Bug Fixes
+~~~~~~~~~~~
+
+- Audit log related attribute access have been fixed to not error out when they shouldn't have.
+
+.. _vp1p2p1:
+
+v1.2.1
+--------
+
+Bug Fixes
+~~~~~~~~~~~
+
+- :attr:`User.avatar_url` and related attributes no longer raise an error.
+- More compatibility shims with the ``enum.Enum`` code.
+
+.. _vp1p2p0:
+
+v1.2.0
+--------
+
+This update mainly brings performance improvements and various nitro boosting attributes (referred to in the API as "premium guilds").
+
+New Features
+~~~~~~~~~~~~~~
+
+- Add :attr:`Guild.premium_tier` to query the guild's current nitro boost level.
+- Add :attr:`Guild.emoji_limit`, :attr:`Guild.bitrate_limit`, :attr:`Guild.filesize_limit` to query the new limits of a guild when taking into consideration boosting.
+- Add :attr:`Guild.premium_subscription_count` to query how many members are boosting a guild.
+- Add :attr:`Member.premium_since` to query since when a member has boosted a guild.
+- Add :attr:`Guild.premium_subscribers` to query all the members currently boosting the guild.
+- Add :attr:`Guild.system_channel_flags` to query the settings for a guild's :attr:`Guild.system_channel`.
+    - This includes a new type named :class:`SystemChannelFlags`
+- Add :attr:`Emoji.available` to query if an emoji can be used (within the guild or otherwise).
+- Add support for animated icons in :meth:`Guild.icon_url_as` and :attr:`Guild.icon_url`.
+- Add :meth:`Guild.is_icon_animated`.
+- Add support for the various new :class:`MessageType` involving nitro boosting.
+- Add :attr:`VoiceRegion.india`. (:old-issue:`2145`)
+- Add :meth:`Embed.insert_field_at`. (:old-issue:`2178`)
+- Add a ``type`` attribute for all channels to their appropriate :class:`ChannelType`. (:old-issue:`2185`)
+- Add :meth:`Client.fetch_channel` to fetch a channel by ID via HTTP. (:old-issue:`2169`)
+- Add :meth:`Guild.fetch_channels` to fetch all channels via HTTP. (:old-issue:`2169`)
+- |tasks| Add :meth:`Loop.stop <.ext.tasks.Loop.stop>` to gracefully stop a task rather than cancelling.
+- |tasks| Add :meth:`Loop.failed <.ext.tasks.Loop.failed>` to query if a task had failed somehow.
+- |tasks| Add :meth:`Loop.change_interval <.ext.tasks.Loop.change_interval>` to change the sleep interval at runtime (:old-issue:`2158`, :old-issue:`2162`)
+
+Bug Fixes
+~~~~~~~~~~~
+
+- Fix internal error when using :meth:`Guild.prune_members`.
+- |commands| Fix :attr:`.Command.invoked_subcommand` being invalid in many cases.
+- |tasks| Reset iteration count when the loop terminates and is restarted.
+- |tasks| The decorator interface now works as expected when stacking (:old-issue:`2154`)
+
+Miscellaneous
+~~~~~~~~~~~~~~~
+
+- Improve performance of all Enum related code significantly.
+    - This was done by replacing the ``enum.Enum`` code with an API compatible one.
+    - This should not be a breaking change for most users due to duck-typing.
+- Improve performance of message creation by about 1.5x.
+- Improve performance of message editing by about 1.5-4x depending on payload size.
+- Improve performance of attribute access on :class:`Member` about by 2x.
+- Improve performance of :func:`utils.get` by around 4-6x depending on usage.
+- Improve performance of event parsing lookup by around 2.5x.
+- Keyword arguments in :meth:`Client.start` and :meth:`Client.run` are now validated (:old-issue:`953`, :old-issue:`2170`)
+- The Discord error code is now shown in the exception message for :exc:`HTTPException`.
+- Internal tasks launched by the library will now have their own custom ``__repr__``.
+- All public facing types should now have a proper and more detailed ``__repr__``.
+- |tasks| Errors are now logged via the standard :mod:`py:logging` module.
+
+.. _vp1p1p1:
+
+v1.1.1
+--------
+
+Bug Fixes
+~~~~~~~~~~~~
+
+- Webhooks do not overwrite data on retrying their HTTP requests (:old-issue:`2140`)
+
+Miscellaneous
+~~~~~~~~~~~~~~
+
+- Add back signal handling to :meth:`Client.run` due to issues some users had with proper cleanup.
+
+.. _vp1p1p0:
+
+v1.1.0
+---------
+
+New Features
+~~~~~~~~~~~~~~
+
+- **There is a new extension dedicated to making background tasks easier.**
+    - You can check the documentation here: :ref:`ext_tasks_api`.
+- Add :attr:`Permissions.stream` permission. (:old-issue:`2077`)
+- Add equality comparison and hash support to :class:`Asset`
+- Add ``compute_prune_members`` parameter to :meth:`Guild.prune_members` (:old-issue:`2085`)
+- Add :attr:`Client.cached_messages` attribute to fetch the message cache (:old-issue:`2086`)
+- Add :meth:`abc.GuildChannel.clone` to clone a guild channel. (:old-issue:`2093`)
+- Add ``delay`` keyword-only argument to :meth:`Message.delete` (:old-issue:`2094`)
+- Add support for ``<:name:id>`` when adding reactions (:old-issue:`2095`)
+- Add :meth:`Asset.read` to fetch the bytes content of an asset (:old-issue:`2107`)
+- Add :meth:`Attachment.read` to fetch the bytes content of an attachment (:old-issue:`2118`)
+- Add support for voice kicking by passing ``None`` to :meth:`Member.move_to`.
+
+``discord.ext.commands``
+++++++++++++++++++++++++++
+
+- Add new :func:`~.commands.dm_only` check.
+- Support callable converters in :data:`~.commands.Greedy`
+- Add new :class:`~.commands.MessageConverter`.
+    - This allows you to use :class:`Message` as a type hint in functions.
+- Allow passing ``cls`` in the :func:`~.commands.group` decorator (:old-issue:`2061`)
+- Add :attr:`.Command.parents` to fetch the parents of a command (:old-issue:`2104`)
+
+
+Bug Fixes
+~~~~~~~~~~~~
+
+- Fix :exc:`AttributeError` when using ``__repr__`` on :class:`Widget`.
+- Fix issue with :attr:`abc.GuildChannel.overwrites` returning ``None`` for keys.
+- Remove incorrect legacy NSFW checks in e.g. :meth:`TextChannel.is_nsfw`.
+- Fix :exc:`UnboundLocalError` when :class:`RequestsWebhookAdapter` raises an error.
+- Fix bug where updating your own user did not update your member instances.
+- Tighten constraints of ``__eq__`` in :class:`Spotify` objects (:old-issue:`2113`, :old-issue:`2117`)
+
+``discord.ext.commands``
+++++++++++++++++++++++++++
+
+- Fix lambda converters in a non-module context (e.g. ``eval``).
+- Use message creation time for reference time when computing cooldowns.
+    - This prevents cooldowns from triggering during e.g. a RESUME session.
+- Fix the default :func:`on_command_error` to work with new-style cogs (:old-issue:`2094`)
+- DM channels are now recognised as NSFW in :func:`~.commands.is_nsfw` check.
+- Fix race condition with help commands (:old-issue:`2123`)
+- Fix cog descriptions not showing in :class:`~.commands.MinimalHelpCommand` (:old-issue:`2139`)
+
+Miscellaneous
+~~~~~~~~~~~~~~~
+
+- Improve the performance of internal enum creation in the library by about 5x.
+- Make the output of ``python -m discord --version`` a bit more useful.
+- The loop cleanup facility has been rewritten again.
+- The signal handling in :meth:`Client.run` has been removed.
+
+``discord.ext.commands``
+++++++++++++++++++++++++++
+
+- Custom exception classes are now used for all default checks in the library (:old-issue:`2101`)
+
+
+.. _vp1p0p1:
+
+v1.0.1
+--------
+
+Bug Fixes
+~~~~~~~~~~~
+
+- Fix issue with speaking state being cast to ``int`` when it was invalid.
+- Fix some issues with loop cleanup that some users experienced on Linux machines.
+- Fix voice handshake race condition (:old-issue:`2056`, :old-issue:`2063`)
+
+.. _vp1p0p0:
+
+v1.0.0
+--------
+
+The changeset for this version are too big to be listed here, for more information please
+see :ref:`the migrating page <migrating_1_0>`.
+
+
+.. _vp0p16p6:
+
+v0.16.6
+--------
+
+Bug Fixes
+~~~~~~~~~~
+
+- Fix issue with :meth:`Client.create_server` that made it stop working.
+- Fix main thread being blocked upon calling ``StreamPlayer.stop``.
+- Handle HEARTBEAT_ACK and resume gracefully when it occurs.
+- Fix race condition when pre-emptively rate limiting that caused releasing an already released lock.
+- Fix invalid state errors when immediately cancelling a coroutine.
+
+.. _vp0p16p1:
+
+v0.16.1
+--------
+
+This release is just a bug fix release with some better rate limit implementation.
+
+Bug Fixes
+~~~~~~~~~~~
+
+- Servers are now properly chunked for user bots.
+- The CDN URL is now used instead of the API URL for assets.
+- Rate limit implementation now tries to use header information if possible.
+- Event loop is now properly propagated (:old-issue:`420`)
+- Allow falsey values in :meth:`Client.send_message` and :meth:`Client.send_file`.
+
+.. _vp0p16p0:
+
+v0.16.0
+---------
+
+New Features
+~~~~~~~~~~~~~~
+
+- Add :attr:`Channel.overwrites` to get all the permission overwrites of a channel.
+- Add :attr:`Server.features` to get information about partnered servers.
+
+Bug Fixes
+~~~~~~~~~~
+
+- Timeout when waiting for offline members while triggering :func:`on_ready`.
+
+    - The fact that we did not timeout caused a gigantic memory leak in the library that caused
+      thousands of duplicate :class:`Member` instances causing big memory spikes.
+
+- Discard null sequences in the gateway.
+
+    - The fact these were not discarded meant that :func:`on_ready` kept being called instead of
+      :func:`on_resumed`. Since this has been corrected, in most cases :func:`on_ready` will be
+      called once or twice with :func:`on_resumed` being called much more often.
+
+.. _vp0p15p1:
+
+v0.15.1
+---------
+
+- Fix crash on duplicate or out of order reactions.
+
+.. _vp0p15p0:
+
+v0.15.0
+--------
+
+New Features
+~~~~~~~~~~~~~~
+
+- Rich Embeds for messages are now supported.
+
+    - To do so, create your own :class:`Embed` and pass the instance to the ``embed`` keyword argument to :meth:`Client.send_message` or :meth:`Client.edit_message`.
+- Add :meth:`Client.clear_reactions` to remove all reactions from a message.
+- Add support for MESSAGE_REACTION_REMOVE_ALL event, under :func:`on_reaction_clear`.
+- Add :meth:`Permissions.update` and :meth:`PermissionOverwrite.update` for bulk permission updates.
+
+    - This allows you to use e.g. ``p.update(read_messages=True, send_messages=False)`` in a single line.
+- Add :meth:`PermissionOverwrite.is_empty` to check if the overwrite is empty (i.e. has no overwrites set explicitly as true or false).
+
+For the command extension, the following changed:
+
+- ``Context`` is no longer slotted to facilitate setting dynamic attributes.
+
+.. _vp0p14p3:
+
+v0.14.3
+---------
+
+Bug Fixes
+~~~~~~~~~~~
+
+- Fix crash when dealing with MESSAGE_REACTION_REMOVE
+- Fix incorrect buckets for reactions.
+
+.. _v0p14p2:
+
+v0.14.2
+---------
+
+New Features
+~~~~~~~~~~~~~~
+
+- :meth:`Client.wait_for_reaction` now returns a namedtuple with ``reaction`` and ``user`` attributes.
+    - This is for better support in the case that ``None`` is returned since tuple unpacking can lead to issues.
+
+Bug Fixes
+~~~~~~~~~~
+
+- Fix bug that disallowed ``None`` to be passed for ``emoji`` parameter in :meth:`Client.wait_for_reaction`.
+
+.. _v0p14p1:
+
+v0.14.1
+---------
+
+Bug fixes
+~~~~~~~~~~
+
+- Fix bug with `Reaction` not being visible at import.
+    - This was also breaking the documentation.
+
+.. _v0p14p0:
+
+v0.14.0
+--------
+
+This update adds new API features and a couple of bug fixes.
+
+New Features
+~~~~~~~~~~~~~
+
+- Add support for Manage Webhooks permission under :attr:`Permissions.manage_webhooks`
+- Add support for ``around`` argument in 3.5+ :meth:`Client.logs_from`.
+- Add support for reactions.
+    - :meth:`Client.add_reaction` to add a reactions
+    - :meth:`Client.remove_reaction` to remove a reaction.
+    - :meth:`Client.get_reaction_users` to get the users that reacted to a message.
+    - :attr:`Permissions.add_reactions` permission bit support.
+    - Two new events, :func:`on_reaction_add` and :func:`on_reaction_remove`.
+    - :attr:`Message.reactions` to get reactions from a message.
+    - :meth:`Client.wait_for_reaction` to wait for a reaction from a user.
+
+Bug Fixes
+~~~~~~~~~~
+
+- Fix bug with Paginator still allowing lines that are too long.
+- Fix the :attr:`Permissions.manage_emojis` bit being incorrect.
+
+.. _v0p13p0:
+
+v0.13.0
+---------
+
+This is a backwards compatible update with new features.
+
+New Features
+~~~~~~~~~~~~~
+
+- Add the ability to manage emojis.
+
+    - :meth:`Client.create_custom_emoji` to create new emoji.
+    - :meth:`Client.edit_custom_emoji` to edit an old emoji.
+    - :meth:`Client.delete_custom_emoji` to delete a custom emoji.
+- Add new :attr:`Permissions.manage_emojis` toggle.
+
+    - This applies for :class:`PermissionOverwrite` as well.
+- Add new statuses for :class:`Status`.
+
+    - :attr:`Status.dnd` (aliased with :attr:`Status.do_not_disturb`\) for Do Not Disturb.
+    - :attr:`Status.invisible` for setting your status to invisible (please see the docs for a caveat).
+- Deprecate :meth:`Client.change_status`
+
+    - Use :meth:`Client.change_presence` instead for better more up to date functionality.
+    - This method is subject for removal in a future API version.
+- Add :meth:`Client.change_presence` for changing your status with the new Discord API change.
+
+    - This is the only method that allows changing your status to invisible or do not disturb.
+
+Bug Fixes
+~~~~~~~~~~
+
+- Paginator pages do not exceed their max_size anymore (:old-issue:`340`)
+- Do Not Disturb users no longer show up offline due to the new :class:`Status` changes.
+
+.. _v0p12p0:
+
+v0.12.0
+---------
+
+This is a bug fix update that also comes with new features.
+
+New Features
+~~~~~~~~~~~~~
+
+- Add custom emoji support.
+
+    - Adds a new class to represent a custom Emoji named :class:`Emoji`
+    - Adds a utility generator function, :meth:`Client.get_all_emojis`.
+    - Adds a list of emojis on a server, :attr:`Server.emojis`.
+    - Adds a new event, :func:`on_server_emojis_update`.
+- Add new server regions to :class:`ServerRegion`
+
+    - :attr:`ServerRegion.eu_central` and :attr:`ServerRegion.eu_west`.
+- Add support for new pinned system message under :attr:`MessageType.pins_add`.
+- Add order comparisons for :class:`Role` to allow it to be compared with regards to hierarchy.
+
+    - This means that you can now do ``role_a > role_b`` etc to check if ``role_b`` is lower in the hierarchy.
+
+- Add :attr:`Server.role_hierarchy` to get the server's role hierarchy.
+- Add :attr:`Member.server_permissions` to get a member's server permissions without their channel specific overwrites.
+- Add :meth:`Client.get_user_info` to retrieve a user's info from their ID.
+- Add a new ``Player`` property, ``Player.error`` to fetch the error that stopped the player.
+
+    - To help with this change, a player's ``after`` function can now take a single parameter denoting the current player.
+- Add support for server verification levels.
+
+    - Adds a new enum called :class:`VerificationLevel`.
+    - This enum can be used in :meth:`Client.edit_server` under the ``verification_level`` keyword argument.
+    - Adds a new attribute in the server, :attr:`Server.verification_level`.
+- Add :attr:`Server.voice_client` shortcut property for :meth:`Client.voice_client_in`.
+
+    - This is technically old (was added in v0.10.0) but was undocumented until v0.12.0.
+
+For the command extension, the following are new:
+
+- Add custom emoji converter.
+- All default converters that can take IDs can now convert via ID.
+- Add coroutine support for ``Bot.command_prefix``.
+- Add a method to reset command cooldown.
+
+Bug Fixes
+~~~~~~~~~~
+
+- Fix bug that caused the library to not work with the latest ``websockets`` library.
+- Fix bug that leaked keep alive threads (:old-issue:`309`)
+- Fix bug that disallowed :class:`ServerRegion` from being used in :meth:`Client.edit_server`.
+- Fix bug in :meth:`Channel.permissions_for` that caused permission resolution to happen out of order.
+- Fix bug in :attr:`Member.top_role` that did not account for same-position roles.
+
+.. _v0p11p0:
+
+v0.11.0
+--------
+
+This is a minor bug fix update that comes with a gateway update (v5 -> v6).
+
+Breaking Changes
+~~~~~~~~~~~~~~~~~
+
+- ``Permissions.change_nicknames`` has been renamed to :attr:`Permissions.change_nickname` to match the UI.
+
+New Features
+~~~~~~~~~~~~~
+
+- Add the ability to prune members via :meth:`Client.prune_members`.
+- Switch the websocket gateway version to v6 from v5. This allows the library to work with group DMs and 1-on-1 calls.
+- Add :attr:`AppInfo.owner` attribute.
+- Add :class:`CallMessage` for group voice call messages.
+- Add :class:`GroupCall` for group voice call information.
+- Add :attr:`Message.system_content` to get the system message.
+- Add the remaining VIP servers and the Brazil servers into :class:`ServerRegion` enum.
+- Add ``stderr`` argument to :meth:`VoiceClient.create_ffmpeg_player` to redirect stderr.
+- The library now handles implicit permission resolution in :meth:`Channel.permissions_for`.
+- Add :attr:`Server.mfa_level` to query a server's 2FA requirement.
+- Add :attr:`Permissions.external_emojis` permission.
+- Add :attr:`Member.voice` attribute that refers to a :class:`VoiceState`.
+
+    - For backwards compatibility, the member object will have properties mirroring the old behaviour.
+
+For the command extension, the following are new:
+
+- Command cooldown system with the ``cooldown`` decorator.
+- ``UserInputError`` exception for the hierarchy for user input related errors.
+
+Bug Fixes
+~~~~~~~~~~
+
+- :attr:`Client.email` is now saved when using a token for user accounts.
+- Fix issue when removing roles out of order.
+- Fix bug where discriminators would not update.
+- Handle cases where ``HEARTBEAT`` opcode is received. This caused bots to disconnect seemingly randomly.
+
+For the command extension, the following bug fixes apply:
+
+- ``Bot.check`` decorator is actually a decorator not requiring parentheses.
+- ``Bot.remove_command`` and ``Group.remove_command`` no longer throw if the command doesn't exist.
+- Command names are no longer forced to be ``lower()``.
+- Fix a bug where Member and User converters failed to work in private message contexts.
+- ``HelpFormatter`` now ignores hidden commands when deciding the maximum width.
+
+.. _v0p10p0:
+
+v0.10.0
+-------
+
+For breaking changes, see :ref:`migrating-to-async`. The breaking changes listed there will not be enumerated below. Since this version is rather a big departure from v0.9.2, this change log will be non-exhaustive.
+
+New Features
+~~~~~~~~~~~~~
+
+- The library is now fully ``asyncio`` compatible, allowing you to write non-blocking code a lot more easily.
+- The library now fully handles 429s and unconditionally retries on 502s.
+- A new command extension module was added but is currently undocumented. Figuring it out is left as an exercise to the reader.
+- Two new exception types, :exc:`Forbidden` and :exc:`NotFound` to denote permission errors or 404 errors.
+- Added :meth:`Client.delete_invite` to revoke invites.
+- Added support for sending voice. Check :class:`VoiceClient` for more details.
+- Added :meth:`Client.wait_for_message` coroutine to aid with follow up commands.
+- Added :data:`version_info` named tuple to check version info of the library.
+- Login credentials are now cached to have a faster login experience. You can disable this by passing in ``cache_auth=False``
+  when constructing a :class:`Client`.
+- New utility function, :func:`discord.utils.get` to simplify retrieval of items based on attributes.
+- All data classes now support ``!=``, ``==``, ``hash(obj)`` and ``str(obj)``.
+- Added :meth:`Client.get_bans` to get banned members from a server.
+- Added :meth:`Client.invites_from` to get currently active invites in a server.
+- Added :attr:`Server.me` attribute to get the :class:`Member` version of :attr:`Client.user`.
+- Most data classes now support a ``hash(obj)`` function to allow you to use them in ``set`` or ``dict`` classes or subclasses.
+- Add :meth:`Message.clean_content` to get a text version of the content with the user and channel mentioned changed into their names.
+- Added a way to remove the messages of the user that just got banned in :meth:`Client.ban`.
+- Added :meth:`Client.wait_until_ready` to facilitate easy creation of tasks that require the client cache to be ready.
+- Added :meth:`Client.wait_until_login` to facilitate easy creation of tasks that require the client to be logged in.
+- Add :class:`discord.Game` to represent any game with custom text to send to :meth:`Client.change_status`.
+- Add :attr:`Message.nonce` attribute.
+- Add :meth:`Member.permissions_in` as another way of doing :meth:`Channel.permissions_for`.
+- Add :meth:`Client.move_member` to move a member to another voice channel.
+- You can now create a server via :meth:`Client.create_server`.
+- Added :meth:`Client.edit_server` to edit existing servers.
+- Added :meth:`Client.server_voice_state` to server mute or server deafen a member.
+- If you are being rate limited, the library will now handle it for you.
+- Add :func:`on_member_ban` and :func:`on_member_unban` events that trigger when a member is banned/unbanned.
+
+Performance Improvements
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+- All data classes now use ``__slots__`` which greatly reduce the memory usage of things kept in cache.
+- Due to the usage of ``asyncio``, the CPU usage of the library has gone down significantly.
+- A lot of the internal cache lists were changed into dictionaries to change the ``O(n)`` lookup into ``O(1)``.
+- Compressed READY is now on by default. This means if you're on a lot of servers (or maybe even a few) you would
+  receive performance improvements by having to download and process less data.
+- While minor, change regex from ``\d+`` to ``[0-9]+`` to avoid unnecessary unicode character lookups.
+
+Bug Fixes
+~~~~~~~~~~
+
+- Fix bug where guilds being updated did not edit the items in cache.
+- Fix bug where ``member.roles`` were empty upon joining instead of having the ``@everyone`` role.
+- Fix bug where :meth:`Role.is_everyone` was not being set properly when the role was being edited.
+- :meth:`Client.logs_from` now handles cases where limit > 100 to sidestep the discord API limitation.
+- Fix bug where a role being deleted would trigger a ``ValueError``.
+- Fix bug where :meth:`Permissions.kick_members` and :meth:`Permissions.ban_members` were flipped.
+- Mentions are now triggered normally. This was changed due to the way discord handles it internally.
+- Fix issue when a :class:`Message` would attempt to upgrade a :attr:`Message.server` when the channel is
+  a :class:`Object`.
+- Unavailable servers were not being added into cache, this has been corrected.
diff --git a/examples.py b/examples.py
deleted file mode 100644
index 72e0e6e6..00000000
--- a/examples.py
+++ /dev/null
@@ -1,181 +0,0 @@
-import typing
-import discord
-from discord.ext import commands
-from discord import ActionRow, Button, ButtonColor
-
-client = commands.Bot(command_prefix=commands.when_mentioned_or('.!'), intents=discord.Intents.all(), case_insensitive=True)
-
-
-# A Command that sends you a Message and edit it when you click a Button
-
-
-@client.command(name='buttons', description='sends you some nice Buttons')
-async def buttons(ctx: commands.Context):
-    components = [ActionRow(Button(label='Option Nr.1',
-                                   custom_id='option1',
-                                   emoji="🆒",
-                                   style=ButtonColor.green
-                                   ),
-                            Button(label='Option Nr.2',
-                                   custom_id='option2',
-                                   emoji="🆗",
-                                   style=ButtonColor.blurple)),
-                  ActionRow(Button(label='A Other Row',
-                                   custom_id='sec_row_1st option',
-                                   style=ButtonColor.red,
-                                   emoji='😀'),
-                            Button(url='https://www.youtube.com/watch?v=dQw4w9WgXcQ',
-                                   label="This is an Link",
-                                   emoji='🎬'))
-                  ]
-    an_embed = discord.Embed(title='Here are some Button\'s', description='Choose an option', color=discord.Color.random())
-    msg = await ctx.send(embed=an_embed, components=components)
-
-    def _check(i: discord.Interaction, b: discord.ButtonClick):
-        return i.message == msg and i.author == ctx.author
-
-    interaction, button = await client.wait_for('button_click', check=_check)
-    button_id = button.custom_id
-
-    # This sends the Discord-API that the interaction has been received and is being "processed"
-    await interaction.defer()  # if this is not used and you also do not edit the message within 3 seconds as described below, Discord will indicate that the interaction has failed.
-
-    # If you use interaction.edit instead of interaction.message.edit, you do not have to deffer the interaction if your response does not last longer than 3 seconds.
-    await interaction.edit(embed=an_embed.add_field(name='Choose', value=f'Your Choose was `{button_id}`'),
-                           components=[components[0].disable_all_buttons(), components[1].disable_all_buttons()])
-
-    # The Discord API doesn't send an event when you press a link button so we can't "receive" that.
-
-client.run('your Bot-Token here')
-########################################################################################################################
-
-
-# Another command where a small embed is sent where you can move the small white ⬜ with the buttons.
-
-pointers = []
-
-
-class Pointer:
-    """Just a small class that facilitates holding and changing the position of the square."""
-    def __init__(self, guild: discord.Guild):
-        self.guild = guild
-        self._possition_x = 0
-        self._possition_y = 0
-
-    @property
-    def possition_x(self):
-        return self._possition_x
-
-    def set_x(self, x: int):
-        self._possition_x += x
-        return self._possition_x
-
-    @property
-    def possition_y(self):
-        return self._possition_y
-
-    def set_y(self, y: int):
-        self._possition_y += y
-        return self._possition_y
-
-
-def get_pointer(obj: typing.Union[discord.Guild, int]):
-    if isinstance(obj, discord.Guild):
-        for p in pointers:
-            if p.guild.id == obj.id:
-                return p
-        pointers.append(Pointer(obj))
-        return get_pointer(obj)
-
-    elif isinstance(obj, int):
-        for p in pointers:
-            if p.guild.id == obj:
-                return p
-        guild = client.get_guild(obj)
-        if guild:
-            pointers.append(Pointer(guild))
-            return get_pointer(guild)
-        return None
-
-
-def display(x: int, y: int):
-    """This function ``renders`` and returns the image"""
-    base = [
-        [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
-        [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
-        [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
-        [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
-        [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
-        [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
-        [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
-        [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
-        [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
-        [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
-    ]
-    base[y].__setitem__(x, 1)
-    base.reverse()
-    return ''.join(f"\n{''.join([str(base[i][w]) for w in range(len(base[i]))]).replace('0', '⬛').replace('1', '⬜')}" for i in range(len(base)))
-
-
-empty_button = discord.Button(style=discord.ButtonStyle.Secondary, label=" ", custom_id="empty", disabled=True)
-
-
-def arrow_button():
-    return discord.Button(style=discord.ButtonStyle.Primary)
-
-
-@client.command(name="start_game")
-async def start_game(ctx: commands.Context):
-    pointer: Pointer = get_pointer(ctx.guild)
-    await ctx.send(embed=discord.Embed(title="Little Game",
-                                       description=display(x=0, y=0)),
-                   components=[discord.ActionRow(empty_button, arrow_button().set_label('↑').set_custom_id('up'), empty_button),
-                               discord.ActionRow(arrow_button().update(disabled=True).set_label('←').set_custom_id('left').disable_if(pointer.possition_x <= 0),
-                                                 arrow_button().set_label('↓').set_custom_id('down').disable_if(pointer.possition_y <= 0),
-                                                 arrow_button().set_label('→').set_custom_id('right'))
-                               ]
-                   )
-
-
-@client.event
-async def on_raw_button_click(interaction: discord.Interaction, button: discord.ButtonClick):
-    await interaction.defer()
-    pointer: Pointer = get_pointer(interaction.guild)
-    if not (message := interaction.message):
-        message: discord.Message = await interaction.channel.fetch_message(interaction.message_id)
-    if button.custom_id == "up":
-        pointer.set_y(1)
-        await message.edit(embed=discord.Embed(title="Little Game",
-                                               description=display(x=pointer.possition_x, y=pointer.possition_y)),
-                           components=[discord.ActionRow(empty_button, arrow_button().set_label('↑').set_custom_id('up').disable_if(pointer.possition_y >= 9), empty_button),
-                                       discord.ActionRow(arrow_button().set_label('←').set_custom_id('left').disable_if(pointer.possition_x <= 0),
-                                                         arrow_button().set_label('↓').set_custom_id('down'),
-                                                         arrow_button().set_label('→').set_custom_id('right').disable_if(pointer.possition_x >= 9))]
-                           )
-    elif button.custom_id == "down":
-        pointer.set_y(-1)
-        await message.edit(embed=discord.Embed(title="Little Game",
-                                               description=display(x=pointer.possition_x, y=pointer.possition_y)),
-                           components=[discord.ActionRow(empty_button, arrow_button().set_label('↑').set_custom_id('up'), empty_button),
-                                       discord.ActionRow(arrow_button().set_label('←').set_custom_id('left').disable_if(pointer.possition_x <= 0),
-                                                         arrow_button().set_label('↓').set_custom_id('down').disable_if(pointer.possition_y <= 0),
-                                                         arrow_button().set_label('→').set_custom_id('right').disable_if(pointer.possition_x >= 9))]
-                           )
-    elif button.custom_id == "right":
-        pointer.set_x(1)
-        await message.edit(embed=discord.Embed(title="Little Game",
-                                               description=display(x=pointer.possition_x, y=pointer.possition_y)),
-                           components=[discord.ActionRow(empty_button, arrow_button().set_label('↑').set_custom_id('up'), empty_button),
-                                       discord.ActionRow(arrow_button().set_label('←').set_custom_id('left'),
-                                                         arrow_button().set_label('↓').set_custom_id('down'),
-                                                         arrow_button().set_label('→').set_custom_id('right').disable_if(pointer.possition_x >= 9))]
-                           )
-    elif button.custom_id == "left":
-        pointer.set_x(-1)
-        await message.edit(embed=discord.Embed(title="Little Game",
-                                               description=display(x=pointer.possition_x, y=pointer.possition_y)),
-                           components=[discord.ActionRow(empty_button, arrow_button().set_label('↑').set_custom_id('up'), empty_button),
-                                       discord.ActionRow(arrow_button().set_label('←').set_custom_id('left').disable_if(pointer.possition_x <= 0),
-                                                         arrow_button().set_label('↓').set_custom_id('down'),
-                                                         arrow_button().set_label('→').set_custom_id('right'))]
-                           )
diff --git a/examples/basic_bot.py b/examples/basic_bot.py
new file mode 100644
index 00000000..1f4fee9f
--- /dev/null
+++ b/examples/basic_bot.py
@@ -0,0 +1,31 @@
+from pathlib import Path
+import discord
+from discord.ext import commands
+
+TOKEN = "TOKEN"
+cog_directory = "cogs"  # directory containing the extensions (cogs)
+
+
+bot = commands.Bot(
+    command_prefix=commands.when_mentioned_or('!'),
+    intents=discord.Intents.all(),
+    case_insensitive=True,
+    sync_commands=True
+)
+
+
+@bot.event
+async def on_ready():
+    print("======")
+    print(f"{bot.user.name}")
+    print("======")
+
+
+@bot.command()
+async def ping(ctx):
+    ctx.send("Pong!")
+
+if __name__ == "__main__":
+    _cogs = [p.stem for p in Path(cog_directory).glob('*.py')]
+    [(bot.load_extension(f'.{ext}', package=cog_directory), print(f'{ext} was loaded successfully')) for ext in _cogs]
+    bot.run(TOKEN)
diff --git a/examples/buttons/README.md b/examples/buttons/README.md
new file mode 100644
index 00000000..680ca9b5
--- /dev/null
+++ b/examples/buttons/README.md
@@ -0,0 +1,16 @@
+A simple calculator using Buttons
+==================================
+
+There are two versions of this calculator. [One](./calculator_ansi.py) that uses the [ansi syntax](https://gist.github.com/kkrypt0nn/a02506f3712ff2d1c8ca7c9e0aed7c06) to let the display looks better and [another](./calculator.py) that uses normal `py` highlight.
+
+#### NOTE
+
+```text
+Currently (on 12.07.2022) the ansi syntax highlight is not available on all clients.
+So if you're on PC it should work, but if you want that mobile users can use it too it's better to use the version without ansi.
+```
+### Usage examples
+
+This video shows the [ansi version](./calculator_ansi.py)
+
+https://user-images.githubusercontent.com/80390413/178399452-3be3ac6f-d142-4a77-802a-f6a83bbb55b2.mp4
diff --git a/examples/buttons/calculator.py b/examples/buttons/calculator.py
new file mode 100644
index 00000000..2ec21a64
--- /dev/null
+++ b/examples/buttons/calculator.py
@@ -0,0 +1,286 @@
+import re
+import typing
+import discord
+import asyncio
+from discord import Button
+from discord.ext import commands
+
+
+components = [
+    [
+        Button(label='C', custom_id='cancel', style=discord.ButtonStyle.red),
+        Button(label='(', custom_id='calculator:(', style=discord.ButtonStyle.green, disabled=True),  # soon™
+        Button(label=')', custom_id='calculator:)', style=discord.ButtonStyle.green, disabled=True),  # soon™
+        Button(label='/', custom_id='calculator:/', style=discord.ButtonStyle.green)
+    ],
+    [
+        Button(label='7', custom_id='calculator:7', style=discord.ButtonStyle.blurple),
+        Button(label='8', custom_id='calculator:8', style=discord.ButtonStyle.blurple),
+        Button(label='9', custom_id='calculator:9', style=discord.ButtonStyle.blurple),
+        Button(label='x', custom_id='calculator:*', style=discord.ButtonStyle.green)
+    ],
+    [
+        Button(label='4', custom_id='calculator:4', style=discord.ButtonStyle.blurple),
+        Button(label='5', custom_id='calculator:5', style=discord.ButtonStyle.blurple),
+        Button(label='6', custom_id='calculator:6', style=discord.ButtonStyle.blurple),
+        Button(label='-', custom_id='calculator:-', style=discord.ButtonStyle.green)
+    ],
+    [
+        Button(label='1', custom_id='calculator:1', style=discord.ButtonStyle.blurple),
+        Button(label='2', custom_id='calculator:2', style=discord.ButtonStyle.blurple),
+        Button(label='3', custom_id='calculator:3', style=discord.ButtonStyle.blurple),
+        Button(label='+', custom_id='calculator:+', style=discord.ButtonStyle.green)
+    ],
+    [
+        Button(label='+/-', custom_id='calculator:+/-', style=discord.ButtonStyle.blurple),
+        Button(label='0', custom_id='calculator:0', style=discord.ButtonStyle.blurple),
+        Button(label=',', custom_id='calculator:,', style=discord.ButtonStyle.blurple),
+        Button(label='=', custom_id='calculator:=', style=discord.ButtonStyle.green)
+    ]
+]
+
+
+def is_author(func) -> typing.Coroutine:
+    """
+    Just a small decorator that checks if the author is allowed to interact with the calculator instance
+    """
+    actual = typing.Final = func
+
+    async def func(self, interaction: discord.BaseInteraction, button):
+        calc = self.get_calculator(interaction.message, interaction.author)
+        if calc:
+            await actual(self, interaction, button, calc)
+
+    func.__name__ = actual.__name__
+    return func
+
+
+class CalculatorUnit:
+    def __init__(self, msg: discord.Message, author: discord.User, color: discord.Color = discord.Color.random()) -> None:
+        self.author: discord.User = author
+        self.msg: discord.Message = msg
+        self.color = color
+        self._a: typing.Optional[str] = None
+        self._b: typing.Optional[str] = None
+        self._method: typing.Optional[str] = None
+        self._result: int = 0
+
+    @property
+    def a(self) -> str:
+        return self._a
+
+    @a.setter
+    def a(self, amount) -> None:
+        if not self.a:
+            self._a = ''
+        if amount == '.':
+            self._a = self._a.replace('.', '')
+            self._a += str(amount)
+        elif amount != '.':
+            self._a += str(amount)
+
+    @property
+    def b(self) -> str:
+        return self._b
+
+    @b.setter
+    def b(self, amount) -> None:
+        if not self.b:
+            self._b = ''
+        if amount == '.':
+            self._b = self._b.replace('.', '')
+            self._b += str(amount)
+        elif amount != '.':
+            self._b += str(amount)
+
+    @property
+    def method(self) -> str:
+        return self._method
+
+    @method.setter
+    def method(self, _type) -> None:
+        self._method = _type
+
+    async def calculate(self, interaction: discord.BaseInteraction, new_method: typing.Optional[str] = None) -> None:
+        self._result = str(eval(f'{float(self._a)} {self.method} {float(self._b)}'))
+        if self._result[-2:] == '.0':
+            self._result = self._a = self._result[:-2]
+        else:
+            self._a = self._result
+        self._b = None
+        self._method = new_method
+        await self.update_display(interaction)
+
+    async def delete(self) -> None:
+        await self.msg.delete()
+        del self
+
+    async def reset(self, interaction: typing.Optional[discord.BaseInteraction] = None) -> None:
+        self._a = None
+        self._b = None
+        self._method = None
+        self._result = 0
+        embed = discord.Embed(description="```py\n                                      0```", color=self.color)
+        if interaction:
+            await interaction.edit(embed=embed, components=components)
+        else:
+            await self.msg.edit(embed=embed, components=components)
+
+    async def update_display(self, interaction: discord.BaseInteraction = None):
+        if self.a and not self.b:
+            output = self.a
+        elif self.b:
+            output = self.b
+        else:
+            output = '0'
+        spaces = '                                       '[len(output) + len(f'{" |  " if self.method else ""}'):]
+        method = f"{self.method}".replace('**', '^')
+        embed = discord.Embed(description=f'```py\n{spaces}{output}{f" | {method}" if self.method else ""}\n```',
+                              color=self.color)
+        if interaction:
+            await interaction.edit(embed=embed)
+        else:
+            await self.msg.edit(embed=embed, components=components)
+
+
+class Calculator(commands.Cog):
+    def __init__(self, bot) -> None:
+        self.bot: commands.Bot = bot
+        self.calculators = {}
+
+    def get_calculator(self, message: discord.Message, author) -> typing.Optional[CalculatorUnit]:
+        try:
+            calc = self.calculators[message.id]
+        except KeyError:
+            c_author = message.mentions[0]
+            self.calculators[message.id] = calc = CalculatorUnit(message, c_author, message.embeds[0].color)
+            description = message.embeds[0].description.split('|')
+            calc.a = description.pop(0).strip('\n```py ')
+            if description:
+                calc._method = description.pop(0).strip('\n``` ')
+        return calc if calc.author == author else None
+
+    def add_calculator(self, calculator: CalculatorUnit) -> CalculatorUnit:
+        self.calculators[calculator.msg.id] = calculator
+        return calculator
+
+    def remove_calculator(self, calculator: CalculatorUnit) -> typing.Optional[CalculatorUnit]:
+        return self.calculators.pop(calculator.msg.id, None)
+
+    @commands.Cog.slash_command(name="calculator", description="open an calculator")
+    async def calculator(self, ctx: discord.ApplicationCommandInteraction) -> None:
+        embed = discord.Embed(color=discord.Color.random(),
+                              description="```py\n                                      \u001b[34m0\n```")
+        calc = self.add_calculator(
+            CalculatorUnit(await ctx.respond(ctx.author.mention, embed=embed, components=components), ctx.author, embed.color))
+
+        def _check(i, _) -> bool:
+            return i.author == ctx.author and i.author == ctx.author
+
+        while True:  # This is just to let the calculator "timeout" after a specific time without any input
+            try:
+                await self.bot.wait_for('button_click', timeout=300.0, check=_check)
+            except asyncio.TimeoutError:
+                break
+        await calc.delete()
+
+    @commands.Cog.on_click()
+    @is_author
+    async def cancel(self, interaction: discord.ComponentInteraction, button, calc):
+        await calc.reset(interaction)
+
+    @commands.Cog.on_click(r'^calculator:\d+$')
+    @is_author
+    async def number_press(self, interaction: discord.ComponentInteraction, button: Button, calc):
+        if not calc.method and not calc.b:
+            if calc.a == '0':
+                return await interaction.defer()
+            calc.a = button.custom_id.replace('calculator:', '')
+        elif calc.a and calc.method:
+            if calc.b == '0':
+                return await interaction.defer()
+            calc.b = button.custom_id.replace('calculator:', '')
+        await calc.update_display(interaction)
+
+    @commands.Cog.on_click(r'^calculator:\+$')
+    @is_author
+    async def add(self, interaction, button, calc):
+        if calc.method and calc.a and calc.b:
+            await calc.calculate(interaction, '+')
+        else:
+            calc.method = '+'
+            await calc.update_display(interaction)
+
+    @commands.Cog.on_click(r'^calculator:-$')
+    @is_author
+    async def subtract(self, interaction, button, calc):
+        if calc.method and calc.a and calc.b:
+            await calc.calculate(interaction, '-')
+        else:
+            calc.method = '-'
+            await calc.update_display(interaction)
+
+    @commands.Cog.on_click(r'^calculator:/$')
+    @is_author
+    async def divide(self, interaction, button, calc):
+        if calc.method and calc.a and calc.b:
+            await calc.calculate(interaction, '/')
+        else:
+            if calc.method == '/':
+                calc.method += '/'
+            else:
+                calc.method = '/'
+            await calc.update_display(interaction)
+
+    @commands.Cog.on_click(r'^calculator:\*$')
+    @is_author
+    async def multiply(self, interaction, button, calc):
+        if calc.method and calc.a and calc.b:
+            await calc.calculate(interaction, '*')
+        else:
+            if calc.method == '*':
+                calc.method += '*'
+            else:
+                calc.method = '*'
+            await calc.update_display(interaction)
+
+    @commands.Cog.on_click(r'^calculator:=$')
+    @is_author
+    async def calculate(self, interaction, button, calc):
+        if calc.a and calc.method and calc.b:
+            await calc.calculate(interaction)
+
+    @commands.Cog.on_click(r'^calculator:[,]$')
+    @is_author
+    async def point(self, interaction, button, calc):
+        if calc.a and not calc.method:
+            if calc._a[-1] == '.':
+                calc._a = calc._a.strip('.')
+            else:
+                calc.a = '.'
+        elif calc.method and calc.b:
+            if calc._b[-1] == '.':
+                calc._b = calc._b.strip('.')
+            else:
+                calc.b = '.'
+        await calc.update_display(interaction)
+
+    @commands.Cog.on_click(r'^calculator:\+/\-$')
+    @is_author
+    async def toggle_negative(self, interaction, button, calc):
+        if calc.a and not calc.method:
+            if calc.a[0].isdigit():
+                calc._a = '-' + calc.a
+            else:
+                calc._a = calc.a.strip('-')
+
+        elif calc.method and calc.b:
+            if calc.b[0].isdigit():
+                calc._b = '-' + calc.b
+            else:
+                calc._b = calc.b.strip('-')
+        await calc.update_display(interaction)
+
+
+def setup(bot):
+    bot.add_cog(Calculator(bot))
diff --git a/examples/buttons/calculator_ansi.py b/examples/buttons/calculator_ansi.py
new file mode 100644
index 00000000..c8ad75b8
--- /dev/null
+++ b/examples/buttons/calculator_ansi.py
@@ -0,0 +1,293 @@
+import re
+import typing
+import discord
+import asyncio
+from discord import Button
+from discord.ext import commands
+
+
+components = [
+    [
+        Button(label='C', custom_id='cancel', style=discord.ButtonStyle.red),
+        Button(label='(', custom_id='calculator:(', style=discord.ButtonStyle.green, disabled=True),  # soon™
+        Button(label=')', custom_id='calculator:)', style=discord.ButtonStyle.green, disabled=True),  # soon™
+        Button(label='/', custom_id='calculator:/', style=discord.ButtonStyle.green)
+    ],
+    [
+        Button(label='7', custom_id='calculator:7', style=discord.ButtonStyle.blurple),
+        Button(label='8', custom_id='calculator:8', style=discord.ButtonStyle.blurple),
+        Button(label='9', custom_id='calculator:9', style=discord.ButtonStyle.blurple),
+        Button(label='x', custom_id='calculator:*', style=discord.ButtonStyle.green)
+    ],
+    [
+        Button(label='4', custom_id='calculator:4', style=discord.ButtonStyle.blurple),
+        Button(label='5', custom_id='calculator:5', style=discord.ButtonStyle.blurple),
+        Button(label='6', custom_id='calculator:6', style=discord.ButtonStyle.blurple),
+        Button(label='-', custom_id='calculator:-', style=discord.ButtonStyle.green)
+    ],
+    [
+        Button(label='1', custom_id='calculator:1', style=discord.ButtonStyle.blurple),
+        Button(label='2', custom_id='calculator:2', style=discord.ButtonStyle.blurple),
+        Button(label='3', custom_id='calculator:3', style=discord.ButtonStyle.blurple),
+        Button(label='+', custom_id='calculator:+', style=discord.ButtonStyle.green)
+    ],
+    [
+        Button(label='+/-', custom_id='calculator:+/-', style=discord.ButtonStyle.blurple),
+        Button(label='0', custom_id='calculator:0', style=discord.ButtonStyle.blurple),
+        Button(label=',', custom_id='calculator:,', style=discord.ButtonStyle.blurple),
+        Button(label='=', custom_id='calculator:=', style=discord.ButtonStyle.green)
+    ]
+]
+
+
+def is_author(func) -> typing.Coroutine:
+    """
+    Just a small decorator that checks if the author is allowed to interact with the calculator instance
+    """
+    actual = typing.Final = func
+
+    async def func(self, interaction: discord.BaseInteraction, button):
+        calc = self.get_calculator(interaction.message, interaction.author)
+        if calc:
+            await actual(self, interaction, button, calc)
+
+    func.__name__ = actual.__name__
+    return func
+
+
+def escape_ansi(line) -> str:
+    """To remove the ansi characters when creating a calculator instance from an existing message"""
+    ansi_escape = re.compile(r'(\x9B|\x1B\[)[0-?]*[ -/]*[@-~]')
+    return ansi_escape.sub('', str(line))
+
+
+class CalculatorUnit:
+    def __init__(self, msg: discord.Message, author: discord.User, color: discord.Color = discord.Color.random()) -> None:
+        self.author: discord.User = author
+        self.msg: discord.Message = msg
+        self.color = color
+        self._a: typing.Optional[str] = None
+        self._b: typing.Optional[str] = None
+        self._method: typing.Optional[str] = None
+        self._result: int = 0
+
+    @property
+    def a(self) -> str:
+        return self._a
+
+    @a.setter
+    def a(self, amount) -> None:
+        if not self.a:
+            self._a = ''
+        if amount == '.':
+            self._a = self._a.replace('.', '')
+            self._a += str(amount)
+        elif amount != '.':
+            self._a += str(amount)
+
+    @property
+    def b(self) -> str:
+        return self._b
+
+    @b.setter
+    def b(self, amount) -> None:
+        if not self.b:
+            self._b = ''
+        if amount == '.':
+            self._b = self._b.replace('.', '')
+            self._b += str(amount)
+        elif amount != '.':
+            self._b += str(amount)
+
+    @property
+    def method(self) -> str:
+        return self._method
+
+    @method.setter
+    def method(self, _type) -> None:
+        self._method = _type
+
+    async def calculate(self, interaction: discord.BaseInteraction, new_method: typing.Optional[str] = None) -> None:
+        self._result = str(eval(f'{float(self._a)} {self.method} {float(self._b)}'))
+        if self._result[-2:] == '.0':
+            self._result = self._a = self._result[:-2]
+        else:
+            self._a = self._result
+        self._b = None
+        self._method = new_method
+        await self.update_display(interaction)
+
+    async def delete(self) -> None:
+        await self.msg.delete()
+        del self
+
+    async def reset(self, interaction: typing.Optional[discord.BaseInteraction] = None) -> None:
+        self._a = None
+        self._b = None
+        self._method = None
+        self._result = 0
+        embed = discord.Embed(description="```ansi\n                                      \u001b[34m0\n```", color=self.color)
+        if interaction:
+            await interaction.edit(embed=embed, components=components)
+        else:
+            await self.msg.edit(embed=embed, components=components)
+
+    async def update_display(self, interaction: discord.BaseInteraction = None):
+        if self.a and not self.b:
+            output = self.a
+        elif self.b:
+            output = self.b
+        else:
+            output = '0'
+        spaces = '                                       '[len(output) + len(f'{" |  " if self.method else ""}'):]
+        output = f'\u001b[1;34m{output}\u001b[0m'.replace("-", f"\u001b[33m-\u001b[34m")
+        method = f"\u001b[0;31m{self.method}\u001b[0m".replace('**', '^')
+        embed = discord.Embed(description=f'```ansi\n{spaces}{output}{f" | {method}" if self.method else ""}\n```',
+                              color=self.color)
+        if interaction:
+            await interaction.edit(embed=embed)
+        else:
+            await self.msg.edit(embed=embed, components=components)
+
+
+class Calculator(commands.Cog):
+    def __init__(self, bot) -> None:
+        self.bot: commands.Bot = bot
+        self.calculators = {}
+
+    def get_calculator(self, message: discord.Message, author) -> typing.Optional[CalculatorUnit]:
+        try:
+            calc = self.calculators[message.id]
+        except KeyError:
+            c_author = message.mentions[0]
+            self.calculators[message.id] = calc = CalculatorUnit(message, c_author, message.embeds[0].color)
+            description = escape_ansi(message.embeds[0].description).split('|')
+            calc.a = description.pop(0).strip('\n```ansi ')
+            if description:
+                calc._method = description.pop(0).strip('\n``` ')
+        return calc if calc.author == author else None
+
+    def add_calculator(self, calculator: CalculatorUnit) -> CalculatorUnit:
+        self.calculators[calculator.msg.id] = calculator
+        return calculator
+
+    def remove_calculator(self, calculator: CalculatorUnit) -> typing.Optional[CalculatorUnit]:
+        return self.calculators.pop(calculator.msg.id, None)
+
+    @commands.Cog.slash_command(name="calculator", description="open an calculator")
+    async def calculator(self, ctx: discord.ApplicationCommandInteraction) -> None:
+        embed = discord.Embed(color=discord.Color.random(),
+                              description="```ansi\n                                      \u001b[34m0\n```")
+        calc = self.add_calculator(
+            CalculatorUnit(await ctx.respond(ctx.author.mention, embed=embed, components=components), ctx.author, embed.color))
+
+        def _check(i, _) -> bool:
+            return i.author == ctx.author and i.author == ctx.author
+
+        while True:  # This is just to let the calculator "timeout" after a specific time without any input
+            try:
+                await self.bot.wait_for('button_click', timeout=300.0, check=_check)
+            except asyncio.TimeoutError:
+                break
+        await calc.delete()
+
+    @commands.Cog.on_click()
+    @is_author
+    async def cancel(self, interaction: discord.ComponentInteraction, button, calc):
+        await calc.reset(interaction)
+
+    @commands.Cog.on_click(r'^calculator:\d+$')
+    @is_author
+    async def number_press(self, interaction: discord.ComponentInteraction, button: Button, calc):
+        if not calc.method and not calc.b:
+            if calc.a == '0':
+                return await interaction.defer()
+            calc.a = button.custom_id.replace('calculator:', '')
+        elif calc.a and calc.method:
+            if calc.b == '0':
+                return await interaction.defer()
+            calc.b = button.custom_id.replace('calculator:', '')
+        await calc.update_display(interaction)
+
+    @commands.Cog.on_click(r'^calculator:\+$')
+    @is_author
+    async def add(self, interaction, button, calc):
+        if calc.method and calc.a and calc.b:
+            await calc.calculate(interaction, '+')
+        else:
+            calc.method = '+'
+            await calc.update_display(interaction)
+
+    @commands.Cog.on_click(r'^calculator:-$')
+    @is_author
+    async def subtract(self, interaction, button, calc):
+        if calc.method and calc.a and calc.b:
+            await calc.calculate(interaction, '-')
+        else:
+            calc.method = '-'
+            await calc.update_display(interaction)
+
+    @commands.Cog.on_click(r'^calculator:/$')
+    @is_author
+    async def divide(self, interaction, button, calc):
+        if calc.method and calc.a and calc.b:
+            await calc.calculate(interaction, '/')
+        else:
+            if calc.method == '/':
+                calc.method += '/'
+            else:
+                calc.method = '/'
+            await calc.update_display(interaction)
+
+    @commands.Cog.on_click(r'^calculator:\*$')
+    @is_author
+    async def multiply(self, interaction, button, calc):
+        if calc.method and calc.a and calc.b:
+            await calc.calculate(interaction, '*')
+        else:
+            if calc.method == '*':
+                calc.method += '*'
+            else:
+                calc.method = '*'
+            await calc.update_display(interaction)
+
+    @commands.Cog.on_click(r'^calculator:=$')
+    @is_author
+    async def calculate(self, interaction, button, calc):
+        if calc.a and calc.method and calc.b:
+            await calc.calculate(interaction)
+
+    @commands.Cog.on_click(r'^calculator:[,]$')
+    @is_author
+    async def point(self, interaction, button, calc):
+        if calc.a and not calc.method:
+            if calc._a[-1] == '.':
+                calc._a = calc._a.strip('.')
+            else:
+                calc.a = '.'
+        elif calc.method and calc.b:
+            if calc._b[-1] == '.':
+                calc._b = calc._b.strip('.')
+            else:
+                calc.b = '.'
+        await calc.update_display(interaction)
+
+    @commands.Cog.on_click(r'^calculator:\+/\-$')
+    @is_author
+    async def toggle_negative(self, interaction, button, calc):
+        if calc.a and not calc.method:
+            if calc.a[0].isdigit():
+                calc._a = '-' + calc.a
+            else:
+                calc._a = calc.a.strip('-')
+
+        elif calc.method and calc.b:
+            if calc.b[0].isdigit():
+                calc._b = '-' + calc.b
+            else:
+                calc._b = calc.b.strip('-')
+        await calc.update_display(interaction)
+
+
+def setup(bot):
+    bot.add_cog(Calculator(bot))
diff --git a/examples/modals/README.md b/examples/modals/README.md
new file mode 100644
index 00000000..b16e750f
--- /dev/null
+++ b/examples/modals/README.md
@@ -0,0 +1,8 @@
+A simple suggestions manager using Modals
+=========================================
+
+### Usage examples
+
+https://user-images.githubusercontent.com/80390413/170806145-074cb35f-1e22-4ad9-8b25-647c3a4b3f8f.mp4
+
+https://user-images.githubusercontent.com/80390413/164894876-19d63c42-9021-4287-a4f1-99ef892eb32f.mp4
diff --git a/examples/modals/suggestions.py b/examples/modals/suggestions.py
new file mode 100644
index 00000000..acf7e077
--- /dev/null
+++ b/examples/modals/suggestions.py
@@ -0,0 +1,371 @@
+import re
+import asyncio
+import discord
+from discord.ext import commands
+
+from discord import ComponentInteraction, ModalSubmitInteraction, Modal, TextInput, Button, ButtonStyle
+
+
+class ModalSuggestions(commands.Cog):
+    def __init__(self, bot):
+        self.bot = bot
+
+    @commands.command()
+    @commands.is_owner()
+    async def send_suggestmsg(self, ctx):
+        embed = discord.Embed(title='Suggestions', description='Click the button below to add a new suggestion',
+                              color=discord.Color.orange())
+        embed.add_field(
+            name='Note:',
+            value='If you want to include images/video you must do this via. a file hoster like '
+                  '[tixte](https://tixte.com/?ref=mccoder-py-needs.to-sleep.xyz) or [imgur](https://imgur.com/).'
+        )
+        embed.set_footer(
+            text='⚠The image link must be a direct(direct link to the file) link '
+                 '(These usually do not form an embed in Discord and look like normal uploaded files)⚠.'
+        )
+        await ctx.send(embed=embed, components=[[
+            Button(label='New Suggestion',
+                   custom_id='suggestion:new',
+                   style=ButtonStyle.blurple,
+                   emoji='💡')
+        ]])
+
+    @commands.Cog.on_click(r'^suggestion:new$')
+    async def new_suggestion(self, interaction: ComponentInteraction, button):
+        suggest_modal = Modal(custom_id=f'suggestion:new:{interaction.id}:{interaction.author.id}',
+                              title='Create a new Suggestion.',
+                              components=[TextInput(custom_id='short_description',
+                                                    label='Short description of your suggestion',
+                                                    style=1,
+                                                    min_length=10,
+                                                    max_length=256,
+                                                    placeholder='Implement new Modals'),
+                                          TextInput(custom_id='description',
+                                                    label='Description',
+                                                    style=2,
+                                                    min_length=20,
+                                                    placeholder='Discord released -x- that should be implemented here.'),
+                                          TextInput(custom_id='wy',
+                                                    label='Wy this feature should be changed/implemented',
+                                                    style=2,
+                                                    min_length=20,
+                                                    max_length=1000,
+                                                    required=False,
+                                                    placeholder='With this new feature you can make -x-.')
+                                          ])
+        await interaction.respond_with_modal(modal=suggest_modal)
+        try:
+            inter: ModalSubmitInteraction = await self.bot.wait_for(
+                'modal_submit',
+                check=lambda ms: ms.custom_id == f'suggestion:new:{interaction.id}:{interaction.author.id}',
+                timeout=5000
+            )
+        except asyncio.TimeoutError:
+            pass
+        else:
+            description: str = inter.get_field('description').value
+            image_urls = re.findall(
+                r"(?P<url>https://[^\s]+\.(jpeg|jpg|webp|png|gif|mp4))",
+                description
+            )  # I know this is actually not the best RegEx
+            for index, url in enumerate(image_urls):
+                if index == 0:
+                    description = description.replace(url[0],
+                                                      f'[see {"video" if url[0].endswith(".mp4") else "image"} below]')
+                else:
+                    description = description.replace(url[0], f'[attachment-{index}]')
+
+            embed = discord.Embed(
+                title=inter.get_field('short_description').value,
+                description=f"```\n{description}\n```"
+            )
+            if wy := inter.get_field('wy').value:
+                embed.add_field(name='Wy should this be added/updated?',
+                                value=f'```\n{wy}\n```',
+                                inline=False
+                                )
+            embed.set_author(icon_url=inter.author.avatar_url,
+                             name=str(inter.author),
+                             url=f'https://discord.com/users/{inter.author.id}'
+                             )
+            embed.set_footer(text='See the attachments in the thread below')
+            content = None
+            if image_urls:
+                url = image_urls.pop(0)[0]
+                if url.endswith('.mp4'):
+                    content = url
+                else:
+                    embed.set_image(url=url)
+            mes = await inter.respond(
+                embed=embed,
+                components=[
+                    [
+                        Button(
+                            label='delete suggestion',
+                            custom_id=f'suggestion:delete',
+                            style=ButtonStyle.red,
+                            emoji='🗑️'
+                        ),
+                        Button(
+                            label='edit suggestion',
+                            custom_id=f'suggestion:edit:{inter.author.id}',
+                            style=ButtonStyle.grey,
+                            emoji='↩'
+                        )
+                    ]
+                ]
+            )
+            url_msg = None
+            if content:
+                url_msg = await inter.channel.send(content)
+            if url_msg:
+                await mes.edit(
+                    components=[
+                        [
+                            Button(
+                                label='delete suggestion',
+                                custom_id=f'suggestion:delete:{url_msg.id}',
+                                style=ButtonStyle.red,
+                                emoji='🗑️'
+                            ),
+                            Button(
+                                label='edit suggestion',
+                                custom_id=f'suggestion:edit:{inter.author.id}',
+                                style=ButtonStyle.grey,
+                                emoji='↩'
+                            )
+                        ]
+                    ]
+                )
+            thread = await mes.create_thread(
+                name=inter.get_field('short_description').value,
+                reason='Thread was created automatically as a result of creating a suggestion'
+            )
+            if image_urls:
+                await thread.send(
+                    embed=discord.Embed(
+                        title='Here are the other images provided in the suggestion',
+                        color=discord.Color.green()
+                    ))
+                await thread.send(
+                    '\n'.join([f'**`attachment-{index + 1}:`** {url[0]}' for index, url in enumerate(image_urls)]))
+
+    @commands.Cog.on_click(r'^suggestion:delete(:\d*)?$')
+    async def delete_suggestion(self, interaction: ComponentInteraction, button):
+        if interaction.author.id == int(
+                interaction.message.embeds[0].author.url.split('/')[-1]) or interaction.author.permissions_in(
+                interaction.channel).manage_messages:
+            before_embeds = interaction.message.embeds
+            before_components = interaction.message.components
+            if match := re.search(r'(?P<url_msg_id>[\d]+)', [c for c in interaction.message.all_buttons][0].custom_id):
+                url_msg = discord.PartialMessage(channel=interaction.channel, id=int(match.group('url_msg_id')))
+            else:
+                url_msg = None
+            msg = await interaction.edit(embed=discord.Embed(
+                title='⚠Warning: ❗This action is not reversible❗⚠',
+                description='Are you sure you want to delete this suggestion and the thread associated with it?'
+            ),
+                components=[
+                    [
+                        Button(label='Yes', custom_id='suggestion:delete-yes', style=ButtonStyle.red),
+                        Button(label='No', custom_id='suggestion:delete-cancel', style=ButtonStyle.red)
+                    ]]
+            )
+            try:
+                inter, but = await self.bot.wait_for(
+                    'raw_button_click',
+                    check=lambda i, b: i.author == interaction.author and i.message.id == msg.id,
+                    timeout=10
+                )
+            except asyncio.TimeoutError:
+                await msg.edit(embeds=before_embeds, components=before_components)
+            else:
+                if but.custom_id == 'suggestion:delete-yes':
+                    if interaction.message.thread:
+                        await interaction.message.thread.delete(
+                            reason=f'The associated suggestion for this thread was deleted by {interaction.author}.')
+                    await inter.edit(
+                        embed=discord.Embed(
+                            title='This message will be deleted in 3 Seconds.',
+                            color=discord.Color.green()),
+                        components=[],
+                        delete_after=4
+                    )
+                    if url_msg:
+                        await url_msg.delete(delay=4)
+                else:
+                    await inter.edit(embeds=before_embeds, components=before_components)
+
+    @commands.Cog.on_click(r'^suggestion:edit(:\d*)?$')
+    async def edit_suggestion(self, interaction: ComponentInteraction, button):
+        if interaction.author.id == int(
+                interaction.message.embeds[0].author.url.split('/')[-1]) or interaction.author.permissions_in(
+            interaction.channel).manage_messages:
+            embed = interaction.message.embeds[0]
+            old_short_description = embed.title
+            old_description = embed.description
+            url_msg = None
+            image_messages =  []
+            if re.search(r'(\[see video below])', old_description):
+                if match := re.search(r'(?P<url_msg_id>[\d]+)', [c for c in interaction.message.all_buttons][0].custom_id):
+                    url_msg = await discord.PartialMessage(channel=interaction.channel, id=int(match.group('url_msg_id'))).fetch()
+                    old_description = old_description.replace('[see video below]', url_msg.content)
+            if re.search(r'(\[see image below])', old_description):
+                old_description = old_description.replace('[see image below]', embed.image.url)
+            if attachments:= re.findall(r'\[attachment-\d{1,2}]', old_description):
+                thread = interaction.message.thread
+                image_messages = await thread.history(after=thread.starter_message, limit=3).flatten()
+                urls =  re.findall(r"(https://[^\s]+\.(jpeg|jpg|webp|png|gif|mp4|mov))", image_messages[-1].content)
+                for attachment, url in zip(attachments, urls):
+                    old_description = old_description.replace(attachment, url[0])
+            old_wy = embed.fields[-1] or discord.embeds.EmbedProxy({'value': ''})
+            suggest_modal = Modal(custom_id=f'suggestion:edit:{interaction.id}:{interaction.author.id}',
+                                  title='Update Suggestion.',
+                                  components=[TextInput(
+                                      custom_id='short_description',
+                                      label='Short description of your suggestion',
+                                      style=1,
+                                      min_length=10,
+                                      max_length=256,
+                                      placeholder='Implement new Modals',
+                                      value=old_short_description
+                                  ),
+                                      TextInput(
+                                          custom_id='description',
+                                          label='Description',
+                                          style=2,
+                                          min_length=20,
+                                          placeholder='Discord released -x- that should be implemented here.',
+                                          value=old_description.replace('```\n', '').replace('\n```', '')
+                                      ),
+                                      TextInput(
+                                          custom_id='wy',
+                                          label='Wy this feature should be changed/implemented',
+                                          style=2,
+                                          min_length=20,
+                                          max_length=1000,
+                                          required=False,
+                                          placeholder='With this new feature you can make -x-.',
+                                          value=old_wy.value.replace('```\n', '').replace('\n```', '')
+                                      )
+                                  ])
+            await interaction.respond_with_modal(modal=suggest_modal)
+            try:
+                inter: discord.ModalSubmitInteraction = await self.bot.wait_for(
+                    'modal_submit',
+                    check=lambda ms: ms.custom_id == f'suggestion:edit:{interaction.id}:{interaction.author.id}',
+                    timeout=5000
+                )
+            except asyncio.TimeoutError:
+                pass
+            else:
+                short_description, description, wy = list(map(lambda f: f.value, inter.fields))
+                if short_description == old_short_description and description == old_description and wy == old_wy.value:
+                    return await inter.respond('Nothing changed', hidden=True)
+
+                await inter.defer(hidden=True)
+                image_urls = re.findall(r"(https://[^\s]+\.(jpeg|jpg|webp|png|gif|mp4))", description)
+                attachments_changed = image_urls != re.findall(r"(https://[^\s]+\.(jpeg|jpg|webp|png|gif|mp4|mov))", old_description)
+                for index, url in enumerate(image_urls):
+                    if index == 0:
+                        description = description.replace(url[0],
+                                                          f'[see {"video" if url[0].endswith((".mp4", ".mov")) else "image"} below]')
+                    else:
+                        description = description.replace(url[0], f'[attachment-{index}]')
+
+                embed = discord.Embed(
+                    title=short_description,
+                    description=f"```\n{description}\n```"
+                )
+                if wy:
+                    embed.add_field(
+                        name='Wy should this be added/updated?',
+                        value=f'```\n{wy}\n```',
+                        inline=False
+                    )
+                embed.set_author(
+                    icon_url=inter.author.avatar_url,
+                    name=str(inter.author),
+                    url=f'https://discord.com/users/{inter.author.id}'
+                )
+                embed.set_footer(text='See the attachments in the thread below')
+                content = None
+                if image_urls:
+                    url = image_urls.pop(0)[0]
+                    if url.endswith(('.mp4', '.mov')):
+                        content = url
+                    else:
+                        embed.set_image(url=url)
+                await interaction.message.edit(embed=embed)
+                if attachments_changed:
+                    if content:
+                        method = url_msg.edit if url_msg else (inter.channel.send if (interaction.message.id == interaction.channel.last_message_id) else image_urls.insert(0, content))
+                        if method:
+                            new_url_msg = await method(content=content)
+                            if not url_msg:
+                                await interaction.message.edit(
+                                    components=[
+                                        [
+                                            Button(
+                                                label='delete suggestion',
+                                                custom_id=f'suggestion:delete:{new_url_msg.id}',
+                                                style=ButtonStyle.red,
+                                                emoji='🗑️'
+                                            ),
+                                            Button(
+                                                label='edit suggestion',
+                                                custom_id=f'suggestion:edit:{inter.author.id}',
+                                                style=ButtonStyle.grey,
+                                                emoji='↩'
+                                            )
+                                        ]
+                                    ]
+                                )
+                    else:
+                        if url_msg:
+                            await url_msg.delete()
+                            await interaction.message.edit(
+                                components=[
+                                    [
+                                        Button(
+                                            label='delete suggestion',
+                                            custom_id=f'suggestion:delete',
+                                            style=ButtonStyle.red,
+                                            emoji='🗑️'
+                                        ),
+                                        Button(
+                                            label='edit suggestion',
+                                            custom_id=f'suggestion:edit:{inter.author.id}',
+                                            style=ButtonStyle.grey,
+                                            emoji='↩'
+                                        )
+                                    ]
+                                ]
+                            )
+                    thread = inter.message.thread
+                    if not len(image_messages) <= 4 or not re.match(
+                        r"(\*\*`attachment-\d{1,2}:`\*\* https://[^\s]+\.(jpeg|jpg|webp|png|gif|mp4|mov)\n?)+",
+                        image_messages[-1].content
+                    ) or not image_messages[-1].author.id == inter.bot.user.id:
+                        image_messages = None
+                    if image_urls:
+                        method = image_messages[-1].edit if image_messages else (thread.send if thread.message_count <= 3 else None)
+                        if method is None:
+                            await thread.send(f"**These attachments have been added**\n" + '\n'.join([f'**`attachment-{index + 1}:`** {url[0]}' for index, url in enumerate(image_urls)]))
+                        else:
+                            if thread.message_count < 2:
+                                await thread.send(
+                                    embed=discord.Embed(
+                                        title='Here are the other images provided in the suggestion',
+                                        color=discord.Color.green()
+                                    ))
+                            await method(content='\n'.join([f'**`attachment-{index + 1}:`** {url[0]}' for index, url in enumerate(image_urls)]))
+                    else:
+                        if image_messages:
+                            for m in image_messages[1:]:
+                                await m.delete()
+                await inter.respond('Successful updated the suggestion', hidden=True)
+
+def setup(bot):
+    bot.add_cog(ModalSuggestions(bot))
diff --git a/examples/slash-commands/ban_command.py b/examples/slash-commands/ban_command.py
new file mode 100644
index 00000000..d4ca82db
--- /dev/null
+++ b/examples/slash-commands/ban_command.py
@@ -0,0 +1,42 @@
+import discord
+from discord import (
+    SlashCommandOption as Option,
+    ApplicationCommandInteraction as APPCI
+)
+from discord.ext import commands
+from typing import Optional
+
+
+class BanCommand(commands.Cog):
+    def __init__(self, bot):
+        self.bot: commands.Bot = bot
+
+    @commands.Cog.slash_command(
+        description='Ban a user',
+        options=[
+            Option(
+                name='user',
+                description='The user which should be banned',
+                option_type=discord.Member
+            ),
+            Option(
+                name='reason',
+                description='The reason why the user should be banned',
+                option_type=str,
+                required=False
+            )
+        ]
+    )
+    async def ban(self, ctx: APPCI, user: discord.Member, reason: Optional[str] = "No reason"):
+
+        await user.ban(reason=reason)
+
+        embed = discord.Embed(
+            title="User banned",
+            description=f"{user.mention} got banned for {reason}"
+        )
+        await ctx.respond(embed=embed)
+
+
+def setup(bot):
+    bot.add_cog(BanCommand(bot))
\ No newline at end of file
diff --git a/examples/slash-commands/clear_command.py b/examples/slash-commands/clear_command.py
new file mode 100644
index 00000000..a8444cee
--- /dev/null
+++ b/examples/slash-commands/clear_command.py
@@ -0,0 +1,163 @@
+import asyncio
+from datetime import datetime
+from typing import Optional, List
+
+import discord
+from discord import SlashCommandOption as Option, Localizations, Permissions, ApplicationCommandInteraction as APPCI
+from discord.ext import commands
+
+
+# The examples for using localizations are german in this case because it is my native language. Of curse you can add your native language too
+class ClearCommand(commands.Cog):
+    def __init__(self, bot):
+        self.bot = bot
+
+    @commands.Cog.slash_command(
+        name='clear',
+        description='Deletes the last x messages in the chat.',
+        description_localizations=Localizations(german='Löscht die letzten x Nachrichten im Chat.'),
+        default_required_permissions=Permissions(manage_messages=True),
+        options=[
+            Option(
+                option_type=int,
+                name='count',
+                description='The number (x) of messages that should be deleted.',
+                description_localizations=Localizations(german='Wie viele (x) Nachrichten gelöscht werden sollen.'),
+                max_value=100,
+                min_value=2
+            ),
+            Option(
+                option_type=discord.Member,
+                name='member',
+                description='The member which last x messages should be deleted.',
+                description_localizations=Localizations(
+                    german='Der Member dessen letzten x Nachrichten gelöscht werden sollen.'),
+                required=False
+            ),
+            Option(
+                option_type=str,
+                name='members',
+                description='Separated by a , the member which last x messages should be deleted. Separated by a ,',
+                description_localizations=Localizations(
+                    german='Per , getrennt, die Member deren letzten x Nachrichten gelöscht werden sollen.'),
+                required=False,
+                converter=commands.Greedy[discord.Member]
+            ),
+            Option(
+                option_type=str,
+                name='before',
+                name_localizations=Localizations(german='vor'),
+                description='If specified, the last x messages before this message are deleted.',
+                description_localizations=Localizations(
+                    german='Wenn angegeben werden die letzten x Nachrichten nach dieser Nachricht gelöscht.'
+                ),
+                required=False,
+                converter=commands.MessageConverter
+            ),
+            Option(
+                option_type=str,
+                name='after',
+                name_localizations=Localizations(german='nach'),
+                description='If specified, the last x messages after this message are deleted.',
+                description_localizations=Localizations(
+                    german='Wenn angegeben werden die letzten x Nachrichten vor dieser Nachricht gelöscht.'
+                ),
+                required=False,
+                converter=commands.MessageConverter
+            ),
+            Option(
+                option_type=str,
+                name='reason',
+                name_localizations=Localizations(german='grund'),
+                description='The reason for deleting message are deleted.',
+                description_localizations=Localizations(
+                    german='Der Grund warum die Nachrichten gelöscht werden.'
+                ),
+                required=False,
+            )
+
+        ],
+        guild_ids=[977326610334228502])
+    async def clear(self,
+                    ctx: APPCI,
+                    count: int,
+                    member: discord.Member = None,
+                    members: Optional[List[discord.Member]] = [],
+                    before: discord.Message = None,
+                    after: discord.Message = None,
+                    reason: str = None,
+                    around: discord.Message = None):
+        if not ctx.author.permissions_in(ctx.channel).manage_messages:
+            return
+        if members and len(members) == 1 and member == members[0]:
+            member = members[0]
+        question = await ctx.respond(
+            embed=discord.Embed(
+                title=f"deleting messages",
+                description=f'[{ctx.author.mention}]\n are you sure to delete the'
+                            f' last {count} messages {f"from {member.mention}" if member else (f"{len(members)} members" if members else "in this Channel")}?',
+                color=discord.Color.red()),
+            components=[
+                [
+                    discord.Button(
+                        label="Yes",
+                        emoji="✅",
+                        style=discord.ButtonColor.green,
+                        custom_id="Yes"
+                    ),
+                    discord.Button(
+                        label="No",
+                        emoji="❌",
+                        style=discord.ButtonColor.red,
+                        custom_id="No"
+                    )
+                ]
+            ]
+        )
+
+        def check(i: discord.ComponentInteraction, b: discord.Button):
+            return i.message.id == question.id and i.author.id == ctx.author.id
+
+        try:
+            i, b = await self.bot.wait_for("button_click", check=check, timeout=10)
+            await i.defer()
+            if b.custom_id == 'Yes':
+                await question.delete()
+
+                def check(m: discord.Message):
+                    if member:
+                        if m.author.id == member.id:
+                            return True
+                    else:
+                        if members:
+                            if m.author in members:
+                                return True
+                        else:
+                            return True
+
+                deleted = await ctx.channel.purge(limit=count, check=check, before=before, after=after,
+                                                  around=around)
+                deleted_from = []
+                for m in deleted:
+                    if m.author not in deleted_from:
+                        deleted_from.append(m.author)
+                m_count = len(deleted_from)
+                embed = discord.Embed(
+                    description=f'Deleted `{len(deleted)}` messages from {m_count} member{"s" if m_count > 1 else ""}| {discord.utils.styled_timestamp(datetime.now(), "R")}',
+                    color=discord.Color.green()
+                )
+                if reason:
+                    embed.add_field(name='Reason:', value=f'```\n{reason}\n```', inline=False)
+                embed.add_field(
+                    name='Deleted messages from:',
+                    value=', '.join([m.mention for m in deleted_from])
+                )
+                await i.channel.send(embed=embed)
+            else:
+                await question.delete()
+        except asyncio.TimeoutError:
+            await question.delete()
+
+
+def setup(bot):
+    bot.add_cog(ClearCommand(bot))
diff --git a/examples/slash-commands/help_command.py b/examples/slash-commands/help_command.py
new file mode 100644
index 00000000..f921560c
--- /dev/null
+++ b/examples/slash-commands/help_command.py
@@ -0,0 +1,112 @@
+from typing import (
+    Optional,
+    Union,
+    List
+)
+
+import discord
+from discord import (
+    SlashCommandOption as Option,
+    ApplicationCommandInteraction as APPCI
+)
+from discord.ext import commands
+
+
+class HelpCommand(commands.Cog):
+    def __init__(self, bot):
+        self.bot: commands.Bot = bot
+        self.latest_command_list = []
+
+    def fill_command_list(self) -> List[Union[discord.SlashCommand, discord.SubCommand]]:
+        self.latest_command_list = command_list = []
+        for cmd in self.bot.global_application_commands:
+            if isinstance(cmd, discord.SlashCommand):
+                if cmd.has_subcommands:
+                    for sub_cmd_or_group in cmd.sub_commands:
+                        if isinstance(sub_cmd_or_group, discord.SubCommandGroup):
+                            for sub_cmd in sub_cmd_or_group.sub_commands:
+                                command_list.append(sub_cmd)
+                        else:
+                            command_list.append(sub_cmd_or_group)
+                else:
+                    command_list.append(cmd)
+        return command_list
+
+    @commands.Cog.slash_command(
+        description='Shows you the help menu',
+        options=[
+            Option(
+                name='command',
+                description='The command to show extra information for',
+                option_type=str,
+                autocomplete=True,
+                required=False
+            )
+        ]
+    )
+    async def help(self, ctx: APPCI, command: Optional[str] = None):
+        if not self.latest_command_list:
+            self.fill_command_list()
+        if command is None:
+            description = ''
+            for cmd in self.latest_command_list:
+                description += f'{cmd.mention} - {cmd.description}\n'
+            embed = discord.Embed(
+                title=f'Help menu for {self.bot.user.name}',
+                description=description,
+                color=discord.Color.blurple()
+            )
+        else:
+            _command: Union[discord.SlashCommand, discord.SubCommand] = discord.utils.get(
+                self.latest_command_list,
+                qualified_name=command
+            )
+            if not _command:
+                return await ctx.respond(
+                    f'The command `{command}` is not a valid command. Please select one from the suggested ones',
+                    hidden=True
+                )
+            else:
+                command = _command
+            embed = discord.Embed(
+                title=f'Info for command {command.qualified_name}',
+                description=f'**Usage of {command.mention}:**\n{command.description}',
+                color=discord.Color.blurple()
+            )
+            if command.options:
+                embed.description += f'\n\n' \
+                                     f'**Usage:**\n' \
+                                     f'`<>` means the option is required, `[]` that it is optional\n\n' \
+                                     f'`/{command.qualified_name} '
+                for option in command.options:
+                    if option.required:
+                        embed.description += f'<{option.name}> '
+                    else:
+                        embed.description += f'[{option.name}] '
+                    embed.add_field(
+                        name=option.name + (' (optional)' if not option.required else ''),
+                        value=option.description,
+                        inline=False
+                    )
+                embed.description += '`'
+        await ctx.respond(embed=embed)
+
+    @help.autocomplete_callback
+    async def help_autocomplete(self, ctx: discord.AutocompleteInteraction, command: discord.option_str):
+        command_list = self.fill_command_list()
+        if not command:
+            await ctx.send_choices(
+                [
+                    discord.SlashCommandOptionChoice(name=cmd.qualified_name) for cmd in command_list[:25]
+                ]
+            )
+        else:
+            await ctx.send_choices(
+                [
+                    discord.SlashCommandOptionChoice(name=cmd.qualified_name) for cmd in command_list if command in cmd.qualified_name
+                ][:25]
+            )
+
+
+def setup(bot):
+    bot.add_cog(HelpCommand(bot))
diff --git a/images/Banner_Konturen.png b/images/Banner_Konturen.png
new file mode 100644
index 00000000..133c4e6d
Binary files /dev/null and b/images/Banner_Konturen.png differ
diff --git a/images/discord4py-logo.ico b/images/discord4py-logo.ico
new file mode 100644
index 00000000..d247ec05
Binary files /dev/null and b/images/discord4py-logo.ico differ
diff --git a/images/flag_ua.png b/images/flag_ua.png
new file mode 100644
index 00000000..b75d504b
Binary files /dev/null and b/images/flag_ua.png differ
diff --git a/pyproject.toml b/pyproject.toml
index f08df42c..17f16739 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -1,5 +1,6 @@
-requires = [
-    "setuptools>=42",
-    "wheel"
-]
+requires = [
+    "setuptools>=42",
+    "setuptools-scm==7.0.5",
+    "wheel",
+]
 build-backend = "setuptools.build_meta"
\ No newline at end of file
diff --git a/readthedocs.yaml b/readthedocs.yaml
index 64beb8f7..59af26c3 100644
--- a/readthedocs.yaml
+++ b/readthedocs.yaml
@@ -1,16 +1,17 @@
-# File: .readthedocs.yaml
-
-version: 2
-
-build:
-  os: ubuntu-22.04
-  tools:
-    python: "3.10"  
-    
-
-sphinx:
-  configuration: docs/conf.py
-
-python:
-  install:
-    - requirements: docs/requirements.txt
+# File: .readthedocs.yaml
+
+
+version: 2
+
+build:
+  os: ubuntu-22.04
+  tools:
+    python: "3.10"  
+    
+
+sphinx:
+  configuration: docs/conf.py
+
+python:
+  install:
+    - requirements: docs/requirements.txt
diff --git a/requirements.txt b/requirements.txt
index 34ccc5a6..47b03688 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1 +1,12 @@
-aiohttp>=3.9.2,<4
+aiohttp>=3.9.1,<4
+aiosignal
+typing-extensions
+importlib-metadata<4;python_version<"3.8.0"
+yarl
+chardet
+async-timeout
+attrs
+multidict
+idna
+color-pprint>=0.0.3
+colorama
\ No newline at end of file
diff --git a/setup.cfg b/setup.cfg
index 51749fcf..96fadd5c 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -1,3 +1,3 @@
-[egg_info]
-tag_build =
-tag_date = 0
+[egg_info]
+tag_build =
+tag_date = 0
diff --git a/setup.py b/setup.py
index 110b1a8d..51a2e3cb 100644
--- a/setup.py
+++ b/setup.py
@@ -1,95 +1,129 @@
-import os
-import re
-from pathlib import Path
-from setuptools import setup
-
-# The directory containing this file
-HERE = Path(__file__).parent
-
-version = ''
-with open(f'{HERE}/discord/__init__.py') as f:
-    version += re.search(r'^__version__\s*=\s*[\'"]([^\'"]*)[\'"]', f.read(), re.MULTILINE).group(1)
-
-v = None
-if os.path.isfile('version.txt'):
-    with open('version.txt', 'r') as fp:
-        v = fp.read()
-
-if version and not v:
-    i = input(f'are you sure to use version {version}>> ')
-    version = i if i else version
-    with open('version.txt', 'w') as fp:
-        fp.write(i)
-
-if not (version or v):
-    version = input('please set an version>> ')
-    if not version:
-        raise RuntimeError('version is not set')
-
-if version.endswith(('a', 'b', 'rc')):
-    # append version identifier based on commit count
-    try:
-        import subprocess
-        p = subprocess.Popen(['git', 'rev-list', '--count', 'HEAD'],
-                             stdout=subprocess.PIPE, stderr=subprocess.PIPE)
-        out, err = p.communicate()
-        if out:
-            version += out.decode('utf-8').strip()
-        p = subprocess.Popen(['git', 'rev-parse', '--short', 'HEAD'],
-                             stdout=subprocess.PIPE, stderr=subprocess.PIPE)
-        out, err = p.communicate()
-        if out:
-            version += '+g' + out.decode('utf-8').strip()
-    except Exception as exc:
-        pass
-
-
-# The text of the README file
-
-readme = Path('./README.rst').read_text(encoding='utf-8')
-
-#
-extras_require = {
-    'voice': ['PyNaCl>=1.3.0,<1.5'],
-    'docs': [
-        'sphinx==3.0.3',
-        'sphinxcontrib_trio==1.1.2',
-        'sphinxcontrib-websupport',
-    ]
-}
-
-# This call to setup() does all the work
-setup(
-    name="discord.py-message-components",
-    url="https://github.com/mccoderpy/discord.py-message-components",
-    project_urls={'Documentation': 'https://discordpy-message-components.readthedocs.io/en/latest/', 'Source': 'https://github.com/mccoderpy/discord.py-message-components/', 'Support': 'https://discord.gg/sb69muSqsg', 'Issue Tracker': 'https://github.com/mccoderpy/discord.py-message-components/issues'},
-    author_email="mccuber04@outlook.de",
-    version=str(v if v else version),
-    author="mccoder.py",
-    description="The discord.py Library with implementation of the Discord-Message-Components",
-    keywords='discord.py discord.py-message-components discord-components discord-interactions discord message-components',
-    long_description=readme,
-    long_description_content_type="text/x-rst",
-    extras_require=extras_require,
-    license="MIT",
-    classifiers=[
-        'Development Status :: 4 - Beta',
-        'License :: OSI Approved :: MIT License',
-        'Intended Audience :: Developers',
-        'Natural Language :: English',
-        'Operating System :: OS Independent',
-        'Programming Language :: Python :: 3.5',
-        'Programming Language :: Python :: 3.6',
-        'Programming Language :: Python :: 3.7',
-        'Programming Language :: Python :: 3.8',
-        'Programming Language :: Python :: 3.9',
-        'Topic :: Internet',
-        'Topic :: Software Development :: Libraries',
-        'Topic :: Software Development :: Libraries :: Python Modules',
-        'Topic :: Utilities'
-    ],
-    packages=['discord', 'discord.ext.commands', 'discord.ext.tasks'],
-    include_package_data=True,
-    install_requires=["aiohttp", "chardet", "yarl", "async-timeout", "typing-extensions", "attrs", "multidict", "idna"],
-    python_requires=">=3.6"
-)
+import os
+import re
+from pathlib import Path
+from setuptools import setup
+
+# The directory containing this file
+HERE = Path(__file__).parent
+
+version = ''
+with open(f'{HERE}/discord/__init__.py') as f:
+    version += re.search(r'^__version__\s*=\s*[\'"]([^\'"]*)[\'"]', f.read(), re.MULTILINE).group(1)
+
+v = None
+if os.path.isfile('version.txt'):
+    with open(f'{HERE}/version.txt', 'r') as fp:
+        v = fp.read()
+
+if version != v:
+    try:
+        i = input(f'are you sure to use version {version}>> ')
+    except EOFError:
+        pass
+    else:
+        version = i if i else version
+        with open('version.txt', 'w') as fp:
+            fp.write(i)
+
+if not (version or v):
+    try:
+        version = input('please set a version>> ')
+    except EOFError:
+        pass
+    if not version:
+        raise RuntimeError('version is not set')
+
+if version.endswith(('a', 'b', 'rc', 'dev')):
+    # append version identifier based on commit count
+    try:
+        import subprocess
+        p = subprocess.Popen(['git', 'rev-list', '--count', 'HEAD'],
+                             stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+        out, err = p.communicate()
+        if out:
+            version += out.decode('utf-8').strip()
+        p = subprocess.Popen(['git', 'rev-parse', '--short', 'HEAD'],
+                             stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+        out, err = p.communicate()
+        if out:
+            version += f'+g{out.decode("utf-8").strip()}'
+    except Exception:
+        __import__('traceback').print_exc()
+    else:
+        with open(f'{HERE}/version.txt', 'w') as fp:
+            fp.write(version)
+
+
+# The text of the README file
+readme = Path('./README.rst').read_text(encoding='utf-8')
+
+#
+extras_require = {
+    'voice': ['PyNaCl>=1.3.0,<1.6'],
+    'docs': [
+        'sphinx==3.0.3',
+        'sphinxcontrib_trio==1.1.2',
+        'sphinxcontrib-websupport',
+        'typing-extensions>=4.3,<5',
+        'sphinx_inline_tabs',
+        'sphinx-autobuild'
+    ],
+    'speedups': [
+        'aiohttp[speedups]'
+    ]
+}
+
+# This call to setup() does all the work
+setup(
+    name="discord.py-message-components",
+    url="https://github.com/mccoderpy/discord.py-message-components",
+    project_urls={
+        'Documentation': 'https://discordpy-message-components.readthedocs.io/en/latest/',
+        'Source': 'https://github.com/mccoderpy/discord.py-message-components/',
+        'Support': 'https://discord.gg/sb69muSqsg',
+        'Issue Tracker': 'https://github.com/mccoderpy/discord.py-message-components/issues'
+    },
+    author_email="mccuber04@outlook.de",
+    version=str(version),
+    author="mccoder.py",
+    description="A \"fork\" of discord.py library made by Rapptz with implementation of the Discord-Message-Components & other features by mccoderpy",
+    keywords='discord discord4py discord.py discord.py-message-components discord-components discord-interactions  message-components components ',
+    long_description=readme,
+    long_description_content_type="text/x-rst",
+    extras_require=extras_require,
+    license="MIT",
+    classifiers=[
+        'Development Status :: 4 - Beta',
+        'License :: OSI Approved :: MIT License',
+        'Intended Audience :: Developers',
+        'Natural Language :: English',
+        'Operating System :: OS Independent',
+        'Programming Language :: Python :: 3.8',
+        'Programming Language :: Python :: 3.9',
+        'Programming Language :: Python :: 3.10',
+        'Programming Language :: Python :: 3.11',
+        'Topic :: Internet',
+        'Framework :: aiohttp',
+        'Framework :: asyncio',
+        'Topic :: Software Development :: Libraries',
+        'Topic :: Software Development :: Libraries :: Python Modules',
+        'Topic :: Utilities'
+    ],
+    packages=['discord', 'discord.types', 'discord.bin', 'discord.oauth2', 'discord.ext.commands', 'discord.ext.tasks'],
+    include_package_data=True,
+    install_requires=[
+        "aiohttp",
+        "chardet",
+        "yarl",
+        'aiosignal',
+        "async-timeout",
+        "typing-extensions",
+        "attrs",
+        "multidict",
+        "idna",
+        'importlib-metadata<4;python_version<"3.8.0"',
+        'colorama',
+        'color-pprint'
+    ],
+    python_requires=">=3.8"
+)
diff --git a/version.txt b/version.txt
index 28811714..e2861cd4 100644
--- a/version.txt
+++ b/version.txt
@@ -1 +1 @@
-1.7.5.4
+2.0a
\ No newline at end of file
