summaryrefslogtreecommitdiff
path: root/node_modules/discord.js/src/managers
diff options
context:
space:
mode:
Diffstat (limited to 'node_modules/discord.js/src/managers')
-rw-r--r--node_modules/discord.js/src/managers/ApplicationCommandManager.js263
-rw-r--r--node_modules/discord.js/src/managers/ApplicationCommandPermissionsManager.js434
-rw-r--r--node_modules/discord.js/src/managers/AutoModerationRuleManager.js288
-rw-r--r--node_modules/discord.js/src/managers/BaseGuildEmojiManager.js80
-rw-r--r--node_modules/discord.js/src/managers/BaseManager.js19
-rw-r--r--node_modules/discord.js/src/managers/CachedManager.js64
-rw-r--r--node_modules/discord.js/src/managers/CategoryChannelChildManager.js77
-rw-r--r--node_modules/discord.js/src/managers/ChannelManager.js128
-rw-r--r--node_modules/discord.js/src/managers/DMMessageManager.js17
-rw-r--r--node_modules/discord.js/src/managers/DataManager.js61
-rw-r--r--node_modules/discord.js/src/managers/GuildApplicationCommandManager.js28
-rw-r--r--node_modules/discord.js/src/managers/GuildBanManager.js204
-rw-r--r--node_modules/discord.js/src/managers/GuildChannelManager.js503
-rw-r--r--node_modules/discord.js/src/managers/GuildEmojiManager.js174
-rw-r--r--node_modules/discord.js/src/managers/GuildEmojiRoleManager.js118
-rw-r--r--node_modules/discord.js/src/managers/GuildForumThreadManager.js83
-rw-r--r--node_modules/discord.js/src/managers/GuildInviteManager.js214
-rw-r--r--node_modules/discord.js/src/managers/GuildManager.js283
-rw-r--r--node_modules/discord.js/src/managers/GuildMemberManager.js540
-rw-r--r--node_modules/discord.js/src/managers/GuildMemberRoleManager.js204
-rw-r--r--node_modules/discord.js/src/managers/GuildMessageManager.js17
-rw-r--r--node_modules/discord.js/src/managers/GuildScheduledEventManager.js297
-rw-r--r--node_modules/discord.js/src/managers/GuildStickerManager.js182
-rw-r--r--node_modules/discord.js/src/managers/GuildTextThreadManager.js91
-rw-r--r--node_modules/discord.js/src/managers/MessageManager.js263
-rw-r--r--node_modules/discord.js/src/managers/PermissionOverwriteManager.js168
-rw-r--r--node_modules/discord.js/src/managers/PresenceManager.js58
-rw-r--r--node_modules/discord.js/src/managers/ReactionManager.js68
-rw-r--r--node_modules/discord.js/src/managers/ReactionUserManager.js77
-rw-r--r--node_modules/discord.js/src/managers/RoleManager.js360
-rw-r--r--node_modules/discord.js/src/managers/StageInstanceManager.js154
-rw-r--r--node_modules/discord.js/src/managers/ThreadManager.js207
-rw-r--r--node_modules/discord.js/src/managers/ThreadMemberManager.js182
-rw-r--r--node_modules/discord.js/src/managers/UserManager.js139
-rw-r--r--node_modules/discord.js/src/managers/VoiceStateManager.js37
35 files changed, 6082 insertions, 0 deletions
diff --git a/node_modules/discord.js/src/managers/ApplicationCommandManager.js b/node_modules/discord.js/src/managers/ApplicationCommandManager.js
new file mode 100644
index 0000000..417afc4
--- /dev/null
+++ b/node_modules/discord.js/src/managers/ApplicationCommandManager.js
@@ -0,0 +1,263 @@
+'use strict';
+
+const { Collection } = require('@discordjs/collection');
+const { makeURLSearchParams } = require('@discordjs/rest');
+const { isJSONEncodable } = require('@discordjs/util');
+const { Routes } = require('discord-api-types/v10');
+const ApplicationCommandPermissionsManager = require('./ApplicationCommandPermissionsManager');
+const CachedManager = require('./CachedManager');
+const { DiscordjsTypeError, ErrorCodes } = require('../errors');
+const ApplicationCommand = require('../structures/ApplicationCommand');
+const PermissionsBitField = require('../util/PermissionsBitField');
+
+/**
+ * Manages API methods for application commands and stores their cache.
+ * @extends {CachedManager}
+ */
+class ApplicationCommandManager extends CachedManager {
+ constructor(client, iterable) {
+ super(client, ApplicationCommand, iterable);
+
+ /**
+ * The manager for permissions of arbitrary commands on arbitrary guilds
+ * @type {ApplicationCommandPermissionsManager}
+ */
+ this.permissions = new ApplicationCommandPermissionsManager(this);
+ }
+
+ /**
+ * The cache of this manager
+ * @type {Collection<Snowflake, ApplicationCommand>}
+ * @name ApplicationCommandManager#cache
+ */
+
+ _add(data, cache, guildId) {
+ return super._add(data, cache, { extras: [this.guild, guildId] });
+ }
+
+ /**
+ * The APIRouter path to the commands
+ * @param {Snowflake} [options.id] The application command's id
+ * @param {Snowflake} [options.guildId] The guild's id to use in the path,
+ * ignored when using a {@link GuildApplicationCommandManager}
+ * @returns {string}
+ * @private
+ */
+ commandPath({ id, guildId } = {}) {
+ if (this.guild ?? guildId) {
+ if (id) {
+ return Routes.applicationGuildCommand(this.client.application.id, this.guild?.id ?? guildId, id);
+ }
+
+ return Routes.applicationGuildCommands(this.client.application.id, this.guild?.id ?? guildId);
+ }
+
+ if (id) {
+ return Routes.applicationCommand(this.client.application.id, id);
+ }
+
+ return Routes.applicationCommands(this.client.application.id);
+ }
+
+ /**
+ * Data that resolves to give an ApplicationCommand object. This can be:
+ * * An ApplicationCommand object
+ * * A Snowflake
+ * @typedef {ApplicationCommand|Snowflake} ApplicationCommandResolvable
+ */
+
+ /**
+ * Data that resolves to the data of an ApplicationCommand
+ * @typedef {ApplicationCommandData|APIApplicationCommand} ApplicationCommandDataResolvable
+ */
+
+ /**
+ * Options used to fetch data from Discord
+ * @typedef {Object} BaseFetchOptions
+ * @property {boolean} [cache=true] Whether to cache the fetched data if it wasn't already
+ * @property {boolean} [force=false] Whether to skip the cache check and request the API
+ */
+
+ /**
+ * Options used to fetch Application Commands from Discord
+ * @typedef {BaseFetchOptions} FetchApplicationCommandOptions
+ * @property {Snowflake} [guildId] The guild's id to fetch commands for, for when the guild is not cached
+ * @property {LocaleString} [locale] The locale to use when fetching this command
+ * @property {boolean} [withLocalizations] Whether to fetch all localization data
+ */
+
+ /**
+ * Obtains one or multiple application commands from Discord, or the cache if it's already available.
+ * @param {Snowflake} [id] The application command's id
+ * @param {FetchApplicationCommandOptions} [options] Additional options for this fetch
+ * @returns {Promise<ApplicationCommand|Collection<Snowflake, ApplicationCommand>>}
+ * @example
+ * // Fetch a single command
+ * client.application.commands.fetch('123456789012345678')
+ * .then(command => console.log(`Fetched command ${command.name}`))
+ * .catch(console.error);
+ * @example
+ * // Fetch all commands
+ * guild.commands.fetch()
+ * .then(commands => console.log(`Fetched ${commands.size} commands`))
+ * .catch(console.error);
+ */
+ async fetch(id, { guildId, cache = true, force = false, locale, withLocalizations } = {}) {
+ if (typeof id === 'object') {
+ ({ guildId, cache = true, locale, withLocalizations } = id);
+ } else if (id) {
+ if (!force) {
+ const existing = this.cache.get(id);
+ if (existing) return existing;
+ }
+ const command = await this.client.rest.get(this.commandPath({ id, guildId }));
+ return this._add(command, cache);
+ }
+
+ const data = await this.client.rest.get(this.commandPath({ guildId }), {
+ headers: {
+ 'X-Discord-Locale': locale,
+ },
+ query: makeURLSearchParams({ with_localizations: withLocalizations }),
+ });
+ return data.reduce((coll, command) => coll.set(command.id, this._add(command, cache, guildId)), new Collection());
+ }
+
+ /**
+ * Creates an application command.
+ * @param {ApplicationCommandDataResolvable} command The command
+ * @param {Snowflake} [guildId] The guild's id to create this command in,
+ * ignored when using a {@link GuildApplicationCommandManager}
+ * @returns {Promise<ApplicationCommand>}
+ * @example
+ * // Create a new command
+ * client.application.commands.create({
+ * name: 'test',
+ * description: 'A test command',
+ * })
+ * .then(console.log)
+ * .catch(console.error);
+ */
+ async create(command, guildId) {
+ const data = await this.client.rest.post(this.commandPath({ guildId }), {
+ body: this.constructor.transformCommand(command),
+ });
+ return this._add(data, true, guildId);
+ }
+
+ /**
+ * Sets all the commands for this application or guild.
+ * @param {ApplicationCommandDataResolvable[]} commands The commands
+ * @param {Snowflake} [guildId] The guild's id to create the commands in,
+ * ignored when using a {@link GuildApplicationCommandManager}
+ * @returns {Promise<Collection<Snowflake, ApplicationCommand>>}
+ * @example
+ * // Set all commands to just this one
+ * client.application.commands.set([
+ * {
+ * name: 'test',
+ * description: 'A test command',
+ * },
+ * ])
+ * .then(console.log)
+ * .catch(console.error);
+ * @example
+ * // Remove all commands
+ * guild.commands.set([])
+ * .then(console.log)
+ * .catch(console.error);
+ */
+ async set(commands, guildId) {
+ const data = await this.client.rest.put(this.commandPath({ guildId }), {
+ body: commands.map(c => this.constructor.transformCommand(c)),
+ });
+ return data.reduce((coll, command) => coll.set(command.id, this._add(command, true, guildId)), new Collection());
+ }
+
+ /**
+ * Edits an application command.
+ * @param {ApplicationCommandResolvable} command The command to edit
+ * @param {Partial<ApplicationCommandDataResolvable>} data The data to update the command with
+ * @param {Snowflake} [guildId] The guild's id where the command registered,
+ * ignored when using a {@link GuildApplicationCommandManager}
+ * @returns {Promise<ApplicationCommand>}
+ * @example
+ * // Edit an existing command
+ * client.application.commands.edit('123456789012345678', {
+ * description: 'New description',
+ * })
+ * .then(console.log)
+ * .catch(console.error);
+ */
+ async edit(command, data, guildId) {
+ const id = this.resolveId(command);
+ if (!id) throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'command', 'ApplicationCommandResolvable');
+
+ const patched = await this.client.rest.patch(this.commandPath({ id, guildId }), {
+ body: this.constructor.transformCommand(data),
+ });
+ return this._add(patched, true, guildId);
+ }
+
+ /**
+ * Deletes an application command.
+ * @param {ApplicationCommandResolvable} command The command to delete
+ * @param {Snowflake} [guildId] The guild's id where the command is registered,
+ * ignored when using a {@link GuildApplicationCommandManager}
+ * @returns {Promise<?ApplicationCommand>}
+ * @example
+ * // Delete a command
+ * guild.commands.delete('123456789012345678')
+ * .then(console.log)
+ * .catch(console.error);
+ */
+ async delete(command, guildId) {
+ const id = this.resolveId(command);
+ if (!id) throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'command', 'ApplicationCommandResolvable');
+
+ await this.client.rest.delete(this.commandPath({ id, guildId }));
+
+ const cached = this.cache.get(id);
+ this.cache.delete(id);
+ return cached ?? null;
+ }
+
+ /**
+ * Transforms an {@link ApplicationCommandData} object into something that can be used with the API.
+ * @param {ApplicationCommandDataResolvable} command The command to transform
+ * @returns {APIApplicationCommand}
+ * @private
+ */
+ static transformCommand(command) {
+ if (isJSONEncodable(command)) return command.toJSON();
+
+ let default_member_permissions;
+
+ if ('default_member_permissions' in command) {
+ default_member_permissions = command.default_member_permissions
+ ? new PermissionsBitField(BigInt(command.default_member_permissions)).bitfield.toString()
+ : command.default_member_permissions;
+ }
+
+ if ('defaultMemberPermissions' in command) {
+ default_member_permissions =
+ command.defaultMemberPermissions !== null
+ ? new PermissionsBitField(command.defaultMemberPermissions).bitfield.toString()
+ : command.defaultMemberPermissions;
+ }
+
+ return {
+ name: command.name,
+ name_localizations: command.nameLocalizations ?? command.name_localizations,
+ description: command.description,
+ nsfw: command.nsfw,
+ description_localizations: command.descriptionLocalizations ?? command.description_localizations,
+ type: command.type,
+ options: command.options?.map(o => ApplicationCommand.transformOption(o)),
+ default_member_permissions,
+ dm_permission: command.dmPermission ?? command.dm_permission,
+ };
+ }
+}
+
+module.exports = ApplicationCommandManager;
diff --git a/node_modules/discord.js/src/managers/ApplicationCommandPermissionsManager.js b/node_modules/discord.js/src/managers/ApplicationCommandPermissionsManager.js
new file mode 100644
index 0000000..2f7279a
--- /dev/null
+++ b/node_modules/discord.js/src/managers/ApplicationCommandPermissionsManager.js
@@ -0,0 +1,434 @@
+'use strict';
+
+const { Collection } = require('@discordjs/collection');
+const { ApplicationCommandPermissionType, RESTJSONErrorCodes, Routes } = require('discord-api-types/v10');
+const BaseManager = require('./BaseManager');
+const { DiscordjsError, DiscordjsTypeError, ErrorCodes } = require('../errors');
+
+/**
+ * Manages API methods for permissions of Application Commands.
+ * @extends {BaseManager}
+ */
+class ApplicationCommandPermissionsManager extends BaseManager {
+ constructor(manager) {
+ super(manager.client);
+
+ /**
+ * The manager or command that this manager belongs to
+ * @type {ApplicationCommandManager|ApplicationCommand}
+ * @private
+ */
+ this.manager = manager;
+
+ /**
+ * The guild that this manager acts on
+ * @type {?Guild}
+ */
+ this.guild = manager.guild ?? null;
+
+ /**
+ * The id of the guild that this manager acts on
+ * @type {?Snowflake}
+ */
+ this.guildId = manager.guildId ?? manager.guild?.id ?? null;
+
+ /**
+ * The id of the command this manager acts on
+ * @type {?Snowflake}
+ */
+ this.commandId = manager.id ?? null;
+ }
+
+ /**
+ * The APIRouter path to the commands
+ * @param {Snowflake} guildId The guild's id to use in the path,
+ * @param {Snowflake} [commandId] The application command's id
+ * @returns {string}
+ * @private
+ */
+ permissionsPath(guildId, commandId) {
+ if (commandId) {
+ return Routes.applicationCommandPermissions(this.client.application.id, guildId, commandId);
+ }
+
+ return Routes.guildApplicationCommandsPermissions(this.client.application.id, guildId);
+ }
+
+ /* eslint-disable max-len */
+ /**
+ * The object returned when fetching permissions for an application command.
+ * @typedef {Object} ApplicationCommandPermissions
+ * @property {Snowflake} id The role, user, or channel's id. Can also be a
+ * {@link https://discord.com/developers/docs/interactions/application-commands#application-command-permissions-object-application-command-permissions-constants permission constant}.
+ * @property {ApplicationCommandPermissionType} type Whether this permission is for a role or a user
+ * @property {boolean} permission Whether the role or user has the permission to use this command
+ */
+ /* eslint-enable max-len */
+
+ /**
+ * Options for managing permissions for one or more Application Commands
+ * <warn>When passing these options to a manager where `guildId` is `null`,
+ * `guild` is a required parameter</warn>
+ * @typedef {Object} BaseApplicationCommandPermissionsOptions
+ * @property {GuildResolvable} [guild] The guild to modify / check permissions for
+ * <warn>Ignored when the manager has a non-null `guildId` property</warn>
+ * @property {ApplicationCommandResolvable} [command] The command to modify / check permissions for
+ * <warn>Ignored when the manager has a non-null `commandId` property</warn>
+ */
+
+ /**
+ * Fetches the permissions for one or multiple commands. Providing the client's id as the "command id" will fetch
+ * *only* the guild level permissions
+ * @param {BaseApplicationCommandPermissionsOptions} [options] Options used to fetch permissions
+ * @returns {Promise<ApplicationCommandPermissions[]|Collection<Snowflake, ApplicationCommandPermissions[]>>}
+ * @example
+ * // Fetch permissions for one command
+ * guild.commands.permissions.fetch({ command: '123456789012345678' })
+ * .then(perms => console.log(`Fetched ${perms.length} overwrites`))
+ * .catch(console.error);
+ * @example
+ * // Fetch permissions for all commands in a guild
+ * client.application.commands.permissions.fetch({ guild: '123456789012345678' })
+ * .then(perms => console.log(`Fetched permissions for ${perms.size} commands`))
+ * .catch(console.error);
+ * @example
+ * // Fetch guild level permissions
+ * guild.commands.permissions.fetch({ command: client.user.id })
+ * .then(perms => console.log(`Fetched ${perms.length} guild level permissions`))
+ * .catch(console.error);
+ */
+ async fetch({ guild, command } = {}) {
+ const { guildId, commandId } = this._validateOptions(guild, command);
+ if (commandId) {
+ const data = await this.client.rest.get(this.permissionsPath(guildId, commandId));
+ return data.permissions;
+ }
+
+ const data = await this.client.rest.get(this.permissionsPath(guildId));
+ return data.reduce((coll, perm) => coll.set(perm.id, perm.permissions), new Collection());
+ }
+
+ /**
+ * Options used to set permissions for one or more Application Commands in a guild
+ * <warn>Omitting the `command` parameter edits the guild wide permissions
+ * when the manager's `commandId` is `null`</warn>
+ * @typedef {BaseApplicationCommandPermissionsOptions} ApplicationCommandPermissionsEditOptions
+ * @property {ApplicationCommandPermissions[]} permissions The new permissions for the guild or overwrite
+ * @property {string} token The bearer token to use that authorizes the permission edit
+ */
+
+ /**
+ * Sets the permissions for the guild or a command overwrite.
+ * @param {ApplicationCommandPermissionsEditOptions} options Options used to set permissions
+ * @returns {Promise<ApplicationCommandPermissions[]|Collection<Snowflake, ApplicationCommandPermissions[]>>}
+ * @example
+ * // Set a permission overwrite for a command
+ * client.application.commands.permissions.set({
+ * guild: '892455839386304532',
+ * command: '123456789012345678',
+ * token: 'TotallyRealToken',
+ * permissions: [
+ * {
+ * id: '876543210987654321',
+ * type: ApplicationCommandPermissionType.User,
+ * permission: false,
+ * },
+ * ]})
+ * .then(console.log)
+ * .catch(console.error);
+ * @example
+ * // Set the permissions used for the guild (commands without overwrites)
+ * guild.commands.permissions.set({ token: 'TotallyRealToken', permissions: [
+ * {
+ * id: '123456789012345678',
+ * permissions: [{
+ * id: '876543210987654321',
+ * type: ApplicationCommandPermissionType.User,
+ * permission: false,
+ * }],
+ * },
+ * ]})
+ * .then(console.log)
+ * .catch(console.error);
+ */
+ async set({ guild, command, permissions, token } = {}) {
+ if (!token) {
+ throw new DiscordjsError(ErrorCodes.ApplicationCommandPermissionsTokenMissing);
+ }
+ let { guildId, commandId } = this._validateOptions(guild, command);
+
+ if (!Array.isArray(permissions)) {
+ throw new DiscordjsTypeError(
+ ErrorCodes.InvalidType,
+ 'permissions',
+ 'Array of ApplicationCommandPermissions',
+ true,
+ );
+ }
+
+ if (!commandId) {
+ commandId = this.client.user.id;
+ }
+ const data = await this.client.rest.put(this.permissionsPath(guildId, commandId), {
+ body: { permissions },
+ auth: false,
+ headers: { Authorization: `Bearer ${token}` },
+ });
+ return data.permissions;
+ }
+
+ /**
+ * Add permissions to a command.
+ * @param {ApplicationCommandPermissionsEditOptions} options Options used to add permissions
+ * @returns {Promise<ApplicationCommandPermissions[]>}
+ * @example
+ * // Add a rule to block a role from using a command
+ * guild.commands.permissions.add({ command: '123456789012345678', token: 'TotallyRealToken', permissions: [
+ * {
+ * id: '876543211234567890',
+ * type: ApplicationCommandPermissionType.Role,
+ * permission: false
+ * },
+ * ]})
+ * .then(console.log)
+ * .catch(console.error);
+ */
+ async add({ guild, command, permissions, token } = {}) {
+ if (!token) {
+ throw new DiscordjsError(ErrorCodes.ApplicationCommandPermissionsTokenMissing);
+ }
+ let { guildId, commandId } = this._validateOptions(guild, command);
+ if (!commandId) {
+ commandId = this.client.user.id;
+ }
+ if (!Array.isArray(permissions)) {
+ throw new DiscordjsTypeError(
+ ErrorCodes.InvalidType,
+ 'permissions',
+ 'Array of ApplicationCommandPermissions',
+ true,
+ );
+ }
+
+ let existing = [];
+ try {
+ existing = await this.fetch({ guild: guildId, command: commandId });
+ } catch (error) {
+ if (error.code !== RESTJSONErrorCodes.UnknownApplicationCommandPermissions) throw error;
+ }
+
+ const newPermissions = permissions.slice();
+ for (const perm of existing) {
+ if (!newPermissions.some(x => x.id === perm.id)) {
+ newPermissions.push(perm);
+ }
+ }
+
+ return this.set({ guild: guildId, command: commandId, permissions: newPermissions, token });
+ }
+
+ /**
+ * A static snowflake that identifies the everyone role for application command permissions.
+ * It is the same as the guild id
+ * @typedef {Snowflake} RolePermissionConstant
+ */
+
+ /**
+ * A static snowflake that identifies the "all channels" entity for application command permissions.
+ * It will be the result of the calculation `guildId - 1`
+ * @typedef {Snowflake} ChannelPermissionConstant
+ */
+
+ /**
+ * Options used to remove permissions from a command
+ * <warn>Omitting the `command` parameter removes from the guild wide permissions
+ * when the managers `commandId` is `null`</warn>
+ * <warn>At least one of `users`, `roles`, and `channels` is required</warn>
+ * @typedef {BaseApplicationCommandPermissionsOptions} RemoveApplicationCommandPermissionsOptions
+ * @property {string} token The bearer token to use that authorizes the permission removal
+ * @property {UserResolvable[]} [users] The user(s) to remove
+ * @property {Array<RoleResolvable|RolePermissionConstant>} [roles] The role(s) to remove
+ * @property {Array<GuildChannelResolvable|ChannelPermissionConstant>} [channels] The channel(s) to remove
+ */
+
+ /**
+ * Remove permissions from a command.
+ * @param {RemoveApplicationCommandPermissionsOptions} options Options used to remove permissions
+ * @returns {Promise<ApplicationCommandPermissions[]>}
+ * @example
+ * // Remove a user permission from this command
+ * guild.commands.permissions.remove({
+ * command: '123456789012345678', users: '876543210123456789', token: 'TotallyRealToken',
+ * })
+ * .then(console.log)
+ * .catch(console.error);
+ * @example
+ * // Remove multiple roles from this command
+ * guild.commands.permissions.remove({
+ * command: '123456789012345678', roles: ['876543210123456789', '765432101234567890'], token: 'TotallyRealToken',
+ * })
+ * .then(console.log)
+ * .catch(console.error);
+ */
+ async remove({ guild, command, users, roles, channels, token } = {}) {
+ if (!token) {
+ throw new DiscordjsError(ErrorCodes.ApplicationCommandPermissionsTokenMissing);
+ }
+ let { guildId, commandId } = this._validateOptions(guild, command);
+ if (!commandId) {
+ commandId = this.client.user.id;
+ }
+
+ if (!users && !roles && !channels) {
+ throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'users OR roles OR channels', 'Array or Resolvable', true);
+ }
+
+ let resolvedUserIds = [];
+ if (Array.isArray(users)) {
+ for (const user of users) {
+ const userId = this.client.users.resolveId(user);
+ if (!userId) throw new DiscordjsTypeError(ErrorCodes.InvalidElement, 'Array', 'users', user);
+ resolvedUserIds.push(userId);
+ }
+ }
+
+ let resolvedRoleIds = [];
+ if (Array.isArray(roles)) {
+ for (const role of roles) {
+ if (typeof role === 'string') {
+ resolvedRoleIds.push(role);
+ continue;
+ }
+ if (!this.guild) throw new DiscordjsError(ErrorCodes.GuildUncachedEntityResolve, 'roles');
+ const roleId = this.guild.roles.resolveId(role);
+ if (!roleId) throw new DiscordjsTypeError(ErrorCodes.InvalidElement, 'Array', 'users', role);
+ resolvedRoleIds.push(roleId);
+ }
+ }
+
+ let resolvedChannelIds = [];
+ if (Array.isArray(channels)) {
+ for (const channel of channels) {
+ if (typeof channel === 'string') {
+ resolvedChannelIds.push(channel);
+ continue;
+ }
+ if (!this.guild) throw new DiscordjsError(ErrorCodes.GuildUncachedEntityResolve, 'channels');
+ const channelId = this.guild.channels.resolveId(channel);
+ if (!channelId) throw new DiscordjsTypeError(ErrorCodes.InvalidElement, 'Array', 'channels', channel);
+ resolvedChannelIds.push(channelId);
+ }
+ }
+
+ let existing = [];
+ try {
+ existing = await this.fetch({ guild: guildId, command: commandId });
+ } catch (error) {
+ if (error.code !== RESTJSONErrorCodes.UnknownApplicationCommandPermissions) throw error;
+ }
+
+ const permissions = existing.filter(perm => {
+ switch (perm.type) {
+ case ApplicationCommandPermissionType.Role:
+ return !resolvedRoleIds.includes(perm.id);
+ case ApplicationCommandPermissionType.User:
+ return !resolvedUserIds.includes(perm.id);
+ case ApplicationCommandPermissionType.Channel:
+ return !resolvedChannelIds.includes(perm.id);
+ }
+ return true;
+ });
+
+ return this.set({ guild: guildId, command: commandId, permissions, token });
+ }
+
+ /**
+ * Options used to check the existence of permissions on a command
+ * <warn>The `command` parameter is not optional when the managers `commandId` is `null`</warn>
+ * @typedef {BaseApplicationCommandPermissionsOptions} HasApplicationCommandPermissionsOptions
+ * @property {ApplicationCommandPermissionIdResolvable} permissionId The entity to check if a permission exists for
+ * on this command.
+ * @property {ApplicationCommandPermissionType} [permissionType] Check for a specific type of permission
+ */
+
+ /**
+ * Check whether a permission exists for a user, role, or channel
+ * @param {HasApplicationCommandPermissionsOptions} options Options used to check permissions
+ * @returns {Promise<boolean>}
+ * @example
+ * // Check whether a user has permission to use a command
+ * guild.commands.permissions.has({ command: '123456789012345678', permissionId: '876543210123456789' })
+ * .then(console.log)
+ * .catch(console.error);
+ */
+ async has({ guild, command, permissionId, permissionType }) {
+ const { guildId, commandId } = this._validateOptions(guild, command);
+ if (!commandId) throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'command', 'ApplicationCommandResolvable');
+
+ if (!permissionId) {
+ throw new DiscordjsTypeError(
+ ErrorCodes.InvalidType,
+ 'permissionId',
+ 'UserResolvable, RoleResolvable, ChannelResolvable, or Permission Constant',
+ );
+ }
+ let resolvedId = permissionId;
+ if (typeof permissionId !== 'string') {
+ resolvedId = this.client.users.resolveId(permissionId);
+ if (!resolvedId) {
+ if (!this.guild) throw new DiscordjsError(ErrorCodes.GuildUncachedEntityResolve, 'roles');
+ resolvedId = this.guild.roles.resolveId(permissionId);
+ }
+ if (!resolvedId) {
+ resolvedId = this.guild.channels.resolveId(permissionId);
+ }
+ if (!resolvedId) {
+ throw new DiscordjsTypeError(
+ ErrorCodes.InvalidType,
+ 'permissionId',
+ 'UserResolvable, RoleResolvable, ChannelResolvable, or Permission Constant',
+ );
+ }
+ }
+
+ let existing = [];
+ try {
+ existing = await this.fetch({ guild: guildId, command: commandId });
+ } catch (error) {
+ if (error.code !== RESTJSONErrorCodes.UnknownApplicationCommandPermissions) throw error;
+ }
+
+ // Check permission type if provided for the single edge case where a channel id is the same as the everyone role id
+ return existing.some(perm => perm.id === resolvedId && (permissionType ?? perm.type) === perm.type);
+ }
+
+ _validateOptions(guild, command) {
+ const guildId = this.guildId ?? this.client.guilds.resolveId(guild);
+ if (!guildId) throw new DiscordjsError(ErrorCodes.GlobalCommandPermissions);
+ let commandId = this.commandId;
+ if (command && !commandId) {
+ commandId = this.manager.resolveId?.(command);
+ if (!commandId && this.guild) {
+ commandId = this.guild.commands.resolveId(command);
+ }
+ commandId ??= this.client.application?.commands.resolveId(command);
+ if (!commandId) {
+ throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'command', 'ApplicationCommandResolvable', true);
+ }
+ }
+ return { guildId, commandId };
+ }
+}
+
+module.exports = ApplicationCommandPermissionsManager;
+
+/* eslint-disable max-len */
+/**
+ * @external APIApplicationCommandPermissions
+ * @see {@link https://discord.com/developers/docs/interactions/application-commands#application-command-permissions-object-application-command-permissions-structure}
+ */
+
+/**
+ * Data that resolves to an id used for an application command permission
+ * @typedef {UserResolvable|RoleResolvable|GuildChannelResolvable|RolePermissionConstant|ChannelPermissionConstant} ApplicationCommandPermissionIdResolvable
+ */
diff --git a/node_modules/discord.js/src/managers/AutoModerationRuleManager.js b/node_modules/discord.js/src/managers/AutoModerationRuleManager.js
new file mode 100644
index 0000000..dd0ee4e
--- /dev/null
+++ b/node_modules/discord.js/src/managers/AutoModerationRuleManager.js
@@ -0,0 +1,288 @@
+'use strict';
+
+const { Collection } = require('@discordjs/collection');
+const { Routes } = require('discord-api-types/v10');
+const CachedManager = require('./CachedManager');
+const AutoModerationRule = require('../structures/AutoModerationRule');
+
+/**
+ * Manages API methods for auto moderation rules and stores their cache.
+ * @extends {CachedManager}
+ */
+class AutoModerationRuleManager extends CachedManager {
+ constructor(guild, iterable) {
+ super(guild.client, AutoModerationRule, iterable);
+
+ /**
+ * The guild this manager belongs to.
+ * @type {Guild}
+ */
+ this.guild = guild;
+ }
+
+ /**
+ * The cache of this manager
+ * @type {Collection<Snowflake, AutoModerationRule>}
+ * @name AutoModerationRuleManager#cache
+ */
+
+ /**
+ * Resolves an {@link AutoModerationRuleResolvable} to an {@link AutoModerationRule} object.
+ * @method resolve
+ * @memberof AutoModerationRuleManager
+ * @instance
+ * @param {AutoModerationRuleResolvable} autoModerationRule The AutoModerationRule resolvable to resolve
+ * @returns {?AutoModerationRule}
+ */
+
+ /**
+ * Resolves an {@link AutoModerationRuleResolvable} to a {@link AutoModerationRule} id.
+ * @method resolveId
+ * @memberof AutoModerationRuleManager
+ * @instance
+ * @param {AutoModerationRuleResolvable} autoModerationRule The AutoModerationRule resolvable to resolve
+ * @returns {?Snowflake}
+ */
+
+ _add(data, cache) {
+ return super._add(data, cache, { extras: [this.guild] });
+ }
+
+ /**
+ * Options used to set the trigger metadata of an auto moderation rule.
+ * @typedef {Object} AutoModerationTriggerMetadataOptions
+ * @property {string[]} [keywordFilter] The substrings that will be searched for in the content
+ * @property {string[]} [regexPatterns] The regular expression patterns which will be matched against the content
+ * <info>Only Rust-flavored regular expressions are supported.</info>
+ * @property {AutoModerationRuleKeywordPresetType[]} [presets]
+ * The internally pre-defined wordsets which will be searched for in the content
+ * @property {string[]} [allowList] The substrings that will be exempt from triggering
+ * {@link AutoModerationRuleTriggerType.Keyword} and {@link AutoModerationRuleTriggerType.KeywordPreset}
+ * @property {?number} [mentionTotalLimit] The total number of role & user mentions allowed per message
+ * @property {boolean} [mentionRaidProtectionEnabled] Whether to automatically detect mention raids
+ */
+
+ /**
+ * Options used to set the actions of an auto moderation rule.
+ * @typedef {Object} AutoModerationActionOptions
+ * @property {AutoModerationActionType} type The type of this auto moderation rule action
+ * @property {AutoModerationActionMetadataOptions} [metadata] Additional metadata needed during execution
+ * <info>This property is required if using a `type` of
+ * {@link AutoModerationActionType.SendAlertMessage} or {@link AutoModerationActionType.Timeout}.</info>
+ */
+
+ /**
+ * Options used to set the metadata of an auto moderation rule action.
+ * @typedef {Object} AutoModerationActionMetadataOptions
+ * @property {GuildTextChannelResolvable|ThreadChannel} [channel] The channel to which content will be logged
+ * @property {number} [durationSeconds] The timeout duration in seconds
+ * @property {string} [customMessage] The custom message that is shown whenever a message is blocked
+ */
+
+ /**
+ * Options used to create an auto moderation rule.
+ * @typedef {Object} AutoModerationRuleCreateOptions
+ * @property {string} name The name of the auto moderation rule
+ * @property {AutoModerationRuleEventType} eventType The event type of the auto moderation rule
+ * @property {AutoModerationRuleTriggerType} triggerType The trigger type of the auto moderation rule
+ * @property {AutoModerationTriggerMetadataOptions} [triggerMetadata] The trigger metadata of the auto moderation rule
+ * <info>This property is required if using a `triggerType` of
+ * {@link AutoModerationRuleTriggerType.Keyword}, {@link AutoModerationRuleTriggerType.KeywordPreset},
+ * or {@link AutoModerationRuleTriggerType.MentionSpam}.</info>
+ * @property {AutoModerationActionOptions[]} actions
+ * The actions that will execute when the auto moderation rule is triggered
+ * @property {boolean} [enabled] Whether the auto moderation rule should be enabled
+ * @property {Collection<Snowflake, Role>|RoleResolvable[]} [exemptRoles]
+ * The roles that should not be affected by the auto moderation rule
+ * @property {Collection<Snowflake, GuildChannel|ThreadChannel>|GuildChannelResolvable[]} [exemptChannels]
+ * The channels that should not be affected by the auto moderation rule
+ * @property {string} [reason] The reason for creating the auto moderation rule
+ */
+
+ /**
+ * Creates a new auto moderation rule.
+ * @param {AutoModerationRuleCreateOptions} options Options for creating the auto moderation rule
+ * @returns {Promise<AutoModerationRule>}
+ */
+ async create({
+ name,
+ eventType,
+ triggerType,
+ triggerMetadata,
+ actions,
+ enabled,
+ exemptRoles,
+ exemptChannels,
+ reason,
+ }) {
+ const data = await this.client.rest.post(Routes.guildAutoModerationRules(this.guild.id), {
+ body: {
+ name,
+ event_type: eventType,
+ trigger_type: triggerType,
+ trigger_metadata: triggerMetadata && {
+ keyword_filter: triggerMetadata.keywordFilter,
+ regex_patterns: triggerMetadata.regexPatterns,
+ presets: triggerMetadata.presets,
+ allow_list: triggerMetadata.allowList,
+ mention_total_limit: triggerMetadata.mentionTotalLimit,
+ mention_raid_protection_enabled: triggerMetadata.mentionRaidProtectionEnabled,
+ },
+ actions: actions.map(action => ({
+ type: action.type,
+ metadata: {
+ duration_seconds: action.metadata?.durationSeconds,
+ channel_id: action.metadata?.channel && this.guild.channels.resolveId(action.metadata.channel),
+ custom_message: action.metadata?.customMessage,
+ },
+ })),
+ enabled,
+ exempt_roles: exemptRoles?.map(exemptRole => this.guild.roles.resolveId(exemptRole)),
+ exempt_channels: exemptChannels?.map(exemptChannel => this.guild.channels.resolveId(exemptChannel)),
+ },
+ reason,
+ });
+
+ return this._add(data);
+ }
+
+ /**
+ * Options used to edit an auto moderation rule.
+ * @typedef {Object} AutoModerationRuleEditOptions
+ * @property {string} [name] The name of the auto moderation rule
+ * @property {AutoModerationRuleEventType} [eventType] The event type of the auto moderation rule
+ * @property {AutoModerationTriggerMetadataOptions} [triggerMetadata] The trigger metadata of the auto moderation rule
+ * @property {AutoModerationActionOptions[]} [actions]
+ * The actions that will execute when the auto moderation rule is triggered
+ * @property {boolean} [enabled] Whether the auto moderation rule should be enabled
+ * @property {Collection<Snowflake, Role>|RoleResolvable[]} [exemptRoles]
+ * The roles that should not be affected by the auto moderation rule
+ * @property {Collection<Snowflake, GuildChannel|ThreadChannel>|GuildChannelResolvable[]} [exemptChannels]
+ * The channels that should not be affected by the auto moderation rule
+ * @property {string} [reason] The reason for creating the auto moderation rule
+ */
+
+ /**
+ * Edits an auto moderation rule.
+ * @param {AutoModerationRuleResolvable} autoModerationRule The auto moderation rule to edit
+ * @param {AutoModerationRuleEditOptions} options Options for editing the auto moderation rule
+ * @returns {Promise<AutoModerationRule>}
+ */
+ async edit(
+ autoModerationRule,
+ { name, eventType, triggerMetadata, actions, enabled, exemptRoles, exemptChannels, reason },
+ ) {
+ const autoModerationRuleId = this.resolveId(autoModerationRule);
+
+ const data = await this.client.rest.patch(Routes.guildAutoModerationRule(this.guild.id, autoModerationRuleId), {
+ body: {
+ name,
+ event_type: eventType,
+ trigger_metadata: triggerMetadata && {
+ keyword_filter: triggerMetadata.keywordFilter,
+ regex_patterns: triggerMetadata.regexPatterns,
+ presets: triggerMetadata.presets,
+ allow_list: triggerMetadata.allowList,
+ mention_total_limit: triggerMetadata.mentionTotalLimit,
+ mention_raid_protection_enabled: triggerMetadata.mentionRaidProtectionEnabled,
+ },
+ actions: actions?.map(action => ({
+ type: action.type,
+ metadata: {
+ duration_seconds: action.metadata?.durationSeconds,
+ channel_id: action.metadata?.channel && this.guild.channels.resolveId(action.metadata.channel),
+ custom_message: action.metadata?.customMessage,
+ },
+ })),
+ enabled,
+ exempt_roles: exemptRoles?.map(exemptRole => this.guild.roles.resolveId(exemptRole)),
+ exempt_channels: exemptChannels?.map(exemptChannel => this.guild.channels.resolveId(exemptChannel)),
+ },
+ reason,
+ });
+
+ return this._add(data);
+ }
+
+ /**
+ * Data that can be resolved to give an AutoModerationRule object. This can be:
+ * * An AutoModerationRule
+ * * A Snowflake
+ * @typedef {AutoModerationRule|Snowflake} AutoModerationRuleResolvable
+ */
+
+ /**
+ * Options used to fetch a single auto moderation rule from a guild.
+ * @typedef {BaseFetchOptions} FetchAutoModerationRuleOptions
+ * @property {AutoModerationRuleResolvable} autoModerationRule The auto moderation rule to fetch
+ */
+
+ /**
+ * Options used to fetch all auto moderation rules from a guild.
+ * @typedef {Object} FetchAutoModerationRulesOptions
+ * @property {boolean} [cache] Whether to cache the fetched auto moderation rules
+ */
+
+ /**
+ * Fetches auto moderation rules from Discord.
+ * @param {AutoModerationRuleResolvable|FetchAutoModerationRuleOptions|FetchAutoModerationRulesOptions} [options]
+ * Options for fetching auto moderation rule(s)
+ * @returns {Promise<AutoModerationRule|Collection<Snowflake, AutoModerationRule>>}
+ * @example
+ * // Fetch all auto moderation rules from a guild without caching
+ * guild.autoModerationRules.fetch({ cache: false })
+ * .then(console.log)
+ * .catch(console.error);
+ * @example
+ * // Fetch a single auto moderation rule
+ * guild.autoModerationRules.fetch('979083472868098119')
+ * .then(console.log)
+ * .catch(console.error);
+ * @example
+ * // Fetch a single auto moderation rule without checking cache and without caching
+ * guild.autoModerationRules.fetch({ autoModerationRule: '979083472868098119', cache: false, force: true })
+ * .then(console.log)
+ * .catch(console.error)
+ */
+ fetch(options) {
+ if (!options) return this._fetchMany();
+ const { autoModerationRule, cache, force } = options;
+ const resolvedAutoModerationRule = this.resolveId(autoModerationRule ?? options);
+ if (resolvedAutoModerationRule) {
+ return this._fetchSingle({ autoModerationRule: resolvedAutoModerationRule, cache, force });
+ }
+ return this._fetchMany(options);
+ }
+
+ async _fetchSingle({ autoModerationRule, cache, force = false }) {
+ if (!force) {
+ const existing = this.cache.get(autoModerationRule);
+ if (existing) return existing;
+ }
+
+ const data = await this.client.rest.get(Routes.guildAutoModerationRule(this.guild.id, autoModerationRule));
+ return this._add(data, cache);
+ }
+
+ async _fetchMany(options = {}) {
+ const data = await this.client.rest.get(Routes.guildAutoModerationRules(this.guild.id));
+
+ return data.reduce(
+ (col, autoModerationRule) => col.set(autoModerationRule.id, this._add(autoModerationRule, options.cache)),
+ new Collection(),
+ );
+ }
+
+ /**
+ * Deletes an auto moderation rule.
+ * @param {AutoModerationRuleResolvable} autoModerationRule The auto moderation rule to delete
+ * @param {string} [reason] The reason for deleting the auto moderation rule
+ * @returns {Promise<void>}
+ */
+ async delete(autoModerationRule, reason) {
+ const autoModerationRuleId = this.resolveId(autoModerationRule);
+ await this.client.rest.delete(Routes.guildAutoModerationRule(this.guild.id, autoModerationRuleId), { reason });
+ }
+}
+
+module.exports = AutoModerationRuleManager;
diff --git a/node_modules/discord.js/src/managers/BaseGuildEmojiManager.js b/node_modules/discord.js/src/managers/BaseGuildEmojiManager.js
new file mode 100644
index 0000000..89eee4c
--- /dev/null
+++ b/node_modules/discord.js/src/managers/BaseGuildEmojiManager.js
@@ -0,0 +1,80 @@
+'use strict';
+
+const CachedManager = require('./CachedManager');
+const GuildEmoji = require('../structures/GuildEmoji');
+const ReactionEmoji = require('../structures/ReactionEmoji');
+const { parseEmoji } = require('../util/Util');
+
+/**
+ * Holds methods to resolve GuildEmojis and stores their cache.
+ * @extends {CachedManager}
+ */
+class BaseGuildEmojiManager extends CachedManager {
+ constructor(client, iterable) {
+ super(client, GuildEmoji, iterable);
+ }
+
+ /**
+ * The cache of GuildEmojis
+ * @type {Collection<Snowflake, GuildEmoji>}
+ * @name BaseGuildEmojiManager#cache
+ */
+
+ /**
+ * Data that can be resolved into a GuildEmoji object. This can be:
+ * * A Snowflake
+ * * A GuildEmoji object
+ * * A ReactionEmoji object
+ * @typedef {Snowflake|GuildEmoji|ReactionEmoji} EmojiResolvable
+ */
+
+ /**
+ * Resolves an EmojiResolvable to an Emoji object.
+ * @param {EmojiResolvable} emoji The Emoji resolvable to identify
+ * @returns {?GuildEmoji}
+ */
+ resolve(emoji) {
+ if (emoji instanceof ReactionEmoji) return super.resolve(emoji.id);
+ return super.resolve(emoji);
+ }
+
+ /**
+ * Resolves an EmojiResolvable to an Emoji id string.
+ * @param {EmojiResolvable} emoji The Emoji resolvable to identify
+ * @returns {?Snowflake}
+ */
+ resolveId(emoji) {
+ if (emoji instanceof ReactionEmoji) return emoji.id;
+ return super.resolveId(emoji);
+ }
+
+ /**
+ * Data that can be resolved to give an emoji identifier. This can be:
+ * * An EmojiResolvable
+ * * The `<a:name:id>`, `<:name:id>`, `a:name:id` or `name:id` emoji identifier string of an emoji
+ * * The Unicode representation of an emoji
+ * @typedef {string|EmojiResolvable} EmojiIdentifierResolvable
+ */
+
+ /**
+ * Resolves an EmojiResolvable to an emoji identifier.
+ * @param {EmojiIdentifierResolvable} emoji The emoji resolvable to resolve
+ * @returns {?string}
+ */
+ resolveIdentifier(emoji) {
+ const emojiResolvable = this.resolve(emoji);
+ if (emojiResolvable) return emojiResolvable.identifier;
+ if (emoji instanceof ReactionEmoji) return emoji.identifier;
+ if (typeof emoji === 'string') {
+ const res = parseEmoji(emoji);
+ if (res?.name.length) {
+ emoji = `${res.animated ? 'a:' : ''}${res.name}${res.id ? `:${res.id}` : ''}`;
+ }
+ if (!emoji.includes('%')) return encodeURIComponent(emoji);
+ return emoji;
+ }
+ return null;
+ }
+}
+
+module.exports = BaseGuildEmojiManager;
diff --git a/node_modules/discord.js/src/managers/BaseManager.js b/node_modules/discord.js/src/managers/BaseManager.js
new file mode 100644
index 0000000..0651401
--- /dev/null
+++ b/node_modules/discord.js/src/managers/BaseManager.js
@@ -0,0 +1,19 @@
+'use strict';
+
+/**
+ * Manages the API methods of a data model.
+ * @abstract
+ */
+class BaseManager {
+ constructor(client) {
+ /**
+ * The client that instantiated this Manager
+ * @name BaseManager#client
+ * @type {Client}
+ * @readonly
+ */
+ Object.defineProperty(this, 'client', { value: client });
+ }
+}
+
+module.exports = BaseManager;
diff --git a/node_modules/discord.js/src/managers/CachedManager.js b/node_modules/discord.js/src/managers/CachedManager.js
new file mode 100644
index 0000000..b4c50b1
--- /dev/null
+++ b/node_modules/discord.js/src/managers/CachedManager.js
@@ -0,0 +1,64 @@
+'use strict';
+
+const DataManager = require('./DataManager');
+const { MakeCacheOverrideSymbol } = require('../util/Symbols');
+
+/**
+ * Manages the API methods of a data model with a mutable cache of instances.
+ * @extends {DataManager}
+ * @abstract
+ */
+class CachedManager extends DataManager {
+ constructor(client, holds, iterable) {
+ super(client, holds);
+
+ /**
+ * The private cache of items for this manager.
+ * @type {Collection}
+ * @private
+ * @readonly
+ * @name CachedManager#_cache
+ */
+ Object.defineProperty(this, '_cache', {
+ value: this.client.options.makeCache(
+ this.constructor[MakeCacheOverrideSymbol] ?? this.constructor,
+ this.holds,
+ this.constructor,
+ ),
+ });
+
+ if (iterable) {
+ for (const item of iterable) {
+ this._add(item);
+ }
+ }
+ }
+
+ /**
+ * The cache of items for this manager.
+ * @type {Collection}
+ * @abstract
+ */
+ get cache() {
+ return this._cache;
+ }
+
+ _add(data, cache = true, { id, extras = [] } = {}) {
+ const existing = this.cache.get(id ?? data.id);
+ if (existing) {
+ if (cache) {
+ existing._patch(data);
+ return existing;
+ }
+ const clone = existing._clone();
+ clone._patch(data);
+ return clone;
+ }
+
+ const entry = this.holds ? new this.holds(this.client, data, ...extras) : data;
+ if (cache) this.cache.set(id ?? entry.id, entry);
+ return entry;
+ }
+}
+
+module.exports = CachedManager;
diff --git a/node_modules/discord.js/src/managers/CategoryChannelChildManager.js b/node_modules/discord.js/src/managers/CategoryChannelChildManager.js
new file mode 100644
index 0000000..347526a
--- /dev/null
+++ b/node_modules/discord.js/src/managers/CategoryChannelChildManager.js
@@ -0,0 +1,77 @@
+'use strict';
+
+const DataManager = require('./DataManager');
+const GuildChannel = require('../structures/GuildChannel');
+
+/**
+ * Manages API methods for CategoryChannels' children.
+ * @extends {DataManager}
+ */
+class CategoryChannelChildManager extends DataManager {
+ constructor(channel) {
+ super(channel.client, GuildChannel);
+ /**
+ * The category channel this manager belongs to
+ * @type {CategoryChannel}
+ */
+ this.channel = channel;
+ }
+
+ /**
+ * The channels that are a part of this category
+ * @type {Collection<Snowflake, GuildChannel>}
+ * @readonly
+ */
+ get cache() {
+ return this.guild.channels.cache.filter(c => c.parentId === this.channel.id);
+ }
+
+ /**
+ * The guild this manager belongs to
+ * @type {Guild}
+ * @readonly
+ */
+ get guild() {
+ return this.channel.guild;
+ }
+
+ /**
+ * Options for creating a channel using {@link CategoryChannel#createChannel}.
+ * @typedef {Object} CategoryCreateChannelOptions
+ * @property {string} name The name for the new channel
+ * @property {ChannelType} [type=ChannelType.GuildText] The type of the new channel.
+ * @property {string} [topic] The topic for the new channel
+ * @property {boolean} [nsfw] Whether the new channel is NSFW
+ * @property {number} [bitrate] Bitrate of the new channel in bits (only voice)
+ * @property {number} [userLimit] Maximum amount of users allowed in the new channel (only voice)
+ * @property {OverwriteResolvable[]|Collection<Snowflake, OverwriteResolvable>} [permissionOverwrites]
+ * Permission overwrites of the new channel
+ * @property {number} [position] Position of the new channel
+ * @property {number} [rateLimitPerUser] The rate limit per user (slowmode) for the new channel in seconds
+ * @property {string} [rtcRegion] The specific region of the new channel.
+ * @property {VideoQualityMode} [videoQualityMode] The camera video quality mode of the voice channel
+ * @property {GuildForumTagData[]} [availableTags] The tags that can be used in this channel (forum only).
+ * @property {DefaultReactionEmoji} [defaultReactionEmoji]
+ * The emoji to show in the add reaction button on a thread in a guild forum channel.
+ * @property {ThreadAutoArchiveDuration} [defaultAutoArchiveDuration]
+ * The default auto archive duration for all new threads in this channel
+ * @property {SortOrderType} [defaultSortOrder] The default sort order mode used to order posts (forum only).
+ * @property {ForumLayoutType} [defaultForumLayout] The default layout used to display posts (forum only).
+ * @property {string} [reason] Reason for creating the new channel
+ */
+
+ /**
+ * Creates a new channel within this category.
+ * <info>You cannot create a channel of type {@link ChannelType.GuildCategory} inside a CategoryChannel.</info>
+ * @param {CategoryCreateChannelOptions} options Options for creating the new channel
+ * @returns {Promise<GuildChannel>}
+ */
+ create(options) {
+ return this.guild.channels.create({
+ ...options,
+ parent: this.channel.id,
+ });
+ }
+}
+
+module.exports = CategoryChannelChildManager;
diff --git a/node_modules/discord.js/src/managers/ChannelManager.js b/node_modules/discord.js/src/managers/ChannelManager.js
new file mode 100644
index 0000000..0126d91
--- /dev/null
+++ b/node_modules/discord.js/src/managers/ChannelManager.js
@@ -0,0 +1,128 @@
+'use strict';
+
+const process = require('node:process');
+const { Routes } = require('discord-api-types/v10');
+const CachedManager = require('./CachedManager');
+const { BaseChannel } = require('../structures/BaseChannel');
+const { createChannel } = require('../util/Channels');
+const { ThreadChannelTypes } = require('../util/Constants');
+const Events = require('../util/Events');
+
+let cacheWarningEmitted = false;
+
+/**
+ * A manager of channels belonging to a client
+ * @extends {CachedManager}
+ */
+class ChannelManager extends CachedManager {
+ constructor(client, iterable) {
+ super(client, BaseChannel, iterable);
+ const defaultCaching =
+ this._cache.constructor.name === 'Collection' ||
+ this._cache.maxSize === undefined ||
+ this._cache.maxSize === Infinity;
+ if (!cacheWarningEmitted && !defaultCaching) {
+ cacheWarningEmitted = true;
+ process.emitWarning(
+ `Overriding the cache handling for ${this.constructor.name} is unsupported and breaks functionality.`,
+ 'UnsupportedCacheOverwriteWarning',
+ );
+ }
+ }
+
+ /**
+ * The cache of Channels
+ * @type {Collection<Snowflake, BaseChannel>}
+ * @name ChannelManager#cache
+ */
+
+ _add(data, guild, { cache = true, allowUnknownGuild = false } = {}) {
+ const existing = this.cache.get(data.id);
+ if (existing) {
+ if (cache) existing._patch(data);
+ guild?.channels?._add(existing);
+ if (ThreadChannelTypes.includes(existing.type)) {
+ existing.parent?.threads?._add(existing);
+ }
+ return existing;
+ }
+
+ const channel = createChannel(this.client, data, guild, { allowUnknownGuild });
+
+ if (!channel) {
+ this.client.emit(Events.Debug, `Failed to find guild, or unknown type for channel ${data.id} ${data.type}`);
+ return null;
+ }
+
+ if (cache && !allowUnknownGuild) this.cache.set(channel.id, channel);
+
+ return channel;
+ }
+
+ _remove(id) {
+ const channel = this.cache.get(id);
+ channel?.guild?.channels.cache.delete(id);
+
+ for (const [code, invite] of channel?.guild?.invites.cache ?? []) {
+ if (invite.channelId === id) channel.guild.invites.cache.delete(code);
+ }
+
+ channel?.parent?.threads?.cache.delete(id);
+ this.cache.delete(id);
+ }
+
+ /**
+ * Data that can be resolved to give a Channel object. This can be:
+ * * A Channel object
+ * * A Snowflake
+ * @typedef {BaseChannel|Snowflake} ChannelResolvable
+ */
+
+ /**
+ * Resolves a ChannelResolvable to a Channel object.
+ * @method resolve
+ * @memberof ChannelManager
+ * @instance
+ * @param {ChannelResolvable} channel The channel resolvable to resolve
+ * @returns {?BaseChannel}
+ */
+
+ /**
+ * Resolves a ChannelResolvable to a channel id string.
+ * @method resolveId
+ * @memberof ChannelManager
+ * @instance
+ * @param {ChannelResolvable} channel The channel resolvable to resolve
+ * @returns {?Snowflake}
+ */
+
+ /**
+ * Options for fetching a channel from Discord
+ * @typedef {BaseFetchOptions} FetchChannelOptions
+ * @property {boolean} [allowUnknownGuild=false] Allows the channel to be returned even if the guild is not in cache,
+ * it will not be cached. <warn>Many of the properties and methods on the returned channel will throw errors</warn>
+ */
+
+ /**
+ * Obtains a channel from Discord, or the channel cache if it's already available.
+ * @param {Snowflake} id The channel's id
+ * @param {FetchChannelOptions} [options] Additional options for this fetch
+ * @returns {Promise<?BaseChannel>}
+ * @example
+ * // Fetch a channel by its id
+ * client.channels.fetch('222109930545610754')
+ * .then(channel => console.log(channel.name))
+ * .catch(console.error);
+ */
+ async fetch(id, { allowUnknownGuild = false, cache = true, force = false } = {}) {
+ if (!force) {
+ const existing = this.cache.get(id);
+ if (existing && !existing.partial) return existing;
+ }
+
+ const data = await this.client.rest.get(Routes.channel(id));
+ return this._add(data, null, { cache, allowUnknownGuild });
+ }
+}
+
+module.exports = ChannelManager;
diff --git a/node_modules/discord.js/src/managers/DMMessageManager.js b/node_modules/discord.js/src/managers/DMMessageManager.js
new file mode 100644
index 0000000..f0b3a33
--- /dev/null
+++ b/node_modules/discord.js/src/managers/DMMessageManager.js
@@ -0,0 +1,17 @@
+'use strict';
+
+const MessageManager = require('./MessageManager');
+
+/**
+ * Manages API methods for messages in direct message channels and holds their cache.
+ * @extends {MessageManager}
+ */
+class DMMessageManager extends MessageManager {
+ /**
+ * The channel that the messages belong to
+ * @name DMMessageManager#channel
+ * @type {DMChannel}
+ */
+}
+
+module.exports = DMMessageManager;
diff --git a/node_modules/discord.js/src/managers/DataManager.js b/node_modules/discord.js/src/managers/DataManager.js
new file mode 100644
index 0000000..383844e
--- /dev/null
+++ b/node_modules/discord.js/src/managers/DataManager.js
@@ -0,0 +1,61 @@
+'use strict';
+
+const BaseManager = require('./BaseManager');
+const { DiscordjsError, ErrorCodes } = require('../errors');
+
+/**
+ * Manages the API methods of a data model along with a collection of instances.
+ * @extends {BaseManager}
+ * @abstract
+ */
+class DataManager extends BaseManager {
+ constructor(client, holds) {
+ super(client);
+
+ /**
+ * The data structure belonging to this manager.
+ * @name DataManager#holds
+ * @type {Function}
+ * @private
+ * @readonly
+ */
+ Object.defineProperty(this, 'holds', { value: holds });
+ }
+
+ /**
+ * The cache of items for this manager.
+ * @type {Collection}
+ * @abstract
+ */
+ get cache() {
+ throw new DiscordjsError(ErrorCodes.NotImplemented, 'get cache', this.constructor.name);
+ }
+
+ /**
+ * Resolves a data entry to a data Object.
+ * @param {string|Object} idOrInstance The id or instance of something in this Manager
+ * @returns {?Object} An instance from this Manager
+ */
+ resolve(idOrInstance) {
+ if (idOrInstance instanceof this.holds) return idOrInstance;
+ if (typeof idOrInstance === 'string') return this.cache.get(idOrInstance) ?? null;
+ return null;
+ }
+
+ /**
+ * Resolves a data entry to an instance id.
+ * @param {string|Object} idOrInstance The id or instance of something in this Manager
+ * @returns {?Snowflake}
+ */
+ resolveId(idOrInstance) {
+ if (idOrInstance instanceof this.holds) return idOrInstance.id;
+ if (typeof idOrInstance === 'string') return idOrInstance;
+ return null;
+ }
+
+ valueOf() {
+ return this.cache;
+ }
+}
+
+module.exports = DataManager;
diff --git a/node_modules/discord.js/src/managers/GuildApplicationCommandManager.js b/node_modules/discord.js/src/managers/GuildApplicationCommandManager.js
new file mode 100644
index 0000000..97fea5e
--- /dev/null
+++ b/node_modules/discord.js/src/managers/GuildApplicationCommandManager.js
@@ -0,0 +1,28 @@
+'use strict';
+
+const ApplicationCommandManager = require('./ApplicationCommandManager');
+const ApplicationCommandPermissionsManager = require('./ApplicationCommandPermissionsManager');
+
+/**
+ * An extension for guild-specific application commands.
+ * @extends {ApplicationCommandManager}
+ */
+class GuildApplicationCommandManager extends ApplicationCommandManager {
+ constructor(guild, iterable) {
+ super(guild.client, iterable);
+
+ /**
+ * The guild that this manager belongs to
+ * @type {Guild}
+ */
+ this.guild = guild;
+
+ /**
+ * The manager for permissions of arbitrary commands on this guild
+ * @type {ApplicationCommandPermissionsManager}
+ */
+ this.permissions = new ApplicationCommandPermissionsManager(this);
+ }
+}
+
+module.exports = GuildApplicationCommandManager;
diff --git a/node_modules/discord.js/src/managers/GuildBanManager.js b/node_modules/discord.js/src/managers/GuildBanManager.js
new file mode 100644
index 0000000..d3c8a00
--- /dev/null
+++ b/node_modules/discord.js/src/managers/GuildBanManager.js
@@ -0,0 +1,204 @@
+'use strict';
+
+const process = require('node:process');
+const { Collection } = require('@discordjs/collection');
+const { makeURLSearchParams } = require('@discordjs/rest');
+const { Routes } = require('discord-api-types/v10');
+const CachedManager = require('./CachedManager');
+const { DiscordjsTypeError, DiscordjsError, ErrorCodes } = require('../errors');
+const GuildBan = require('../structures/GuildBan');
+const { GuildMember } = require('../structures/GuildMember');
+
+let deprecationEmittedForDeleteMessageDays = false;
+
+/**
+ * Manages API methods for guild bans and stores their cache.
+ * @extends {CachedManager}
+ */
+class GuildBanManager extends CachedManager {
+ constructor(guild, iterable) {
+ super(guild.client, GuildBan, iterable);
+
+ /**
+ * The guild this Manager belongs to
+ * @type {Guild}
+ */
+ this.guild = guild;
+ }
+
+ /**
+ * The cache of this Manager
+ * @type {Collection<Snowflake, GuildBan>}
+ * @name GuildBanManager#cache
+ */
+
+ _add(data, cache) {
+ return super._add(data, cache, { id: data.user.id, extras: [this.guild] });
+ }
+
+ /**
+ * Data that resolves to give a GuildBan object. This can be:
+ * * A GuildBan object
+ * * A User resolvable
+ * @typedef {GuildBan|UserResolvable} GuildBanResolvable
+ */
+
+ /**
+ * Resolves a GuildBanResolvable to a GuildBan object.
+ * @param {GuildBanResolvable} ban The ban that is in the guild
+ * @returns {?GuildBan}
+ */
+ resolve(ban) {
+ return super.resolve(ban) ?? super.resolve(this.client.users.resolveId(ban));
+ }
+
+ /**
+ * Options used to fetch a single ban from a guild.
+ * @typedef {BaseFetchOptions} FetchBanOptions
+ * @property {UserResolvable} user The ban to fetch
+ */
+
+ /**
+ * Options used to fetch multiple bans from a guild.
+ * @typedef {Object} FetchBansOptions
+ * @property {number} [limit] The maximum number of bans to return
+ * @property {Snowflake} [before] Consider only bans before this id
+ * @property {Snowflake} [after] Consider only bans after this id
+ * @property {boolean} [cache] Whether to cache the fetched bans
+ */
+
+ /**
+ * Fetches ban(s) from Discord.
+ * @param {UserResolvable|FetchBanOptions|FetchBansOptions} [options] Options for fetching guild ban(s)
+ * @returns {Promise<GuildBan|Collection<Snowflake, GuildBan>>}
+ * @example
+ * // Fetch multiple bans from a guild
+ * guild.bans.fetch()
+ * .then(console.log)
+ * .catch(console.error);
+ * @example
+ * // Fetch a maximum of 5 bans from a guild without caching
+ * guild.bans.fetch({ limit: 5, cache: false })
+ * .then(console.log)
+ * .catch(console.error);
+ * @example
+ * // Fetch a single ban
+ * guild.bans.fetch('351871113346809860')
+ * .then(console.log)
+ * .catch(console.error);
+ * @example
+ * // Fetch a single ban without checking cache
+ * guild.bans.fetch({ user, force: true })
+ * .then(console.log)
+ * .catch(console.error)
+ * @example
+ * // Fetch a single ban without caching
+ * guild.bans.fetch({ user, cache: false })
+ * .then(console.log)
+ * .catch(console.error);
+ */
+ fetch(options) {
+ if (!options) return this._fetchMany();
+ const { user, cache, force, limit, before, after } = options;
+ const resolvedUser = this.client.users.resolveId(user ?? options);
+ if (resolvedUser) return this._fetchSingle({ user: resolvedUser, cache, force });
+
+ if (!before && !after && !limit && cache === undefined) {
+ return Promise.reject(new DiscordjsError(ErrorCodes.FetchBanResolveId));
+ }
+
+ return this._fetchMany(options);
+ }
+
+ async _fetchSingle({ user, cache, force = false }) {
+ if (!force) {
+ const existing = this.cache.get(user);
+ if (existing && !existing.partial) return existing;
+ }
+
+ const data = await this.client.rest.get(Routes.guildBan(this.guild.id, user));
+ return this._add(data, cache);
+ }
+
+ async _fetchMany(options = {}) {
+ const data = await this.client.rest.get(Routes.guildBans(this.guild.id), {
+ query: makeURLSearchParams(options),
+ });
+
+ return data.reduce((col, ban) => col.set(ban.user.id, this._add(ban, options.cache)), new Collection());
+ }
+
+ /**
+ * Options used to ban a user from a guild.
+ * @typedef {Object} BanOptions
+ * @property {number} [deleteMessageDays] Number of days of messages to delete, must be between 0 and 7, inclusive
+ * <warn>This property is deprecated. Use `deleteMessageSeconds` instead.</warn>
+ * @property {number} [deleteMessageSeconds] Number of seconds of messages to delete,
+ * must be between 0 and 604800 (7 days), inclusive
+ * @property {string} [reason] The reason for the ban
+ */
+
+ /**
+ * Bans a user from the guild.
+ * @param {UserResolvable} user The user to ban
+ * @param {BanOptions} [options] Options for the ban
+ * @returns {Promise<GuildMember|User|Snowflake>} Result object will be resolved as specifically as possible.
+ * If the GuildMember cannot be resolved, the User will instead be attempted to be resolved. If that also cannot
+ * be resolved, the user id will be the result.
+ * @example
+ * // Ban a user by id (or with a user/guild member object)
+ * guild.bans.create('84484653687267328')
+ * .then(banInfo => console.log(`Banned ${banInfo.user?.tag ?? banInfo.tag ?? banInfo}`))
+ * .catch(console.error);
+ */
+ async create(user, options = {}) {
+ if (typeof options !== 'object') throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'options', 'object', true);
+ const id = this.client.users.resolveId(user);
+ if (!id) throw new DiscordjsError(ErrorCodes.BanResolveId, true);
+
+ if (options.deleteMessageDays !== undefined && !deprecationEmittedForDeleteMessageDays) {
+ process.emitWarning(
+ // eslint-disable-next-line max-len
+ 'The deleteMessageDays option for GuildBanManager#create() is deprecated. Use the deleteMessageSeconds option instead.',
+ 'DeprecationWarning',
+ );
+
+ deprecationEmittedForDeleteMessageDays = true;
+ }
+
+ await this.client.rest.put(Routes.guildBan(this.guild.id, id), {
+ body: {
+ delete_message_seconds:
+ options.deleteMessageSeconds ??
+ (options.deleteMessageDays ? options.deleteMessageDays * 24 * 60 * 60 : undefined),
+ },
+ reason: options.reason,
+ });
+ if (user instanceof GuildMember) return user;
+ const _user = this.client.users.resolve(id);
+ if (_user) {
+ return this.guild.members.resolve(_user) ?? _user;
+ }
+ return id;
+ }
+
+ /**
+ * Unbans a user from the guild.
+ * @param {UserResolvable} user The user to unban
+ * @param {string} [reason] Reason for unbanning user
+ * @returns {Promise<?User>}
+ * @example
+ * // Unban a user by id (or with a user/guild member object)
+ * guild.bans.remove('84484653687267328')
+ * .then(user => console.log(`Unbanned ${user.username} from ${guild.name}`))
+ * .catch(console.error);
+ */
+ async remove(user, reason) {
+ const id = this.client.users.resolveId(user);
+ if (!id) throw new DiscordjsError(ErrorCodes.BanResolveId);
+ await this.client.rest.delete(Routes.guildBan(this.guild.id, id), { reason });
+ return this.client.users.resolve(user);
+ }
+}
+
+module.exports = GuildBanManager;
diff --git a/node_modules/discord.js/src/managers/GuildChannelManager.js b/node_modules/discord.js/src/managers/GuildChannelManager.js
new file mode 100644
index 0000000..7ca9287
--- /dev/null
+++ b/node_modules/discord.js/src/managers/GuildChannelManager.js
@@ -0,0 +1,503 @@
+'use strict';
+
+const process = require('node:process');
+const { Collection } = require('@discordjs/collection');
+const { ChannelType, Routes } = require('discord-api-types/v10');
+const CachedManager = require('./CachedManager');
+const GuildTextThreadManager = require('./GuildTextThreadManager');
+const { DiscordjsError, DiscordjsTypeError, ErrorCodes } = require('../errors');
+const GuildChannel = require('../structures/GuildChannel');
+const PermissionOverwrites = require('../structures/PermissionOverwrites');
+const ThreadChannel = require('../structures/ThreadChannel');
+const Webhook = require('../structures/Webhook');
+const ChannelFlagsBitField = require('../util/ChannelFlagsBitField');
+const { transformGuildForumTag, transformGuildDefaultReaction } = require('../util/Channels');
+const { ThreadChannelTypes } = require('../util/Constants');
+const DataResolver = require('../util/DataResolver');
+const { setPosition } = require('../util/Util');
+
+let cacheWarningEmitted = false;
+
+/**
+ * Manages API methods for GuildChannels and stores their cache.
+ * @extends {CachedManager}
+ */
+class GuildChannelManager extends CachedManager {
+ constructor(guild, iterable) {
+ super(guild.client, GuildChannel, iterable);
+ const defaultCaching =
+ this._cache.constructor.name === 'Collection' ||
+ this._cache.maxSize === undefined ||
+ this._cache.maxSize === Infinity;
+ if (!cacheWarningEmitted && !defaultCaching) {
+ cacheWarningEmitted = true;
+ process.emitWarning(
+ `Overriding the cache handling for ${this.constructor.name} is unsupported and breaks functionality.`,
+ 'UnsupportedCacheOverwriteWarning',
+ );
+ }
+
+ /**
+ * The guild this Manager belongs to
+ * @type {Guild}
+ */
+ this.guild = guild;
+ }
+
+ /**
+ * The number of channels in this managers cache excluding thread channels
+ * that do not count towards a guild's maximum channels restriction.
+ * @type {number}
+ * @readonly
+ */
+ get channelCountWithoutThreads() {
+ return this.cache.reduce((acc, channel) => {
+ if (ThreadChannelTypes.includes(channel.type)) return acc;
+ return ++acc;
+ }, 0);
+ }
+
+ /**
+ * The cache of this Manager
+ * @type {Collection<Snowflake, GuildChannel|ThreadChannel>}
+ * @name GuildChannelManager#cache
+ */
+
+ _add(channel) {
+ const existing = this.cache.get(channel.id);
+ if (existing) return existing;
+ this.cache.set(channel.id, channel);
+ return channel;
+ }
+
+ /**
+ * Data that can be resolved to give a Guild Channel object. This can be:
+ * * A GuildChannel object
+ * * A ThreadChannel object
+ * * A Snowflake
+ * @typedef {GuildChannel|ThreadChannel|Snowflake} GuildChannelResolvable
+ */
+
+ /**
+ * Resolves a GuildChannelResolvable to a Channel object.
+ * @param {GuildChannelResolvable} channel The GuildChannel resolvable to resolve
+ * @returns {?(GuildChannel|ThreadChannel)}
+ */
+ resolve(channel) {
+ if (channel instanceof ThreadChannel) return super.resolve(channel.id);
+ return super.resolve(channel);
+ }
+
+ /**
+ * Resolves a GuildChannelResolvable to a channel id.
+ * @param {GuildChannelResolvable} channel The GuildChannel resolvable to resolve
+ * @returns {?Snowflake}
+ */
+ resolveId(channel) {
+ if (channel instanceof ThreadChannel) return super.resolveId(channel.id);
+ return super.resolveId(channel);
+ }
+
+ /**
+ * Adds the target channel to a channel's followers.
+ * @param {NewsChannel|Snowflake} channel The channel to follow
+ * @param {TextChannelResolvable} targetChannel The channel where published announcements will be posted at
+ * @param {string} [reason] Reason for creating the webhook
+ * @returns {Promise<Snowflake>} Returns created target webhook id.
+ */
+ async addFollower(channel, targetChannel, reason) {
+ const channelId = this.resolveId(channel);
+ const targetChannelId = this.resolveId(targetChannel);
+ if (!channelId || !targetChannelId) throw new Error(ErrorCodes.GuildChannelResolve);
+ const { webhook_id } = await this.client.rest.post(Routes.channelFollowers(channelId), {
+ body: { webhook_channel_id: targetChannelId },
+ reason,
+ });
+ return webhook_id;
+ }
+
+ /**
+ * Options used to create a new channel in a guild.
+ * @typedef {CategoryCreateChannelOptions} GuildChannelCreateOptions
+ * @property {?CategoryChannelResolvable} [parent] Parent of the new channel
+ */
+
+ /**
+ * Creates a new channel in the guild.
+ * @param {GuildChannelCreateOptions} options Options for creating the new channel
+ * @returns {Promise<GuildChannel>}
+ * @example
+ * // Create a new text channel
+ * guild.channels.create({ name: 'new-general', reason: 'Needed a cool new channel' })
+ * .then(console.log)
+ * .catch(console.error);
+ * @example
+ * // Create a new channel with permission overwrites
+ * guild.channels.create({
+ * name: 'new-general',
+ * type: ChannelType.GuildVoice,
+ * permissionOverwrites: [
+ * {
+ * id: message.author.id,
+ * deny: [PermissionFlagsBits.ViewChannel],
+ * },
+ * ],
+ * })
+ */
+ async create({
+ name,
+ type,
+ topic,
+ nsfw,
+ bitrate,
+ userLimit,
+ parent,
+ permissionOverwrites,
+ position,
+ rateLimitPerUser,
+ rtcRegion,
+ videoQualityMode,
+ availableTags,
+ defaultReactionEmoji,
+ defaultAutoArchiveDuration,
+ defaultSortOrder,
+ defaultForumLayout,
+ reason,
+ }) {
+ parent &&= this.client.channels.resolveId(parent);
+ permissionOverwrites &&= permissionOverwrites.map(o => PermissionOverwrites.resolve(o, this.guild));
+
+ const data = await this.client.rest.post(Routes.guildChannels(this.guild.id), {
+ body: {
+ name,
+ topic,
+ type,
+ nsfw,
+ bitrate,
+ user_limit: userLimit,
+ parent_id: parent,
+ position,
+ permission_overwrites: permissionOverwrites,
+ rate_limit_per_user: rateLimitPerUser,
+ rtc_region: rtcRegion,
+ video_quality_mode: videoQualityMode,
+ available_tags: availableTags?.map(availableTag => transformGuildForumTag(availableTag)),
+ default_reaction_emoji: defaultReactionEmoji && transformGuildDefaultReaction(defaultReactionEmoji),
+ default_auto_archive_duration: defaultAutoArchiveDuration,
+ default_sort_order: defaultSortOrder,
+ default_forum_layout: defaultForumLayout,
+ },
+ reason,
+ });
+ return this.client.actions.ChannelCreate.handle(data).channel;
+ }
+
+ /**
+ * @typedef {ChannelWebhookCreateOptions} WebhookCreateOptions
+ * @property {TextChannel|NewsChannel|VoiceChannel|StageChannel|ForumChannel|Snowflake} channel
+ * The channel to create the webhook for
+ */
+
+ /**
+ * Creates a webhook for the channel.
+ * @param {WebhookCreateOptions} options Options for creating the webhook
+ * @returns {Promise<Webhook>} Returns the created Webhook
+ * @example
+ * // Create a webhook for the current channel
+ * guild.channels.createWebhook({
+ * channel: '222197033908436994',
+ * name: 'Snek',
+ * avatar: 'https://i.imgur.com/mI8XcpG.jpg',
+ * reason: 'Needed a cool new Webhook'
+ * })
+ * .then(console.log)
+ * .catch(console.error)
+ */
+ async createWebhook({ channel, name, avatar, reason }) {
+ const id = this.resolveId(channel);
+ if (!id) throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'channel', 'GuildChannelResolvable');
+ if (typeof avatar === 'string' && !avatar.startsWith('data:')) {
+ avatar = await DataResolver.resolveImage(avatar);
+ }
+ const data = await this.client.rest.post(Routes.channelWebhooks(id), {
+ body: {
+ name,
+ avatar,
+ },
+ reason,
+ });
+ return new Webhook(this.client, data);
+ }
+
+ /**
+ * Options used to edit a guild channel.
+ * @typedef {Object} GuildChannelEditOptions
+ * @property {string} [name] The name of the channel
+ * @property {ChannelType} [type] The type of the channel (only conversion between text and news is supported)
+ * @property {number} [position] The position of the channel
+ * @property {?string} [topic] The topic of the text channel
+ * @property {boolean} [nsfw] Whether the channel is NSFW
+ * @property {number} [bitrate] The bitrate of the voice channel
+ * @property {number} [userLimit] The user limit of the voice channel
+ * @property {?CategoryChannelResolvable} [parent] The parent of the channel
+ * @property {boolean} [lockPermissions]
+ * Lock the permissions of the channel to what the parent's permissions are
+ * @property {OverwriteResolvable[]|Collection<Snowflake, OverwriteResolvable>} [permissionOverwrites]
+ * Permission overwrites for the channel
+ * @property {number} [rateLimitPerUser] The rate limit per user (slowmode) for the channel in seconds
+ * @property {ThreadAutoArchiveDuration} [defaultAutoArchiveDuration]
+ * The default auto archive duration for all new threads in this channel
+ * @property {?string} [rtcRegion] The RTC region of the channel
+ * @property {?VideoQualityMode} [videoQualityMode] The camera video quality mode of the channel
+ * @property {GuildForumTagData[]} [availableTags] The tags to set as available in a forum channel
+ * @property {?DefaultReactionEmoji} [defaultReactionEmoji] The emoji to set as the default reaction emoji
+ * @property {number} [defaultThreadRateLimitPerUser] The rate limit per user (slowmode) to set on forum posts
+ * @property {ChannelFlagsResolvable} [flags] The flags to set on the channel
+ * @property {?SortOrderType} [defaultSortOrder] The default sort order mode to set on the channel
+ * @property {ForumLayoutType} [defaultForumLayout] The default forum layout to set on the channel
+ * @property {string} [reason] Reason for editing this channel
+ */
+
+ /**
+ * Edits the channel.
+ * @param {GuildChannelResolvable} channel The channel to edit
+ * @param {GuildChannelEditOptions} options Options for editing the channel
+ * @returns {Promise<GuildChannel>}
+ * @example
+ * // Edit a channel
+ * guild.channels.edit('222197033908436994', { name: 'new-channel' })
+ * .then(console.log)
+ * .catch(console.error);
+ */
+ async edit(channel, options) {
+ channel = this.resolve(channel);
+ if (!channel) throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'channel', 'GuildChannelResolvable');
+
+ const parent = options.parent && this.client.channels.resolveId(options.parent);
+
+ if (options.position !== undefined) {
+ await this.setPosition(channel, options.position, { position: options.position, reason: options.reason });
+ }
+
+ let permission_overwrites = options.permissionOverwrites?.map(o => PermissionOverwrites.resolve(o, this.guild));
+
+ if (options.lockPermissions) {
+ if (parent) {
+ const newParent = this.guild.channels.resolve(parent);
+ if (newParent?.type === ChannelType.GuildCategory) {
+ permission_overwrites = newParent.permissionOverwrites.cache.map(o =>
+ PermissionOverwrites.resolve(o, this.guild),
+ );
+ }
+ } else if (channel.parent) {
+ permission_overwrites = channel.parent.permissionOverwrites.cache.map(o =>
+ PermissionOverwrites.resolve(o, this.guild),
+ );
+ }
+ }
+
+ const newData = await this.client.rest.patch(Routes.channel(channel.id), {
+ body: {
+ name: (options.name ?? channel.name).trim(),
+ type: options.type,
+ topic: options.topic,
+ nsfw: options.nsfw,
+ bitrate: options.bitrate ?? channel.bitrate,
+ user_limit: options.userLimit ?? channel.userLimit,
+ rtc_region: 'rtcRegion' in options ? options.rtcRegion : channel.rtcRegion,
+ video_quality_mode: options.videoQualityMode,
+ parent_id: parent,
+ lock_permissions: options.lockPermissions,
+ rate_limit_per_user: options.rateLimitPerUser,
+ default_auto_archive_duration: options.defaultAutoArchiveDuration,
+ permission_overwrites,
+ available_tags: options.availableTags?.map(availableTag => transformGuildForumTag(availableTag)),
+ default_reaction_emoji:
+ options.defaultReactionEmoji && transformGuildDefaultReaction(options.defaultReactionEmoji),
+ default_thread_rate_limit_per_user: options.defaultThreadRateLimitPerUser,
+ flags: 'flags' in options ? ChannelFlagsBitField.resolve(options.flags) : undefined,
+ default_sort_order: options.defaultSortOrder,
+ default_forum_layout: options.defaultForumLayout,
+ },
+ reason: options.reason,
+ });
+
+ return this.client.actions.ChannelUpdate.handle(newData).updated;
+ }
+
+ /**
+ * Sets a new position for the guild channel.
+ * @param {GuildChannelResolvable} channel The channel to set the position for
+ * @param {number} position The new position for the guild channel
+ * @param {SetChannelPositionOptions} options Options for setting position
+ * @returns {Promise<GuildChannel>}
+ * @example
+ * // Set a new channel position
+ * guild.channels.setPosition('222078374472843266', 2)
+ * .then(newChannel => console.log(`Channel's new position is ${newChannel.position}`))
+ * .catch(console.error);
+ */
+ async setPosition(channel, position, { relative, reason } = {}) {
+ channel = this.resolve(channel);
+ if (!channel) throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'channel', 'GuildChannelResolvable');
+ const updatedChannels = await setPosition(
+ channel,
+ position,
+ relative,
+ this.guild._sortedChannels(channel),
+ this.client,
+ Routes.guildChannels(this.guild.id),
+ reason,
+ );
+
+ this.client.actions.GuildChannelsPositionUpdate.handle({
+ guild_id: this.guild.id,
+ channels: updatedChannels,
+ });
+ return channel;
+ }
+
+ /**
+ * Obtains one or more guild channels from Discord, or the channel cache if they're already available.
+ * @param {Snowflake} [id] The channel's id
+ * @param {BaseFetchOptions} [options] Additional options for this fetch
+ * @returns {Promise<?GuildChannel|ThreadChannel|Collection<Snowflake, ?GuildChannel>>}
+ * @example
+ * // Fetch all channels from the guild (excluding threads)
+ * message.guild.channels.fetch()
+ * .then(channels => console.log(`There are ${channels.size} channels.`))
+ * .catch(console.error);
+ * @example
+ * // Fetch a single channel
+ * message.guild.channels.fetch('222197033908436994')
+ * .then(channel => console.log(`The channel name is: ${channel.name}`))
+ * .catch(console.error);
+ */
+ async fetch(id, { cache = true, force = false } = {}) {
+ if (id && !force) {
+ const existing = this.cache.get(id);
+ if (existing) return existing;
+ }
+
+ if (id) {
+ const data = await this.client.rest.get(Routes.channel(id));
+ // Since this is the guild manager, throw if on a different guild
+ if (this.guild.id !== data.guild_id) throw new DiscordjsError(ErrorCodes.GuildChannelUnowned);
+ return this.client.channels._add(data, this.guild, { cache });
+ }
+
+ const data = await this.client.rest.get(Routes.guildChannels(this.guild.id));
+ const channels = new Collection();
+ for (const channel of data) channels.set(channel.id, this.client.channels._add(channel, this.guild, { cache }));
+ return channels;
+ }
+
+ /**
+ * Fetches all webhooks for the channel.
+ * @param {GuildChannelResolvable} channel The channel to fetch webhooks for
+ * @returns {Promise<Collection<Snowflake, Webhook>>}
+ * @example
+ * // Fetch webhooks
+ * guild.channels.fetchWebhooks('769862166131245066')
+ * .then(hooks => console.log(`This channel has ${hooks.size} hooks`))
+ * .catch(console.error);
+ */
+ async fetchWebhooks(channel) {
+ const id = this.resolveId(channel);
+ if (!id) throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'channel', 'GuildChannelResolvable');
+ const data = await this.client.rest.get(Routes.channelWebhooks(id));
+ return data.reduce((hooks, hook) => hooks.set(hook.id, new Webhook(this.client, hook)), new Collection());
+ }
+
+ /**
+ * Data that can be resolved to give a Category Channel object. This can be:
+ * * A CategoryChannel object
+ * * A Snowflake
+ * @typedef {CategoryChannel|Snowflake} CategoryChannelResolvable
+ */
+
+ /**
+ * The data needed for updating a channel's position.
+ * @typedef {Object} ChannelPosition
+ * @property {GuildChannel|Snowflake} channel Channel to update
+ * @property {number} [position] New position for the channel
+ * @property {CategoryChannelResolvable} [parent] Parent channel for this channel
+ * @property {boolean} [lockPermissions] If the overwrites should be locked to the parents overwrites
+ */
+
+ /**
+ * Batch-updates the guild's channels' positions.
+ * <info>Only one channel's parent can be changed at a time</info>
+ * @param {ChannelPosition[]} channelPositions Channel positions to update
+ * @returns {Promise<Guild>}
+ * @example
+ * guild.channels.setPositions([{ channel: channelId, position: newChannelIndex }])
+ * .then(guild => console.log(`Updated channel positions for ${guild}`))
+ * .catch(console.error);
+ */
+ async setPositions(channelPositions) {
+ channelPositions = channelPositions.map(r => ({
+ id: this.client.channels.resolveId(r.channel),
+ position: r.position,
+ lock_permissions: r.lockPermissions,
+ parent_id: r.parent !== undefined ? this.resolveId(r.parent) : undefined,
+ }));
+
+ await this.client.rest.patch(Routes.guildChannels(this.guild.id), { body: channelPositions });
+ return this.client.actions.GuildChannelsPositionUpdate.handle({
+ guild_id: this.guild.id,
+ channels: channelPositions,
+ }).guild;
+ }
+
+ /**
+ * Data returned from fetching threads.
+ * @typedef {Object} FetchedThreads
+ * @property {Collection<Snowflake, ThreadChannel>} threads The threads that were fetched
+ * @property {Collection<Snowflake, ThreadMember>} members The thread members in the received threads
+ */
+
+ /**
+ * Obtains all active thread channels in the guild.
+ * @param {boolean} [cache=true] Whether to cache the fetched data
+ * @returns {Promise<FetchedThreads>}
+ * @example
+ * // Fetch all threads from the guild
+ * message.guild.channels.fetchActiveThreads()
+ * .then(fetched => console.log(`There are ${fetched.threads.size} threads.`))
+ * .catch(console.error);
+ */
+ async fetchActiveThreads(cache = true) {
+ const data = await this.rawFetchGuildActiveThreads();
+ return GuildTextThreadManager._mapThreads(data, this.client, { guild: this.guild, cache });
+ }
+
+ /**
+ * `GET /guilds/{guild.id}/threads/active`
+ * @private
+ * @returns {Promise<RESTGetAPIGuildThreadsResult>}
+ */
+ rawFetchGuildActiveThreads() {
+ return this.client.rest.get(Routes.guildActiveThreads(this.guild.id));
+ }
+
+ /**
+ * Deletes the channel.
+ * @param {GuildChannelResolvable} channel The channel to delete
+ * @param {string} [reason] Reason for deleting this channel
+ * @returns {Promise<void>}
+ * @example
+ * // Delete the channel
+ * guild.channels.delete('858850993013260338', 'making room for new channels')
+ * .then(console.log)
+ * .catch(console.error);
+ */
+ async delete(channel, reason) {
+ const id = this.resolveId(channel);
+ if (!id) throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'channel', 'GuildChannelResolvable');
+ await this.client.rest.delete(Routes.channel(id), { reason });
+ this.client.actions.ChannelDelete.handle({ id });
+ }
+}
+
+module.exports = GuildChannelManager;
diff --git a/node_modules/discord.js/src/managers/GuildEmojiManager.js b/node_modules/discord.js/src/managers/GuildEmojiManager.js
new file mode 100644
index 0000000..61f5050
--- /dev/null
+++ b/node_modules/discord.js/src/managers/GuildEmojiManager.js
@@ -0,0 +1,174 @@
+'use strict';
+
+const { Collection } = require('@discordjs/collection');
+const { Routes, PermissionFlagsBits } = require('discord-api-types/v10');
+const BaseGuildEmojiManager = require('./BaseGuildEmojiManager');
+const { DiscordjsError, DiscordjsTypeError, ErrorCodes } = require('../errors');
+const DataResolver = require('../util/DataResolver');
+
+/**
+ * Manages API methods for GuildEmojis and stores their cache.
+ * @extends {BaseGuildEmojiManager}
+ */
+class GuildEmojiManager extends BaseGuildEmojiManager {
+ constructor(guild, iterable) {
+ super(guild.client, iterable);
+
+ /**
+ * The guild this manager belongs to
+ * @type {Guild}
+ */
+ this.guild = guild;
+ }
+
+ _add(data, cache) {
+ return super._add(data, cache, { extras: [this.guild] });
+ }
+
+ /**
+ * Options used for creating an emoji in a guild.
+ * @typedef {Object} GuildEmojiCreateOptions
+ * @property {BufferResolvable|Base64Resolvable} attachment The image for the emoji
+ * @property {string} name The name for the emoji
+ * @property {Collection<Snowflake, Role>|RoleResolvable[]} [roles] The roles to limit the emoji to
+ * @property {string} [reason] The reason for creating the emoji
+ */
+
+ /**
+ * Creates a new custom emoji in the guild.
+ * @param {GuildEmojiCreateOptions} options Options for creating the emoji
+ * @returns {Promise<Emoji>} The created emoji
+ * @example
+ * // Create a new emoji from a URL
+ * guild.emojis.create({ attachment: 'https://i.imgur.com/w3duR07.png', name: 'rip' })
+ * .then(emoji => console.log(`Created new emoji with name ${emoji.name}!`))
+ * .catch(console.error);
+ * @example
+ * // Create a new emoji from a file on your computer
+ * guild.emojis.create({ attachment: './memes/banana.png', name: 'banana' })
+ * .then(emoji => console.log(`Created new emoji with name ${emoji.name}!`))
+ * .catch(console.error);
+ */
+ async create({ attachment, name, roles, reason }) {
+ attachment = await DataResolver.resolveImage(attachment);
+ if (!attachment) throw new DiscordjsTypeError(ErrorCodes.ReqResourceType);
+
+ const body = { image: attachment, name };
+ if (roles) {
+ if (!Array.isArray(roles) && !(roles instanceof Collection)) {
+ throw new DiscordjsTypeError(
+ ErrorCodes.InvalidType,
+ 'options.roles',
+ 'Array or Collection of Roles or Snowflakes',
+ true,
+ );
+ }
+ body.roles = [];
+ for (const role of roles.values()) {
+ const resolvedRole = this.guild.roles.resolveId(role);
+ if (!resolvedRole) {
+ throw new DiscordjsTypeError(ErrorCodes.InvalidElement, 'Array or Collection', 'options.roles', role);
+ }
+ body.roles.push(resolvedRole);
+ }
+ }
+
+ const emoji = await this.client.rest.post(Routes.guildEmojis(this.guild.id), { body, reason });
+ return this.client.actions.GuildEmojiCreate.handle(this.guild, emoji).emoji;
+ }
+
+ /**
+ * Obtains one or more emojis from Discord, or the emoji cache if they're already available.
+ * @param {Snowflake} [id] The emoji's id
+ * @param {BaseFetchOptions} [options] Additional options for this fetch
+ * @returns {Promise<GuildEmoji|Collection<Snowflake, GuildEmoji>>}
+ * @example
+ * // Fetch all emojis from the guild
+ * message.guild.emojis.fetch()
+ * .then(emojis => console.log(`There are ${emojis.size} emojis.`))
+ * .catch(console.error);
+ * @example
+ * // Fetch a single emoji
+ * message.guild.emojis.fetch('222078108977594368')
+ * .then(emoji => console.log(`The emoji name is: ${emoji.name}`))
+ * .catch(console.error);
+ */
+ async fetch(id, { cache = true, force = false } = {}) {
+ if (id) {
+ if (!force) {
+ const existing = this.cache.get(id);
+ if (existing) return existing;
+ }
+ const emoji = await this.client.rest.get(Routes.guildEmoji(this.guild.id, id));
+ return this._add(emoji, cache);
+ }
+
+ const data = await this.client.rest.get(Routes.guildEmojis(this.guild.id));
+ const emojis = new Collection();
+ for (const emoji of data) emojis.set(emoji.id, this._add(emoji, cache));
+ return emojis;
+ }
+
+ /**
+ * Deletes an emoji.
+ * @param {EmojiResolvable} emoji The Emoji resolvable to delete
+ * @param {string} [reason] Reason for deleting the emoji
+ * @returns {Promise<void>}
+ */
+ async delete(emoji, reason) {
+ const id = this.resolveId(emoji);
+ if (!id) throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'emoji', 'EmojiResolvable', true);
+ await this.client.rest.delete(Routes.guildEmoji(this.guild.id, id), { reason });
+ }
+
+ /**
+ * Edits an emoji.
+ * @param {EmojiResolvable} emoji The Emoji resolvable to edit
+ * @param {GuildEmojiEditOptions} options The options to provide
+ * @returns {Promise<GuildEmoji>}
+ */
+ async edit(emoji, options) {
+ const id = this.resolveId(emoji);
+ if (!id) throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'emoji', 'EmojiResolvable', true);
+ const roles = options.roles?.map(r => this.guild.roles.resolveId(r));
+ const newData = await this.client.rest.patch(Routes.guildEmoji(this.guild.id, id), {
+ body: {
+ name: options.name,
+ roles,
+ },
+ reason: options.reason,
+ });
+ const existing = this.cache.get(id);
+ if (existing) {
+ const clone = existing._clone();
+ clone._patch(newData);
+ return clone;
+ }
+ return this._add(newData);
+ }
+
+ /**
+ * Fetches the author for this emoji
+ * @param {EmojiResolvable} emoji The emoji to fetch the author of
+ * @returns {Promise<User>}
+ */
+ async fetchAuthor(emoji) {
+ emoji = this.resolve(emoji);
+ if (!emoji) throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'emoji', 'EmojiResolvable', true);
+ if (emoji.managed) {
+ throw new DiscordjsError(ErrorCodes.EmojiManaged);
+ }
+
+ const { me } = this.guild.members;
+ if (!me) throw new DiscordjsError(ErrorCodes.GuildUncachedMe);
+ if (!me.permissions.has(PermissionFlagsBits.ManageGuildExpressions)) {
+ throw new DiscordjsError(ErrorCodes.MissingManageGuildExpressionsPermission, this.guild);
+ }
+
+ const data = await this.client.rest.get(Routes.guildEmoji(this.guild.id, emoji.id));
+ emoji._patch(data);
+ return emoji.author;
+ }
+}
+
+module.exports = GuildEmojiManager;
diff --git a/node_modules/discord.js/src/managers/GuildEmojiRoleManager.js b/node_modules/discord.js/src/managers/GuildEmojiRoleManager.js
new file mode 100644
index 0000000..7b97f41
--- /dev/null
+++ b/node_modules/discord.js/src/managers/GuildEmojiRoleManager.js
@@ -0,0 +1,118 @@
+'use strict';
+
+const { Collection } = require('@discordjs/collection');
+const DataManager = require('./DataManager');
+const { DiscordjsTypeError, ErrorCodes } = require('../errors');
+const { Role } = require('../structures/Role');
+
+/**
+ * Manages API methods for roles belonging to emojis and stores their cache.
+ * @extends {DataManager}
+ */
+class GuildEmojiRoleManager extends DataManager {
+ constructor(emoji) {
+ super(emoji.client, Role);
+
+ /**
+ * The emoji belonging to this manager
+ * @type {GuildEmoji}
+ */
+ this.emoji = emoji;
+ /**
+ * The guild belonging to this manager
+ * @type {Guild}
+ */
+ this.guild = emoji.guild;
+ }
+
+ /**
+ * The cache of roles belonging to this emoji
+ * @type {Collection<Snowflake, Role>}
+ * @readonly
+ */
+ get cache() {
+ return this.guild.roles.cache.filter(role => this.emoji._roles.includes(role.id));
+ }
+
+ /**
+ * Adds a role (or multiple roles) to the list of roles that can use this emoji.
+ * @param {RoleResolvable|RoleResolvable[]|Collection<Snowflake, Role>} roleOrRoles The role or roles to add
+ * @returns {Promise<GuildEmoji>}
+ */
+ add(roleOrRoles) {
+ if (!Array.isArray(roleOrRoles) && !(roleOrRoles instanceof Collection)) roleOrRoles = [roleOrRoles];
+
+ const resolvedRoles = [];
+ for (const role of roleOrRoles.values()) {
+ const resolvedRole = this.guild.roles.resolveId(role);
+ if (!resolvedRole) {
+ return Promise.reject(new DiscordjsTypeError(ErrorCodes.InvalidElement, 'Array or Collection', 'roles', role));
+ }
+ resolvedRoles.push(resolvedRole);
+ }
+
+ const newRoles = [...new Set(resolvedRoles.concat(...this.cache.keys()))];
+ return this.set(newRoles);
+ }
+
+ /**
+ * Removes a role (or multiple roles) from the list of roles that can use this emoji.
+ * @param {RoleResolvable|RoleResolvable[]|Collection<Snowflake, Role>} roleOrRoles The role or roles to remove
+ * @returns {Promise<GuildEmoji>}
+ */
+ remove(roleOrRoles) {
+ if (!Array.isArray(roleOrRoles) && !(roleOrRoles instanceof Collection)) roleOrRoles = [roleOrRoles];
+
+ const resolvedRoleIds = [];
+ for (const role of roleOrRoles.values()) {
+ const roleId = this.guild.roles.resolveId(role);
+ if (!roleId) {
+ return Promise.reject(new DiscordjsTypeError(ErrorCodes.InvalidElement, 'Array or Collection', 'roles', role));
+ }
+ resolvedRoleIds.push(roleId);
+ }
+
+ const newRoles = [...this.cache.keys()].filter(id => !resolvedRoleIds.includes(id));
+ return this.set(newRoles);
+ }
+
+ /**
+ * Sets the role(s) that can use this emoji.
+ * @param {Collection<Snowflake, Role>|RoleResolvable[]} roles The roles or role ids to apply
+ * @returns {Promise<GuildEmoji>}
+ * @example
+ * // Set the emoji's roles to a single role
+ * guildEmoji.roles.set(['391156570408615936'])
+ * .then(console.log)
+ * .catch(console.error);
+ * @example
+ * // Remove all roles from an emoji
+ * guildEmoji.roles.set([])
+ * .then(console.log)
+ * .catch(console.error);
+ */
+ set(roles) {
+ return this.emoji.edit({ roles });
+ }
+
+ clone() {
+ const clone = new this.constructor(this.emoji);
+ clone._patch([...this.cache.keys()]);
+ return clone;
+ }
+
+ /**
+ * Patches the roles for this manager's cache
+ * @param {Snowflake[]} roles The new roles
+ * @private
+ */
+ _patch(roles) {
+ this.emoji._roles = roles;
+ }
+
+ valueOf() {
+ return this.cache;
+ }
+}
+
+module.exports = GuildEmojiRoleManager;
diff --git a/node_modules/discord.js/src/managers/GuildForumThreadManager.js b/node_modules/discord.js/src/managers/GuildForumThreadManager.js
new file mode 100644
index 0000000..f830b98
--- /dev/null
+++ b/node_modules/discord.js/src/managers/GuildForumThreadManager.js
@@ -0,0 +1,83 @@
+'use strict';
+
+const { Routes } = require('discord-api-types/v10');
+const ThreadManager = require('./ThreadManager');
+const { DiscordjsTypeError, ErrorCodes } = require('../errors');
+const MessagePayload = require('../structures/MessagePayload');
+
+/**
+ * Manages API methods for threads in forum channels and stores their cache.
+ * @extends {ThreadManager}
+ */
+class GuildForumThreadManager extends ThreadManager {
+ /**
+ * The channel this Manager belongs to
+ * @name GuildForumThreadManager#channel
+ * @type {ForumChannel}
+ */
+
+ /**
+ * @typedef {BaseMessageOptions} GuildForumThreadMessageCreateOptions
+ * @property {StickerResolvable} [stickers] The stickers to send with the message
+ * @property {BitFieldResolvable} [flags] The flags to send with the message
+ * <info>Only `MessageFlags.SuppressEmbeds` and `MessageFlags.SuppressNotifications` can be set.</info>
+ */
+
+ /**
+ * Options for creating a thread.
+ * @typedef {StartThreadOptions} GuildForumThreadCreateOptions
+ * @property {GuildForumThreadMessageCreateOptions|MessagePayload} message The message associated with the thread post
+ * @property {Snowflake[]} [appliedTags] The tags to apply to the thread
+ */
+
+ /**
+ * Creates a new thread in the channel.
+ * @param {GuildForumThreadCreateOptions} [options] Options to create a new thread
+ * @returns {Promise<ThreadChannel>}
+ * @example
+ * // Create a new forum post
+ * forum.threads
+ * .create({
+ * name: 'Food Talk',
+ * autoArchiveDuration: ThreadAutoArchiveDuration.OneHour,
+ * message: {
+ * content: 'Discuss your favorite food!',
+ * },
+ * reason: 'Needed a separate thread for food',
+ * })
+ * .then(threadChannel => console.log(threadChannel))
+ * .catch(console.error);
+ */
+ async create({
+ name,
+ autoArchiveDuration = this.channel.defaultAutoArchiveDuration,
+ message,
+ reason,
+ rateLimitPerUser,
+ appliedTags,
+ } = {}) {
+ if (!message) {
+ throw new DiscordjsTypeError(ErrorCodes.GuildForumMessageRequired);
+ }
+
+ const { body, files } = await (message instanceof MessagePayload ? message : MessagePayload.create(this, message))
+ .resolveBody()
+ .resolveFiles();
+
+ const data = await this.client.rest.post(Routes.threads(this.channel.id), {
+ body: {
+ name,
+ auto_archive_duration: autoArchiveDuration,
+ rate_limit_per_user: rateLimitPerUser,
+ applied_tags: appliedTags,
+ message: body,
+ },
+ files,
+ reason,
+ });
+
+ return this.client.actions.ThreadCreate.handle(data).thread;
+ }
+}
+
+module.exports = GuildForumThreadManager;
diff --git a/node_modules/discord.js/src/managers/GuildInviteManager.js b/node_modules/discord.js/src/managers/GuildInviteManager.js
new file mode 100644
index 0000000..f1fe3eb
--- /dev/null
+++ b/node_modules/discord.js/src/managers/GuildInviteManager.js
@@ -0,0 +1,214 @@
+'use strict';
+
+const { Collection } = require('@discordjs/collection');
+const { Routes } = require('discord-api-types/v10');
+const CachedManager = require('./CachedManager');
+const { DiscordjsError, ErrorCodes } = require('../errors');
+const Invite = require('../structures/Invite');
+const DataResolver = require('../util/DataResolver');
+
+/**
+ * Manages API methods for GuildInvites and stores their cache.
+ * @extends {CachedManager}
+ */
+class GuildInviteManager extends CachedManager {
+ constructor(guild, iterable) {
+ super(guild.client, Invite, iterable);
+
+ /**
+ * The guild this Manager belongs to
+ * @type {Guild}
+ */
+ this.guild = guild;
+ }
+
+ /**
+ * The cache of this Manager
+ * @type {Collection<string, Invite>}
+ * @name GuildInviteManager#cache
+ */
+
+ _add(data, cache) {
+ return super._add(data, cache, { id: data.code, extras: [this.guild] });
+ }
+
+ /**
+ * Data that resolves to give an Invite object. This can be:
+ * * An invite code
+ * * An invite URL
+ * @typedef {string} InviteResolvable
+ */
+
+ /**
+ * Data that can be resolved to a channel that an invite can be created on. This can be:
+ * * TextChannel
+ * * VoiceChannel
+ * * NewsChannel
+ * * StageChannel
+ * * ForumChannel
+ * * Snowflake
+ * @typedef {TextChannel|VoiceChannel|NewsChannel|StageChannel|ForumChannel|Snowflake}
+ * GuildInvitableChannelResolvable
+ */
+
+ /**
+ * Resolves an InviteResolvable to an Invite object.
+ * @method resolve
+ * @memberof GuildInviteManager
+ * @instance
+ * @param {InviteResolvable} invite The invite resolvable to resolve
+ * @returns {?Invite}
+ */
+
+ /**
+ * Resolves an InviteResolvable to an invite code string.
+ * @method resolveId
+ * @memberof GuildInviteManager
+ * @instance
+ * @param {InviteResolvable} invite The invite resolvable to resolve
+ * @returns {?string}
+ */
+
+ /**
+ * Options used to fetch a single invite from a guild.
+ * @typedef {Object} FetchInviteOptions
+ * @property {InviteResolvable} code The invite to fetch
+ * @property {boolean} [cache=true] Whether or not to cache the fetched invite
+ * @property {boolean} [force=false] Whether to skip the cache check and request the API
+ */
+
+ /**
+ * Options used to fetch all invites from a guild.
+ * @typedef {Object} FetchInvitesOptions
+ * @property {GuildInvitableChannelResolvable} [channelId]
+ * The channel to fetch all invites from
+ * @property {boolean} [cache=true] Whether or not to cache the fetched invites
+ */
+
+ /**
+ * Fetches invite(s) from Discord.
+ * @param {InviteResolvable|FetchInviteOptions|FetchInvitesOptions} [options] Options for fetching guild invite(s)
+ * @returns {Promise<Invite|Collection<string, Invite>>}
+ * @example
+ * // Fetch all invites from a guild
+ * guild.invites.fetch()
+ * .then(console.log)
+ * .catch(console.error);
+ * @example
+ * // Fetch all invites from a guild without caching
+ * guild.invites.fetch({ cache: false })
+ * .then(console.log)
+ * .catch(console.error);
+ * @example
+ * // Fetch all invites from a channel
+ * guild.invites.fetch({ channelId: '222197033908436994' })
+ * .then(console.log)
+ * .catch(console.error);
+ * @example
+ * // Fetch a single invite
+ * guild.invites.fetch('bRCvFy9')
+ * .then(console.log)
+ * .catch(console.error);
+ * @example
+ * // Fetch a single invite without checking cache
+ * guild.invites.fetch({ code: 'bRCvFy9', force: true })
+ * .then(console.log)
+ * .catch(console.error)
+ * @example
+ * // Fetch a single invite without caching
+ * guild.invites.fetch({ code: 'bRCvFy9', cache: false })
+ * .then(console.log)
+ * .catch(console.error);
+ */
+ fetch(options) {
+ if (!options) return this._fetchMany();
+ if (typeof options === 'string') {
+ const code = DataResolver.resolveInviteCode(options);
+ if (!code) return Promise.reject(new DiscordjsError(ErrorCodes.InviteResolveCode));
+ return this._fetchSingle({ code, cache: true });
+ }
+ if (!options.code) {
+ if (options.channelId) {
+ const id = this.guild.channels.resolveId(options.channelId);
+ if (!id) return Promise.reject(new DiscordjsError(ErrorCodes.GuildChannelResolve));
+ return this._fetchChannelMany(id, options.cache);
+ }
+
+ if ('cache' in options) return this._fetchMany(options.cache);
+ return Promise.reject(new DiscordjsError(ErrorCodes.InviteResolveCode));
+ }
+ return this._fetchSingle({
+ ...options,
+ code: DataResolver.resolveInviteCode(options.code),
+ });
+ }
+
+ async _fetchSingle({ code, cache, force = false }) {
+ if (!force) {
+ const existing = this.cache.get(code);
+ if (existing) return existing;
+ }
+
+ const invites = await this._fetchMany(cache);
+ const invite = invites.get(code);
+ if (!invite) throw new DiscordjsError(ErrorCodes.InviteNotFound);
+ return invite;
+ }
+
+ async _fetchMany(cache) {
+ const data = await this.client.rest.get(Routes.guildInvites(this.guild.id));
+ return data.reduce((col, invite) => col.set(invite.code, this._add(invite, cache)), new Collection());
+ }
+
+ async _fetchChannelMany(channelId, cache) {
+ const data = await this.client.rest.get(Routes.channelInvites(channelId));
+ return data.reduce((col, invite) => col.set(invite.code, this._add(invite, cache)), new Collection());
+ }
+
+ /**
+ * Create an invite to the guild from the provided channel.
+ * @param {GuildInvitableChannelResolvable} channel The options for creating the invite from a channel.
+ * @param {InviteCreateOptions} [options={}] The options for creating the invite from a channel.
+ * @returns {Promise<Invite>}
+ * @example
+ * // Create an invite to a selected channel
+ * guild.invites.create('599942732013764608')
+ * .then(console.log)
+ * .catch(console.error);
+ */
+ async create(
+ channel,
+ { temporary, maxAge, maxUses, unique, targetUser, targetApplication, targetType, reason } = {},
+ ) {
+ const id = this.guild.channels.resolveId(channel);
+ if (!id) throw new DiscordjsError(ErrorCodes.GuildChannelResolve);
+
+ const invite = await this.client.rest.post(Routes.channelInvites(id), {
+ body: {
+ temporary,
+ max_age: maxAge,
+ max_uses: maxUses,
+ unique,
+ target_user_id: this.client.users.resolveId(targetUser),
+ target_application_id: targetApplication?.id ?? targetApplication?.applicationId ?? targetApplication,
+ target_type: targetType,
+ },
+ reason,
+ });
+ return new Invite(this.client, invite);
+ }
+
+ /**
+ * Deletes an invite.
+ * @param {InviteResolvable} invite The invite to delete
+ * @param {string} [reason] Reason for deleting the invite
+ * @returns {Promise<void>}
+ */
+ async delete(invite, reason) {
+ const code = DataResolver.resolveInviteCode(invite);
+
+ await this.client.rest.delete(Routes.invite(code), { reason });
+ }
+}
+
+module.exports = GuildInviteManager;
diff --git a/node_modules/discord.js/src/managers/GuildManager.js b/node_modules/discord.js/src/managers/GuildManager.js
new file mode 100644
index 0000000..1d2d4ba
--- /dev/null
+++ b/node_modules/discord.js/src/managers/GuildManager.js
@@ -0,0 +1,283 @@
+'use strict';
+
+const process = require('node:process');
+const { setTimeout, clearTimeout } = require('node:timers');
+const { Collection } = require('@discordjs/collection');
+const { makeURLSearchParams } = require('@discordjs/rest');
+const { Routes } = require('discord-api-types/v10');
+const CachedManager = require('./CachedManager');
+const { Guild } = require('../structures/Guild');
+const GuildChannel = require('../structures/GuildChannel');
+const GuildEmoji = require('../structures/GuildEmoji');
+const { GuildMember } = require('../structures/GuildMember');
+const Invite = require('../structures/Invite');
+const OAuth2Guild = require('../structures/OAuth2Guild');
+const { Role } = require('../structures/Role');
+const DataResolver = require('../util/DataResolver');
+const Events = require('../util/Events');
+const PermissionsBitField = require('../util/PermissionsBitField');
+const SystemChannelFlagsBitField = require('../util/SystemChannelFlagsBitField');
+const { resolveColor } = require('../util/Util');
+
+let cacheWarningEmitted = false;
+
+/**
+ * Manages API methods for Guilds and stores their cache.
+ * @extends {CachedManager}
+ */
+class GuildManager extends CachedManager {
+ constructor(client, iterable) {
+ super(client, Guild, iterable);
+ if (!cacheWarningEmitted && this._cache.constructor.name !== 'Collection') {
+ cacheWarningEmitted = true;
+ process.emitWarning(
+ `Overriding the cache handling for ${this.constructor.name} is unsupported and breaks functionality.`,
+ 'UnsupportedCacheOverwriteWarning',
+ );
+ }
+ }
+
+ /**
+ * The cache of this Manager
+ * @type {Collection<Snowflake, Guild>}
+ * @name GuildManager#cache
+ */
+
+ /**
+ * Data that resolves to give a Guild object. This can be:
+ * * A Guild object
+ * * A GuildChannel object
+ * * A GuildEmoji object
+ * * A Role object
+ * * A Snowflake
+ * * An Invite object
+ * @typedef {Guild|GuildChannel|GuildMember|GuildEmoji|Role|Snowflake|Invite} GuildResolvable
+ */
+
+ /**
+ * Partial data for a Role.
+ * @typedef {Object} PartialRoleData
+ * @property {Snowflake|number} [id] The role's id, used to set channel overrides.
+ * This is a placeholder and will be replaced by the API after consumption
+ * @property {string} [name] The name of the role
+ * @property {ColorResolvable} [color] The color of the role, either a hex string or a base 10 number
+ * @property {boolean} [hoist] Whether the role should be hoisted
+ * @property {number} [position] The position of the role
+ * @property {PermissionResolvable} [permissions] The permissions of the role
+ * @property {boolean} [mentionable] Whether the role should be mentionable
+ */
+
+ /**
+ * Partial overwrite data.
+ * @typedef {Object} PartialOverwriteData
+ * @property {Snowflake|number} id The id of the {@link Role} or {@link User} this overwrite belongs to
+ * @property {OverwriteType} [type] The type of this overwrite
+ * @property {PermissionResolvable} [allow] The permissions to allow
+ * @property {PermissionResolvable} [deny] The permissions to deny
+ */
+
+ /**
+ * Partial data for a Channel.
+ * @typedef {Object} PartialChannelData
+ * @property {Snowflake|number} [id] The channel's id, used to set its parent.
+ * This is a placeholder and will be replaced by the API after consumption
+ * @property {Snowflake|number} [parentId] The parent id for this channel
+ * @property {ChannelType.GuildText|ChannelType.GuildVoice|ChannelType.GuildCategory} [type] The type of the channel
+ * @property {string} name The name of the channel
+ * @property {?string} [topic] The topic of the text channel
+ * @property {boolean} [nsfw] Whether the channel is NSFW
+ * @property {number} [bitrate] The bitrate of the voice channel
+ * @property {number} [userLimit] The user limit of the channel
+ * @property {?string} [rtcRegion] The RTC region of the channel
+ * @property {VideoQualityMode} [videoQualityMode] The camera video quality mode of the channel
+ * @property {PartialOverwriteData[]} [permissionOverwrites]
+ * Overwrites of the channel
+ * @property {number} [rateLimitPerUser] The rate limit per user (slowmode) of the channel in seconds
+ */
+
+ /**
+ * Resolves a GuildResolvable to a Guild object.
+ * @method resolve
+ * @memberof GuildManager
+ * @instance
+ * @param {GuildResolvable} guild The guild resolvable to identify
+ * @returns {?Guild}
+ */
+ resolve(guild) {
+ if (
+ guild instanceof GuildChannel ||
+ guild instanceof GuildMember ||
+ guild instanceof GuildEmoji ||
+ guild instanceof Role ||
+ (guild instanceof Invite && guild.guild)
+ ) {
+ return super.resolve(guild.guild);
+ }
+ return super.resolve(guild);
+ }
+
+ /**
+ * Resolves a {@link GuildResolvable} to a {@link Guild} id string.
+ * @method resolveId
+ * @memberof GuildManager
+ * @instance
+ * @param {GuildResolvable} guild The guild resolvable to identify
+ * @returns {?Snowflake}
+ */
+ resolveId(guild) {
+ if (
+ guild instanceof GuildChannel ||
+ guild instanceof GuildMember ||
+ guild instanceof GuildEmoji ||
+ guild instanceof Role ||
+ (guild instanceof Invite && guild.guild)
+ ) {
+ return super.resolveId(guild.guild.id);
+ }
+ return super.resolveId(guild);
+ }
+
+ /**
+ * Options used to create a guild.
+ * @typedef {Object} GuildCreateOptions
+ * @property {string} name The name of the guild
+ * @property {?(BufferResolvable|Base64Resolvable)} [icon=null] The icon for the guild
+ * @property {GuildVerificationLevel} [verificationLevel] The verification level for the guild
+ * @property {GuildDefaultMessageNotifications} [defaultMessageNotifications] The default message notifications
+ * for the guild
+ * @property {GuildExplicitContentFilter} [explicitContentFilter] The explicit content filter level for the guild
+ * @property {PartialRoleData[]} [roles=[]] The roles for this guild,
+ * @property {PartialChannelData[]} [channels=[]] The channels for this guild
+ * @property {Snowflake|number} [afkChannelId] The AFK channel's id
+ * @property {number} [afkTimeout] The AFK timeout in seconds
+ * the first element of this array is used to change properties of the guild's everyone role.
+ * @property {Snowflake|number} [systemChannelId] The system channel's id
+ * @property {SystemChannelFlagsResolvable} [systemChannelFlags] The flags of the system channel
+ */
+ /* eslint-enable max-len */
+
+ /**
+ * Creates a guild.
+ * <warn>This is only available to bots in fewer than 10 guilds.</warn>
+ * @param {GuildCreateOptions} options Options for creating the guild
+ * @returns {Promise<Guild>} The guild that was created
+ */
+ async create({
+ name,
+ icon = null,
+ verificationLevel,
+ defaultMessageNotifications,
+ explicitContentFilter,
+ roles = [],
+ channels = [],
+ afkChannelId,
+ afkTimeout,
+ systemChannelId,
+ systemChannelFlags,
+ }) {
+ const data = await this.client.rest.post(Routes.guilds(), {
+ body: {
+ name,
+ icon: icon && (await DataResolver.resolveImage(icon)),
+ verification_level: verificationLevel,
+ default_message_notifications: defaultMessageNotifications,
+ explicit_content_filter: explicitContentFilter,
+ roles: roles.map(({ color, permissions, ...options }) => ({
+ ...options,
+ color: color && resolveColor(color),
+ permissions: permissions === undefined ? undefined : PermissionsBitField.resolve(permissions).toString(),
+ })),
+ channels: channels.map(
+ ({
+ parentId,
+ userLimit,
+ rtcRegion,
+ videoQualityMode,
+ permissionOverwrites,
+ rateLimitPerUser,
+ ...options
+ }) => ({
+ ...options,
+ parent_id: parentId,
+ user_limit: userLimit,
+ rtc_region: rtcRegion,
+ video_quality_mode: videoQualityMode,
+ permission_overwrites: permissionOverwrites?.map(({ allow, deny, ...permissionOverwriteOptions }) => ({
+ ...permissionOverwriteOptions,
+ allow: allow === undefined ? undefined : PermissionsBitField.resolve(allow).toString(),
+ deny: deny === undefined ? undefined : PermissionsBitField.resolve(deny).toString(),
+ })),
+ rate_limit_per_user: rateLimitPerUser,
+ }),
+ ),
+ afk_channel_id: afkChannelId,
+ afk_timeout: afkTimeout,
+ system_channel_id: systemChannelId,
+ system_channel_flags:
+ systemChannelFlags === undefined ? undefined : SystemChannelFlagsBitField.resolve(systemChannelFlags),
+ },
+ });
+
+ return (
+ this.client.guilds.cache.get(data.id) ??
+ new Promise(resolve => {
+ const handleGuild = guild => {
+ if (guild.id === data.id) {
+ clearTimeout(timeout);
+ this.client.decrementMaxListeners();
+ resolve(guild);
+ }
+ };
+ this.client.incrementMaxListeners();
+ this.client.once(Events.GuildCreate, handleGuild);
+
+ const timeout = setTimeout(() => {
+ this.client.removeListener(Events.GuildCreate, handleGuild);
+ this.client.decrementMaxListeners();
+ resolve(this.client.guilds._add(data));
+ }, 10_000).unref();
+ })
+ );
+ }
+
+ /**
+ * Options used to fetch a single guild.
+ * @typedef {BaseFetchOptions} FetchGuildOptions
+ * @property {GuildResolvable} guild The guild to fetch
+ * @property {boolean} [withCounts=true] Whether the approximate member and presence counts should be returned
+ */
+
+ /**
+ * Options used to fetch multiple guilds.
+ * @typedef {Object} FetchGuildsOptions
+ * @property {Snowflake} [before] Get guilds before this guild id
+ * @property {Snowflake} [after] Get guilds after this guild id
+ * @property {number} [limit] Maximum number of guilds to request (1-200)
+ */
+
+ /**
+ * Obtains one or multiple guilds from Discord, or the guild cache if it's already available.
+ * @param {GuildResolvable|FetchGuildOptions|FetchGuildsOptions} [options] The guild's id or options
+ * @returns {Promise<Guild|Collection<Snowflake, OAuth2Guild>>}
+ */
+ async fetch(options = {}) {
+ const id = this.resolveId(options) ?? this.resolveId(options.guild);
+
+ if (id) {
+ if (!options.force) {
+ const existing = this.cache.get(id);
+ if (existing) return existing;
+ }
+
+ const data = await this.client.rest.get(Routes.guild(id), {
+ query: makeURLSearchParams({ with_counts: options.withCounts ?? true }),
+ });
+ return this._add(data, options.cache);
+ }
+
+ const data = await this.client.rest.get(Routes.userGuilds(), { query: makeURLSearchParams(options) });
+ return data.reduce((coll, guild) => coll.set(guild.id, new OAuth2Guild(this.client, guild)), new Collection());
+ }
+}
+
+module.exports = GuildManager;
diff --git a/node_modules/discord.js/src/managers/GuildMemberManager.js b/node_modules/discord.js/src/managers/GuildMemberManager.js
new file mode 100644
index 0000000..a4cf09b
--- /dev/null
+++ b/node_modules/discord.js/src/managers/GuildMemberManager.js
@@ -0,0 +1,540 @@
+'use strict';
+
+const { setTimeout, clearTimeout } = require('node:timers');
+const { Collection } = require('@discordjs/collection');
+const { makeURLSearchParams } = require('@discordjs/rest');
+const { DiscordSnowflake } = require('@sapphire/snowflake');
+const { Routes, GatewayOpcodes } = require('discord-api-types/v10');
+const CachedManager = require('./CachedManager');
+const { DiscordjsError, DiscordjsTypeError, DiscordjsRangeError, ErrorCodes } = require('../errors');
+const BaseGuildVoiceChannel = require('../structures/BaseGuildVoiceChannel');
+const { GuildMember } = require('../structures/GuildMember');
+const { Role } = require('../structures/Role');
+const Events = require('../util/Events');
+const { GuildMemberFlagsBitField } = require('../util/GuildMemberFlagsBitField');
+const Partials = require('../util/Partials');
+
+/**
+ * Manages API methods for GuildMembers and stores their cache.
+ * @extends {CachedManager}
+ */
+class GuildMemberManager extends CachedManager {
+ constructor(guild, iterable) {
+ super(guild.client, GuildMember, iterable);
+
+ /**
+ * The guild this manager belongs to
+ * @type {Guild}
+ */
+ this.guild = guild;
+ }
+
+ /**
+ * The cache of this Manager
+ * @type {Collection<Snowflake, GuildMember>}
+ * @name GuildMemberManager#cache
+ */
+
+ _add(data, cache = true) {
+ return super._add(data, cache, { id: data.user.id, extras: [this.guild] });
+ }
+
+ /**
+ * Data that resolves to give a GuildMember object. This can be:
+ * * A GuildMember object
+ * * A User resolvable
+ * @typedef {GuildMember|UserResolvable} GuildMemberResolvable
+ */
+
+ /**
+ * Resolves a {@link GuildMemberResolvable} to a {@link GuildMember} object.
+ * @param {GuildMemberResolvable} member The user that is part of the guild
+ * @returns {?GuildMember}
+ */
+ resolve(member) {
+ const memberResolvable = super.resolve(member);
+ if (memberResolvable) return memberResolvable;
+ const userResolvable = this.client.users.resolveId(member);
+ if (userResolvable) return super.resolve(userResolvable);
+ return null;
+ }
+
+ /**
+ * Resolves a {@link GuildMemberResolvable} to a member id.
+ * @param {GuildMemberResolvable} member The user that is part of the guild
+ * @returns {?Snowflake}
+ */
+ resolveId(member) {
+ const memberResolvable = super.resolveId(member);
+ if (memberResolvable) return memberResolvable;
+ const userResolvable = this.client.users.resolveId(member);
+ return this.cache.has(userResolvable) ? userResolvable : null;
+ }
+
+ /**
+ * Options used to add a user to a guild using OAuth2.
+ * @typedef {Object} AddGuildMemberOptions
+ * @property {string} accessToken An OAuth2 access token for the user with the {@link OAuth2Scopes.GuildsJoin}
+ * scope granted to the bot's application
+ * @property {string} [nick] The nickname to give to the member
+ * <info>This property requires the {@link PermissionFlagsBits.ManageNicknames} permission.</info>
+ * @property {Collection<Snowflake, Role>|RoleResolvable[]} [roles] The roles to add to the member
+ * <info>This property requires the {@link PermissionFlagsBits.ManageRoles} permission.</info>
+ * @property {boolean} [mute] Whether the member should be muted
+ * <info>This property requires the {@link PermissionFlagsBits.MuteMembers} permission.</info>
+ * @property {boolean} [deaf] Whether the member should be deafened
+ * <info>This property requires the {@link PermissionFlagsBits.MuteMembers} permission.</info>
+ * @property {boolean} [force] Whether to skip the cache check and request the API directly
+ * @property {boolean} [fetchWhenExisting=true] Whether to fetch the user if not cached and already a member
+ */
+
+ /**
+ * Adds a user to the guild using OAuth2.
+ * <info>This method requires the {@link PermissionFlagsBits.CreateInstantInvite} permission.
+ * @param {UserResolvable} user The user to add to the guild
+ * @param {AddGuildMemberOptions} options Options for adding the user to the guild
+ * @returns {Promise<GuildMember|null>}
+ */
+ async add(user, options) {
+ const userId = this.client.users.resolveId(user);
+ if (!userId) throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'user', 'UserResolvable');
+ if (!options.force) {
+ const cachedUser = this.cache.get(userId);
+ if (cachedUser) return cachedUser;
+ }
+ const resolvedOptions = {
+ access_token: options.accessToken,
+ nick: options.nick,
+ mute: options.mute,
+ deaf: options.deaf,
+ };
+ if (options.roles) {
+ if (!Array.isArray(options.roles) && !(options.roles instanceof Collection)) {
+ throw new DiscordjsTypeError(
+ ErrorCodes.InvalidType,
+ 'options.roles',
+ 'Array or Collection of Roles or Snowflakes',
+ true,
+ );
+ }
+ const resolvedRoles = [];
+ for (const role of options.roles.values()) {
+ const resolvedRole = this.guild.roles.resolveId(role);
+ if (!resolvedRole) {
+ throw new DiscordjsTypeError(ErrorCodes.InvalidElement, 'Array or Collection', 'options.roles', role);
+ }
+ resolvedRoles.push(resolvedRole);
+ }
+ resolvedOptions.roles = resolvedRoles;
+ }
+ const data = await this.client.rest.put(Routes.guildMember(this.guild.id, userId), { body: resolvedOptions });
+ // Data is an empty Uint8Array if the member is already part of the guild.
+ return data instanceof Uint8Array
+ ? options.fetchWhenExisting === false
+ ? null
+ : this.fetch(userId)
+ : this._add(data);
+ }
+
+ /**
+ * The client user as a GuildMember of this guild
+ * @type {?GuildMember}
+ * @readonly
+ */
+ get me() {
+ return (
+ this.resolve(this.client.user.id) ??
+ (this.client.options.partials.includes(Partials.GuildMember)
+ ? this._add({ user: { id: this.client.user.id } }, true)
+ : null)
+ );
+ }
+
+ /**
+ * Options used to fetch a single member from a guild.
+ * @typedef {BaseFetchOptions} FetchMemberOptions
+ * @property {UserResolvable} user The user to fetch
+ */
+
+ /**
+ * Options used to fetch multiple members from a guild.
+ * @typedef {Object} FetchMembersOptions
+ * @property {UserResolvable|UserResolvable[]} [user] The user(s) to fetch
+ * @property {?string} [query] Limit fetch to members with similar usernames
+ * @property {number} [limit=0] Maximum number of members to request
+ * @property {boolean} [withPresences=false] Whether to include the presences
+ * @property {number} [time=120e3] Timeout for receipt of members
+ * @property {?string} [nonce] Nonce for this request (32 characters max - default to base 16 now timestamp)
+ */
+
+ /**
+ * Fetches member(s) from a guild.
+ * @param {UserResolvable|FetchMemberOptions|FetchMembersOptions} [options] Options for fetching member(s).
+ * Omitting the parameter or providing `undefined` will fetch all members.
+ * @returns {Promise<GuildMember|Collection<Snowflake, GuildMember>>}
+ * @example
+ * // Fetch all members from a guild
+ * guild.members.fetch()
+ * .then(console.log)
+ * .catch(console.error);
+ * @example
+ * // Fetch a single member
+ * guild.members.fetch('66564597481480192')
+ * .then(console.log)
+ * .catch(console.error);
+ * @example
+ * // Fetch a single member without checking cache
+ * guild.members.fetch({ user, force: true })
+ * .then(console.log)
+ * .catch(console.error)
+ * @example
+ * // Fetch a single member without caching
+ * guild.members.fetch({ user, cache: false })
+ * .then(console.log)
+ * .catch(console.error);
+ * @example
+ * // Fetch by an array of users including their presences
+ * guild.members.fetch({ user: ['66564597481480192', '191615925336670208'], withPresences: true })
+ * .then(console.log)
+ * .catch(console.error);
+ * @example
+ * // Fetch by query
+ * guild.members.fetch({ query: 'hydra', limit: 1 })
+ * .then(console.log)
+ * .catch(console.error);
+ */
+ fetch(options) {
+ if (!options) return this._fetchMany();
+ const { user: users, limit, withPresences, cache, force } = options;
+ const resolvedUser = this.client.users.resolveId(users ?? options);
+ if (resolvedUser && !limit && !withPresences) return this._fetchSingle({ user: resolvedUser, cache, force });
+ const resolvedUsers = users?.map?.(user => this.client.users.resolveId(user)) ?? resolvedUser ?? undefined;
+ return this._fetchMany({ ...options, users: resolvedUsers });
+ }
+
+ async _fetchSingle({ user, cache, force = false }) {
+ if (!force) {
+ const existing = this.cache.get(user);
+ if (existing && !existing.partial) return existing;
+ }
+
+ const data = await this.client.rest.get(Routes.guildMember(this.guild.id, user));
+ return this._add(data, cache);
+ }
+
+ _fetchMany({
+ limit = 0,
+ withPresences: presences,
+ users,
+ query,
+ time = 120e3,
+ nonce = DiscordSnowflake.generate().toString(),
+ } = {}) {
+ if (nonce.length > 32) return Promise.reject(new DiscordjsRangeError(ErrorCodes.MemberFetchNonceLength));
+
+ return new Promise((resolve, reject) => {
+ if (!query && !users) query = '';
+ this.guild.shard.send({
+ op: GatewayOpcodes.RequestGuildMembers,
+ d: {
+ guild_id: this.guild.id,
+ presences,
+ user_ids: users,
+ query,
+ nonce,
+ limit,
+ },
+ });
+ const fetchedMembers = new Collection();
+ let i = 0;
+ const handler = (members, _, chunk) => {
+ if (chunk.nonce !== nonce) return;
+ timeout.refresh();
+ i++;
+ for (const member of members.values()) {
+ fetchedMembers.set(member.id, member);
+ }
+ if (members.size < 1_000 || (limit && fetchedMembers.size >= limit) || i === chunk.count) {
+ clearTimeout(timeout);
+ this.client.removeListener(Events.GuildMembersChunk, handler);
+ this.client.decrementMaxListeners();
+ resolve(users && !Array.isArray(users) && fetchedMembers.size ? fetchedMembers.first() : fetchedMembers);
+ }
+ };
+ const timeout = setTimeout(() => {
+ this.client.removeListener(Events.GuildMembersChunk, handler);
+ this.client.decrementMaxListeners();
+ reject(new DiscordjsError(ErrorCodes.GuildMembersTimeout));
+ }, time).unref();
+ this.client.incrementMaxListeners();
+ this.client.on(Events.GuildMembersChunk, handler);
+ });
+ }
+
+ /**
+ * Fetches the client user as a GuildMember of the guild.
+ * @param {BaseFetchOptions} [options] The options for fetching the member
+ * @returns {Promise<GuildMember>}
+ */
+ fetchMe(options) {
+ return this.fetch({ ...options, user: this.client.user.id });
+ }
+
+ /**
+ * Options used for searching guild members.
+ * @typedef {Object} GuildSearchMembersOptions
+ * @property {string} query Filter members whose username or nickname start with this query
+ * @property {number} [limit] Maximum number of members to search
+ * @property {boolean} [cache=true] Whether or not to cache the fetched member(s)
+ */
+
+ /**
+ * Searches for members in the guild based on a query.
+ * @param {GuildSearchMembersOptions} options Options for searching members
+ * @returns {Promise<Collection<Snowflake, GuildMember>>}
+ */
+ async search({ query, limit, cache = true } = {}) {
+ const data = await this.client.rest.get(Routes.guildMembersSearch(this.guild.id), {
+ query: makeURLSearchParams({ query, limit }),
+ });
+ return data.reduce((col, member) => col.set(member.user.id, this._add(member, cache)), new Collection());
+ }
+
+ /**
+ * Options used for listing guild members.
+ * @typedef {Object} GuildListMembersOptions
+ * @property {Snowflake} [after] Limit fetching members to those with an id greater than the supplied id
+ * @property {number} [limit] Maximum number of members to list
+ * @property {boolean} [cache=true] Whether or not to cache the fetched member(s)
+ */
+
+ /**
+ * Lists up to 1000 members of the guild.
+ * @param {GuildListMembersOptions} [options] Options for listing members
+ * @returns {Promise<Collection<Snowflake, GuildMember>>}
+ */
+ async list({ after, limit, cache = true } = {}) {
+ const query = makeURLSearchParams({ limit, after });
+ const data = await this.client.rest.get(Routes.guildMembers(this.guild.id), { query });
+ return data.reduce((col, member) => col.set(member.user.id, this._add(member, cache)), new Collection());
+ }
+
+ /**
+ * The data for editing a guild member.
+ * @typedef {Object} GuildMemberEditOptions
+ * @property {?string} [nick] The nickname to set for the member
+ * @property {Collection<Snowflake, Role>|RoleResolvable[]} [roles] The roles or role ids to apply
+ * @property {boolean} [mute] Whether or not the member should be muted
+ * @property {boolean} [deaf] Whether or not the member should be deafened
+ * @property {GuildVoiceChannelResolvable|null} [channel] Channel to move the member to
+ * (if they are connected to voice), or `null` if you want to disconnect them from voice
+ * @property {DateResolvable|null} [communicationDisabledUntil] The date or timestamp
+ * for the member's communication to be disabled until. Provide `null` to enable communication again.
+ * @property {GuildMemberFlagsResolvable} [flags] The flags to set for the member
+ * @property {string} [reason] Reason for editing this user
+ */
+
+ /**
+ * Edits a member of the guild.
+ * <info>The user must be a member of the guild</info>
+ * @param {UserResolvable} user The member to edit
+ * @param {GuildMemberEditOptions} options The options to provide
+ * @returns {Promise<GuildMember>}
+ */
+ async edit(user, { reason, ...options }) {
+ const id = this.client.users.resolveId(user);
+ if (!id) throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'user', 'UserResolvable');
+
+ if (options.channel) {
+ options.channel = this.guild.channels.resolve(options.channel);
+ if (!(options.channel instanceof BaseGuildVoiceChannel)) {
+ throw new DiscordjsError(ErrorCodes.GuildVoiceChannelResolve);
+ }
+ options.channel_id = options.channel.id;
+ options.channel = undefined;
+ } else if (options.channel === null) {
+ options.channel_id = null;
+ options.channel = undefined;
+ }
+ options.roles &&= options.roles.map(role => (role instanceof Role ? role.id : role));
+
+ if (options.communicationDisabledUntil !== undefined) {
+ options.communication_disabled_until =
+ // eslint-disable-next-line eqeqeq
+ options.communicationDisabledUntil != null
+ ? new Date(options.communicationDisabledUntil).toISOString()
+ : options.communicationDisabledUntil;
+ }
+
+ if (options.flags !== undefined) {
+ options.flags = GuildMemberFlagsBitField.resolve(options.flags);
+ }
+
+ let endpoint;
+ if (id === this.client.user.id) {
+ const keys = Object.keys(options);
+ if (keys.length === 1 && keys[0] === 'nick') endpoint = Routes.guildMember(this.guild.id);
+ else endpoint = Routes.guildMember(this.guild.id, id);
+ } else {
+ endpoint = Routes.guildMember(this.guild.id, id);
+ }
+ const d = await this.client.rest.patch(endpoint, { body: options, reason });
+
+ const clone = this.cache.get(id)?._clone();
+ clone?._patch(d);
+ return clone ?? this._add(d, false);
+ }
+
+ /**
+ * Options used for pruning guild members.
+ * <info>It's recommended to set {@link GuildPruneMembersOptions#count options.count}
+ * to `false` for large guilds.</info>
+ * @typedef {Object} GuildPruneMembersOptions
+ * @property {number} [days] Number of days of inactivity required to kick
+ * @property {boolean} [dry=false] Get the number of users that will be kicked, without actually kicking them
+ * @property {boolean} [count] Whether or not to return the number of users that have been kicked.
+ * @property {RoleResolvable[]} [roles] Array of roles to bypass the "...and no roles" constraint when pruning
+ * @property {string} [reason] Reason for this prune
+ */
+
+ /**
+ * Prunes members from the guild based on how long they have been inactive.
+ * @param {GuildPruneMembersOptions} [options] Options for pruning
+ * @returns {Promise<number|null>} The number of members that were/will be kicked
+ * @example
+ * // See how many members will be pruned
+ * guild.members.prune({ dry: true })
+ * .then(pruned => console.log(`This will prune ${pruned} people!`))
+ * .catch(console.error);
+ * @example
+ * // Actually prune the members
+ * guild.members.prune({ days: 1, reason: 'too many people!' })
+ * .then(pruned => console.log(`I just pruned ${pruned} people!`))
+ * .catch(console.error);
+ * @example
+ * // Include members with a specified role
+ * guild.members.prune({ days: 7, roles: ['657259391652855808'] })
+ * .then(pruned => console.log(`I just pruned ${pruned} people!`))
+ * .catch(console.error);
+ */
+ async prune({ days, dry = false, count: compute_prune_count, roles = [], reason } = {}) {
+ if (typeof days !== 'number') throw new DiscordjsTypeError(ErrorCodes.PruneDaysType);
+
+ const query = { days };
+ const resolvedRoles = [];
+
+ for (const role of roles) {
+ const resolvedRole = this.guild.roles.resolveId(role);
+ if (!resolvedRole) {
+ throw new DiscordjsTypeError(ErrorCodes.InvalidElement, 'Array', 'options.roles', role);
+ }
+ resolvedRoles.push(resolvedRole);
+ }
+
+ if (resolvedRoles.length) {
+ query.include_roles = dry ? resolvedRoles.join(',') : resolvedRoles;
+ }
+
+ const endpoint = Routes.guildPrune(this.guild.id);
+
+ const { pruned } = await (dry
+ ? this.client.rest.get(endpoint, { query: makeURLSearchParams(query), reason })
+ : this.client.rest.post(endpoint, { body: { ...query, compute_prune_count }, reason }));
+
+ return pruned;
+ }
+
+ /**
+ * Kicks a user from the guild.
+ * <info>The user must be a member of the guild</info>
+ * @param {UserResolvable} user The member to kick
+ * @param {string} [reason] Reason for kicking
+ * @returns {Promise<GuildMember|User|Snowflake>} Result object will be resolved as specifically as possible.
+ * If the GuildMember cannot be resolved, the User will instead be attempted to be resolved. If that also cannot
+ * be resolved, the user's id will be the result.
+ * @example
+ * // Kick a user by id (or with a user/guild member object)
+ * guild.members.kick('84484653687267328')
+ * .then(kickInfo => console.log(`Kicked ${kickInfo.user?.tag ?? kickInfo.tag ?? kickInfo}`))
+ * .catch(console.error);
+ */
+ async kick(user, reason) {
+ const id = this.client.users.resolveId(user);
+ if (!id) return Promise.reject(new DiscordjsTypeError(ErrorCodes.InvalidType, 'user', 'UserResolvable'));
+
+ await this.client.rest.delete(Routes.guildMember(this.guild.id, id), { reason });
+
+ return this.resolve(user) ?? this.client.users.resolve(user) ?? id;
+ }
+
+ /**
+ * Bans a user from the guild.
+ * @param {UserResolvable} user The user to ban
+ * @param {BanOptions} [options] Options for the ban
+ * @returns {Promise<GuildMember|User|Snowflake>} Result object will be resolved as specifically as possible.
+ * If the GuildMember cannot be resolved, the User will instead be attempted to be resolved. If that also cannot
+ * be resolved, the user id will be the result.
+ * Internally calls the GuildBanManager#create method.
+ * @example
+ * // Ban a user by id (or with a user/guild member object)
+ * guild.members.ban('84484653687267328')
+ * .then(banInfo => console.log(`Banned ${banInfo.user?.tag ?? banInfo.tag ?? banInfo}`))
+ * .catch(console.error);
+ */
+ ban(user, options) {
+ return this.guild.bans.create(user, options);
+ }
+
+ /**
+ * Unbans a user from the guild. Internally calls the {@link GuildBanManager#remove} method.
+ * @param {UserResolvable} user The user to unban
+ * @param {string} [reason] Reason for unbanning user
+ * @returns {Promise<?User>} The user that was unbanned
+ * @example
+ * // Unban a user by id (or with a user/guild member object)
+ * guild.members.unban('84484653687267328')
+ * .then(user => console.log(`Unbanned ${user.username} from ${guild.name}`))
+ * .catch(console.error);
+ */
+ unban(user, reason) {
+ return this.guild.bans.remove(user, reason);
+ }
+
+ /**
+ * Options used for adding or removing a role from a member.
+ * @typedef {Object} AddOrRemoveGuildMemberRoleOptions
+ * @property {GuildMemberResolvable} user The user to add/remove the role from
+ * @property {RoleResolvable} role The role to add/remove
+ * @property {string} [reason] Reason for adding/removing the role
+ */
+
+ /**
+ * Adds a role to a member.
+ * @param {AddOrRemoveGuildMemberRoleOptions} options Options for adding the role
+ * @returns {Promise<GuildMember|User|Snowflake>}
+ */
+ async addRole(options) {
+ const { user, role, reason } = options;
+ const userId = this.guild.members.resolveId(user);
+ const roleId = this.guild.roles.resolveId(role);
+ await this.client.rest.put(Routes.guildMemberRole(this.guild.id, userId, roleId), { reason });
+
+ return this.resolve(user) ?? this.client.users.resolve(user) ?? userId;
+ }
+
+ /**
+ * Removes a role from a member.
+ * @param {AddOrRemoveGuildMemberRoleOptions} options Options for removing the role
+ * @returns {Promise<GuildMember|User|Snowflake>}
+ */
+ async removeRole(options) {
+ const { user, role, reason } = options;
+ const userId = this.guild.members.resolveId(user);
+ const roleId = this.guild.roles.resolveId(role);
+ await this.client.rest.delete(Routes.guildMemberRole(this.guild.id, userId, roleId), { reason });
+
+ return this.resolve(user) ?? this.client.users.resolve(user) ?? userId;
+ }
+}
+
+module.exports = GuildMemberManager;
diff --git a/node_modules/discord.js/src/managers/GuildMemberRoleManager.js b/node_modules/discord.js/src/managers/GuildMemberRoleManager.js
new file mode 100644
index 0000000..e530268
--- /dev/null
+++ b/node_modules/discord.js/src/managers/GuildMemberRoleManager.js
@@ -0,0 +1,204 @@
+'use strict';
+
+const { Collection } = require('@discordjs/collection');
+const { Routes } = require('discord-api-types/v10');
+const DataManager = require('./DataManager');
+const { DiscordjsTypeError, ErrorCodes } = require('../errors');
+const { Role } = require('../structures/Role');
+
+/**
+ * Manages API methods for roles of a GuildMember and stores their cache.
+ * @extends {DataManager}
+ */
+class GuildMemberRoleManager extends DataManager {
+ constructor(member) {
+ super(member.client, Role);
+
+ /**
+ * The GuildMember this manager belongs to
+ * @type {GuildMember}
+ */
+ this.member = member;
+
+ /**
+ * The Guild this manager belongs to
+ * @type {Guild}
+ */
+ this.guild = member.guild;
+ }
+
+ /**
+ * The roles of this member
+ * @type {Collection<Snowflake, Role>}
+ * @readonly
+ */
+ get cache() {
+ const everyone = this.guild.roles.everyone;
+ return this.guild.roles.cache.filter(role => this.member._roles.includes(role.id)).set(everyone.id, everyone);
+ }
+
+ /**
+ * The role of the member used to hoist them in a separate category in the users list
+ * @type {?Role}
+ * @readonly
+ */
+ get hoist() {
+ const hoistedRoles = this.cache.filter(role => role.hoist);
+ if (!hoistedRoles.size) return null;
+ return hoistedRoles.reduce((prev, role) => (role.comparePositionTo(prev) > 0 ? role : prev));
+ }
+
+ /**
+ * The role of the member used to set their role icon
+ * @type {?Role}
+ * @readonly
+ */
+ get icon() {
+ const iconRoles = this.cache.filter(role => role.icon || role.unicodeEmoji);
+ if (!iconRoles.size) return null;
+ return iconRoles.reduce((prev, role) => (role.comparePositionTo(prev) > 0 ? role : prev));
+ }
+
+ /**
+ * The role of the member used to set their color
+ * @type {?Role}
+ * @readonly
+ */
+ get color() {
+ const coloredRoles = this.cache.filter(role => role.color);
+ if (!coloredRoles.size) return null;
+ return coloredRoles.reduce((prev, role) => (role.comparePositionTo(prev) > 0 ? role : prev));
+ }
+
+ /**
+ * The role of the member with the highest position
+ * @type {Role}
+ * @readonly
+ */
+ get highest() {
+ return this.cache.reduce((prev, role) => (role.comparePositionTo(prev) > 0 ? role : prev), this.cache.first());
+ }
+
+ /**
+ * The premium subscriber role of the guild, if present on the member
+ * @type {?Role}
+ * @readonly
+ */
+ get premiumSubscriberRole() {
+ return this.cache.find(role => role.tags?.premiumSubscriberRole) ?? null;
+ }
+
+ /**
+ * The managed role this member created when joining the guild, if any
+ * <info>Only ever available on bots</info>
+ * @type {?Role}
+ * @readonly
+ */
+ get botRole() {
+ if (!this.member.user.bot) return null;
+ return this.cache.find(role => role.tags?.botId === this.member.user.id) ?? null;
+ }
+
+ /**
+ * Adds a role (or multiple roles) to the member.
+ * @param {RoleResolvable|RoleResolvable[]|Collection<Snowflake, Role>} roleOrRoles The role or roles to add
+ * @param {string} [reason] Reason for adding the role(s)
+ * @returns {Promise<GuildMember>}
+ */
+ async add(roleOrRoles, reason) {
+ if (roleOrRoles instanceof Collection || Array.isArray(roleOrRoles)) {
+ const resolvedRoles = [];
+ for (const role of roleOrRoles.values()) {
+ const resolvedRole = this.guild.roles.resolveId(role);
+ if (!resolvedRole) {
+ throw new DiscordjsTypeError(ErrorCodes.InvalidElement, 'Array or Collection', 'roles', role);
+ }
+ resolvedRoles.push(resolvedRole);
+ }
+
+ const newRoles = [...new Set(resolvedRoles.concat(...this.cache.keys()))];
+ return this.set(newRoles, reason);
+ } else {
+ roleOrRoles = this.guild.roles.resolveId(roleOrRoles);
+ if (roleOrRoles === null) {
+ throw new DiscordjsTypeError(
+ ErrorCodes.InvalidType,
+ 'roles',
+ 'Role, Snowflake or Array or Collection of Roles or Snowflakes',
+ );
+ }
+
+ await this.client.rest.put(Routes.guildMemberRole(this.guild.id, this.member.id, roleOrRoles), { reason });
+
+ const clone = this.member._clone();
+ clone._roles = [...this.cache.keys(), roleOrRoles];
+ return clone;
+ }
+ }
+
+ /**
+ * Removes a role (or multiple roles) from the member.
+ * @param {RoleResolvable|RoleResolvable[]|Collection<Snowflake, Role>} roleOrRoles The role or roles to remove
+ * @param {string} [reason] Reason for removing the role(s)
+ * @returns {Promise<GuildMember>}
+ */
+ async remove(roleOrRoles, reason) {
+ if (roleOrRoles instanceof Collection || Array.isArray(roleOrRoles)) {
+ const resolvedRoles = [];
+ for (const role of roleOrRoles.values()) {
+ const resolvedRole = this.guild.roles.resolveId(role);
+ if (!resolvedRole) {
+ throw new DiscordjsTypeError(ErrorCodes.InvalidElement, 'Array or Collection', 'roles', role);
+ }
+ resolvedRoles.push(resolvedRole);
+ }
+
+ const newRoles = this.cache.filter(role => !resolvedRoles.includes(role.id));
+ return this.set(newRoles, reason);
+ } else {
+ roleOrRoles = this.guild.roles.resolveId(roleOrRoles);
+ if (roleOrRoles === null) {
+ throw new DiscordjsTypeError(
+ ErrorCodes.InvalidType,
+ 'roles',
+ 'Role, Snowflake or Array or Collection of Roles or Snowflakes',
+ );
+ }
+
+ await this.client.rest.delete(Routes.guildMemberRole(this.guild.id, this.member.id, roleOrRoles), { reason });
+
+ const clone = this.member._clone();
+ const newRoles = this.cache.filter(role => role.id !== roleOrRoles);
+ clone._roles = [...newRoles.keys()];
+ return clone;
+ }
+ }
+
+ /**
+ * Sets the roles applied to the member.
+ * @param {Collection<Snowflake, Role>|RoleResolvable[]} roles The roles or role ids to apply
+ * @param {string} [reason] Reason for applying the roles
+ * @returns {Promise<GuildMember>}
+ * @example
+ * // Set the member's roles to a single role
+ * guildMember.roles.set(['391156570408615936'])
+ * .then(console.log)
+ * .catch(console.error);
+ * @example
+ * // Remove all the roles from a member
+ * guildMember.roles.set([])
+ * .then(member => console.log(`Member roles is now of ${member.roles.cache.size} size`))
+ * .catch(console.error);
+ */
+ set(roles, reason) {
+ return this.member.edit({ roles, reason });
+ }
+
+ clone() {
+ const clone = new this.constructor(this.member);
+ clone.member._roles = [...this.cache.keys()];
+ return clone;
+ }
+}
+
+module.exports = GuildMemberRoleManager;
diff --git a/node_modules/discord.js/src/managers/GuildMessageManager.js b/node_modules/discord.js/src/managers/GuildMessageManager.js
new file mode 100644
index 0000000..7a93c99
--- /dev/null
+++ b/node_modules/discord.js/src/managers/GuildMessageManager.js
@@ -0,0 +1,17 @@
+'use strict';
+
+const MessageManager = require('./MessageManager');
+
+/**
+ * Manages API methods for messages in a guild and holds their cache.
+ * @extends {MessageManager}
+ */
+class GuildMessageManager extends MessageManager {
+ /**
+ * The channel that the messages belong to
+ * @name GuildMessageManager#channel
+ * @type {GuildTextBasedChannel}
+ */
+}
+
+module.exports = GuildMessageManager;
diff --git a/node_modules/discord.js/src/managers/GuildScheduledEventManager.js b/node_modules/discord.js/src/managers/GuildScheduledEventManager.js
new file mode 100644
index 0000000..9071b60
--- /dev/null
+++ b/node_modules/discord.js/src/managers/GuildScheduledEventManager.js
@@ -0,0 +1,297 @@
+'use strict';
+
+const { Collection } = require('@discordjs/collection');
+const { makeURLSearchParams } = require('@discordjs/rest');
+const { GuildScheduledEventEntityType, Routes } = require('discord-api-types/v10');
+const CachedManager = require('./CachedManager');
+const { DiscordjsTypeError, DiscordjsError, ErrorCodes } = require('../errors');
+const { GuildScheduledEvent } = require('../structures/GuildScheduledEvent');
+const DataResolver = require('../util/DataResolver');
+
+/**
+ * Manages API methods for GuildScheduledEvents and stores their cache.
+ * @extends {CachedManager}
+ */
+class GuildScheduledEventManager extends CachedManager {
+ constructor(guild, iterable) {
+ super(guild.client, GuildScheduledEvent, iterable);
+
+ /**
+ * The guild this manager belongs to
+ * @type {Guild}
+ */
+ this.guild = guild;
+ }
+
+ /**
+ * The cache of this manager
+ * @type {Collection<Snowflake, GuildScheduledEvent>}
+ * @name GuildScheduledEventManager#cache
+ */
+
+ /**
+ * Data that resolves to give a GuildScheduledEvent object. This can be:
+ * * A Snowflake
+ * * A GuildScheduledEvent object
+ * @typedef {Snowflake|GuildScheduledEvent} GuildScheduledEventResolvable
+ */
+
+ /**
+ * Options used to create a guild scheduled event.
+ * @typedef {Object} GuildScheduledEventCreateOptions
+ * @property {string} name The name of the guild scheduled event
+ * @property {DateResolvable} scheduledStartTime The time to schedule the event at
+ * @property {DateResolvable} [scheduledEndTime] The time to end the event at
+ * <warn>This is required if `entityType` is {@link GuildScheduledEventEntityType.External}</warn>
+ * @property {GuildScheduledEventPrivacyLevel} privacyLevel The privacy level of the guild scheduled event
+ * @property {GuildScheduledEventEntityType} entityType The scheduled entity type of the event
+ * @property {string} [description] The description of the guild scheduled event
+ * @property {GuildVoiceChannelResolvable} [channel] The channel of the guild scheduled event
+ * <warn>This is required if `entityType` is {@link GuildScheduledEventEntityType.StageInstance} or
+ * {@link GuildScheduledEventEntityType.Voice}</warn>
+ * @property {GuildScheduledEventEntityMetadataOptions} [entityMetadata] The entity metadata of the
+ * guild scheduled event
+ * <warn>This is required if `entityType` is {@link GuildScheduledEventEntityType.External}</warn>
+ * @property {?(BufferResolvable|Base64Resolvable)} [image] The cover image of the guild scheduled event
+ * @property {string} [reason] The reason for creating the guild scheduled event
+ */
+
+ /**
+ * Options used to set entity metadata of a guild scheduled event.
+ * @typedef {Object} GuildScheduledEventEntityMetadataOptions
+ * @property {string} [location] The location of the guild scheduled event
+ * <warn>This is required if `entityType` is {@link GuildScheduledEventEntityType.External}</warn>
+ */
+
+ /**
+ * Creates a new guild scheduled event.
+ * @param {GuildScheduledEventCreateOptions} options Options for creating the guild scheduled event
+ * @returns {Promise<GuildScheduledEvent>}
+ */
+ async create(options) {
+ if (typeof options !== 'object') throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'options', 'object', true);
+ let {
+ privacyLevel,
+ entityType,
+ channel,
+ name,
+ scheduledStartTime,
+ description,
+ scheduledEndTime,
+ entityMetadata,
+ reason,
+ image,
+ } = options;
+
+ let entity_metadata, channel_id;
+ if (entityType === GuildScheduledEventEntityType.External) {
+ channel_id = channel === undefined ? channel : null;
+ entity_metadata = { location: entityMetadata?.location };
+ } else {
+ channel_id = this.guild.channels.resolveId(channel);
+ if (!channel_id) throw new DiscordjsError(ErrorCodes.GuildVoiceChannelResolve);
+ entity_metadata = entityMetadata === undefined ? entityMetadata : null;
+ }
+
+ const data = await this.client.rest.post(Routes.guildScheduledEvents(this.guild.id), {
+ body: {
+ channel_id,
+ name,
+ privacy_level: privacyLevel,
+ scheduled_start_time: new Date(scheduledStartTime).toISOString(),
+ scheduled_end_time: scheduledEndTime ? new Date(scheduledEndTime).toISOString() : scheduledEndTime,
+ description,
+ entity_type: entityType,
+ entity_metadata,
+ image: image && (await DataResolver.resolveImage(image)),
+ },
+ reason,
+ });
+
+ return this._add(data);
+ }
+
+ /**
+ * Options used to fetch a single guild scheduled event from a guild.
+ * @typedef {BaseFetchOptions} FetchGuildScheduledEventOptions
+ * @property {GuildScheduledEventResolvable} guildScheduledEvent The guild scheduled event to fetch
+ * @property {boolean} [withUserCount=true] Whether to fetch the number of users subscribed to the scheduled event
+ */
+
+ /**
+ * Options used to fetch multiple guild scheduled events from a guild.
+ * @typedef {Object} FetchGuildScheduledEventsOptions
+ * @property {boolean} [cache] Whether or not to cache the fetched guild scheduled events
+ * @property {boolean} [withUserCount=true] Whether to fetch the number of users subscribed to each scheduled event
+ * should be returned
+ */
+
+ /**
+ * Obtains one or more guild scheduled events from Discord, or the guild cache if it's already available.
+ * @param {GuildScheduledEventResolvable|FetchGuildScheduledEventOptions|FetchGuildScheduledEventsOptions} [options]
+ * The id of the guild scheduled event or options
+ * @returns {Promise<GuildScheduledEvent|Collection<Snowflake, GuildScheduledEvent>>}
+ */
+ async fetch(options = {}) {
+ const id = this.resolveId(options.guildScheduledEvent ?? options);
+
+ if (id) {
+ if (!options.force) {
+ const existing = this.cache.get(id);
+ if (existing) return existing;
+ }
+
+ const data = await this.client.rest.get(Routes.guildScheduledEvent(this.guild.id, id), {
+ query: makeURLSearchParams({ with_user_count: options.withUserCount ?? true }),
+ });
+ return this._add(data, options.cache);
+ }
+
+ const data = await this.client.rest.get(Routes.guildScheduledEvents(this.guild.id), {
+ query: makeURLSearchParams({ with_user_count: options.withUserCount ?? true }),
+ });
+
+ return data.reduce(
+ (coll, rawGuildScheduledEventData) =>
+ coll.set(
+ rawGuildScheduledEventData.id,
+ this.guild.scheduledEvents._add(rawGuildScheduledEventData, options.cache),
+ ),
+ new Collection(),
+ );
+ }
+
+ /**
+ * Options used to edit a guild scheduled event.
+ * @typedef {Object} GuildScheduledEventEditOptions
+ * @property {string} [name] The name of the guild scheduled event
+ * @property {DateResolvable} [scheduledStartTime] The time to schedule the event at
+ * @property {DateResolvable} [scheduledEndTime] The time to end the event at
+ * @property {GuildScheduledEventPrivacyLevel} [privacyLevel] The privacy level of the guild scheduled event
+ * @property {GuildScheduledEventEntityType} [entityType] The scheduled entity type of the event
+ * @property {string} [description] The description of the guild scheduled event
+ * @property {?GuildVoiceChannelResolvable} [channel] The channel of the guild scheduled event
+ * @property {GuildScheduledEventStatus} [status] The status of the guild scheduled event
+ * @property {GuildScheduledEventEntityMetadataOptions} [entityMetadata] The entity metadata of the
+ * guild scheduled event
+ * <warn>This can be modified only if `entityType` of the `GuildScheduledEvent` to be edited is
+ * {@link GuildScheduledEventEntityType.External}</warn>
+ * @property {?(BufferResolvable|Base64Resolvable)} [image] The cover image of the guild scheduled event
+ * @property {string} [reason] The reason for editing the guild scheduled event
+ */
+
+ /**
+ * Edits a guild scheduled event.
+ * @param {GuildScheduledEventResolvable} guildScheduledEvent The guild scheduled event to edit
+ * @param {GuildScheduledEventEditOptions} options Options to edit the guild scheduled event
+ * @returns {Promise<GuildScheduledEvent>}
+ */
+ async edit(guildScheduledEvent, options) {
+ const guildScheduledEventId = this.resolveId(guildScheduledEvent);
+ if (!guildScheduledEventId) throw new DiscordjsError(ErrorCodes.GuildScheduledEventResolve);
+
+ if (typeof options !== 'object') throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'options', 'object', true);
+ let {
+ privacyLevel,
+ entityType,
+ channel,
+ status,
+ name,
+ scheduledStartTime,
+ description,
+ scheduledEndTime,
+ entityMetadata,
+ reason,
+ image,
+ } = options;
+
+ let entity_metadata;
+ if (entityMetadata) {
+ entity_metadata = {
+ location: entityMetadata.location,
+ };
+ }
+
+ const data = await this.client.rest.patch(Routes.guildScheduledEvent(this.guild.id, guildScheduledEventId), {
+ body: {
+ channel_id: channel === undefined ? channel : this.guild.channels.resolveId(channel),
+ name,
+ privacy_level: privacyLevel,
+ scheduled_start_time: scheduledStartTime ? new Date(scheduledStartTime).toISOString() : undefined,
+ scheduled_end_time: scheduledEndTime ? new Date(scheduledEndTime).toISOString() : scheduledEndTime,
+ description,
+ entity_type: entityType,
+ status,
+ image: image && (await DataResolver.resolveImage(image)),
+ entity_metadata,
+ },
+ reason,
+ });
+
+ return this._add(data);
+ }
+
+ /**
+ * Deletes a guild scheduled event.
+ * @param {GuildScheduledEventResolvable} guildScheduledEvent The guild scheduled event to delete
+ * @returns {Promise<void>}
+ */
+ async delete(guildScheduledEvent) {
+ const guildScheduledEventId = this.resolveId(guildScheduledEvent);
+ if (!guildScheduledEventId) throw new DiscordjsError(ErrorCodes.GuildScheduledEventResolve);
+
+ await this.client.rest.delete(Routes.guildScheduledEvent(this.guild.id, guildScheduledEventId));
+ }
+
+ /**
+ * Options used to fetch subscribers of a guild scheduled event
+ * @typedef {Object} FetchGuildScheduledEventSubscribersOptions
+ * @property {number} [limit] The maximum numbers of users to fetch
+ * @property {boolean} [withMember] Whether to fetch guild member data of the users
+ * @property {Snowflake} [before] Consider only users before this user id
+ * @property {Snowflake} [after] Consider only users after this user id
+ * <warn>If both `before` and `after` are provided, only `before` is respected</warn>
+ */
+
+ /**
+ * Represents a subscriber of a {@link GuildScheduledEvent}
+ * @typedef {Object} GuildScheduledEventUser
+ * @property {Snowflake} guildScheduledEventId The id of the guild scheduled event which the user subscribed to
+ * @property {User} user The user that subscribed to the guild scheduled event
+ * @property {?GuildMember} member The guild member associated with the user, if any
+ */
+
+ /**
+ * Fetches subscribers of a guild scheduled event.
+ * @param {GuildScheduledEventResolvable} guildScheduledEvent The guild scheduled event to fetch subscribers of
+ * @param {FetchGuildScheduledEventSubscribersOptions} [options={}] Options for fetching the subscribers
+ * @returns {Promise<Collection<Snowflake, GuildScheduledEventUser>>}
+ */
+ async fetchSubscribers(guildScheduledEvent, options = {}) {
+ const guildScheduledEventId = this.resolveId(guildScheduledEvent);
+ if (!guildScheduledEventId) throw new DiscordjsError(ErrorCodes.GuildScheduledEventResolve);
+
+ const query = makeURLSearchParams({
+ limit: options.limit,
+ with_member: options.withMember,
+ before: options.before,
+ after: options.after,
+ });
+
+ const data = await this.client.rest.get(Routes.guildScheduledEventUsers(this.guild.id, guildScheduledEventId), {
+ query,
+ });
+
+ return data.reduce(
+ (coll, rawData) =>
+ coll.set(rawData.user.id, {
+ guildScheduledEventId: rawData.guild_scheduled_event_id,
+ user: this.client.users._add(rawData.user),
+ member: rawData.member ? this.guild.members._add({ ...rawData.member, user: rawData.user }) : null,
+ }),
+ new Collection(),
+ );
+ }
+}
+
+module.exports = GuildScheduledEventManager;
diff --git a/node_modules/discord.js/src/managers/GuildStickerManager.js b/node_modules/discord.js/src/managers/GuildStickerManager.js
new file mode 100644
index 0000000..a4974ec
--- /dev/null
+++ b/node_modules/discord.js/src/managers/GuildStickerManager.js
@@ -0,0 +1,182 @@
+'use strict';
+
+const { Collection } = require('@discordjs/collection');
+const { Routes } = require('discord-api-types/v10');
+const CachedManager = require('./CachedManager');
+const { DiscordjsTypeError, ErrorCodes } = require('../errors');
+const MessagePayload = require('../structures/MessagePayload');
+const { Sticker } = require('../structures/Sticker');
+
+/**
+ * Manages API methods for Guild Stickers and stores their cache.
+ * @extends {CachedManager}
+ */
+class GuildStickerManager extends CachedManager {
+ constructor(guild, iterable) {
+ super(guild.client, Sticker, iterable);
+
+ /**
+ * The guild this manager belongs to
+ * @type {Guild}
+ */
+ this.guild = guild;
+ }
+
+ /**
+ * The cache of Guild Stickers
+ * @type {Collection<Snowflake, Sticker>}
+ * @name GuildStickerManager#cache
+ */
+
+ _add(data, cache) {
+ return super._add(data, cache, { extras: [this.guild] });
+ }
+
+ /**
+ * Options used to create a guild sticker.
+ * @typedef {Object} GuildStickerCreateOptions
+ * @property {AttachmentPayload|BufferResolvable|Stream} file The file for the sticker
+ * @property {string} name The name for the sticker
+ * @property {string} tags The Discord name of a unicode emoji representing the sticker's expression
+ * @property {?string} [description] The description for the sticker
+ * @property {string} [reason] Reason for creating the sticker
+ */
+
+ /**
+ * Creates a new custom sticker in the guild.
+ * @param {GuildStickerCreateOptions} options Options for creating a guild sticker
+ * @returns {Promise<Sticker>} The created sticker
+ * @example
+ * // Create a new sticker from a URL
+ * guild.stickers.create({ file: 'https://i.imgur.com/w3duR07.png', name: 'rip', tags: 'headstone' })
+ * .then(sticker => console.log(`Created new sticker with name ${sticker.name}!`))
+ * .catch(console.error);
+ * @example
+ * // Create a new sticker from a file on your computer
+ * guild.stickers.create({ file: './memes/banana.png', name: 'banana', tags: 'banana' })
+ * .then(sticker => console.log(`Created new sticker with name ${sticker.name}!`))
+ * .catch(console.error);
+ */
+ async create({ file, name, tags, description, reason } = {}) {
+ const resolvedFile = await MessagePayload.resolveFile(file);
+ if (!resolvedFile) throw new DiscordjsTypeError(ErrorCodes.ReqResourceType);
+ file = { ...resolvedFile, key: 'file' };
+
+ const body = { name, tags, description: description ?? '' };
+
+ const sticker = await this.client.rest.post(Routes.guildStickers(this.guild.id), {
+ appendToFormData: true,
+ body,
+ files: [file],
+ reason,
+ });
+ return this.client.actions.GuildStickerCreate.handle(this.guild, sticker).sticker;
+ }
+
+ /**
+ * Data that resolves to give a Sticker object. This can be:
+ * * A Sticker object
+ * * A Snowflake
+ * @typedef {Sticker|Snowflake} StickerResolvable
+ */
+
+ /**
+ * Resolves a StickerResolvable to a Sticker object.
+ * @method resolve
+ * @memberof GuildStickerManager
+ * @instance
+ * @param {StickerResolvable} sticker The Sticker resolvable to identify
+ * @returns {?Sticker}
+ */
+
+ /**
+ * Resolves a StickerResolvable to a Sticker id string.
+ * @method resolveId
+ * @memberof GuildStickerManager
+ * @instance
+ * @param {StickerResolvable} sticker The Sticker resolvable to identify
+ * @returns {?Snowflake}
+ */
+
+ /**
+ * Edits a sticker.
+ * @param {StickerResolvable} sticker The sticker to edit
+ * @param {GuildStickerEditOptions} [options={}] The new data for the sticker
+ * @returns {Promise<Sticker>}
+ */
+ async edit(sticker, options = {}) {
+ const stickerId = this.resolveId(sticker);
+ if (!stickerId) throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'sticker', 'StickerResolvable');
+
+ const d = await this.client.rest.patch(Routes.guildSticker(this.guild.id, stickerId), {
+ body: options,
+ reason: options.reason,
+ });
+
+ const existing = this.cache.get(stickerId);
+ if (existing) {
+ const clone = existing._clone();
+ clone._patch(d);
+ return clone;
+ }
+ return this._add(d);
+ }
+
+ /**
+ * Deletes a sticker.
+ * @param {StickerResolvable} sticker The sticker to delete
+ * @param {string} [reason] Reason for deleting this sticker
+ * @returns {Promise<void>}
+ */
+ async delete(sticker, reason) {
+ sticker = this.resolveId(sticker);
+ if (!sticker) throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'sticker', 'StickerResolvable');
+
+ await this.client.rest.delete(Routes.guildSticker(this.guild.id, sticker), { reason });
+ }
+
+ /**
+ * Obtains one or more stickers from Discord, or the sticker cache if they're already available.
+ * @param {Snowflake} [id] The Sticker's id
+ * @param {BaseFetchOptions} [options] Additional options for this fetch
+ * @returns {Promise<Sticker|Collection<Snowflake, Sticker>>}
+ * @example
+ * // Fetch all stickers from the guild
+ * message.guild.stickers.fetch()
+ * .then(stickers => console.log(`There are ${stickers.size} stickers.`))
+ * .catch(console.error);
+ * @example
+ * // Fetch a single sticker
+ * message.guild.stickers.fetch('222078108977594368')
+ * .then(sticker => console.log(`The sticker name is: ${sticker.name}`))
+ * .catch(console.error);
+ */
+ async fetch(id, { cache = true, force = false } = {}) {
+ if (id) {
+ if (!force) {
+ const existing = this.cache.get(id);
+ if (existing) return existing;
+ }
+ const sticker = await this.client.rest.get(Routes.guildSticker(this.guild.id, id));
+ return this._add(sticker, cache);
+ }
+
+ const data = await this.client.rest.get(Routes.guildStickers(this.guild.id));
+ return new Collection(data.map(sticker => [sticker.id, this._add(sticker, cache)]));
+ }
+
+ /**
+ * Fetches the user who uploaded this sticker, if this is a guild sticker.
+ * @param {StickerResolvable} sticker The sticker to fetch the user for
+ * @returns {Promise<?User>}
+ */
+ async fetchUser(sticker) {
+ sticker = this.resolve(sticker);
+ if (!sticker) throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'sticker', 'StickerResolvable');
+ const data = await this.client.rest.get(Routes.guildSticker(this.guild.id, sticker.id));
+ sticker._patch(data);
+ return sticker.user;
+ }
+}
+
+module.exports = GuildStickerManager;
diff --git a/node_modules/discord.js/src/managers/GuildTextThreadManager.js b/node_modules/discord.js/src/managers/GuildTextThreadManager.js
new file mode 100644
index 0000000..5591845
--- /dev/null
+++ b/node_modules/discord.js/src/managers/GuildTextThreadManager.js
@@ -0,0 +1,91 @@
+'use strict';
+
+const { ChannelType, Routes } = require('discord-api-types/v10');
+const ThreadManager = require('./ThreadManager');
+const { DiscordjsTypeError, ErrorCodes } = require('../errors');
+
+/**
+ * Manages API methods for {@link ThreadChannel} objects and stores their cache.
+ * @extends {ThreadManager}
+ */
+class GuildTextThreadManager extends ThreadManager {
+ /**
+ * The channel this Manager belongs to
+ * @name GuildTextThreadManager#channel
+ * @type {TextChannel|NewsChannel}
+ */
+
+ /**
+ * Options for creating a thread. <warn>Only one of `startMessage` or `type` can be defined.</warn>
+ * @typedef {StartThreadOptions} ThreadCreateOptions
+ * @property {MessageResolvable} [startMessage] The message to start a thread from.
+ * <warn>If this is defined, then the `type` of thread gets inferred automatically and cannot be changed.</warn>
+ * @property {ThreadChannelTypes} [type] The type of thread to create.
+ * Defaults to {@link ChannelType.PublicThread} if created in a {@link TextChannel}
+ * <warn>When creating threads in a {@link NewsChannel}, this is ignored and is always
+ * {@link ChannelType.AnnouncementThread}</warn>
+ * @property {boolean} [invitable] Whether non-moderators can add other non-moderators to the thread
+ * <info>Can only be set when type will be {@link ChannelType.PrivateThread}</info>
+ */
+
+ /**
+ * Creates a new thread in the channel.
+ * @param {ThreadCreateOptions} [options] Options to create a new thread
+ * @returns {Promise<ThreadChannel>}
+ * @example
+ * // Create a new public thread
+ * channel.threads
+ * .create({
+ * name: 'food-talk',
+ * autoArchiveDuration: ThreadAutoArchiveDuration.OneHour,
+ * reason: 'Needed a separate thread for food',
+ * })
+ * .then(threadChannel => console.log(threadChannel))
+ * .catch(console.error);
+ * @example
+ * // Create a new private thread
+ * channel.threads
+ * .create({
+ * name: 'mod-talk',
+ * autoArchiveDuration: ThreadAutoArchiveDuration.OneHour,
+ * type: ChannelType.PrivateThread,
+ * reason: 'Needed a separate thread for moderation',
+ * })
+ * .then(threadChannel => console.log(threadChannel))
+ * .catch(console.error);
+ */
+ async create({
+ name,
+ autoArchiveDuration = this.channel.defaultAutoArchiveDuration,
+ startMessage,
+ type,
+ invitable,
+ reason,
+ rateLimitPerUser,
+ } = {}) {
+ let resolvedType =
+ this.channel.type === ChannelType.GuildAnnouncement ? ChannelType.AnnouncementThread : ChannelType.PublicThread;
+ let startMessageId;
+ if (startMessage) {
+ startMessageId = this.channel.messages.resolveId(startMessage);
+ if (!startMessageId) throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'startMessage', 'MessageResolvable');
+ } else if (this.channel.type !== ChannelType.GuildAnnouncement) {
+ resolvedType = type ?? resolvedType;
+ }
+
+ const data = await this.client.rest.post(Routes.threads(this.channel.id, startMessageId), {
+ body: {
+ name,
+ auto_archive_duration: autoArchiveDuration,
+ type: resolvedType,
+ invitable: resolvedType === ChannelType.PrivateThread ? invitable : undefined,
+ rate_limit_per_user: rateLimitPerUser,
+ },
+ reason,
+ });
+
+ return this.client.actions.ThreadCreate.handle(data).thread;
+ }
+}
+
+module.exports = GuildTextThreadManager;
diff --git a/node_modules/discord.js/src/managers/MessageManager.js b/node_modules/discord.js/src/managers/MessageManager.js
new file mode 100644
index 0000000..6fb95eb
--- /dev/null
+++ b/node_modules/discord.js/src/managers/MessageManager.js
@@ -0,0 +1,263 @@
+'use strict';
+
+const { Collection } = require('@discordjs/collection');
+const { makeURLSearchParams } = require('@discordjs/rest');
+const { Routes } = require('discord-api-types/v10');
+const CachedManager = require('./CachedManager');
+const { DiscordjsTypeError, ErrorCodes } = require('../errors');
+const { Message } = require('../structures/Message');
+const MessagePayload = require('../structures/MessagePayload');
+const { MakeCacheOverrideSymbol } = require('../util/Symbols');
+const { resolvePartialEmoji } = require('../util/Util');
+
+/**
+ * Manages API methods for Messages and holds their cache.
+ * @extends {CachedManager}
+ * @abstract
+ */
+class MessageManager extends CachedManager {
+ static [MakeCacheOverrideSymbol] = MessageManager;
+
+ constructor(channel, iterable) {
+ super(channel.client, Message, iterable);
+
+ /**
+ * The channel that the messages belong to
+ * @type {TextBasedChannels}
+ */
+ this.channel = channel;
+ }
+
+ /**
+ * The cache of Messages
+ * @type {Collection<Snowflake, Message>}
+ * @name MessageManager#cache
+ */
+
+ _add(data, cache) {
+ return super._add(data, cache);
+ }
+
+ /**
+ * Data that can be resolved to a Message object. This can be:
+ * * A Message
+ * * A Snowflake
+ * @typedef {Message|Snowflake} MessageResolvable
+ */
+
+ /**
+ * Options used to fetch a message.
+ * @typedef {BaseFetchOptions} FetchMessageOptions
+ * @property {MessageResolvable} message The message to fetch
+ */
+
+ /**
+ * Options used to fetch multiple messages.
+ * <info>The `before`, `after`, and `around` parameters are mutually exclusive.</info>
+ * @typedef {Object} FetchMessagesOptions
+ * @property {number} [limit] The maximum number of messages to return
+ * @property {Snowflake} [before] Consider only messages before this id
+ * @property {Snowflake} [after] Consider only messages after this id
+ * @property {Snowflake} [around] Consider only messages around this id
+ * @property {boolean} [cache] Whether to cache the fetched messages
+ */
+
+ /**
+ * Fetches message(s) from a channel.
+ * <info>The returned Collection does not contain reaction users of the messages if they were not cached.
+ * Those need to be fetched separately in such a case.</info>
+ * @param {MessageResolvable|FetchMessageOptions|FetchMessagesOptions} [options] Options for fetching message(s)
+ * @returns {Promise<Message|Collection<Snowflake, Message>>}
+ * @example
+ * // Fetch a message
+ * channel.messages.fetch('99539446449315840')
+ * .then(message => console.log(message.content))
+ * .catch(console.error);
+ * @example
+ * // Fetch a maximum of 10 messages without caching
+ * channel.messages.fetch({ limit: 10, cache: false })
+ * .then(messages => console.log(`Received ${messages.size} messages`))
+ * .catch(console.error);
+ * @example
+ * // Fetch a maximum of 10 messages without caching around a message id
+ * channel.messages.fetch({ limit: 10, cache: false, around: '99539446449315840' })
+ * .then(messages => console.log(`Received ${messages.size} messages`))
+ * .catch(console.error);
+ * @example
+ * // Fetch messages and filter by a user id
+ * channel.messages.fetch()
+ * .then(messages => console.log(`${messages.filter(m => m.author.id === '84484653687267328').size} messages`))
+ * .catch(console.error);
+ */
+ fetch(options) {
+ if (!options) return this._fetchMany();
+ const { message, cache, force } = options;
+ const resolvedMessage = this.resolveId(message ?? options);
+ if (resolvedMessage) return this._fetchSingle({ message: resolvedMessage, cache, force });
+ return this._fetchMany(options);
+ }
+
+ async _fetchSingle({ message, cache, force = false }) {
+ if (!force) {
+ const existing = this.cache.get(message);
+ if (existing && !existing.partial) return existing;
+ }
+
+ const data = await this.client.rest.get(Routes.channelMessage(this.channel.id, message));
+ return this._add(data, cache);
+ }
+
+ async _fetchMany(options = {}) {
+ const data = await this.client.rest.get(Routes.channelMessages(this.channel.id), {
+ query: makeURLSearchParams(options),
+ });
+
+ return data.reduce((_data, message) => _data.set(message.id, this._add(message, options.cache)), new Collection());
+ }
+
+ /**
+ * Fetches the pinned messages of this channel and returns a collection of them.
+ * <info>The returned Collection does not contain any reaction data of the messages.
+ * Those need to be fetched separately.</info>
+ * @param {boolean} [cache=true] Whether to cache the message(s)
+ * @returns {Promise<Collection<Snowflake, Message>>}
+ * @example
+ * // Get pinned messages
+ * channel.messages.fetchPinned()
+ * .then(messages => console.log(`Received ${messages.size} messages`))
+ * .catch(console.error);
+ */
+ async fetchPinned(cache = true) {
+ const data = await this.client.rest.get(Routes.channelPins(this.channel.id));
+ const messages = new Collection();
+ for (const message of data) messages.set(message.id, this._add(message, cache));
+ return messages;
+ }
+
+ /**
+ * Resolves a {@link MessageResolvable} to a {@link Message} object.
+ * @method resolve
+ * @memberof MessageManager
+ * @instance
+ * @param {MessageResolvable} message The message resolvable to resolve
+ * @returns {?Message}
+ */
+
+ /**
+ * Resolves a {@link MessageResolvable} to a {@link Message} id.
+ * @method resolveId
+ * @memberof MessageManager
+ * @instance
+ * @param {MessageResolvable} message The message resolvable to resolve
+ * @returns {?Snowflake}
+ */
+
+ /**
+ * Options that can be passed to edit a message.
+ * @typedef {BaseMessageOptions} MessageEditOptions
+ * @property {AttachmentPayload[]} [attachments] An array of attachments to keep,
+ * all attachments will be kept if omitted
+ * @property {MessageFlags} [flags] Which flags to set for the message
+ * <info>Only the {@link MessageFlags.SuppressEmbeds} flag can be modified.</info>
+ */
+
+ /**
+ * Edits a message, even if it's not cached.
+ * @param {MessageResolvable} message The message to edit
+ * @param {string|MessageEditOptions|MessagePayload} options The options to edit the message
+ * @returns {Promise<Message>}
+ */
+ async edit(message, options) {
+ const messageId = this.resolveId(message);
+ if (!messageId) throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'message', 'MessageResolvable');
+
+ const { body, files } = await (options instanceof MessagePayload
+ ? options
+ : MessagePayload.create(message instanceof Message ? message : this, options)
+ )
+ .resolveBody()
+ .resolveFiles();
+ const d = await this.client.rest.patch(Routes.channelMessage(this.channel.id, messageId), { body, files });
+
+ const existing = this.cache.get(messageId);
+ if (existing) {
+ const clone = existing._clone();
+ clone._patch(d);
+ return clone;
+ }
+ return this._add(d);
+ }
+
+ /**
+ * Publishes a message in an announcement channel to all channels following it, even if it's not cached.
+ * @param {MessageResolvable} message The message to publish
+ * @returns {Promise<Message>}
+ */
+ async crosspost(message) {
+ message = this.resolveId(message);
+ if (!message) throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'message', 'MessageResolvable');
+
+ const data = await this.client.rest.post(Routes.channelMessageCrosspost(this.channel.id, message));
+ return this.cache.get(data.id) ?? this._add(data);
+ }
+
+ /**
+ * Pins a message to the channel's pinned messages, even if it's not cached.
+ * @param {MessageResolvable} message The message to pin
+ * @param {string} [reason] Reason for pinning
+ * @returns {Promise<void>}
+ */
+ async pin(message, reason) {
+ message = this.resolveId(message);
+ if (!message) throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'message', 'MessageResolvable');
+
+ await this.client.rest.put(Routes.channelPin(this.channel.id, message), { reason });
+ }
+
+ /**
+ * Unpins a message from the channel's pinned messages, even if it's not cached.
+ * @param {MessageResolvable} message The message to unpin
+ * @param {string} [reason] Reason for unpinning
+ * @returns {Promise<void>}
+ */
+ async unpin(message, reason) {
+ message = this.resolveId(message);
+ if (!message) throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'message', 'MessageResolvable');
+
+ await this.client.rest.delete(Routes.channelPin(this.channel.id, message), { reason });
+ }
+
+ /**
+ * Adds a reaction to a message, even if it's not cached.
+ * @param {MessageResolvable} message The message to react to
+ * @param {EmojiIdentifierResolvable} emoji The emoji to react with
+ * @returns {Promise<void>}
+ */
+ async react(message, emoji) {
+ message = this.resolveId(message);
+ if (!message) throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'message', 'MessageResolvable');
+
+ emoji = resolvePartialEmoji(emoji);
+ if (!emoji) throw new DiscordjsTypeError(ErrorCodes.EmojiType, 'emoji', 'EmojiIdentifierResolvable');
+
+ const emojiId = emoji.id
+ ? `${emoji.animated ? 'a:' : ''}${emoji.name}:${emoji.id}`
+ : encodeURIComponent(emoji.name);
+
+ await this.client.rest.put(Routes.channelMessageOwnReaction(this.channel.id, message, emojiId));
+ }
+
+ /**
+ * Deletes a message, even if it's not cached.
+ * @param {MessageResolvable} message The message to delete
+ * @returns {Promise<void>}
+ */
+ async delete(message) {
+ message = this.resolveId(message);
+ if (!message) throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'message', 'MessageResolvable');
+
+ await this.client.rest.delete(Routes.channelMessage(this.channel.id, message));
+ }
+}
+
+module.exports = MessageManager;
diff --git a/node_modules/discord.js/src/managers/PermissionOverwriteManager.js b/node_modules/discord.js/src/managers/PermissionOverwriteManager.js
new file mode 100644
index 0000000..011a649
--- /dev/null
+++ b/node_modules/discord.js/src/managers/PermissionOverwriteManager.js
@@ -0,0 +1,168 @@
+'use strict';
+
+const process = require('node:process');
+const { Collection } = require('@discordjs/collection');
+const { OverwriteType, Routes } = require('discord-api-types/v10');
+const CachedManager = require('./CachedManager');
+const { DiscordjsTypeError, ErrorCodes } = require('../errors');
+const PermissionOverwrites = require('../structures/PermissionOverwrites');
+const { Role } = require('../structures/Role');
+
+let cacheWarningEmitted = false;
+
+/**
+ * Manages API methods for guild channel permission overwrites and stores their cache.
+ * @extends {CachedManager}
+ */
+class PermissionOverwriteManager extends CachedManager {
+ constructor(channel, iterable) {
+ super(channel.client, PermissionOverwrites);
+ if (!cacheWarningEmitted && this._cache.constructor.name !== 'Collection') {
+ cacheWarningEmitted = true;
+ process.emitWarning(
+ `Overriding the cache handling for ${this.constructor.name} is unsupported and breaks functionality.`,
+ 'UnsupportedCacheOverwriteWarning',
+ );
+ }
+
+ /**
+ * The channel of the permission overwrite this manager belongs to
+ * @type {GuildChannel}
+ */
+ this.channel = channel;
+
+ if (iterable) {
+ for (const item of iterable) {
+ this._add(item);
+ }
+ }
+ }
+
+ /**
+ * The cache of this Manager
+ * @type {Collection<Snowflake, PermissionOverwrites>}
+ * @name PermissionOverwriteManager#cache
+ */
+
+ _add(data, cache) {
+ return super._add(data, cache, { extras: [this.channel] });
+ }
+
+ /**
+ * Replaces the permission overwrites in this channel.
+ * @param {OverwriteResolvable[]|Collection<Snowflake, OverwriteResolvable>} overwrites
+ * Permission overwrites the channel gets updated with
+ * @param {string} [reason] Reason for updating the channel overwrites
+ * @returns {Promise<GuildChannel>}
+ * @example
+ * message.channel.permissionOverwrites.set([
+ * {
+ * id: message.author.id,
+ * deny: [PermissionsFlagsBit.ViewChannel],
+ * },
+ * ], 'Needed to change permissions');
+ */
+ set(overwrites, reason) {
+ if (!Array.isArray(overwrites) && !(overwrites instanceof Collection)) {
+ return Promise.reject(
+ new DiscordjsTypeError(
+ ErrorCodes.InvalidType,
+ 'overwrites',
+ 'Array or Collection of Permission Overwrites',
+ true,
+ ),
+ );
+ }
+ return this.channel.edit({ permissionOverwrites: overwrites, reason });
+ }
+
+ /**
+ * Extra information about the overwrite.
+ * @typedef {Object} GuildChannelOverwriteOptions
+ * @property {string} [reason] The reason for creating/editing this overwrite
+ * @property {OverwriteType} [type] The type of overwrite. Use this to bypass automatic resolution of `type`
+ * that results in an error for an uncached structure
+ */
+
+ /**
+ * Creates or edits permission overwrites for a user or role in this channel.
+ * @param {RoleResolvable|UserResolvable} userOrRole The user or role to update
+ * @param {PermissionOverwriteOptions} options The options for the update
+ * @param {GuildChannelOverwriteOptions} [overwriteOptions] The extra information for the update
+ * @param {PermissionOverwrites} [existing] The existing overwrites to merge with this update
+ * @returns {Promise<GuildChannel>}
+ * @private
+ */
+ async upsert(userOrRole, options, overwriteOptions = {}, existing) {
+ let userOrRoleId = this.channel.guild.roles.resolveId(userOrRole) ?? this.client.users.resolveId(userOrRole);
+ let { type, reason } = overwriteOptions;
+ if (typeof type !== 'number') {
+ userOrRole = this.channel.guild.roles.resolve(userOrRole) ?? this.client.users.resolve(userOrRole);
+ if (!userOrRole) throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'parameter', 'User nor a Role');
+ type = userOrRole instanceof Role ? OverwriteType.Role : OverwriteType.Member;
+ }
+
+ const { allow, deny } = PermissionOverwrites.resolveOverwriteOptions(options, existing);
+
+ await this.client.rest.put(Routes.channelPermission(this.channel.id, userOrRoleId), {
+ body: { id: userOrRoleId, type, allow, deny },
+ reason,
+ });
+ return this.channel;
+ }
+
+ /**
+ * Creates permission overwrites for a user or role in this channel, or replaces them if already present.
+ * @param {RoleResolvable|UserResolvable} userOrRole The user or role to update
+ * @param {PermissionOverwriteOptions} options The options for the update
+ * @param {GuildChannelOverwriteOptions} [overwriteOptions] The extra information for the update
+ * @returns {Promise<GuildChannel>}
+ * @example
+ * // Create or Replace permission overwrites for a message author
+ * message.channel.permissionOverwrites.create(message.author, {
+ * SendMessages: false
+ * })
+ * .then(channel => console.log(channel.permissionOverwrites.cache.get(message.author.id)))
+ * .catch(console.error);
+ */
+ create(userOrRole, options, overwriteOptions) {
+ return this.upsert(userOrRole, options, overwriteOptions);
+ }
+
+ /**
+ * Edits permission overwrites for a user or role in this channel, or creates an entry if not already present.
+ * @param {RoleResolvable|UserResolvable} userOrRole The user or role to update
+ * @param {PermissionOverwriteOptions} options The options for the update
+ * @param {GuildChannelOverwriteOptions} [overwriteOptions] The extra information for the update
+ * @returns {Promise<GuildChannel>}
+ * @example
+ * // Edit or Create permission overwrites for a message author
+ * message.channel.permissionOverwrites.edit(message.author, {
+ * SendMessages: false
+ * })
+ * .then(channel => console.log(channel.permissionOverwrites.cache.get(message.author.id)))
+ * .catch(console.error);
+ */
+ edit(userOrRole, options, overwriteOptions) {
+ const existing = this.cache.get(
+ this.channel.guild.roles.resolveId(userOrRole) ?? this.client.users.resolveId(userOrRole),
+ );
+ return this.upsert(userOrRole, options, overwriteOptions, existing);
+ }
+
+ /**
+ * Deletes permission overwrites for a user or role in this channel.
+ * @param {UserResolvable|RoleResolvable} userOrRole The user or role to delete
+ * @param {string} [reason] The reason for deleting the overwrite
+ * @returns {Promise<GuildChannel>}
+ */
+ async delete(userOrRole, reason) {
+ const userOrRoleId = this.channel.guild.roles.resolveId(userOrRole) ?? this.client.users.resolveId(userOrRole);
+ if (!userOrRoleId) throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'parameter', 'User nor a Role');
+
+ await this.client.rest.delete(Routes.channelPermission(this.channel.id, userOrRoleId), { reason });
+ return this.channel;
+ }
+}
+
+module.exports = PermissionOverwriteManager;
diff --git a/node_modules/discord.js/src/managers/PresenceManager.js b/node_modules/discord.js/src/managers/PresenceManager.js
new file mode 100644
index 0000000..2d64834
--- /dev/null
+++ b/node_modules/discord.js/src/managers/PresenceManager.js
@@ -0,0 +1,58 @@
+'use strict';
+
+const CachedManager = require('./CachedManager');
+const { Presence } = require('../structures/Presence');
+
+/**
+ * Manages API methods for Presences and holds their cache.
+ * @extends {CachedManager}
+ */
+class PresenceManager extends CachedManager {
+ constructor(client, iterable) {
+ super(client, Presence, iterable);
+ }
+
+ /**
+ * The cache of Presences
+ * @type {Collection<Snowflake, Presence>}
+ * @name PresenceManager#cache
+ */
+
+ _add(data, cache) {
+ return super._add(data, cache, { id: data.user.id });
+ }
+
+ /**
+ * Data that can be resolved to a Presence object. This can be:
+ * * A Presence
+ * * A UserResolvable
+ * * A Snowflake
+ * @typedef {Presence|UserResolvable|Snowflake} PresenceResolvable
+ */
+
+ /**
+ * Resolves a {@link PresenceResolvable} to a {@link Presence} object.
+ * @param {PresenceResolvable} presence The presence resolvable to resolve
+ * @returns {?Presence}
+ */
+ resolve(presence) {
+ const presenceResolvable = super.resolve(presence);
+ if (presenceResolvable) return presenceResolvable;
+ const UserResolvable = this.client.users.resolveId(presence);
+ return super.resolve(UserResolvable);
+ }
+
+ /**
+ * Resolves a {@link PresenceResolvable} to a {@link Presence} id.
+ * @param {PresenceResolvable} presence The presence resolvable to resolve
+ * @returns {?Snowflake}
+ */
+ resolveId(presence) {
+ const presenceResolvable = super.resolveId(presence);
+ if (presenceResolvable) return presenceResolvable;
+ const userResolvable = this.client.users.resolveId(presence);
+ return this.cache.has(userResolvable) ? userResolvable : null;
+ }
+}
+
+module.exports = PresenceManager;
diff --git a/node_modules/discord.js/src/managers/ReactionManager.js b/node_modules/discord.js/src/managers/ReactionManager.js
new file mode 100644
index 0000000..5535882
--- /dev/null
+++ b/node_modules/discord.js/src/managers/ReactionManager.js
@@ -0,0 +1,68 @@
+'use strict';
+
+const { Routes } = require('discord-api-types/v10');
+const CachedManager = require('./CachedManager');
+const MessageReaction = require('../structures/MessageReaction');
+
+/**
+ * Manages API methods for reactions and holds their cache.
+ * @extends {CachedManager}
+ */
+class ReactionManager extends CachedManager {
+ constructor(message, iterable) {
+ super(message.client, MessageReaction, iterable);
+
+ /**
+ * The message that this manager belongs to
+ * @type {Message}
+ */
+ this.message = message;
+ }
+
+ _add(data, cache) {
+ return super._add(data, cache, { id: data.emoji.id ?? data.emoji.name, extras: [this.message] });
+ }
+
+ /**
+ * The reaction cache of this manager
+ * @type {Collection<string|Snowflake, MessageReaction>}
+ * @name ReactionManager#cache
+ */
+
+ /**
+ * Data that can be resolved to a MessageReaction object. This can be:
+ * * A MessageReaction
+ * * A Snowflake
+ * * The Unicode representation of an emoji
+ * @typedef {MessageReaction|Snowflake} MessageReactionResolvable
+ */
+
+ /**
+ * Resolves a {@link MessageReactionResolvable} to a {@link MessageReaction} object.
+ * @method resolve
+ * @memberof ReactionManager
+ * @instance
+ * @param {MessageReactionResolvable} reaction The MessageReaction to resolve
+ * @returns {?MessageReaction}
+ */
+
+ /**
+ * Resolves a {@link MessageReactionResolvable} to a {@link MessageReaction} id.
+ * @method resolveId
+ * @memberof ReactionManager
+ * @instance
+ * @param {MessageReactionResolvable} reaction The MessageReaction to resolve
+ * @returns {?Snowflake}
+ */
+
+ /**
+ * Removes all reactions from a message.
+ * @returns {Promise<Message>}
+ */
+ async removeAll() {
+ await this.client.rest.delete(Routes.channelMessageAllReactions(this.message.channelId, this.message.id));
+ return this.message;
+ }
+}
+
+module.exports = ReactionManager;
diff --git a/node_modules/discord.js/src/managers/ReactionUserManager.js b/node_modules/discord.js/src/managers/ReactionUserManager.js
new file mode 100644
index 0000000..014cea8
--- /dev/null
+++ b/node_modules/discord.js/src/managers/ReactionUserManager.js
@@ -0,0 +1,77 @@
+'use strict';
+
+const { Collection } = require('@discordjs/collection');
+const { makeURLSearchParams } = require('@discordjs/rest');
+const { Routes } = require('discord-api-types/v10');
+const CachedManager = require('./CachedManager');
+const { DiscordjsError, ErrorCodes } = require('../errors');
+const User = require('../structures/User');
+
+/**
+ * Manages API methods for users who reacted to a reaction and stores their cache.
+ * @extends {CachedManager}
+ */
+class ReactionUserManager extends CachedManager {
+ constructor(reaction, iterable) {
+ super(reaction.client, User, iterable);
+
+ /**
+ * The reaction that this manager belongs to
+ * @type {MessageReaction}
+ */
+ this.reaction = reaction;
+ }
+
+ /**
+ * The cache of this manager
+ * @type {Collection<Snowflake, User>}
+ * @name ReactionUserManager#cache
+ */
+
+ /**
+ * Options used to fetch users who gave a reaction.
+ * @typedef {Object} FetchReactionUsersOptions
+ * @property {number} [limit=100] The maximum amount of users to fetch, defaults to `100`
+ * @property {Snowflake} [after] Limit fetching users to those with an id greater than the supplied id
+ */
+
+ /**
+ * Fetches all the users that gave this reaction. Resolves with a collection of users, mapped by their ids.
+ * @param {FetchReactionUsersOptions} [options] Options for fetching the users
+ * @returns {Promise<Collection<Snowflake, User>>}
+ */
+ async fetch({ limit = 100, after } = {}) {
+ const message = this.reaction.message;
+ const query = makeURLSearchParams({ limit, after });
+ const data = await this.client.rest.get(
+ Routes.channelMessageReaction(message.channelId, message.id, this.reaction.emoji.identifier),
+ { query },
+ );
+ const users = new Collection();
+ for (const rawUser of data) {
+ const user = this.client.users._add(rawUser);
+ this.cache.set(user.id, user);
+ users.set(user.id, user);
+ }
+ return users;
+ }
+
+ /**
+ * Removes a user from this reaction.
+ * @param {UserResolvable} [user=this.client.user] The user to remove the reaction of
+ * @returns {Promise<MessageReaction>}
+ */
+ async remove(user = this.client.user) {
+ const userId = this.client.users.resolveId(user);
+ if (!userId) throw new DiscordjsError(ErrorCodes.ReactionResolveUser);
+ const message = this.reaction.message;
+ const route =
+ userId === this.client.user.id
+ ? Routes.channelMessageOwnReaction(message.channelId, message.id, this.reaction.emoji.identifier)
+ : Routes.channelMessageUserReaction(message.channelId, message.id, this.reaction.emoji.identifier, userId);
+ await this.client.rest.delete(route);
+ return this.reaction;
+ }
+}
+
+module.exports = ReactionUserManager;
diff --git a/node_modules/discord.js/src/managers/RoleManager.js b/node_modules/discord.js/src/managers/RoleManager.js
new file mode 100644
index 0000000..e0c4ed7
--- /dev/null
+++ b/node_modules/discord.js/src/managers/RoleManager.js
@@ -0,0 +1,360 @@
+'use strict';
+
+const process = require('node:process');
+const { Collection } = require('@discordjs/collection');
+const { Routes } = require('discord-api-types/v10');
+const CachedManager = require('./CachedManager');
+const { DiscordjsTypeError, ErrorCodes } = require('../errors');
+const { Role } = require('../structures/Role');
+const DataResolver = require('../util/DataResolver');
+const PermissionsBitField = require('../util/PermissionsBitField');
+const { setPosition, resolveColor } = require('../util/Util');
+
+let cacheWarningEmitted = false;
+
+/**
+ * Manages API methods for roles and stores their cache.
+ * @extends {CachedManager}
+ */
+class RoleManager extends CachedManager {
+ constructor(guild, iterable) {
+ super(guild.client, Role, iterable);
+ if (!cacheWarningEmitted && this._cache.constructor.name !== 'Collection') {
+ cacheWarningEmitted = true;
+ process.emitWarning(
+ `Overriding the cache handling for ${this.constructor.name} is unsupported and breaks functionality.`,
+ 'UnsupportedCacheOverwriteWarning',
+ );
+ }
+
+ /**
+ * The guild belonging to this manager
+ * @type {Guild}
+ */
+ this.guild = guild;
+ }
+
+ /**
+ * The role cache of this manager
+ * @type {Collection<Snowflake, Role>}
+ * @name RoleManager#cache
+ */
+
+ _add(data, cache) {
+ return super._add(data, cache, { extras: [this.guild] });
+ }
+
+ /**
+ * Obtains a role from Discord, or the role cache if they're already available.
+ * @param {Snowflake} [id] The role's id
+ * @param {BaseFetchOptions} [options] Additional options for this fetch
+ * @returns {Promise<?Role|Collection<Snowflake, Role>>}
+ * @example
+ * // Fetch all roles from the guild
+ * message.guild.roles.fetch()
+ * .then(roles => console.log(`There are ${roles.size} roles.`))
+ * .catch(console.error);
+ * @example
+ * // Fetch a single role
+ * message.guild.roles.fetch('222078108977594368')
+ * .then(role => console.log(`The role color is: ${role.color}`))
+ * .catch(console.error);
+ */
+ async fetch(id, { cache = true, force = false } = {}) {
+ if (id && !force) {
+ const existing = this.cache.get(id);
+ if (existing) return existing;
+ }
+
+ // We cannot fetch a single role, as of this commit's date, Discord API throws with 405
+ const data = await this.client.rest.get(Routes.guildRoles(this.guild.id));
+ const roles = new Collection();
+ for (const role of data) roles.set(role.id, this._add(role, cache));
+ return id ? roles.get(id) ?? null : roles;
+ }
+
+ /**
+ * Data that can be resolved to a Role object. This can be:
+ * * A Role
+ * * A Snowflake
+ * @typedef {Role|Snowflake} RoleResolvable
+ */
+
+ /**
+ * Resolves a {@link RoleResolvable} to a {@link Role} object.
+ * @method resolve
+ * @memberof RoleManager
+ * @instance
+ * @param {RoleResolvable} role The role resolvable to resolve
+ * @returns {?Role}
+ */
+
+ /**
+ * Resolves a {@link RoleResolvable} to a {@link Role} id.
+ * @method resolveId
+ * @memberof RoleManager
+ * @instance
+ * @param {RoleResolvable} role The role resolvable to resolve
+ * @returns {?Snowflake}
+ */
+
+ /**
+ * Options used to create a new role.
+ * @typedef {Object} RoleCreateOptions
+ * @property {string} [name] The name of the new role
+ * @property {ColorResolvable} [color] The data to create the role with
+ * @property {boolean} [hoist] Whether or not the new role should be hoisted
+ * @property {PermissionResolvable} [permissions] The permissions for the new role
+ * @property {number} [position] The position of the new role
+ * @property {boolean} [mentionable] Whether or not the new role should be mentionable
+ * @property {?(BufferResolvable|Base64Resolvable|EmojiResolvable)} [icon] The icon for the role
+ * <warn>The `EmojiResolvable` should belong to the same guild as the role.
+ * If not, pass the emoji's URL directly</warn>
+ * @property {?string} [unicodeEmoji] The unicode emoji for the role
+ * @property {string} [reason] The reason for creating this role
+ */
+
+ /**
+ * Creates a new role in the guild with given information.
+ * <warn>The position will silently reset to 1 if an invalid one is provided, or none.</warn>
+ * @param {RoleCreateOptions} [options] Options for creating the new role
+ * @returns {Promise<Role>}
+ * @example
+ * // Create a new role
+ * guild.roles.create()
+ * .then(console.log)
+ * .catch(console.error);
+ * @example
+ * // Create a new role with data and a reason
+ * guild.roles.create({
+ * name: 'Super Cool Blue People',
+ * color: Colors.Blue,
+ * reason: 'we needed a role for Super Cool People',
+ * })
+ * .then(console.log)
+ * .catch(console.error);
+ */
+ async create(options = {}) {
+ let { name, color, hoist, permissions, position, mentionable, reason, icon, unicodeEmoji } = options;
+ color &&= resolveColor(color);
+ if (permissions !== undefined) permissions = new PermissionsBitField(permissions);
+ if (icon) {
+ const guildEmojiURL = this.guild.emojis.resolve(icon)?.url;
+ icon = guildEmojiURL ? await DataResolver.resolveImage(guildEmojiURL) : await DataResolver.resolveImage(icon);
+ if (typeof icon !== 'string') icon = undefined;
+ }
+
+ const data = await this.client.rest.post(Routes.guildRoles(this.guild.id), {
+ body: {
+ name,
+ color,
+ hoist,
+ permissions,
+ mentionable,
+ icon,
+ unicode_emoji: unicodeEmoji,
+ },
+ reason,
+ });
+ const { role } = this.client.actions.GuildRoleCreate.handle({
+ guild_id: this.guild.id,
+ role: data,
+ });
+ if (position) return this.setPosition(role, position, { reason });
+ return role;
+ }
+
+ /**
+ * Options for editing a role
+ * @typedef {RoleData} RoleEditOptions
+ * @property {string} [reason] The reason for editing this role
+ */
+
+ /**
+ * Edits a role of the guild.
+ * @param {RoleResolvable} role The role to edit
+ * @param {RoleEditOptions} options The options to provide
+ * @returns {Promise<Role>}
+ * @example
+ * // Edit a role
+ * guild.roles.edit('222079219327434752', { name: 'buddies' })
+ * .then(updated => console.log(`Edited role name to ${updated.name}`))
+ * .catch(console.error);
+ */
+ async edit(role, options) {
+ role = this.resolve(role);
+ if (!role) throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'role', 'RoleResolvable');
+
+ if (typeof options.position === 'number') {
+ await this.setPosition(role, options.position, { reason: options.reason });
+ }
+
+ let icon = options.icon;
+ if (icon) {
+ const guildEmojiURL = this.guild.emojis.resolve(icon)?.url;
+ icon = guildEmojiURL ? await DataResolver.resolveImage(guildEmojiURL) : await DataResolver.resolveImage(icon);
+ if (typeof icon !== 'string') icon = undefined;
+ }
+
+ const body = {
+ name: options.name,
+ color: options.color === undefined ? undefined : resolveColor(options.color),
+ hoist: options.hoist,
+ permissions: options.permissions === undefined ? undefined : new PermissionsBitField(options.permissions),
+ mentionable: options.mentionable,
+ icon,
+ unicode_emoji: options.unicodeEmoji,
+ };
+
+ const d = await this.client.rest.patch(Routes.guildRole(this.guild.id, role.id), { body, reason: options.reason });
+
+ const clone = role._clone();
+ clone._patch(d);
+ return clone;
+ }
+
+ /**
+ * Deletes a role.
+ * @param {RoleResolvable} role The role to delete
+ * @param {string} [reason] Reason for deleting the role
+ * @returns {Promise<void>}
+ * @example
+ * // Delete a role
+ * guild.roles.delete('222079219327434752', 'The role needed to go')
+ * .then(() => console.log('Deleted the role'))
+ * .catch(console.error);
+ */
+ async delete(role, reason) {
+ const id = this.resolveId(role);
+ await this.client.rest.delete(Routes.guildRole(this.guild.id, id), { reason });
+ this.client.actions.GuildRoleDelete.handle({ guild_id: this.guild.id, role_id: id });
+ }
+
+ /**
+ * Sets the new position of the role.
+ * @param {RoleResolvable} role The role to change the position of
+ * @param {number} position The new position for the role
+ * @param {SetRolePositionOptions} [options] Options for setting the position
+ * @returns {Promise<Role>}
+ * @example
+ * // Set the position of the role
+ * guild.roles.setPosition('222197033908436994', 1)
+ * .then(updated => console.log(`Role position: ${updated.position}`))
+ * .catch(console.error);
+ */
+ async setPosition(role, position, { relative, reason } = {}) {
+ role = this.resolve(role);
+ if (!role) throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'role', 'RoleResolvable');
+ const updatedRoles = await setPosition(
+ role,
+ position,
+ relative,
+ this.guild._sortedRoles(),
+ this.client,
+ Routes.guildRoles(this.guild.id),
+ reason,
+ );
+
+ this.client.actions.GuildRolesPositionUpdate.handle({
+ guild_id: this.guild.id,
+ roles: updatedRoles,
+ });
+ return role;
+ }
+
+ /**
+ * The data needed for updating a guild role's position
+ * @typedef {Object} GuildRolePosition
+ * @property {RoleResolvable} role The role's id
+ * @property {number} position The position to update
+ */
+
+ /**
+ * Batch-updates the guild's role positions
+ * @param {GuildRolePosition[]} rolePositions Role positions to update
+ * @returns {Promise<Guild>}
+ * @example
+ * guild.roles.setPositions([{ role: roleId, position: updatedRoleIndex }])
+ * .then(guild => console.log(`Role positions updated for ${guild}`))
+ * .catch(console.error);
+ */
+ async setPositions(rolePositions) {
+ // Make sure rolePositions are prepared for API
+ rolePositions = rolePositions.map(o => ({
+ id: this.resolveId(o.role),
+ position: o.position,
+ }));
+
+ // Call the API to update role positions
+ await this.client.rest.patch(Routes.guildRoles(this.guild.id), { body: rolePositions });
+ return this.client.actions.GuildRolesPositionUpdate.handle({
+ guild_id: this.guild.id,
+ roles: rolePositions,
+ }).guild;
+ }
+
+ /**
+ * Compares the positions of two roles.
+ * @param {RoleResolvable} role1 First role to compare
+ * @param {RoleResolvable} role2 Second role to compare
+ * @returns {number} Negative number if the first role's position is lower (second role's is higher),
+ * positive number if the first's is higher (second's is lower), 0 if equal
+ */
+ comparePositions(role1, role2) {
+ const resolvedRole1 = this.resolve(role1);
+ const resolvedRole2 = this.resolve(role2);
+ if (!resolvedRole1 || !resolvedRole2) {
+ throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'role', 'Role nor a Snowflake');
+ }
+
+ const role1Position = resolvedRole1.position;
+ const role2Position = resolvedRole2.position;
+
+ if (role1Position === role2Position) {
+ return Number(BigInt(resolvedRole2.id) - BigInt(resolvedRole1.id));
+ }
+
+ return role1Position - role2Position;
+ }
+
+ /**
+ * Gets the managed role a user created when joining the guild, if any
+ * <info>Only ever available for bots</info>
+ * @param {UserResolvable} user The user to access the bot role for
+ * @returns {?Role}
+ */
+ botRoleFor(user) {
+ const userId = this.client.users.resolveId(user);
+ if (!userId) return null;
+ return this.cache.find(role => role.tags?.botId === userId) ?? null;
+ }
+
+ /**
+ * The `@everyone` role of the guild
+ * @type {Role}
+ * @readonly
+ */
+ get everyone() {
+ return this.cache.get(this.guild.id);
+ }
+
+ /**
+ * The premium subscriber role of the guild, if any
+ * @type {?Role}
+ * @readonly
+ */
+ get premiumSubscriberRole() {
+ return this.cache.find(role => role.tags?.premiumSubscriberRole) ?? null;
+ }
+
+ /**
+ * The role with the highest position in the cache
+ * @type {Role}
+ * @readonly
+ */
+ get highest() {
+ return this.cache.reduce((prev, role) => (role.comparePositionTo(prev) > 0 ? role : prev), this.cache.first());
+ }
+}
+
+module.exports = RoleManager;
diff --git a/node_modules/discord.js/src/managers/StageInstanceManager.js b/node_modules/discord.js/src/managers/StageInstanceManager.js
new file mode 100644
index 0000000..ea037cf
--- /dev/null
+++ b/node_modules/discord.js/src/managers/StageInstanceManager.js
@@ -0,0 +1,154 @@
+'use strict';
+
+const { Routes } = require('discord-api-types/v10');
+const CachedManager = require('./CachedManager');
+const { DiscordjsTypeError, DiscordjsError, ErrorCodes } = require('../errors');
+const { StageInstance } = require('../structures/StageInstance');
+
+/**
+ * Manages API methods for {@link StageInstance} objects and holds their cache.
+ * @extends {CachedManager}
+ */
+class StageInstanceManager extends CachedManager {
+ constructor(guild, iterable) {
+ super(guild.client, StageInstance, iterable);
+
+ /**
+ * The guild this manager belongs to
+ * @type {Guild}
+ */
+ this.guild = guild;
+ }
+
+ /**
+ * The cache of this Manager
+ * @type {Collection<Snowflake, StageInstance>}
+ * @name StageInstanceManager#cache
+ */
+
+ /**
+ * Options used to create a stage instance.
+ * @typedef {Object} StageInstanceCreateOptions
+ * @property {string} topic The topic of the stage instance
+ * @property {StageInstancePrivacyLevel} [privacyLevel] The privacy level of the stage instance
+ * @property {boolean} [sendStartNotification] Whether to notify `@everyone` that the stage instance has started
+ */
+
+ /**
+ * Data that can be resolved to a Stage Channel object. This can be:
+ * * A StageChannel
+ * * A Snowflake
+ * @typedef {StageChannel|Snowflake} StageChannelResolvable
+ */
+
+ /**
+ * Creates a new stage instance.
+ * @param {StageChannelResolvable} channel The stage channel to associate the created stage instance to
+ * @param {StageInstanceCreateOptions} options The options to create the stage instance
+ * @returns {Promise<StageInstance>}
+ * @example
+ * // Create a stage instance
+ * guild.stageInstances.create('1234567890123456789', {
+ * topic: 'A very creative topic',
+ * privacyLevel: GuildPrivacyLevel.GuildOnly
+ * })
+ * .then(stageInstance => console.log(stageInstance))
+ * .catch(console.error);
+ */
+ async create(channel, options) {
+ const channelId = this.guild.channels.resolveId(channel);
+ if (!channelId) throw new DiscordjsError(ErrorCodes.StageChannelResolve);
+ if (typeof options !== 'object') throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'options', 'object', true);
+ let { topic, privacyLevel, sendStartNotification } = options;
+
+ const data = await this.client.rest.post(Routes.stageInstances(), {
+ body: {
+ channel_id: channelId,
+ topic,
+ privacy_level: privacyLevel,
+ send_start_notification: sendStartNotification,
+ },
+ });
+
+ return this._add(data);
+ }
+
+ /**
+ * Fetches the stage instance associated with a stage channel, if it exists.
+ * @param {StageChannelResolvable} channel The stage channel whose associated stage instance is to be fetched
+ * @param {BaseFetchOptions} [options] Additional options for this fetch
+ * @returns {Promise<StageInstance>}
+ * @example
+ * // Fetch a stage instance
+ * guild.stageInstances.fetch('1234567890123456789')
+ * .then(stageInstance => console.log(stageInstance))
+ * .catch(console.error);
+ */
+ async fetch(channel, { cache = true, force = false } = {}) {
+ const channelId = this.guild.channels.resolveId(channel);
+ if (!channelId) throw new DiscordjsError(ErrorCodes.StageChannelResolve);
+
+ if (!force) {
+ const existing = this.cache.find(stageInstance => stageInstance.channelId === channelId);
+ if (existing) return existing;
+ }
+
+ const data = await this.client.rest.get(Routes.stageInstance(channelId));
+ return this._add(data, cache);
+ }
+
+ /**
+ * Options used to edit an existing stage instance.
+ * @typedef {Object} StageInstanceEditOptions
+ * @property {string} [topic] The new topic of the stage instance
+ * @property {StageInstancePrivacyLevel} [privacyLevel] The new privacy level of the stage instance
+ */
+
+ /**
+ * Edits an existing stage instance.
+ * @param {StageChannelResolvable} channel The stage channel whose associated stage instance is to be edited
+ * @param {StageInstanceEditOptions} options The options to edit the stage instance
+ * @returns {Promise<StageInstance>}
+ * @example
+ * // Edit a stage instance
+ * guild.stageInstances.edit('1234567890123456789', { topic: 'new topic' })
+ * .then(stageInstance => console.log(stageInstance))
+ * .catch(console.error);
+ */
+ async edit(channel, options) {
+ if (typeof options !== 'object') throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'options', 'object', true);
+ const channelId = this.guild.channels.resolveId(channel);
+ if (!channelId) throw new DiscordjsError(ErrorCodes.StageChannelResolve);
+
+ let { topic, privacyLevel } = options;
+
+ const data = await this.client.rest.patch(Routes.stageInstance(channelId), {
+ body: {
+ topic,
+ privacy_level: privacyLevel,
+ },
+ });
+
+ if (this.cache.has(data.id)) {
+ const clone = this.cache.get(data.id)._clone();
+ clone._patch(data);
+ return clone;
+ }
+
+ return this._add(data);
+ }
+
+ /**
+ * Deletes an existing stage instance.
+ * @param {StageChannelResolvable} channel The stage channel whose associated stage instance is to be deleted
+ * @returns {Promise<void>}
+ */
+ async delete(channel) {
+ const channelId = this.guild.channels.resolveId(channel);
+ if (!channelId) throw new DiscordjsError(ErrorCodes.StageChannelResolve);
+
+ await this.client.rest.delete(Routes.stageInstance(channelId));
+ }
+}
+
+module.exports = StageInstanceManager;
diff --git a/node_modules/discord.js/src/managers/ThreadManager.js b/node_modules/discord.js/src/managers/ThreadManager.js
new file mode 100644
index 0000000..17569f5
--- /dev/null
+++ b/node_modules/discord.js/src/managers/ThreadManager.js
@@ -0,0 +1,207 @@
+'use strict';
+
+const { Collection } = require('@discordjs/collection');
+const { makeURLSearchParams } = require('@discordjs/rest');
+const { Routes } = require('discord-api-types/v10');
+const CachedManager = require('./CachedManager');
+const { DiscordjsTypeError, ErrorCodes } = require('../errors');
+const ThreadChannel = require('../structures/ThreadChannel');
+const { MakeCacheOverrideSymbol } = require('../util/Symbols');
+
+/**
+ * Manages API methods for thread-based channels and stores their cache.
+ * @extends {CachedManager}
+ */
+class ThreadManager extends CachedManager {
+ static [MakeCacheOverrideSymbol] = ThreadManager;
+
+ constructor(channel, iterable) {
+ super(channel.client, ThreadChannel, iterable);
+
+ /**
+ * The channel this Manager belongs to
+ * @type {TextChannel|NewsChannel|ForumChannel}
+ */
+ this.channel = channel;
+ }
+
+ /**
+ * Data that can be resolved to a Thread Channel object. This can be:
+ * * A ThreadChannel object
+ * * A Snowflake
+ * @typedef {ThreadChannel|Snowflake} ThreadChannelResolvable
+ */
+
+ /**
+ * The cache of this Manager
+ * @type {Collection<Snowflake, ThreadChannel>}
+ * @name ThreadManager#cache
+ */
+
+ _add(thread) {
+ const existing = this.cache.get(thread.id);
+ if (existing) return existing;
+ this.cache.set(thread.id, thread);
+ return thread;
+ }
+
+ /**
+ * Resolves a {@link ThreadChannelResolvable} to a {@link ThreadChannel} object.
+ * @method resolve
+ * @memberof ThreadManager
+ * @instance
+ * @param {ThreadChannelResolvable} thread The ThreadChannel resolvable to resolve
+ * @returns {?ThreadChannel}
+ */
+
+ /**
+ * Resolves a {@link ThreadChannelResolvable} to a {@link ThreadChannel} id.
+ * @method resolveId
+ * @memberof ThreadManager
+ * @instance
+ * @param {ThreadChannelResolvable} thread The ThreadChannel resolvable to resolve
+ * @returns {?Snowflake}
+ */
+
+ /**
+ * Options for creating a thread. <warn>Only one of `startMessage` or `type` can be defined.</warn>
+ * @typedef {StartThreadOptions} ThreadCreateOptions
+ * @property {MessageResolvable} [startMessage] The message to start a thread from. <warn>If this is defined then type
+ * of thread gets automatically defined and cannot be changed. The provided `type` field will be ignored</warn>
+ * @property {ChannelType.AnnouncementThread|ChannelType.PublicThread|ChannelType.PrivateThread} [type]
+ * The type of thread to create.
+ * Defaults to {@link ChannelType.PublicThread} if created in a {@link TextChannel}
+ * <warn>When creating threads in a {@link NewsChannel} this is ignored and is always
+ * {@link ChannelType.AnnouncementThread}</warn>
+ * @property {boolean} [invitable] Whether non-moderators can add other non-moderators to the thread
+ * <info>Can only be set when type will be {@link ChannelType.PrivateThread}</info>
+ */
+
+ /**
+ * Options for fetching multiple threads.
+ * @typedef {Object} FetchThreadsOptions
+ * @property {FetchArchivedThreadOptions} [archived] Options used to fetch archived threads
+ */
+
+ /**
+ * Obtains a thread from Discord, or the channel cache if it's already available.
+ * @param {ThreadChannelResolvable|FetchThreadsOptions} [options] The options to fetch threads. If it is a
+ * ThreadChannelResolvable then the specified thread will be fetched. Fetches all active threads if `undefined`
+ * @param {BaseFetchOptions} [cacheOptions] Additional options for this fetch. <warn>The `force` field gets ignored
+ * if `options` is not a {@link ThreadChannelResolvable}</warn>
+ * @returns {Promise<?(ThreadChannel|FetchedThreads|FetchedThreadsMore)>}
+ * {@link FetchedThreads} if active & {@link FetchedThreadsMore} if archived.
+ * @example
+ * // Fetch a thread by its id
+ * channel.threads.fetch('831955138126104859')
+ * .then(channel => console.log(channel.name))
+ * .catch(console.error);
+ */
+ fetch(options, { cache, force } = {}) {
+ if (!options) return this.fetchActive(cache);
+ const channel = this.client.channels.resolveId(options);
+ if (channel) return this.client.channels.fetch(channel, { cache, force });
+ if (options.archived) {
+ return this.fetchArchived(options.archived, cache);
+ }
+ return this.fetchActive(cache);
+ }
+
+ /**
+ * Data that can be resolved to a Date object. This can be:
+ * * A Date object
+ * * A number representing a timestamp
+ * * An [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601) string
+ * @typedef {Date|number|string} DateResolvable
+ */
+
+ /**
+ * The options used to fetch archived threads.
+ * @typedef {Object} FetchArchivedThreadOptions
+ * @property {string} [type='public'] The type of threads to fetch (`public` or `private`)
+ * @property {boolean} [fetchAll=false] Whether to fetch **all** archived threads when `type` is `private`
+ * <info>This property requires the {@link PermissionFlagsBits.ManageThreads} permission if `true`.</info>
+ * @property {DateResolvable|ThreadChannelResolvable} [before] Only return threads that were archived before this Date
+ * or Snowflake
+ * <warn>Must be a {@link ThreadChannelResolvable} when `type` is `private` and `fetchAll` is `false`.</warn>
+ * @property {number} [limit] Maximum number of threads to return
+ */
+
+ /**
+ * Data returned from fetching multiple threads.
+ * @typedef {FetchedThreads} FetchedThreadsMore
+ * @property {?boolean} hasMore Whether there are potentially additional threads that require a subsequent call
+ */
+
+ /**
+ * Obtains a set of archived threads from Discord.
+ * <info>This method requires the {@link PermissionFlagsBits.ReadMessageHistory} permission
+ * in the parent channel.</info>
+ * @param {FetchArchivedThreadOptions} [options] The options to fetch archived threads
+ * @param {boolean} [cache=true] Whether to cache the new thread objects if they aren't already
+ * @returns {Promise<FetchedThreadsMore>}
+ */
+ async fetchArchived({ type = 'public', fetchAll = false, before, limit } = {}, cache = true) {
+ let path = Routes.channelThreads(this.channel.id, type);
+ if (type === 'private' && !fetchAll) {
+ path = Routes.channelJoinedArchivedThreads(this.channel.id);
+ }
+ let timestamp;
+ let id;
+ const query = makeURLSearchParams({ limit });
+ if (before !== undefined) {
+ if (before instanceof ThreadChannel || /^\d{17,19}$/.test(String(before))) {
+ id = this.resolveId(before);
+ timestamp = this.resolve(before)?.archivedAt?.toISOString();
+ const toUse = type === 'private' && !fetchAll ? id : timestamp;
+ if (toUse) {
+ query.set('before', toUse);
+ }
+ } else {
+ try {
+ timestamp = new Date(before).toISOString();
+ if (type === 'public' || fetchAll) {
+ query.set('before', timestamp);
+ }
+ } catch {
+ throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'before', 'DateResolvable or ThreadChannelResolvable');
+ }
+ }
+ }
+
+ const raw = await this.client.rest.get(path, { query });
+ return this.constructor._mapThreads(raw, this.client, { parent: this.channel, cache });
+ }
+
+ /**
+ * Obtains all active threads in the channel.
+ * @param {boolean} [cache=true] Whether to cache the fetched data
+ * @returns {Promise<FetchedThreads>}
+ */
+ async fetchActive(cache = true) {
+ const data = await this.channel.guild.channels.rawFetchGuildActiveThreads();
+ return this.constructor._mapThreads(data, this.client, { parent: this.channel, cache });
+ }
+
+ static _mapThreads(rawThreads, client, { parent, guild, cache }) {
+ const threads = rawThreads.threads.reduce((coll, raw) => {
+ const thread = client.channels._add(raw, guild ?? parent?.guild, { cache });
+ if (parent && thread.parentId !== parent.id) return coll;
+ return coll.set(thread.id, thread);
+ }, new Collection());
+
+ // Discord sends the thread id as id in this object
+ const threadMembers = rawThreads.members.reduce((coll, raw) => {
+ const thread = threads.get(raw.id);
+ return thread ? coll.set(raw.user_id, thread.members._add(raw)) : coll;
+ }, new Collection());
+
+ const response = { threads, members: threadMembers };
+
+ // The GET `/guilds/{guild.id}/threads/active` route does not return `has_more`.
+ if ('has_more' in rawThreads) response.hasMore = rawThreads.has_more;
+ return response;
+ }
+}
+
+module.exports = ThreadManager;
diff --git a/node_modules/discord.js/src/managers/ThreadMemberManager.js b/node_modules/discord.js/src/managers/ThreadMemberManager.js
new file mode 100644
index 0000000..c138aa3
--- /dev/null
+++ b/node_modules/discord.js/src/managers/ThreadMemberManager.js
@@ -0,0 +1,182 @@
+'use strict';
+
+const { Collection } = require('@discordjs/collection');
+const { makeURLSearchParams } = require('@discordjs/rest');
+const { Routes } = require('discord-api-types/v10');
+const CachedManager = require('./CachedManager');
+const { DiscordjsTypeError, ErrorCodes } = require('../errors');
+const ThreadMember = require('../structures/ThreadMember');
+
+/**
+ * Manages API methods for GuildMembers and stores their cache.
+ * @extends {CachedManager}
+ */
+class ThreadMemberManager extends CachedManager {
+ constructor(thread, iterable) {
+ super(thread.client, ThreadMember, iterable);
+
+ /**
+ * The thread this manager belongs to
+ * @type {ThreadChannel}
+ */
+ this.thread = thread;
+ }
+
+ /**
+ * The cache of this Manager
+ * @type {Collection<Snowflake, ThreadMember>}
+ * @name ThreadMemberManager#cache
+ */
+
+ _add(data, cache = true) {
+ const existing = this.cache.get(data.user_id);
+ if (cache) existing?._patch(data, { cache });
+ if (existing) return existing;
+
+ const member = new ThreadMember(this.thread, data, { cache });
+ if (cache) this.cache.set(data.user_id, member);
+ return member;
+ }
+
+ /**
+ * Fetches the client user as a ThreadMember of the thread.
+ * @param {BaseFetchOptions} [options] The options for fetching the member
+ * @returns {Promise<ThreadMember>}
+ */
+ fetchMe(options) {
+ return this.fetch({ ...options, member: this.client.user.id });
+ }
+
+ /**
+ * The client user as a ThreadMember of this ThreadChannel
+ * @type {?ThreadMember}
+ * @readonly
+ */
+ get me() {
+ return this.resolve(this.client.user.id);
+ }
+
+ /**
+ * Data that resolves to give a ThreadMember object. This can be:
+ * * A ThreadMember object
+ * * A User resolvable
+ * @typedef {ThreadMember|UserResolvable} ThreadMemberResolvable
+ */
+
+ /**
+ * Resolves a {@link ThreadMemberResolvable} to a {@link ThreadMember} object.
+ * @param {ThreadMemberResolvable} member The user that is part of the thread
+ * @returns {?GuildMember}
+ */
+ resolve(member) {
+ const memberResolvable = super.resolve(member);
+ if (memberResolvable) return memberResolvable;
+ const userResolvable = this.client.users.resolveId(member);
+ if (userResolvable) return super.resolve(userResolvable);
+ return null;
+ }
+
+ /**
+ * Resolves a {@link ThreadMemberResolvable} to a {@link ThreadMember} id string.
+ * @param {ThreadMemberResolvable} member The user that is part of the guild
+ * @returns {?Snowflake}
+ */
+ resolveId(member) {
+ const memberResolvable = super.resolveId(member);
+ if (memberResolvable) return memberResolvable;
+ const userResolvable = this.client.users.resolveId(member);
+ return this.cache.has(userResolvable) ? userResolvable : null;
+ }
+
+ /**
+ * Adds a member to the thread.
+ * @param {UserResolvable|'@me'} member The member to add
+ * @param {string} [reason] The reason for adding this member
+ * @returns {Promise<Snowflake>}
+ */
+ async add(member, reason) {
+ const id = member === '@me' ? member : this.client.users.resolveId(member);
+ if (!id) throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'member', 'UserResolvable');
+ await this.client.rest.put(Routes.threadMembers(this.thread.id, id), { reason });
+ return id;
+ }
+
+ /**
+ * Remove a user from the thread.
+ * @param {Snowflake|'@me'} id The id of the member to remove
+ * @param {string} [reason] The reason for removing this member from the thread
+ * @returns {Promise<Snowflake>}
+ */
+ async remove(id, reason) {
+ await this.client.rest.delete(Routes.threadMembers(this.thread.id, id), { reason });
+ return id;
+ }
+
+ /**
+ * Options used to fetch a thread member.
+ * @typedef {BaseFetchOptions} FetchThreadMemberOptions
+ * @property {ThreadMemberResolvable} member The thread member to fetch
+ * @property {boolean} [withMember] Whether to also return the guild member associated with this thread member
+ */
+
+ /**
+ * Options used to fetch multiple thread members with guild member data.
+ * <info>With `withMember` set to `true`, pagination is enabled.</info>
+ * @typedef {Object} FetchThreadMembersWithGuildMemberDataOptions
+ * @property {true} withMember Whether to also return the guild member data
+ * @property {Snowflake} [after] Consider only thread members after this id
+ * @property {number} [limit] The maximum number of thread members to return
+ * @property {boolean} [cache] Whether to cache the fetched thread members and guild members
+ */
+
+ /**
+ * Options used to fetch multiple thread members without guild member data.
+ * @typedef {Object} FetchThreadMembersWithoutGuildMemberDataOptions
+ * @property {false} [withMember] Whether to also return the guild member data
+ * @property {boolean} [cache] Whether to cache the fetched thread members
+ */
+
+ /**
+ * Options used to fetch multiple thread members.
+ * @typedef {FetchThreadMembersWithGuildMemberDataOptions|
+ * FetchThreadMembersWithoutGuildMemberDataOptions} FetchThreadMembersOptions
+ */
+
+ /**
+ * Fetches thread member(s) from Discord.
+ * <info>This method requires the {@link GatewayIntentBits.GuildMembers} privileged gateway intent.</info>
+ * @param {ThreadMemberResolvable|FetchThreadMemberOptions|FetchThreadMembersOptions} [options]
+ * Options for fetching thread member(s)
+ * @returns {Promise<ThreadMember|Collection<Snowflake, ThreadMember>>}
+ */
+ fetch(options) {
+ if (!options) return this._fetchMany();
+ const { member, withMember, cache, force } = options;
+ const resolvedMember = this.resolveId(member ?? options);
+ if (resolvedMember) return this._fetchSingle({ member: resolvedMember, withMember, cache, force });
+ return this._fetchMany(options);
+ }
+
+ async _fetchSingle({ member, withMember, cache, force = false }) {
+ if (!force) {
+ const existing = this.cache.get(member);
+ if (existing) return existing;
+ }
+
+ const data = await this.client.rest.get(Routes.threadMembers(this.thread.id, member), {
+ query: makeURLSearchParams({ with_member: withMember }),
+ });
+
+ return this._add(data, cache);
+ }
+
+ async _fetchMany({ withMember, after, limit, cache } = {}) {
+ const data = await this.client.rest.get(Routes.threadMembers(this.thread.id), {
+ query: makeURLSearchParams({ with_member: withMember, after, limit }),
+ });
+
+ return data.reduce((col, member) => col.set(member.user_id, this._add(member, cache)), new Collection());
+ }
+}
+
+module.exports = ThreadMemberManager;
diff --git a/node_modules/discord.js/src/managers/UserManager.js b/node_modules/discord.js/src/managers/UserManager.js
new file mode 100644
index 0000000..24478f6
--- /dev/null
+++ b/node_modules/discord.js/src/managers/UserManager.js
@@ -0,0 +1,139 @@
+'use strict';
+
+const { ChannelType, Routes } = require('discord-api-types/v10');
+const CachedManager = require('./CachedManager');
+const { DiscordjsError, ErrorCodes } = require('../errors');
+const { GuildMember } = require('../structures/GuildMember');
+const { Message } = require('../structures/Message');
+const ThreadMember = require('../structures/ThreadMember');
+const User = require('../structures/User');
+
+/**
+ * Manages API methods for users and stores their cache.
+ * @extends {CachedManager}
+ */
+class UserManager extends CachedManager {
+ constructor(client, iterable) {
+ super(client, User, iterable);
+ }
+
+ /**
+ * The cache of this manager
+ * @type {Collection<Snowflake, User>}
+ * @name UserManager#cache
+ */
+
+ /**
+ * Data that resolves to give a User object. This can be:
+ * * A User object
+ * * A Snowflake
+ * * A Message object (resolves to the message author)
+ * * A GuildMember object
+ * * A ThreadMember object
+ * @typedef {User|Snowflake|Message|GuildMember|ThreadMember} UserResolvable
+ */
+
+ /**
+ * The DM between the client's user and a user
+ * @param {Snowflake} userId The user id
+ * @returns {?DMChannel}
+ * @private
+ */
+ dmChannel(userId) {
+ return this.client.channels.cache.find(c => c.type === ChannelType.DM && c.recipientId === userId) ?? null;
+ }
+
+ /**
+ * Creates a {@link DMChannel} between the client and a user.
+ * @param {UserResolvable} user The UserResolvable to identify
+ * @param {BaseFetchOptions} [options] Additional options for this fetch
+ * @returns {Promise<DMChannel>}
+ */
+ async createDM(user, { cache = true, force = false } = {}) {
+ const id = this.resolveId(user);
+
+ if (!force) {
+ const dmChannel = this.dmChannel(id);
+ if (dmChannel && !dmChannel.partial) return dmChannel;
+ }
+
+ const data = await this.client.rest.post(Routes.userChannels(), { body: { recipient_id: id } });
+ return this.client.channels._add(data, null, { cache });
+ }
+
+ /**
+ * Deletes a {@link DMChannel} (if one exists) between the client and a user. Resolves with the channel if successful.
+ * @param {UserResolvable} user The UserResolvable to identify
+ * @returns {Promise<DMChannel>}
+ */
+ async deleteDM(user) {
+ const id = this.resolveId(user);
+ const dmChannel = this.dmChannel(id);
+ if (!dmChannel) throw new DiscordjsError(ErrorCodes.UserNoDMChannel);
+ await this.client.rest.delete(Routes.channel(dmChannel.id));
+ this.client.channels._remove(dmChannel.id);
+ return dmChannel;
+ }
+
+ /**
+ * Obtains a user from Discord, or the user cache if it's already available.
+ * @param {UserResolvable} user The user to fetch
+ * @param {BaseFetchOptions} [options] Additional options for this fetch
+ * @returns {Promise<User>}
+ */
+ async fetch(user, { cache = true, force = false } = {}) {
+ const id = this.resolveId(user);
+ if (!force) {
+ const existing = this.cache.get(id);
+ if (existing && !existing.partial) return existing;
+ }
+
+ const data = await this.client.rest.get(Routes.user(id));
+ return this._add(data, cache);
+ }
+
+ /**
+ * Fetches a user's flags.
+ * @param {UserResolvable} user The UserResolvable to identify
+ * @param {BaseFetchOptions} [options] Additional options for this fetch
+ * @returns {Promise<UserFlagsBitField>}
+ */
+ async fetchFlags(user, options) {
+ return (await this.fetch(user, options)).flags;
+ }
+
+ /**
+ * Sends a message to a user.
+ * @param {UserResolvable} user The UserResolvable to identify
+ * @param {string|MessagePayload|MessageCreateOptions} options The options to provide
+ * @returns {Promise<Message>}
+ */
+ async send(user, options) {
+ return (await this.createDM(user)).send(options);
+ }
+
+ /**
+ * Resolves a {@link UserResolvable} to a {@link User} object.
+ * @param {UserResolvable} user The UserResolvable to identify
+ * @returns {?User}
+ */
+ resolve(user) {
+ if (user instanceof GuildMember || user instanceof ThreadMember) return user.user;
+ if (user instanceof Message) return user.author;
+ return super.resolve(user);
+ }
+
+ /**
+ * Resolves a {@link UserResolvable} to a {@link User} id.
+ * @param {UserResolvable} user The UserResolvable to identify
+ * @returns {?Snowflake}
+ */
+ resolveId(user) {
+ if (user instanceof ThreadMember) return user.id;
+ if (user instanceof GuildMember) return user.user.id;
+ if (user instanceof Message) return user.author.id;
+ return super.resolveId(user);
+ }
+}
+
+module.exports = UserManager;
diff --git a/node_modules/discord.js/src/managers/VoiceStateManager.js b/node_modules/discord.js/src/managers/VoiceStateManager.js
new file mode 100644
index 0000000..c42fdd2
--- /dev/null
+++ b/node_modules/discord.js/src/managers/VoiceStateManager.js
@@ -0,0 +1,37 @@
+'use strict';
+
+const CachedManager = require('./CachedManager');
+const VoiceState = require('../structures/VoiceState');
+
+/**
+ * Manages API methods for VoiceStates and stores their cache.
+ * @extends {CachedManager}
+ */
+class VoiceStateManager extends CachedManager {
+ constructor(guild, iterable) {
+ super(guild.client, VoiceState, iterable);
+
+ /**
+ * The guild this manager belongs to
+ * @type {Guild}
+ */
+ this.guild = guild;
+ }
+
+ /**
+ * The cache of this manager
+ * @type {Collection<Snowflake, VoiceState>}
+ * @name VoiceStateManager#cache
+ */
+
+ _add(data, cache = true) {
+ const existing = this.cache.get(data.user_id);
+ if (existing) return existing._patch(data);
+
+ const entry = new this.holds(this.guild, data);
+ if (cache) this.cache.set(data.user_id, entry);
+ return entry;
+ }
+}
+
+module.exports = VoiceStateManager;