We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
make !otn accept uppercase and punctuation
There are weird unicode alternatives for stuff like capital letters and punctuation that will get through the discord "only lowercase and dashes" filters.

When someone uses `!otn a` and tries to add a name with an apostrophe, we currently are transforming those into something that the system will accept. Let's do the same for exclamation points, question marks, and uppercase letters!

* For exclamation points, use ǃ
* For questionmarks, use ？
* For uppercase, use 𝖠𝖡𝖢𝖣𝖤𝖥𝖦𝖧𝖨𝖩𝖪𝖫𝖬𝖭𝖮𝖯𝖰𝖱𝖲𝖳𝖴𝖵𝖶𝖷𝖸𝖹

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `bot/cogs/off_topic_names.py`
Content:
```
1 import asyncio
2 import logging
3 from datetime import datetime, timedelta
4 
5 from discord import Colour, Embed
6 from discord.ext.commands import BadArgument, Bot, Context, Converter, group
7 
8 from bot.constants import Channels, Keys, MODERATION_ROLES, URLs
9 from bot.decorators import with_role
10 from bot.pagination import LinePaginator
11 
12 
13 CHANNELS = (Channels.off_topic_0, Channels.off_topic_1, Channels.off_topic_2)
14 log = logging.getLogger(__name__)
15 
16 
17 class OffTopicName(Converter):
18     """A converter that ensures an added off-topic name is valid."""
19 
20     @staticmethod
21     async def convert(ctx: Context, argument: str):
22         allowed_characters = ("-", "’", "'", "`")
23 
24         if not (2 <= len(argument) <= 96):
25             raise BadArgument("Channel name must be between 2 and 96 chars long")
26 
27         elif not all(c.isalnum() or c in allowed_characters for c in argument):
28             raise BadArgument(
29                 "Channel name must only consist of "
30                 "alphanumeric characters, minus signs or apostrophes."
31             )
32 
33         elif not argument.islower():
34             raise BadArgument("Channel name must be lowercase")
35 
36         # Replace some unusable apostrophe-like characters with "’".
37         return argument.replace("'", "’").replace("`", "’")
38 
39 
40 async def update_names(bot: Bot, headers: dict):
41     """
42     The background updater task that performs a channel name update daily.
43 
44     Args:
45         bot (Bot):
46             The running bot instance, used for fetching data from the
47             website via the bot's `http_session`.
48     """
49 
50     while True:
51         # Since we truncate the compute timedelta to seconds, we add one second to ensure
52         # we go past midnight in the `seconds_to_sleep` set below.
53         today_at_midnight = datetime.utcnow().replace(microsecond=0, second=0, minute=0, hour=0)
54         next_midnight = today_at_midnight + timedelta(days=1)
55         seconds_to_sleep = (next_midnight - datetime.utcnow()).seconds + 1
56         await asyncio.sleep(seconds_to_sleep)
57 
58         response = await bot.http_session.get(
59             f'{URLs.site_off_topic_names_api}?random_items=3',
60             headers=headers
61         )
62         channel_0_name, channel_1_name, channel_2_name = await response.json()
63         channel_0, channel_1, channel_2 = (bot.get_channel(channel_id) for channel_id in CHANNELS)
64 
65         await channel_0.edit(name=f'ot0-{channel_0_name}')
66         await channel_1.edit(name=f'ot1-{channel_1_name}')
67         await channel_2.edit(name=f'ot2-{channel_2_name}')
68         log.debug(
69             "Updated off-topic channel names to"
70             f" {channel_0_name}, {channel_1_name} and {channel_2_name}"
71         )
72 
73 
74 class OffTopicNames:
75     """Commands related to managing the off-topic category channel names."""
76 
77     def __init__(self, bot: Bot):
78         self.bot = bot
79         self.headers = {"X-API-KEY": Keys.site_api}
80         self.updater_task = None
81 
82     def __cleanup(self):
83         if self.updater_task is not None:
84             self.updater_task.cancel()
85 
86     async def on_ready(self):
87         if self.updater_task is None:
88             coro = update_names(self.bot, self.headers)
89             self.updater_task = self.bot.loop.create_task(coro)
90 
91     @group(name='otname', aliases=('otnames', 'otn'), invoke_without_command=True)
92     @with_role(*MODERATION_ROLES)
93     async def otname_group(self, ctx):
94         """Add or list items from the off-topic channel name rotation."""
95 
96         await ctx.invoke(self.bot.get_command("help"), "otname")
97 
98     @otname_group.command(name='add', aliases=('a',))
99     @with_role(*MODERATION_ROLES)
100     async def add_command(self, ctx, name: OffTopicName):
101         """Adds a new off-topic name to the rotation."""
102 
103         result = await self.bot.http_session.post(
104             URLs.site_off_topic_names_api,
105             headers=self.headers,
106             params={'name': name}
107         )
108 
109         response = await result.json()
110 
111         if result.status == 200:
112             log.info(
113                 f"{ctx.author.name}#{ctx.author.discriminator}"
114                 f" added the off-topic channel name '{name}"
115             )
116             await ctx.send(":ok_hand:")
117         else:
118             error_reason = response.get('message', "No reason provided.")
119             await ctx.send(f":warning: got non-200 from the API: {error_reason}")
120 
121     @otname_group.command(name='delete', aliases=('remove', 'rm', 'del', 'd'))
122     @with_role(*MODERATION_ROLES)
123     async def delete_command(self, ctx, name: OffTopicName):
124         """Removes a off-topic name from the rotation."""
125 
126         result = await self.bot.http_session.delete(
127             URLs.site_off_topic_names_api,
128             headers=self.headers,
129             params={'name': name}
130         )
131 
132         response = await result.json()
133 
134         if result.status == 200:
135             if response['deleted'] == 0:
136                 await ctx.send(f":warning: No name matching `{name}` was found in the database.")
137             else:
138                 log.info(
139                     f"{ctx.author.name}#{ctx.author.discriminator}"
140                     f" deleted the off-topic channel name '{name}"
141                 )
142                 await ctx.send(":ok_hand:")
143         else:
144             error_reason = response.get('message', "No reason provided.")
145             await ctx.send(f":warning: got non-200 from the API: {error_reason}")
146 
147     @otname_group.command(name='list', aliases=('l',))
148     @with_role(*MODERATION_ROLES)
149     async def list_command(self, ctx):
150         """
151         Lists all currently known off-topic channel names in a paginator.
152         Restricted to Moderator and above to not spoil the surprise.
153         """
154 
155         result = await self.bot.http_session.get(
156             URLs.site_off_topic_names_api,
157             headers=self.headers
158         )
159         response = await result.json()
160         lines = sorted(f"• {name}" for name in response)
161 
162         embed = Embed(
163             title=f"Known off-topic names (`{len(response)}` total)",
164             colour=Colour.blue()
165         )
166         await LinePaginator.paginate(lines, ctx, embed, max_size=400, empty=False)
167 
168 
169 def setup(bot: Bot):
170     bot.add_cog(OffTopicNames(bot))
171     log.info("Cog loaded: OffTopicNames")
172
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/bot/cogs/off_topic_names.py b/bot/cogs/off_topic_names.py
--- a/bot/cogs/off_topic_names.py
+++ b/bot/cogs/off_topic_names.py
@@ -19,7 +19,7 @@
 
     @staticmethod
     async def convert(ctx: Context, argument: str):
-        allowed_characters = ("-", "’", "'", "`")
+        allowed_characters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ!?'`"
 
         if not (2 <= len(argument) <= 96):
             raise BadArgument("Channel name must be between 2 and 96 chars long")
@@ -30,11 +30,11 @@
                 "alphanumeric characters, minus signs or apostrophes."
             )
 
-        elif not argument.islower():
-            raise BadArgument("Channel name must be lowercase")
-
-        # Replace some unusable apostrophe-like characters with "’".
-        return argument.replace("'", "’").replace("`", "’")
+        # Replace invalid characters with unicode alternatives.
+        table = str.maketrans(
+            allowed_characters, '𝖠𝖡𝖢𝖣𝖤𝖥𝖦𝖧𝖨𝖩𝖪𝖫𝖬𝖭𝖮𝖯𝖰𝖱𝖲𝖳𝖴𝖵𝖶𝖷𝖸𝖹ǃ？’’'
+        )
+        return argument.translate(table)
 
 
 async def update_names(bot: Bot, headers: dict):

{"golden_diff": "diff --git a/bot/cogs/off_topic_names.py b/bot/cogs/off_topic_names.py\n--- a/bot/cogs/off_topic_names.py\n+++ b/bot/cogs/off_topic_names.py\n@@ -19,7 +19,7 @@\n \n     @staticmethod\n     async def convert(ctx: Context, argument: str):\n-        allowed_characters = (\"-\", \"\u2019\", \"'\", \"`\")\n+        allowed_characters = \"ABCDEFGHIJKLMNOPQRSTUVWXYZ!?'`\"\n \n         if not (2 <= len(argument) <= 96):\n             raise BadArgument(\"Channel name must be between 2 and 96 chars long\")\n@@ -30,11 +30,11 @@\n                 \"alphanumeric characters, minus signs or apostrophes.\"\n             )\n \n-        elif not argument.islower():\n-            raise BadArgument(\"Channel name must be lowercase\")\n-\n-        # Replace some unusable apostrophe-like characters with \"\u2019\".\n-        return argument.replace(\"'\", \"\u2019\").replace(\"`\", \"\u2019\")\n+        # Replace invalid characters with unicode alternatives.\n+        table = str.maketrans(\n+            allowed_characters, '\ud835\udda0\ud835\udda1\ud835\udda2\ud835\udda3\ud835\udda4\ud835\udda5\ud835\udda6\ud835\udda7\ud835\udda8\ud835\udda9\ud835\uddaa\ud835\uddab\ud835\uddac\ud835\uddad\ud835\uddae\ud835\uddaf\ud835\uddb0\ud835\uddb1\ud835\uddb2\ud835\uddb3\ud835\uddb4\ud835\uddb5\ud835\uddb6\ud835\uddb7\ud835\uddb8\ud835\uddb9\u01c3\uff1f\u2019\u2019'\n+        )\n+        return argument.translate(table)\n \n \n async def update_names(bot: Bot, headers: dict):\n", "issue": "make !otn accept uppercase and punctuation\nThere are weird unicode alternatives for stuff like capital letters and punctuation that will get through the discord \"only lowercase and dashes\" filters.\r\n\r\nWhen someone uses `!otn a` and tries to add a name with an apostrophe, we currently are transforming those into something that the system will accept. Let's do the same for exclamation points, question marks, and uppercase letters!\r\n\r\n* For exclamation points, use \u01c3\r\n* For questionmarks, use \uff1f\r\n* For uppercase, use \ud835\udda0\ud835\udda1\ud835\udda2\ud835\udda3\ud835\udda4\ud835\udda5\ud835\udda6\ud835\udda7\ud835\udda8\ud835\udda9\ud835\uddaa\ud835\uddab\ud835\uddac\ud835\uddad\ud835\uddae\ud835\uddaf\ud835\uddb0\ud835\uddb1\ud835\uddb2\ud835\uddb3\ud835\uddb4\ud835\uddb5\ud835\uddb6\ud835\uddb7\ud835\uddb8\ud835\uddb9\n", "before_files": [{"content": "import asyncio\nimport logging\nfrom datetime import datetime, timedelta\n\nfrom discord import Colour, Embed\nfrom discord.ext.commands import BadArgument, Bot, Context, Converter, group\n\nfrom bot.constants import Channels, Keys, MODERATION_ROLES, URLs\nfrom bot.decorators import with_role\nfrom bot.pagination import LinePaginator\n\n\nCHANNELS = (Channels.off_topic_0, Channels.off_topic_1, Channels.off_topic_2)\nlog = logging.getLogger(__name__)\n\n\nclass OffTopicName(Converter):\n    \"\"\"A converter that ensures an added off-topic name is valid.\"\"\"\n\n    @staticmethod\n    async def convert(ctx: Context, argument: str):\n        allowed_characters = (\"-\", \"\u2019\", \"'\", \"`\")\n\n        if not (2 <= len(argument) <= 96):\n            raise BadArgument(\"Channel name must be between 2 and 96 chars long\")\n\n        elif not all(c.isalnum() or c in allowed_characters for c in argument):\n            raise BadArgument(\n                \"Channel name must only consist of \"\n                \"alphanumeric characters, minus signs or apostrophes.\"\n            )\n\n        elif not argument.islower():\n            raise BadArgument(\"Channel name must be lowercase\")\n\n        # Replace some unusable apostrophe-like characters with \"\u2019\".\n        return argument.replace(\"'\", \"\u2019\").replace(\"`\", \"\u2019\")\n\n\nasync def update_names(bot: Bot, headers: dict):\n    \"\"\"\n    The background updater task that performs a channel name update daily.\n\n    Args:\n        bot (Bot):\n            The running bot instance, used for fetching data from the\n            website via the bot's `http_session`.\n    \"\"\"\n\n    while True:\n        # Since we truncate the compute timedelta to seconds, we add one second to ensure\n        # we go past midnight in the `seconds_to_sleep` set below.\n        today_at_midnight = datetime.utcnow().replace(microsecond=0, second=0, minute=0, hour=0)\n        next_midnight = today_at_midnight + timedelta(days=1)\n        seconds_to_sleep = (next_midnight - datetime.utcnow()).seconds + 1\n        await asyncio.sleep(seconds_to_sleep)\n\n        response = await bot.http_session.get(\n            f'{URLs.site_off_topic_names_api}?random_items=3',\n            headers=headers\n        )\n        channel_0_name, channel_1_name, channel_2_name = await response.json()\n        channel_0, channel_1, channel_2 = (bot.get_channel(channel_id) for channel_id in CHANNELS)\n\n        await channel_0.edit(name=f'ot0-{channel_0_name}')\n        await channel_1.edit(name=f'ot1-{channel_1_name}')\n        await channel_2.edit(name=f'ot2-{channel_2_name}')\n        log.debug(\n            \"Updated off-topic channel names to\"\n            f\" {channel_0_name}, {channel_1_name} and {channel_2_name}\"\n        )\n\n\nclass OffTopicNames:\n    \"\"\"Commands related to managing the off-topic category channel names.\"\"\"\n\n    def __init__(self, bot: Bot):\n        self.bot = bot\n        self.headers = {\"X-API-KEY\": Keys.site_api}\n        self.updater_task = None\n\n    def __cleanup(self):\n        if self.updater_task is not None:\n            self.updater_task.cancel()\n\n    async def on_ready(self):\n        if self.updater_task is None:\n            coro = update_names(self.bot, self.headers)\n            self.updater_task = self.bot.loop.create_task(coro)\n\n    @group(name='otname', aliases=('otnames', 'otn'), invoke_without_command=True)\n    @with_role(*MODERATION_ROLES)\n    async def otname_group(self, ctx):\n        \"\"\"Add or list items from the off-topic channel name rotation.\"\"\"\n\n        await ctx.invoke(self.bot.get_command(\"help\"), \"otname\")\n\n    @otname_group.command(name='add', aliases=('a',))\n    @with_role(*MODERATION_ROLES)\n    async def add_command(self, ctx, name: OffTopicName):\n        \"\"\"Adds a new off-topic name to the rotation.\"\"\"\n\n        result = await self.bot.http_session.post(\n            URLs.site_off_topic_names_api,\n            headers=self.headers,\n            params={'name': name}\n        )\n\n        response = await result.json()\n\n        if result.status == 200:\n            log.info(\n                f\"{ctx.author.name}#{ctx.author.discriminator}\"\n                f\" added the off-topic channel name '{name}\"\n            )\n            await ctx.send(\":ok_hand:\")\n        else:\n            error_reason = response.get('message', \"No reason provided.\")\n            await ctx.send(f\":warning: got non-200 from the API: {error_reason}\")\n\n    @otname_group.command(name='delete', aliases=('remove', 'rm', 'del', 'd'))\n    @with_role(*MODERATION_ROLES)\n    async def delete_command(self, ctx, name: OffTopicName):\n        \"\"\"Removes a off-topic name from the rotation.\"\"\"\n\n        result = await self.bot.http_session.delete(\n            URLs.site_off_topic_names_api,\n            headers=self.headers,\n            params={'name': name}\n        )\n\n        response = await result.json()\n\n        if result.status == 200:\n            if response['deleted'] == 0:\n                await ctx.send(f\":warning: No name matching `{name}` was found in the database.\")\n            else:\n                log.info(\n                    f\"{ctx.author.name}#{ctx.author.discriminator}\"\n                    f\" deleted the off-topic channel name '{name}\"\n                )\n                await ctx.send(\":ok_hand:\")\n        else:\n            error_reason = response.get('message', \"No reason provided.\")\n            await ctx.send(f\":warning: got non-200 from the API: {error_reason}\")\n\n    @otname_group.command(name='list', aliases=('l',))\n    @with_role(*MODERATION_ROLES)\n    async def list_command(self, ctx):\n        \"\"\"\n        Lists all currently known off-topic channel names in a paginator.\n        Restricted to Moderator and above to not spoil the surprise.\n        \"\"\"\n\n        result = await self.bot.http_session.get(\n            URLs.site_off_topic_names_api,\n            headers=self.headers\n        )\n        response = await result.json()\n        lines = sorted(f\"\u2022 {name}\" for name in response)\n\n        embed = Embed(\n            title=f\"Known off-topic names (`{len(response)}` total)\",\n            colour=Colour.blue()\n        )\n        await LinePaginator.paginate(lines, ctx, embed, max_size=400, empty=False)\n\n\ndef setup(bot: Bot):\n    bot.add_cog(OffTopicNames(bot))\n    log.info(\"Cog loaded: OffTopicNames\")\n", "path": "bot/cogs/off_topic_names.py"}], "after_files": [{"content": "import asyncio\nimport logging\nfrom datetime import datetime, timedelta\n\nfrom discord import Colour, Embed\nfrom discord.ext.commands import BadArgument, Bot, Context, Converter, group\n\nfrom bot.constants import Channels, Keys, MODERATION_ROLES, URLs\nfrom bot.decorators import with_role\nfrom bot.pagination import LinePaginator\n\n\nCHANNELS = (Channels.off_topic_0, Channels.off_topic_1, Channels.off_topic_2)\nlog = logging.getLogger(__name__)\n\n\nclass OffTopicName(Converter):\n    \"\"\"A converter that ensures an added off-topic name is valid.\"\"\"\n\n    @staticmethod\n    async def convert(ctx: Context, argument: str):\n        allowed_characters = \"ABCDEFGHIJKLMNOPQRSTUVWXYZ!?'`\"\n\n        if not (2 <= len(argument) <= 96):\n            raise BadArgument(\"Channel name must be between 2 and 96 chars long\")\n\n        elif not all(c.isalnum() or c in allowed_characters for c in argument):\n            raise BadArgument(\n                \"Channel name must only consist of \"\n                \"alphanumeric characters, minus signs or apostrophes.\"\n            )\n\n        # Replace invalid characters with unicode alternatives.\n        table = str.maketrans(\n            allowed_characters, '\ud835\udda0\ud835\udda1\ud835\udda2\ud835\udda3\ud835\udda4\ud835\udda5\ud835\udda6\ud835\udda7\ud835\udda8\ud835\udda9\ud835\uddaa\ud835\uddab\ud835\uddac\ud835\uddad\ud835\uddae\ud835\uddaf\ud835\uddb0\ud835\uddb1\ud835\uddb2\ud835\uddb3\ud835\uddb4\ud835\uddb5\ud835\uddb6\ud835\uddb7\ud835\uddb8\ud835\uddb9\u01c3\uff1f\u2019\u2019'\n        )\n        return argument.translate(table)\n\n\nasync def update_names(bot: Bot, headers: dict):\n    \"\"\"\n    The background updater task that performs a channel name update daily.\n\n    Args:\n        bot (Bot):\n            The running bot instance, used for fetching data from the\n            website via the bot's `http_session`.\n    \"\"\"\n\n    while True:\n        # Since we truncate the compute timedelta to seconds, we add one second to ensure\n        # we go past midnight in the `seconds_to_sleep` set below.\n        today_at_midnight = datetime.utcnow().replace(microsecond=0, second=0, minute=0, hour=0)\n        next_midnight = today_at_midnight + timedelta(days=1)\n        seconds_to_sleep = (next_midnight - datetime.utcnow()).seconds + 1\n        await asyncio.sleep(seconds_to_sleep)\n\n        response = await bot.http_session.get(\n            f'{URLs.site_off_topic_names_api}?random_items=3',\n            headers=headers\n        )\n        channel_0_name, channel_1_name, channel_2_name = await response.json()\n        channel_0, channel_1, channel_2 = (bot.get_channel(channel_id) for channel_id in CHANNELS)\n\n        await channel_0.edit(name=f'ot0-{channel_0_name}')\n        await channel_1.edit(name=f'ot1-{channel_1_name}')\n        await channel_2.edit(name=f'ot2-{channel_2_name}')\n        log.debug(\n            \"Updated off-topic channel names to\"\n            f\" {channel_0_name}, {channel_1_name} and {channel_2_name}\"\n        )\n\n\nclass OffTopicNames:\n    \"\"\"Commands related to managing the off-topic category channel names.\"\"\"\n\n    def __init__(self, bot: Bot):\n        self.bot = bot\n        self.headers = {\"X-API-KEY\": Keys.site_api}\n        self.updater_task = None\n\n    def __cleanup(self):\n        if self.updater_task is not None:\n            self.updater_task.cancel()\n\n    async def on_ready(self):\n        if self.updater_task is None:\n            coro = update_names(self.bot, self.headers)\n            self.updater_task = self.bot.loop.create_task(coro)\n\n    @group(name='otname', aliases=('otnames', 'otn'), invoke_without_command=True)\n    @with_role(*MODERATION_ROLES)\n    async def otname_group(self, ctx):\n        \"\"\"Add or list items from the off-topic channel name rotation.\"\"\"\n\n        await ctx.invoke(self.bot.get_command(\"help\"), \"otname\")\n\n    @otname_group.command(name='add', aliases=('a',))\n    @with_role(*MODERATION_ROLES)\n    async def add_command(self, ctx, name: OffTopicName):\n        \"\"\"Adds a new off-topic name to the rotation.\"\"\"\n\n        result = await self.bot.http_session.post(\n            URLs.site_off_topic_names_api,\n            headers=self.headers,\n            params={'name': name}\n        )\n\n        response = await result.json()\n\n        if result.status == 200:\n            log.info(\n                f\"{ctx.author.name}#{ctx.author.discriminator}\"\n                f\" added the off-topic channel name '{name}\"\n            )\n            await ctx.send(\":ok_hand:\")\n        else:\n            error_reason = response.get('message', \"No reason provided.\")\n            await ctx.send(f\":warning: got non-200 from the API: {error_reason}\")\n\n    @otname_group.command(name='delete', aliases=('remove', 'rm', 'del', 'd'))\n    @with_role(*MODERATION_ROLES)\n    async def delete_command(self, ctx, name: OffTopicName):\n        \"\"\"Removes a off-topic name from the rotation.\"\"\"\n\n        result = await self.bot.http_session.delete(\n            URLs.site_off_topic_names_api,\n            headers=self.headers,\n            params={'name': name}\n        )\n\n        response = await result.json()\n\n        if result.status == 200:\n            if response['deleted'] == 0:\n                await ctx.send(f\":warning: No name matching `{name}` was found in the database.\")\n            else:\n                log.info(\n                    f\"{ctx.author.name}#{ctx.author.discriminator}\"\n                    f\" deleted the off-topic channel name '{name}\"\n                )\n                await ctx.send(\":ok_hand:\")\n        else:\n            error_reason = response.get('message', \"No reason provided.\")\n            await ctx.send(f\":warning: got non-200 from the API: {error_reason}\")\n\n    @otname_group.command(name='list', aliases=('l',))\n    @with_role(*MODERATION_ROLES)\n    async def list_command(self, ctx):\n        \"\"\"\n        Lists all currently known off-topic channel names in a paginator.\n        Restricted to Moderator and above to not spoil the surprise.\n        \"\"\"\n\n        result = await self.bot.http_session.get(\n            URLs.site_off_topic_names_api,\n            headers=self.headers\n        )\n        response = await result.json()\n        lines = sorted(f\"\u2022 {name}\" for name in response)\n\n        embed = Embed(\n            title=f\"Known off-topic names (`{len(response)}` total)\",\n            colour=Colour.blue()\n        )\n        await LinePaginator.paginate(lines, ctx, embed, max_size=400, empty=False)\n\n\ndef setup(bot: Bot):\n    bot.add_cog(OffTopicNames(bot))\n    log.info(\"Cog loaded: OffTopicNames\")\n", "path": "bot/cogs/off_topic_names.py"}]}