diff --git a/discord.11.5-dev.js b/discord.11.5-dev.js index 65026dde..72c8e585 100644 --- a/discord.11.5-dev.js +++ b/discord.11.5-dev.js @@ -1541,7 +1541,7 @@ eval("const Channel = __webpack_require__(/*! ./Channel */ \"./src/structures/Ch /*! ModuleConcatenation bailout: Module is not an ECMAScript module */ /***/ (function(module, exports, __webpack_require__) { -eval("const util = __webpack_require__(/*! util */ \"./node_modules/util/util.js\");\nconst Long = __webpack_require__(/*! long */ \"./node_modules/long/src/long.js\");\nconst User = __webpack_require__(/*! ./User */ \"./src/structures/User.js\");\nconst Role = __webpack_require__(/*! ./Role */ \"./src/structures/Role.js\");\nconst Emoji = __webpack_require__(/*! ./Emoji */ \"./src/structures/Emoji.js\");\nconst Presence = __webpack_require__(/*! ./Presence */ \"./src/structures/Presence.js\").Presence;\nconst GuildMember = __webpack_require__(/*! ./GuildMember */ \"./src/structures/GuildMember.js\");\nconst Constants = __webpack_require__(/*! ../util/Constants */ \"./src/util/Constants.js\");\nconst Collection = __webpack_require__(/*! ../util/Collection */ \"./src/util/Collection.js\");\nconst Util = __webpack_require__(/*! ../util/Util */ \"./src/util/Util.js\");\nconst Snowflake = __webpack_require__(/*! ../util/Snowflake */ \"./src/util/Snowflake.js\");\n\n/**\n * Represents a guild (or a server) on Discord.\n * It's recommended to see if a guild is available before performing operations or reading data from it. You can\n * check this with `guild.available`.\n */\nclass Guild {\n constructor(client, data) {\n /**\n * The client that created the instance of the guild\n * @name Guild#client\n * @type {Client}\n * @readonly\n */\n Object.defineProperty(this, 'client', { value: client });\n\n /**\n * A collection of members that are in this guild. The key is the member's ID, the value is the member\n * @type {Collection}\n */\n this.members = new Collection();\n\n /**\n * A collection of channels that are in this guild. The key is the channel's ID, the value is the channel\n * @type {Collection}\n */\n this.channels = new Collection();\n\n /**\n * A collection of roles that are in this guild. The key is the role's ID, the value is the role\n * @type {Collection}\n */\n this.roles = new Collection();\n\n /**\n * A collection of presences in this guild\n * @type {Collection}\n */\n this.presences = new Collection();\n\n /**\n * Whether the bot has been removed from the guild\n * @type {boolean}\n */\n this.deleted = false;\n\n if (!data) return;\n if (data.unavailable) {\n /**\n * Whether the guild is available to access. If it is not available, it indicates a server outage\n * @type {boolean}\n */\n this.available = false;\n\n /**\n * The Unique ID of the guild, useful for comparisons\n * @type {Snowflake}\n */\n this.id = data.id;\n } else {\n this.setup(data);\n if (!data.channels) this.available = false;\n }\n }\n\n /* eslint-disable complexity */\n /**\n * Sets up the guild.\n * @param {*} data The raw data of the guild\n * @private\n */\n setup(data) {\n /**\n * The name of the guild\n * @type {string}\n */\n this.name = data.name;\n\n /**\n * The hash of the guild icon\n * @type {?string}\n */\n this.icon = data.icon;\n\n /**\n * The hash of the guild splash image (VIP only)\n * @type {?string}\n */\n this.splash = data.splash;\n\n /**\n * The region the guild is located in\n * @type {string}\n */\n this.region = data.region;\n\n /**\n * The full amount of members in this guild\n * @type {number}\n */\n this.memberCount = data.member_count || this.memberCount;\n\n /**\n * Whether the guild is \"large\" (has more than 250 members)\n * @type {boolean}\n */\n this.large = Boolean('large' in data ? data.large : this.large);\n\n /**\n * An array of guild features\n * @type {Object[]}\n */\n this.features = data.features;\n\n /**\n * The ID of the application that created this guild (if applicable)\n * @type {?Snowflake}\n */\n this.applicationID = data.application_id;\n\n /**\n * The time in seconds before a user is counted as \"away from keyboard\"\n * @type {?number}\n */\n this.afkTimeout = data.afk_timeout;\n\n /**\n * The ID of the voice channel where AFK members are moved\n * @type {?string}\n */\n this.afkChannelID = data.afk_channel_id;\n\n /**\n * The ID of the system channel\n * @type {?Snowflake}\n */\n this.systemChannelID = data.system_channel_id;\n\n /**\n * Whether embedded images are enabled on this guild\n * @type {boolean}\n */\n this.embedEnabled = data.embed_enabled;\n\n /**\n * The verification level of the guild\n * @type {number}\n */\n this.verificationLevel = data.verification_level;\n\n /**\n * The explicit content filter level of the guild\n * @type {number}\n */\n this.explicitContentFilter = data.explicit_content_filter;\n\n /**\n * The required MFA level for the guild\n * @type {number}\n */\n this.mfaLevel = data.mfa_level;\n\n /**\n * The timestamp the client user joined the guild at\n * @type {number}\n */\n this.joinedTimestamp = data.joined_at ? new Date(data.joined_at).getTime() : this.joinedTimestamp;\n\n /**\n * The value set for a guild's default message notifications\n * @type {DefaultMessageNotifications|number}\n */\n this.defaultMessageNotifications = Constants.DefaultMessageNotifications[data.default_message_notifications] ||\n data.default_message_notifications;\n\n this.id = data.id;\n this.available = !data.unavailable;\n this.features = data.features || this.features || [];\n\n if (data.members) {\n this.members.clear();\n for (const guildUser of data.members) this._addMember(guildUser, false);\n }\n\n if (data.owner_id) {\n /**\n * The user ID of this guild's owner\n * @type {Snowflake}\n */\n this.ownerID = data.owner_id;\n }\n\n if (data.channels) {\n this.channels.clear();\n for (const channel of data.channels) this.client.dataManager.newChannel(channel, this);\n }\n\n if (data.roles) {\n this.roles.clear();\n for (const role of data.roles) {\n const newRole = new Role(this, role);\n this.roles.set(newRole.id, newRole);\n }\n }\n\n if (data.presences) {\n for (const presence of data.presences) {\n this._setPresence(presence.user.id, presence);\n }\n }\n\n this._rawVoiceStates = new Collection();\n if (data.voice_states) {\n for (const voiceState of data.voice_states) {\n this._rawVoiceStates.set(voiceState.user_id, voiceState);\n const member = this.members.get(voiceState.user_id);\n const voiceChannel = this.channels.get(voiceState.channel_id);\n if (member && voiceChannel) {\n member.serverMute = voiceState.mute;\n member.serverDeaf = voiceState.deaf;\n member.selfMute = voiceState.self_mute;\n member.selfDeaf = voiceState.self_deaf;\n member.voiceSessionID = voiceState.session_id;\n member.voiceChannelID = voiceState.channel_id;\n voiceChannel.members.set(member.user.id, member);\n }\n }\n }\n\n if (!this.emojis) {\n /**\n * A collection of emojis that are in this guild\n * The key is the emoji's ID, the value is the emoji\n * @type {Collection}\n */\n this.emojis = new Collection();\n for (const emoji of data.emojis) this.emojis.set(emoji.id, new Emoji(this, emoji));\n } else {\n this.client.actions.GuildEmojisUpdate.handle({\n guild_id: this.id,\n emojis: data.emojis,\n });\n }\n }\n\n /**\n * The timestamp the guild was created at\n * @type {number}\n * @readonly\n */\n get createdTimestamp() {\n return Snowflake.deconstruct(this.id).timestamp;\n }\n\n /**\n * The time the guild was created\n * @type {Date}\n * @readonly\n */\n get createdAt() {\n return new Date(this.createdTimestamp);\n }\n\n /**\n * The time the client user joined the guild\n * @type {Date}\n * @readonly\n */\n get joinedAt() {\n return new Date(this.joinedTimestamp);\n }\n\n /**\n * If this guild is verified\n * @type {boolean}\n * @readonly\n */\n get verified() {\n return this.features.includes('VERIFIED');\n }\n\n /**\n * The URL to this guild's icon\n * @type {?string}\n * @readonly\n */\n get iconURL() {\n if (!this.icon) return null;\n return Constants.Endpoints.Guild(this).Icon(this.client.options.http.cdn, this.icon);\n }\n\n /**\n * The acronym that shows up in place of a guild icon.\n * @type {string}\n * @readonly\n */\n get nameAcronym() {\n return this.name.replace(/\\w+/g, name => name[0]).replace(/\\s/g, '');\n }\n\n /**\n * The URL to this guild's splash\n * @type {?string}\n * @readonly\n */\n get splashURL() {\n if (!this.splash) return null;\n return Constants.Endpoints.Guild(this).Splash(this.client.options.http.cdn, this.splash);\n }\n\n /**\n * The owner of the guild\n * @type {?GuildMember}\n * @readonly\n */\n get owner() {\n return this.members.get(this.ownerID);\n }\n\n /**\n * AFK voice channel for this guild\n * @type {?VoiceChannel}\n * @readonly\n */\n get afkChannel() {\n return this.client.channels.get(this.afkChannelID) || null;\n }\n\n /**\n * System channel for this guild\n * @type {?GuildChannel}\n * @readonly\n */\n get systemChannel() {\n return this.client.channels.get(this.systemChannelID) || null;\n }\n\n /**\n * If the client is connected to any voice channel in this guild, this will be the relevant VoiceConnection\n * @type {?VoiceConnection}\n * @readonly\n */\n get voiceConnection() {\n if (this.client.browser) return null;\n return this.client.voice.connections.get(this.id) || null;\n }\n\n /**\n * The position of this guild\n * This is only available when using a user account.\n * @type {?number}\n * @readonly\n */\n get position() {\n if (this.client.user.bot) return null;\n if (!this.client.user.settings.guildPositions) return null;\n return this.client.user.settings.guildPositions.indexOf(this.id);\n }\n\n /**\n * Whether the guild is muted\n * This is only available when using a user account.\n * @type {?boolean}\n * @readonly\n */\n get muted() {\n if (this.client.user.bot) return null;\n try {\n return this.client.user.guildSettings.get(this.id).muted;\n } catch (err) {\n return false;\n }\n }\n\n /**\n * The type of message that should notify you\n * This is only available when using a user account.\n * @type {?MessageNotificationType}\n * @readonly\n */\n get messageNotifications() {\n if (this.client.user.bot) return null;\n try {\n return this.client.user.guildSettings.get(this.id).messageNotifications;\n } catch (err) {\n return null;\n }\n }\n\n /**\n * Whether to receive mobile push notifications\n * This is only available when using a user account.\n * @type {?boolean}\n * @readonly\n */\n get mobilePush() {\n if (this.client.user.bot) return null;\n try {\n return this.client.user.guildSettings.get(this.id).mobilePush;\n } catch (err) {\n return false;\n }\n }\n\n /**\n * Whether to suppress everyone messages\n * This is only available when using a user account.\n * @type {?boolean}\n * @readonly\n */\n get suppressEveryone() {\n if (this.client.user.bot) return null;\n try {\n return this.client.user.guildSettings.get(this.id).suppressEveryone;\n } catch (err) {\n return null;\n }\n }\n\n /**\n * The `@everyone` role of the guild\n * @type {Role}\n * @readonly\n */\n get defaultRole() {\n return this.roles.get(this.id);\n }\n\n /**\n * The client user as a GuildMember of this guild\n * @type {?GuildMember}\n * @readonly\n */\n get me() {\n return this.members.get(this.client.user.id);\n }\n\n /**\n * Fetches a collection of roles in the current guild sorted by position\n * @type {Collection}\n * @readonly\n * @private\n */\n get _sortedRoles() {\n return this._sortPositionWithID(this.roles);\n }\n\n /**\n * Returns the GuildMember form of a User object, if the user is present in the guild.\n * @param {UserResolvable} user The user that you want to obtain the GuildMember of\n * @returns {?GuildMember}\n * @example\n * // Get the guild member of a user\n * const member = guild.member(message.author);\n */\n member(user) {\n return this.client.resolver.resolveGuildMember(this, user);\n }\n\n /**\n * An object containing information about a guild member's ban.\n * @typedef {Object} BanInfo\n * @property {User} user User that was banned\n * @property {?string} reason Reason the user was banned\n */\n\n /**\n * Fetch a ban for a user.\n * @returns {Promise}\n * @param {UserResolvable} user The user to fetch the ban for\n * @example\n * // Get ban\n * guild.fetchBan(message.author)\n * .then(({ user, reason }) => console.log(`${user.tag} was banned for the reason: ${reason}.`))\n * .catch(console.error);\n */\n fetchBan(user) {\n return this.client.rest.methods.getGuildBan(this, user);\n }\n\n /**\n * Fetch a collection of banned users in this guild.\n * @returns {Promise>}\n * @param {boolean} [withReasons=false] Whether or not to include the ban reason(s)\n * @example\n * // Fetch bans in guild\n * guild.fetchBans()\n * .then(bans => console.log(`This guild has ${bans.size} bans`))\n * .catch(console.error);\n */\n fetchBans(withReasons = false) {\n if (withReasons) return this.client.rest.methods.getGuildBans(this);\n return this.client.rest.methods.getGuildBans(this)\n .then(bans => {\n const users = new Collection();\n for (const ban of bans.values()) users.set(ban.user.id, ban.user);\n return users;\n });\n }\n\n /**\n * Fetch a collection of invites to this guild.\n * Resolves with a collection mapping invites by their codes.\n * @returns {Promise>}\n * @example\n * // Fetch invites\n * guild.fetchInvites()\n * .then(invites => console.log(`Fetched ${invites.size} invites`))\n * .catch(console.error);\n * @example\n * // Fetch invite creator by their id\n * guild.fetchInvites()\n * .then(invites => console.log(invites.find(invite => invite.inviter.id === '84484653687267328')))\n * .catch(console.error);\n */\n fetchInvites() {\n return this.client.rest.methods.getGuildInvites(this);\n }\n\n /**\n * Fetches the vanity url invite code to this guild.\n * Resolves with a string matching the vanity url invite code, not the full url.\n * @returns {Promise}\n * @example\n * // Fetch invites\n * guild.fetchVanityCode()\n * .then(code => {\n * console.log(`Vanity URL: https://discord.gg/${code}`);\n * })\n * .catch(console.error);\n */\n fetchVanityCode() {\n if (!this.features.includes('VANITY_URL')) {\n return Promise.reject(new Error('This guild does not have the VANITY_URL feature enabled.'));\n }\n return this.client.rest.methods.getGuildVanityCode(this);\n }\n\n\n /**\n * Fetch all webhooks for the guild.\n * @returns {Promise>}\n * @example\n * // Fetch webhooks\n * guild.fetchWebhooks()\n * .then(webhooks => console.log(`Fetched ${webhooks.size} webhooks`))\n * .catch(console.error);\n */\n fetchWebhooks() {\n return this.client.rest.methods.getGuildWebhooks(this);\n }\n\n /**\n * Fetch available voice regions.\n * @returns {Promise>}\n * @example\n * // Fetch voice regions\n * guild.fetchVoiceRegions()\n * .then(console.log)\n * .catch(console.error);\n */\n fetchVoiceRegions() {\n return this.client.rest.methods.fetchVoiceRegions(this.id);\n }\n\n /**\n * The Guild Embed object\n * @typedef {Object} GuildEmbedData\n * @property {boolean} enabled Whether the embed is enabled\n * @property {?ChannelResolvable} channel The embed channel\n */\n\n /**\n * Fetches the guild embed.\n * @returns {Promise}\n * @example\n * // Fetches the guild embed\n * guild.fetchEmbed()\n * .then(embed => console.log(`The embed is ${embed.enabled ? 'enabled' : 'disabled'}`))\n * .catch(console.error);\n */\n fetchEmbed() {\n return this.client.rest.methods.fetchEmbed(this.id);\n }\n\n /**\n * Fetch audit logs for this guild.\n * @param {Object} [options={}] Options for fetching audit logs\n * @param {Snowflake|GuildAuditLogsEntry} [options.before] Limit to entries from before specified entry\n * @param {Snowflake|GuildAuditLogsEntry} [options.after] Limit to entries from after specified entry\n * @param {number} [options.limit] Limit number of entries\n * @param {UserResolvable} [options.user] Only show entries involving this user\n * @param {AuditLogAction} [options.type] Only show entries involving this action type\n * @returns {Promise}\n * @example\n * // Output audit log entries\n * guild.fetchAuditLogs()\n * .then(audit => console.log(audit.entries.first()))\n * .catch(console.error);\n */\n fetchAuditLogs(options) {\n return this.client.rest.methods.getGuildAuditLogs(this, options);\n }\n\n /**\n * Adds a user to the guild using OAuth2. Requires the `CREATE_INSTANT_INVITE` permission.\n * @param {UserResolvable} user User to add to the guild\n * @param {Object} options Options for the addition\n * @param {string} options.accessToken An OAuth2 access token for the user with the `guilds.join` scope granted to the\n * bot's application\n * @param {string} [options.nick] Nickname to give the member (requires `MANAGE_NICKNAMES`)\n * @param {Collection|Role[]|Snowflake[]} [options.roles] Roles to add to the member\n * (requires `MANAGE_ROLES`)\n * @param {boolean} [options.mute] Whether the member should be muted (requires `MUTE_MEMBERS`)\n * @param {boolean} [options.deaf] Whether the member should be deafened (requires `DEAFEN_MEMBERS`)\n * @returns {Promise}\n */\n addMember(user, options) {\n user = this.client.resolver.resolveUserID(user);\n if (this.members.has(user)) return Promise.resolve(this.members.get(user));\n return this.client.rest.methods.putGuildMember(this, user, options);\n }\n\n /**\n * Fetch a single guild member from a user.\n * @param {UserResolvable} user The user to fetch the member for\n * @param {boolean} [cache=true] Insert the member into the members cache\n * @returns {Promise}\n * @example\n * // Fetch a guild member\n * guild.fetchMember(message.author)\n * .then(console.log)\n * .catch(console.error);\n */\n fetchMember(user, cache = true) {\n user = this.client.resolver.resolveUser(user);\n if (!user) return Promise.reject(new Error('Invalid or uncached id provided.'));\n const member = this.members.get(user.id);\n if (member && member.joinedTimestamp) return Promise.resolve(member);\n return this.client.rest.methods.getGuildMember(this, user, cache);\n }\n\n /**\n * Fetches all the members in the guild, even if they are offline. If the guild has less than 250 members,\n * this should not be necessary.\n * @param {string} [query=''] Limit fetch to members with similar usernames\n * @param {number} [limit=0] Maximum number of members to request\n * @returns {Promise}\n * @example\n * // Fetch guild members\n * guild.fetchMembers()\n * .then(console.log)\n * .catch(console.error);\n * @example\n * // Fetches a maximum of 1 member with the given query\n * guild.fetchMembers('hydrabolt', 1)\n * .then(console.log)\n * .catch(console.error);\n */\n fetchMembers(query = '', limit = 0) {\n return new Promise((resolve, reject) => {\n if (this.memberCount === this.members.size) {\n resolve(this);\n return;\n }\n this.client.ws.send({\n op: Constants.OPCodes.REQUEST_GUILD_MEMBERS,\n d: {\n guild_id: this.id,\n query,\n limit,\n },\n });\n const handler = (members, guild) => {\n if (guild.id !== this.id) return;\n if (this.memberCount === this.members.size || members.length < 1000) {\n this.client.removeListener(Constants.Events.GUILD_MEMBERS_CHUNK, handler);\n resolve(this);\n }\n };\n this.client.on(Constants.Events.GUILD_MEMBERS_CHUNK, handler);\n this.client.setTimeout(() => reject(new Error('Members didn\\'t arrive in time.')), 120 * 1000);\n });\n }\n\n /**\n * Performs a search within the entire guild.\n * This is only available when using a user account.\n * @param {MessageSearchOptions} [options={}] Options to pass to the search\n * @returns {Promise}\n * @example\n * guild.search({\n * content: 'discord.js',\n * before: '2016-11-17'\n * })\n * .then(res => {\n * const hit = res.messages[0].find(m => m.hit).content;\n * console.log(`I found: **${hit}**, total results: ${res.totalResults}`);\n * })\n * .catch(console.error);\n */\n search(options = {}) {\n return this.client.rest.methods.search(this, options);\n }\n\n /**\n * The data for editing a guild.\n * @typedef {Object} GuildEditData\n * @property {string} [name] The name of the guild\n * @property {string} [region] The region of the guild\n * @property {number} [verificationLevel] The verification level of the guild\n * @property {number} [explicitContentFilter] The level of the explicit content filter\n * @property {ChannelResolvable} [afkChannel] The AFK channel of the guild\n * @property {ChannelResolvable} [systemChannel] The system channel of the guild\n * @property {number} [afkTimeout] The AFK timeout of the guild\n * @property {Base64Resolvable} [icon] The icon of the guild\n * @property {GuildMemberResolvable} [owner] The owner of the guild\n * @property {Base64Resolvable} [splash] The splash screen of the guild\n */\n\n /**\n * Updates the guild with new information - e.g. a new name.\n * @param {GuildEditData} data The data to update the guild with\n * @param {string} [reason] Reason for editing the guild\n * @returns {Promise}\n * @example\n * // Set the guild name and region\n * guild.edit({\n * name: 'Discord Guild',\n * region: 'london',\n * })\n * .then(g => console.log(`Changed guild name to ${g} and region to ${g.region}`))\n * .catch(console.error);\n */\n edit(data, reason) {\n const _data = {};\n if (data.name) _data.name = data.name;\n if (data.region) _data.region = data.region;\n if (typeof data.verificationLevel !== 'undefined') _data.verification_level = Number(data.verificationLevel);\n if (typeof data.afkChannel !== 'undefined') {\n _data.afk_channel_id = this.client.resolver.resolveChannelID(data.afkChannel);\n }\n if (typeof data.systemChannel !== 'undefined') {\n _data.system_channel_id = this.client.resolver.resolveChannelID(data.systemChannel);\n }\n if (data.afkTimeout) _data.afk_timeout = Number(data.afkTimeout);\n if (typeof data.icon !== 'undefined') _data.icon = data.icon;\n if (data.owner) _data.owner_id = this.client.resolver.resolveUser(data.owner).id;\n if (typeof data.splash !== 'undefined') _data.splash = data.splash;\n if (typeof data.explicitContentFilter !== 'undefined') {\n _data.explicit_content_filter = Number(data.explicitContentFilter);\n }\n if (typeof data.defaultMessageNotifications !== 'undefined') {\n _data.default_message_notifications = typeof data.defaultMessageNotifications === 'string' ?\n Constants.DefaultMessageNotifications.indexOf(data.defaultMessageNotifications) :\n Number(data.defaultMessageNotifications);\n }\n return this.client.rest.methods.updateGuild(this, _data, reason);\n }\n\n /**\n * Edit the level of the explicit content filter.\n * @param {number} explicitContentFilter The new level of the explicit content filter\n * @param {string} [reason] Reason for changing the level of the guild's explicit content filter\n * @returns {Promise}\n */\n setExplicitContentFilter(explicitContentFilter, reason) {\n return this.edit({ explicitContentFilter }, reason);\n }\n\n /**\n * Edits the setting of the default message notifications of the guild.\n * @param {DefaultMessageNotifications|number} defaultMessageNotifications\n * The new setting for the default message notifications\n * @param {string} [reason] Reason for changing the setting of the default message notifications\n * @returns {Promise}\n */\n setDefaultMessageNotifications(defaultMessageNotifications, reason) {\n return this.edit({ defaultMessageNotifications }, reason);\n }\n\n /**\n * Edit the name of the guild.\n * @param {string} name The new name of the guild\n * @param {string} [reason] Reason for changing the guild's name\n * @returns {Promise}\n * @example\n * // Edit the guild name\n * guild.setName('Discord Guild')\n * .then(g => console.log(`Updated guild name to ${g}`))\n * .catch(console.error);\n */\n setName(name, reason) {\n return this.edit({ name }, reason);\n }\n\n /**\n * Edit the region of the guild.\n * @param {string} region The new region of the guild\n * @param {string} [reason] Reason for changing the guild's region\n * @returns {Promise}\n * @example\n * // Edit the guild region\n * guild.setRegion('london')\n * .then(g => console.log(`Updated guild region to ${g.region}`))\n * .catch(console.error);\n */\n setRegion(region, reason) {\n return this.edit({ region }, reason);\n }\n\n /**\n * Edit the verification level of the guild.\n * @param {number} verificationLevel The new verification level of the guild\n * @param {string} [reason] Reason for changing the guild's verification level\n * @returns {Promise}\n * @example\n * // Edit the guild verification level\n * guild.setVerificationLevel(1)\n * .then(g => console.log(`Updated guild verification level to ${g.verificationLevel}`))\n * .catch(console.error);\n */\n setVerificationLevel(verificationLevel, reason) {\n return this.edit({ verificationLevel }, reason);\n }\n\n /**\n * Edit the AFK channel of the guild.\n * @param {ChannelResolvable} afkChannel The new AFK channel\n * @param {string} [reason] Reason for changing the guild's AFK channel\n * @returns {Promise}\n * @example\n * // Edit the guild AFK channel\n * guild.setAFKChannel(channel)\n * .then(g => console.log(`Updated guild AFK channel to ${g.afkChannel.name}`))\n * .catch(console.error);\n */\n setAFKChannel(afkChannel, reason) {\n return this.edit({ afkChannel }, reason);\n }\n\n /**\n * Edit the system channel of the guild.\n * @param {ChannelResolvable} systemChannel The new system channel\n * @param {string} [reason] Reason for changing the guild's system channel\n * @returns {Promise}\n */\n setSystemChannel(systemChannel, reason) {\n return this.edit({ systemChannel }, reason);\n }\n\n /**\n * Edit the AFK timeout of the guild.\n * @param {number} afkTimeout The time in seconds that a user must be idle to be considered AFK\n * @param {string} [reason] Reason for changing the guild's AFK timeout\n * @returns {Promise}\n * @example\n * // Edit the guild AFK channel\n * guild.setAFKTimeout(60)\n * .then(g => console.log(`Updated guild AFK timeout to ${g.afkTimeout}`))\n * .catch(console.error);\n */\n setAFKTimeout(afkTimeout, reason) {\n return this.edit({ afkTimeout }, reason);\n }\n\n /**\n * Set a new guild icon.\n * @param {Base64Resolvable|BufferResolvable} icon The new icon of the guild\n * @param {string} [reason] Reason for changing the guild's icon\n * @returns {Promise}\n * @example\n * // Edit the guild icon\n * guild.setIcon('./icon.png')\n * .then(console.log)\n * .catch(console.error);\n */\n setIcon(icon, reason) {\n return this.client.resolver.resolveImage(icon).then(data => this.edit({ icon: data, reason }));\n }\n\n /**\n * Sets a new owner of the guild.\n * @param {GuildMemberResolvable} owner The new owner of the guild\n * @param {string} [reason] Reason for setting the new owner\n * @returns {Promise}\n * @example\n * // Edit the guild owner\n * guild.setOwner(guild.members.first())\n * .then(g => console.log(`Updated the guild owner to ${g.owner.displayName}`))\n * .catch(console.error);\n */\n setOwner(owner, reason) {\n return this.edit({ owner }, reason);\n }\n\n /**\n * Set a new guild splash screen.\n * @param {BufferResolvable|Base64Resolvable} splash The new splash screen of the guild\n * @param {string} [reason] Reason for changing the guild's splash screen\n * @returns {Promise}\n * @example\n * // Edit the guild splash\n * guild.setSplash('./splash.png')\n * .then(console.log)\n * .catch(console.error);\n */\n setSplash(splash) {\n return this.client.resolver.resolveImage(splash).then(data => this.edit({ splash: data }));\n }\n\n /**\n * Sets the position of the guild in the guild listing.\n * This is only available when using a user account.\n * @param {number} position Absolute or relative position\n * @param {boolean} [relative=false] Whether to position relatively or absolutely\n * @returns {Promise}\n */\n setPosition(position, relative) {\n if (this.client.user.bot) {\n return Promise.reject(new Error('Setting guild position is only available for user accounts'));\n }\n return this.client.user.settings.setGuildPosition(this, position, relative);\n }\n\n /**\n * Marks all messages in this guild as read.\n * This is only available when using a user account.\n * @returns {Promise}\n */\n acknowledge() {\n return this.client.rest.methods.ackGuild(this);\n }\n\n /**\n * Allow direct messages from guild members.\n * This is only available when using a user account.\n * @param {boolean} allow Whether to allow direct messages\n * @returns {Promise}\n */\n allowDMs(allow) {\n const settings = this.client.user.settings;\n if (allow) return settings.removeRestrictedGuild(this);\n else return settings.addRestrictedGuild(this);\n }\n\n /**\n * Bans a user from the guild.\n * @param {UserResolvable} user The user to ban\n * @param {Object|number|string} [options] Ban options. If a number, the number of days to delete messages for, if a\n * string, the ban reason. Supplying an object allows you to do both.\n * @param {number} [options.days=0] Number of days of messages to delete\n * @param {string} [options.reason] Reason for banning\n * @returns {Promise} Result object will be resolved as specifically as possible.\n * If the GuildMember cannot be resolved, the User will instead be attempted to be resolved. If that also cannot\n * be resolved, the user ID will be the result.\n * @example\n * // Ban a user by ID\n * guild.ban('some user ID')\n * .then(user => console.log(`Banned ${user.username || user.id || user} from ${guild}`))\n * .catch(console.error);\n * @example\n * // Ban a user by object with reason and days\n * guild.ban(user, { days: 7, reason: 'He needed to go' })\n * .then(console.log)\n * .catch(console.error);\n */\n ban(user, options = {}) {\n if (typeof options === 'number') {\n options = { reason: null, 'delete-message-days': options };\n } else if (typeof options === 'string') {\n options = { reason: options, 'delete-message-days': 0 };\n }\n if (options.days) options['delete-message-days'] = options.days;\n return this.client.rest.methods.banGuildMember(this, user, options);\n }\n\n /**\n * Unbans a user from the guild.\n * @param {UserResolvable} user The user to unban\n * @param {string} [reason] Reason for unbanning the user\n * @returns {Promise}\n * @example\n * // Unban a user by ID (or with a user/guild member object)\n * guild.unban('some user ID')\n * .then(user => console.log(`Unbanned ${user.username} from ${guild}`))\n * .catch(console.error);\n */\n unban(user, reason) {\n return this.client.rest.methods.unbanGuildMember(this, user, reason);\n }\n\n /**\n * Prunes members from the guild based on how long they have been inactive.\n * @param {number} days Number of days of inactivity required to kick\n * @param {boolean} [dry=false] If true, will return number of users that will be kicked, without actually doing it\n * @param {string} [reason] Reason for this prune\n * @returns {Promise} The number of members that were/will be kicked\n * @example\n * // See how many members will be pruned\n * guild.pruneMembers(12, true)\n * .then(pruned => console.log(`This will prune ${pruned} people!`))\n * .catch(console.error);\n * @example\n * // Actually prune the members\n * guild.pruneMembers(12)\n * .then(pruned => console.log(`I just pruned ${pruned} people!`))\n * .catch(console.error);\n */\n pruneMembers(days, dry = false, reason) {\n if (typeof days !== 'number') throw new TypeError('Days must be a number.');\n return this.client.rest.methods.pruneGuildMembers(this, days, dry, reason);\n }\n\n /**\n * Syncs this guild (already done automatically every 30 seconds).\n * This is only available when using a user account.\n */\n sync() {\n if (!this.client.user.bot) this.client.syncGuilds([this]);\n }\n\n /**\n * Overwrites to use when creating a channel or replacing overwrites\n * @typedef {Object} ChannelCreationOverwrites\n * @property {PermissionResolvable} [allow] The permissions to allow\n * @property {PermissionResolvable} [allowed] The permissions to allow\n * **(deprecated)**\n * @property {PermissionResolvable} [deny] The permissions to deny\n * @property {PermissionResolvable} [denied] The permissions to deny\n * **(deprecated)**\n * @property {GuildMemberResolvable|RoleResolvable} memberOrRole Member or role this overwrite is for\n */\n\n /**\n * Creates a new channel in the guild.\n * @param {string} name The name of the new channel\n * @param {string|ChannelData} [typeOrOptions='text']\n * The type of the new channel, one of `text`, `voice`, `category`, `news`, or `store`. **(deprecated, use options)**\n * Alternatively options for the new channel, overriding the following parameters.\n * @param {ChannelCreationOverwrites[]|Collection} [permissionOverwrites]\n * Permission overwrites **(deprecated, use options)**\n * @param {string} [reason] Reason for creating this channel **(deprecated, use options)**\n * @returns {Promise}\n * @example\n * // Create a new text channel\n * guild.createChannel('new-general', { type: 'text' })\n * .then(console.log)\n * .catch(console.error);\n * @example\n * // Create a new category channel with permission overwrites\n * guild.createChannel('new-category', {\n * type: 'category',\n * permissionOverwrites: [{\n * id: guild.id,\n * deny: ['MANAGE_MESSAGES'],\n * allow: ['SEND_MESSAGES']\n * }]\n * })\n * .then(console.log)\n * .catch(console.error);\n */\n createChannel(name, typeOrOptions, permissionOverwrites, reason) {\n if (!typeOrOptions || (typeof typeOrOptions === 'string')) {\n if (typeOrOptions) {\n ((any, ...more) => console.warn(any, more))(\n 'Guild#createChannel: Create channels with an options object instead of separate parameters',\n 'DeprecationWarning'\n );\n }\n typeOrOptions = {\n type: typeOrOptions,\n permissionOverwrites,\n reason,\n };\n }\n return this.client.rest.methods.createChannel(this, name, typeOrOptions);\n }\n\n /**\n * The data needed for updating a channel's position.\n * @typedef {Object} ChannelPosition\n * @property {ChannelResolvable} channel Channel to update\n * @property {number} position New position for the channel\n */\n\n /**\n * Batch-updates the guild's channels' positions.\n * @param {ChannelPosition[]} channelPositions Channel positions to update\n * @returns {Promise}\n * @example\n * guild.updateChannels([{ channel: channelID, position: newChannelIndex }])\n * .then(g => console.log(`Updated channel positions for ${g}`))\n * .catch(console.error);\n */\n setChannelPositions(channelPositions) {\n return this.client.rest.methods.updateChannelPositions(this.id, channelPositions);\n }\n\n /**\n * Edits the guild's embed.\n * @param {GuildEmbedData} embed The embed for the guild\n * @param {string} [reason] Reason for changing the guild's embed\n * @returns {Promise}\n */\n setEmbed(embed, reason) {\n return this.client.rest.methods.updateEmbed(this.id, embed, reason)\n .then(() => this);\n }\n\n /**\n * Creates a new role in the guild with given information.\n * @param {RoleData} [data] The data to update the role with\n * @param {string} [reason] Reason for creating this role\n * @returns {Promise}\n * @example\n * // Create a new role\n * guild.createRole()\n * .then(role => console.log(`Created new role with name ${role.name}`))\n * .catch(console.error);\n * @example\n * // Create a new role with data\n * guild.createRole({\n * name: 'Super Cool People',\n * color: 'BLUE',\n * })\n * .then(role => console.log(`Created new role with name ${role.name} and color ${role.color}`))\n * .catch(console.error)\n */\n createRole(data = {}, reason) {\n return this.client.rest.methods.createGuildRole(this, data, reason);\n }\n\n /**\n * Creates a new custom emoji in the guild.\n * @param {BufferResolvable|Base64Resolvable} attachment The image for the emoji\n * @param {string} name The name for the emoji\n * @param {Collection|Role[]} [roles] Roles to limit the emoji to\n * @param {string} [reason] Reason for creating the emoji\n * @returns {Promise} The created emoji\n * @example\n * // Create a new emoji from a url\n * guild.createEmoji('https://i.imgur.com/w3duR07.png', 'rip')\n * .then(emoji => console.log(`Created new emoji with name ${emoji.name}`))\n * .catch(console.error);\n * @example\n * // Create a new emoji from a file on your computer\n * guild.createEmoji('./memes/banana.png', 'banana')\n * .then(emoji => console.log(`Created new emoji with name ${emoji.name}`))\n * .catch(console.error);\n */\n createEmoji(attachment, name, roles, reason) {\n if (typeof attachment === 'string' && attachment.startsWith('data:')) {\n return this.client.rest.methods.createEmoji(this, attachment, name, roles, reason);\n } else {\n return this.client.resolver.resolveImage(attachment).then(data =>\n this.client.rest.methods.createEmoji(this, data, name, roles, reason)\n );\n }\n }\n\n /**\n * Delete an emoji.\n * @param {Emoji|string} emoji The emoji to delete\n * @param {string} [reason] Reason for deleting the emoji\n * @returns {Promise}\n */\n deleteEmoji(emoji, reason) {\n if (typeof emoji === 'string') emoji = this.emojis.get(emoji);\n if (!(emoji instanceof Emoji)) throw new TypeError('Emoji must be either an instance of Emoji or an ID');\n return this.client.rest.methods.deleteEmoji(emoji, reason);\n }\n\n /**\n * Causes the client to leave the guild.\n * @returns {Promise}\n * @example\n * // Leave a guild\n * guild.leave()\n * .then(g => console.log(`Left the guild ${g}`))\n * .catch(console.error);\n */\n leave() {\n return this.client.rest.methods.leaveGuild(this);\n }\n\n /**\n * Causes the client to delete the guild.\n * @returns {Promise}\n * @example\n * // Delete a guild\n * guild.delete()\n * .then(g => console.log(`Deleted the guild ${g}`))\n * .catch(console.error);\n */\n delete() {\n return this.client.rest.methods.deleteGuild(this);\n }\n\n /**\n * Whether this guild equals another guild. It compares all properties, so for most operations\n * it is advisable to just compare `guild.id === guild2.id` as it is much faster and is often\n * what most users need.\n * @param {Guild} guild The guild to compare with\n * @returns {boolean}\n */\n equals(guild) {\n let equal =\n guild &&\n this.id === guild.id &&\n this.available === !guild.unavailable &&\n this.splash === guild.splash &&\n this.region === guild.region &&\n this.name === guild.name &&\n this.memberCount === guild.member_count &&\n this.large === guild.large &&\n this.icon === guild.icon &&\n Util.arraysEqual(this.features, guild.features) &&\n this.ownerID === guild.owner_id &&\n this.verificationLevel === guild.verification_level &&\n this.embedEnabled === guild.embed_enabled;\n\n if (equal) {\n if (this.embedChannel) {\n if (this.embedChannel.id !== guild.embed_channel_id) equal = false;\n } else if (guild.embed_channel_id) {\n equal = false;\n }\n }\n\n return equal;\n }\n\n /**\n * When concatenated with a string, this automatically concatenates the guild's name instead of the guild object.\n * @returns {string}\n * @example\n * // Logs: Hello from My Guild!\n * console.log(`Hello from ${guild}!`);\n * @example\n * // Logs: Hello from My Guild!\n * console.log('Hello from ' + guild + '!');\n */\n toString() {\n return this.name;\n }\n\n _addMember(guildUser, emitEvent = true) {\n const existing = this.members.has(guildUser.user.id);\n if (!(guildUser.user instanceof User)) guildUser.user = this.client.dataManager.newUser(guildUser.user);\n\n guildUser.joined_at = guildUser.joined_at || 0;\n const member = new GuildMember(this, guildUser);\n this.members.set(member.id, member);\n\n if (this._rawVoiceStates && this._rawVoiceStates.has(member.user.id)) {\n const voiceState = this._rawVoiceStates.get(member.user.id);\n member.serverMute = voiceState.mute;\n member.serverDeaf = voiceState.deaf;\n member.selfMute = voiceState.self_mute;\n member.selfDeaf = voiceState.self_deaf;\n member.voiceSessionID = voiceState.session_id;\n member.voiceChannelID = voiceState.channel_id;\n if (this.client.channels.has(voiceState.channel_id)) {\n this.client.channels.get(voiceState.channel_id).members.set(member.user.id, member);\n } else {\n this.client.emit('warn', `Member ${member.id} added in guild ${this.id} with an uncached voice channel`);\n }\n }\n\n /**\n * Emitted whenever a user joins a guild.\n * @event Client#guildMemberAdd\n * @param {GuildMember} member The member that has joined a guild\n */\n if (this.client.ws.connection.status === Constants.Status.READY && emitEvent && !existing) {\n this.client.emit(Constants.Events.GUILD_MEMBER_ADD, member);\n }\n\n return member;\n }\n\n _updateMember(member, data) {\n const oldMember = Util.cloneObject(member);\n\n if (data.roles) member._roles = data.roles;\n if (typeof data.nick !== 'undefined') member.nickname = data.nick;\n\n const notSame = member.nickname !== oldMember.nickname || !Util.arraysEqual(member._roles, oldMember._roles);\n\n if (this.client.ws.connection.status === Constants.Status.READY && notSame) {\n /**\n * Emitted whenever a guild member changes - i.e. new role, removed role, nickname.\n * @event Client#guildMemberUpdate\n * @param {GuildMember} oldMember The member before the update\n * @param {GuildMember} newMember The member after the update\n */\n this.client.emit(Constants.Events.GUILD_MEMBER_UPDATE, oldMember, member);\n }\n\n return {\n old: oldMember,\n mem: member,\n };\n }\n\n _removeMember(guildMember) {\n if (guildMember.voiceChannel) guildMember.voiceChannel.members.delete(guildMember.id);\n this.members.delete(guildMember.id);\n }\n\n _memberSpeakUpdate(user, speaking) {\n const member = this.members.get(user);\n if (member && member.speaking !== speaking) {\n member.speaking = speaking;\n /**\n * Emitted once a guild member starts/stops speaking.\n * @event Client#guildMemberSpeaking\n * @param {GuildMember} member The member that started/stopped speaking\n * @param {boolean} speaking Whether or not the member is speaking\n */\n this.client.emit(Constants.Events.GUILD_MEMBER_SPEAKING, member, speaking);\n }\n }\n\n _setPresence(id, presence) {\n if (this.presences.get(id)) {\n this.presences.get(id).update(presence);\n return;\n }\n this.presences.set(id, new Presence(presence, this.client));\n }\n\n /**\n * Set the position of a role in this guild.\n * @param {string|Role} role The role to edit, can be a role object or a role ID\n * @param {number} position The new position of the role\n * @param {boolean} [relative=false] Position Moves the role relative to its current position\n * @returns {Promise}\n */\n setRolePosition(role, position, relative = false) {\n if (typeof role === 'string') {\n role = this.roles.get(role);\n if (!role) return Promise.reject(new Error('Supplied role is not a role or snowflake.'));\n }\n\n position = Number(position);\n if (isNaN(position)) return Promise.reject(new Error('Supplied position is not a number.'));\n\n let updatedRoles = this._sortedRoles.array();\n\n Util.moveElementInArray(updatedRoles, role, position, relative);\n\n updatedRoles = updatedRoles.map((r, i) => ({ id: r.id, position: i }));\n return this.client.rest.methods.setRolePositions(this.id, updatedRoles);\n }\n\n /**\n * Set the position of a channel in this guild.\n * @param {string|GuildChannel} channel The channel to edit, can be a channel object or a channel ID\n * @param {number} position The new position of the channel\n * @param {boolean} [relative=false] Position Moves the channel relative to its current position\n * @returns {Promise}\n */\n setChannelPosition(channel, position, relative = false) {\n if (typeof channel === 'string') {\n channel = this.channels.get(channel);\n if (!channel) return Promise.reject(new Error('Supplied channel is not a channel or snowflake.'));\n }\n\n position = Number(position);\n if (isNaN(position)) return Promise.reject(new Error('Supplied position is not a number.'));\n\n let updatedChannels = this._sortedChannels(channel.type).array();\n\n Util.moveElementInArray(updatedChannels, channel, position, relative);\n\n updatedChannels = updatedChannels.map((r, i) => ({ id: r.id, position: i }));\n return this.client.rest.methods.setChannelPositions(this.id, updatedChannels);\n }\n\n /**\n * Fetches a collection of channels in the current guild sorted by position.\n * @param {string} type The channel type\n * @returns {Collection}\n * @private\n */\n _sortedChannels(type) {\n return this._sortPositionWithID(this.channels.filter(c => {\n if (type === 'voice' && c.type === 'voice') return true;\n else if (type !== 'voice' && c.type !== 'voice') return true;\n else return type === c.type;\n }));\n }\n\n /**\n * Sorts a collection by object position or ID if the positions are equivalent.\n * Intended to be identical to Discord's sorting method.\n * @param {Collection} collection The collection to sort\n * @returns {Collection}\n * @private\n */\n _sortPositionWithID(collection) {\n return collection.sort((a, b) =>\n a.position !== b.position ?\n a.position - b.position :\n Long.fromString(b.id).sub(Long.fromString(a.id)).toNumber()\n );\n }\n}\n\n/**\n * The `#general` TextChannel of the guild\n * @name Guild#defaultChannel\n * @type {TextChannel}\n * @readonly\n * @deprecated\n */\nObject.defineProperty(Guild.prototype, 'defaultChannel', {\n get: util.deprecate(function defaultChannel() {\n return this.channels.get(this.id);\n }, 'Guild#defaultChannel: This property is obsolete, will be removed in v12.0.0, and may not function as expected.'),\n});\n\nGuild.prototype.acknowledge =\n util.deprecate(Guild.prototype.acknowledge, 'Guild#acknowledge: userbot methods will be removed');\n\nGuild.prototype.setPosition =\n util.deprecate(Guild.prototype.setPosition, 'Guild#setPosition: userbot methods will be removed');\n\nGuild.prototype.search =\n util.deprecate(Guild.prototype.search, 'Guild#search: userbot methods will be removed');\n\nGuild.prototype.sync =\n util.deprecate(Guild.prototype.sync, 'Guild#sync:, userbot methods will be removed');\n\nmodule.exports = Guild;\n\n\n//# sourceURL=webpack:///./src/structures/Guild.js?"); +eval("const util = __webpack_require__(/*! util */ \"./node_modules/util/util.js\");\nconst Long = __webpack_require__(/*! long */ \"./node_modules/long/src/long.js\");\nconst User = __webpack_require__(/*! ./User */ \"./src/structures/User.js\");\nconst Role = __webpack_require__(/*! ./Role */ \"./src/structures/Role.js\");\nconst Emoji = __webpack_require__(/*! ./Emoji */ \"./src/structures/Emoji.js\");\nconst Presence = __webpack_require__(/*! ./Presence */ \"./src/structures/Presence.js\").Presence;\nconst GuildMember = __webpack_require__(/*! ./GuildMember */ \"./src/structures/GuildMember.js\");\nconst Constants = __webpack_require__(/*! ../util/Constants */ \"./src/util/Constants.js\");\nconst Collection = __webpack_require__(/*! ../util/Collection */ \"./src/util/Collection.js\");\nconst Util = __webpack_require__(/*! ../util/Util */ \"./src/util/Util.js\");\nconst Snowflake = __webpack_require__(/*! ../util/Snowflake */ \"./src/util/Snowflake.js\");\n\n/**\n * Represents a guild (or a server) on Discord.\n * It's recommended to see if a guild is available before performing operations or reading data from it. You can\n * check this with `guild.available`.\n */\nclass Guild {\n constructor(client, data) {\n /**\n * The client that created the instance of the guild\n * @name Guild#client\n * @type {Client}\n * @readonly\n */\n Object.defineProperty(this, 'client', { value: client });\n\n /**\n * A collection of members that are in this guild. The key is the member's ID, the value is the member\n * @type {Collection}\n */\n this.members = new Collection();\n\n /**\n * A collection of channels that are in this guild. The key is the channel's ID, the value is the channel\n * @type {Collection}\n */\n this.channels = new Collection();\n\n /**\n * A collection of roles that are in this guild. The key is the role's ID, the value is the role\n * @type {Collection}\n */\n this.roles = new Collection();\n\n /**\n * A collection of presences in this guild\n * @type {Collection}\n */\n this.presences = new Collection();\n\n /**\n * Whether the bot has been removed from the guild\n * @type {boolean}\n */\n this.deleted = false;\n\n if (!data) return;\n if (data.unavailable) {\n /**\n * Whether the guild is available to access. If it is not available, it indicates a server outage\n * @type {boolean}\n */\n this.available = false;\n\n /**\n * The Unique ID of the guild, useful for comparisons\n * @type {Snowflake}\n */\n this.id = data.id;\n } else {\n this.setup(data);\n if (!data.channels) this.available = false;\n }\n }\n\n /* eslint-disable complexity */\n /**\n * Sets up the guild.\n * @param {*} data The raw data of the guild\n * @private\n */\n setup(data) {\n /**\n * The name of the guild\n * @type {string}\n */\n this.name = data.name;\n\n /**\n * The hash of the guild icon\n * @type {?string}\n */\n this.icon = data.icon;\n\n /**\n * The hash of the guild splash image (VIP only)\n * @type {?string}\n */\n this.splash = data.splash;\n\n /**\n * The region the guild is located in\n * @type {string}\n */\n this.region = data.region;\n\n /**\n * The full amount of members in this guild\n * @type {number}\n */\n this.memberCount = data.member_count || this.memberCount;\n\n /**\n * Whether the guild is \"large\" (has more than 250 members)\n * @type {boolean}\n */\n this.large = Boolean('large' in data ? data.large : this.large);\n\n /**\n * An array of guild features\n * @type {Object[]}\n */\n this.features = data.features;\n\n /**\n * The ID of the application that created this guild (if applicable)\n * @type {?Snowflake}\n */\n this.applicationID = data.application_id;\n\n /**\n * The time in seconds before a user is counted as \"away from keyboard\"\n * @type {?number}\n */\n this.afkTimeout = data.afk_timeout;\n\n /**\n * The ID of the voice channel where AFK members are moved\n * @type {?string}\n */\n this.afkChannelID = data.afk_channel_id;\n\n /**\n * The ID of the system channel\n * @type {?Snowflake}\n */\n this.systemChannelID = data.system_channel_id;\n\n /**\n * Whether embedded images are enabled on this guild\n * @type {boolean}\n */\n this.embedEnabled = data.embed_enabled;\n\n /**\n * The verification level of the guild\n * @type {number}\n */\n this.verificationLevel = data.verification_level;\n\n /**\n * The explicit content filter level of the guild\n * @type {number}\n */\n this.explicitContentFilter = data.explicit_content_filter;\n\n /**\n * The required MFA level for the guild\n * @type {number}\n */\n this.mfaLevel = data.mfa_level;\n\n /**\n * The timestamp the client user joined the guild at\n * @type {number}\n */\n this.joinedTimestamp = data.joined_at ? new Date(data.joined_at).getTime() : this.joinedTimestamp;\n\n /**\n * The value set for a guild's default message notifications\n * @type {DefaultMessageNotifications|number}\n */\n this.defaultMessageNotifications = Constants.DefaultMessageNotifications[data.default_message_notifications] ||\n data.default_message_notifications;\n\n this.id = data.id;\n this.available = !data.unavailable;\n this.features = data.features || this.features || [];\n\n if (data.members) {\n this.members.clear();\n for (const guildUser of data.members) this._addMember(guildUser, false);\n }\n\n if (data.owner_id) {\n /**\n * The user ID of this guild's owner\n * @type {Snowflake}\n */\n this.ownerID = data.owner_id;\n }\n\n if (data.channels) {\n this.channels.clear();\n for (const channel of data.channels) this.client.dataManager.newChannel(channel, this);\n }\n\n if (data.roles) {\n this.roles.clear();\n for (const role of data.roles) {\n const newRole = new Role(this, role);\n this.roles.set(newRole.id, newRole);\n }\n }\n\n if (data.presences) {\n for (const presence of data.presences) {\n this._setPresence(presence.user.id, presence);\n }\n }\n\n this._rawVoiceStates = new Collection();\n if (data.voice_states) {\n for (const voiceState of data.voice_states) {\n this._rawVoiceStates.set(voiceState.user_id, voiceState);\n const member = this.members.get(voiceState.user_id);\n const voiceChannel = this.channels.get(voiceState.channel_id);\n if (member && voiceChannel) {\n member.serverMute = voiceState.mute;\n member.serverDeaf = voiceState.deaf;\n member.selfMute = voiceState.self_mute;\n member.selfDeaf = voiceState.self_deaf;\n member.voiceSessionID = voiceState.session_id;\n member.voiceChannelID = voiceState.channel_id;\n voiceChannel.members.set(member.user.id, member);\n }\n }\n }\n\n if (!this.emojis) {\n /**\n * A collection of emojis that are in this guild\n * The key is the emoji's ID, the value is the emoji\n * @type {Collection}\n */\n this.emojis = new Collection();\n for (const emoji of data.emojis) this.emojis.set(emoji.id, new Emoji(this, emoji));\n } else {\n this.client.actions.GuildEmojisUpdate.handle({\n guild_id: this.id,\n emojis: data.emojis,\n });\n }\n }\n\n /**\n * The timestamp the guild was created at\n * @type {number}\n * @readonly\n */\n get createdTimestamp() {\n return Snowflake.deconstruct(this.id).timestamp;\n }\n\n /**\n * The time the guild was created\n * @type {Date}\n * @readonly\n */\n get createdAt() {\n return new Date(this.createdTimestamp);\n }\n\n /**\n * The time the client user joined the guild\n * @type {Date}\n * @readonly\n */\n get joinedAt() {\n return new Date(this.joinedTimestamp);\n }\n\n /**\n * If this guild is verified\n * @type {boolean}\n * @readonly\n */\n get verified() {\n return this.features.includes('VERIFIED');\n }\n\n /**\n * The URL to this guild's icon\n * @type {?string}\n * @readonly\n */\n get iconURL() {\n if (!this.icon) return null;\n return Constants.Endpoints.Guild(this).Icon(this.client.options.http.cdn, this.icon);\n }\n\n /**\n * The acronym that shows up in place of a guild icon.\n * @type {string}\n * @readonly\n */\n get nameAcronym() {\n return this.name.replace(/\\w+/g, name => name[0]).replace(/\\s/g, '');\n }\n\n /**\n * The URL to this guild's splash\n * @type {?string}\n * @readonly\n */\n get splashURL() {\n if (!this.splash) return null;\n return Constants.Endpoints.Guild(this).Splash(this.client.options.http.cdn, this.splash);\n }\n\n /**\n * The owner of the guild\n * @type {?GuildMember}\n * @readonly\n */\n get owner() {\n return this.members.get(this.ownerID);\n }\n\n /**\n * AFK voice channel for this guild\n * @type {?VoiceChannel}\n * @readonly\n */\n get afkChannel() {\n return this.client.channels.get(this.afkChannelID) || null;\n }\n\n /**\n * System channel for this guild\n * @type {?GuildChannel}\n * @readonly\n */\n get systemChannel() {\n return this.client.channels.get(this.systemChannelID) || null;\n }\n\n /**\n * If the client is connected to any voice channel in this guild, this will be the relevant VoiceConnection\n * @type {?VoiceConnection}\n * @readonly\n */\n get voiceConnection() {\n if (this.client.browser) return null;\n return this.client.voice.connections.get(this.id) || null;\n }\n\n /**\n * The position of this guild\n * This is only available when using a user account.\n * @type {?number}\n * @readonly\n */\n get position() {\n if (this.client.user.bot) return null;\n if (!this.client.user.settings.guildPositions) return null;\n return this.client.user.settings.guildPositions.indexOf(this.id);\n }\n\n /**\n * Whether the guild is muted\n * This is only available when using a user account.\n * @type {?boolean}\n * @readonly\n */\n get muted() {\n if (this.client.user.bot) return null;\n try {\n return this.client.user.guildSettings.get(this.id).muted;\n } catch (err) {\n return false;\n }\n }\n\n /**\n * The type of message that should notify you\n * This is only available when using a user account.\n * @type {?MessageNotificationType}\n * @readonly\n */\n get messageNotifications() {\n if (this.client.user.bot) return null;\n try {\n return this.client.user.guildSettings.get(this.id).messageNotifications;\n } catch (err) {\n return null;\n }\n }\n\n /**\n * Whether to receive mobile push notifications\n * This is only available when using a user account.\n * @type {?boolean}\n * @readonly\n */\n get mobilePush() {\n if (this.client.user.bot) return null;\n try {\n return this.client.user.guildSettings.get(this.id).mobilePush;\n } catch (err) {\n return false;\n }\n }\n\n /**\n * Whether to suppress everyone messages\n * This is only available when using a user account.\n * @type {?boolean}\n * @readonly\n */\n get suppressEveryone() {\n if (this.client.user.bot) return null;\n try {\n return this.client.user.guildSettings.get(this.id).suppressEveryone;\n } catch (err) {\n return null;\n }\n }\n\n /**\n * The `@everyone` role of the guild\n * @type {Role}\n * @readonly\n */\n get defaultRole() {\n return this.roles.get(this.id);\n }\n\n /**\n * The client user as a GuildMember of this guild\n * @type {?GuildMember}\n * @readonly\n */\n get me() {\n return this.members.get(this.client.user.id);\n }\n\n /**\n * Fetches a collection of roles in the current guild sorted by position\n * @type {Collection}\n * @readonly\n * @private\n */\n get _sortedRoles() {\n return this._sortPositionWithID(this.roles);\n }\n\n /**\n * Returns the GuildMember form of a User object, if the user is present in the guild.\n * @param {UserResolvable} user The user that you want to obtain the GuildMember of\n * @returns {?GuildMember}\n * @example\n * // Get the guild member of a user\n * const member = guild.member(message.author);\n */\n member(user) {\n return this.client.resolver.resolveGuildMember(this, user);\n }\n\n /**\n * An object containing information about a guild member's ban.\n * @typedef {Object} BanInfo\n * @property {User} user User that was banned\n * @property {?string} reason Reason the user was banned\n */\n\n /**\n * Fetch a ban for a user.\n * @returns {Promise}\n * @param {UserResolvable} user The user to fetch the ban for\n * @example\n * // Get ban\n * guild.fetchBan(message.author)\n * .then(({ user, reason }) => console.log(`${user.tag} was banned for the reason: ${reason}.`))\n * .catch(console.error);\n */\n fetchBan(user) {\n return this.client.rest.methods.getGuildBan(this, user);\n }\n\n /**\n * Fetch a collection of banned users in this guild.\n * @returns {Promise>}\n * @param {boolean} [withReasons=false] Whether or not to include the ban reason(s)\n * @example\n * // Fetch bans in guild\n * guild.fetchBans()\n * .then(bans => console.log(`This guild has ${bans.size} bans`))\n * .catch(console.error);\n */\n fetchBans(withReasons = false) {\n if (withReasons) return this.client.rest.methods.getGuildBans(this);\n return this.client.rest.methods.getGuildBans(this)\n .then(bans => {\n const users = new Collection();\n for (const ban of bans.values()) users.set(ban.user.id, ban.user);\n return users;\n });\n }\n\n /**\n * Fetch a collection of invites to this guild.\n * Resolves with a collection mapping invites by their codes.\n * @returns {Promise>}\n * @example\n * // Fetch invites\n * guild.fetchInvites()\n * .then(invites => console.log(`Fetched ${invites.size} invites`))\n * .catch(console.error);\n * @example\n * // Fetch invite creator by their id\n * guild.fetchInvites()\n * .then(invites => console.log(invites.find(invite => invite.inviter.id === '84484653687267328')))\n * .catch(console.error);\n */\n fetchInvites() {\n return this.client.rest.methods.getGuildInvites(this);\n }\n\n /**\n * Fetches the vanity url invite code to this guild.\n * Resolves with a string matching the vanity url invite code, not the full url.\n * @returns {Promise}\n * @example\n * // Fetch invites\n * guild.fetchVanityCode()\n * .then(code => {\n * console.log(`Vanity URL: https://discord.gg/${code}`);\n * })\n * .catch(console.error);\n */\n fetchVanityCode() {\n if (!this.features.includes('VANITY_URL')) {\n return Promise.reject(new Error('This guild does not have the VANITY_URL feature enabled.'));\n }\n return this.client.rest.methods.getGuildVanityCode(this);\n }\n\n\n /**\n * Fetch all webhooks for the guild.\n * @returns {Promise>}\n * @example\n * // Fetch webhooks\n * guild.fetchWebhooks()\n * .then(webhooks => console.log(`Fetched ${webhooks.size} webhooks`))\n * .catch(console.error);\n */\n fetchWebhooks() {\n return this.client.rest.methods.getGuildWebhooks(this);\n }\n\n /**\n * Fetch available voice regions.\n * @returns {Promise>}\n * @example\n * // Fetch voice regions\n * guild.fetchVoiceRegions()\n * .then(console.log)\n * .catch(console.error);\n */\n fetchVoiceRegions() {\n return this.client.rest.methods.fetchVoiceRegions(this.id);\n }\n\n /**\n * The Guild Embed object\n * @typedef {Object} GuildEmbedData\n * @property {boolean} enabled Whether the embed is enabled\n * @property {?ChannelResolvable} channel The embed channel\n */\n\n /**\n * Fetches the guild embed.\n * @returns {Promise}\n * @example\n * // Fetches the guild embed\n * guild.fetchEmbed()\n * .then(embed => console.log(`The embed is ${embed.enabled ? 'enabled' : 'disabled'}`))\n * .catch(console.error);\n */\n fetchEmbed() {\n return this.client.rest.methods.fetchEmbed(this.id);\n }\n\n /**\n * Fetch audit logs for this guild.\n * @param {Object} [options={}] Options for fetching audit logs\n * @param {Snowflake|GuildAuditLogsEntry} [options.before] Limit to entries from before specified entry\n * @param {Snowflake|GuildAuditLogsEntry} [options.after] Limit to entries from after specified entry\n * @param {number} [options.limit] Limit number of entries\n * @param {UserResolvable} [options.user] Only show entries involving this user\n * @param {AuditLogAction} [options.type] Only show entries involving this action type\n * @returns {Promise}\n * @example\n * // Output audit log entries\n * guild.fetchAuditLogs()\n * .then(audit => console.log(audit.entries.first()))\n * .catch(console.error);\n */\n fetchAuditLogs(options) {\n return this.client.rest.methods.getGuildAuditLogs(this, options);\n }\n\n /**\n * Adds a user to the guild using OAuth2. Requires the `CREATE_INSTANT_INVITE` permission.\n * @param {UserResolvable} user User to add to the guild\n * @param {Object} options Options for the addition\n * @param {string} options.accessToken An OAuth2 access token for the user with the `guilds.join` scope granted to the\n * bot's application\n * @param {string} [options.nick] Nickname to give the member (requires `MANAGE_NICKNAMES`)\n * @param {Collection|Role[]|Snowflake[]} [options.roles] Roles to add to the member\n * (requires `MANAGE_ROLES`)\n * @param {boolean} [options.mute] Whether the member should be muted (requires `MUTE_MEMBERS`)\n * @param {boolean} [options.deaf] Whether the member should be deafened (requires `DEAFEN_MEMBERS`)\n * @returns {Promise}\n */\n addMember(user, options) {\n user = this.client.resolver.resolveUserID(user);\n if (this.members.has(user)) return Promise.resolve(this.members.get(user));\n return this.client.rest.methods.putGuildMember(this, user, options);\n }\n\n /**\n * Fetch a single guild member from a user.\n * @param {UserResolvable} user The user to fetch the member for\n * @param {boolean} [cache=true] Insert the member into the members cache\n * @returns {Promise}\n * @example\n * // Fetch a guild member\n * guild.fetchMember(message.author)\n * .then(console.log)\n * .catch(console.error);\n */\n fetchMember(user, cache = true) {\n user = this.client.resolver.resolveUser(user);\n if (!user) return Promise.reject(new Error('Invalid or uncached id provided.'));\n const member = this.members.get(user.id);\n if (member && member.joinedTimestamp) return Promise.resolve(member);\n return this.client.rest.methods.getGuildMember(this, user, cache);\n }\n\n /**\n * Fetches all the members in the guild, even if they are offline. If the guild has less than 250 members,\n * this should not be necessary.\n * @param {string} [query=''] Limit fetch to members with similar usernames\n * @param {number} [limit=0] Maximum number of members to request\n * @returns {Promise}\n * @example\n * // Fetch guild members\n * guild.fetchMembers()\n * .then(console.log)\n * .catch(console.error);\n * @example\n * // Fetches a maximum of 1 member with the given query\n * guild.fetchMembers('hydrabolt', 1)\n * .then(console.log)\n * .catch(console.error);\n */\n fetchMembers(query = '', limit = 0) {\n return new Promise((resolve, reject) => {\n if (this.memberCount === this.members.size) {\n resolve(this);\n return;\n }\n this.client.ws.send({\n op: Constants.OPCodes.REQUEST_GUILD_MEMBERS,\n d: {\n guild_id: this.id,\n query,\n limit,\n },\n });\n const handler = (members, guild) => {\n if (guild.id !== this.id) return;\n if (this.memberCount === this.members.size || members.length < 1000) {\n this.client.removeListener(Constants.Events.GUILD_MEMBERS_CHUNK, handler);\n resolve(this);\n }\n };\n this.client.on(Constants.Events.GUILD_MEMBERS_CHUNK, handler);\n this.client.setTimeout(() => reject(new Error('Members didn\\'t arrive in time.')), 120 * 1000);\n });\n }\n\n /**\n * Performs a search within the entire guild.\n * This is only available when using a user account.\n * @param {MessageSearchOptions} [options={}] Options to pass to the search\n * @returns {Promise}\n * @example\n * guild.search({\n * content: 'discord.js',\n * before: '2016-11-17'\n * })\n * .then(res => {\n * const hit = res.messages[0].find(m => m.hit).content;\n * console.log(`I found: **${hit}**, total results: ${res.totalResults}`);\n * })\n * .catch(console.error);\n */\n search(options = {}) {\n return this.client.rest.methods.search(this, options);\n }\n\n /**\n * The data for editing a guild.\n * @typedef {Object} GuildEditData\n * @property {string} [name] The name of the guild\n * @property {string} [region] The region of the guild\n * @property {number} [verificationLevel] The verification level of the guild\n * @property {number} [explicitContentFilter] The level of the explicit content filter\n * @property {ChannelResolvable} [afkChannel] The AFK channel of the guild\n * @property {ChannelResolvable} [systemChannel] The system channel of the guild\n * @property {number} [afkTimeout] The AFK timeout of the guild\n * @property {Base64Resolvable} [icon] The icon of the guild\n * @property {GuildMemberResolvable} [owner] The owner of the guild\n * @property {Base64Resolvable} [splash] The splash screen of the guild\n */\n\n /**\n * Updates the guild with new information - e.g. a new name.\n * @param {GuildEditData} data The data to update the guild with\n * @param {string} [reason] Reason for editing the guild\n * @returns {Promise}\n * @example\n * // Set the guild name and region\n * guild.edit({\n * name: 'Discord Guild',\n * region: 'london',\n * })\n * .then(g => console.log(`Changed guild name to ${g} and region to ${g.region}`))\n * .catch(console.error);\n */\n edit(data, reason) {\n const _data = {};\n if (data.name) _data.name = data.name;\n if (data.region) _data.region = data.region;\n if (typeof data.verificationLevel !== 'undefined') _data.verification_level = Number(data.verificationLevel);\n if (typeof data.afkChannel !== 'undefined') {\n _data.afk_channel_id = this.client.resolver.resolveChannelID(data.afkChannel);\n }\n if (typeof data.systemChannel !== 'undefined') {\n _data.system_channel_id = this.client.resolver.resolveChannelID(data.systemChannel);\n }\n if (data.afkTimeout) _data.afk_timeout = Number(data.afkTimeout);\n if (typeof data.icon !== 'undefined') _data.icon = data.icon;\n if (data.owner) _data.owner_id = this.client.resolver.resolveUser(data.owner).id;\n if (typeof data.splash !== 'undefined') _data.splash = data.splash;\n if (typeof data.explicitContentFilter !== 'undefined') {\n _data.explicit_content_filter = Number(data.explicitContentFilter);\n }\n if (typeof data.defaultMessageNotifications !== 'undefined') {\n _data.default_message_notifications = typeof data.defaultMessageNotifications === 'string' ?\n Constants.DefaultMessageNotifications.indexOf(data.defaultMessageNotifications) :\n Number(data.defaultMessageNotifications);\n }\n return this.client.rest.methods.updateGuild(this, _data, reason);\n }\n\n /**\n * Edit the level of the explicit content filter.\n * @param {number} explicitContentFilter The new level of the explicit content filter\n * @param {string} [reason] Reason for changing the level of the guild's explicit content filter\n * @returns {Promise}\n */\n setExplicitContentFilter(explicitContentFilter, reason) {\n return this.edit({ explicitContentFilter }, reason);\n }\n\n /**\n * Edits the setting of the default message notifications of the guild.\n * @param {DefaultMessageNotifications|number} defaultMessageNotifications\n * The new setting for the default message notifications\n * @param {string} [reason] Reason for changing the setting of the default message notifications\n * @returns {Promise}\n */\n setDefaultMessageNotifications(defaultMessageNotifications, reason) {\n return this.edit({ defaultMessageNotifications }, reason);\n }\n\n /**\n * Edit the name of the guild.\n * @param {string} name The new name of the guild\n * @param {string} [reason] Reason for changing the guild's name\n * @returns {Promise}\n * @example\n * // Edit the guild name\n * guild.setName('Discord Guild')\n * .then(g => console.log(`Updated guild name to ${g}`))\n * .catch(console.error);\n */\n setName(name, reason) {\n return this.edit({ name }, reason);\n }\n\n /**\n * Edit the region of the guild.\n * @param {string} region The new region of the guild\n * @param {string} [reason] Reason for changing the guild's region\n * @returns {Promise}\n * @example\n * // Edit the guild region\n * guild.setRegion('london')\n * .then(g => console.log(`Updated guild region to ${g.region}`))\n * .catch(console.error);\n */\n setRegion(region, reason) {\n return this.edit({ region }, reason);\n }\n\n /**\n * Edit the verification level of the guild.\n * @param {number} verificationLevel The new verification level of the guild\n * @param {string} [reason] Reason for changing the guild's verification level\n * @returns {Promise}\n * @example\n * // Edit the guild verification level\n * guild.setVerificationLevel(1)\n * .then(g => console.log(`Updated guild verification level to ${g.verificationLevel}`))\n * .catch(console.error);\n */\n setVerificationLevel(verificationLevel, reason) {\n return this.edit({ verificationLevel }, reason);\n }\n\n /**\n * Edit the AFK channel of the guild.\n * @param {ChannelResolvable} afkChannel The new AFK channel\n * @param {string} [reason] Reason for changing the guild's AFK channel\n * @returns {Promise}\n * @example\n * // Edit the guild AFK channel\n * guild.setAFKChannel(channel)\n * .then(g => console.log(`Updated guild AFK channel to ${g.afkChannel.name}`))\n * .catch(console.error);\n */\n setAFKChannel(afkChannel, reason) {\n return this.edit({ afkChannel }, reason);\n }\n\n /**\n * Edit the system channel of the guild.\n * @param {ChannelResolvable} systemChannel The new system channel\n * @param {string} [reason] Reason for changing the guild's system channel\n * @returns {Promise}\n */\n setSystemChannel(systemChannel, reason) {\n return this.edit({ systemChannel }, reason);\n }\n\n /**\n * Edit the AFK timeout of the guild.\n * @param {number} afkTimeout The time in seconds that a user must be idle to be considered AFK\n * @param {string} [reason] Reason for changing the guild's AFK timeout\n * @returns {Promise}\n * @example\n * // Edit the guild AFK channel\n * guild.setAFKTimeout(60)\n * .then(g => console.log(`Updated guild AFK timeout to ${g.afkTimeout}`))\n * .catch(console.error);\n */\n setAFKTimeout(afkTimeout, reason) {\n return this.edit({ afkTimeout }, reason);\n }\n\n /**\n * Set a new guild icon.\n * @param {Base64Resolvable|BufferResolvable} icon The new icon of the guild\n * @param {string} [reason] Reason for changing the guild's icon\n * @returns {Promise}\n * @example\n * // Edit the guild icon\n * guild.setIcon('./icon.png')\n * .then(console.log)\n * .catch(console.error);\n */\n setIcon(icon, reason) {\n return this.client.resolver.resolveImage(icon).then(data => this.edit({ icon: data, reason }));\n }\n\n /**\n * Sets a new owner of the guild.\n * @param {GuildMemberResolvable} owner The new owner of the guild\n * @param {string} [reason] Reason for setting the new owner\n * @returns {Promise}\n * @example\n * // Edit the guild owner\n * guild.setOwner(guild.members.first())\n * .then(g => console.log(`Updated the guild owner to ${g.owner.displayName}`))\n * .catch(console.error);\n */\n setOwner(owner, reason) {\n return this.edit({ owner }, reason);\n }\n\n /**\n * Set a new guild splash screen.\n * @param {BufferResolvable|Base64Resolvable} splash The new splash screen of the guild\n * @param {string} [reason] Reason for changing the guild's splash screen\n * @returns {Promise}\n * @example\n * // Edit the guild splash\n * guild.setSplash('./splash.png')\n * .then(console.log)\n * .catch(console.error);\n */\n setSplash(splash) {\n return this.client.resolver.resolveImage(splash).then(data => this.edit({ splash: data }));\n }\n\n /**\n * Sets the position of the guild in the guild listing.\n * This is only available when using a user account.\n * @param {number} position Absolute or relative position\n * @param {boolean} [relative=false] Whether to position relatively or absolutely\n * @returns {Promise}\n */\n setPosition(position, relative) {\n if (this.client.user.bot) {\n return Promise.reject(new Error('Setting guild position is only available for user accounts'));\n }\n return this.client.user.settings.setGuildPosition(this, position, relative);\n }\n\n /**\n * Marks all messages in this guild as read.\n * This is only available when using a user account.\n * @returns {Promise}\n */\n acknowledge() {\n return this.client.rest.methods.ackGuild(this);\n }\n\n /**\n * Allow direct messages from guild members.\n * This is only available when using a user account.\n * @param {boolean} allow Whether to allow direct messages\n * @returns {Promise}\n */\n allowDMs(allow) {\n const settings = this.client.user.settings;\n if (allow) return settings.removeRestrictedGuild(this);\n else return settings.addRestrictedGuild(this);\n }\n\n /**\n * Bans a user from the guild.\n * @param {UserResolvable} user The user to ban\n * @param {Object|number|string} [options] Ban options. If a number, the number of days to delete messages for, if a\n * string, the ban reason. Supplying an object allows you to do both.\n * @param {number} [options.days=0] Number of days of messages to delete\n * @param {string} [options.reason] Reason for banning\n * @returns {Promise} Result object will be resolved as specifically as possible.\n * If the GuildMember cannot be resolved, the User will instead be attempted to be resolved. If that also cannot\n * be resolved, the user ID will be the result.\n * @example\n * // Ban a user by ID\n * guild.ban('some user ID')\n * .then(user => console.log(`Banned ${user.username || user.id || user} from ${guild}`))\n * .catch(console.error);\n * @example\n * // Ban a user by object with reason and days\n * guild.ban(user, { days: 7, reason: 'He needed to go' })\n * .then(console.log)\n * .catch(console.error);\n */\n ban(user, options = {}) {\n if (typeof options === 'number') {\n options = { reason: null, 'delete-message-days': options };\n } else if (typeof options === 'string') {\n options = { reason: options, 'delete-message-days': 0 };\n }\n if (options.days) options['delete-message-days'] = options.days;\n return this.client.rest.methods.banGuildMember(this, user, options);\n }\n\n /**\n * Unbans a user from the guild.\n * @param {UserResolvable} user The user to unban\n * @param {string} [reason] Reason for unbanning the user\n * @returns {Promise}\n * @example\n * // Unban a user by ID (or with a user/guild member object)\n * guild.unban('some user ID')\n * .then(user => console.log(`Unbanned ${user.username} from ${guild}`))\n * .catch(console.error);\n */\n unban(user, reason) {\n return this.client.rest.methods.unbanGuildMember(this, user, reason);\n }\n\n /**\n * Prunes members from the guild based on how long they have been inactive.\n * @param {number} days Number of days of inactivity required to kick\n * @param {boolean} [dry=false] If true, will return number of users that will be kicked, without actually doing it\n * @param {string} [reason] Reason for this prune\n * @returns {Promise} The number of members that were/will be kicked\n * @example\n * // See how many members will be pruned\n * guild.pruneMembers(12, true)\n * .then(pruned => console.log(`This will prune ${pruned} people!`))\n * .catch(console.error);\n * @example\n * // Actually prune the members\n * guild.pruneMembers(12)\n * .then(pruned => console.log(`I just pruned ${pruned} people!`))\n * .catch(console.error);\n */\n pruneMembers(days, dry = false, reason) {\n if (typeof days !== 'number') throw new TypeError('Days must be a number.');\n return this.client.rest.methods.pruneGuildMembers(this, days, dry, reason);\n }\n\n /**\n * Syncs this guild (already done automatically every 30 seconds).\n * This is only available when using a user account.\n */\n sync() {\n if (!this.client.user.bot) this.client.syncGuilds([this]);\n }\n\n /**\n * Overwrites to use when creating a channel or replacing overwrites\n * @typedef {Object} ChannelCreationOverwrites\n * @property {PermissionResolvable} [allow] The permissions to allow\n * @property {PermissionResolvable} [allowed] The permissions to allow\n * **(deprecated)**\n * @property {PermissionResolvable} [deny] The permissions to deny\n * @property {PermissionResolvable} [denied] The permissions to deny\n * **(deprecated)**\n * @property {GuildMemberResolvable|RoleResolvable} id Member or role this overwrite is for\n */\n\n /**\n * Creates a new channel in the guild.\n * @param {string} name The name of the new channel\n * @param {string|ChannelData} [typeOrOptions='text']\n * The type of the new channel, one of `text`, `voice`, `category`, `news`, or `store`. **(deprecated, use options)**\n * Alternatively options for the new channel, overriding the following parameters.\n * @param {ChannelCreationOverwrites[]|Collection} [permissionOverwrites]\n * Permission overwrites **(deprecated, use options)**\n * @param {string} [reason] Reason for creating this channel **(deprecated, use options)**\n * @returns {Promise}\n * @example\n * // Create a new text channel\n * guild.createChannel('new-general', { type: 'text' })\n * .then(console.log)\n * .catch(console.error);\n * @example\n * // Create a new category channel with permission overwrites\n * guild.createChannel('new-category', {\n * type: 'category',\n * permissionOverwrites: [{\n * id: guild.id,\n * deny: ['MANAGE_MESSAGES'],\n * allow: ['SEND_MESSAGES']\n * }]\n * })\n * .then(console.log)\n * .catch(console.error);\n */\n createChannel(name, typeOrOptions, permissionOverwrites, reason) {\n if (!typeOrOptions || (typeof typeOrOptions === 'string')) {\n if (typeOrOptions) {\n ((any, ...more) => console.warn(any, more))(\n 'Guild#createChannel: Create channels with an options object instead of separate parameters',\n 'DeprecationWarning'\n );\n }\n typeOrOptions = {\n type: typeOrOptions,\n permissionOverwrites,\n reason,\n };\n }\n return this.client.rest.methods.createChannel(this, name, typeOrOptions);\n }\n\n /**\n * The data needed for updating a channel's position.\n * @typedef {Object} ChannelPosition\n * @property {ChannelResolvable} channel Channel to update\n * @property {number} position New position for the channel\n */\n\n /**\n * Batch-updates the guild's channels' positions.\n * @param {ChannelPosition[]} channelPositions Channel positions to update\n * @returns {Promise}\n * @example\n * guild.updateChannels([{ channel: channelID, position: newChannelIndex }])\n * .then(g => console.log(`Updated channel positions for ${g}`))\n * .catch(console.error);\n */\n setChannelPositions(channelPositions) {\n return this.client.rest.methods.updateChannelPositions(this.id, channelPositions);\n }\n\n /**\n * Edits the guild's embed.\n * @param {GuildEmbedData} embed The embed for the guild\n * @param {string} [reason] Reason for changing the guild's embed\n * @returns {Promise}\n */\n setEmbed(embed, reason) {\n return this.client.rest.methods.updateEmbed(this.id, embed, reason)\n .then(() => this);\n }\n\n /**\n * Creates a new role in the guild with given information.\n * @param {RoleData} [data] The data to update the role with\n * @param {string} [reason] Reason for creating this role\n * @returns {Promise}\n * @example\n * // Create a new role\n * guild.createRole()\n * .then(role => console.log(`Created new role with name ${role.name}`))\n * .catch(console.error);\n * @example\n * // Create a new role with data\n * guild.createRole({\n * name: 'Super Cool People',\n * color: 'BLUE',\n * })\n * .then(role => console.log(`Created new role with name ${role.name} and color ${role.color}`))\n * .catch(console.error)\n */\n createRole(data = {}, reason) {\n return this.client.rest.methods.createGuildRole(this, data, reason);\n }\n\n /**\n * Creates a new custom emoji in the guild.\n * @param {BufferResolvable|Base64Resolvable} attachment The image for the emoji\n * @param {string} name The name for the emoji\n * @param {Collection|Role[]} [roles] Roles to limit the emoji to\n * @param {string} [reason] Reason for creating the emoji\n * @returns {Promise} The created emoji\n * @example\n * // Create a new emoji from a url\n * guild.createEmoji('https://i.imgur.com/w3duR07.png', 'rip')\n * .then(emoji => console.log(`Created new emoji with name ${emoji.name}`))\n * .catch(console.error);\n * @example\n * // Create a new emoji from a file on your computer\n * guild.createEmoji('./memes/banana.png', 'banana')\n * .then(emoji => console.log(`Created new emoji with name ${emoji.name}`))\n * .catch(console.error);\n */\n createEmoji(attachment, name, roles, reason) {\n if (typeof attachment === 'string' && attachment.startsWith('data:')) {\n return this.client.rest.methods.createEmoji(this, attachment, name, roles, reason);\n } else {\n return this.client.resolver.resolveImage(attachment).then(data =>\n this.client.rest.methods.createEmoji(this, data, name, roles, reason)\n );\n }\n }\n\n /**\n * Delete an emoji.\n * @param {Emoji|string} emoji The emoji to delete\n * @param {string} [reason] Reason for deleting the emoji\n * @returns {Promise}\n */\n deleteEmoji(emoji, reason) {\n if (typeof emoji === 'string') emoji = this.emojis.get(emoji);\n if (!(emoji instanceof Emoji)) throw new TypeError('Emoji must be either an instance of Emoji or an ID');\n return this.client.rest.methods.deleteEmoji(emoji, reason);\n }\n\n /**\n * Causes the client to leave the guild.\n * @returns {Promise}\n * @example\n * // Leave a guild\n * guild.leave()\n * .then(g => console.log(`Left the guild ${g}`))\n * .catch(console.error);\n */\n leave() {\n return this.client.rest.methods.leaveGuild(this);\n }\n\n /**\n * Causes the client to delete the guild.\n * @returns {Promise}\n * @example\n * // Delete a guild\n * guild.delete()\n * .then(g => console.log(`Deleted the guild ${g}`))\n * .catch(console.error);\n */\n delete() {\n return this.client.rest.methods.deleteGuild(this);\n }\n\n /**\n * Whether this guild equals another guild. It compares all properties, so for most operations\n * it is advisable to just compare `guild.id === guild2.id` as it is much faster and is often\n * what most users need.\n * @param {Guild} guild The guild to compare with\n * @returns {boolean}\n */\n equals(guild) {\n let equal =\n guild &&\n this.id === guild.id &&\n this.available === !guild.unavailable &&\n this.splash === guild.splash &&\n this.region === guild.region &&\n this.name === guild.name &&\n this.memberCount === guild.member_count &&\n this.large === guild.large &&\n this.icon === guild.icon &&\n Util.arraysEqual(this.features, guild.features) &&\n this.ownerID === guild.owner_id &&\n this.verificationLevel === guild.verification_level &&\n this.embedEnabled === guild.embed_enabled;\n\n if (equal) {\n if (this.embedChannel) {\n if (this.embedChannel.id !== guild.embed_channel_id) equal = false;\n } else if (guild.embed_channel_id) {\n equal = false;\n }\n }\n\n return equal;\n }\n\n /**\n * When concatenated with a string, this automatically concatenates the guild's name instead of the guild object.\n * @returns {string}\n * @example\n * // Logs: Hello from My Guild!\n * console.log(`Hello from ${guild}!`);\n * @example\n * // Logs: Hello from My Guild!\n * console.log('Hello from ' + guild + '!');\n */\n toString() {\n return this.name;\n }\n\n _addMember(guildUser, emitEvent = true) {\n const existing = this.members.has(guildUser.user.id);\n if (!(guildUser.user instanceof User)) guildUser.user = this.client.dataManager.newUser(guildUser.user);\n\n guildUser.joined_at = guildUser.joined_at || 0;\n const member = new GuildMember(this, guildUser);\n this.members.set(member.id, member);\n\n if (this._rawVoiceStates && this._rawVoiceStates.has(member.user.id)) {\n const voiceState = this._rawVoiceStates.get(member.user.id);\n member.serverMute = voiceState.mute;\n member.serverDeaf = voiceState.deaf;\n member.selfMute = voiceState.self_mute;\n member.selfDeaf = voiceState.self_deaf;\n member.voiceSessionID = voiceState.session_id;\n member.voiceChannelID = voiceState.channel_id;\n if (this.client.channels.has(voiceState.channel_id)) {\n this.client.channels.get(voiceState.channel_id).members.set(member.user.id, member);\n } else {\n this.client.emit('warn', `Member ${member.id} added in guild ${this.id} with an uncached voice channel`);\n }\n }\n\n /**\n * Emitted whenever a user joins a guild.\n * @event Client#guildMemberAdd\n * @param {GuildMember} member The member that has joined a guild\n */\n if (this.client.ws.connection.status === Constants.Status.READY && emitEvent && !existing) {\n this.client.emit(Constants.Events.GUILD_MEMBER_ADD, member);\n }\n\n return member;\n }\n\n _updateMember(member, data) {\n const oldMember = Util.cloneObject(member);\n\n if (data.roles) member._roles = data.roles;\n if (typeof data.nick !== 'undefined') member.nickname = data.nick;\n\n const notSame = member.nickname !== oldMember.nickname || !Util.arraysEqual(member._roles, oldMember._roles);\n\n if (this.client.ws.connection.status === Constants.Status.READY && notSame) {\n /**\n * Emitted whenever a guild member changes - i.e. new role, removed role, nickname.\n * @event Client#guildMemberUpdate\n * @param {GuildMember} oldMember The member before the update\n * @param {GuildMember} newMember The member after the update\n */\n this.client.emit(Constants.Events.GUILD_MEMBER_UPDATE, oldMember, member);\n }\n\n return {\n old: oldMember,\n mem: member,\n };\n }\n\n _removeMember(guildMember) {\n if (guildMember.voiceChannel) guildMember.voiceChannel.members.delete(guildMember.id);\n this.members.delete(guildMember.id);\n }\n\n _memberSpeakUpdate(user, speaking) {\n const member = this.members.get(user);\n if (member && member.speaking !== speaking) {\n member.speaking = speaking;\n /**\n * Emitted once a guild member starts/stops speaking.\n * @event Client#guildMemberSpeaking\n * @param {GuildMember} member The member that started/stopped speaking\n * @param {boolean} speaking Whether or not the member is speaking\n */\n this.client.emit(Constants.Events.GUILD_MEMBER_SPEAKING, member, speaking);\n }\n }\n\n _setPresence(id, presence) {\n if (this.presences.get(id)) {\n this.presences.get(id).update(presence);\n return;\n }\n this.presences.set(id, new Presence(presence, this.client));\n }\n\n /**\n * Set the position of a role in this guild.\n * @param {string|Role} role The role to edit, can be a role object or a role ID\n * @param {number} position The new position of the role\n * @param {boolean} [relative=false] Position Moves the role relative to its current position\n * @returns {Promise}\n */\n setRolePosition(role, position, relative = false) {\n if (typeof role === 'string') {\n role = this.roles.get(role);\n if (!role) return Promise.reject(new Error('Supplied role is not a role or snowflake.'));\n }\n\n position = Number(position);\n if (isNaN(position)) return Promise.reject(new Error('Supplied position is not a number.'));\n\n let updatedRoles = this._sortedRoles.array();\n\n Util.moveElementInArray(updatedRoles, role, position, relative);\n\n updatedRoles = updatedRoles.map((r, i) => ({ id: r.id, position: i }));\n return this.client.rest.methods.setRolePositions(this.id, updatedRoles);\n }\n\n /**\n * Set the position of a channel in this guild.\n * @param {string|GuildChannel} channel The channel to edit, can be a channel object or a channel ID\n * @param {number} position The new position of the channel\n * @param {boolean} [relative=false] Position Moves the channel relative to its current position\n * @returns {Promise}\n */\n setChannelPosition(channel, position, relative = false) {\n if (typeof channel === 'string') {\n channel = this.channels.get(channel);\n if (!channel) return Promise.reject(new Error('Supplied channel is not a channel or snowflake.'));\n }\n\n position = Number(position);\n if (isNaN(position)) return Promise.reject(new Error('Supplied position is not a number.'));\n\n let updatedChannels = this._sortedChannels(channel.type).array();\n\n Util.moveElementInArray(updatedChannels, channel, position, relative);\n\n updatedChannels = updatedChannels.map((r, i) => ({ id: r.id, position: i }));\n return this.client.rest.methods.setChannelPositions(this.id, updatedChannels);\n }\n\n /**\n * Fetches a collection of channels in the current guild sorted by position.\n * @param {string} type The channel type\n * @returns {Collection}\n * @private\n */\n _sortedChannels(type) {\n return this._sortPositionWithID(this.channels.filter(c => {\n if (type === 'voice' && c.type === 'voice') return true;\n else if (type !== 'voice' && c.type !== 'voice') return true;\n else return type === c.type;\n }));\n }\n\n /**\n * Sorts a collection by object position or ID if the positions are equivalent.\n * Intended to be identical to Discord's sorting method.\n * @param {Collection} collection The collection to sort\n * @returns {Collection}\n * @private\n */\n _sortPositionWithID(collection) {\n return collection.sort((a, b) =>\n a.position !== b.position ?\n a.position - b.position :\n Long.fromString(b.id).sub(Long.fromString(a.id)).toNumber()\n );\n }\n}\n\n/**\n * The `#general` TextChannel of the guild\n * @name Guild#defaultChannel\n * @type {TextChannel}\n * @readonly\n * @deprecated\n */\nObject.defineProperty(Guild.prototype, 'defaultChannel', {\n get: util.deprecate(function defaultChannel() {\n return this.channels.get(this.id);\n }, 'Guild#defaultChannel: This property is obsolete, will be removed in v12.0.0, and may not function as expected.'),\n});\n\nGuild.prototype.acknowledge =\n util.deprecate(Guild.prototype.acknowledge, 'Guild#acknowledge: userbot methods will be removed');\n\nGuild.prototype.setPosition =\n util.deprecate(Guild.prototype.setPosition, 'Guild#setPosition: userbot methods will be removed');\n\nGuild.prototype.search =\n util.deprecate(Guild.prototype.search, 'Guild#search: userbot methods will be removed');\n\nGuild.prototype.sync =\n util.deprecate(Guild.prototype.sync, 'Guild#sync:, userbot methods will be removed');\n\nmodule.exports = Guild;\n\n\n//# sourceURL=webpack:///./src/structures/Guild.js?"); /***/ }),