diff --git a/discord.master.js b/discord.master.js index 62ef6a08..e6dd43e1 100644 --- a/discord.master.js +++ b/discord.master.js @@ -61,14 +61,14 @@ window["Discord"] = /******/ __webpack_require__.p = ""; /******/ /******/ // Load entry module and return exports -/******/ return __webpack_require__(__webpack_require__.s = 79); +/******/ return __webpack_require__(__webpack_require__.s = 62); /******/ }) /************************************************************************/ /******/ ([ /* 0 */ /***/ (function(module, exports, __webpack_require__) { -/* WEBPACK VAR INJECTION */(function(process) {exports.Package = __webpack_require__(57); +/* WEBPACK VAR INJECTION */(function(process) {exports.Package = __webpack_require__(39); const { Error, RangeError } = __webpack_require__(4); /** @@ -126,7 +126,7 @@ exports.DefaultOptions = { */ ws: { large_threshold: 250, - compress: __webpack_require__(115).platform() !== 'browser', + compress: __webpack_require__(76).platform() !== 'browser', properties: { $os: process ? process.platform : 'discord.js', $browser: 'discord.js', @@ -777,7 +777,7 @@ function keyMirror(arr) { return tmp; } -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(8))) +/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(18))) /***/ }), /* 1 */ @@ -1263,14 +1263,2852 @@ module.exports = Collection; /* 4 */ /***/ (function(module, exports, __webpack_require__) { -module.exports = __webpack_require__(58); -module.exports.Messages = __webpack_require__(114); +module.exports = __webpack_require__(40); +module.exports.Messages = __webpack_require__(75); /***/ }), /* 5 */ /***/ (function(module, exports, __webpack_require__) { +/* WEBPACK VAR INJECTION */(function(Buffer) {const Long = __webpack_require__(28); +const snekfetch = __webpack_require__(29); +const { Colors, DefaultOptions, Endpoints } = __webpack_require__(0); +const { Error: DiscordError, RangeError, TypeError } = __webpack_require__(4); +const has = (o, k) => Object.prototype.hasOwnProperty.call(o, k); + +/** + * Contains various general-purpose utility methods. These functions are also available on the base `Discord` object. + */ +class Util { + constructor() { + throw new Error(`The ${this.constructor.name} class may not be instantiated.`); + } + + /** + * Splits a string into multiple chunks at a designated character that do not exceed a specific length. + * @param {string} text Content to split + * @param {SplitOptions} [options] Options controlling the behaviour of the split + * @returns {string|string[]} + */ + static splitMessage(text, { maxLength = 1950, char = '\n', prepend = '', append = '' } = {}) { + if (text.length <= maxLength) return text; + const splitText = text.split(char); + if (splitText.length === 1) { + throw new RangeError('SPLIT_MAX_LEN'); + } + const messages = ['']; + let msg = 0; + for (let i = 0; i < splitText.length; i++) { + if (messages[msg].length + splitText[i].length + 1 > maxLength) { + messages[msg] += append; + messages.push(prepend); + msg++; + } + messages[msg] += (messages[msg].length > 0 && messages[msg] !== prepend ? char : '') + splitText[i]; + } + return messages.filter(m => m); + } + + /** + * Escapes any Discord-flavour markdown in a string. + * @param {string} text Content to escape + * @param {boolean} [onlyCodeBlock=false] Whether to only escape codeblocks (takes priority) + * @param {boolean} [onlyInlineCode=false] Whether to only escape inline code + * @returns {string} + */ + static escapeMarkdown(text, onlyCodeBlock = false, onlyInlineCode = false) { + if (onlyCodeBlock) return text.replace(/```/g, '`\u200b``'); + if (onlyInlineCode) return text.replace(/\\(`|\\)/g, '$1').replace(/(`|\\)/g, '\\$1'); + return text.replace(/\\(\*|_|`|~|\\)/g, '$1').replace(/(\*|_|`|~|\\)/g, '\\$1'); + } + + /** + * Gets the recommended shard count from Discord. + * @param {string} token Discord auth token + * @param {number} [guildsPerShard=1000] Number of guilds per shard + * @returns {Promise} The recommended number of shards + */ + static fetchRecommendedShards(token, guildsPerShard = 1000) { + return new Promise((resolve, reject) => { + if (!token) throw new DiscordError('TOKEN_MISSING'); + snekfetch.get(`${DefaultOptions.http.api}/v${DefaultOptions.http.version}${Endpoints.botGateway}`) + .set('Authorization', `Bot ${token.replace(/^Bot\s*/i, '')}`) + .end((err, res) => { + if (err) reject(err); + resolve(res.body.shards * (1000 / guildsPerShard)); + }); + }); + } + + /** + * Parses emoji info out of a string. The string must be one of: + * * A UTF-8 emoji (no ID) + * * A URL-encoded UTF-8 emoji (no ID) + * * A Discord custom emoji (`<:name:id>`) + * @param {string} text Emoji string to parse + * @returns {Object} Object with `name` and `id` properties + * @private + */ + static parseEmoji(text) { + if (text.includes('%')) text = decodeURIComponent(text); + if (text.includes(':')) { + const [name, id] = text.split(':'); + return { name, id }; + } else { + return { + name: text, + id: null, + }; + } + } + + /** + * Checks whether the arrays are equal, also removes duplicated entries from b. + * @param {Array<*>} a Array which will not be modified. + * @param {Array<*>} b Array to remove duplicated entries from. + * @returns {boolean} Whether the arrays are equal. + * @private + */ + static arraysEqual(a, b) { + if (a === b) return true; + if (a.length !== b.length) return false; + + for (const item of a) { + const ind = b.indexOf(item); + if (ind !== -1) b.splice(ind, 1); + } + + return b.length === 0; + } + + /** + * Shallow-copies an object with its class/prototype intact. + * @param {Object} obj Object to clone + * @returns {Object} + * @private + */ + static cloneObject(obj) { + return Object.assign(Object.create(obj), obj); + } + + /** + * Sets default properties on an object that aren't already specified. + * @param {Object} def Default properties + * @param {Object} given Object to assign defaults to + * @returns {Object} + * @private + */ + static mergeDefault(def, given) { + if (!given) return def; + for (const key in def) { + if (!has(given, key) || given[key] === undefined) { + given[key] = def[key]; + } else if (given[key] === Object(given[key])) { + given[key] = this.mergeDefault(def[key], given[key]); + } + } + + return given; + } + + /** + * Converts an ArrayBuffer or string to a Buffer. + * @param {ArrayBuffer|string} ab ArrayBuffer to convert + * @returns {Buffer} + * @private + */ + static convertToBuffer(ab) { + if (typeof ab === 'string') ab = this.str2ab(ab); + return Buffer.from(ab); + } + + /** + * Converts a string to an ArrayBuffer. + * @param {string} str String to convert + * @returns {ArrayBuffer} + * @private + */ + static str2ab(str) { + const buffer = new ArrayBuffer(str.length * 2); + const view = new Uint16Array(buffer); + for (var i = 0, strLen = str.length; i < strLen; i++) view[i] = str.charCodeAt(i); + return buffer; + } + + /** + * Makes an Error from a plain info object. + * @param {Object} obj Error info + * @param {string} obj.name Error type + * @param {string} obj.message Message for the error + * @param {string} obj.stack Stack for the error + * @returns {Error} + * @private + */ + static makeError(obj) { + const err = new Error(obj.message); + err.name = obj.name; + err.stack = obj.stack; + return err; + } + + /** + * Makes a plain error info object from an Error. + * @param {Error} err Error to get info from + * @returns {Object} + * @private + */ + static makePlainError(err) { + const obj = {}; + obj.name = err.name; + obj.message = err.message; + obj.stack = err.stack; + return obj; + } + + /** + * Moves an element in an array *in place*. + * @param {Array<*>} array Array to modify + * @param {*} element Element to move + * @param {number} newIndex Index or offset to move the element to + * @param {boolean} [offset=false] Move the element by an offset amount rather than to a set index + * @returns {number} + * @private + */ + static moveElementInArray(array, element, newIndex, offset = false) { + const index = array.indexOf(element); + newIndex = (offset ? index : 0) + newIndex; + if (newIndex > -1 && newIndex < array.length) { + const removedElement = array.splice(index, 1)[0]; + array.splice(newIndex, 0, removedElement); + } + return array.indexOf(element); + } + + /** + * Data that can be resolved to give a string. This can be: + * * A string + * * An array (joined with a new line delimiter to give a string) + * * Any value + * @typedef {string|Array|*} StringResolvable + */ + + /** + * Resolves a StringResolvable to a string. + * @param {StringResolvable} data The string resolvable to resolve + * @returns {string} + */ + + static resolveString(data) { + if (typeof data === 'string') return data; + if (data instanceof Array) return data.join('\n'); + return String(data); + } + + /** + * Can be a Hex Literal, Hex String, Number, RGB Array, or one of the following + * ``` + * [ + * 'DEFAULT', + * 'AQUA', + * 'GREEN', + * 'BLUE', + * 'PURPLE', + * 'GOLD', + * 'ORANGE', + * 'RED', + * 'GREY', + * 'DARKER_GREY', + * 'NAVY', + * 'DARK_AQUA', + * 'DARK_GREEN', + * 'DARK_BLUE', + * 'DARK_PURPLE', + * 'DARK_GOLD', + * 'DARK_ORANGE', + * 'DARK_RED', + * 'DARK_GREY', + * 'LIGHT_GREY', + * 'DARK_NAVY', + * 'RANDOM', + * ] + * ``` + * or something like + * ``` + * [255, 0, 255] + * ``` + * for purple + * @typedef {string|number|Array} ColorResolvable + */ + + /** + * Resolves a ColorResolvable into a color number. + * @param {ColorResolvable} color Color to resolve + * @returns {number} A color + */ + + static resolveColor(color) { + if (typeof color === 'string') { + if (color === 'RANDOM') return Math.floor(Math.random() * (0xFFFFFF + 1)); + color = Colors[color] || parseInt(color.replace('#', ''), 16); + } else if (color instanceof Array) { + color = (color[0] << 16) + (color[1] << 8) + color[2]; + } + + if (color < 0 || color > 0xFFFFFF) { + throw new RangeError('COLOR_RANGE'); + } else if (color && isNaN(color)) { + throw new TypeError('COLOR_CONVERT'); + } + + return color; + } + + /** + * Sort by discord's position then ID thing + * @param {Collection} collection Collection of objects to sort + * @returns {Collection} + */ + static discordSort(collection) { + return collection + .sort((a, b) => a.rawPosition - b.rawPosition || Long.fromString(a.id).sub(Long.fromString(b.id)).toNumber()); + } + + static setPosition(item, position, relative, sorted, route, reason) { + let updatedItems = sorted.array(); + Util.moveElementInArray(updatedItems, item, position, relative); + updatedItems = updatedItems.map((r, i) => ({ id: r.id, position: i })); + return route.patch({ data: updatedItems, reason }); + } +} + +module.exports = Util; + +/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(17).Buffer)) + +/***/ }), +/* 6 */ +/***/ (function(module, exports, __webpack_require__) { + +const Long = __webpack_require__(28); + +// Discord epoch (2015-01-01T00:00:00.000Z) +const EPOCH = 1420070400000; +let INCREMENT = 0; + +/** + * A container for useful snowflake-related methods. + */ +class SnowflakeUtil { + constructor() { + throw new Error(`The ${this.constructor.name} class may not be instantiated.`); + } + + /** + * A Twitter snowflake, except the epoch is 2015-01-01T00:00:00.000Z + * ``` + * If we have a snowflake '266241948824764416' we can represent it as binary: + * + * 64 22 17 12 0 + * 000000111011000111100001101001000101000000 00001 00000 000000000000 + * number of ms since Discord epoch worker pid increment + * ``` + * @typedef {string} Snowflake + */ + + /** + * Generates a Discord snowflake. + * This hardcodes the worker ID as 1 and the process ID as 0. + * @returns {Snowflake} The generated snowflake + */ + static generate() { + if (INCREMENT >= 4095) INCREMENT = 0; + const BINARY = `${pad((Date.now() - EPOCH).toString(2), 42)}0000100000${pad((INCREMENT++).toString(2), 12)}`; + return Long.fromString(BINARY, 2).toString(); + } + + /** + * A deconstructed snowflake. + * @typedef {Object} DeconstructedSnowflake + * @property {number} timestamp Timestamp the snowflake was created + * @property {Date} date Date the snowflake was created + * @property {number} workerID Worker ID in the snowflake + * @property {number} processID Process ID in the snowflake + * @property {number} increment Increment in the snowflake + * @property {string} binary Binary representation of the snowflake + */ + + /** + * Deconstructs a Discord snowflake. + * @param {Snowflake} snowflake Snowflake to deconstruct + * @returns {DeconstructedSnowflake} Deconstructed snowflake + */ + static deconstruct(snowflake) { + const BINARY = pad(Long.fromString(snowflake).toString(2), 64); + const res = { + timestamp: parseInt(BINARY.substring(0, 42), 2) + EPOCH, + workerID: parseInt(BINARY.substring(42, 47), 2), + processID: parseInt(BINARY.substring(47, 52), 2), + increment: parseInt(BINARY.substring(52, 64), 2), + binary: BINARY, + }; + Object.defineProperty(res, 'date', { + get: function get() { return new Date(this.timestamp); }, + enumerable: true, + }); + return res; + } +} + +function pad(v, n, c = '0') { + return String(v).length >= n ? String(v) : (String(c).repeat(n) + v).slice(-n); +} + +module.exports = SnowflakeUtil; + + +/***/ }), +/* 7 */ +/***/ (function(module, exports) { + +/** + * Represents a data model that is identifiable by a Snowflake (i.e. Discord API data models). + */ +class Base { + constructor(client) { + /** + * The client that instantiated this + * @name Base#client + * @type {Client} + * @readonly + */ + Object.defineProperty(this, 'client', { value: client }); + } + + _clone() { + return Object.assign(Object.create(this), this); + } + + _patch(data) { return data; } + + _update(data) { + const clone = this._clone(); + this._patch(data); + return clone; + } +} + +module.exports = Base; + + +/***/ }), +/* 8 */ +/***/ (function(module, exports, __webpack_require__) { + +const Collection = __webpack_require__(3); + +/** + * Manages the creation, retrieval and deletion of a specific data model. + * @extends {Collection} + */ +class DataStore extends Collection { + constructor(client, iterable, holds) { + super(); + Object.defineProperty(this, 'client', { value: client }); + Object.defineProperty(this, 'holds', { value: holds }); + if (iterable) for (const item of iterable) this.create(item); + } + + create(data, cache = true, { id, extras = [] } = {}) { + const existing = this.get(id || data.id); + if (existing) return existing; + + const entry = this.holds ? new this.holds(this.client, data, ...extras) : data; + if (cache) this.set(id || entry.id, entry); + return entry; + } + + remove(key) { return this.delete(key); } + + /** + * Resolves a data entry to a data Object. + * @param {string|Object} idOrInstance The id or instance of something in this datastore + * @returns {?Object} An instance from this datastore + */ + resolve(idOrInstance) { + if (idOrInstance instanceof this.holds) return idOrInstance; + if (typeof idOrInstance === 'string') return this.get(idOrInstance) || null; + return null; + } + + /** + * Resolves a data entry to a instance ID. + * @param {string|Instance} idOrInstance The id or instance of something in this datastore + * @returns {?string} + */ + resolveID(idOrInstance) { + if (idOrInstance instanceof this.holds) return idOrInstance.id; + if (typeof idOrInstance === 'string') return idOrInstance; + return null; + } +} + +module.exports = DataStore; + + +/***/ }), +/* 9 */ +/***/ (function(module, exports, __webpack_require__) { + +const { RangeError } = __webpack_require__(4); + +/** + * Data structure that makes it easy to interact with a permission bitfield. All {@link GuildMember}s have a set of + * permissions in their guild, and each channel in the guild may also have {@link PermissionOverwrites} for the member + * that override their default permissions. + */ +class Permissions { + /** + * @param {number|PermissionResolvable[]} permissions Permissions or bitfield to read from + */ + constructor(permissions) { + /** + * Bitfield of the packed permissions + * @type {number} + */ + this.bitfield = typeof permissions === 'number' ? permissions : this.constructor.resolve(permissions); + } + + /** + * Checks whether the bitfield has a permission, or multiple permissions. + * @param {PermissionResolvable|PermissionResolvable[]} permission Permission(s) to check for + * @param {boolean} [checkAdmin=true] Whether to allow the administrator permission to override + * @returns {boolean} + */ + has(permission, checkAdmin = true) { + if (permission instanceof Array) return permission.every(p => this.has(p, checkAdmin)); + permission = this.constructor.resolve(permission); + if (checkAdmin && (this.bitfield & this.constructor.FLAGS.ADMINISTRATOR) > 0) return true; + return (this.bitfield & permission) === permission; + } + + /** + * Gets all given permissions that are missing from the bitfield. + * @param {PermissionResolvable[]} permissions Permissions to check for + * @param {boolean} [checkAdmin=true] Whether to allow the administrator permission to override + * @returns {PermissionResolvable[]} + */ + missing(permissions, checkAdmin = true) { + return permissions.filter(p => !this.has(p, checkAdmin)); + } + + /** + * Freezes the permission making it immutable. + * @returns {Permissions} This permissions + */ + freeze() { + return Object.freeze(this); + } + + /** + * Adds permissions to this one. + * @param {...PermissionResolvable} permissions Permissions to add + * @returns {Permissions} This permissions or new permissions if the instance is frozen. + */ + add(...permissions) { + let total = 0; + for (let p = permissions.length - 1; p >= 0; p--) { + const perm = this.constructor.resolve(permissions[p]); + total |= perm; + } + if (Object.isFrozen(this)) return new this.constructor(this.bitfield | total); + this.bitfield |= total; + return this; + } + + /** + * Removes permissions from this one. + * @param {...PermissionResolvable} permissions Permissions to remove + * @returns {Permissions} This permissions or new permissions if the instance is frozen. + */ + remove(...permissions) { + let total = 0; + for (let p = permissions.length - 1; p >= 0; p--) { + const perm = this.constructor.resolve(permissions[p]); + total |= perm; + } + if (Object.isFrozen(this)) return new this.constructor(this.bitfield & ~total); + this.bitfield &= ~total; + return this; + } + + /** + * Gets an object mapping permission name (like `VIEW_CHANNEL`) to a {@link boolean} indicating whether the + * permission is available. + * @param {boolean} [checkAdmin=true] Whether to allow the administrator permission to override + * @returns {Object} + */ + serialize(checkAdmin = true) { + const serialized = {}; + for (const perm in this.constructor.FLAGS) serialized[perm] = this.has(perm, checkAdmin); + return serialized; + } + + /** + * Data that can be resolved to give a permission number. This can be: + * * A string (see {@link Permissions.FLAGS}) + * * A permission number + * * An instance of Permissions + * @typedef {string|number|Permissions} PermissionResolvable + */ + + /** + * Resolves permissions to their numeric form. + * @param {PermissionResolvable|PermissionResolvable[]} permission - Permission(s) to resolve + * @returns {number} + */ + static resolve(permission) { + if (typeof permission === 'number' && permission >= 0) return permission; + if (permission instanceof Permissions) return permission.bitfield; + if (permission instanceof Array) return permission.map(p => this.resolve(p)).reduce((prev, p) => prev | p, 0); + if (typeof permission === 'string') return this.FLAGS[permission]; + throw new RangeError('PERMISSIONS_INVALID'); + } +} + +/** + * Numeric permission flags. All available properties: + * * `ADMINISTRATOR` (implicitly has *all* permissions, and bypasses all channel overwrites) + * * `CREATE_INSTANT_INVITE` (create invitations to the guild) + * * `KICK_MEMBERS` + * * `BAN_MEMBERS` + * * `MANAGE_CHANNELS` (edit and reorder channels) + * * `MANAGE_GUILD` (edit the guild information, region, etc.) + * * `ADD_REACTIONS` (add new reactions to messages) + * * `VIEW_AUDIT_LOG` + * * `VIEW_CHANNEL` + * * `SEND_MESSAGES` + * * `SEND_TTS_MESSAGES` + * * `MANAGE_MESSAGES` (delete messages and reactions) + * * `EMBED_LINKS` (links posted will have a preview embedded) + * * `ATTACH_FILES` + * * `READ_MESSAGE_HISTORY` (view messages that were posted prior to opening Discord) + * * `MENTION_EVERYONE` + * * `USE_EXTERNAL_EMOJIS` (use emojis from different guilds) + * * `CONNECT` (connect to a voice channel) + * * `SPEAK` (speak in a voice channel) + * * `MUTE_MEMBERS` (mute members across all voice channels) + * * `DEAFEN_MEMBERS` (deafen members across all voice channels) + * * `MOVE_MEMBERS` (move members between voice channels) + * * `USE_VAD` (use voice activity detection) + * * `CHANGE_NICKNAME` + * * `MANAGE_NICKNAMES` (change other members' nicknames) + * * `MANAGE_ROLES` + * * `MANAGE_WEBHOOKS` + * * `MANAGE_EMOJIS` + * @type {Object} + * @see {@link https://discordapp.com/developers/docs/topics/permissions} + */ +Permissions.FLAGS = { + CREATE_INSTANT_INVITE: 1 << 0, + KICK_MEMBERS: 1 << 1, + BAN_MEMBERS: 1 << 2, + ADMINISTRATOR: 1 << 3, + MANAGE_CHANNELS: 1 << 4, + MANAGE_GUILD: 1 << 5, + ADD_REACTIONS: 1 << 6, + VIEW_AUDIT_LOG: 1 << 7, + + VIEW_CHANNEL: 1 << 10, + SEND_MESSAGES: 1 << 11, + SEND_TTS_MESSAGES: 1 << 12, + MANAGE_MESSAGES: 1 << 13, + EMBED_LINKS: 1 << 14, + ATTACH_FILES: 1 << 15, + READ_MESSAGE_HISTORY: 1 << 16, + MENTION_EVERYONE: 1 << 17, + USE_EXTERNAL_EMOJIS: 1 << 18, + + CONNECT: 1 << 20, + SPEAK: 1 << 21, + MUTE_MEMBERS: 1 << 22, + DEAFEN_MEMBERS: 1 << 23, + MOVE_MEMBERS: 1 << 24, + USE_VAD: 1 << 25, + + CHANGE_NICKNAME: 1 << 26, + MANAGE_NICKNAMES: 1 << 27, + MANAGE_ROLES: 1 << 28, + MANAGE_WEBHOOKS: 1 << 29, + MANAGE_EMOJIS: 1 << 30, +}; + +/** + * Bitfield representing every permission combined + * @type {number} + */ +Permissions.ALL = Object.values(Permissions.FLAGS).reduce((all, p) => all | p, 0); + +/** + * Bitfield representing the default permissions for users + * @type {number} + */ +Permissions.DEFAULT = 104324097; + +module.exports = Permissions; + + +/***/ }), +/* 10 */ +/***/ (function(module, exports, __webpack_require__) { + +/* WEBPACK VAR INJECTION */(function(Buffer) {const path = __webpack_require__(33); +const fs = __webpack_require__(49); +const snekfetch = __webpack_require__(29); +const Util = __webpack_require__(5); +const { Error, TypeError } = __webpack_require__(4); + +/** + * The DataResolver identifies different objects and tries to resolve a specific piece of information from them. + * @private + */ +class DataResolver { + constructor() { + throw new Error(`The ${this.constructor.name} class may not be instantiated.`); + } + + /** + * Data that can be resolved to give an invite code. This can be: + * * An invite code + * * An invite URL + * @typedef {string} InviteResolvable + */ + + /** + * Resolves InviteResolvable to an invite code. + * @param {InviteResolvable} data The invite resolvable to resolve + * @returns {string} + */ + static resolveInviteCode(data) { + const inviteRegex = /discord(?:app\.com\/invite|\.gg)\/([\w-]{2,255})/i; + const match = inviteRegex.exec(data); + if (match && match[1]) return match[1]; + return data; + } + + /** + * Resolves a Base64Resolvable, a string, or a BufferResolvable to a Base 64 image. + * @param {BufferResolvable|Base64Resolvable} image The image to be resolved + * @param {boolean} browser Whether this should resolve for a browser + * @returns {Promise} + */ + static async resolveImage(image, browser) { + if (!image) return null; + if (typeof image === 'string' && image.startsWith('data:')) { + return image; + } + const file = await this.resolveFile(image, browser); + return DataResolver.resolveBase64(file); + } + + /** + * Data that resolves to give a Base64 string, typically for image uploading. This can be: + * * A Buffer + * * A base64 string + * @typedef {Buffer|string} Base64Resolvable + */ + + /** + * Resolves a Base64Resolvable to a Base 64 image. + * @param {Base64Resolvable} data The base 64 resolvable you want to resolve + * @returns {?string} + */ + static resolveBase64(data) { + if (data instanceof Buffer) return `data:image/jpg;base64,${data.toString('base64')}`; + return data; + } + + /** + * Data that can be resolved to give a Buffer. This can be: + * * A Buffer + * * The path to a local file + * * A URL + * @typedef {string|Buffer} BufferResolvable + */ + + /** + * @external Stream + * @see {@link https://nodejs.org/api/stream.html} + */ + + /** + * Resolves a BufferResolvable to a Buffer. + * @param {BufferResolvable|Stream} resource The buffer or stream resolvable to resolve + * @param {boolean} browser Whether this should resolve for a browser + * @returns {Promise} + */ + static resolveFile(resource, browser) { + if (resource instanceof Buffer) return Promise.resolve(resource); + if (browser && resource instanceof ArrayBuffer) return Promise.resolve(Util.convertToBuffer(resource)); + + if (typeof resource === 'string') { + return new Promise((resolve, reject) => { + if (/^https?:\/\//.test(resource)) { + snekfetch.get(resource) + .end((err, res) => { + if (err) return reject(err); + if (!(res.body instanceof Buffer)) return reject(new TypeError('REQ_BODY_TYPE')); + return resolve(res.body); + }); + } else { + const file = path.resolve(resource); + fs.stat(file, (err, stats) => { + if (err) return reject(err); + if (!stats || !stats.isFile()) return reject(new Error('FILE_NOT_FOUND', file)); + fs.readFile(file, (err2, data) => { + if (err2) reject(err2); else resolve(data); + }); + return null; + }); + } + }); + } else if (resource.pipe && typeof resource.pipe === 'function') { + return new Promise((resolve, reject) => { + const buffers = []; + resource.once('error', reject); + resource.on('data', data => buffers.push(data)); + resource.once('end', () => resolve(Buffer.concat(buffers))); + }); + } + + return Promise.reject(new TypeError('REQ_RESOURCE_TYPE')); + } +} + +module.exports = DataResolver; + +/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(17).Buffer)) + +/***/ }), +/* 11 */ +/***/ (function(module, exports, __webpack_require__) { + +const Snowflake = __webpack_require__(6); +const Base = __webpack_require__(7); +const { ChannelTypes } = __webpack_require__(0); + +/** + * Represents any channel on Discord. + * @extends {Base} + */ +class Channel extends Base { + constructor(client, data) { + super(client); + + const type = Object.keys(ChannelTypes)[data.type]; + /** + * The type of the channel, either: + * * `dm` - a DM channel + * * `group` - a Group DM channel + * * `text` - a guild text channel + * * `voice` - a guild voice channel + * * `category` - a guild category channel + * * `unknown` - a generic channel of unknown type, could be Channel or GuildChannel + * @type {string} + */ + this.type = type ? type.toLowerCase() : 'unknown'; + + if (data) this._patch(data); + } + + _patch(data) { + /** + * The unique ID of the channel + * @type {Snowflake} + */ + this.id = data.id; + } + + /** + * The timestamp the channel was created at + * @type {number} + * @readonly + */ + get createdTimestamp() { + return Snowflake.deconstruct(this.id).timestamp; + } + + /** + * The time the channel was created + * @type {Date} + * @readonly + */ + get createdAt() { + return new Date(this.createdTimestamp); + } + + /** + * Deletes this channel. + * @returns {Promise} + * @example + * // Delete the channel + * channel.delete() + * .then() // Success + * .catch(console.error); // Log error + */ + delete() { + return this.client.api.channels(this.id).delete().then(() => this); + } + + static create(client, data, guild) { + const DMChannel = __webpack_require__(46); + const GroupDMChannel = __webpack_require__(51); + const TextChannel = __webpack_require__(52); + const VoiceChannel = __webpack_require__(54); + const CategoryChannel = __webpack_require__(93); + const GuildChannel = __webpack_require__(15); + let channel; + if (data.type === ChannelTypes.DM) { + channel = new DMChannel(client, data); + } else if (data.type === ChannelTypes.GROUP) { + channel = new GroupDMChannel(client, data); + } else { + guild = guild || client.guilds.get(data.guild_id); + if (guild) { + switch (data.type) { + case ChannelTypes.TEXT: + channel = new TextChannel(guild, data); + break; + case ChannelTypes.VOICE: + channel = new VoiceChannel(guild, data); + break; + case ChannelTypes.CATEGORY: + channel = new CategoryChannel(guild, data); + break; + default: + channel = new GuildChannel(guild, data); + } + guild.channels.set(channel.id, channel); + } + } + return channel; + } +} + +module.exports = Channel; + + +/***/ }), +/* 12 */ +/***/ (function(module, exports, __webpack_require__) { + +const TextBasedChannel = __webpack_require__(19); +const Role = __webpack_require__(24); +const Permissions = __webpack_require__(9); +const Collection = __webpack_require__(3); +const Base = __webpack_require__(7); +const { Presence } = __webpack_require__(13); +const { Error, TypeError } = __webpack_require__(4); + +/** + * Represents a member of a guild on Discord. + * @implements {TextBasedChannel} + * @extends {Base} + */ +class GuildMember extends Base { + constructor(client, data, guild) { + super(client); + + /** + * The guild that this member is part of + * @type {Guild} + */ + this.guild = guild; + + /** + * The user that this guild member instance Represents + * @type {User} + */ + this.user = {}; + + this._roles = []; + + if (data) this._patch(data); + + /** + * The ID of the last message sent by the member in their guild, if one was sent + * @type {?Snowflake} + */ + this.lastMessageID = null; + + /** + * The Message object of the last message sent by the member in their guild, if one was sent + * @type {?Message} + */ + this.lastMessage = null; + } + + _patch(data) { + /** + * Whether this member is speaking + * @type {boolean} + * @name GuildMember#speaking + */ + if (typeof this.speaking === 'undefined') this.speaking = false; + + /** + * The nickname of this guild member, if they have one + * @type {?string} + * @name GuildMember#nickname + */ + if (typeof data.nick !== 'undefined') this.nickname = data.nick; + + /** + * The timestamp the member joined the guild at + * @type {number} + * @name GuildMember#joinedTimestamp + */ + if (typeof data.joined_at !== 'undefined') this.joinedTimestamp = new Date(data.joined_at).getTime(); + + this.user = this.guild.client.users.create(data.user); + if (data.roles) this._roles = data.roles; + } + + get voiceState() { + return this._frozenVoiceState || this.guild.voiceStates.get(this.id) || {}; + } + + /** + * Whether this member is deafened server-wide + * @type {boolean} + */ + get serverDeaf() { return this.voiceState.deaf; } + + /** + * Whether this member is muted server-wide + * @type {boolean} + */ + get serverMute() { return this.voiceState.mute; } + + /** + * Whether this member is self-muted + * @type {boolean} + */ + get selfMute() { return this.voiceState.self_mute; } + + /** + * Whether this member is self-deafened + * @type {boolean} + */ + get selfDeaf() { return this.voiceState.self_deaf; } + + /** + * The voice session ID of this member (if any) + * @type {?Snowflake} + */ + get voiceSessionID() { return this.voiceState.session_id; } + + /** + * The voice channel ID of this member, (if any) + * @type {?Snowflake} + */ + get voiceChannelID() { return this.voiceState.channel_id; } + + /** + * The time the member joined the guild + * @type {Date} + * @readonly + */ + get joinedAt() { + return new Date(this.joinedTimestamp); + } + + /** + * The presence of this guild member + * @type {Presence} + * @readonly + */ + get presence() { + return this.frozenPresence || this.guild.presences.get(this.id) || new Presence(); + } + + /** + * A list of roles that are applied to this GuildMember, mapped by the role ID + * @type {Collection} + * @readonly + */ + get roles() { + const list = new Collection(); + const everyoneRole = this.guild.roles.get(this.guild.id); + + if (everyoneRole) list.set(everyoneRole.id, everyoneRole); + + for (const roleID of this._roles) { + const role = this.guild.roles.get(roleID); + if (role) list.set(role.id, role); + } + + return list; + } + + /** + * The role of the member with the highest position + * @type {Role} + * @readonly + */ + get highestRole() { + return this.roles.reduce((prev, role) => !prev || role.comparePositionTo(prev) > 0 ? role : prev); + } + + /** + * The role of the member used to set their color + * @type {?Role} + * @readonly + */ + get colorRole() { + const coloredRoles = this.roles.filter(role => role.color); + if (!coloredRoles.size) return null; + return coloredRoles.reduce((prev, role) => !prev || role.comparePositionTo(prev) > 0 ? role : prev); + } + + /** + * The displayed color of the member in base 10 + * @type {number} + * @readonly + */ + get displayColor() { + const role = this.colorRole; + return (role && role.color) || 0; + } + + /** + * The displayed color of the member in hexadecimal + * @type {string} + * @readonly + */ + get displayHexColor() { + const role = this.colorRole; + return (role && role.hexColor) || '#000000'; + } + + /** + * The role of the member used to hoist them in a separate category in the users list + * @type {?Role} + * @readonly + */ + get hoistRole() { + const hoistedRoles = this.roles.filter(role => role.hoist); + if (!hoistedRoles.size) return null; + return hoistedRoles.reduce((prev, role) => !prev || role.comparePositionTo(prev) > 0 ? role : prev); + } + + /** + * Whether this member is muted in any way + * @type {boolean} + * @readonly + */ + get mute() { + return this.selfMute || this.serverMute; + } + + /** + * Whether this member is deafened in any way + * @type {boolean} + * @readonly + */ + get deaf() { + return this.selfDeaf || this.serverDeaf; + } + + /** + * The voice channel this member is in, if any + * @type {?VoiceChannel} + * @readonly + */ + get voiceChannel() { + return this.guild.channels.get(this.voiceChannelID); + } + + /** + * The ID of this user + * @type {Snowflake} + * @readonly + */ + get id() { + return this.user.id; + } + + /** + * The nickname of the member, or their username if they don't have one + * @type {string} + * @readonly + */ + get displayName() { + return this.nickname || this.user.username; + } + + /** + * The overall set of permissions for the guild member, taking only roles into account + * @type {Permissions} + * @readonly + */ + get permissions() { + if (this.user.id === this.guild.ownerID) return new Permissions(Permissions.ALL).freeze(); + return new Permissions(this.roles.map(role => role.permissions)).freeze(); + } + + /** + * Whether the member is kickable by the client user + * @type {boolean} + * @readonly + */ + get kickable() { + if (this.user.id === this.guild.ownerID) return false; + if (this.user.id === this.client.user.id) return false; + const clientMember = this.guild.member(this.client.user); + if (!clientMember.permissions.has(Permissions.FLAGS.KICK_MEMBERS)) return false; + return clientMember.highestRole.comparePositionTo(this.highestRole) > 0; + } + + /** + * Whether the member is bannable by the client user + * @type {boolean} + * @readonly + */ + get bannable() { + if (this.user.id === this.guild.ownerID) return false; + if (this.user.id === this.client.user.id) return false; + const clientMember = this.guild.member(this.client.user); + if (!clientMember.permissions.has(Permissions.FLAGS.BAN_MEMBERS)) return false; + return clientMember.highestRole.comparePositionTo(this.highestRole) > 0; + } + + /** + * Returns `channel.permissionsFor(guildMember)`. Returns permissions for a member in a guild channel, + * taking into account roles and permission overwrites. + * @param {ChannelResolvable} channel The guild channel to use as context + * @returns {?Permissions} + */ + permissionsIn(channel) { + channel = this.client.channels.resolve(channel); + if (!channel || !channel.guild) throw new Error('GUILD_CHANNEL_RESOLVE'); + return channel.permissionsFor(this); + } + + /** + * Checks if any of the member's roles have a permission. + * @param {PermissionResolvable|PermissionResolvable[]} permission Permission(s) to check for + * @param {boolean} [explicit=false] Whether to require the role to explicitly have the exact permission + * **(deprecated)** + * @param {boolean} [checkAdmin] Whether to allow the administrator permission to override + * (takes priority over `explicit`) + * @param {boolean} [checkOwner] Whether to allow being the guild's owner to override + * (takes priority over `explicit`) + * @returns {boolean} + */ + hasPermission(permission, explicit = false, checkAdmin, checkOwner) { + if (typeof checkAdmin === 'undefined') checkAdmin = !explicit; + if (typeof checkOwner === 'undefined') checkOwner = !explicit; + if (checkOwner && this.user.id === this.guild.ownerID) return true; + return this.roles.some(r => r.permissions.has(permission, undefined, checkAdmin)); + } + + /** + * Checks whether the roles of the member allows them to perform specific actions, and lists any missing permissions. + * @param {PermissionResolvable[]} permissions The permissions to check for + * @param {boolean} [explicit=false] Whether to require the member to explicitly have the exact permissions + * @returns {PermissionResolvable[]} + */ + missingPermissions(permissions, explicit = false) { + return this.permissions.missing(permissions, explicit); + } + + /** + * The data for editing a guild member. + * @typedef {Object} GuildMemberEditData + * @property {string} [nick] The nickname to set for the member + * @property {Collection|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 {ChannelResolvable} [channel] Channel to move member to (if they are connected to voice) + */ + + /** + * Edit a guild member. + * @param {GuildMemberEditData} data The data to edit the member with + * @param {string} [reason] Reason for editing this user + * @returns {Promise} + */ + edit(data, reason) { + if (data.channel) { + data.channel_id = this.client.channels.resolve(data.channel).id; + data.channel = null; + } + if (data.roles) data.roles = data.roles.map(role => role instanceof Role ? role.id : role); + let endpoint = this.client.api.guilds(this.guild.id); + if (this.user.id === this.client.user.id) { + const keys = Object.keys(data); + if (keys.length === 1 && keys[0] === 'nick') endpoint = endpoint.members('@me').nick; + else endpoint = endpoint.members(this.id); + } else { + endpoint = endpoint.members(this.id); + } + return endpoint.patch({ data, reason }).then(() => { + const clone = this._clone(); + data.user = this.user; + clone._patch(data); + clone._frozenVoiceState = this.voiceState; + if (typeof data.mute !== 'undefined') clone._frozenVoiceState.mute = data.mute; + if (typeof data.deaf !== 'undefined') clone._frozenVoiceState.mute = data.deaf; + if (typeof data.channel_id !== 'undefined') clone._frozenVoiceState.channel_id = data.channel_id; + return clone; + }); + } + + /** + * Mute/unmute a user. + * @param {boolean} mute Whether or not the member should be muted + * @param {string} [reason] Reason for muting or unmuting + * @returns {Promise} + */ + setMute(mute, reason) { + return this.edit({ mute }, reason); + } + + /** + * Deafen/undeafen a user. + * @param {boolean} deaf Whether or not the member should be deafened + * @param {string} [reason] Reason for deafening or undeafening + * @returns {Promise} + */ + setDeaf(deaf, reason) { + return this.edit({ deaf }, reason); + } + + /** + * Moves the guild member to the given channel. + * @param {ChannelResolvable} channel The channel to move the member to + * @returns {Promise} + */ + setVoiceChannel(channel) { + return this.edit({ channel }); + } + + /** + * Sets the roles applied to the member. + * @param {Collection|RoleResolvable[]} roles The roles or role IDs to apply + * @param {string} [reason] Reason for applying the roles + * @returns {Promise} + */ + setRoles(roles, reason) { + return this.edit({ roles }, reason); + } + + /** + * Adds a single role to the member. + * @param {RoleResolvable} role The role or ID of the role to add + * @param {string} [reason] Reason for adding the role + * @returns {Promise} + */ + addRole(role, reason) { + role = this.guild.roles.resolve(role); + if (!role) return Promise.reject(new TypeError('INVALID_TYPE', 'role', 'Role nor a Snowflake')); + if (this._roles.includes(role.id)) return Promise.resolve(this); + return this.client.api.guilds(this.guild.id).members(this.user.id).roles(role.id) + .put({ reason }) + .then(() => { + const clone = this._clone(); + if (!clone._roles.includes(role.id)) clone._roles.push(role.id); + return clone; + }); + } + + /** + * Adds multiple roles to the member. + * @param {Collection|RoleResolvable[]} roles The roles or role IDs to add + * @param {string} [reason] Reason for adding the roles + * @returns {Promise} + */ + addRoles(roles, reason) { + let allRoles = this._roles.slice(); + for (let role of roles instanceof Collection ? roles.values() : roles) { + role = this.guild.roles.resolve(role); + if (!role) { + return Promise.reject(new TypeError('INVALID_TYPE', 'roles', + 'Array or Collection of Roles or Snowflakes', true)); + } + allRoles.push(role.id); + } + return this.edit({ roles: allRoles }, reason); + } + + /** + * Removes a single role from the member. + * @param {RoleResolvable} role The role or ID of the role to remove + * @param {string} [reason] Reason for removing the role + * @returns {Promise} + */ + removeRole(role, reason) { + role = this.guild.roles.resolve(role); + if (!role) return Promise.reject(new TypeError('INVALID_TYPE', 'role', 'Role nor a Snowflake')); + if (!this._roles.includes(role.id)) return Promise.resolve(this); + return this.client.api.guilds(this.guild.id).members(this.user.id).roles(role.id) + .delete({ reason }) + .then(() => { + const clone = this._clone(); + const index = clone._roles.indexOf(role.id); + if (~index) clone._roles.splice(index, 1); + return clone; + }); + } + + /** + * Removes multiple roles from the member. + * @param {Collection|RoleResolvable[]} roles The roles or role IDs to remove + * @param {string} [reason] Reason for removing the roles + * @returns {Promise} + */ + removeRoles(roles, reason) { + const allRoles = this._roles.slice(); + for (let role of roles instanceof Collection ? roles.values() : roles) { + role = this.guild.roles.resolve(role); + if (!role) { + return Promise.reject(new TypeError('INVALID_TYPE', 'roles', + 'Array or Collection of Roles or Snowflakes', true)); + } + const index = allRoles.indexOf(role.id); + if (index >= 0) allRoles.splice(index, 1); + } + return this.edit({ roles: allRoles }, reason); + } + + /** + * Set the nickname for the guild member. + * @param {string} nick The nickname for the guild member + * @param {string} [reason] Reason for setting the nickname + * @returns {Promise} + */ + setNickname(nick, reason) { + return this.edit({ nick }, reason); + } + + /** + * Creates a DM channel between the client and the member. + * @returns {Promise} + */ + createDM() { + return this.user.createDM(); + } + + /** + * Deletes any DMs with this guild member. + * @returns {Promise} + */ + deleteDM() { + return this.user.deleteDM(); + } + + /** + * Kick this member from the guild. + * @param {string} [reason] Reason for kicking user + * @returns {Promise} + */ + kick(reason) { + return this.client.api.guilds(this.guild.id).members(this.user.id).delete({ reason }) + .then(() => + this.client.actions.GuildMemberRemove.handle({ + guild_id: this.guild.id, + user: this.user, + }).member + ); + } + + /** + * Ban this guild member. + * @param {Object|number|string} [options] Ban options. If a number, the number of days to delete messages for, if a + * string, the ban reason. Supplying an object allows you to do both. + * @param {number} [options.days=0] Number of days of messages to delete + * @param {string} [options.reason] Reason for banning + * @returns {Promise} + * @example + * // ban a guild member + * guildMember.ban(7); + */ + ban(options) { + return this.guild.ban(this, options); + } + + /** + * When concatenated with a string, this automatically concatenates the user's mention instead of the Member object. + * @returns {string} + * @example + * // Logs: Hello from <@123456789>! + * console.log(`Hello from ${member}!`); + */ + toString() { + return `<@${this.nickname ? '!' : ''}${this.user.id}>`; + } + + // These are here only for documentation purposes - they are implemented by TextBasedChannel + /* eslint-disable no-empty-function */ + send() {} +} + +TextBasedChannel.applyToClass(GuildMember); + +module.exports = GuildMember; + + +/***/ }), +/* 13 */ +/***/ (function(module, exports, __webpack_require__) { + +const { ActivityTypes } = __webpack_require__(0); + +/** + * Represents a user's presence. + */ +class Presence { + constructor(client, data = {}) { + Object.defineProperty(this, 'client', { value: client }); + this.patch(data); + } + + patch(data) { + /** + * The status of the presence: + * + * * **`online`** - user is online + * * **`offline`** - user is offline or invisible + * * **`idle`** - user is AFK + * * **`dnd`** - user is in Do Not Disturb + * @type {string} + */ + this.status = data.status || this.status; + + const activity = data.game || data.activity; + /** + * The activity of the presence + * @type {?Activity} + */ + this.activity = activity ? new Activity(this, activity) : null; + + return this; + } + + _clone() { + const clone = Object.assign(Object.create(this), this); + if (this.activity) clone.activity = this.activity._clone(); + return clone; + } + + /** + * Whether this presence is equal to another + * @param {Presence} presence The presence to compare with + * @returns {boolean} + */ + equals(presence) { + return this === presence || ( + presence && + this.status === presence.status && + this.activity ? this.activity.equals(presence.activity) : !presence.activity + ); + } +} + +/** + * Represents an activity that is part of a user's presence. + */ +class Activity { + constructor(presence, data) { + Object.defineProperty(this, 'presence', { value: presence }); + + /** + * The name of the activity being played + * @type {string} + */ + this.name = data.name; + + /** + * The type of the activity status + * @type {ActivityType} + */ + this.type = ActivityTypes[data.type]; + + /** + * If the activity is being streamed, a link to the stream + * @type {?string} + */ + this.url = data.url || null; + + /** + * Details about the activity + * @type {?string} + */ + this.details = data.details || null; + + /** + * State of the activity + * @type {?string} + */ + this.state = data.state || null; + + /** + * Application ID associated with this activity + * @type {?Snowflake} + */ + this.applicationID = data.application_id || null; + + /** + * Timestamps for the activity + * @type {?Object} + * @prop {?Date} start When the activity started + * @prop {?Date} end When the activity will end + */ + this.timestamps = data.timestamps ? { + start: data.timestamps.start ? new Date(data.timestamps.start) : null, + end: data.timestamps.end ? new Date(data.timestamps.end) : null, + } : null; + + /** + * Party of the activity + * @type {?Object} + * @prop {?string} id ID of the party + * @prop {number[]} size Size of the party as `[current, max]` + */ + this.party = data.party || null; + + /** + * Assets for rich presence + * @type {?RichPresenceAssets} + */ + this.assets = data.assets ? new RichPresenceAssets(this, data.assets) : null; + } + + /** + * Whether this activity is equal to another activity. + * @param {Activity} activity The activity to compare with + * @returns {boolean} + */ + equals(activity) { + return this === activity || ( + activity && + this.name === activity.name && + this.type === activity.type && + this.url === activity.url + ); + } + + _clone() { + return Object.assign(Object.create(this), this); + } +} + +/** + * Assets for a rich presence + */ +class RichPresenceAssets { + constructor(activity, assets) { + Object.defineProperty(this, 'activity', { value: activity }); + + /** + * Hover text for large image + * @type {?string} + */ + this.largeText = assets.large_text || null; + + /** + * Hover text for small image + * @type {?string} + */ + this.smallText = assets.small_text || null; + + /** + * ID of large image asset + * @type {?string} + */ + this.largeImage = assets.large_image || null; + + /** + * ID of small image asset + * @type {?string} + */ + this.smallImage = assets.small_image || null; + } + + /** + * @param {string} format Format of the image + * @param {number} size Size of the iamge + * @returns {?string} small image url + */ + smallImageURL({ format, size } = {}) { + if (!this.smallImage) return null; + return this.activity.presence.client.rest.cdn + .AppAsset(this.activity.applicationID, this.smallImage, { format, size }); + } + + /** + * @param {string} format Format of the image + * @param {number} size Size of the iamge + * @returns {?string} large image url + */ + largeImageURL({ format, size } = {}) { + if (!this.largeImage) return null; + return this.activity.presence.client.rest.cdn + .AppAsset(this.activity.applicationID, this.largeImage, { format, size }); + } +} + +exports.Presence = Presence; +exports.Activity = Activity; +exports.RichPresenceAssets = RichPresenceAssets; + + +/***/ }), +/* 14 */ +/***/ (function(module, exports, __webpack_require__) { + +const MessageAttachment = __webpack_require__(20); +const Util = __webpack_require__(5); +const { RangeError } = __webpack_require__(4); + +/** + * Represents an embed in a message (image/video preview, rich embed, etc.) + */ +class MessageEmbed { + constructor(data = {}) { + this.setup(data); + } + + setup(data) { // eslint-disable-line complexity + /** + * The type of this embed + * @type {string} + */ + this.type = data.type; + + /** + * The title of this embed + * @type {?string} + */ + this.title = data.title; + + /** + * The description of this embed + * @type {?string} + */ + this.description = data.description; + + /** + * The URL of this embed + * @type {?string} + */ + this.url = data.url; + + /** + * The color of the embed + * @type {?number} + */ + this.color = data.color; + + /** + * The timestamp of this embed + * @type {?number} + */ + this.timestamp = data.timestamp ? new Date(data.timestamp).getTime() : null; + + /** + * The fields of this embed + * @type {Object[]} + * @property {string} name The name of this field + * @property {string} value The value of this field + * @property {boolean} inline If this field will be displayed inline + */ + this.fields = data.fields ? data.fields.map(Util.cloneObject) : []; + + /** + * The thumbnail of this embed (if there is one) + * @type {?Object} + * @property {string} url URL for this thumbnail + * @property {string} proxyURL ProxyURL for this thumbnail + * @property {number} height Height of this thumbnail + * @property {number} width Width of this thumbnail + */ + this.thumbnail = data.thumbnail ? { + url: data.thumbnail.url, + proxyURL: data.thumbnail.proxy_url, + height: data.height, + width: data.width, + } : null; + + /** + * The image of this embed, if there is one + * @type {?Object} + * @property {string} url URL for this image + * @property {string} proxyURL ProxyURL for this image + * @property {number} height Height of this image + * @property {number} width Width of this image + */ + this.image = data.image ? { + url: data.image.url, + proxyURL: data.image.proxy_url, + height: data.height, + width: data.width, + } : null; + + /** + * The video of this embed (if there is one) + * @type {?Object} + * @property {string} url URL of this video + * @property {number} height Height of this video + * @property {number} width Width of this video + * @readonly + */ + this.video = data.video; + + /** + * The author of this embed (if there is one) + * @type {?Object} + * @property {string} name The name of this author + * @property {string} url URL of this author + * @property {string} iconURL URL of the icon for this author + * @property {string} proxyIconURL Proxied URL of the icon for this author + */ + this.author = data.author ? { + name: data.author.name, + url: data.author.url, + iconURL: data.author.iconURL || data.author.icon_url, + proxyIconURL: data.author.proxyIconUrl || data.author.proxy_icon_url, + } : null; + + /** + * The provider of this embed (if there is one) + * @type {?Object} + * @property {string} name The name of this provider + * @property {string} url URL of this provider + */ + this.provider = data.provider; + + /** + * The footer of this embed + * @type {?Object} + * @property {string} text The text of this footer + * @property {string} iconURL URL of the icon for this footer + * @property {string} proxyIconURL Proxied URL of the icon for this footer + */ + this.footer = data.footer ? { + text: data.footer.text, + iconURL: data.footer.iconURL || data.footer.icon_url, + proxyIconURL: data.footer.proxyIconURL || data.footer.proxy_icon_url, + } : null; + + /** + * The files of this embed + * @type {?Object} + * @property {Array} files Files to attach + */ + if (data.files) { + this.files = data.files.map(file => { + if (file instanceof MessageAttachment) { + return typeof file.file === 'string' ? file.file : Util.cloneObject(file.file); + } + return file; + }); + } + } + + /** + * The date this embed was created + * @type {?Date} + * @readonly + */ + get createdAt() { + return this.timestamp ? new Date(this.timestamp) : null; + } + + /** + * The hexadecimal version of the embed color, with a leading hash + * @type {string} + * @readonly + */ + get hexColor() { + return this.color ? `#${this.color.toString(16).padStart(6, '0')}` : null; + } + + /** + * Adds a field to the embed (max 25). + * @param {StringResolvable} name The name of the field + * @param {StringResolvable} value The value of the field + * @param {boolean} [inline=false] Set the field to display inline + * @returns {MessageEmbed} + */ + addField(name, value, inline = false) { + if (this.fields.length >= 25) throw new RangeError('EMBED_FIELD_COUNT'); + name = Util.resolveString(name); + if (!String(name) || name.length > 256) throw new RangeError('EMBED_FIELD_NAME'); + value = Util.resolveString(value); + if (!String(value) || value.length > 1024) throw new RangeError('EMBED_FIELD_VALUE'); + this.fields.push({ name, value, inline }); + return this; + } + + /** + * Convenience function for `.addField('\u200B', '\u200B', inline)`. + * @param {boolean} [inline=false] Set the field to display inline + * @returns {MessageEmbed} + */ + addBlankField(inline = false) { + return this.addField('\u200B', '\u200B', inline); + } + + /** + * Sets the file to upload alongside the embed. This file can be accessed via `attachment://fileName.extension` when + * setting an embed image or author/footer icons. Only one file may be attached. + * @param {Array} files Files to attach + * @returns {MessageEmbed} + */ + attachFiles(files) { + if (this.files) this.files = this.files.concat(files); + else this.files = files; + for (let file of files) { + if (file instanceof MessageAttachment) file = file.file; + } + return this; + } + + /** + * Sets the author of this embed. + * @param {StringResolvable} name The name of the author + * @param {string} [iconURL] The icon URL of the author + * @param {string} [url] The URL of the author + * @returns {MessageEmbed} + */ + setAuthor(name, iconURL, url) { + this.author = { name: Util.resolveString(name), iconURL, url }; + return this; + } + + /** + * Sets the color of this embed. + * @param {ColorResolvable} color The color of the embed + * @returns {MessageEmbed} + */ + setColor(color) { + this.color = Util.resolveColor(color); + return this; + } + + /** + * Sets the description of this embed. + * @param {StringResolvable} description The description + * @returns {MessageEmbed} + */ + setDescription(description) { + description = Util.resolveString(description); + if (description.length > 2048) throw new RangeError('EMBED_DESCRIPTION'); + this.description = description; + return this; + } + + /** + * Sets the footer of this embed. + * @param {StringResolvable} text The text of the footer + * @param {string} [iconURL] The icon URL of the footer + * @returns {MessageEmbed} + */ + setFooter(text, iconURL) { + text = Util.resolveString(text); + if (text.length > 2048) throw new RangeError('EMBED_FOOTER_TEXT'); + this.footer = { text, iconURL }; + return this; + } + + /** + * Set the image of this embed. + * @param {string} url The URL of the image + * @returns {MessageEmbed} + */ + setImage(url) { + this.image = { url }; + return this; + } + + /** + * Set the thumbnail of this embed. + * @param {string} url The URL of the thumbnail + * @returns {MessageEmbed} + */ + setThumbnail(url) { + this.thumbnail = { url }; + return this; + } + + /** + * Sets the timestamp of this embed. + * @param {Date} [timestamp=current date] The timestamp + * @returns {MessageEmbed} + */ + setTimestamp(timestamp = new Date()) { + this.timestamp = timestamp.getTime(); + return this; + } + + /** + * Sets the title of this embed. + * @param {StringResolvable} title The title + * @returns {MessageEmbed} + */ + setTitle(title) { + title = Util.resolveString(title); + if (title.length > 256) throw new RangeError('EMBED_TITLE'); + this.title = title; + return this; + } + + /** + * Sets the URL of this embed. + * @param {string} url The URL + * @returns {MessageEmbed} + */ + setURL(url) { + this.url = url; + return this; + } + + /** + * Transforms the embed object to be processed. + * @returns {Object} The raw data of this embed + * @private + */ + _apiTransform() { + return { + title: this.title, + type: 'rich', + description: this.description, + url: this.url, + timestamp: this.timestamp ? new Date(this.timestamp) : null, + color: this.color, + fields: this.fields, + files: this.files, + thumbnail: this.thumbnail, + image: this.image, + author: this.author ? { + name: this.author.name, + url: this.author.url, + icon_url: this.author.iconURL, + } : null, + footer: this.footer ? { + text: this.footer.text, + icon_url: this.footer.iconURL, + } : null, + }; + } +} + +module.exports = MessageEmbed; + + +/***/ }), +/* 15 */ +/***/ (function(module, exports, __webpack_require__) { + +const Channel = __webpack_require__(11); +const Role = __webpack_require__(24); +const Invite = __webpack_require__(25); +const PermissionOverwrites = __webpack_require__(53); +const Util = __webpack_require__(5); +const Permissions = __webpack_require__(9); +const Collection = __webpack_require__(3); +const { MessageNotificationTypes } = __webpack_require__(0); +const { Error, TypeError } = __webpack_require__(4); + +/** + * Represents a guild channel (e.g. text channels and voice channels). + * @extends {Channel} + */ +class GuildChannel extends Channel { + constructor(guild, data) { + super(guild.client, data); + + /** + * The guild the channel is in + * @type {Guild} + */ + this.guild = guild; + } + + _patch(data) { + super._patch(data); + + /** + * The name of the guild channel + * @type {string} + */ + this.name = data.name; + + /** + * The raw position of the channel from discord + * @type {number} + */ + this.rawPosition = data.position; + + /** + * The ID of the category parent of this channel + * @type {?Snowflake} + */ + this.parentID = data.parent_id; + + /** + * A map of permission overwrites in this channel for roles and users + * @type {Collection} + */ + this.permissionOverwrites = new Collection(); + if (data.permission_overwrites) { + for (const overwrite of data.permission_overwrites) { + this.permissionOverwrites.set(overwrite.id, new PermissionOverwrites(this, overwrite)); + } + } + } + + /** + * The category parent of this channel + * @type {?CategoryChannel} + * @readonly + */ + get parent() { + return this.guild.channels.get(this.parentID); + } + + /** + * If the permissionOverwrites match the parent channel, null if no parent + * @type {?boolean} + * @readonly + */ + get permissionsLocked() { + if (!this.parent) return null; + if (this.permissionOverwrites.size !== this.parent.permissionOverwrites.size) return false; + return !this.permissionOverwrites.find((value, key) => { + const testVal = this.parent.permissionOverwrites.get(key); + return testVal === undefined || + testVal.denied.bitfield !== value.denied.bitfield || + testVal.allowed.bitfield !== value.allowed.bitfield; + }); + } + + /** + * The position of the channel + * @type {number} + * @readonly + */ + get position() { + const sorted = this.guild._sortedChannels(this); + return sorted.array().indexOf(sorted.get(this.id)); + } + + /** + * Gets the overall set of permissions for a user in this channel, taking into account roles and permission + * overwrites. + * @param {GuildMemberResolvable} member The user that you want to obtain the overall permissions for + * @returns {?Permissions} + */ + permissionsFor(member) { + member = this.guild.members.resolve(member); + if (!member) return null; + if (member.id === this.guild.ownerID) return new Permissions(Permissions.ALL).freeze(); + + const roles = member.roles; + const permissions = new Permissions(roles.map(role => role.permissions)); + + if (permissions.has(Permissions.FLAGS.ADMINISTRATOR)) return new Permissions(Permissions.ALL).freeze(); + + const overwrites = this.overwritesFor(member, true, roles); + + return permissions + .remove(overwrites.everyone ? overwrites.everyone.denied : 0) + .add(overwrites.everyone ? overwrites.everyone.allowed : 0) + .remove(overwrites.roles.length > 0 ? overwrites.roles.map(role => role.denied) : 0) + .add(overwrites.roles.length > 0 ? overwrites.roles.map(role => role.allowed) : 0) + .remove(overwrites.member ? overwrites.member.denied : 0) + .add(overwrites.member ? overwrites.member.allowed : 0) + .freeze(); + } + + overwritesFor(member, verified = false, roles = null) { + if (!verified) member = this.guild.members.resolve(member); + if (!member) return []; + + roles = roles || member.roles; + const roleOverwrites = []; + let memberOverwrites; + let everyoneOverwrites; + + for (const overwrite of this.permissionOverwrites.values()) { + if (overwrite.id === this.guild.id) { + everyoneOverwrites = overwrite; + } else if (roles.has(overwrite.id)) { + roleOverwrites.push(overwrite); + } else if (overwrite.id === member.id) { + memberOverwrites = overwrite; + } + } + + return { + everyone: everyoneOverwrites, + roles: roleOverwrites, + member: memberOverwrites, + }; + } + + /** + * An object mapping permission flags to `true` (enabled), `null` (default) or `false` (disabled). + * ```js + * { + * 'SEND_MESSAGES': true, + * 'EMBED_LINKS': null, + * 'ATTACH_FILES': false, + * } + * ``` + * @typedef {Object} PermissionOverwriteOptions + */ + + /** + * Overwrites the permissions for a user or role in this channel. + * @param {RoleResolvable|UserResolvable} userOrRole The user or role to update + * @param {PermissionOverwriteOptions} options The configuration for the update + * @param {string} [reason] Reason for creating/editing this overwrite + * @returns {Promise} + * @example + * // Overwrite permissions for a message author + * message.channel.overwritePermissions(message.author, { + * SEND_MESSAGES: false + * }) + * .then(() => console.log('Done!')) + * .catch(console.error); + */ + overwritePermissions(userOrRole, options, reason) { + const allow = new Permissions(0); + const deny = new Permissions(0); + let type; + + const role = this.guild.roles.get(userOrRole); + + if (role || userOrRole instanceof Role) { + userOrRole = role || userOrRole; + type = 'role'; + } else { + userOrRole = this.client.users.resolve(userOrRole); + type = 'member'; + if (!userOrRole) return Promise.reject(new TypeError('INVALID_TYPE', 'parameter', 'User nor a Role', true)); + } + + const prevOverwrite = this.permissionOverwrites.get(userOrRole.id); + + if (prevOverwrite) { + allow.add(prevOverwrite.allowed); + deny.add(prevOverwrite.denied); + } + + for (const perm in options) { + if (options[perm] === true) { + allow.add(Permissions.FLAGS[perm] || 0); + deny.remove(Permissions.FLAGS[perm] || 0); + } else if (options[perm] === false) { + allow.remove(Permissions.FLAGS[perm] || 0); + deny.add(Permissions.FLAGS[perm] || 0); + } else if (options[perm] === null) { + allow.remove(Permissions.FLAGS[perm] || 0); + deny.remove(Permissions.FLAGS[perm] || 0); + } + } + + return this.client.api.channels(this.id).permissions[userOrRole.id] + .put({ data: { id: userOrRole.id, type, allow: allow.bitfield, deny: deny.bitfield }, reason }) + .then(() => this); + } + + /** + * Locks in the permission overwrites from the parent channel. + * @returns {Promise} + */ + lockPermissions() { + if (!this.parent) return Promise.reject(new Error('GUILD_CHANNEL_ORPHAN')); + const permissionOverwrites = this.parent.permissionOverwrites.map(overwrite => ({ + deny: overwrite.denied.bitfield, + allow: overwrite.allowed.bitfield, + id: overwrite.id, + type: overwrite.type, + })); + return this.edit({ permissionOverwrites }); + } + + /** + * A collection of members that can see this channel, mapped by their ID + * @type {Collection} + * @readonly + */ + get members() { + const members = new Collection(); + for (const member of this.guild.members.values()) { + if (this.permissionsFor(member).has('VIEW_CHANNEL')) { + members.set(member.id, member); + } + } + return members; + } + + /** + * The data for a guild channel. + * @typedef {Object} ChannelData + * @property {string} [name] The name of the channel + * @property {number} [position] The position of the channel + * @property {string} [topic] The topic of the text channel + * @property {number} [bitrate] The bitrate of the voice channel + * @property {number} [userLimit] The user limit of the voice channel + * @property {Snowflake} [parentID] The parent ID of the channel + * @property {boolean} [lockPermissions] Lock the permissions of the channel to what the parent's permissions are + * @property {OverwriteData[]} [permissionOverwrites] An array of overwrites to set for the channel + */ + + /** + * The data for a permission overwrite + * @typedef {Object} OverwriteData + * @property {string} id The id of the overwrite + * @property {string} type The type of the overwrite, either role or member + * @property {number} allow The bitfield for the allowed permissions + * @property {number} deny The bitfield for the denied permissions + */ + + /** + * Edits the channel. + * @param {ChannelData} data The new data for the channel + * @param {string} [reason] Reason for editing this channel + * @returns {Promise} + * @example + * // Edit a channel + * channel.edit({name: 'new-channel'}) + * .then(c => console.log(`Edited channel ${c}`)) + * .catch(console.error); + */ + edit(data, reason) { + return this.client.api.channels(this.id).patch({ + data: { + name: (data.name || this.name).trim(), + topic: data.topic, + position: data.position || this.rawPosition, + bitrate: data.bitrate || (this.bitrate ? this.bitrate * 1000 : undefined), + user_limit: data.userLimit != null ? data.userLimit : this.userLimit, // eslint-disable-line eqeqeq + parent_id: data.parentID, + lock_permissions: data.lockPermissions, + permission_overwrites: data.permissionOverwrites, + }, + reason, + }).then(newData => { + const clone = this._clone(); + clone._patch(newData); + return clone; + }); + } + + /** + * Set a new name for the guild channel. + * @param {string} name The new name for the guild channel + * @param {string} [reason] Reason for changing the guild channel's name + * @returns {Promise} + * @example + * // Set a new channel name + * channel.setName('not_general') + * .then(newChannel => console.log(`Channel's new name is ${newChannel.name}`)) + * .catch(console.error); + */ + setName(name, reason) { + return this.edit({ name }, reason); + } + + /** + * Set the category parent of this channel. + * @param {GuildChannel|Snowflake} channel Parent channel + * @param {boolean} [options.lockPermissions] Lock the permissions to what the parent's permissions are + * @param {string} [options.reason] Reason for modifying the parent of this channel + * @returns {Promise} + */ + setParent(channel, { lockPermissions = true, reason } = {}) { + return this.edit({ + parentID: channel.id ? channel.id : channel, + lockPermissions, + }, reason); + } + + /** + * Set a new topic for the guild channel. + * @param {string} topic The new topic for the guild channel + * @param {string} [reason] Reason for changing the guild channel's topic + * @returns {Promise} + * @example + * // Set a new channel topic + * channel.setTopic('needs more rate limiting') + * .then(newChannel => console.log(`Channel's new topic is ${newChannel.topic}`)) + * .catch(console.error); + */ + setTopic(topic, reason) { + return this.edit({ topic }, reason); + } + + /** + * Set a new position for the guild channel. + * @param {number} position The new position for the guild channel + * @param {Object} [options] Options for setting position + * @param {boolean} [options.relative=false] Change the position relative to its current value + * @param {boolean} [options.reason] Reasion for changing the position + * @returns {Promise} + * @example + * // Set a new channel position + * channel.setPosition(2) + * .then(newChannel => console.log(`Channel's new position is ${newChannel.position}`)) + * .catch(console.error); + */ + setPosition(position, { relative, reason } = {}) { + return Util.setPosition(this, position, relative, + this.guild._sortedChannels(this), this.client.api.guilds(this.guild.id).channels, reason) + .then(updatedChannels => { + this.client.actions.GuildChannelsPositionUpdate.handle({ + guild_id: this.id, + channels: updatedChannels, + }); + return this; + }); + } + + /** + * Create an invite to this guild channel. + * @param {Object} [options={}] Options for the invite + * @param {boolean} [options.temporary=false] Whether members that joined via the invite should be automatically + * kicked after 24 hours if they have not yet received a role + * @param {number} [options.maxAge=86400] How long the invite should last (in seconds, 0 for forever) + * @param {number} [options.maxUses=0] Maximum number of uses + * @param {boolean} [options.unique=false] Create a unique invite, or use an existing one with similar settings + * @param {string} [options.reason] Reason for creating this + * @returns {Promise} + */ + createInvite({ temporary = false, maxAge = 86400, maxUses = 0, unique, reason } = {}) { + return this.client.api.channels(this.id).invites.post({ data: { + temporary, max_age: maxAge, max_uses: maxUses, unique, + }, reason }) + .then(invite => new Invite(this.client, invite)); + } + + /** + * Clone this channel. + * @param {Object} [options] The options + * @param {string} [options.name=this.name] Optional name for the new channel, otherwise it has the name + * of this channel + * @param {boolean} [options.withPermissions=true] Whether to clone the channel with this channel's + * permission overwrites + * @param {boolean} [options.withTopic=true] Whether to clone the channel with this channel's topic + * @param {string} [options.reason] Reason for cloning this channel + * @returns {Promise} + */ + clone({ name = this.name, withPermissions = true, withTopic = true, reason } = {}) { + const options = { overwrites: withPermissions ? this.permissionOverwrites : [], reason }; + return this.guild.createChannel(name, this.type, options) + .then(channel => withTopic ? channel.setTopic(this.topic) : channel); + } + + /** + * Checks if this channel has the same type, topic, position, name, overwrites and ID as another channel. + * In most cases, a simple `channel.id === channel2.id` will do, and is much faster too. + * @param {GuildChannel} channel Channel to compare with + * @returns {boolean} + */ + equals(channel) { + let equal = channel && + this.id === channel.id && + this.type === channel.type && + this.topic === channel.topic && + this.position === channel.position && + this.name === channel.name; + + if (equal) { + if (this.permissionOverwrites && channel.permissionOverwrites) { + equal = this.permissionOverwrites.equals(channel.permissionOverwrites); + } else { + equal = !this.permissionOverwrites && !channel.permissionOverwrites; + } + } + + return equal; + } + + /** + * Whether the channel is deletable by the client user + * @type {boolean} + * @readonly + */ + get deletable() { + return this.permissionsFor(this.client.user).has(Permissions.FLAGS.MANAGE_CHANNELS); + } + + /** + * Deletes this channel. + * @param {string} [reason] Reason for deleting this channel + * @returns {Promise} + * @example + * // Delete the channel + * channel.delete('making room for new channels') + * .then() // Success + * .catch(console.error); // Log error + */ + delete(reason) { + return this.client.api.channels(this.id).delete({ reason }).then(() => this); + } + + /** + * Whether the channel is muted + * This is only available when using a user account. + * @type {?boolean} + * @readonly + */ + get muted() { + if (this.client.user.bot) return null; + try { + return this.client.user.guildSettings.get(this.guild.id).channelOverrides.get(this.id).muted; + } catch (err) { + return false; + } + } + + /** + * The type of message that should notify you + * one of `EVERYTHING`, `MENTIONS`, `NOTHING`, `INHERIT` + * This is only available when using a user account. + * @type {?string} + * @readonly + */ + get messageNotifications() { + if (this.client.user.bot) return null; + try { + return this.client.user.guildSettings.get(this.guild.id).channelOverrides.get(this.id).messageNotifications; + } catch (err) { + return MessageNotificationTypes[3]; + } + } + + /** + * When concatenated with a string, this automatically returns the channel's mention instead of the Channel object. + * @returns {string} + * @example + * // Outputs: Hello from #general + * console.log(`Hello from ${channel}`); + * @example + * // Outputs: Hello from #general + * console.log('Hello from ' + channel); + */ + toString() { + return `<#${this.id}>`; + } +} + +module.exports = GuildChannel; + + +/***/ }), +/* 16 */ +/***/ (function(module, exports, __webpack_require__) { + +/* WEBPACK VAR INJECTION */(function(Buffer) {const path = __webpack_require__(33); +const Util = __webpack_require__(5); +const DataResolver = __webpack_require__(10); +const Embed = __webpack_require__(14); +const MessageAttachment = __webpack_require__(20); +const MessageEmbed = __webpack_require__(14); + +/** + * Represents a webhook. + */ +class Webhook { + constructor(client, data) { + /** + * The client that instantiated the webhook + * @name Webhook#client + * @type {Client} + * @readonly + */ + Object.defineProperty(this, 'client', { value: client }); + if (data) this._patch(data); + } + + _patch(data) { + /** + * The name of the webhook + * @type {string} + */ + this.name = data.name; + + /** + * The token for the webhook + * @type {string} + */ + this.token = data.token; + + /** + * The avatar for the webhook + * @type {?string} + */ + this.avatar = data.avatar; + + /** + * The ID of the webhook + * @type {Snowflake} + */ + this.id = data.id; + + /** + * The guild the webhook belongs to + * @type {Snowflake} + */ + this.guildID = data.guild_id; + + /** + * The channel the webhook belongs to + * @type {Snowflake} + */ + this.channelID = data.channel_id; + + if (data.user) { + /** + * The owner of the webhook + * @type {?User|Object} + */ + this.owner = this.client.users ? this.client.users.get(data.user.id) : data.user; + } else { + this.owner = null; + } + } + + /** + * Options that can be passed into send. + * @typedef {Object} WebhookMessageOptions + * @property {string} [username=this.name] Username override for the message + * @property {string} [avatarURL] Avatar URL override for the message + * @property {boolean} [tts=false] Whether or not the message should be spoken aloud + * @property {string} [nonce=''] The nonce for the message + * @property {Object[]} [embeds] An array of embeds for the message + * (see [here](https://discordapp.com/developers/docs/resources/channel#embed-object) for more details) + * @property {boolean} [disableEveryone=this.client.options.disableEveryone] Whether or not @everyone and @here + * should be replaced with plain-text + * @property {FileOptions|BufferResolvable} [file] A file to send with the message + * @property {FileOptions[]|string[]} [files] Files to send with the message + * @property {string|boolean} [code] Language for optional codeblock formatting to apply + * @property {boolean|SplitOptions} [split=false] Whether or not the message should be split into multiple messages if + * it exceeds the character limit. If an object is provided, these are the options for splitting the message. + */ + + /* eslint-disable max-len */ + /** + * Send a message with this webhook. + * @param {StringResolvable} [content] The content to send + * @param {WebhookMessageOptions|MessageEmbed|MessageAttachment|MessageAttachment[]} [options={}] The options to provide + * @returns {Promise} + * @example + * // Send a message + * webhook.send('hello!') + * .then(message => console.log(`Sent message: ${message.content}`)) + * .catch(console.error); + */ + /* eslint-enable max-len */ + send(content, options) { // eslint-disable-line complexity + if (!options && typeof content === 'object' && !(content instanceof Array)) { + options = content; + content = ''; + } else if (!options) { + options = {}; + } + + if (options instanceof MessageAttachment) options = { files: [options.file] }; + if (options instanceof MessageEmbed) options = { embeds: [options] }; + if (options.embed) options = { embeds: [options.embed] }; + + if (content instanceof Array || options instanceof Array) { + const which = content instanceof Array ? content : options; + const attachments = which.filter(item => item instanceof MessageAttachment); + const embeds = which.filter(item => item instanceof MessageEmbed); + if (attachments.length) options = { files: attachments }; + if (embeds.length) options = { embeds }; + if ((embeds.length || attachments.length) && content instanceof Array) content = ''; + } + + if (!options.username) options.username = this.name; + if (options.avatarURL) { + options.avatar_url = options.avatarURL; + options.avatarURL = null; + } + + if (content) { + content = Util.resolveString(content); + let { split, code, disableEveryone } = options; + if (split && typeof split !== 'object') split = {}; + if (typeof code !== 'undefined' && (typeof code !== 'boolean' || code === true)) { + content = Util.escapeMarkdown(content, true); + content = `\`\`\`${typeof code !== 'boolean' ? code || '' : ''}\n${content}\n\`\`\``; + if (split) { + split.prepend = `\`\`\`${typeof code !== 'boolean' ? code || '' : ''}\n`; + split.append = '\n```'; + } + } + if (disableEveryone || (typeof disableEveryone === 'undefined' && this.client.options.disableEveryone)) { + content = content.replace(/@(everyone|here)/g, '@\u200b$1'); + } + + if (split) content = Util.splitMessage(content, split); + } + options.content = content; + + if (options.embeds) options.embeds = options.embeds.map(embed => new Embed(embed)._apiTransform()); + + if (options.files) { + for (let i = 0; i < options.files.length; i++) { + let file = options.files[i]; + if (typeof file === 'string' || Buffer.isBuffer(file)) file = { attachment: file }; + if (!file.name) { + if (typeof file.attachment === 'string') { + file.name = path.basename(file.attachment); + } else if (file.attachment && file.attachment.path) { + file.name = path.basename(file.attachment.path); + } else if (file instanceof MessageAttachment) { + file = { attachment: file.file, name: path.basename(file.file) || 'file.jpg' }; + } else { + file.name = 'file.jpg'; + } + } else if (file instanceof MessageAttachment) { + file = file.file; + } + options.files[i] = file; + } + + return Promise.all(options.files.map(file => + DataResolver.resolveFile(file.attachment, this.client.browser).then(resource => { + file.file = resource; + return file; + }) + )).then(files => this.client.api.webhooks(this.id, this.token).post({ + data: options, + query: { wait: true }, + files, + auth: false, + })); + } + + if (content instanceof Array) { + return new Promise((resolve, reject) => { + const messages = []; + (function sendChunk() { + const opt = content.length ? null : { embeds: options.embeds, files: options.files }; + this.client.api.webhooks(this.id, this.token).post({ + data: { content: content.shift(), opt }, + query: { wait: true }, + auth: false, + }) + .then(message => { + messages.push(message); + if (content.length === 0) return resolve(messages); + return sendChunk.call(this); + }) + .catch(reject); + }.call(this)); + }); + } + + return this.client.api.webhooks(this.id, this.token).post({ + data: options, + query: { wait: true }, + auth: false, + }).then(data => { + if (!this.client.channels) return data; + return this.client.channels.get(data.channel_id).messages.create(data, false); + }); + } + + /** + * Send a raw slack message with this webhook. + * @param {Object} body The raw body to send + * @returns {Promise} + * @example + * // Send a slack message + * webhook.sendSlackMessage({ + * 'username': 'Wumpus', + * 'attachments': [{ + * 'pretext': 'this looks pretty cool', + * 'color': '#F0F', + * 'footer_icon': 'http://snek.s3.amazonaws.com/topSnek.png', + * 'footer': 'Powered by sneks', + * 'ts': Date.now() / 1000 + * }] + * }).catch(console.error); + */ + sendSlackMessage(body) { + return this.client.api.webhooks(this.id, this.token).slack.post({ + query: { wait: true }, + auth: false, + data: body, + }).then(data => { + if (!this.client.channels) return data; + return this.client.channels.get(data.channel_id).messages.create(data, false); + }); + } + + /** + * Edit the webhook. + * @param {Object} options Options + * @param {string} [options.name=this.name] New name for this webhook + * @param {BufferResolvable} [options.avatar] New avatar for this webhook + * @param {string} [reason] Reason for editing this webhook + * @returns {Promise} + */ + edit({ name = this.name, avatar }, reason) { + if (avatar && (typeof avatar === 'string' && !avatar.startsWith('data:'))) { + return DataResolver.resolveImage(avatar, this.client.browser).then(image => + this.edit({ name, avatar: image }, reason) + ); + } + return this.client.api.webhooks(this.id, this.token).patch({ + data: { name, avatar }, + reason, + }).then(data => { + this.name = data.name; + this.avatar = data.avatar; + return this; + }); + } + + /** + * Delete the webhook. + * @param {string} [reason] Reason for deleting this webhook + * @returns {Promise} + */ + delete(reason) { + return this.client.api.webhooks(this.id, this.token).delete({ reason }); + } + + static applyToClass(structure) { + for (const prop of [ + 'send', + 'sendSlackMessage', + 'edit', + 'delete', + ]) { + Object.defineProperty(structure.prototype, prop, + Object.getOwnPropertyDescriptor(Webhook.prototype, prop)); + } + } +} + +module.exports = Webhook; + +/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(17).Buffer)) + +/***/ }), +/* 17 */ +/***/ (function(module, exports, __webpack_require__) { + "use strict"; /* WEBPACK VAR INJECTION */(function(global) {/*! * The buffer module from node.js, for the browser. @@ -1282,9 +4120,9 @@ module.exports.Messages = __webpack_require__(114); -var base64 = __webpack_require__(80) -var ieee754 = __webpack_require__(81) -var isArray = __webpack_require__(47) +var base64 = __webpack_require__(63) +var ieee754 = __webpack_require__(64) +var isArray = __webpack_require__(65) exports.Buffer = Buffer exports.SlowBuffer = SlowBuffer @@ -3062,356 +5900,10 @@ function isnan (val) { return val !== val // eslint-disable-line no-self-compare } -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(7))) +/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(27))) /***/ }), -/* 6 */ -/***/ (function(module, exports, __webpack_require__) { - -/* WEBPACK VAR INJECTION */(function(Buffer) {const Long = __webpack_require__(35); -const snekfetch = __webpack_require__(36); -const { Colors, DefaultOptions, Endpoints } = __webpack_require__(0); -const { Error: DiscordError, RangeError, TypeError } = __webpack_require__(4); -const has = (o, k) => Object.prototype.hasOwnProperty.call(o, k); - -/** - * Contains various general-purpose utility methods. These functions are also available on the base `Discord` object. - */ -class Util { - constructor() { - throw new Error(`The ${this.constructor.name} class may not be instantiated.`); - } - - /** - * Splits a string into multiple chunks at a designated character that do not exceed a specific length. - * @param {string} text Content to split - * @param {SplitOptions} [options] Options controlling the behaviour of the split - * @returns {string|string[]} - */ - static splitMessage(text, { maxLength = 1950, char = '\n', prepend = '', append = '' } = {}) { - if (text.length <= maxLength) return text; - const splitText = text.split(char); - if (splitText.length === 1) { - throw new RangeError('SPLIT_MAX_LEN'); - } - const messages = ['']; - let msg = 0; - for (let i = 0; i < splitText.length; i++) { - if (messages[msg].length + splitText[i].length + 1 > maxLength) { - messages[msg] += append; - messages.push(prepend); - msg++; - } - messages[msg] += (messages[msg].length > 0 && messages[msg] !== prepend ? char : '') + splitText[i]; - } - return messages.filter(m => m); - } - - /** - * Escapes any Discord-flavour markdown in a string. - * @param {string} text Content to escape - * @param {boolean} [onlyCodeBlock=false] Whether to only escape codeblocks (takes priority) - * @param {boolean} [onlyInlineCode=false] Whether to only escape inline code - * @returns {string} - */ - static escapeMarkdown(text, onlyCodeBlock = false, onlyInlineCode = false) { - if (onlyCodeBlock) return text.replace(/```/g, '`\u200b``'); - if (onlyInlineCode) return text.replace(/\\(`|\\)/g, '$1').replace(/(`|\\)/g, '\\$1'); - return text.replace(/\\(\*|_|`|~|\\)/g, '$1').replace(/(\*|_|`|~|\\)/g, '\\$1'); - } - - /** - * Gets the recommended shard count from Discord. - * @param {string} token Discord auth token - * @param {number} [guildsPerShard=1000] Number of guilds per shard - * @returns {Promise} The recommended number of shards - */ - static fetchRecommendedShards(token, guildsPerShard = 1000) { - return new Promise((resolve, reject) => { - if (!token) throw new DiscordError('TOKEN_MISSING'); - snekfetch.get(`${DefaultOptions.http.api}/v${DefaultOptions.http.version}${Endpoints.botGateway}`) - .set('Authorization', `Bot ${token.replace(/^Bot\s*/i, '')}`) - .end((err, res) => { - if (err) reject(err); - resolve(res.body.shards * (1000 / guildsPerShard)); - }); - }); - } - - /** - * Parses emoji info out of a string. The string must be one of: - * * A UTF-8 emoji (no ID) - * * A URL-encoded UTF-8 emoji (no ID) - * * A Discord custom emoji (`<:name:id>`) - * @param {string} text Emoji string to parse - * @returns {Object} Object with `name` and `id` properties - * @private - */ - static parseEmoji(text) { - if (text.includes('%')) text = decodeURIComponent(text); - if (text.includes(':')) { - const [name, id] = text.split(':'); - return { name, id }; - } else { - return { - name: text, - id: null, - }; - } - } - - /** - * Checks whether the arrays are equal, also removes duplicated entries from b. - * @param {Array<*>} a Array which will not be modified. - * @param {Array<*>} b Array to remove duplicated entries from. - * @returns {boolean} Whether the arrays are equal. - * @private - */ - static arraysEqual(a, b) { - if (a === b) return true; - if (a.length !== b.length) return false; - - for (const item of a) { - const ind = b.indexOf(item); - if (ind !== -1) b.splice(ind, 1); - } - - return b.length === 0; - } - - /** - * Shallow-copies an object with its class/prototype intact. - * @param {Object} obj Object to clone - * @returns {Object} - * @private - */ - static cloneObject(obj) { - return Object.assign(Object.create(obj), obj); - } - - /** - * Sets default properties on an object that aren't already specified. - * @param {Object} def Default properties - * @param {Object} given Object to assign defaults to - * @returns {Object} - * @private - */ - static mergeDefault(def, given) { - if (!given) return def; - for (const key in def) { - if (!has(given, key) || given[key] === undefined) { - given[key] = def[key]; - } else if (given[key] === Object(given[key])) { - given[key] = this.mergeDefault(def[key], given[key]); - } - } - - return given; - } - - /** - * Converts an ArrayBuffer or string to a Buffer. - * @param {ArrayBuffer|string} ab ArrayBuffer to convert - * @returns {Buffer} - * @private - */ - static convertToBuffer(ab) { - if (typeof ab === 'string') ab = this.str2ab(ab); - return Buffer.from(ab); - } - - /** - * Converts a string to an ArrayBuffer. - * @param {string} str String to convert - * @returns {ArrayBuffer} - * @private - */ - static str2ab(str) { - const buffer = new ArrayBuffer(str.length * 2); - const view = new Uint16Array(buffer); - for (var i = 0, strLen = str.length; i < strLen; i++) view[i] = str.charCodeAt(i); - return buffer; - } - - /** - * Makes an Error from a plain info object. - * @param {Object} obj Error info - * @param {string} obj.name Error type - * @param {string} obj.message Message for the error - * @param {string} obj.stack Stack for the error - * @returns {Error} - * @private - */ - static makeError(obj) { - const err = new Error(obj.message); - err.name = obj.name; - err.stack = obj.stack; - return err; - } - - /** - * Makes a plain error info object from an Error. - * @param {Error} err Error to get info from - * @returns {Object} - * @private - */ - static makePlainError(err) { - const obj = {}; - obj.name = err.name; - obj.message = err.message; - obj.stack = err.stack; - return obj; - } - - /** - * Moves an element in an array *in place*. - * @param {Array<*>} array Array to modify - * @param {*} element Element to move - * @param {number} newIndex Index or offset to move the element to - * @param {boolean} [offset=false] Move the element by an offset amount rather than to a set index - * @returns {number} - * @private - */ - static moveElementInArray(array, element, newIndex, offset = false) { - const index = array.indexOf(element); - newIndex = (offset ? index : 0) + newIndex; - if (newIndex > -1 && newIndex < array.length) { - const removedElement = array.splice(index, 1)[0]; - array.splice(newIndex, 0, removedElement); - } - return array.indexOf(element); - } - - /** - * Data that can be resolved to give a string. This can be: - * * A string - * * An array (joined with a new line delimiter to give a string) - * * Any value - * @typedef {string|Array|*} StringResolvable - */ - - /** - * Resolves a StringResolvable to a string. - * @param {StringResolvable} data The string resolvable to resolve - * @returns {string} - */ - - static resolveString(data) { - if (typeof data === 'string') return data; - if (data instanceof Array) return data.join('\n'); - return String(data); - } - - /** - * Can be a Hex Literal, Hex String, Number, RGB Array, or one of the following - * ``` - * [ - * 'DEFAULT', - * 'AQUA', - * 'GREEN', - * 'BLUE', - * 'PURPLE', - * 'GOLD', - * 'ORANGE', - * 'RED', - * 'GREY', - * 'DARKER_GREY', - * 'NAVY', - * 'DARK_AQUA', - * 'DARK_GREEN', - * 'DARK_BLUE', - * 'DARK_PURPLE', - * 'DARK_GOLD', - * 'DARK_ORANGE', - * 'DARK_RED', - * 'DARK_GREY', - * 'LIGHT_GREY', - * 'DARK_NAVY', - * 'RANDOM', - * ] - * ``` - * or something like - * ``` - * [255, 0, 255] - * ``` - * for purple - * @typedef {string|number|Array} ColorResolvable - */ - - /** - * Resolves a ColorResolvable into a color number. - * @param {ColorResolvable} color Color to resolve - * @returns {number} A color - */ - - static resolveColor(color) { - if (typeof color === 'string') { - if (color === 'RANDOM') return Math.floor(Math.random() * (0xFFFFFF + 1)); - color = Colors[color] || parseInt(color.replace('#', ''), 16); - } else if (color instanceof Array) { - color = (color[0] << 16) + (color[1] << 8) + color[2]; - } - - if (color < 0 || color > 0xFFFFFF) { - throw new RangeError('COLOR_RANGE'); - } else if (color && isNaN(color)) { - throw new TypeError('COLOR_CONVERT'); - } - - return color; - } - - /** - * Sort by discord's position then ID thing - * @param {Collection} collection Collection of objects to sort - * @returns {Collection} - */ - static discordSort(collection) { - return collection - .sort((a, b) => a.rawPosition - b.rawPosition || Long.fromString(a.id).sub(Long.fromString(b.id)).toNumber()); - } - - static setPosition(item, position, relative, sorted, route, reason) { - let updatedItems = sorted.array(); - Util.moveElementInArray(updatedItems, item, position, relative); - updatedItems = updatedItems.map((r, i) => ({ id: r.id, position: i })); - return route.patch({ data: updatedItems, reason }); - } -} - -module.exports = Util; - -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(5).Buffer)) - -/***/ }), -/* 7 */ -/***/ (function(module, exports) { - -var g; - -// This works in non-strict mode -g = (function() { - return this; -})(); - -try { - // This works if eval is allowed (see CSP) - g = g || Function("return this")() || (1,eval)("this"); -} catch(e) { - // This works if the window reference is available - if(typeof window === "object") - g = window; -} - -// g can still be undefined, but nothing to do about it... -// We return undefined, instead of nothing here, so it's -// easier to handle this case. if(!global) { ...} - -module.exports = g; - - -/***/ }), -/* 8 */ +/* 18 */ /***/ (function(module, exports) { // shim for using process in browser @@ -3600,3131 +6092,18 @@ process.chdir = function (dir) { process.umask = function() { return 0; }; -/***/ }), -/* 9 */ -/***/ (function(module, exports, __webpack_require__) { - -const Long = __webpack_require__(35); - -// Discord epoch (2015-01-01T00:00:00.000Z) -const EPOCH = 1420070400000; -let INCREMENT = 0; - -/** - * A container for useful snowflake-related methods. - */ -class SnowflakeUtil { - constructor() { - throw new Error(`The ${this.constructor.name} class may not be instantiated.`); - } - - /** - * A Twitter snowflake, except the epoch is 2015-01-01T00:00:00.000Z - * ``` - * If we have a snowflake '266241948824764416' we can represent it as binary: - * - * 64 22 17 12 0 - * 000000111011000111100001101001000101000000 00001 00000 000000000000 - * number of ms since Discord epoch worker pid increment - * ``` - * @typedef {string} Snowflake - */ - - /** - * Generates a Discord snowflake. - * This hardcodes the worker ID as 1 and the process ID as 0. - * @returns {Snowflake} The generated snowflake - */ - static generate() { - if (INCREMENT >= 4095) INCREMENT = 0; - const BINARY = `${pad((Date.now() - EPOCH).toString(2), 42)}0000100000${pad((INCREMENT++).toString(2), 12)}`; - return Long.fromString(BINARY, 2).toString(); - } - - /** - * A deconstructed snowflake. - * @typedef {Object} DeconstructedSnowflake - * @property {number} timestamp Timestamp the snowflake was created - * @property {Date} date Date the snowflake was created - * @property {number} workerID Worker ID in the snowflake - * @property {number} processID Process ID in the snowflake - * @property {number} increment Increment in the snowflake - * @property {string} binary Binary representation of the snowflake - */ - - /** - * Deconstructs a Discord snowflake. - * @param {Snowflake} snowflake Snowflake to deconstruct - * @returns {DeconstructedSnowflake} Deconstructed snowflake - */ - static deconstruct(snowflake) { - const BINARY = pad(Long.fromString(snowflake).toString(2), 64); - const res = { - timestamp: parseInt(BINARY.substring(0, 42), 2) + EPOCH, - workerID: parseInt(BINARY.substring(42, 47), 2), - processID: parseInt(BINARY.substring(47, 52), 2), - increment: parseInt(BINARY.substring(52, 64), 2), - binary: BINARY, - }; - Object.defineProperty(res, 'date', { - get: function get() { return new Date(this.timestamp); }, - enumerable: true, - }); - return res; - } -} - -function pad(v, n, c = '0') { - return String(v).length >= n ? String(v) : (String(c).repeat(n) + v).slice(-n); -} - -module.exports = SnowflakeUtil; - - -/***/ }), -/* 10 */ -/***/ (function(module, exports) { - -/** - * Represents a data model that is identifiable by a Snowflake (i.e. Discord API data models). - */ -class Base { - constructor(client) { - /** - * The client that instantiated this - * @name Base#client - * @type {Client} - * @readonly - */ - Object.defineProperty(this, 'client', { value: client }); - } - - _clone() { - return Object.assign(Object.create(this), this); - } - - _patch(data) { return data; } - - _update(data) { - const clone = this._clone(); - this._patch(data); - return clone; - } -} - -module.exports = Base; - - -/***/ }), -/* 11 */ -/***/ (function(module, exports, __webpack_require__) { - -const Collection = __webpack_require__(3); - -/** - * Manages the creation, retrieval and deletion of a specific data model. - * @extends {Collection} - */ -class DataStore extends Collection { - constructor(client, iterable, holds) { - super(); - Object.defineProperty(this, 'client', { value: client }); - Object.defineProperty(this, 'holds', { value: holds }); - if (iterable) for (const item of iterable) this.create(item); - } - - create(data, cache = true, { id, extras = [] } = {}) { - const existing = this.get(id || data.id); - if (existing) return existing; - - const entry = this.holds ? new this.holds(this.client, data, ...extras) : data; - if (cache) this.set(id || entry.id, entry); - return entry; - } - - remove(key) { return this.delete(key); } - - /** - * Resolves a data entry to a data Object. - * @param {string|Object} idOrInstance The id or instance of something in this datastore - * @returns {?Object} An instance from this datastore - */ - resolve(idOrInstance) { - if (idOrInstance instanceof this.holds) return idOrInstance; - if (typeof idOrInstance === 'string') return this.get(idOrInstance) || null; - return null; - } - - /** - * Resolves a data entry to a instance ID. - * @param {string|Instance} idOrInstance The id or instance of something in this datastore - * @returns {?string} - */ - resolveID(idOrInstance) { - if (idOrInstance instanceof this.holds) return idOrInstance.id; - if (typeof idOrInstance === 'string') return idOrInstance; - return null; - } -} - -module.exports = DataStore; - - -/***/ }), -/* 12 */ -/***/ (function(module, exports, __webpack_require__) { - -const { RangeError } = __webpack_require__(4); - -/** - * Data structure that makes it easy to interact with a permission bitfield. All {@link GuildMember}s have a set of - * permissions in their guild, and each channel in the guild may also have {@link PermissionOverwrites} for the member - * that override their default permissions. - */ -class Permissions { - /** - * @param {number|PermissionResolvable[]} permissions Permissions or bitfield to read from - */ - constructor(permissions) { - /** - * Bitfield of the packed permissions - * @type {number} - */ - this.bitfield = typeof permissions === 'number' ? permissions : this.constructor.resolve(permissions); - } - - /** - * Checks whether the bitfield has a permission, or multiple permissions. - * @param {PermissionResolvable|PermissionResolvable[]} permission Permission(s) to check for - * @param {boolean} [checkAdmin=true] Whether to allow the administrator permission to override - * @returns {boolean} - */ - has(permission, checkAdmin = true) { - if (permission instanceof Array) return permission.every(p => this.has(p, checkAdmin)); - permission = this.constructor.resolve(permission); - if (checkAdmin && (this.bitfield & this.constructor.FLAGS.ADMINISTRATOR) > 0) return true; - return (this.bitfield & permission) === permission; - } - - /** - * Gets all given permissions that are missing from the bitfield. - * @param {PermissionResolvable[]} permissions Permissions to check for - * @param {boolean} [checkAdmin=true] Whether to allow the administrator permission to override - * @returns {PermissionResolvable[]} - */ - missing(permissions, checkAdmin = true) { - return permissions.filter(p => !this.has(p, checkAdmin)); - } - - /** - * Freezes the permission making it immutable. - * @returns {Permissions} This permissions - */ - freeze() { - return Object.freeze(this); - } - - /** - * Adds permissions to this one. - * @param {...PermissionResolvable} permissions Permissions to add - * @returns {Permissions} This permissions or new permissions if the instance is frozen. - */ - add(...permissions) { - let total = 0; - for (let p = permissions.length - 1; p >= 0; p--) { - const perm = this.constructor.resolve(permissions[p]); - total |= perm; - } - if (Object.isFrozen(this)) return new this.constructor(this.bitfield | total); - this.bitfield |= total; - return this; - } - - /** - * Removes permissions from this one. - * @param {...PermissionResolvable} permissions Permissions to remove - * @returns {Permissions} This permissions or new permissions if the instance is frozen. - */ - remove(...permissions) { - let total = 0; - for (let p = permissions.length - 1; p >= 0; p--) { - const perm = this.constructor.resolve(permissions[p]); - total |= perm; - } - if (Object.isFrozen(this)) return new this.constructor(this.bitfield & ~total); - this.bitfield &= ~total; - return this; - } - - /** - * Gets an object mapping permission name (like `VIEW_CHANNEL`) to a {@link boolean} indicating whether the - * permission is available. - * @param {boolean} [checkAdmin=true] Whether to allow the administrator permission to override - * @returns {Object} - */ - serialize(checkAdmin = true) { - const serialized = {}; - for (const perm in this.constructor.FLAGS) serialized[perm] = this.has(perm, checkAdmin); - return serialized; - } - - /** - * Data that can be resolved to give a permission number. This can be: - * * A string (see {@link Permissions.FLAGS}) - * * A permission number - * * An instance of Permissions - * @typedef {string|number|Permissions} PermissionResolvable - */ - - /** - * Resolves permissions to their numeric form. - * @param {PermissionResolvable|PermissionResolvable[]} permission - Permission(s) to resolve - * @returns {number} - */ - static resolve(permission) { - if (typeof permission === 'number' && permission >= 0) return permission; - if (permission instanceof Permissions) return permission.bitfield; - if (permission instanceof Array) return permission.map(p => this.resolve(p)).reduce((prev, p) => prev | p, 0); - if (typeof permission === 'string') return this.FLAGS[permission]; - throw new RangeError('PERMISSIONS_INVALID'); - } -} - -/** - * Numeric permission flags. All available properties: - * * `ADMINISTRATOR` (implicitly has *all* permissions, and bypasses all channel overwrites) - * * `CREATE_INSTANT_INVITE` (create invitations to the guild) - * * `KICK_MEMBERS` - * * `BAN_MEMBERS` - * * `MANAGE_CHANNELS` (edit and reorder channels) - * * `MANAGE_GUILD` (edit the guild information, region, etc.) - * * `ADD_REACTIONS` (add new reactions to messages) - * * `VIEW_AUDIT_LOG` - * * `VIEW_CHANNEL` - * * `SEND_MESSAGES` - * * `SEND_TTS_MESSAGES` - * * `MANAGE_MESSAGES` (delete messages and reactions) - * * `EMBED_LINKS` (links posted will have a preview embedded) - * * `ATTACH_FILES` - * * `READ_MESSAGE_HISTORY` (view messages that were posted prior to opening Discord) - * * `MENTION_EVERYONE` - * * `USE_EXTERNAL_EMOJIS` (use emojis from different guilds) - * * `CONNECT` (connect to a voice channel) - * * `SPEAK` (speak in a voice channel) - * * `MUTE_MEMBERS` (mute members across all voice channels) - * * `DEAFEN_MEMBERS` (deafen members across all voice channels) - * * `MOVE_MEMBERS` (move members between voice channels) - * * `USE_VAD` (use voice activity detection) - * * `CHANGE_NICKNAME` - * * `MANAGE_NICKNAMES` (change other members' nicknames) - * * `MANAGE_ROLES` - * * `MANAGE_WEBHOOKS` - * * `MANAGE_EMOJIS` - * @type {Object} - * @see {@link https://discordapp.com/developers/docs/topics/permissions} - */ -Permissions.FLAGS = { - CREATE_INSTANT_INVITE: 1 << 0, - KICK_MEMBERS: 1 << 1, - BAN_MEMBERS: 1 << 2, - ADMINISTRATOR: 1 << 3, - MANAGE_CHANNELS: 1 << 4, - MANAGE_GUILD: 1 << 5, - ADD_REACTIONS: 1 << 6, - VIEW_AUDIT_LOG: 1 << 7, - - VIEW_CHANNEL: 1 << 10, - SEND_MESSAGES: 1 << 11, - SEND_TTS_MESSAGES: 1 << 12, - MANAGE_MESSAGES: 1 << 13, - EMBED_LINKS: 1 << 14, - ATTACH_FILES: 1 << 15, - READ_MESSAGE_HISTORY: 1 << 16, - MENTION_EVERYONE: 1 << 17, - USE_EXTERNAL_EMOJIS: 1 << 18, - - CONNECT: 1 << 20, - SPEAK: 1 << 21, - MUTE_MEMBERS: 1 << 22, - DEAFEN_MEMBERS: 1 << 23, - MOVE_MEMBERS: 1 << 24, - USE_VAD: 1 << 25, - - CHANGE_NICKNAME: 1 << 26, - MANAGE_NICKNAMES: 1 << 27, - MANAGE_ROLES: 1 << 28, - MANAGE_WEBHOOKS: 1 << 29, - MANAGE_EMOJIS: 1 << 30, -}; - -/** - * Bitfield representing every permission combined - * @type {number} - */ -Permissions.ALL = Object.values(Permissions.FLAGS).reduce((all, p) => all | p, 0); - -/** - * Bitfield representing the default permissions for users - * @type {number} - */ -Permissions.DEFAULT = 104324097; - -module.exports = Permissions; - - -/***/ }), -/* 13 */ -/***/ (function(module, exports, __webpack_require__) { - -/* WEBPACK VAR INJECTION */(function(Buffer) {const path = __webpack_require__(29); -const fs = __webpack_require__(39); -const snekfetch = __webpack_require__(36); -const Util = __webpack_require__(6); -const { Error, TypeError } = __webpack_require__(4); - -/** - * The DataResolver identifies different objects and tries to resolve a specific piece of information from them. - * @private - */ -class DataResolver { - constructor() { - throw new Error(`The ${this.constructor.name} class may not be instantiated.`); - } - - /** - * Data that can be resolved to give an invite code. This can be: - * * An invite code - * * An invite URL - * @typedef {string} InviteResolvable - */ - - /** - * Resolves InviteResolvable to an invite code. - * @param {InviteResolvable} data The invite resolvable to resolve - * @returns {string} - */ - static resolveInviteCode(data) { - const inviteRegex = /discord(?:app\.com\/invite|\.gg)\/([\w-]{2,255})/i; - const match = inviteRegex.exec(data); - if (match && match[1]) return match[1]; - return data; - } - - /** - * Resolves a Base64Resolvable, a string, or a BufferResolvable to a Base 64 image. - * @param {BufferResolvable|Base64Resolvable} image The image to be resolved - * @param {boolean} browser Whether this should resolve for a browser - * @returns {Promise} - */ - static async resolveImage(image, browser) { - if (!image) return null; - if (typeof image === 'string' && image.startsWith('data:')) { - return image; - } - const file = await this.resolveFile(image, browser); - return DataResolver.resolveBase64(file); - } - - /** - * Data that resolves to give a Base64 string, typically for image uploading. This can be: - * * A Buffer - * * A base64 string - * @typedef {Buffer|string} Base64Resolvable - */ - - /** - * Resolves a Base64Resolvable to a Base 64 image. - * @param {Base64Resolvable} data The base 64 resolvable you want to resolve - * @returns {?string} - */ - static resolveBase64(data) { - if (data instanceof Buffer) return `data:image/jpg;base64,${data.toString('base64')}`; - return data; - } - - /** - * Data that can be resolved to give a Buffer. This can be: - * * A Buffer - * * The path to a local file - * * A URL - * @typedef {string|Buffer} BufferResolvable - */ - - /** - * @external Stream - * @see {@link https://nodejs.org/api/stream.html} - */ - - /** - * Resolves a BufferResolvable to a Buffer. - * @param {BufferResolvable|Stream} resource The buffer or stream resolvable to resolve - * @param {boolean} browser Whether this should resolve for a browser - * @returns {Promise} - */ - static resolveFile(resource, browser) { - if (resource instanceof Buffer) return Promise.resolve(resource); - if (browser && resource instanceof ArrayBuffer) return Promise.resolve(Util.convertToBuffer(resource)); - - if (typeof resource === 'string') { - return new Promise((resolve, reject) => { - if (/^https?:\/\//.test(resource)) { - snekfetch.get(resource) - .end((err, res) => { - if (err) return reject(err); - if (!(res.body instanceof Buffer)) return reject(new TypeError('REQ_BODY_TYPE')); - return resolve(res.body); - }); - } else { - const file = path.resolve(resource); - fs.stat(file, (err, stats) => { - if (err) return reject(err); - if (!stats || !stats.isFile()) return reject(new Error('FILE_NOT_FOUND', file)); - fs.readFile(file, (err2, data) => { - if (err2) reject(err2); else resolve(data); - }); - return null; - }); - } - }); - } else if (resource.pipe && typeof resource.pipe === 'function') { - return new Promise((resolve, reject) => { - const buffers = []; - resource.once('error', reject); - resource.on('data', data => buffers.push(data)); - resource.once('end', () => resolve(Buffer.concat(buffers))); - }); - } - - return Promise.reject(new TypeError('REQ_RESOURCE_TYPE')); - } -} - -module.exports = DataResolver; - -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(5).Buffer)) - -/***/ }), -/* 14 */ -/***/ (function(module, exports) { - -if (typeof Object.create === 'function') { - // implementation from standard node.js 'util' module - module.exports = function inherits(ctor, superCtor) { - ctor.super_ = superCtor - ctor.prototype = Object.create(superCtor.prototype, { - constructor: { - value: ctor, - enumerable: false, - writable: true, - configurable: true - } - }); - }; -} else { - // old school shim for old browsers - module.exports = function inherits(ctor, superCtor) { - ctor.super_ = superCtor - var TempCtor = function () {} - TempCtor.prototype = superCtor.prototype - ctor.prototype = new TempCtor() - ctor.prototype.constructor = ctor - } -} - - -/***/ }), -/* 15 */ -/***/ (function(module, exports) { - -// Copyright Joyent, Inc. and other Node contributors. -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to permit -// persons to whom the Software is furnished to do so, subject to the -// following conditions: -// -// The above copyright notice and this permission notice shall be included -// in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN -// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE -// USE OR OTHER DEALINGS IN THE SOFTWARE. - -function EventEmitter() { - this._events = this._events || {}; - this._maxListeners = this._maxListeners || undefined; -} -module.exports = EventEmitter; - -// Backwards-compat with node 0.10.x -EventEmitter.EventEmitter = EventEmitter; - -EventEmitter.prototype._events = undefined; -EventEmitter.prototype._maxListeners = undefined; - -// By default EventEmitters will print a warning if more than 10 listeners are -// added to it. This is a useful default which helps finding memory leaks. -EventEmitter.defaultMaxListeners = 10; - -// Obviously not all Emitters should be limited to 10. This function allows -// that to be increased. Set to zero for unlimited. -EventEmitter.prototype.setMaxListeners = function(n) { - if (!isNumber(n) || n < 0 || isNaN(n)) - throw TypeError('n must be a positive number'); - this._maxListeners = n; - return this; -}; - -EventEmitter.prototype.emit = function(type) { - var er, handler, len, args, i, listeners; - - if (!this._events) - this._events = {}; - - // If there is no 'error' event listener then throw. - if (type === 'error') { - if (!this._events.error || - (isObject(this._events.error) && !this._events.error.length)) { - er = arguments[1]; - if (er instanceof Error) { - throw er; // Unhandled 'error' event - } else { - // At least give some kind of context to the user - var err = new Error('Uncaught, unspecified "error" event. (' + er + ')'); - err.context = er; - throw err; - } - } - } - - handler = this._events[type]; - - if (isUndefined(handler)) - return false; - - if (isFunction(handler)) { - switch (arguments.length) { - // fast cases - case 1: - handler.call(this); - break; - case 2: - handler.call(this, arguments[1]); - break; - case 3: - handler.call(this, arguments[1], arguments[2]); - break; - // slower - default: - args = Array.prototype.slice.call(arguments, 1); - handler.apply(this, args); - } - } else if (isObject(handler)) { - args = Array.prototype.slice.call(arguments, 1); - listeners = handler.slice(); - len = listeners.length; - for (i = 0; i < len; i++) - listeners[i].apply(this, args); - } - - return true; -}; - -EventEmitter.prototype.addListener = function(type, listener) { - var m; - - if (!isFunction(listener)) - throw TypeError('listener must be a function'); - - if (!this._events) - this._events = {}; - - // To avoid recursion in the case that type === "newListener"! Before - // adding it to the listeners, first emit "newListener". - if (this._events.newListener) - this.emit('newListener', type, - isFunction(listener.listener) ? - listener.listener : listener); - - if (!this._events[type]) - // Optimize the case of one listener. Don't need the extra array object. - this._events[type] = listener; - else if (isObject(this._events[type])) - // If we've already got an array, just append. - this._events[type].push(listener); - else - // Adding the second element, need to change to array. - this._events[type] = [this._events[type], listener]; - - // Check for listener leak - if (isObject(this._events[type]) && !this._events[type].warned) { - if (!isUndefined(this._maxListeners)) { - m = this._maxListeners; - } else { - m = EventEmitter.defaultMaxListeners; - } - - if (m && m > 0 && this._events[type].length > m) { - this._events[type].warned = true; - console.error('(node) warning: possible EventEmitter memory ' + - 'leak detected. %d listeners added. ' + - 'Use emitter.setMaxListeners() to increase limit.', - this._events[type].length); - if (typeof console.trace === 'function') { - // not supported in IE 10 - console.trace(); - } - } - } - - return this; -}; - -EventEmitter.prototype.on = EventEmitter.prototype.addListener; - -EventEmitter.prototype.once = function(type, listener) { - if (!isFunction(listener)) - throw TypeError('listener must be a function'); - - var fired = false; - - function g() { - this.removeListener(type, g); - - if (!fired) { - fired = true; - listener.apply(this, arguments); - } - } - - g.listener = listener; - this.on(type, g); - - return this; -}; - -// emits a 'removeListener' event iff the listener was removed -EventEmitter.prototype.removeListener = function(type, listener) { - var list, position, length, i; - - if (!isFunction(listener)) - throw TypeError('listener must be a function'); - - if (!this._events || !this._events[type]) - return this; - - list = this._events[type]; - length = list.length; - position = -1; - - if (list === listener || - (isFunction(list.listener) && list.listener === listener)) { - delete this._events[type]; - if (this._events.removeListener) - this.emit('removeListener', type, listener); - - } else if (isObject(list)) { - for (i = length; i-- > 0;) { - if (list[i] === listener || - (list[i].listener && list[i].listener === listener)) { - position = i; - break; - } - } - - if (position < 0) - return this; - - if (list.length === 1) { - list.length = 0; - delete this._events[type]; - } else { - list.splice(position, 1); - } - - if (this._events.removeListener) - this.emit('removeListener', type, listener); - } - - return this; -}; - -EventEmitter.prototype.removeAllListeners = function(type) { - var key, listeners; - - if (!this._events) - return this; - - // not listening for removeListener, no need to emit - if (!this._events.removeListener) { - if (arguments.length === 0) - this._events = {}; - else if (this._events[type]) - delete this._events[type]; - return this; - } - - // emit removeListener for all listeners on all events - if (arguments.length === 0) { - for (key in this._events) { - if (key === 'removeListener') continue; - this.removeAllListeners(key); - } - this.removeAllListeners('removeListener'); - this._events = {}; - return this; - } - - listeners = this._events[type]; - - if (isFunction(listeners)) { - this.removeListener(type, listeners); - } else if (listeners) { - // LIFO order - while (listeners.length) - this.removeListener(type, listeners[listeners.length - 1]); - } - delete this._events[type]; - - return this; -}; - -EventEmitter.prototype.listeners = function(type) { - var ret; - if (!this._events || !this._events[type]) - ret = []; - else if (isFunction(this._events[type])) - ret = [this._events[type]]; - else - ret = this._events[type].slice(); - return ret; -}; - -EventEmitter.prototype.listenerCount = function(type) { - if (this._events) { - var evlistener = this._events[type]; - - if (isFunction(evlistener)) - return 1; - else if (evlistener) - return evlistener.length; - } - return 0; -}; - -EventEmitter.listenerCount = function(emitter, type) { - return emitter.listenerCount(type); -}; - -function isFunction(arg) { - return typeof arg === 'function'; -} - -function isNumber(arg) { - return typeof arg === 'number'; -} - -function isObject(arg) { - return typeof arg === 'object' && arg !== null; -} - -function isUndefined(arg) { - return arg === void 0; -} - - -/***/ }), -/* 16 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -// Copyright Joyent, Inc. and other Node contributors. -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to permit -// persons to whom the Software is furnished to do so, subject to the -// following conditions: -// -// The above copyright notice and this permission notice shall be included -// in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN -// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE -// USE OR OTHER DEALINGS IN THE SOFTWARE. - -// a duplex stream is just a stream that is both readable and writable. -// Since JS doesn't have multiple prototypal inheritance, this class -// prototypally inherits from Readable, and then parasitically from -// Writable. - - - -/**/ - -var processNextTick = __webpack_require__(27); -/**/ - -/**/ -var objectKeys = Object.keys || function (obj) { - var keys = []; - for (var key in obj) { - keys.push(key); - }return keys; -}; -/**/ - -module.exports = Duplex; - -/**/ -var util = __webpack_require__(24); -util.inherits = __webpack_require__(14); -/**/ - -var Readable = __webpack_require__(49); -var Writable = __webpack_require__(38); - -util.inherits(Duplex, Readable); - -var keys = objectKeys(Writable.prototype); -for (var v = 0; v < keys.length; v++) { - var method = keys[v]; - if (!Duplex.prototype[method]) Duplex.prototype[method] = Writable.prototype[method]; -} - -function Duplex(options) { - if (!(this instanceof Duplex)) return new Duplex(options); - - Readable.call(this, options); - Writable.call(this, options); - - if (options && options.readable === false) this.readable = false; - - if (options && options.writable === false) this.writable = false; - - this.allowHalfOpen = true; - if (options && options.allowHalfOpen === false) this.allowHalfOpen = false; - - this.once('end', onend); -} - -// the no-half-open enforcer -function onend() { - // if we allow half-open state, or if the writable side ended, - // then we're ok. - if (this.allowHalfOpen || this._writableState.ended) return; - - // no more data can be written. - // But allow more writes to happen in this tick. - processNextTick(onEndNT, this); -} - -function onEndNT(self) { - self.end(); -} - -Object.defineProperty(Duplex.prototype, 'destroyed', { - get: function () { - if (this._readableState === undefined || this._writableState === undefined) { - return false; - } - return this._readableState.destroyed && this._writableState.destroyed; - }, - set: function (value) { - // we ignore the value if the stream - // has not been initialized yet - if (this._readableState === undefined || this._writableState === undefined) { - return; - } - - // backward compatibility, the user is explicitly - // managing destroyed - this._readableState.destroyed = value; - this._writableState.destroyed = value; - } -}); - -Duplex.prototype._destroy = function (err, cb) { - this.push(null); - this.end(); - - processNextTick(cb, err); -}; - -function forEach(xs, f) { - for (var i = 0, l = xs.length; i < l; i++) { - f(xs[i], i); - } -} - -/***/ }), -/* 17 */ -/***/ (function(module, exports, __webpack_require__) { - -const Snowflake = __webpack_require__(9); -const Base = __webpack_require__(10); -const { ChannelTypes } = __webpack_require__(0); - -/** - * Represents any channel on Discord. - * @extends {Base} - */ -class Channel extends Base { - constructor(client, data) { - super(client); - - const type = Object.keys(ChannelTypes)[data.type]; - /** - * The type of the channel, either: - * * `dm` - a DM channel - * * `group` - a Group DM channel - * * `text` - a guild text channel - * * `voice` - a guild voice channel - * * `category` - a guild category channel - * * `unknown` - a generic channel of unknown type, could be Channel or GuildChannel - * @type {string} - */ - this.type = type ? type.toLowerCase() : 'unknown'; - - if (data) this._patch(data); - } - - _patch(data) { - /** - * The unique ID of the channel - * @type {Snowflake} - */ - this.id = data.id; - } - - /** - * The timestamp the channel was created at - * @type {number} - * @readonly - */ - get createdTimestamp() { - return Snowflake.deconstruct(this.id).timestamp; - } - - /** - * The time the channel was created - * @type {Date} - * @readonly - */ - get createdAt() { - return new Date(this.createdTimestamp); - } - - /** - * Deletes this channel. - * @returns {Promise} - * @example - * // Delete the channel - * channel.delete() - * .then() // Success - * .catch(console.error); // Log error - */ - delete() { - return this.client.api.channels(this.id).delete().then(() => this); - } - - static create(client, data, guild) { - const DMChannel = __webpack_require__(64); - const GroupDMChannel = __webpack_require__(68); - const TextChannel = __webpack_require__(69); - const VoiceChannel = __webpack_require__(71); - const CategoryChannel = __webpack_require__(132); - const GuildChannel = __webpack_require__(21); - let channel; - if (data.type === ChannelTypes.DM) { - channel = new DMChannel(client, data); - } else if (data.type === ChannelTypes.GROUP) { - channel = new GroupDMChannel(client, data); - } else { - guild = guild || client.guilds.get(data.guild_id); - if (guild) { - switch (data.type) { - case ChannelTypes.TEXT: - channel = new TextChannel(guild, data); - break; - case ChannelTypes.VOICE: - channel = new VoiceChannel(guild, data); - break; - case ChannelTypes.CATEGORY: - channel = new CategoryChannel(guild, data); - break; - default: - channel = new GuildChannel(guild, data); - } - guild.channels.set(channel.id, channel); - } - } - return channel; - } -} - -module.exports = Channel; - - -/***/ }), -/* 18 */ -/***/ (function(module, exports, __webpack_require__) { - -const TextBasedChannel = __webpack_require__(25); -const Role = __webpack_require__(32); -const Permissions = __webpack_require__(12); -const Collection = __webpack_require__(3); -const Base = __webpack_require__(10); -const { Presence } = __webpack_require__(19); -const { Error, TypeError } = __webpack_require__(4); - -/** - * Represents a member of a guild on Discord. - * @implements {TextBasedChannel} - * @extends {Base} - */ -class GuildMember extends Base { - constructor(client, data, guild) { - super(client); - - /** - * The guild that this member is part of - * @type {Guild} - */ - this.guild = guild; - - /** - * The user that this guild member instance Represents - * @type {User} - */ - this.user = {}; - - this._roles = []; - - if (data) this._patch(data); - - /** - * The ID of the last message sent by the member in their guild, if one was sent - * @type {?Snowflake} - */ - this.lastMessageID = null; - - /** - * The Message object of the last message sent by the member in their guild, if one was sent - * @type {?Message} - */ - this.lastMessage = null; - } - - _patch(data) { - /** - * Whether this member is speaking - * @type {boolean} - * @name GuildMember#speaking - */ - if (typeof this.speaking === 'undefined') this.speaking = false; - - /** - * The nickname of this guild member, if they have one - * @type {?string} - * @name GuildMember#nickname - */ - if (typeof data.nick !== 'undefined') this.nickname = data.nick; - - /** - * The timestamp the member joined the guild at - * @type {number} - * @name GuildMember#joinedTimestamp - */ - if (typeof data.joined_at !== 'undefined') this.joinedTimestamp = new Date(data.joined_at).getTime(); - - this.user = this.guild.client.users.create(data.user); - if (data.roles) this._roles = data.roles; - } - - get voiceState() { - return this._frozenVoiceState || this.guild.voiceStates.get(this.id) || {}; - } - - /** - * Whether this member is deafened server-wide - * @type {boolean} - */ - get serverDeaf() { return this.voiceState.deaf; } - - /** - * Whether this member is muted server-wide - * @type {boolean} - */ - get serverMute() { return this.voiceState.mute; } - - /** - * Whether this member is self-muted - * @type {boolean} - */ - get selfMute() { return this.voiceState.self_mute; } - - /** - * Whether this member is self-deafened - * @type {boolean} - */ - get selfDeaf() { return this.voiceState.self_deaf; } - - /** - * The voice session ID of this member (if any) - * @type {?Snowflake} - */ - get voiceSessionID() { return this.voiceState.session_id; } - - /** - * The voice channel ID of this member, (if any) - * @type {?Snowflake} - */ - get voiceChannelID() { return this.voiceState.channel_id; } - - /** - * The time the member joined the guild - * @type {Date} - * @readonly - */ - get joinedAt() { - return new Date(this.joinedTimestamp); - } - - /** - * The presence of this guild member - * @type {Presence} - * @readonly - */ - get presence() { - return this.frozenPresence || this.guild.presences.get(this.id) || new Presence(); - } - - /** - * A list of roles that are applied to this GuildMember, mapped by the role ID - * @type {Collection} - * @readonly - */ - get roles() { - const list = new Collection(); - const everyoneRole = this.guild.roles.get(this.guild.id); - - if (everyoneRole) list.set(everyoneRole.id, everyoneRole); - - for (const roleID of this._roles) { - const role = this.guild.roles.get(roleID); - if (role) list.set(role.id, role); - } - - return list; - } - - /** - * The role of the member with the highest position - * @type {Role} - * @readonly - */ - get highestRole() { - return this.roles.reduce((prev, role) => !prev || role.comparePositionTo(prev) > 0 ? role : prev); - } - - /** - * The role of the member used to set their color - * @type {?Role} - * @readonly - */ - get colorRole() { - const coloredRoles = this.roles.filter(role => role.color); - if (!coloredRoles.size) return null; - return coloredRoles.reduce((prev, role) => !prev || role.comparePositionTo(prev) > 0 ? role : prev); - } - - /** - * The displayed color of the member in base 10 - * @type {number} - * @readonly - */ - get displayColor() { - const role = this.colorRole; - return (role && role.color) || 0; - } - - /** - * The displayed color of the member in hexadecimal - * @type {string} - * @readonly - */ - get displayHexColor() { - const role = this.colorRole; - return (role && role.hexColor) || '#000000'; - } - - /** - * The role of the member used to hoist them in a separate category in the users list - * @type {?Role} - * @readonly - */ - get hoistRole() { - const hoistedRoles = this.roles.filter(role => role.hoist); - if (!hoistedRoles.size) return null; - return hoistedRoles.reduce((prev, role) => !prev || role.comparePositionTo(prev) > 0 ? role : prev); - } - - /** - * Whether this member is muted in any way - * @type {boolean} - * @readonly - */ - get mute() { - return this.selfMute || this.serverMute; - } - - /** - * Whether this member is deafened in any way - * @type {boolean} - * @readonly - */ - get deaf() { - return this.selfDeaf || this.serverDeaf; - } - - /** - * The voice channel this member is in, if any - * @type {?VoiceChannel} - * @readonly - */ - get voiceChannel() { - return this.guild.channels.get(this.voiceChannelID); - } - - /** - * The ID of this user - * @type {Snowflake} - * @readonly - */ - get id() { - return this.user.id; - } - - /** - * The nickname of the member, or their username if they don't have one - * @type {string} - * @readonly - */ - get displayName() { - return this.nickname || this.user.username; - } - - /** - * The overall set of permissions for the guild member, taking only roles into account - * @type {Permissions} - * @readonly - */ - get permissions() { - if (this.user.id === this.guild.ownerID) return new Permissions(Permissions.ALL).freeze(); - return new Permissions(this.roles.map(role => role.permissions)).freeze(); - } - - /** - * Whether the member is kickable by the client user - * @type {boolean} - * @readonly - */ - get kickable() { - if (this.user.id === this.guild.ownerID) return false; - if (this.user.id === this.client.user.id) return false; - const clientMember = this.guild.member(this.client.user); - if (!clientMember.permissions.has(Permissions.FLAGS.KICK_MEMBERS)) return false; - return clientMember.highestRole.comparePositionTo(this.highestRole) > 0; - } - - /** - * Whether the member is bannable by the client user - * @type {boolean} - * @readonly - */ - get bannable() { - if (this.user.id === this.guild.ownerID) return false; - if (this.user.id === this.client.user.id) return false; - const clientMember = this.guild.member(this.client.user); - if (!clientMember.permissions.has(Permissions.FLAGS.BAN_MEMBERS)) return false; - return clientMember.highestRole.comparePositionTo(this.highestRole) > 0; - } - - /** - * Returns `channel.permissionsFor(guildMember)`. Returns permissions for a member in a guild channel, - * taking into account roles and permission overwrites. - * @param {ChannelResolvable} channel The guild channel to use as context - * @returns {?Permissions} - */ - permissionsIn(channel) { - channel = this.client.channels.resolve(channel); - if (!channel || !channel.guild) throw new Error('GUILD_CHANNEL_RESOLVE'); - return channel.permissionsFor(this); - } - - /** - * Checks if any of the member's roles have a permission. - * @param {PermissionResolvable|PermissionResolvable[]} permission Permission(s) to check for - * @param {boolean} [explicit=false] Whether to require the role to explicitly have the exact permission - * **(deprecated)** - * @param {boolean} [checkAdmin] Whether to allow the administrator permission to override - * (takes priority over `explicit`) - * @param {boolean} [checkOwner] Whether to allow being the guild's owner to override - * (takes priority over `explicit`) - * @returns {boolean} - */ - hasPermission(permission, explicit = false, checkAdmin, checkOwner) { - if (typeof checkAdmin === 'undefined') checkAdmin = !explicit; - if (typeof checkOwner === 'undefined') checkOwner = !explicit; - if (checkOwner && this.user.id === this.guild.ownerID) return true; - return this.roles.some(r => r.permissions.has(permission, undefined, checkAdmin)); - } - - /** - * Checks whether the roles of the member allows them to perform specific actions, and lists any missing permissions. - * @param {PermissionResolvable[]} permissions The permissions to check for - * @param {boolean} [explicit=false] Whether to require the member to explicitly have the exact permissions - * @returns {PermissionResolvable[]} - */ - missingPermissions(permissions, explicit = false) { - return this.permissions.missing(permissions, explicit); - } - - /** - * The data for editing a guild member. - * @typedef {Object} GuildMemberEditData - * @property {string} [nick] The nickname to set for the member - * @property {Collection|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 {ChannelResolvable} [channel] Channel to move member to (if they are connected to voice) - */ - - /** - * Edit a guild member. - * @param {GuildMemberEditData} data The data to edit the member with - * @param {string} [reason] Reason for editing this user - * @returns {Promise} - */ - edit(data, reason) { - if (data.channel) { - data.channel_id = this.client.channels.resolve(data.channel).id; - data.channel = null; - } - if (data.roles) data.roles = data.roles.map(role => role instanceof Role ? role.id : role); - let endpoint = this.client.api.guilds(this.guild.id); - if (this.user.id === this.client.user.id) { - const keys = Object.keys(data); - if (keys.length === 1 && keys[0] === 'nick') endpoint = endpoint.members('@me').nick; - else endpoint = endpoint.members(this.id); - } else { - endpoint = endpoint.members(this.id); - } - return endpoint.patch({ data, reason }).then(() => { - const clone = this._clone(); - data.user = this.user; - clone._patch(data); - clone._frozenVoiceState = this.voiceState; - if (typeof data.mute !== 'undefined') clone._frozenVoiceState.mute = data.mute; - if (typeof data.deaf !== 'undefined') clone._frozenVoiceState.mute = data.deaf; - if (typeof data.channel_id !== 'undefined') clone._frozenVoiceState.channel_id = data.channel_id; - return clone; - }); - } - - /** - * Mute/unmute a user. - * @param {boolean} mute Whether or not the member should be muted - * @param {string} [reason] Reason for muting or unmuting - * @returns {Promise} - */ - setMute(mute, reason) { - return this.edit({ mute }, reason); - } - - /** - * Deafen/undeafen a user. - * @param {boolean} deaf Whether or not the member should be deafened - * @param {string} [reason] Reason for deafening or undeafening - * @returns {Promise} - */ - setDeaf(deaf, reason) { - return this.edit({ deaf }, reason); - } - - /** - * Moves the guild member to the given channel. - * @param {ChannelResolvable} channel The channel to move the member to - * @returns {Promise} - */ - setVoiceChannel(channel) { - return this.edit({ channel }); - } - - /** - * Sets the roles applied to the member. - * @param {Collection|RoleResolvable[]} roles The roles or role IDs to apply - * @param {string} [reason] Reason for applying the roles - * @returns {Promise} - */ - setRoles(roles, reason) { - return this.edit({ roles }, reason); - } - - /** - * Adds a single role to the member. - * @param {RoleResolvable} role The role or ID of the role to add - * @param {string} [reason] Reason for adding the role - * @returns {Promise} - */ - addRole(role, reason) { - role = this.guild.roles.resolve(role); - if (!role) return Promise.reject(new TypeError('INVALID_TYPE', 'role', 'Role nor a Snowflake')); - if (this._roles.includes(role.id)) return Promise.resolve(this); - return this.client.api.guilds(this.guild.id).members(this.user.id).roles(role.id) - .put({ reason }) - .then(() => { - const clone = this._clone(); - if (!clone._roles.includes(role.id)) clone._roles.push(role.id); - return clone; - }); - } - - /** - * Adds multiple roles to the member. - * @param {Collection|RoleResolvable[]} roles The roles or role IDs to add - * @param {string} [reason] Reason for adding the roles - * @returns {Promise} - */ - addRoles(roles, reason) { - let allRoles = this._roles.slice(); - for (let role of roles instanceof Collection ? roles.values() : roles) { - role = this.guild.roles.resolve(role); - if (!role) { - return Promise.reject(new TypeError('INVALID_TYPE', 'roles', - 'Array or Collection of Roles or Snowflakes', true)); - } - allRoles.push(role.id); - } - return this.edit({ roles: allRoles }, reason); - } - - /** - * Removes a single role from the member. - * @param {RoleResolvable} role The role or ID of the role to remove - * @param {string} [reason] Reason for removing the role - * @returns {Promise} - */ - removeRole(role, reason) { - role = this.guild.roles.resolve(role); - if (!role) return Promise.reject(new TypeError('INVALID_TYPE', 'role', 'Role nor a Snowflake')); - if (!this._roles.includes(role.id)) return Promise.resolve(this); - return this.client.api.guilds(this.guild.id).members(this.user.id).roles(role.id) - .delete({ reason }) - .then(() => { - const clone = this._clone(); - const index = clone._roles.indexOf(role.id); - if (~index) clone._roles.splice(index, 1); - return clone; - }); - } - - /** - * Removes multiple roles from the member. - * @param {Collection|RoleResolvable[]} roles The roles or role IDs to remove - * @param {string} [reason] Reason for removing the roles - * @returns {Promise} - */ - removeRoles(roles, reason) { - const allRoles = this._roles.slice(); - for (let role of roles instanceof Collection ? roles.values() : roles) { - role = this.guild.roles.resolve(role); - if (!role) { - return Promise.reject(new TypeError('INVALID_TYPE', 'roles', - 'Array or Collection of Roles or Snowflakes', true)); - } - const index = allRoles.indexOf(role.id); - if (index >= 0) allRoles.splice(index, 1); - } - return this.edit({ roles: allRoles }, reason); - } - - /** - * Set the nickname for the guild member. - * @param {string} nick The nickname for the guild member - * @param {string} [reason] Reason for setting the nickname - * @returns {Promise} - */ - setNickname(nick, reason) { - return this.edit({ nick }, reason); - } - - /** - * Creates a DM channel between the client and the member. - * @returns {Promise} - */ - createDM() { - return this.user.createDM(); - } - - /** - * Deletes any DMs with this guild member. - * @returns {Promise} - */ - deleteDM() { - return this.user.deleteDM(); - } - - /** - * Kick this member from the guild. - * @param {string} [reason] Reason for kicking user - * @returns {Promise} - */ - kick(reason) { - return this.client.api.guilds(this.guild.id).members(this.user.id).delete({ reason }) - .then(() => - this.client.actions.GuildMemberRemove.handle({ - guild_id: this.guild.id, - user: this.user, - }).member - ); - } - - /** - * Ban this guild member. - * @param {Object|number|string} [options] Ban options. If a number, the number of days to delete messages for, if a - * string, the ban reason. Supplying an object allows you to do both. - * @param {number} [options.days=0] Number of days of messages to delete - * @param {string} [options.reason] Reason for banning - * @returns {Promise} - * @example - * // ban a guild member - * guildMember.ban(7); - */ - ban(options) { - return this.guild.ban(this, options); - } - - /** - * When concatenated with a string, this automatically concatenates the user's mention instead of the Member object. - * @returns {string} - * @example - * // Logs: Hello from <@123456789>! - * console.log(`Hello from ${member}!`); - */ - toString() { - return `<@${this.nickname ? '!' : ''}${this.user.id}>`; - } - - // These are here only for documentation purposes - they are implemented by TextBasedChannel - /* eslint-disable no-empty-function */ - send() {} -} - -TextBasedChannel.applyToClass(GuildMember); - -module.exports = GuildMember; - - /***/ }), /* 19 */ /***/ (function(module, exports, __webpack_require__) { -const { ActivityTypes } = __webpack_require__(0); - -/** - * Represents a user's presence. - */ -class Presence { - constructor(client, data = {}) { - Object.defineProperty(this, 'client', { value: client }); - this.patch(data); - } - - patch(data) { - /** - * The status of the presence: - * - * * **`online`** - user is online - * * **`offline`** - user is offline or invisible - * * **`idle`** - user is AFK - * * **`dnd`** - user is in Do Not Disturb - * @type {string} - */ - this.status = data.status || this.status; - - const activity = data.game || data.activity; - /** - * The activity of the presence - * @type {?Activity} - */ - this.activity = activity ? new Activity(this, activity) : null; - - return this; - } - - _clone() { - const clone = Object.assign(Object.create(this), this); - if (this.activity) clone.activity = this.activity._clone(); - return clone; - } - - /** - * Whether this presence is equal to another - * @param {Presence} presence The presence to compare with - * @returns {boolean} - */ - equals(presence) { - return this === presence || ( - presence && - this.status === presence.status && - this.activity ? this.activity.equals(presence.activity) : !presence.activity - ); - } -} - -/** - * Represents an activity that is part of a user's presence. - */ -class Activity { - constructor(presence, data) { - Object.defineProperty(this, 'presence', { value: presence }); - - /** - * The name of the activity being played - * @type {string} - */ - this.name = data.name; - - /** - * The type of the activity status - * @type {ActivityType} - */ - this.type = ActivityTypes[data.type]; - - /** - * If the activity is being streamed, a link to the stream - * @type {?string} - */ - this.url = data.url || null; - - /** - * Details about the activity - * @type {?string} - */ - this.details = data.details || null; - - /** - * State of the activity - * @type {?string} - */ - this.state = data.state || null; - - /** - * Application ID associated with this activity - * @type {?Snowflake} - */ - this.applicationID = data.application_id || null; - - /** - * Timestamps for the activity - * @type {?Object} - * @prop {?Date} start When the activity started - * @prop {?Date} end When the activity will end - */ - this.timestamps = data.timestamps ? { - start: data.timestamps.start ? new Date(data.timestamps.start) : null, - end: data.timestamps.end ? new Date(data.timestamps.end) : null, - } : null; - - /** - * Party of the activity - * @type {?Object} - * @prop {?string} id ID of the party - * @prop {number[]} size Size of the party as `[current, max]` - */ - this.party = data.party || null; - - /** - * Assets for rich presence - * @type {?RichPresenceAssets} - */ - this.assets = data.assets ? new RichPresenceAssets(this, data.assets) : null; - } - - /** - * Whether this activity is equal to another activity. - * @param {Activity} activity The activity to compare with - * @returns {boolean} - */ - equals(activity) { - return this === activity || ( - activity && - this.name === activity.name && - this.type === activity.type && - this.url === activity.url - ); - } - - _clone() { - return Object.assign(Object.create(this), this); - } -} - -/** - * Assets for a rich presence - */ -class RichPresenceAssets { - constructor(activity, assets) { - Object.defineProperty(this, 'activity', { value: activity }); - - /** - * Hover text for large image - * @type {?string} - */ - this.largeText = assets.large_text || null; - - /** - * Hover text for small image - * @type {?string} - */ - this.smallText = assets.small_text || null; - - /** - * ID of large image asset - * @type {?string} - */ - this.largeImage = assets.large_image || null; - - /** - * ID of small image asset - * @type {?string} - */ - this.smallImage = assets.small_image || null; - } - - /** - * @param {string} format Format of the image - * @param {number} size Size of the iamge - * @returns {?string} small image url - */ - smallImageURL({ format, size } = {}) { - if (!this.smallImage) return null; - return this.activity.presence.client.rest.cdn - .AppAsset(this.activity.applicationID, this.smallImage, { format, size }); - } - - /** - * @param {string} format Format of the image - * @param {number} size Size of the iamge - * @returns {?string} large image url - */ - largeImageURL({ format, size } = {}) { - if (!this.largeImage) return null; - return this.activity.presence.client.rest.cdn - .AppAsset(this.activity.applicationID, this.largeImage, { format, size }); - } -} - -exports.Presence = Presence; -exports.Activity = Activity; -exports.RichPresenceAssets = RichPresenceAssets; - - -/***/ }), -/* 20 */ -/***/ (function(module, exports, __webpack_require__) { - -const MessageAttachment = __webpack_require__(26); -const Util = __webpack_require__(6); -const { RangeError } = __webpack_require__(4); - -/** - * Represents an embed in a message (image/video preview, rich embed, etc.) - */ -class MessageEmbed { - constructor(data = {}) { - this.setup(data); - } - - setup(data) { // eslint-disable-line complexity - /** - * The type of this embed - * @type {string} - */ - this.type = data.type; - - /** - * The title of this embed - * @type {?string} - */ - this.title = data.title; - - /** - * The description of this embed - * @type {?string} - */ - this.description = data.description; - - /** - * The URL of this embed - * @type {?string} - */ - this.url = data.url; - - /** - * The color of the embed - * @type {?number} - */ - this.color = data.color; - - /** - * The timestamp of this embed - * @type {?number} - */ - this.timestamp = data.timestamp ? new Date(data.timestamp).getTime() : null; - - /** - * The fields of this embed - * @type {Object[]} - * @property {string} name The name of this field - * @property {string} value The value of this field - * @property {boolean} inline If this field will be displayed inline - */ - this.fields = data.fields ? data.fields.map(Util.cloneObject) : []; - - /** - * The thumbnail of this embed (if there is one) - * @type {?Object} - * @property {string} url URL for this thumbnail - * @property {string} proxyURL ProxyURL for this thumbnail - * @property {number} height Height of this thumbnail - * @property {number} width Width of this thumbnail - */ - this.thumbnail = data.thumbnail ? { - url: data.thumbnail.url, - proxyURL: data.thumbnail.proxy_url, - height: data.height, - width: data.width, - } : null; - - /** - * The image of this embed, if there is one - * @type {?Object} - * @property {string} url URL for this image - * @property {string} proxyURL ProxyURL for this image - * @property {number} height Height of this image - * @property {number} width Width of this image - */ - this.image = data.image ? { - url: data.image.url, - proxyURL: data.image.proxy_url, - height: data.height, - width: data.width, - } : null; - - /** - * The video of this embed (if there is one) - * @type {?Object} - * @property {string} url URL of this video - * @property {number} height Height of this video - * @property {number} width Width of this video - * @readonly - */ - this.video = data.video; - - /** - * The author of this embed (if there is one) - * @type {?Object} - * @property {string} name The name of this author - * @property {string} url URL of this author - * @property {string} iconURL URL of the icon for this author - * @property {string} proxyIconURL Proxied URL of the icon for this author - */ - this.author = data.author ? { - name: data.author.name, - url: data.author.url, - iconURL: data.author.iconURL || data.author.icon_url, - proxyIconURL: data.author.proxyIconUrl || data.author.proxy_icon_url, - } : null; - - /** - * The provider of this embed (if there is one) - * @type {?Object} - * @property {string} name The name of this provider - * @property {string} url URL of this provider - */ - this.provider = data.provider; - - /** - * The footer of this embed - * @type {?Object} - * @property {string} text The text of this footer - * @property {string} iconURL URL of the icon for this footer - * @property {string} proxyIconURL Proxied URL of the icon for this footer - */ - this.footer = data.footer ? { - text: data.footer.text, - iconURL: data.footer.iconURL || data.footer.icon_url, - proxyIconURL: data.footer.proxyIconURL || data.footer.proxy_icon_url, - } : null; - - /** - * The files of this embed - * @type {?Object} - * @property {Array} files Files to attach - */ - if (data.files) { - this.files = data.files.map(file => { - if (file instanceof MessageAttachment) { - return typeof file.file === 'string' ? file.file : Util.cloneObject(file.file); - } - return file; - }); - } - } - - /** - * The date this embed was created - * @type {?Date} - * @readonly - */ - get createdAt() { - return this.timestamp ? new Date(this.timestamp) : null; - } - - /** - * The hexadecimal version of the embed color, with a leading hash - * @type {string} - * @readonly - */ - get hexColor() { - return this.color ? `#${this.color.toString(16).padStart(6, '0')}` : null; - } - - /** - * Adds a field to the embed (max 25). - * @param {StringResolvable} name The name of the field - * @param {StringResolvable} value The value of the field - * @param {boolean} [inline=false] Set the field to display inline - * @returns {MessageEmbed} - */ - addField(name, value, inline = false) { - if (this.fields.length >= 25) throw new RangeError('EMBED_FIELD_COUNT'); - name = Util.resolveString(name); - if (!String(name) || name.length > 256) throw new RangeError('EMBED_FIELD_NAME'); - value = Util.resolveString(value); - if (!String(value) || value.length > 1024) throw new RangeError('EMBED_FIELD_VALUE'); - this.fields.push({ name, value, inline }); - return this; - } - - /** - * Convenience function for `.addField('\u200B', '\u200B', inline)`. - * @param {boolean} [inline=false] Set the field to display inline - * @returns {MessageEmbed} - */ - addBlankField(inline = false) { - return this.addField('\u200B', '\u200B', inline); - } - - /** - * Sets the file to upload alongside the embed. This file can be accessed via `attachment://fileName.extension` when - * setting an embed image or author/footer icons. Only one file may be attached. - * @param {Array} files Files to attach - * @returns {MessageEmbed} - */ - attachFiles(files) { - if (this.files) this.files = this.files.concat(files); - else this.files = files; - for (let file of files) { - if (file instanceof MessageAttachment) file = file.file; - } - return this; - } - - /** - * Sets the author of this embed. - * @param {StringResolvable} name The name of the author - * @param {string} [iconURL] The icon URL of the author - * @param {string} [url] The URL of the author - * @returns {MessageEmbed} - */ - setAuthor(name, iconURL, url) { - this.author = { name: Util.resolveString(name), iconURL, url }; - return this; - } - - /** - * Sets the color of this embed. - * @param {ColorResolvable} color The color of the embed - * @returns {MessageEmbed} - */ - setColor(color) { - this.color = Util.resolveColor(color); - return this; - } - - /** - * Sets the description of this embed. - * @param {StringResolvable} description The description - * @returns {MessageEmbed} - */ - setDescription(description) { - description = Util.resolveString(description); - if (description.length > 2048) throw new RangeError('EMBED_DESCRIPTION'); - this.description = description; - return this; - } - - /** - * Sets the footer of this embed. - * @param {StringResolvable} text The text of the footer - * @param {string} [iconURL] The icon URL of the footer - * @returns {MessageEmbed} - */ - setFooter(text, iconURL) { - text = Util.resolveString(text); - if (text.length > 2048) throw new RangeError('EMBED_FOOTER_TEXT'); - this.footer = { text, iconURL }; - return this; - } - - /** - * Set the image of this embed. - * @param {string} url The URL of the image - * @returns {MessageEmbed} - */ - setImage(url) { - this.image = { url }; - return this; - } - - /** - * Set the thumbnail of this embed. - * @param {string} url The URL of the thumbnail - * @returns {MessageEmbed} - */ - setThumbnail(url) { - this.thumbnail = { url }; - return this; - } - - /** - * Sets the timestamp of this embed. - * @param {Date} [timestamp=current date] The timestamp - * @returns {MessageEmbed} - */ - setTimestamp(timestamp = new Date()) { - this.timestamp = timestamp.getTime(); - return this; - } - - /** - * Sets the title of this embed. - * @param {StringResolvable} title The title - * @returns {MessageEmbed} - */ - setTitle(title) { - title = Util.resolveString(title); - if (title.length > 256) throw new RangeError('EMBED_TITLE'); - this.title = title; - return this; - } - - /** - * Sets the URL of this embed. - * @param {string} url The URL - * @returns {MessageEmbed} - */ - setURL(url) { - this.url = url; - return this; - } - - /** - * Transforms the embed object to be processed. - * @returns {Object} The raw data of this embed - * @private - */ - _apiTransform() { - return { - title: this.title, - type: 'rich', - description: this.description, - url: this.url, - timestamp: this.timestamp ? new Date(this.timestamp) : null, - color: this.color, - fields: this.fields, - files: this.files, - thumbnail: this.thumbnail, - image: this.image, - author: this.author ? { - name: this.author.name, - url: this.author.url, - icon_url: this.author.iconURL, - } : null, - footer: this.footer ? { - text: this.footer.text, - icon_url: this.footer.iconURL, - } : null, - }; - } -} - -module.exports = MessageEmbed; - - -/***/ }), -/* 21 */ -/***/ (function(module, exports, __webpack_require__) { - -const Channel = __webpack_require__(17); -const Role = __webpack_require__(32); -const Invite = __webpack_require__(33); -const PermissionOverwrites = __webpack_require__(70); -const Util = __webpack_require__(6); -const Permissions = __webpack_require__(12); +/* WEBPACK VAR INJECTION */(function(Buffer) {const path = __webpack_require__(33); +const MessageCollector = __webpack_require__(44); +const Shared = __webpack_require__(45); +const Snowflake = __webpack_require__(6); const Collection = __webpack_require__(3); -const { MessageNotificationTypes } = __webpack_require__(0); -const { Error, TypeError } = __webpack_require__(4); - -/** - * Represents a guild channel (e.g. text channels and voice channels). - * @extends {Channel} - */ -class GuildChannel extends Channel { - constructor(guild, data) { - super(guild.client, data); - - /** - * The guild the channel is in - * @type {Guild} - */ - this.guild = guild; - } - - _patch(data) { - super._patch(data); - - /** - * The name of the guild channel - * @type {string} - */ - this.name = data.name; - - /** - * The raw position of the channel from discord - * @type {number} - */ - this.rawPosition = data.position; - - /** - * The ID of the category parent of this channel - * @type {?Snowflake} - */ - this.parentID = data.parent_id; - - /** - * A map of permission overwrites in this channel for roles and users - * @type {Collection} - */ - this.permissionOverwrites = new Collection(); - if (data.permission_overwrites) { - for (const overwrite of data.permission_overwrites) { - this.permissionOverwrites.set(overwrite.id, new PermissionOverwrites(this, overwrite)); - } - } - } - - /** - * The category parent of this channel - * @type {?CategoryChannel} - * @readonly - */ - get parent() { - return this.guild.channels.get(this.parentID); - } - - /** - * If the permissionOverwrites match the parent channel, null if no parent - * @type {?boolean} - * @readonly - */ - get permissionsLocked() { - if (!this.parent) return null; - if (this.permissionOverwrites.size !== this.parent.permissionOverwrites.size) return false; - return !this.permissionOverwrites.find((value, key) => { - const testVal = this.parent.permissionOverwrites.get(key); - return testVal === undefined || - testVal.denied.bitfield !== value.denied.bitfield || - testVal.allowed.bitfield !== value.allowed.bitfield; - }); - } - - /** - * The position of the channel - * @type {number} - * @readonly - */ - get position() { - const sorted = this.guild._sortedChannels(this); - return sorted.array().indexOf(sorted.get(this.id)); - } - - /** - * Gets the overall set of permissions for a user in this channel, taking into account roles and permission - * overwrites. - * @param {GuildMemberResolvable} member The user that you want to obtain the overall permissions for - * @returns {?Permissions} - */ - permissionsFor(member) { - member = this.guild.members.resolve(member); - if (!member) return null; - if (member.id === this.guild.ownerID) return new Permissions(Permissions.ALL).freeze(); - - const roles = member.roles; - const permissions = new Permissions(roles.map(role => role.permissions)); - - if (permissions.has(Permissions.FLAGS.ADMINISTRATOR)) return new Permissions(Permissions.ALL).freeze(); - - const overwrites = this.overwritesFor(member, true, roles); - - return permissions - .remove(overwrites.everyone ? overwrites.everyone.denied : 0) - .add(overwrites.everyone ? overwrites.everyone.allowed : 0) - .remove(overwrites.roles.length > 0 ? overwrites.roles.map(role => role.denied) : 0) - .add(overwrites.roles.length > 0 ? overwrites.roles.map(role => role.allowed) : 0) - .remove(overwrites.member ? overwrites.member.denied : 0) - .add(overwrites.member ? overwrites.member.allowed : 0) - .freeze(); - } - - overwritesFor(member, verified = false, roles = null) { - if (!verified) member = this.guild.members.resolve(member); - if (!member) return []; - - roles = roles || member.roles; - const roleOverwrites = []; - let memberOverwrites; - let everyoneOverwrites; - - for (const overwrite of this.permissionOverwrites.values()) { - if (overwrite.id === this.guild.id) { - everyoneOverwrites = overwrite; - } else if (roles.has(overwrite.id)) { - roleOverwrites.push(overwrite); - } else if (overwrite.id === member.id) { - memberOverwrites = overwrite; - } - } - - return { - everyone: everyoneOverwrites, - roles: roleOverwrites, - member: memberOverwrites, - }; - } - - /** - * An object mapping permission flags to `true` (enabled), `null` (default) or `false` (disabled). - * ```js - * { - * 'SEND_MESSAGES': true, - * 'EMBED_LINKS': null, - * 'ATTACH_FILES': false, - * } - * ``` - * @typedef {Object} PermissionOverwriteOptions - */ - - /** - * Overwrites the permissions for a user or role in this channel. - * @param {RoleResolvable|UserResolvable} userOrRole The user or role to update - * @param {PermissionOverwriteOptions} options The configuration for the update - * @param {string} [reason] Reason for creating/editing this overwrite - * @returns {Promise} - * @example - * // Overwrite permissions for a message author - * message.channel.overwritePermissions(message.author, { - * SEND_MESSAGES: false - * }) - * .then(() => console.log('Done!')) - * .catch(console.error); - */ - overwritePermissions(userOrRole, options, reason) { - const allow = new Permissions(0); - const deny = new Permissions(0); - let type; - - const role = this.guild.roles.get(userOrRole); - - if (role || userOrRole instanceof Role) { - userOrRole = role || userOrRole; - type = 'role'; - } else { - userOrRole = this.client.users.resolve(userOrRole); - type = 'member'; - if (!userOrRole) return Promise.reject(new TypeError('INVALID_TYPE', 'parameter', 'User nor a Role', true)); - } - - const prevOverwrite = this.permissionOverwrites.get(userOrRole.id); - - if (prevOverwrite) { - allow.add(prevOverwrite.allowed); - deny.add(prevOverwrite.denied); - } - - for (const perm in options) { - if (options[perm] === true) { - allow.add(Permissions.FLAGS[perm] || 0); - deny.remove(Permissions.FLAGS[perm] || 0); - } else if (options[perm] === false) { - allow.remove(Permissions.FLAGS[perm] || 0); - deny.add(Permissions.FLAGS[perm] || 0); - } else if (options[perm] === null) { - allow.remove(Permissions.FLAGS[perm] || 0); - deny.remove(Permissions.FLAGS[perm] || 0); - } - } - - return this.client.api.channels(this.id).permissions[userOrRole.id] - .put({ data: { id: userOrRole.id, type, allow: allow.bitfield, deny: deny.bitfield }, reason }) - .then(() => this); - } - - /** - * Locks in the permission overwrites from the parent channel. - * @returns {Promise} - */ - lockPermissions() { - if (!this.parent) return Promise.reject(new Error('GUILD_CHANNEL_ORPHAN')); - const permissionOverwrites = this.parent.permissionOverwrites.map(overwrite => ({ - deny: overwrite.denied.bitfield, - allow: overwrite.allowed.bitfield, - id: overwrite.id, - type: overwrite.type, - })); - return this.edit({ permissionOverwrites }); - } - - /** - * A collection of members that can see this channel, mapped by their ID - * @type {Collection} - * @readonly - */ - get members() { - const members = new Collection(); - for (const member of this.guild.members.values()) { - if (this.permissionsFor(member).has('VIEW_CHANNEL')) { - members.set(member.id, member); - } - } - return members; - } - - /** - * The data for a guild channel. - * @typedef {Object} ChannelData - * @property {string} [name] The name of the channel - * @property {number} [position] The position of the channel - * @property {string} [topic] The topic of the text channel - * @property {number} [bitrate] The bitrate of the voice channel - * @property {number} [userLimit] The user limit of the voice channel - * @property {Snowflake} [parentID] The parent ID of the channel - * @property {boolean} [lockPermissions] Lock the permissions of the channel to what the parent's permissions are - * @property {OverwriteData[]} [permissionOverwrites] An array of overwrites to set for the channel - */ - - /** - * The data for a permission overwrite - * @typedef {Object} OverwriteData - * @property {string} id The id of the overwrite - * @property {string} type The type of the overwrite, either role or member - * @property {number} allow The bitfield for the allowed permissions - * @property {number} deny The bitfield for the denied permissions - */ - - /** - * Edits the channel. - * @param {ChannelData} data The new data for the channel - * @param {string} [reason] Reason for editing this channel - * @returns {Promise} - * @example - * // Edit a channel - * channel.edit({name: 'new-channel'}) - * .then(c => console.log(`Edited channel ${c}`)) - * .catch(console.error); - */ - edit(data, reason) { - return this.client.api.channels(this.id).patch({ - data: { - name: (data.name || this.name).trim(), - topic: data.topic, - position: data.position || this.rawPosition, - bitrate: data.bitrate || (this.bitrate ? this.bitrate * 1000 : undefined), - user_limit: data.userLimit != null ? data.userLimit : this.userLimit, // eslint-disable-line eqeqeq - parent_id: data.parentID, - lock_permissions: data.lockPermissions, - permission_overwrites: data.permissionOverwrites, - }, - reason, - }).then(newData => { - const clone = this._clone(); - clone._patch(newData); - return clone; - }); - } - - /** - * Set a new name for the guild channel. - * @param {string} name The new name for the guild channel - * @param {string} [reason] Reason for changing the guild channel's name - * @returns {Promise} - * @example - * // Set a new channel name - * channel.setName('not_general') - * .then(newChannel => console.log(`Channel's new name is ${newChannel.name}`)) - * .catch(console.error); - */ - setName(name, reason) { - return this.edit({ name }, reason); - } - - /** - * Set the category parent of this channel. - * @param {GuildChannel|Snowflake} channel Parent channel - * @param {boolean} [options.lockPermissions] Lock the permissions to what the parent's permissions are - * @param {string} [options.reason] Reason for modifying the parent of this channel - * @returns {Promise} - */ - setParent(channel, { lockPermissions = true, reason } = {}) { - return this.edit({ - parentID: channel.id ? channel.id : channel, - lockPermissions, - }, reason); - } - - /** - * Set a new topic for the guild channel. - * @param {string} topic The new topic for the guild channel - * @param {string} [reason] Reason for changing the guild channel's topic - * @returns {Promise} - * @example - * // Set a new channel topic - * channel.setTopic('needs more rate limiting') - * .then(newChannel => console.log(`Channel's new topic is ${newChannel.topic}`)) - * .catch(console.error); - */ - setTopic(topic, reason) { - return this.edit({ topic }, reason); - } - - /** - * Set a new position for the guild channel. - * @param {number} position The new position for the guild channel - * @param {Object} [options] Options for setting position - * @param {boolean} [options.relative=false] Change the position relative to its current value - * @param {boolean} [options.reason] Reasion for changing the position - * @returns {Promise} - * @example - * // Set a new channel position - * channel.setPosition(2) - * .then(newChannel => console.log(`Channel's new position is ${newChannel.position}`)) - * .catch(console.error); - */ - setPosition(position, { relative, reason } = {}) { - return Util.setPosition(this, position, relative, - this.guild._sortedChannels(this), this.client.api.guilds(this.guild.id).channels, reason) - .then(updatedChannels => { - this.client.actions.GuildChannelsPositionUpdate.handle({ - guild_id: this.id, - channels: updatedChannels, - }); - return this; - }); - } - - /** - * Create an invite to this guild channel. - * @param {Object} [options={}] Options for the invite - * @param {boolean} [options.temporary=false] Whether members that joined via the invite should be automatically - * kicked after 24 hours if they have not yet received a role - * @param {number} [options.maxAge=86400] How long the invite should last (in seconds, 0 for forever) - * @param {number} [options.maxUses=0] Maximum number of uses - * @param {boolean} [options.unique=false] Create a unique invite, or use an existing one with similar settings - * @param {string} [options.reason] Reason for creating this - * @returns {Promise} - */ - createInvite({ temporary = false, maxAge = 86400, maxUses = 0, unique, reason } = {}) { - return this.client.api.channels(this.id).invites.post({ data: { - temporary, max_age: maxAge, max_uses: maxUses, unique, - }, reason }) - .then(invite => new Invite(this.client, invite)); - } - - /** - * Clone this channel. - * @param {Object} [options] The options - * @param {string} [options.name=this.name] Optional name for the new channel, otherwise it has the name - * of this channel - * @param {boolean} [options.withPermissions=true] Whether to clone the channel with this channel's - * permission overwrites - * @param {boolean} [options.withTopic=true] Whether to clone the channel with this channel's topic - * @param {string} [options.reason] Reason for cloning this channel - * @returns {Promise} - */ - clone({ name = this.name, withPermissions = true, withTopic = true, reason } = {}) { - const options = { overwrites: withPermissions ? this.permissionOverwrites : [], reason }; - return this.guild.createChannel(name, this.type, options) - .then(channel => withTopic ? channel.setTopic(this.topic) : channel); - } - - /** - * Checks if this channel has the same type, topic, position, name, overwrites and ID as another channel. - * In most cases, a simple `channel.id === channel2.id` will do, and is much faster too. - * @param {GuildChannel} channel Channel to compare with - * @returns {boolean} - */ - equals(channel) { - let equal = channel && - this.id === channel.id && - this.type === channel.type && - this.topic === channel.topic && - this.position === channel.position && - this.name === channel.name; - - if (equal) { - if (this.permissionOverwrites && channel.permissionOverwrites) { - equal = this.permissionOverwrites.equals(channel.permissionOverwrites); - } else { - equal = !this.permissionOverwrites && !channel.permissionOverwrites; - } - } - - return equal; - } - - /** - * Whether the channel is deletable by the client user - * @type {boolean} - * @readonly - */ - get deletable() { - return this.permissionsFor(this.client.user).has(Permissions.FLAGS.MANAGE_CHANNELS); - } - - /** - * Deletes this channel. - * @param {string} [reason] Reason for deleting this channel - * @returns {Promise} - * @example - * // Delete the channel - * channel.delete('making room for new channels') - * .then() // Success - * .catch(console.error); // Log error - */ - delete(reason) { - return this.client.api.channels(this.id).delete({ reason }).then(() => this); - } - - /** - * Whether the channel is muted - * This is only available when using a user account. - * @type {?boolean} - * @readonly - */ - get muted() { - if (this.client.user.bot) return null; - try { - return this.client.user.guildSettings.get(this.guild.id).channelOverrides.get(this.id).muted; - } catch (err) { - return false; - } - } - - /** - * The type of message that should notify you - * one of `EVERYTHING`, `MENTIONS`, `NOTHING`, `INHERIT` - * This is only available when using a user account. - * @type {?string} - * @readonly - */ - get messageNotifications() { - if (this.client.user.bot) return null; - try { - return this.client.user.guildSettings.get(this.guild.id).channelOverrides.get(this.id).messageNotifications; - } catch (err) { - return MessageNotificationTypes[3]; - } - } - - /** - * When concatenated with a string, this automatically returns the channel's mention instead of the Channel object. - * @returns {string} - * @example - * // Outputs: Hello from #general - * console.log(`Hello from ${channel}`); - * @example - * // Outputs: Hello from #general - * console.log('Hello from ' + channel); - */ - toString() { - return `<#${this.id}>`; - } -} - -module.exports = GuildChannel; - - -/***/ }), -/* 22 */ -/***/ (function(module, exports, __webpack_require__) { - -/* WEBPACK VAR INJECTION */(function(Buffer) {const path = __webpack_require__(29); -const Util = __webpack_require__(6); -const DataResolver = __webpack_require__(13); -const Embed = __webpack_require__(20); -const MessageAttachment = __webpack_require__(26); -const MessageEmbed = __webpack_require__(20); - -/** - * Represents a webhook. - */ -class Webhook { - constructor(client, data) { - /** - * The client that instantiated the webhook - * @name Webhook#client - * @type {Client} - * @readonly - */ - Object.defineProperty(this, 'client', { value: client }); - if (data) this._patch(data); - } - - _patch(data) { - /** - * The name of the webhook - * @type {string} - */ - this.name = data.name; - - /** - * The token for the webhook - * @type {string} - */ - this.token = data.token; - - /** - * The avatar for the webhook - * @type {?string} - */ - this.avatar = data.avatar; - - /** - * The ID of the webhook - * @type {Snowflake} - */ - this.id = data.id; - - /** - * The guild the webhook belongs to - * @type {Snowflake} - */ - this.guildID = data.guild_id; - - /** - * The channel the webhook belongs to - * @type {Snowflake} - */ - this.channelID = data.channel_id; - - if (data.user) { - /** - * The owner of the webhook - * @type {?User|Object} - */ - this.owner = this.client.users ? this.client.users.get(data.user.id) : data.user; - } else { - this.owner = null; - } - } - - /** - * Options that can be passed into send. - * @typedef {Object} WebhookMessageOptions - * @property {string} [username=this.name] Username override for the message - * @property {string} [avatarURL] Avatar URL override for the message - * @property {boolean} [tts=false] Whether or not the message should be spoken aloud - * @property {string} [nonce=''] The nonce for the message - * @property {Object[]} [embeds] An array of embeds for the message - * (see [here](https://discordapp.com/developers/docs/resources/channel#embed-object) for more details) - * @property {boolean} [disableEveryone=this.client.options.disableEveryone] Whether or not @everyone and @here - * should be replaced with plain-text - * @property {FileOptions|BufferResolvable} [file] A file to send with the message - * @property {FileOptions[]|string[]} [files] Files to send with the message - * @property {string|boolean} [code] Language for optional codeblock formatting to apply - * @property {boolean|SplitOptions} [split=false] Whether or not the message should be split into multiple messages if - * it exceeds the character limit. If an object is provided, these are the options for splitting the message. - */ - - /* eslint-disable max-len */ - /** - * Send a message with this webhook. - * @param {StringResolvable} [content] The content to send - * @param {WebhookMessageOptions|MessageEmbed|MessageAttachment|MessageAttachment[]} [options={}] The options to provide - * @returns {Promise} - * @example - * // Send a message - * webhook.send('hello!') - * .then(message => console.log(`Sent message: ${message.content}`)) - * .catch(console.error); - */ - /* eslint-enable max-len */ - send(content, options) { // eslint-disable-line complexity - if (!options && typeof content === 'object' && !(content instanceof Array)) { - options = content; - content = ''; - } else if (!options) { - options = {}; - } - - if (options instanceof MessageAttachment) options = { files: [options.file] }; - if (options instanceof MessageEmbed) options = { embeds: [options] }; - if (options.embed) options = { embeds: [options.embed] }; - - if (content instanceof Array || options instanceof Array) { - const which = content instanceof Array ? content : options; - const attachments = which.filter(item => item instanceof MessageAttachment); - const embeds = which.filter(item => item instanceof MessageEmbed); - if (attachments.length) options = { files: attachments }; - if (embeds.length) options = { embeds }; - if ((embeds.length || attachments.length) && content instanceof Array) content = ''; - } - - if (!options.username) options.username = this.name; - if (options.avatarURL) { - options.avatar_url = options.avatarURL; - options.avatarURL = null; - } - - if (content) { - content = Util.resolveString(content); - let { split, code, disableEveryone } = options; - if (split && typeof split !== 'object') split = {}; - if (typeof code !== 'undefined' && (typeof code !== 'boolean' || code === true)) { - content = Util.escapeMarkdown(content, true); - content = `\`\`\`${typeof code !== 'boolean' ? code || '' : ''}\n${content}\n\`\`\``; - if (split) { - split.prepend = `\`\`\`${typeof code !== 'boolean' ? code || '' : ''}\n`; - split.append = '\n```'; - } - } - if (disableEveryone || (typeof disableEveryone === 'undefined' && this.client.options.disableEveryone)) { - content = content.replace(/@(everyone|here)/g, '@\u200b$1'); - } - - if (split) content = Util.splitMessage(content, split); - } - options.content = content; - - if (options.embeds) options.embeds = options.embeds.map(embed => new Embed(embed)._apiTransform()); - - if (options.files) { - for (let i = 0; i < options.files.length; i++) { - let file = options.files[i]; - if (typeof file === 'string' || Buffer.isBuffer(file)) file = { attachment: file }; - if (!file.name) { - if (typeof file.attachment === 'string') { - file.name = path.basename(file.attachment); - } else if (file.attachment && file.attachment.path) { - file.name = path.basename(file.attachment.path); - } else if (file instanceof MessageAttachment) { - file = { attachment: file.file, name: path.basename(file.file) || 'file.jpg' }; - } else { - file.name = 'file.jpg'; - } - } else if (file instanceof MessageAttachment) { - file = file.file; - } - options.files[i] = file; - } - - return Promise.all(options.files.map(file => - DataResolver.resolveFile(file.attachment, this.client.browser).then(resource => { - file.file = resource; - return file; - }) - )).then(files => this.client.api.webhooks(this.id, this.token).post({ - data: options, - query: { wait: true }, - files, - auth: false, - })); - } - - if (content instanceof Array) { - return new Promise((resolve, reject) => { - const messages = []; - (function sendChunk() { - const opt = content.length ? null : { embeds: options.embeds, files: options.files }; - this.client.api.webhooks(this.id, this.token).post({ - data: { content: content.shift(), opt }, - query: { wait: true }, - auth: false, - }) - .then(message => { - messages.push(message); - if (content.length === 0) return resolve(messages); - return sendChunk.call(this); - }) - .catch(reject); - }.call(this)); - }); - } - - return this.client.api.webhooks(this.id, this.token).post({ - data: options, - query: { wait: true }, - auth: false, - }).then(data => { - if (!this.client.channels) return data; - return this.client.channels.get(data.channel_id).messages.create(data, false); - }); - } - - /** - * Send a raw slack message with this webhook. - * @param {Object} body The raw body to send - * @returns {Promise} - * @example - * // Send a slack message - * webhook.sendSlackMessage({ - * 'username': 'Wumpus', - * 'attachments': [{ - * 'pretext': 'this looks pretty cool', - * 'color': '#F0F', - * 'footer_icon': 'http://snek.s3.amazonaws.com/topSnek.png', - * 'footer': 'Powered by sneks', - * 'ts': Date.now() / 1000 - * }] - * }).catch(console.error); - */ - sendSlackMessage(body) { - return this.client.api.webhooks(this.id, this.token).slack.post({ - query: { wait: true }, - auth: false, - data: body, - }).then(data => { - if (!this.client.channels) return data; - return this.client.channels.get(data.channel_id).messages.create(data, false); - }); - } - - /** - * Edit the webhook. - * @param {Object} options Options - * @param {string} [options.name=this.name] New name for this webhook - * @param {BufferResolvable} [options.avatar] New avatar for this webhook - * @param {string} [reason] Reason for editing this webhook - * @returns {Promise} - */ - edit({ name = this.name, avatar }, reason) { - if (avatar && (typeof avatar === 'string' && !avatar.startsWith('data:'))) { - return DataResolver.resolveImage(avatar, this.client.browser).then(image => - this.edit({ name, avatar: image }, reason) - ); - } - return this.client.api.webhooks(this.id, this.token).patch({ - data: { name, avatar }, - reason, - }).then(data => { - this.name = data.name; - this.avatar = data.avatar; - return this; - }); - } - - /** - * Delete the webhook. - * @param {string} [reason] Reason for deleting this webhook - * @returns {Promise} - */ - delete(reason) { - return this.client.api.webhooks(this.id, this.token).delete({ reason }); - } - - static applyToClass(structure) { - for (const prop of [ - 'send', - 'sendSlackMessage', - 'edit', - 'delete', - ]) { - Object.defineProperty(structure.prototype, prop, - Object.getOwnPropertyDescriptor(Webhook.prototype, prop)); - } - } -} - -module.exports = Webhook; - -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(5).Buffer)) - -/***/ }), -/* 23 */ -/***/ (function(module, exports, __webpack_require__) { - -exports = module.exports = __webpack_require__(49); -exports.Stream = exports; -exports.Readable = exports; -exports.Writable = __webpack_require__(38); -exports.Duplex = __webpack_require__(16); -exports.Transform = __webpack_require__(53); -exports.PassThrough = __webpack_require__(88); - - -/***/ }), -/* 24 */ -/***/ (function(module, exports, __webpack_require__) { - -/* WEBPACK VAR INJECTION */(function(Buffer) {// Copyright Joyent, Inc. and other Node contributors. -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to permit -// persons to whom the Software is furnished to do so, subject to the -// following conditions: -// -// The above copyright notice and this permission notice shall be included -// in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN -// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE -// USE OR OTHER DEALINGS IN THE SOFTWARE. - -// NOTE: These type checking functions intentionally don't use `instanceof` -// because it is fragile and can be easily faked with `Object.create()`. - -function isArray(arg) { - if (Array.isArray) { - return Array.isArray(arg); - } - return objectToString(arg) === '[object Array]'; -} -exports.isArray = isArray; - -function isBoolean(arg) { - return typeof arg === 'boolean'; -} -exports.isBoolean = isBoolean; - -function isNull(arg) { - return arg === null; -} -exports.isNull = isNull; - -function isNullOrUndefined(arg) { - return arg == null; -} -exports.isNullOrUndefined = isNullOrUndefined; - -function isNumber(arg) { - return typeof arg === 'number'; -} -exports.isNumber = isNumber; - -function isString(arg) { - return typeof arg === 'string'; -} -exports.isString = isString; - -function isSymbol(arg) { - return typeof arg === 'symbol'; -} -exports.isSymbol = isSymbol; - -function isUndefined(arg) { - return arg === void 0; -} -exports.isUndefined = isUndefined; - -function isRegExp(re) { - return objectToString(re) === '[object RegExp]'; -} -exports.isRegExp = isRegExp; - -function isObject(arg) { - return typeof arg === 'object' && arg !== null; -} -exports.isObject = isObject; - -function isDate(d) { - return objectToString(d) === '[object Date]'; -} -exports.isDate = isDate; - -function isError(e) { - return (objectToString(e) === '[object Error]' || e instanceof Error); -} -exports.isError = isError; - -function isFunction(arg) { - return typeof arg === 'function'; -} -exports.isFunction = isFunction; - -function isPrimitive(arg) { - return arg === null || - typeof arg === 'boolean' || - typeof arg === 'number' || - typeof arg === 'string' || - typeof arg === 'symbol' || // ES6 symbol - typeof arg === 'undefined'; -} -exports.isPrimitive = isPrimitive; - -exports.isBuffer = Buffer.isBuffer; - -function objectToString(o) { - return Object.prototype.toString.call(o); -} - -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(5).Buffer)) - -/***/ }), -/* 25 */ -/***/ (function(module, exports, __webpack_require__) { - -/* WEBPACK VAR INJECTION */(function(Buffer) {const path = __webpack_require__(29); -const MessageCollector = __webpack_require__(62); -const Shared = __webpack_require__(63); -const Snowflake = __webpack_require__(9); -const Collection = __webpack_require__(3); -const DataResolver = __webpack_require__(13); -const MessageAttachment = __webpack_require__(26); -const MessageEmbed = __webpack_require__(20); +const DataResolver = __webpack_require__(10); +const MessageAttachment = __webpack_require__(20); +const MessageEmbed = __webpack_require__(14); const { RangeError, TypeError } = __webpack_require__(4); /** @@ -7062,12 +6441,12 @@ class TextBasedChannel { module.exports = TextBasedChannel; // Fixes Circular -const MessageStore = __webpack_require__(31); +const MessageStore = __webpack_require__(23); -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(5).Buffer)) +/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(17).Buffer)) /***/ }), -/* 26 */ +/* 20 */ /***/ (function(module, exports) { /** @@ -7186,72 +6565,10 @@ module.exports = MessageAttachment; /***/ }), -/* 27 */ -/***/ (function(module, exports, __webpack_require__) { +/* 21 */ +/***/ (function(module, exports) { -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) { - -if (!process.version || - process.version.indexOf('v0.') === 0 || - process.version.indexOf('v1.') === 0 && process.version.indexOf('v1.8.') !== 0) { - module.exports = nextTick; -} else { - module.exports = process.nextTick; -} - -function nextTick(fn, arg1, arg2, arg3) { - if (typeof fn !== 'function') { - throw new TypeError('"callback" argument must be a function'); - } - var len = arguments.length; - var args, i; - switch (len) { - case 0: - case 1: - return process.nextTick(fn); - case 2: - return process.nextTick(function afterTickOne() { - fn.call(null, arg1); - }); - case 3: - return process.nextTick(function afterTickTwo() { - fn.call(null, arg1, arg2); - }); - case 4: - return process.nextTick(function afterTickThree() { - fn.call(null, arg1, arg2, arg3); - }); - default: - args = new Array(len - 1); - i = 0; - while (i < args.length) { - args[i++] = arguments[i]; - } - return process.nextTick(function afterTick() { - fn.apply(null, args); - }); - } -} - -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(8))) - -/***/ }), -/* 28 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -exports.decode = exports.parse = __webpack_require__(93); -exports.encode = exports.stringify = __webpack_require__(94); - - -/***/ }), -/* 29 */ -/***/ (function(module, exports, __webpack_require__) { - -/* WEBPACK VAR INJECTION */(function(process) {// Copyright Joyent, Inc. and other Node contributors. +// Copyright Joyent, Inc. and other Node contributors. // // Permission is hereby granted, free of charge, to any person obtaining a // copy of this software and associated documentation files (the @@ -7272,221 +6589,298 @@ exports.encode = exports.stringify = __webpack_require__(94); // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE // USE OR OTHER DEALINGS IN THE SOFTWARE. -// resolves . and .. elements in a path array with directory names there -// must be no slashes, empty elements, or device names (c:\) in the array -// (so also no leading and trailing slashes - it does not distinguish -// relative and absolute paths) -function normalizeArray(parts, allowAboveRoot) { - // if the path tries to go above the root, `up` ends up > 0 - var up = 0; - for (var i = parts.length - 1; i >= 0; i--) { - var last = parts[i]; - if (last === '.') { - parts.splice(i, 1); - } else if (last === '..') { - parts.splice(i, 1); - up++; - } else if (up) { - parts.splice(i, 1); - up--; +function EventEmitter() { + this._events = this._events || {}; + this._maxListeners = this._maxListeners || undefined; +} +module.exports = EventEmitter; + +// Backwards-compat with node 0.10.x +EventEmitter.EventEmitter = EventEmitter; + +EventEmitter.prototype._events = undefined; +EventEmitter.prototype._maxListeners = undefined; + +// By default EventEmitters will print a warning if more than 10 listeners are +// added to it. This is a useful default which helps finding memory leaks. +EventEmitter.defaultMaxListeners = 10; + +// Obviously not all Emitters should be limited to 10. This function allows +// that to be increased. Set to zero for unlimited. +EventEmitter.prototype.setMaxListeners = function(n) { + if (!isNumber(n) || n < 0 || isNaN(n)) + throw TypeError('n must be a positive number'); + this._maxListeners = n; + return this; +}; + +EventEmitter.prototype.emit = function(type) { + var er, handler, len, args, i, listeners; + + if (!this._events) + this._events = {}; + + // If there is no 'error' event listener then throw. + if (type === 'error') { + if (!this._events.error || + (isObject(this._events.error) && !this._events.error.length)) { + er = arguments[1]; + if (er instanceof Error) { + throw er; // Unhandled 'error' event + } else { + // At least give some kind of context to the user + var err = new Error('Uncaught, unspecified "error" event. (' + er + ')'); + err.context = er; + throw err; + } } } - // if the path is allowed to go above the root, restore leading ..s - if (allowAboveRoot) { - for (; up--; up) { - parts.unshift('..'); + handler = this._events[type]; + + if (isUndefined(handler)) + return false; + + if (isFunction(handler)) { + switch (arguments.length) { + // fast cases + case 1: + handler.call(this); + break; + case 2: + handler.call(this, arguments[1]); + break; + case 3: + handler.call(this, arguments[1], arguments[2]); + break; + // slower + default: + args = Array.prototype.slice.call(arguments, 1); + handler.apply(this, args); + } + } else if (isObject(handler)) { + args = Array.prototype.slice.call(arguments, 1); + listeners = handler.slice(); + len = listeners.length; + for (i = 0; i < len; i++) + listeners[i].apply(this, args); + } + + return true; +}; + +EventEmitter.prototype.addListener = function(type, listener) { + var m; + + if (!isFunction(listener)) + throw TypeError('listener must be a function'); + + if (!this._events) + this._events = {}; + + // To avoid recursion in the case that type === "newListener"! Before + // adding it to the listeners, first emit "newListener". + if (this._events.newListener) + this.emit('newListener', type, + isFunction(listener.listener) ? + listener.listener : listener); + + if (!this._events[type]) + // Optimize the case of one listener. Don't need the extra array object. + this._events[type] = listener; + else if (isObject(this._events[type])) + // If we've already got an array, just append. + this._events[type].push(listener); + else + // Adding the second element, need to change to array. + this._events[type] = [this._events[type], listener]; + + // Check for listener leak + if (isObject(this._events[type]) && !this._events[type].warned) { + if (!isUndefined(this._maxListeners)) { + m = this._maxListeners; + } else { + m = EventEmitter.defaultMaxListeners; + } + + if (m && m > 0 && this._events[type].length > m) { + this._events[type].warned = true; + console.error('(node) warning: possible EventEmitter memory ' + + 'leak detected. %d listeners added. ' + + 'Use emitter.setMaxListeners() to increase limit.', + this._events[type].length); + if (typeof console.trace === 'function') { + // not supported in IE 10 + console.trace(); + } } } - return parts; + return this; +}; + +EventEmitter.prototype.on = EventEmitter.prototype.addListener; + +EventEmitter.prototype.once = function(type, listener) { + if (!isFunction(listener)) + throw TypeError('listener must be a function'); + + var fired = false; + + function g() { + this.removeListener(type, g); + + if (!fired) { + fired = true; + listener.apply(this, arguments); + } + } + + g.listener = listener; + this.on(type, g); + + return this; +}; + +// emits a 'removeListener' event iff the listener was removed +EventEmitter.prototype.removeListener = function(type, listener) { + var list, position, length, i; + + if (!isFunction(listener)) + throw TypeError('listener must be a function'); + + if (!this._events || !this._events[type]) + return this; + + list = this._events[type]; + length = list.length; + position = -1; + + if (list === listener || + (isFunction(list.listener) && list.listener === listener)) { + delete this._events[type]; + if (this._events.removeListener) + this.emit('removeListener', type, listener); + + } else if (isObject(list)) { + for (i = length; i-- > 0;) { + if (list[i] === listener || + (list[i].listener && list[i].listener === listener)) { + position = i; + break; + } + } + + if (position < 0) + return this; + + if (list.length === 1) { + list.length = 0; + delete this._events[type]; + } else { + list.splice(position, 1); + } + + if (this._events.removeListener) + this.emit('removeListener', type, listener); + } + + return this; +}; + +EventEmitter.prototype.removeAllListeners = function(type) { + var key, listeners; + + if (!this._events) + return this; + + // not listening for removeListener, no need to emit + if (!this._events.removeListener) { + if (arguments.length === 0) + this._events = {}; + else if (this._events[type]) + delete this._events[type]; + return this; + } + + // emit removeListener for all listeners on all events + if (arguments.length === 0) { + for (key in this._events) { + if (key === 'removeListener') continue; + this.removeAllListeners(key); + } + this.removeAllListeners('removeListener'); + this._events = {}; + return this; + } + + listeners = this._events[type]; + + if (isFunction(listeners)) { + this.removeListener(type, listeners); + } else if (listeners) { + // LIFO order + while (listeners.length) + this.removeListener(type, listeners[listeners.length - 1]); + } + delete this._events[type]; + + return this; +}; + +EventEmitter.prototype.listeners = function(type) { + var ret; + if (!this._events || !this._events[type]) + ret = []; + else if (isFunction(this._events[type])) + ret = [this._events[type]]; + else + ret = this._events[type].slice(); + return ret; +}; + +EventEmitter.prototype.listenerCount = function(type) { + if (this._events) { + var evlistener = this._events[type]; + + if (isFunction(evlistener)) + return 1; + else if (evlistener) + return evlistener.length; + } + return 0; +}; + +EventEmitter.listenerCount = function(emitter, type) { + return emitter.listenerCount(type); +}; + +function isFunction(arg) { + return typeof arg === 'function'; } -// Split a filename into [root, dir, basename, ext], unix version -// 'root' is just a slash, or nothing. -var splitPathRe = - /^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/; -var splitPath = function(filename) { - return splitPathRe.exec(filename).slice(1); -}; - -// path.resolve([from ...], to) -// posix version -exports.resolve = function() { - var resolvedPath = '', - resolvedAbsolute = false; - - for (var i = arguments.length - 1; i >= -1 && !resolvedAbsolute; i--) { - var path = (i >= 0) ? arguments[i] : process.cwd(); - - // Skip empty and invalid entries - if (typeof path !== 'string') { - throw new TypeError('Arguments to path.resolve must be strings'); - } else if (!path) { - continue; - } - - resolvedPath = path + '/' + resolvedPath; - resolvedAbsolute = path.charAt(0) === '/'; - } - - // At this point the path should be resolved to a full absolute path, but - // handle relative paths to be safe (might happen when process.cwd() fails) - - // Normalize the path - resolvedPath = normalizeArray(filter(resolvedPath.split('/'), function(p) { - return !!p; - }), !resolvedAbsolute).join('/'); - - return ((resolvedAbsolute ? '/' : '') + resolvedPath) || '.'; -}; - -// path.normalize(path) -// posix version -exports.normalize = function(path) { - var isAbsolute = exports.isAbsolute(path), - trailingSlash = substr(path, -1) === '/'; - - // Normalize the path - path = normalizeArray(filter(path.split('/'), function(p) { - return !!p; - }), !isAbsolute).join('/'); - - if (!path && !isAbsolute) { - path = '.'; - } - if (path && trailingSlash) { - path += '/'; - } - - return (isAbsolute ? '/' : '') + path; -}; - -// posix version -exports.isAbsolute = function(path) { - return path.charAt(0) === '/'; -}; - -// posix version -exports.join = function() { - var paths = Array.prototype.slice.call(arguments, 0); - return exports.normalize(filter(paths, function(p, index) { - if (typeof p !== 'string') { - throw new TypeError('Arguments to path.join must be strings'); - } - return p; - }).join('/')); -}; - - -// path.relative(from, to) -// posix version -exports.relative = function(from, to) { - from = exports.resolve(from).substr(1); - to = exports.resolve(to).substr(1); - - function trim(arr) { - var start = 0; - for (; start < arr.length; start++) { - if (arr[start] !== '') break; - } - - var end = arr.length - 1; - for (; end >= 0; end--) { - if (arr[end] !== '') break; - } - - if (start > end) return []; - return arr.slice(start, end - start + 1); - } - - var fromParts = trim(from.split('/')); - var toParts = trim(to.split('/')); - - var length = Math.min(fromParts.length, toParts.length); - var samePartsLength = length; - for (var i = 0; i < length; i++) { - if (fromParts[i] !== toParts[i]) { - samePartsLength = i; - break; - } - } - - var outputParts = []; - for (var i = samePartsLength; i < fromParts.length; i++) { - outputParts.push('..'); - } - - outputParts = outputParts.concat(toParts.slice(samePartsLength)); - - return outputParts.join('/'); -}; - -exports.sep = '/'; -exports.delimiter = ':'; - -exports.dirname = function(path) { - var result = splitPath(path), - root = result[0], - dir = result[1]; - - if (!root && !dir) { - // No dirname whatsoever - return '.'; - } - - if (dir) { - // It has a dirname, strip trailing slash - dir = dir.substr(0, dir.length - 1); - } - - return root + dir; -}; - - -exports.basename = function(path, ext) { - var f = splitPath(path)[2]; - // TODO: make this comparison case-insensitive on windows? - if (ext && f.substr(-1 * ext.length) === ext) { - f = f.substr(0, f.length - ext.length); - } - return f; -}; - - -exports.extname = function(path) { - return splitPath(path)[3]; -}; - -function filter (xs, f) { - if (xs.filter) return xs.filter(f); - var res = []; - for (var i = 0; i < xs.length; i++) { - if (f(xs[i], i, xs)) res.push(xs[i]); - } - return res; +function isNumber(arg) { + return typeof arg === 'number'; } -// String.prototype.substr - negative index don't work in IE8 -var substr = 'ab'.substr(-1) === 'b' - ? function (str, start, len) { return str.substr(start, len) } - : function (str, start, len) { - if (start < 0) start = str.length + start; - return str.substr(start, len); - } -; +function isObject(arg) { + return typeof arg === 'object' && arg !== null; +} + +function isUndefined(arg) { + return arg === void 0; +} -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(8))) /***/ }), -/* 30 */ +/* 22 */ /***/ (function(module, exports, __webpack_require__) { -const TextBasedChannel = __webpack_require__(25); -const { Presence } = __webpack_require__(19); -const UserProfile = __webpack_require__(137); -const Snowflake = __webpack_require__(9); -const Base = __webpack_require__(10); +const TextBasedChannel = __webpack_require__(19); +const { Presence } = __webpack_require__(13); +const UserProfile = __webpack_require__(98); +const Snowflake = __webpack_require__(6); +const Base = __webpack_require__(7); const { Error } = __webpack_require__(4); /** @@ -7755,12 +7149,12 @@ module.exports = User; /***/ }), -/* 31 */ +/* 23 */ /***/ (function(module, exports, __webpack_require__) { -const DataStore = __webpack_require__(11); +const DataStore = __webpack_require__(8); const Collection = __webpack_require__(3); -const Message = __webpack_require__(43); +const Message = __webpack_require__(35); const { Error } = __webpack_require__(4); /** @@ -7880,13 +7274,13 @@ module.exports = MessageStore; /***/ }), -/* 32 */ +/* 24 */ /***/ (function(module, exports, __webpack_require__) { -const Snowflake = __webpack_require__(9); -const Permissions = __webpack_require__(12); -const Util = __webpack_require__(6); -const Base = __webpack_require__(10); +const Snowflake = __webpack_require__(6); +const Permissions = __webpack_require__(9); +const Util = __webpack_require__(5); +const Base = __webpack_require__(7); const { TypeError } = __webpack_require__(4); /** @@ -8233,11 +7627,11 @@ module.exports = Role; /***/ }), -/* 33 */ +/* 25 */ /***/ (function(module, exports, __webpack_require__) { const { Endpoints } = __webpack_require__(0); -const Base = __webpack_require__(10); +const Base = __webpack_require__(7); /** * Represents an invitation to a guild channel. @@ -8393,27 +7787,27 @@ module.exports = Invite; /***/ }), -/* 34 */ +/* 26 */ /***/ (function(module, exports, __webpack_require__) { -const Invite = __webpack_require__(33); -const GuildAuditLogs = __webpack_require__(72); -const Webhook = __webpack_require__(22); -const GuildMember = __webpack_require__(18); -const VoiceRegion = __webpack_require__(73); +const Invite = __webpack_require__(25); +const GuildAuditLogs = __webpack_require__(55); +const Webhook = __webpack_require__(16); +const GuildMember = __webpack_require__(12); +const VoiceRegion = __webpack_require__(56); const { ChannelTypes, Events } = __webpack_require__(0); const Collection = __webpack_require__(3); -const Util = __webpack_require__(6); -const DataResolver = __webpack_require__(13); -const Snowflake = __webpack_require__(9); -const Permissions = __webpack_require__(12); -const Shared = __webpack_require__(63); -const GuildMemberStore = __webpack_require__(133); -const RoleStore = __webpack_require__(134); -const EmojiStore = __webpack_require__(74); -const GuildChannelStore = __webpack_require__(135); -const PresenceStore = __webpack_require__(75); -const Base = __webpack_require__(10); +const Util = __webpack_require__(5); +const DataResolver = __webpack_require__(10); +const Snowflake = __webpack_require__(6); +const Permissions = __webpack_require__(9); +const Shared = __webpack_require__(45); +const GuildMemberStore = __webpack_require__(94); +const RoleStore = __webpack_require__(95); +const EmojiStore = __webpack_require__(57); +const GuildChannelStore = __webpack_require__(96); +const PresenceStore = __webpack_require__(58); +const Base = __webpack_require__(7); const { Error, TypeError } = __webpack_require__(4); /** @@ -9564,7 +8958,34 @@ module.exports = Guild; /***/ }), -/* 35 */ +/* 27 */ +/***/ (function(module, exports) { + +var g; + +// This works in non-strict mode +g = (function() { + return this; +})(); + +try { + // This works if eval is allowed (see CSP) + g = g || Function("return this")() || (1,eval)("this"); +} catch(e) { + // This works if the window reference is available + if(typeof window === "object") + g = window; +} + +// g can still be undefined, but nothing to do about it... +// We return undefined, instead of nothing here, so it's +// easier to handle this case. if(!global) { ...} + +module.exports = g; + + +/***/ }), +/* 28 */ /***/ (function(module, exports, __webpack_require__) { var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/* @@ -10782,763 +10203,25 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_ /***/ }), -/* 36 */ +/* 29 */ /***/ (function(module, exports, __webpack_require__) { -const Snekfetch = __webpack_require__(82); - -// Sync stuff might go here - -module.exports = Snekfetch; +module.exports = __webpack_require__(66); /***/ }), -/* 37 */ -/***/ (function(module, exports, __webpack_require__) { - -/* eslint-disable node/no-deprecated-api */ -var buffer = __webpack_require__(5) -var Buffer = buffer.Buffer - -// alternative to using Object.keys for old browsers -function copyProps (src, dst) { - for (var key in src) { - dst[key] = src[key] - } -} -if (Buffer.from && Buffer.alloc && Buffer.allocUnsafe && Buffer.allocUnsafeSlow) { - module.exports = buffer -} else { - // Copy properties from require('buffer') - copyProps(buffer, exports) - exports.Buffer = SafeBuffer -} - -function SafeBuffer (arg, encodingOrOffset, length) { - return Buffer(arg, encodingOrOffset, length) -} - -// Copy static methods from Buffer -copyProps(Buffer, SafeBuffer) - -SafeBuffer.from = function (arg, encodingOrOffset, length) { - if (typeof arg === 'number') { - throw new TypeError('Argument must not be a number') - } - return Buffer(arg, encodingOrOffset, length) -} - -SafeBuffer.alloc = function (size, fill, encoding) { - if (typeof size !== 'number') { - throw new TypeError('Argument must be a number') - } - var buf = Buffer(size) - if (fill !== undefined) { - if (typeof encoding === 'string') { - buf.fill(fill, encoding) - } else { - buf.fill(fill) - } - } else { - buf.fill(0) - } - return buf -} - -SafeBuffer.allocUnsafe = function (size) { - if (typeof size !== 'number') { - throw new TypeError('Argument must be a number') - } - return Buffer(size) -} - -SafeBuffer.allocUnsafeSlow = function (size) { - if (typeof size !== 'number') { - throw new TypeError('Argument must be a number') - } - return buffer.SlowBuffer(size) -} - - -/***/ }), -/* 38 */ +/* 30 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -/* WEBPACK VAR INJECTION */(function(process, setImmediate, global) {// Copyright Joyent, Inc. and other Node contributors. -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to permit -// persons to whom the Software is furnished to do so, subject to the -// following conditions: -// -// The above copyright notice and this permission notice shall be included -// in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN -// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE -// USE OR OTHER DEALINGS IN THE SOFTWARE. -// A bit simpler than readable streams. -// Implement an async ._write(chunk, encoding, cb), and it'll handle all -// the drain event emission and buffering. - - - -/**/ - -var processNextTick = __webpack_require__(27); -/**/ - -module.exports = Writable; - -/* */ -function WriteReq(chunk, encoding, cb) { - this.chunk = chunk; - this.encoding = encoding; - this.callback = cb; - this.next = null; -} - -// It seems a linked list but it is not -// there will be only 2 of these for each stream -function CorkedRequest(state) { - var _this = this; - - this.next = null; - this.entry = null; - this.finish = function () { - onCorkedFinish(_this, state); - }; -} -/* */ - -/**/ -var asyncWrite = !process.browser && ['v0.10', 'v0.9.'].indexOf(process.version.slice(0, 5)) > -1 ? setImmediate : processNextTick; -/**/ - -/**/ -var Duplex; -/**/ - -Writable.WritableState = WritableState; - -/**/ -var util = __webpack_require__(24); -util.inherits = __webpack_require__(14); -/**/ - -/**/ -var internalUtil = { - deprecate: __webpack_require__(87) -}; -/**/ - -/**/ -var Stream = __webpack_require__(50); -/**/ - -/**/ -var Buffer = __webpack_require__(37).Buffer; -var OurUint8Array = global.Uint8Array || function () {}; -function _uint8ArrayToBuffer(chunk) { - return Buffer.from(chunk); -} -function _isUint8Array(obj) { - return Buffer.isBuffer(obj) || obj instanceof OurUint8Array; -} -/**/ - -var destroyImpl = __webpack_require__(51); - -util.inherits(Writable, Stream); - -function nop() {} - -function WritableState(options, stream) { - Duplex = Duplex || __webpack_require__(16); - - options = options || {}; - - // object stream flag to indicate whether or not this stream - // contains buffers or objects. - this.objectMode = !!options.objectMode; - - if (stream instanceof Duplex) this.objectMode = this.objectMode || !!options.writableObjectMode; - - // the point at which write() starts returning false - // Note: 0 is a valid value, means that we always return false if - // the entire buffer is not flushed immediately on write() - var hwm = options.highWaterMark; - var defaultHwm = this.objectMode ? 16 : 16 * 1024; - this.highWaterMark = hwm || hwm === 0 ? hwm : defaultHwm; - - // cast to ints. - this.highWaterMark = Math.floor(this.highWaterMark); - - // if _final has been called - this.finalCalled = false; - - // drain event flag. - this.needDrain = false; - // at the start of calling end() - this.ending = false; - // when end() has been called, and returned - this.ended = false; - // when 'finish' is emitted - this.finished = false; - - // has it been destroyed - this.destroyed = false; - - // should we decode strings into buffers before passing to _write? - // this is here so that some node-core streams can optimize string - // handling at a lower level. - var noDecode = options.decodeStrings === false; - this.decodeStrings = !noDecode; - - // Crypto is kind of old and crusty. Historically, its default string - // encoding is 'binary' so we have to make this configurable. - // Everything else in the universe uses 'utf8', though. - this.defaultEncoding = options.defaultEncoding || 'utf8'; - - // not an actual buffer we keep track of, but a measurement - // of how much we're waiting to get pushed to some underlying - // socket or file. - this.length = 0; - - // a flag to see when we're in the middle of a write. - this.writing = false; - - // when true all writes will be buffered until .uncork() call - this.corked = 0; - - // a flag to be able to tell if the onwrite cb is called immediately, - // or on a later tick. We set this to true at first, because any - // actions that shouldn't happen until "later" should generally also - // not happen before the first write call. - this.sync = true; - - // a flag to know if we're processing previously buffered items, which - // may call the _write() callback in the same tick, so that we don't - // end up in an overlapped onwrite situation. - this.bufferProcessing = false; - - // the callback that's passed to _write(chunk,cb) - this.onwrite = function (er) { - onwrite(stream, er); - }; - - // the callback that the user supplies to write(chunk,encoding,cb) - this.writecb = null; - - // the amount that is being written when _write is called. - this.writelen = 0; - - this.bufferedRequest = null; - this.lastBufferedRequest = null; - - // number of pending user-supplied write callbacks - // this must be 0 before 'finish' can be emitted - this.pendingcb = 0; - - // emit prefinish if the only thing we're waiting for is _write cbs - // This is relevant for synchronous Transform streams - this.prefinished = false; - - // True if the error was already emitted and should not be thrown again - this.errorEmitted = false; - - // count buffered requests - this.bufferedRequestCount = 0; - - // allocate the first CorkedRequest, there is always - // one allocated and free to use, and we maintain at most two - this.corkedRequestsFree = new CorkedRequest(this); -} - -WritableState.prototype.getBuffer = function getBuffer() { - var current = this.bufferedRequest; - var out = []; - while (current) { - out.push(current); - current = current.next; - } - return out; -}; - -(function () { - try { - Object.defineProperty(WritableState.prototype, 'buffer', { - get: internalUtil.deprecate(function () { - return this.getBuffer(); - }, '_writableState.buffer is deprecated. Use _writableState.getBuffer ' + 'instead.', 'DEP0003') - }); - } catch (_) {} -})(); - -// Test _writableState for inheritance to account for Duplex streams, -// whose prototype chain only points to Readable. -var realHasInstance; -if (typeof Symbol === 'function' && Symbol.hasInstance && typeof Function.prototype[Symbol.hasInstance] === 'function') { - realHasInstance = Function.prototype[Symbol.hasInstance]; - Object.defineProperty(Writable, Symbol.hasInstance, { - value: function (object) { - if (realHasInstance.call(this, object)) return true; - - return object && object._writableState instanceof WritableState; - } - }); -} else { - realHasInstance = function (object) { - return object instanceof this; - }; -} - -function Writable(options) { - Duplex = Duplex || __webpack_require__(16); - - // Writable ctor is applied to Duplexes, too. - // `realHasInstance` is necessary because using plain `instanceof` - // would return false, as no `_writableState` property is attached. - - // Trying to use the custom `instanceof` for Writable here will also break the - // Node.js LazyTransform implementation, which has a non-trivial getter for - // `_writableState` that would lead to infinite recursion. - if (!realHasInstance.call(Writable, this) && !(this instanceof Duplex)) { - return new Writable(options); - } - - this._writableState = new WritableState(options, this); - - // legacy. - this.writable = true; - - if (options) { - if (typeof options.write === 'function') this._write = options.write; - - if (typeof options.writev === 'function') this._writev = options.writev; - - if (typeof options.destroy === 'function') this._destroy = options.destroy; - - if (typeof options.final === 'function') this._final = options.final; - } - - Stream.call(this); -} - -// Otherwise people can pipe Writable streams, which is just wrong. -Writable.prototype.pipe = function () { - this.emit('error', new Error('Cannot pipe, not readable')); -}; - -function writeAfterEnd(stream, cb) { - var er = new Error('write after end'); - // TODO: defer error events consistently everywhere, not just the cb - stream.emit('error', er); - processNextTick(cb, er); -} - -// Checks that a user-supplied chunk is valid, especially for the particular -// mode the stream is in. Currently this means that `null` is never accepted -// and undefined/non-string values are only allowed in object mode. -function validChunk(stream, state, chunk, cb) { - var valid = true; - var er = false; - - if (chunk === null) { - er = new TypeError('May not write null values to stream'); - } else if (typeof chunk !== 'string' && chunk !== undefined && !state.objectMode) { - er = new TypeError('Invalid non-string/buffer chunk'); - } - if (er) { - stream.emit('error', er); - processNextTick(cb, er); - valid = false; - } - return valid; -} - -Writable.prototype.write = function (chunk, encoding, cb) { - var state = this._writableState; - var ret = false; - var isBuf = _isUint8Array(chunk) && !state.objectMode; - - if (isBuf && !Buffer.isBuffer(chunk)) { - chunk = _uint8ArrayToBuffer(chunk); - } - - if (typeof encoding === 'function') { - cb = encoding; - encoding = null; - } - - if (isBuf) encoding = 'buffer';else if (!encoding) encoding = state.defaultEncoding; - - if (typeof cb !== 'function') cb = nop; - - if (state.ended) writeAfterEnd(this, cb);else if (isBuf || validChunk(this, state, chunk, cb)) { - state.pendingcb++; - ret = writeOrBuffer(this, state, isBuf, chunk, encoding, cb); - } - - return ret; -}; - -Writable.prototype.cork = function () { - var state = this._writableState; - - state.corked++; -}; - -Writable.prototype.uncork = function () { - var state = this._writableState; - - if (state.corked) { - state.corked--; - - if (!state.writing && !state.corked && !state.finished && !state.bufferProcessing && state.bufferedRequest) clearBuffer(this, state); - } -}; - -Writable.prototype.setDefaultEncoding = function setDefaultEncoding(encoding) { - // node::ParseEncoding() requires lower case. - if (typeof encoding === 'string') encoding = encoding.toLowerCase(); - if (!(['hex', 'utf8', 'utf-8', 'ascii', 'binary', 'base64', 'ucs2', 'ucs-2', 'utf16le', 'utf-16le', 'raw'].indexOf((encoding + '').toLowerCase()) > -1)) throw new TypeError('Unknown encoding: ' + encoding); - this._writableState.defaultEncoding = encoding; - return this; -}; - -function decodeChunk(state, chunk, encoding) { - if (!state.objectMode && state.decodeStrings !== false && typeof chunk === 'string') { - chunk = Buffer.from(chunk, encoding); - } - return chunk; -} - -// if we're already writing something, then just put this -// in the queue, and wait our turn. Otherwise, call _write -// If we return false, then we need a drain event, so set that flag. -function writeOrBuffer(stream, state, isBuf, chunk, encoding, cb) { - if (!isBuf) { - var newChunk = decodeChunk(state, chunk, encoding); - if (chunk !== newChunk) { - isBuf = true; - encoding = 'buffer'; - chunk = newChunk; - } - } - var len = state.objectMode ? 1 : chunk.length; - - state.length += len; - - var ret = state.length < state.highWaterMark; - // we must ensure that previous needDrain will not be reset to false. - if (!ret) state.needDrain = true; - - if (state.writing || state.corked) { - var last = state.lastBufferedRequest; - state.lastBufferedRequest = { - chunk: chunk, - encoding: encoding, - isBuf: isBuf, - callback: cb, - next: null - }; - if (last) { - last.next = state.lastBufferedRequest; - } else { - state.bufferedRequest = state.lastBufferedRequest; - } - state.bufferedRequestCount += 1; - } else { - doWrite(stream, state, false, len, chunk, encoding, cb); - } - - return ret; -} - -function doWrite(stream, state, writev, len, chunk, encoding, cb) { - state.writelen = len; - state.writecb = cb; - state.writing = true; - state.sync = true; - if (writev) stream._writev(chunk, state.onwrite);else stream._write(chunk, encoding, state.onwrite); - state.sync = false; -} - -function onwriteError(stream, state, sync, er, cb) { - --state.pendingcb; - - if (sync) { - // defer the callback if we are being called synchronously - // to avoid piling up things on the stack - processNextTick(cb, er); - // this can emit finish, and it will always happen - // after error - processNextTick(finishMaybe, stream, state); - stream._writableState.errorEmitted = true; - stream.emit('error', er); - } else { - // the caller expect this to happen before if - // it is async - cb(er); - stream._writableState.errorEmitted = true; - stream.emit('error', er); - // this can emit finish, but finish must - // always follow error - finishMaybe(stream, state); - } -} - -function onwriteStateUpdate(state) { - state.writing = false; - state.writecb = null; - state.length -= state.writelen; - state.writelen = 0; -} - -function onwrite(stream, er) { - var state = stream._writableState; - var sync = state.sync; - var cb = state.writecb; - - onwriteStateUpdate(state); - - if (er) onwriteError(stream, state, sync, er, cb);else { - // Check if we're actually ready to finish, but don't emit yet - var finished = needFinish(state); - - if (!finished && !state.corked && !state.bufferProcessing && state.bufferedRequest) { - clearBuffer(stream, state); - } - - if (sync) { - /**/ - asyncWrite(afterWrite, stream, state, finished, cb); - /**/ - } else { - afterWrite(stream, state, finished, cb); - } - } -} - -function afterWrite(stream, state, finished, cb) { - if (!finished) onwriteDrain(stream, state); - state.pendingcb--; - cb(); - finishMaybe(stream, state); -} - -// Must force callback to be called on nextTick, so that we don't -// emit 'drain' before the write() consumer gets the 'false' return -// value, and has a chance to attach a 'drain' listener. -function onwriteDrain(stream, state) { - if (state.length === 0 && state.needDrain) { - state.needDrain = false; - stream.emit('drain'); - } -} - -// if there's something in the buffer waiting, then process it -function clearBuffer(stream, state) { - state.bufferProcessing = true; - var entry = state.bufferedRequest; - - if (stream._writev && entry && entry.next) { - // Fast case, write everything using _writev() - var l = state.bufferedRequestCount; - var buffer = new Array(l); - var holder = state.corkedRequestsFree; - holder.entry = entry; - - var count = 0; - var allBuffers = true; - while (entry) { - buffer[count] = entry; - if (!entry.isBuf) allBuffers = false; - entry = entry.next; - count += 1; - } - buffer.allBuffers = allBuffers; - - doWrite(stream, state, true, state.length, buffer, '', holder.finish); - - // doWrite is almost always async, defer these to save a bit of time - // as the hot path ends with doWrite - state.pendingcb++; - state.lastBufferedRequest = null; - if (holder.next) { - state.corkedRequestsFree = holder.next; - holder.next = null; - } else { - state.corkedRequestsFree = new CorkedRequest(state); - } - } else { - // Slow case, write chunks one-by-one - while (entry) { - var chunk = entry.chunk; - var encoding = entry.encoding; - var cb = entry.callback; - var len = state.objectMode ? 1 : chunk.length; - - doWrite(stream, state, false, len, chunk, encoding, cb); - entry = entry.next; - // if we didn't call the onwrite immediately, then - // it means that we need to wait until it does. - // also, that means that the chunk and cb are currently - // being processed, so move the buffer counter past them. - if (state.writing) { - break; - } - } - - if (entry === null) state.lastBufferedRequest = null; - } - - state.bufferedRequestCount = 0; - state.bufferedRequest = entry; - state.bufferProcessing = false; -} - -Writable.prototype._write = function (chunk, encoding, cb) { - cb(new Error('_write() is not implemented')); -}; - -Writable.prototype._writev = null; - -Writable.prototype.end = function (chunk, encoding, cb) { - var state = this._writableState; - - if (typeof chunk === 'function') { - cb = chunk; - chunk = null; - encoding = null; - } else if (typeof encoding === 'function') { - cb = encoding; - encoding = null; - } - - if (chunk !== null && chunk !== undefined) this.write(chunk, encoding); - - // .end() fully uncorks - if (state.corked) { - state.corked = 1; - this.uncork(); - } - - // ignore unnecessary end() calls. - if (!state.ending && !state.finished) endWritable(this, state, cb); -}; - -function needFinish(state) { - return state.ending && state.length === 0 && state.bufferedRequest === null && !state.finished && !state.writing; -} -function callFinal(stream, state) { - stream._final(function (err) { - state.pendingcb--; - if (err) { - stream.emit('error', err); - } - state.prefinished = true; - stream.emit('prefinish'); - finishMaybe(stream, state); - }); -} -function prefinish(stream, state) { - if (!state.prefinished && !state.finalCalled) { - if (typeof stream._final === 'function') { - state.pendingcb++; - state.finalCalled = true; - processNextTick(callFinal, stream, state); - } else { - state.prefinished = true; - stream.emit('prefinish'); - } - } -} - -function finishMaybe(stream, state) { - var need = needFinish(state); - if (need) { - prefinish(stream, state); - if (state.pendingcb === 0) { - state.finished = true; - stream.emit('finish'); - } - } - return need; -} - -function endWritable(stream, state, cb) { - state.ending = true; - finishMaybe(stream, state); - if (cb) { - if (state.finished) processNextTick(cb);else stream.once('finish', cb); - } - state.ended = true; - stream.writable = false; -} - -function onCorkedFinish(corkReq, state, err) { - var entry = corkReq.entry; - corkReq.entry = null; - while (entry) { - var cb = entry.callback; - state.pendingcb--; - cb(err); - entry = entry.next; - } - if (state.corkedRequestsFree) { - state.corkedRequestsFree.next = corkReq; - } else { - state.corkedRequestsFree = corkReq; - } -} - -Object.defineProperty(Writable.prototype, 'destroyed', { - get: function () { - if (this._writableState === undefined) { - return false; - } - return this._writableState.destroyed; - }, - set: function (value) { - // we ignore the value if the stream - // has not been initialized yet - if (!this._writableState) { - return; - } - - // backward compatibility, the user is explicitly - // managing destroyed - this._writableState.destroyed = value; - } -}); - -Writable.prototype.destroy = destroyImpl.destroy; -Writable.prototype._undestroy = destroyImpl.undestroy; -Writable.prototype._destroy = function (err, cb) { - this.end(); - cb(err); -}; -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(8), __webpack_require__(85).setImmediate, __webpack_require__(7))) - -/***/ }), -/* 39 */ -/***/ (function(module, exports) { +exports.decode = exports.parse = __webpack_require__(67); +exports.encode = exports.stringify = __webpack_require__(68); /***/ }), -/* 40 */ +/* 31 */ /***/ (function(module, exports, __webpack_require__) { /* WEBPACK VAR INJECTION */(function(global, process) {// Copyright Joyent, Inc. and other Node contributors. @@ -12066,7 +10749,7 @@ function isPrimitive(arg) { } exports.isPrimitive = isPrimitive; -exports.isBuffer = __webpack_require__(112); +exports.isBuffer = __webpack_require__(73); function objectToString(o) { return Object.prototype.toString.call(o); @@ -12110,7 +10793,7 @@ exports.log = function() { * prototype. * @param {function} superCtor Constructor function to inherit prototype from. */ -exports.inherits = __webpack_require__(113); +exports.inherits = __webpack_require__(74); exports._extend = function(origin, add) { // Don't do anything if add isn't an object @@ -12128,15 +10811,15 @@ function hasOwnProperty(obj, prop) { return Object.prototype.hasOwnProperty.call(obj, prop); } -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(7), __webpack_require__(8))) +/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(27), __webpack_require__(18))) /***/ }), -/* 41 */ +/* 32 */ /***/ (function(module, exports, __webpack_require__) { -const EventEmitter = __webpack_require__(15); -const RESTManager = __webpack_require__(59); -const Util = __webpack_require__(6); +const EventEmitter = __webpack_require__(21); +const RESTManager = __webpack_require__(41); +const Util = __webpack_require__(5); const { DefaultOptions } = __webpack_require__(0); /** @@ -12255,11 +10938,242 @@ module.exports = BaseClient; /***/ }), -/* 42 */ +/* 33 */ +/***/ (function(module, exports, __webpack_require__) { + +/* WEBPACK VAR INJECTION */(function(process) {// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +// resolves . and .. elements in a path array with directory names there +// must be no slashes, empty elements, or device names (c:\) in the array +// (so also no leading and trailing slashes - it does not distinguish +// relative and absolute paths) +function normalizeArray(parts, allowAboveRoot) { + // if the path tries to go above the root, `up` ends up > 0 + var up = 0; + for (var i = parts.length - 1; i >= 0; i--) { + var last = parts[i]; + if (last === '.') { + parts.splice(i, 1); + } else if (last === '..') { + parts.splice(i, 1); + up++; + } else if (up) { + parts.splice(i, 1); + up--; + } + } + + // if the path is allowed to go above the root, restore leading ..s + if (allowAboveRoot) { + for (; up--; up) { + parts.unshift('..'); + } + } + + return parts; +} + +// Split a filename into [root, dir, basename, ext], unix version +// 'root' is just a slash, or nothing. +var splitPathRe = + /^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/; +var splitPath = function(filename) { + return splitPathRe.exec(filename).slice(1); +}; + +// path.resolve([from ...], to) +// posix version +exports.resolve = function() { + var resolvedPath = '', + resolvedAbsolute = false; + + for (var i = arguments.length - 1; i >= -1 && !resolvedAbsolute; i--) { + var path = (i >= 0) ? arguments[i] : process.cwd(); + + // Skip empty and invalid entries + if (typeof path !== 'string') { + throw new TypeError('Arguments to path.resolve must be strings'); + } else if (!path) { + continue; + } + + resolvedPath = path + '/' + resolvedPath; + resolvedAbsolute = path.charAt(0) === '/'; + } + + // At this point the path should be resolved to a full absolute path, but + // handle relative paths to be safe (might happen when process.cwd() fails) + + // Normalize the path + resolvedPath = normalizeArray(filter(resolvedPath.split('/'), function(p) { + return !!p; + }), !resolvedAbsolute).join('/'); + + return ((resolvedAbsolute ? '/' : '') + resolvedPath) || '.'; +}; + +// path.normalize(path) +// posix version +exports.normalize = function(path) { + var isAbsolute = exports.isAbsolute(path), + trailingSlash = substr(path, -1) === '/'; + + // Normalize the path + path = normalizeArray(filter(path.split('/'), function(p) { + return !!p; + }), !isAbsolute).join('/'); + + if (!path && !isAbsolute) { + path = '.'; + } + if (path && trailingSlash) { + path += '/'; + } + + return (isAbsolute ? '/' : '') + path; +}; + +// posix version +exports.isAbsolute = function(path) { + return path.charAt(0) === '/'; +}; + +// posix version +exports.join = function() { + var paths = Array.prototype.slice.call(arguments, 0); + return exports.normalize(filter(paths, function(p, index) { + if (typeof p !== 'string') { + throw new TypeError('Arguments to path.join must be strings'); + } + return p; + }).join('/')); +}; + + +// path.relative(from, to) +// posix version +exports.relative = function(from, to) { + from = exports.resolve(from).substr(1); + to = exports.resolve(to).substr(1); + + function trim(arr) { + var start = 0; + for (; start < arr.length; start++) { + if (arr[start] !== '') break; + } + + var end = arr.length - 1; + for (; end >= 0; end--) { + if (arr[end] !== '') break; + } + + if (start > end) return []; + return arr.slice(start, end - start + 1); + } + + var fromParts = trim(from.split('/')); + var toParts = trim(to.split('/')); + + var length = Math.min(fromParts.length, toParts.length); + var samePartsLength = length; + for (var i = 0; i < length; i++) { + if (fromParts[i] !== toParts[i]) { + samePartsLength = i; + break; + } + } + + var outputParts = []; + for (var i = samePartsLength; i < fromParts.length; i++) { + outputParts.push('..'); + } + + outputParts = outputParts.concat(toParts.slice(samePartsLength)); + + return outputParts.join('/'); +}; + +exports.sep = '/'; +exports.delimiter = ':'; + +exports.dirname = function(path) { + var result = splitPath(path), + root = result[0], + dir = result[1]; + + if (!root && !dir) { + // No dirname whatsoever + return '.'; + } + + if (dir) { + // It has a dirname, strip trailing slash + dir = dir.substr(0, dir.length - 1); + } + + return root + dir; +}; + + +exports.basename = function(path, ext) { + var f = splitPath(path)[2]; + // TODO: make this comparison case-insensitive on windows? + if (ext && f.substr(-1 * ext.length) === ext) { + f = f.substr(0, f.length - ext.length); + } + return f; +}; + + +exports.extname = function(path) { + return splitPath(path)[3]; +}; + +function filter (xs, f) { + if (xs.filter) return xs.filter(f); + var res = []; + for (var i = 0; i < xs.length; i++) { + if (f(xs[i], i, xs)) res.push(xs[i]); + } + return res; +} + +// String.prototype.substr - negative index don't work in IE8 +var substr = 'ab'.substr(-1) === 'b' + ? function (str, start, len) { return str.substr(start, len) } + : function (str, start, len) { + if (start < 0) start = str.length + start; + return str.substr(start, len); + } +; + +/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(18))) + +/***/ }), +/* 34 */ /***/ (function(module, exports, __webpack_require__) { const Collection = __webpack_require__(3); -const EventEmitter = __webpack_require__(15); +const EventEmitter = __webpack_require__(21); /** * Filter to be applied to the collector. @@ -12469,21 +11383,21 @@ module.exports = Collector; /***/ }), -/* 43 */ +/* 35 */ /***/ (function(module, exports, __webpack_require__) { -const Mentions = __webpack_require__(65); -const MessageAttachment = __webpack_require__(26); -const Embed = __webpack_require__(20); -const ReactionCollector = __webpack_require__(66); -const ClientApplication = __webpack_require__(44); -const Util = __webpack_require__(6); +const Mentions = __webpack_require__(47); +const MessageAttachment = __webpack_require__(20); +const Embed = __webpack_require__(14); +const ReactionCollector = __webpack_require__(48); +const ClientApplication = __webpack_require__(36); +const Util = __webpack_require__(5); const Collection = __webpack_require__(3); -const ReactionStore = __webpack_require__(131); +const ReactionStore = __webpack_require__(92); const { MessageTypes } = __webpack_require__(0); -const Permissions = __webpack_require__(12); -const GuildMember = __webpack_require__(18); -const Base = __webpack_require__(10); +const Permissions = __webpack_require__(9); +const GuildMember = __webpack_require__(12); +const Base = __webpack_require__(7); const { Error, TypeError } = __webpack_require__(4); /** @@ -13047,13 +11961,13 @@ module.exports = Message; /***/ }), -/* 44 */ +/* 36 */ /***/ (function(module, exports, __webpack_require__) { -const Snowflake = __webpack_require__(9); +const Snowflake = __webpack_require__(6); const { ClientApplicationAssetTypes, Endpoints } = __webpack_require__(0); -const DataResolver = __webpack_require__(13); -const Base = __webpack_require__(10); +const DataResolver = __webpack_require__(10); +const Base = __webpack_require__(7); /** * Represents a Client OAuth2 Application. @@ -13259,12 +12173,12 @@ module.exports = ClientApplication; /***/ }), -/* 45 */ +/* 37 */ /***/ (function(module, exports, __webpack_require__) { const Collection = __webpack_require__(3); -const Snowflake = __webpack_require__(9); -const Base = __webpack_require__(10); +const Snowflake = __webpack_require__(6); +const Base = __webpack_require__(7); const { TypeError } = __webpack_require__(4); /** @@ -13503,7 +12417,7 @@ module.exports = Emoji; /***/ }), -/* 46 */ +/* 38 */ /***/ (function(module, exports) { /** @@ -13558,2611 +12472,21 @@ module.exports = ReactionEmoji; /***/ }), -/* 47 */ -/***/ (function(module, exports) { - -var toString = {}.toString; - -module.exports = Array.isArray || function (arr) { - return toString.call(arr) == '[object Array]'; -}; - - -/***/ }), -/* 48 */ -/***/ (function(module, exports, __webpack_require__) { - -// Copyright Joyent, Inc. and other Node contributors. -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to permit -// persons to whom the Software is furnished to do so, subject to the -// following conditions: -// -// The above copyright notice and this permission notice shall be included -// in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN -// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE -// USE OR OTHER DEALINGS IN THE SOFTWARE. - -module.exports = Stream; - -var EE = __webpack_require__(15).EventEmitter; -var inherits = __webpack_require__(14); - -inherits(Stream, EE); -Stream.Readable = __webpack_require__(23); -Stream.Writable = __webpack_require__(89); -Stream.Duplex = __webpack_require__(90); -Stream.Transform = __webpack_require__(91); -Stream.PassThrough = __webpack_require__(92); - -// Backwards-compat with node 0.4.x -Stream.Stream = Stream; - - - -// old-style streams. Note that the pipe method (the only relevant -// part of this class) is overridden in the Readable class. - -function Stream() { - EE.call(this); -} - -Stream.prototype.pipe = function(dest, options) { - var source = this; - - function ondata(chunk) { - if (dest.writable) { - if (false === dest.write(chunk) && source.pause) { - source.pause(); - } - } - } - - source.on('data', ondata); - - function ondrain() { - if (source.readable && source.resume) { - source.resume(); - } - } - - dest.on('drain', ondrain); - - // If the 'end' option is not supplied, dest.end() will be called when - // source gets the 'end' or 'close' events. Only dest.end() once. - if (!dest._isStdio && (!options || options.end !== false)) { - source.on('end', onend); - source.on('close', onclose); - } - - var didOnEnd = false; - function onend() { - if (didOnEnd) return; - didOnEnd = true; - - dest.end(); - } - - - function onclose() { - if (didOnEnd) return; - didOnEnd = true; - - if (typeof dest.destroy === 'function') dest.destroy(); - } - - // don't leave dangling pipes when there are errors. - function onerror(er) { - cleanup(); - if (EE.listenerCount(this, 'error') === 0) { - throw er; // Unhandled stream error in pipe. - } - } - - source.on('error', onerror); - dest.on('error', onerror); - - // remove all the event listeners that were added. - function cleanup() { - source.removeListener('data', ondata); - dest.removeListener('drain', ondrain); - - source.removeListener('end', onend); - source.removeListener('close', onclose); - - source.removeListener('error', onerror); - dest.removeListener('error', onerror); - - source.removeListener('end', cleanup); - source.removeListener('close', cleanup); - - dest.removeListener('close', cleanup); - } - - source.on('end', cleanup); - source.on('close', cleanup); - - dest.on('close', cleanup); - - dest.emit('pipe', source); - - // Allow for unix-like usage: A.pipe(B).pipe(C) - return dest; -}; - - -/***/ }), -/* 49 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(global, process) {// Copyright Joyent, Inc. and other Node contributors. -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to permit -// persons to whom the Software is furnished to do so, subject to the -// following conditions: -// -// The above copyright notice and this permission notice shall be included -// in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN -// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE -// USE OR OTHER DEALINGS IN THE SOFTWARE. - - - -/**/ - -var processNextTick = __webpack_require__(27); -/**/ - -module.exports = Readable; - -/**/ -var isArray = __webpack_require__(47); -/**/ - -/**/ -var Duplex; -/**/ - -Readable.ReadableState = ReadableState; - -/**/ -var EE = __webpack_require__(15).EventEmitter; - -var EElistenerCount = function (emitter, type) { - return emitter.listeners(type).length; -}; -/**/ - -/**/ -var Stream = __webpack_require__(50); -/**/ - -// TODO(bmeurer): Change this back to const once hole checks are -// properly optimized away early in Ignition+TurboFan. -/**/ -var Buffer = __webpack_require__(37).Buffer; -var OurUint8Array = global.Uint8Array || function () {}; -function _uint8ArrayToBuffer(chunk) { - return Buffer.from(chunk); -} -function _isUint8Array(obj) { - return Buffer.isBuffer(obj) || obj instanceof OurUint8Array; -} -/**/ - -/**/ -var util = __webpack_require__(24); -util.inherits = __webpack_require__(14); -/**/ - -/**/ -var debugUtil = __webpack_require__(83); -var debug = void 0; -if (debugUtil && debugUtil.debuglog) { - debug = debugUtil.debuglog('stream'); -} else { - debug = function () {}; -} -/**/ - -var BufferList = __webpack_require__(84); -var destroyImpl = __webpack_require__(51); -var StringDecoder; - -util.inherits(Readable, Stream); - -var kProxyEvents = ['error', 'close', 'destroy', 'pause', 'resume']; - -function prependListener(emitter, event, fn) { - // Sadly this is not cacheable as some libraries bundle their own - // event emitter implementation with them. - if (typeof emitter.prependListener === 'function') { - return emitter.prependListener(event, fn); - } else { - // This is a hack to make sure that our error handler is attached before any - // userland ones. NEVER DO THIS. This is here only because this code needs - // to continue to work with older versions of Node.js that do not include - // the prependListener() method. The goal is to eventually remove this hack. - if (!emitter._events || !emitter._events[event]) emitter.on(event, fn);else if (isArray(emitter._events[event])) emitter._events[event].unshift(fn);else emitter._events[event] = [fn, emitter._events[event]]; - } -} - -function ReadableState(options, stream) { - Duplex = Duplex || __webpack_require__(16); - - options = options || {}; - - // object stream flag. Used to make read(n) ignore n and to - // make all the buffer merging and length checks go away - this.objectMode = !!options.objectMode; - - if (stream instanceof Duplex) this.objectMode = this.objectMode || !!options.readableObjectMode; - - // the point at which it stops calling _read() to fill the buffer - // Note: 0 is a valid value, means "don't call _read preemptively ever" - var hwm = options.highWaterMark; - var defaultHwm = this.objectMode ? 16 : 16 * 1024; - this.highWaterMark = hwm || hwm === 0 ? hwm : defaultHwm; - - // cast to ints. - this.highWaterMark = Math.floor(this.highWaterMark); - - // A linked list is used to store data chunks instead of an array because the - // linked list can remove elements from the beginning faster than - // array.shift() - this.buffer = new BufferList(); - this.length = 0; - this.pipes = null; - this.pipesCount = 0; - this.flowing = null; - this.ended = false; - this.endEmitted = false; - this.reading = false; - - // a flag to be able to tell if the event 'readable'/'data' is emitted - // immediately, or on a later tick. We set this to true at first, because - // any actions that shouldn't happen until "later" should generally also - // not happen before the first read call. - this.sync = true; - - // whenever we return null, then we set a flag to say - // that we're awaiting a 'readable' event emission. - this.needReadable = false; - this.emittedReadable = false; - this.readableListening = false; - this.resumeScheduled = false; - - // has it been destroyed - this.destroyed = false; - - // Crypto is kind of old and crusty. Historically, its default string - // encoding is 'binary' so we have to make this configurable. - // Everything else in the universe uses 'utf8', though. - this.defaultEncoding = options.defaultEncoding || 'utf8'; - - // the number of writers that are awaiting a drain event in .pipe()s - this.awaitDrain = 0; - - // if true, a maybeReadMore has been scheduled - this.readingMore = false; - - this.decoder = null; - this.encoding = null; - if (options.encoding) { - if (!StringDecoder) StringDecoder = __webpack_require__(52).StringDecoder; - this.decoder = new StringDecoder(options.encoding); - this.encoding = options.encoding; - } -} - -function Readable(options) { - Duplex = Duplex || __webpack_require__(16); - - if (!(this instanceof Readable)) return new Readable(options); - - this._readableState = new ReadableState(options, this); - - // legacy - this.readable = true; - - if (options) { - if (typeof options.read === 'function') this._read = options.read; - - if (typeof options.destroy === 'function') this._destroy = options.destroy; - } - - Stream.call(this); -} - -Object.defineProperty(Readable.prototype, 'destroyed', { - get: function () { - if (this._readableState === undefined) { - return false; - } - return this._readableState.destroyed; - }, - set: function (value) { - // we ignore the value if the stream - // has not been initialized yet - if (!this._readableState) { - return; - } - - // backward compatibility, the user is explicitly - // managing destroyed - this._readableState.destroyed = value; - } -}); - -Readable.prototype.destroy = destroyImpl.destroy; -Readable.prototype._undestroy = destroyImpl.undestroy; -Readable.prototype._destroy = function (err, cb) { - this.push(null); - cb(err); -}; - -// Manually shove something into the read() buffer. -// This returns true if the highWaterMark has not been hit yet, -// similar to how Writable.write() returns true if you should -// write() some more. -Readable.prototype.push = function (chunk, encoding) { - var state = this._readableState; - var skipChunkCheck; - - if (!state.objectMode) { - if (typeof chunk === 'string') { - encoding = encoding || state.defaultEncoding; - if (encoding !== state.encoding) { - chunk = Buffer.from(chunk, encoding); - encoding = ''; - } - skipChunkCheck = true; - } - } else { - skipChunkCheck = true; - } - - return readableAddChunk(this, chunk, encoding, false, skipChunkCheck); -}; - -// Unshift should *always* be something directly out of read() -Readable.prototype.unshift = function (chunk) { - return readableAddChunk(this, chunk, null, true, false); -}; - -function readableAddChunk(stream, chunk, encoding, addToFront, skipChunkCheck) { - var state = stream._readableState; - if (chunk === null) { - state.reading = false; - onEofChunk(stream, state); - } else { - var er; - if (!skipChunkCheck) er = chunkInvalid(state, chunk); - if (er) { - stream.emit('error', er); - } else if (state.objectMode || chunk && chunk.length > 0) { - if (typeof chunk !== 'string' && !state.objectMode && Object.getPrototypeOf(chunk) !== Buffer.prototype) { - chunk = _uint8ArrayToBuffer(chunk); - } - - if (addToFront) { - if (state.endEmitted) stream.emit('error', new Error('stream.unshift() after end event'));else addChunk(stream, state, chunk, true); - } else if (state.ended) { - stream.emit('error', new Error('stream.push() after EOF')); - } else { - state.reading = false; - if (state.decoder && !encoding) { - chunk = state.decoder.write(chunk); - if (state.objectMode || chunk.length !== 0) addChunk(stream, state, chunk, false);else maybeReadMore(stream, state); - } else { - addChunk(stream, state, chunk, false); - } - } - } else if (!addToFront) { - state.reading = false; - } - } - - return needMoreData(state); -} - -function addChunk(stream, state, chunk, addToFront) { - if (state.flowing && state.length === 0 && !state.sync) { - stream.emit('data', chunk); - stream.read(0); - } else { - // update the buffer info. - state.length += state.objectMode ? 1 : chunk.length; - if (addToFront) state.buffer.unshift(chunk);else state.buffer.push(chunk); - - if (state.needReadable) emitReadable(stream); - } - maybeReadMore(stream, state); -} - -function chunkInvalid(state, chunk) { - var er; - if (!_isUint8Array(chunk) && typeof chunk !== 'string' && chunk !== undefined && !state.objectMode) { - er = new TypeError('Invalid non-string/buffer chunk'); - } - return er; -} - -// if it's past the high water mark, we can push in some more. -// Also, if we have no data yet, we can stand some -// more bytes. This is to work around cases where hwm=0, -// such as the repl. Also, if the push() triggered a -// readable event, and the user called read(largeNumber) such that -// needReadable was set, then we ought to push more, so that another -// 'readable' event will be triggered. -function needMoreData(state) { - return !state.ended && (state.needReadable || state.length < state.highWaterMark || state.length === 0); -} - -Readable.prototype.isPaused = function () { - return this._readableState.flowing === false; -}; - -// backwards compatibility. -Readable.prototype.setEncoding = function (enc) { - if (!StringDecoder) StringDecoder = __webpack_require__(52).StringDecoder; - this._readableState.decoder = new StringDecoder(enc); - this._readableState.encoding = enc; - return this; -}; - -// Don't raise the hwm > 8MB -var MAX_HWM = 0x800000; -function computeNewHighWaterMark(n) { - if (n >= MAX_HWM) { - n = MAX_HWM; - } else { - // Get the next highest power of 2 to prevent increasing hwm excessively in - // tiny amounts - n--; - n |= n >>> 1; - n |= n >>> 2; - n |= n >>> 4; - n |= n >>> 8; - n |= n >>> 16; - n++; - } - return n; -} - -// This function is designed to be inlinable, so please take care when making -// changes to the function body. -function howMuchToRead(n, state) { - if (n <= 0 || state.length === 0 && state.ended) return 0; - if (state.objectMode) return 1; - if (n !== n) { - // Only flow one buffer at a time - if (state.flowing && state.length) return state.buffer.head.data.length;else return state.length; - } - // If we're asking for more than the current hwm, then raise the hwm. - if (n > state.highWaterMark) state.highWaterMark = computeNewHighWaterMark(n); - if (n <= state.length) return n; - // Don't have enough - if (!state.ended) { - state.needReadable = true; - return 0; - } - return state.length; -} - -// you can override either this method, or the async _read(n) below. -Readable.prototype.read = function (n) { - debug('read', n); - n = parseInt(n, 10); - var state = this._readableState; - var nOrig = n; - - if (n !== 0) state.emittedReadable = false; - - // if we're doing read(0) to trigger a readable event, but we - // already have a bunch of data in the buffer, then just trigger - // the 'readable' event and move on. - if (n === 0 && state.needReadable && (state.length >= state.highWaterMark || state.ended)) { - debug('read: emitReadable', state.length, state.ended); - if (state.length === 0 && state.ended) endReadable(this);else emitReadable(this); - return null; - } - - n = howMuchToRead(n, state); - - // if we've ended, and we're now clear, then finish it up. - if (n === 0 && state.ended) { - if (state.length === 0) endReadable(this); - return null; - } - - // All the actual chunk generation logic needs to be - // *below* the call to _read. The reason is that in certain - // synthetic stream cases, such as passthrough streams, _read - // may be a completely synchronous operation which may change - // the state of the read buffer, providing enough data when - // before there was *not* enough. - // - // So, the steps are: - // 1. Figure out what the state of things will be after we do - // a read from the buffer. - // - // 2. If that resulting state will trigger a _read, then call _read. - // Note that this may be asynchronous, or synchronous. Yes, it is - // deeply ugly to write APIs this way, but that still doesn't mean - // that the Readable class should behave improperly, as streams are - // designed to be sync/async agnostic. - // Take note if the _read call is sync or async (ie, if the read call - // has returned yet), so that we know whether or not it's safe to emit - // 'readable' etc. - // - // 3. Actually pull the requested chunks out of the buffer and return. - - // if we need a readable event, then we need to do some reading. - var doRead = state.needReadable; - debug('need readable', doRead); - - // if we currently have less than the highWaterMark, then also read some - if (state.length === 0 || state.length - n < state.highWaterMark) { - doRead = true; - debug('length less than watermark', doRead); - } - - // however, if we've ended, then there's no point, and if we're already - // reading, then it's unnecessary. - if (state.ended || state.reading) { - doRead = false; - debug('reading or ended', doRead); - } else if (doRead) { - debug('do read'); - state.reading = true; - state.sync = true; - // if the length is currently zero, then we *need* a readable event. - if (state.length === 0) state.needReadable = true; - // call internal read method - this._read(state.highWaterMark); - state.sync = false; - // If _read pushed data synchronously, then `reading` will be false, - // and we need to re-evaluate how much data we can return to the user. - if (!state.reading) n = howMuchToRead(nOrig, state); - } - - var ret; - if (n > 0) ret = fromList(n, state);else ret = null; - - if (ret === null) { - state.needReadable = true; - n = 0; - } else { - state.length -= n; - } - - if (state.length === 0) { - // If we have nothing in the buffer, then we want to know - // as soon as we *do* get something into the buffer. - if (!state.ended) state.needReadable = true; - - // If we tried to read() past the EOF, then emit end on the next tick. - if (nOrig !== n && state.ended) endReadable(this); - } - - if (ret !== null) this.emit('data', ret); - - return ret; -}; - -function onEofChunk(stream, state) { - if (state.ended) return; - if (state.decoder) { - var chunk = state.decoder.end(); - if (chunk && chunk.length) { - state.buffer.push(chunk); - state.length += state.objectMode ? 1 : chunk.length; - } - } - state.ended = true; - - // emit 'readable' now to make sure it gets picked up. - emitReadable(stream); -} - -// Don't emit readable right away in sync mode, because this can trigger -// another read() call => stack overflow. This way, it might trigger -// a nextTick recursion warning, but that's not so bad. -function emitReadable(stream) { - var state = stream._readableState; - state.needReadable = false; - if (!state.emittedReadable) { - debug('emitReadable', state.flowing); - state.emittedReadable = true; - if (state.sync) processNextTick(emitReadable_, stream);else emitReadable_(stream); - } -} - -function emitReadable_(stream) { - debug('emit readable'); - stream.emit('readable'); - flow(stream); -} - -// at this point, the user has presumably seen the 'readable' event, -// and called read() to consume some data. that may have triggered -// in turn another _read(n) call, in which case reading = true if -// it's in progress. -// However, if we're not ended, or reading, and the length < hwm, -// then go ahead and try to read some more preemptively. -function maybeReadMore(stream, state) { - if (!state.readingMore) { - state.readingMore = true; - processNextTick(maybeReadMore_, stream, state); - } -} - -function maybeReadMore_(stream, state) { - var len = state.length; - while (!state.reading && !state.flowing && !state.ended && state.length < state.highWaterMark) { - debug('maybeReadMore read 0'); - stream.read(0); - if (len === state.length) - // didn't get any data, stop spinning. - break;else len = state.length; - } - state.readingMore = false; -} - -// abstract method. to be overridden in specific implementation classes. -// call cb(er, data) where data is <= n in length. -// for virtual (non-string, non-buffer) streams, "length" is somewhat -// arbitrary, and perhaps not very meaningful. -Readable.prototype._read = function (n) { - this.emit('error', new Error('_read() is not implemented')); -}; - -Readable.prototype.pipe = function (dest, pipeOpts) { - var src = this; - var state = this._readableState; - - switch (state.pipesCount) { - case 0: - state.pipes = dest; - break; - case 1: - state.pipes = [state.pipes, dest]; - break; - default: - state.pipes.push(dest); - break; - } - state.pipesCount += 1; - debug('pipe count=%d opts=%j', state.pipesCount, pipeOpts); - - var doEnd = (!pipeOpts || pipeOpts.end !== false) && dest !== process.stdout && dest !== process.stderr; - - var endFn = doEnd ? onend : unpipe; - if (state.endEmitted) processNextTick(endFn);else src.once('end', endFn); - - dest.on('unpipe', onunpipe); - function onunpipe(readable, unpipeInfo) { - debug('onunpipe'); - if (readable === src) { - if (unpipeInfo && unpipeInfo.hasUnpiped === false) { - unpipeInfo.hasUnpiped = true; - cleanup(); - } - } - } - - function onend() { - debug('onend'); - dest.end(); - } - - // when the dest drains, it reduces the awaitDrain counter - // on the source. This would be more elegant with a .once() - // handler in flow(), but adding and removing repeatedly is - // too slow. - var ondrain = pipeOnDrain(src); - dest.on('drain', ondrain); - - var cleanedUp = false; - function cleanup() { - debug('cleanup'); - // cleanup event handlers once the pipe is broken - dest.removeListener('close', onclose); - dest.removeListener('finish', onfinish); - dest.removeListener('drain', ondrain); - dest.removeListener('error', onerror); - dest.removeListener('unpipe', onunpipe); - src.removeListener('end', onend); - src.removeListener('end', unpipe); - src.removeListener('data', ondata); - - cleanedUp = true; - - // if the reader is waiting for a drain event from this - // specific writer, then it would cause it to never start - // flowing again. - // So, if this is awaiting a drain, then we just call it now. - // If we don't know, then assume that we are waiting for one. - if (state.awaitDrain && (!dest._writableState || dest._writableState.needDrain)) ondrain(); - } - - // If the user pushes more data while we're writing to dest then we'll end up - // in ondata again. However, we only want to increase awaitDrain once because - // dest will only emit one 'drain' event for the multiple writes. - // => Introduce a guard on increasing awaitDrain. - var increasedAwaitDrain = false; - src.on('data', ondata); - function ondata(chunk) { - debug('ondata'); - increasedAwaitDrain = false; - var ret = dest.write(chunk); - if (false === ret && !increasedAwaitDrain) { - // If the user unpiped during `dest.write()`, it is possible - // to get stuck in a permanently paused state if that write - // also returned false. - // => Check whether `dest` is still a piping destination. - if ((state.pipesCount === 1 && state.pipes === dest || state.pipesCount > 1 && indexOf(state.pipes, dest) !== -1) && !cleanedUp) { - debug('false write response, pause', src._readableState.awaitDrain); - src._readableState.awaitDrain++; - increasedAwaitDrain = true; - } - src.pause(); - } - } - - // if the dest has an error, then stop piping into it. - // however, don't suppress the throwing behavior for this. - function onerror(er) { - debug('onerror', er); - unpipe(); - dest.removeListener('error', onerror); - if (EElistenerCount(dest, 'error') === 0) dest.emit('error', er); - } - - // Make sure our error handler is attached before userland ones. - prependListener(dest, 'error', onerror); - - // Both close and finish should trigger unpipe, but only once. - function onclose() { - dest.removeListener('finish', onfinish); - unpipe(); - } - dest.once('close', onclose); - function onfinish() { - debug('onfinish'); - dest.removeListener('close', onclose); - unpipe(); - } - dest.once('finish', onfinish); - - function unpipe() { - debug('unpipe'); - src.unpipe(dest); - } - - // tell the dest that it's being piped to - dest.emit('pipe', src); - - // start the flow if it hasn't been started already. - if (!state.flowing) { - debug('pipe resume'); - src.resume(); - } - - return dest; -}; - -function pipeOnDrain(src) { - return function () { - var state = src._readableState; - debug('pipeOnDrain', state.awaitDrain); - if (state.awaitDrain) state.awaitDrain--; - if (state.awaitDrain === 0 && EElistenerCount(src, 'data')) { - state.flowing = true; - flow(src); - } - }; -} - -Readable.prototype.unpipe = function (dest) { - var state = this._readableState; - var unpipeInfo = { hasUnpiped: false }; - - // if we're not piping anywhere, then do nothing. - if (state.pipesCount === 0) return this; - - // just one destination. most common case. - if (state.pipesCount === 1) { - // passed in one, but it's not the right one. - if (dest && dest !== state.pipes) return this; - - if (!dest) dest = state.pipes; - - // got a match. - state.pipes = null; - state.pipesCount = 0; - state.flowing = false; - if (dest) dest.emit('unpipe', this, unpipeInfo); - return this; - } - - // slow case. multiple pipe destinations. - - if (!dest) { - // remove all. - var dests = state.pipes; - var len = state.pipesCount; - state.pipes = null; - state.pipesCount = 0; - state.flowing = false; - - for (var i = 0; i < len; i++) { - dests[i].emit('unpipe', this, unpipeInfo); - }return this; - } - - // try to find the right one. - var index = indexOf(state.pipes, dest); - if (index === -1) return this; - - state.pipes.splice(index, 1); - state.pipesCount -= 1; - if (state.pipesCount === 1) state.pipes = state.pipes[0]; - - dest.emit('unpipe', this, unpipeInfo); - - return this; -}; - -// set up data events if they are asked for -// Ensure readable listeners eventually get something -Readable.prototype.on = function (ev, fn) { - var res = Stream.prototype.on.call(this, ev, fn); - - if (ev === 'data') { - // Start flowing on next tick if stream isn't explicitly paused - if (this._readableState.flowing !== false) this.resume(); - } else if (ev === 'readable') { - var state = this._readableState; - if (!state.endEmitted && !state.readableListening) { - state.readableListening = state.needReadable = true; - state.emittedReadable = false; - if (!state.reading) { - processNextTick(nReadingNextTick, this); - } else if (state.length) { - emitReadable(this); - } - } - } - - return res; -}; -Readable.prototype.addListener = Readable.prototype.on; - -function nReadingNextTick(self) { - debug('readable nexttick read 0'); - self.read(0); -} - -// pause() and resume() are remnants of the legacy readable stream API -// If the user uses them, then switch into old mode. -Readable.prototype.resume = function () { - var state = this._readableState; - if (!state.flowing) { - debug('resume'); - state.flowing = true; - resume(this, state); - } - return this; -}; - -function resume(stream, state) { - if (!state.resumeScheduled) { - state.resumeScheduled = true; - processNextTick(resume_, stream, state); - } -} - -function resume_(stream, state) { - if (!state.reading) { - debug('resume read 0'); - stream.read(0); - } - - state.resumeScheduled = false; - state.awaitDrain = 0; - stream.emit('resume'); - flow(stream); - if (state.flowing && !state.reading) stream.read(0); -} - -Readable.prototype.pause = function () { - debug('call pause flowing=%j', this._readableState.flowing); - if (false !== this._readableState.flowing) { - debug('pause'); - this._readableState.flowing = false; - this.emit('pause'); - } - return this; -}; - -function flow(stream) { - var state = stream._readableState; - debug('flow', state.flowing); - while (state.flowing && stream.read() !== null) {} -} - -// wrap an old-style stream as the async data source. -// This is *not* part of the readable stream interface. -// It is an ugly unfortunate mess of history. -Readable.prototype.wrap = function (stream) { - var state = this._readableState; - var paused = false; - - var self = this; - stream.on('end', function () { - debug('wrapped end'); - if (state.decoder && !state.ended) { - var chunk = state.decoder.end(); - if (chunk && chunk.length) self.push(chunk); - } - - self.push(null); - }); - - stream.on('data', function (chunk) { - debug('wrapped data'); - if (state.decoder) chunk = state.decoder.write(chunk); - - // don't skip over falsy values in objectMode - if (state.objectMode && (chunk === null || chunk === undefined)) return;else if (!state.objectMode && (!chunk || !chunk.length)) return; - - var ret = self.push(chunk); - if (!ret) { - paused = true; - stream.pause(); - } - }); - - // proxy all the other methods. - // important when wrapping filters and duplexes. - for (var i in stream) { - if (this[i] === undefined && typeof stream[i] === 'function') { - this[i] = function (method) { - return function () { - return stream[method].apply(stream, arguments); - }; - }(i); - } - } - - // proxy certain important events. - for (var n = 0; n < kProxyEvents.length; n++) { - stream.on(kProxyEvents[n], self.emit.bind(self, kProxyEvents[n])); - } - - // when we try to consume some more bytes, simply unpause the - // underlying stream. - self._read = function (n) { - debug('wrapped _read', n); - if (paused) { - paused = false; - stream.resume(); - } - }; - - return self; -}; - -// exposed for testing purposes only. -Readable._fromList = fromList; - -// Pluck off n bytes from an array of buffers. -// Length is the combined lengths of all the buffers in the list. -// This function is designed to be inlinable, so please take care when making -// changes to the function body. -function fromList(n, state) { - // nothing buffered - if (state.length === 0) return null; - - var ret; - if (state.objectMode) ret = state.buffer.shift();else if (!n || n >= state.length) { - // read it all, truncate the list - if (state.decoder) ret = state.buffer.join('');else if (state.buffer.length === 1) ret = state.buffer.head.data;else ret = state.buffer.concat(state.length); - state.buffer.clear(); - } else { - // read part of list - ret = fromListPartial(n, state.buffer, state.decoder); - } - - return ret; -} - -// Extracts only enough buffered data to satisfy the amount requested. -// This function is designed to be inlinable, so please take care when making -// changes to the function body. -function fromListPartial(n, list, hasStrings) { - var ret; - if (n < list.head.data.length) { - // slice is the same for buffers and strings - ret = list.head.data.slice(0, n); - list.head.data = list.head.data.slice(n); - } else if (n === list.head.data.length) { - // first chunk is a perfect match - ret = list.shift(); - } else { - // result spans more than one buffer - ret = hasStrings ? copyFromBufferString(n, list) : copyFromBuffer(n, list); - } - return ret; -} - -// Copies a specified amount of characters from the list of buffered data -// chunks. -// This function is designed to be inlinable, so please take care when making -// changes to the function body. -function copyFromBufferString(n, list) { - var p = list.head; - var c = 1; - var ret = p.data; - n -= ret.length; - while (p = p.next) { - var str = p.data; - var nb = n > str.length ? str.length : n; - if (nb === str.length) ret += str;else ret += str.slice(0, n); - n -= nb; - if (n === 0) { - if (nb === str.length) { - ++c; - if (p.next) list.head = p.next;else list.head = list.tail = null; - } else { - list.head = p; - p.data = str.slice(nb); - } - break; - } - ++c; - } - list.length -= c; - return ret; -} - -// Copies a specified amount of bytes from the list of buffered data chunks. -// This function is designed to be inlinable, so please take care when making -// changes to the function body. -function copyFromBuffer(n, list) { - var ret = Buffer.allocUnsafe(n); - var p = list.head; - var c = 1; - p.data.copy(ret); - n -= p.data.length; - while (p = p.next) { - var buf = p.data; - var nb = n > buf.length ? buf.length : n; - buf.copy(ret, ret.length - n, 0, nb); - n -= nb; - if (n === 0) { - if (nb === buf.length) { - ++c; - if (p.next) list.head = p.next;else list.head = list.tail = null; - } else { - list.head = p; - p.data = buf.slice(nb); - } - break; - } - ++c; - } - list.length -= c; - return ret; -} - -function endReadable(stream) { - var state = stream._readableState; - - // If we get here before consuming all the bytes, then that is a - // bug in node. Should never happen. - if (state.length > 0) throw new Error('"endReadable()" called on non-empty stream'); - - if (!state.endEmitted) { - state.ended = true; - processNextTick(endReadableNT, state, stream); - } -} - -function endReadableNT(state, stream) { - // Check that we didn't get one last unshift. - if (!state.endEmitted && state.length === 0) { - state.endEmitted = true; - stream.readable = false; - stream.emit('end'); - } -} - -function forEach(xs, f) { - for (var i = 0, l = xs.length; i < l; i++) { - f(xs[i], i); - } -} - -function indexOf(xs, x) { - for (var i = 0, l = xs.length; i < l; i++) { - if (xs[i] === x) return i; - } - return -1; -} -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(7), __webpack_require__(8))) - -/***/ }), -/* 50 */ -/***/ (function(module, exports, __webpack_require__) { - -module.exports = __webpack_require__(15).EventEmitter; - - -/***/ }), -/* 51 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -/**/ - -var processNextTick = __webpack_require__(27); -/**/ - -// undocumented cb() API, needed for core, not for public API -function destroy(err, cb) { - var _this = this; - - var readableDestroyed = this._readableState && this._readableState.destroyed; - var writableDestroyed = this._writableState && this._writableState.destroyed; - - if (readableDestroyed || writableDestroyed) { - if (cb) { - cb(err); - } else if (err && (!this._writableState || !this._writableState.errorEmitted)) { - processNextTick(emitErrorNT, this, err); - } - return; - } - - // we set destroyed to true before firing error callbacks in order - // to make it re-entrance safe in case destroy() is called within callbacks - - if (this._readableState) { - this._readableState.destroyed = true; - } - - // if this is a duplex stream mark the writable part as destroyed as well - if (this._writableState) { - this._writableState.destroyed = true; - } - - this._destroy(err || null, function (err) { - if (!cb && err) { - processNextTick(emitErrorNT, _this, err); - if (_this._writableState) { - _this._writableState.errorEmitted = true; - } - } else if (cb) { - cb(err); - } - }); -} - -function undestroy() { - if (this._readableState) { - this._readableState.destroyed = false; - this._readableState.reading = false; - this._readableState.ended = false; - this._readableState.endEmitted = false; - } - - if (this._writableState) { - this._writableState.destroyed = false; - this._writableState.ended = false; - this._writableState.ending = false; - this._writableState.finished = false; - this._writableState.errorEmitted = false; - } -} - -function emitErrorNT(self, err) { - self.emit('error', err); -} - -module.exports = { - destroy: destroy, - undestroy: undestroy -}; - -/***/ }), -/* 52 */ -/***/ (function(module, exports, __webpack_require__) { - -// Copyright Joyent, Inc. and other Node contributors. -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to permit -// persons to whom the Software is furnished to do so, subject to the -// following conditions: -// -// The above copyright notice and this permission notice shall be included -// in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN -// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE -// USE OR OTHER DEALINGS IN THE SOFTWARE. - -var Buffer = __webpack_require__(5).Buffer; - -var isBufferEncoding = Buffer.isEncoding - || function(encoding) { - switch (encoding && encoding.toLowerCase()) { - case 'hex': case 'utf8': case 'utf-8': case 'ascii': case 'binary': case 'base64': case 'ucs2': case 'ucs-2': case 'utf16le': case 'utf-16le': case 'raw': return true; - default: return false; - } - } - - -function assertEncoding(encoding) { - if (encoding && !isBufferEncoding(encoding)) { - throw new Error('Unknown encoding: ' + encoding); - } -} - -// StringDecoder provides an interface for efficiently splitting a series of -// buffers into a series of JS strings without breaking apart multi-byte -// characters. CESU-8 is handled as part of the UTF-8 encoding. -// -// @TODO Handling all encodings inside a single object makes it very difficult -// to reason about this code, so it should be split up in the future. -// @TODO There should be a utf8-strict encoding that rejects invalid UTF-8 code -// points as used by CESU-8. -var StringDecoder = exports.StringDecoder = function(encoding) { - this.encoding = (encoding || 'utf8').toLowerCase().replace(/[-_]/, ''); - assertEncoding(encoding); - switch (this.encoding) { - case 'utf8': - // CESU-8 represents each of Surrogate Pair by 3-bytes - this.surrogateSize = 3; - break; - case 'ucs2': - case 'utf16le': - // UTF-16 represents each of Surrogate Pair by 2-bytes - this.surrogateSize = 2; - this.detectIncompleteChar = utf16DetectIncompleteChar; - break; - case 'base64': - // Base-64 stores 3 bytes in 4 chars, and pads the remainder. - this.surrogateSize = 3; - this.detectIncompleteChar = base64DetectIncompleteChar; - break; - default: - this.write = passThroughWrite; - return; - } - - // Enough space to store all bytes of a single character. UTF-8 needs 4 - // bytes, but CESU-8 may require up to 6 (3 bytes per surrogate). - this.charBuffer = new Buffer(6); - // Number of bytes received for the current incomplete multi-byte character. - this.charReceived = 0; - // Number of bytes expected for the current incomplete multi-byte character. - this.charLength = 0; -}; - - -// write decodes the given buffer and returns it as JS string that is -// guaranteed to not contain any partial multi-byte characters. Any partial -// character found at the end of the buffer is buffered up, and will be -// returned when calling write again with the remaining bytes. -// -// Note: Converting a Buffer containing an orphan surrogate to a String -// currently works, but converting a String to a Buffer (via `new Buffer`, or -// Buffer#write) will replace incomplete surrogates with the unicode -// replacement character. See https://codereview.chromium.org/121173009/ . -StringDecoder.prototype.write = function(buffer) { - var charStr = ''; - // if our last write ended with an incomplete multibyte character - while (this.charLength) { - // determine how many remaining bytes this buffer has to offer for this char - var available = (buffer.length >= this.charLength - this.charReceived) ? - this.charLength - this.charReceived : - buffer.length; - - // add the new bytes to the char buffer - buffer.copy(this.charBuffer, this.charReceived, 0, available); - this.charReceived += available; - - if (this.charReceived < this.charLength) { - // still not enough chars in this buffer? wait for more ... - return ''; - } - - // remove bytes belonging to the current character from the buffer - buffer = buffer.slice(available, buffer.length); - - // get the character that was split - charStr = this.charBuffer.slice(0, this.charLength).toString(this.encoding); - - // CESU-8: lead surrogate (D800-DBFF) is also the incomplete character - var charCode = charStr.charCodeAt(charStr.length - 1); - if (charCode >= 0xD800 && charCode <= 0xDBFF) { - this.charLength += this.surrogateSize; - charStr = ''; - continue; - } - this.charReceived = this.charLength = 0; - - // if there are no more bytes in this buffer, just emit our char - if (buffer.length === 0) { - return charStr; - } - break; - } - - // determine and set charLength / charReceived - this.detectIncompleteChar(buffer); - - var end = buffer.length; - if (this.charLength) { - // buffer the incomplete character bytes we got - buffer.copy(this.charBuffer, 0, buffer.length - this.charReceived, end); - end -= this.charReceived; - } - - charStr += buffer.toString(this.encoding, 0, end); - - var end = charStr.length - 1; - var charCode = charStr.charCodeAt(end); - // CESU-8: lead surrogate (D800-DBFF) is also the incomplete character - if (charCode >= 0xD800 && charCode <= 0xDBFF) { - var size = this.surrogateSize; - this.charLength += size; - this.charReceived += size; - this.charBuffer.copy(this.charBuffer, size, 0, size); - buffer.copy(this.charBuffer, 0, 0, size); - return charStr.substring(0, end); - } - - // or just emit the charStr - return charStr; -}; - -// detectIncompleteChar determines if there is an incomplete UTF-8 character at -// the end of the given buffer. If so, it sets this.charLength to the byte -// length that character, and sets this.charReceived to the number of bytes -// that are available for this character. -StringDecoder.prototype.detectIncompleteChar = function(buffer) { - // determine how many bytes we have to check at the end of this buffer - var i = (buffer.length >= 3) ? 3 : buffer.length; - - // Figure out if one of the last i bytes of our buffer announces an - // incomplete char. - for (; i > 0; i--) { - var c = buffer[buffer.length - i]; - - // See http://en.wikipedia.org/wiki/UTF-8#Description - - // 110XXXXX - if (i == 1 && c >> 5 == 0x06) { - this.charLength = 2; - break; - } - - // 1110XXXX - if (i <= 2 && c >> 4 == 0x0E) { - this.charLength = 3; - break; - } - - // 11110XXX - if (i <= 3 && c >> 3 == 0x1E) { - this.charLength = 4; - break; - } - } - this.charReceived = i; -}; - -StringDecoder.prototype.end = function(buffer) { - var res = ''; - if (buffer && buffer.length) - res = this.write(buffer); - - if (this.charReceived) { - var cr = this.charReceived; - var buf = this.charBuffer; - var enc = this.encoding; - res += buf.slice(0, cr).toString(enc); - } - - return res; -}; - -function passThroughWrite(buffer) { - return buffer.toString(this.encoding); -} - -function utf16DetectIncompleteChar(buffer) { - this.charReceived = buffer.length % 2; - this.charLength = this.charReceived ? 2 : 0; -} - -function base64DetectIncompleteChar(buffer) { - this.charReceived = buffer.length % 3; - this.charLength = this.charReceived ? 3 : 0; -} - - -/***/ }), -/* 53 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -// Copyright Joyent, Inc. and other Node contributors. -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to permit -// persons to whom the Software is furnished to do so, subject to the -// following conditions: -// -// The above copyright notice and this permission notice shall be included -// in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN -// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE -// USE OR OTHER DEALINGS IN THE SOFTWARE. - -// a transform stream is a readable/writable stream where you do -// something with the data. Sometimes it's called a "filter", -// but that's not a great name for it, since that implies a thing where -// some bits pass through, and others are simply ignored. (That would -// be a valid example of a transform, of course.) -// -// While the output is causally related to the input, it's not a -// necessarily symmetric or synchronous transformation. For example, -// a zlib stream might take multiple plain-text writes(), and then -// emit a single compressed chunk some time in the future. -// -// Here's how this works: -// -// The Transform stream has all the aspects of the readable and writable -// stream classes. When you write(chunk), that calls _write(chunk,cb) -// internally, and returns false if there's a lot of pending writes -// buffered up. When you call read(), that calls _read(n) until -// there's enough pending readable data buffered up. -// -// In a transform stream, the written data is placed in a buffer. When -// _read(n) is called, it transforms the queued up data, calling the -// buffered _write cb's as it consumes chunks. If consuming a single -// written chunk would result in multiple output chunks, then the first -// outputted bit calls the readcb, and subsequent chunks just go into -// the read buffer, and will cause it to emit 'readable' if necessary. -// -// This way, back-pressure is actually determined by the reading side, -// since _read has to be called to start processing a new chunk. However, -// a pathological inflate type of transform can cause excessive buffering -// here. For example, imagine a stream where every byte of input is -// interpreted as an integer from 0-255, and then results in that many -// bytes of output. Writing the 4 bytes {ff,ff,ff,ff} would result in -// 1kb of data being output. In this case, you could write a very small -// amount of input, and end up with a very large amount of output. In -// such a pathological inflating mechanism, there'd be no way to tell -// the system to stop doing the transform. A single 4MB write could -// cause the system to run out of memory. -// -// However, even in such a pathological case, only a single written chunk -// would be consumed, and then the rest would wait (un-transformed) until -// the results of the previous transformed chunk were consumed. - - - -module.exports = Transform; - -var Duplex = __webpack_require__(16); - -/**/ -var util = __webpack_require__(24); -util.inherits = __webpack_require__(14); -/**/ - -util.inherits(Transform, Duplex); - -function TransformState(stream) { - this.afterTransform = function (er, data) { - return afterTransform(stream, er, data); - }; - - this.needTransform = false; - this.transforming = false; - this.writecb = null; - this.writechunk = null; - this.writeencoding = null; -} - -function afterTransform(stream, er, data) { - var ts = stream._transformState; - ts.transforming = false; - - var cb = ts.writecb; - - if (!cb) { - return stream.emit('error', new Error('write callback called multiple times')); - } - - ts.writechunk = null; - ts.writecb = null; - - if (data !== null && data !== undefined) stream.push(data); - - cb(er); - - var rs = stream._readableState; - rs.reading = false; - if (rs.needReadable || rs.length < rs.highWaterMark) { - stream._read(rs.highWaterMark); - } -} - -function Transform(options) { - if (!(this instanceof Transform)) return new Transform(options); - - Duplex.call(this, options); - - this._transformState = new TransformState(this); - - var stream = this; - - // start out asking for a readable event once data is transformed. - this._readableState.needReadable = true; - - // we have implemented the _read method, and done the other things - // that Readable wants before the first _read call, so unset the - // sync guard flag. - this._readableState.sync = false; - - if (options) { - if (typeof options.transform === 'function') this._transform = options.transform; - - if (typeof options.flush === 'function') this._flush = options.flush; - } - - // When the writable side finishes, then flush out anything remaining. - this.once('prefinish', function () { - if (typeof this._flush === 'function') this._flush(function (er, data) { - done(stream, er, data); - });else done(stream); - }); -} - -Transform.prototype.push = function (chunk, encoding) { - this._transformState.needTransform = false; - return Duplex.prototype.push.call(this, chunk, encoding); -}; - -// This is the part where you do stuff! -// override this function in implementation classes. -// 'chunk' is an input chunk. -// -// Call `push(newChunk)` to pass along transformed output -// to the readable side. You may call 'push' zero or more times. -// -// Call `cb(err)` when you are done with this chunk. If you pass -// an error, then that'll put the hurt on the whole operation. If you -// never call cb(), then you'll never get another chunk. -Transform.prototype._transform = function (chunk, encoding, cb) { - throw new Error('_transform() is not implemented'); -}; - -Transform.prototype._write = function (chunk, encoding, cb) { - var ts = this._transformState; - ts.writecb = cb; - ts.writechunk = chunk; - ts.writeencoding = encoding; - if (!ts.transforming) { - var rs = this._readableState; - if (ts.needTransform || rs.needReadable || rs.length < rs.highWaterMark) this._read(rs.highWaterMark); - } -}; - -// Doesn't matter what the args are here. -// _transform does all the work. -// That we got here means that the readable side wants more data. -Transform.prototype._read = function (n) { - var ts = this._transformState; - - if (ts.writechunk !== null && ts.writecb && !ts.transforming) { - ts.transforming = true; - this._transform(ts.writechunk, ts.writeencoding, ts.afterTransform); - } else { - // mark that we need a transform, so that any data that comes in - // will get processed, now that we've asked for it. - ts.needTransform = true; - } -}; - -Transform.prototype._destroy = function (err, cb) { - var _this = this; - - Duplex.prototype._destroy.call(this, err, function (err2) { - cb(err2); - _this.emit('close'); - }); -}; - -function done(stream, er, data) { - if (er) return stream.emit('error', er); - - if (data !== null && data !== undefined) stream.push(data); - - // if there's nothing in the write buffer, then that means - // that nothing more will ever be provided - var ws = stream._writableState; - var ts = stream._transformState; - - if (ws.length) throw new Error('Calling transform done when ws.length != 0'); - - if (ts.transforming) throw new Error('Calling transform done when still transforming'); - - return stream.push(null); -} - -/***/ }), -/* 54 */ -/***/ (function(module, exports, __webpack_require__) { - -/* WEBPACK VAR INJECTION */(function(global) {var ClientRequest = __webpack_require__(95) -var extend = __webpack_require__(98) -var statusCodes = __webpack_require__(99) -var url = __webpack_require__(56) - -var http = exports - -http.request = function (opts, cb) { - if (typeof opts === 'string') - opts = url.parse(opts) - else - opts = extend(opts) - - // Normally, the page is loaded from http or https, so not specifying a protocol - // will result in a (valid) protocol-relative url. However, this won't work if - // the protocol is something else, like 'file:' - var defaultProtocol = global.location.protocol.search(/^https?:$/) === -1 ? 'http:' : '' - - var protocol = opts.protocol || defaultProtocol - var host = opts.hostname || opts.host - var port = opts.port - var path = opts.path || '/' - - // Necessary for IPv6 addresses - if (host && host.indexOf(':') !== -1) - host = '[' + host + ']' - - // This may be a relative url. The browser should always be able to interpret it correctly. - opts.url = (host ? (protocol + '//' + host) : '') + (port ? ':' + port : '') + path - opts.method = (opts.method || 'GET').toUpperCase() - opts.headers = opts.headers || {} - - // Also valid opts.auth, opts.mode - - var req = new ClientRequest(opts) - if (cb) - req.on('response', cb) - return req -} - -http.get = function get (opts, cb) { - var req = http.request(opts, cb) - req.end() - return req -} - -http.Agent = function () {} -http.Agent.defaultMaxSockets = 4 - -http.STATUS_CODES = statusCodes - -http.METHODS = [ - 'CHECKOUT', - 'CONNECT', - 'COPY', - 'DELETE', - 'GET', - 'HEAD', - 'LOCK', - 'M-SEARCH', - 'MERGE', - 'MKACTIVITY', - 'MKCOL', - 'MOVE', - 'NOTIFY', - 'OPTIONS', - 'PATCH', - 'POST', - 'PROPFIND', - 'PROPPATCH', - 'PURGE', - 'PUT', - 'REPORT', - 'SEARCH', - 'SUBSCRIBE', - 'TRACE', - 'UNLOCK', - 'UNSUBSCRIBE' -] -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(7))) - -/***/ }), -/* 55 */ -/***/ (function(module, exports, __webpack_require__) { - -/* WEBPACK VAR INJECTION */(function(global) {exports.fetch = isFunction(global.fetch) && isFunction(global.ReadableStream) - -exports.blobConstructor = false -try { - new Blob([new ArrayBuffer(1)]) - exports.blobConstructor = true -} catch (e) {} - -// The xhr request to example.com may violate some restrictive CSP configurations, -// so if we're running in a browser that supports `fetch`, avoid calling getXHR() -// and assume support for certain features below. -var xhr -function getXHR () { - // Cache the xhr value - if (xhr !== undefined) return xhr - - if (global.XMLHttpRequest) { - xhr = new global.XMLHttpRequest() - // If XDomainRequest is available (ie only, where xhr might not work - // cross domain), use the page location. Otherwise use example.com - // Note: this doesn't actually make an http request. - try { - xhr.open('GET', global.XDomainRequest ? '/' : 'https://example.com') - } catch(e) { - xhr = null - } - } else { - // Service workers don't have XHR - xhr = null - } - return xhr -} - -function checkTypeSupport (type) { - var xhr = getXHR() - if (!xhr) return false - try { - xhr.responseType = type - return xhr.responseType === type - } catch (e) {} - return false -} - -// For some strange reason, Safari 7.0 reports typeof global.ArrayBuffer === 'object'. -// Safari 7.1 appears to have fixed this bug. -var haveArrayBuffer = typeof global.ArrayBuffer !== 'undefined' -var haveSlice = haveArrayBuffer && isFunction(global.ArrayBuffer.prototype.slice) - -// If fetch is supported, then arraybuffer will be supported too. Skip calling -// checkTypeSupport(), since that calls getXHR(). -exports.arraybuffer = exports.fetch || (haveArrayBuffer && checkTypeSupport('arraybuffer')) - -// These next two tests unavoidably show warnings in Chrome. Since fetch will always -// be used if it's available, just return false for these to avoid the warnings. -exports.msstream = !exports.fetch && haveSlice && checkTypeSupport('ms-stream') -exports.mozchunkedarraybuffer = !exports.fetch && haveArrayBuffer && - checkTypeSupport('moz-chunked-arraybuffer') - -// If fetch is supported, then overrideMimeType will be supported too. Skip calling -// getXHR(). -exports.overrideMimeType = exports.fetch || (getXHR() ? isFunction(getXHR().overrideMimeType) : false) - -exports.vbArray = isFunction(global.VBArray) - -function isFunction (value) { - return typeof value === 'function' -} - -xhr = null // Help gc - -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(7))) - -/***/ }), -/* 56 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -// Copyright Joyent, Inc. and other Node contributors. -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to permit -// persons to whom the Software is furnished to do so, subject to the -// following conditions: -// -// The above copyright notice and this permission notice shall be included -// in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN -// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE -// USE OR OTHER DEALINGS IN THE SOFTWARE. - - - -var punycode = __webpack_require__(100); -var util = __webpack_require__(102); - -exports.parse = urlParse; -exports.resolve = urlResolve; -exports.resolveObject = urlResolveObject; -exports.format = urlFormat; - -exports.Url = Url; - -function Url() { - this.protocol = null; - this.slashes = null; - this.auth = null; - this.host = null; - this.port = null; - this.hostname = null; - this.hash = null; - this.search = null; - this.query = null; - this.pathname = null; - this.path = null; - this.href = null; -} - -// Reference: RFC 3986, RFC 1808, RFC 2396 - -// define these here so at least they only have to be -// compiled once on the first module load. -var protocolPattern = /^([a-z0-9.+-]+:)/i, - portPattern = /:[0-9]*$/, - - // Special case for a simple path URL - simplePathPattern = /^(\/\/?(?!\/)[^\?\s]*)(\?[^\s]*)?$/, - - // RFC 2396: characters reserved for delimiting URLs. - // We actually just auto-escape these. - delims = ['<', '>', '"', '`', ' ', '\r', '\n', '\t'], - - // RFC 2396: characters not allowed for various reasons. - unwise = ['{', '}', '|', '\\', '^', '`'].concat(delims), - - // Allowed by RFCs, but cause of XSS attacks. Always escape these. - autoEscape = ['\''].concat(unwise), - // Characters that are never ever allowed in a hostname. - // Note that any invalid chars are also handled, but these - // are the ones that are *expected* to be seen, so we fast-path - // them. - nonHostChars = ['%', '/', '?', ';', '#'].concat(autoEscape), - hostEndingChars = ['/', '?', '#'], - hostnameMaxLen = 255, - hostnamePartPattern = /^[+a-z0-9A-Z_-]{0,63}$/, - hostnamePartStart = /^([+a-z0-9A-Z_-]{0,63})(.*)$/, - // protocols that can allow "unsafe" and "unwise" chars. - unsafeProtocol = { - 'javascript': true, - 'javascript:': true - }, - // protocols that never have a hostname. - hostlessProtocol = { - 'javascript': true, - 'javascript:': true - }, - // protocols that always contain a // bit. - slashedProtocol = { - 'http': true, - 'https': true, - 'ftp': true, - 'gopher': true, - 'file': true, - 'http:': true, - 'https:': true, - 'ftp:': true, - 'gopher:': true, - 'file:': true - }, - querystring = __webpack_require__(28); - -function urlParse(url, parseQueryString, slashesDenoteHost) { - if (url && util.isObject(url) && url instanceof Url) return url; - - var u = new Url; - u.parse(url, parseQueryString, slashesDenoteHost); - return u; -} - -Url.prototype.parse = function(url, parseQueryString, slashesDenoteHost) { - if (!util.isString(url)) { - throw new TypeError("Parameter 'url' must be a string, not " + typeof url); - } - - // Copy chrome, IE, opera backslash-handling behavior. - // Back slashes before the query string get converted to forward slashes - // See: https://code.google.com/p/chromium/issues/detail?id=25916 - var queryIndex = url.indexOf('?'), - splitter = - (queryIndex !== -1 && queryIndex < url.indexOf('#')) ? '?' : '#', - uSplit = url.split(splitter), - slashRegex = /\\/g; - uSplit[0] = uSplit[0].replace(slashRegex, '/'); - url = uSplit.join(splitter); - - var rest = url; - - // trim before proceeding. - // This is to support parse stuff like " http://foo.com \n" - rest = rest.trim(); - - if (!slashesDenoteHost && url.split('#').length === 1) { - // Try fast path regexp - var simplePath = simplePathPattern.exec(rest); - if (simplePath) { - this.path = rest; - this.href = rest; - this.pathname = simplePath[1]; - if (simplePath[2]) { - this.search = simplePath[2]; - if (parseQueryString) { - this.query = querystring.parse(this.search.substr(1)); - } else { - this.query = this.search.substr(1); - } - } else if (parseQueryString) { - this.search = ''; - this.query = {}; - } - return this; - } - } - - var proto = protocolPattern.exec(rest); - if (proto) { - proto = proto[0]; - var lowerProto = proto.toLowerCase(); - this.protocol = lowerProto; - rest = rest.substr(proto.length); - } - - // figure out if it's got a host - // user@server is *always* interpreted as a hostname, and url - // resolution will treat //foo/bar as host=foo,path=bar because that's - // how the browser resolves relative URLs. - if (slashesDenoteHost || proto || rest.match(/^\/\/[^@\/]+@[^@\/]+/)) { - var slashes = rest.substr(0, 2) === '//'; - if (slashes && !(proto && hostlessProtocol[proto])) { - rest = rest.substr(2); - this.slashes = true; - } - } - - if (!hostlessProtocol[proto] && - (slashes || (proto && !slashedProtocol[proto]))) { - - // there's a hostname. - // the first instance of /, ?, ;, or # ends the host. - // - // If there is an @ in the hostname, then non-host chars *are* allowed - // to the left of the last @ sign, unless some host-ending character - // comes *before* the @-sign. - // URLs are obnoxious. - // - // ex: - // http://a@b@c/ => user:a@b host:c - // http://a@b?@c => user:a host:c path:/?@c - - // v0.12 TODO(isaacs): This is not quite how Chrome does things. - // Review our test case against browsers more comprehensively. - - // find the first instance of any hostEndingChars - var hostEnd = -1; - for (var i = 0; i < hostEndingChars.length; i++) { - var hec = rest.indexOf(hostEndingChars[i]); - if (hec !== -1 && (hostEnd === -1 || hec < hostEnd)) - hostEnd = hec; - } - - // at this point, either we have an explicit point where the - // auth portion cannot go past, or the last @ char is the decider. - var auth, atSign; - if (hostEnd === -1) { - // atSign can be anywhere. - atSign = rest.lastIndexOf('@'); - } else { - // atSign must be in auth portion. - // http://a@b/c@d => host:b auth:a path:/c@d - atSign = rest.lastIndexOf('@', hostEnd); - } - - // Now we have a portion which is definitely the auth. - // Pull that off. - if (atSign !== -1) { - auth = rest.slice(0, atSign); - rest = rest.slice(atSign + 1); - this.auth = decodeURIComponent(auth); - } - - // the host is the remaining to the left of the first non-host char - hostEnd = -1; - for (var i = 0; i < nonHostChars.length; i++) { - var hec = rest.indexOf(nonHostChars[i]); - if (hec !== -1 && (hostEnd === -1 || hec < hostEnd)) - hostEnd = hec; - } - // if we still have not hit it, then the entire thing is a host. - if (hostEnd === -1) - hostEnd = rest.length; - - this.host = rest.slice(0, hostEnd); - rest = rest.slice(hostEnd); - - // pull out port. - this.parseHost(); - - // we've indicated that there is a hostname, - // so even if it's empty, it has to be present. - this.hostname = this.hostname || ''; - - // if hostname begins with [ and ends with ] - // assume that it's an IPv6 address. - var ipv6Hostname = this.hostname[0] === '[' && - this.hostname[this.hostname.length - 1] === ']'; - - // validate a little. - if (!ipv6Hostname) { - var hostparts = this.hostname.split(/\./); - for (var i = 0, l = hostparts.length; i < l; i++) { - var part = hostparts[i]; - if (!part) continue; - if (!part.match(hostnamePartPattern)) { - var newpart = ''; - for (var j = 0, k = part.length; j < k; j++) { - if (part.charCodeAt(j) > 127) { - // we replace non-ASCII char with a temporary placeholder - // we need this to make sure size of hostname is not - // broken by replacing non-ASCII by nothing - newpart += 'x'; - } else { - newpart += part[j]; - } - } - // we test again with ASCII char only - if (!newpart.match(hostnamePartPattern)) { - var validParts = hostparts.slice(0, i); - var notHost = hostparts.slice(i + 1); - var bit = part.match(hostnamePartStart); - if (bit) { - validParts.push(bit[1]); - notHost.unshift(bit[2]); - } - if (notHost.length) { - rest = '/' + notHost.join('.') + rest; - } - this.hostname = validParts.join('.'); - break; - } - } - } - } - - if (this.hostname.length > hostnameMaxLen) { - this.hostname = ''; - } else { - // hostnames are always lower case. - this.hostname = this.hostname.toLowerCase(); - } - - if (!ipv6Hostname) { - // IDNA Support: Returns a punycoded representation of "domain". - // It only converts parts of the domain name that - // have non-ASCII characters, i.e. it doesn't matter if - // you call it with a domain that already is ASCII-only. - this.hostname = punycode.toASCII(this.hostname); - } - - var p = this.port ? ':' + this.port : ''; - var h = this.hostname || ''; - this.host = h + p; - this.href += this.host; - - // strip [ and ] from the hostname - // the host field still retains them, though - if (ipv6Hostname) { - this.hostname = this.hostname.substr(1, this.hostname.length - 2); - if (rest[0] !== '/') { - rest = '/' + rest; - } - } - } - - // now rest is set to the post-host stuff. - // chop off any delim chars. - if (!unsafeProtocol[lowerProto]) { - - // First, make 100% sure that any "autoEscape" chars get - // escaped, even if encodeURIComponent doesn't think they - // need to be. - for (var i = 0, l = autoEscape.length; i < l; i++) { - var ae = autoEscape[i]; - if (rest.indexOf(ae) === -1) - continue; - var esc = encodeURIComponent(ae); - if (esc === ae) { - esc = escape(ae); - } - rest = rest.split(ae).join(esc); - } - } - - - // chop off from the tail first. - var hash = rest.indexOf('#'); - if (hash !== -1) { - // got a fragment string. - this.hash = rest.substr(hash); - rest = rest.slice(0, hash); - } - var qm = rest.indexOf('?'); - if (qm !== -1) { - this.search = rest.substr(qm); - this.query = rest.substr(qm + 1); - if (parseQueryString) { - this.query = querystring.parse(this.query); - } - rest = rest.slice(0, qm); - } else if (parseQueryString) { - // no query string, but parseQueryString still requested - this.search = ''; - this.query = {}; - } - if (rest) this.pathname = rest; - if (slashedProtocol[lowerProto] && - this.hostname && !this.pathname) { - this.pathname = '/'; - } - - //to support http.request - if (this.pathname || this.search) { - var p = this.pathname || ''; - var s = this.search || ''; - this.path = p + s; - } - - // finally, reconstruct the href based on what has been validated. - this.href = this.format(); - return this; -}; - -// format a parsed object into a url string -function urlFormat(obj) { - // ensure it's an object, and not a string url. - // If it's an obj, this is a no-op. - // this way, you can call url_format() on strings - // to clean up potentially wonky urls. - if (util.isString(obj)) obj = urlParse(obj); - if (!(obj instanceof Url)) return Url.prototype.format.call(obj); - return obj.format(); -} - -Url.prototype.format = function() { - var auth = this.auth || ''; - if (auth) { - auth = encodeURIComponent(auth); - auth = auth.replace(/%3A/i, ':'); - auth += '@'; - } - - var protocol = this.protocol || '', - pathname = this.pathname || '', - hash = this.hash || '', - host = false, - query = ''; - - if (this.host) { - host = auth + this.host; - } else if (this.hostname) { - host = auth + (this.hostname.indexOf(':') === -1 ? - this.hostname : - '[' + this.hostname + ']'); - if (this.port) { - host += ':' + this.port; - } - } - - if (this.query && - util.isObject(this.query) && - Object.keys(this.query).length) { - query = querystring.stringify(this.query); - } - - var search = this.search || (query && ('?' + query)) || ''; - - if (protocol && protocol.substr(-1) !== ':') protocol += ':'; - - // only the slashedProtocols get the //. Not mailto:, xmpp:, etc. - // unless they had them to begin with. - if (this.slashes || - (!protocol || slashedProtocol[protocol]) && host !== false) { - host = '//' + (host || ''); - if (pathname && pathname.charAt(0) !== '/') pathname = '/' + pathname; - } else if (!host) { - host = ''; - } - - if (hash && hash.charAt(0) !== '#') hash = '#' + hash; - if (search && search.charAt(0) !== '?') search = '?' + search; - - pathname = pathname.replace(/[?#]/g, function(match) { - return encodeURIComponent(match); - }); - search = search.replace('#', '%23'); - - return protocol + host + pathname + search + hash; -}; - -function urlResolve(source, relative) { - return urlParse(source, false, true).resolve(relative); -} - -Url.prototype.resolve = function(relative) { - return this.resolveObject(urlParse(relative, false, true)).format(); -}; - -function urlResolveObject(source, relative) { - if (!source) return relative; - return urlParse(source, false, true).resolveObject(relative); -} - -Url.prototype.resolveObject = function(relative) { - if (util.isString(relative)) { - var rel = new Url(); - rel.parse(relative, false, true); - relative = rel; - } - - var result = new Url(); - var tkeys = Object.keys(this); - for (var tk = 0; tk < tkeys.length; tk++) { - var tkey = tkeys[tk]; - result[tkey] = this[tkey]; - } - - // hash is always overridden, no matter what. - // even href="" will remove it. - result.hash = relative.hash; - - // if the relative url is empty, then there's nothing left to do here. - if (relative.href === '') { - result.href = result.format(); - return result; - } - - // hrefs like //foo/bar always cut to the protocol. - if (relative.slashes && !relative.protocol) { - // take everything except the protocol from relative - var rkeys = Object.keys(relative); - for (var rk = 0; rk < rkeys.length; rk++) { - var rkey = rkeys[rk]; - if (rkey !== 'protocol') - result[rkey] = relative[rkey]; - } - - //urlParse appends trailing / to urls like http://www.example.com - if (slashedProtocol[result.protocol] && - result.hostname && !result.pathname) { - result.path = result.pathname = '/'; - } - - result.href = result.format(); - return result; - } - - if (relative.protocol && relative.protocol !== result.protocol) { - // if it's a known url protocol, then changing - // the protocol does weird things - // first, if it's not file:, then we MUST have a host, - // and if there was a path - // to begin with, then we MUST have a path. - // if it is file:, then the host is dropped, - // because that's known to be hostless. - // anything else is assumed to be absolute. - if (!slashedProtocol[relative.protocol]) { - var keys = Object.keys(relative); - for (var v = 0; v < keys.length; v++) { - var k = keys[v]; - result[k] = relative[k]; - } - result.href = result.format(); - return result; - } - - result.protocol = relative.protocol; - if (!relative.host && !hostlessProtocol[relative.protocol]) { - var relPath = (relative.pathname || '').split('/'); - while (relPath.length && !(relative.host = relPath.shift())); - if (!relative.host) relative.host = ''; - if (!relative.hostname) relative.hostname = ''; - if (relPath[0] !== '') relPath.unshift(''); - if (relPath.length < 2) relPath.unshift(''); - result.pathname = relPath.join('/'); - } else { - result.pathname = relative.pathname; - } - result.search = relative.search; - result.query = relative.query; - result.host = relative.host || ''; - result.auth = relative.auth; - result.hostname = relative.hostname || relative.host; - result.port = relative.port; - // to support http.request - if (result.pathname || result.search) { - var p = result.pathname || ''; - var s = result.search || ''; - result.path = p + s; - } - result.slashes = result.slashes || relative.slashes; - result.href = result.format(); - return result; - } - - var isSourceAbs = (result.pathname && result.pathname.charAt(0) === '/'), - isRelAbs = ( - relative.host || - relative.pathname && relative.pathname.charAt(0) === '/' - ), - mustEndAbs = (isRelAbs || isSourceAbs || - (result.host && relative.pathname)), - removeAllDots = mustEndAbs, - srcPath = result.pathname && result.pathname.split('/') || [], - relPath = relative.pathname && relative.pathname.split('/') || [], - psychotic = result.protocol && !slashedProtocol[result.protocol]; - - // if the url is a non-slashed url, then relative - // links like ../.. should be able - // to crawl up to the hostname, as well. This is strange. - // result.protocol has already been set by now. - // Later on, put the first path part into the host field. - if (psychotic) { - result.hostname = ''; - result.port = null; - if (result.host) { - if (srcPath[0] === '') srcPath[0] = result.host; - else srcPath.unshift(result.host); - } - result.host = ''; - if (relative.protocol) { - relative.hostname = null; - relative.port = null; - if (relative.host) { - if (relPath[0] === '') relPath[0] = relative.host; - else relPath.unshift(relative.host); - } - relative.host = null; - } - mustEndAbs = mustEndAbs && (relPath[0] === '' || srcPath[0] === ''); - } - - if (isRelAbs) { - // it's absolute. - result.host = (relative.host || relative.host === '') ? - relative.host : result.host; - result.hostname = (relative.hostname || relative.hostname === '') ? - relative.hostname : result.hostname; - result.search = relative.search; - result.query = relative.query; - srcPath = relPath; - // fall through to the dot-handling below. - } else if (relPath.length) { - // it's relative - // throw away the existing file, and take the new path instead. - if (!srcPath) srcPath = []; - srcPath.pop(); - srcPath = srcPath.concat(relPath); - result.search = relative.search; - result.query = relative.query; - } else if (!util.isNullOrUndefined(relative.search)) { - // just pull out the search. - // like href='?foo'. - // Put this after the other two cases because it simplifies the booleans - if (psychotic) { - result.hostname = result.host = srcPath.shift(); - //occationaly the auth can get stuck only in host - //this especially happens in cases like - //url.resolveObject('mailto:local1@domain1', 'local2@domain2') - var authInHost = result.host && result.host.indexOf('@') > 0 ? - result.host.split('@') : false; - if (authInHost) { - result.auth = authInHost.shift(); - result.host = result.hostname = authInHost.shift(); - } - } - result.search = relative.search; - result.query = relative.query; - //to support http.request - if (!util.isNull(result.pathname) || !util.isNull(result.search)) { - result.path = (result.pathname ? result.pathname : '') + - (result.search ? result.search : ''); - } - result.href = result.format(); - return result; - } - - if (!srcPath.length) { - // no path at all. easy. - // we've already handled the other stuff above. - result.pathname = null; - //to support http.request - if (result.search) { - result.path = '/' + result.search; - } else { - result.path = null; - } - result.href = result.format(); - return result; - } - - // if a url ENDs in . or .., then it must get a trailing slash. - // however, if it ends in anything else non-slashy, - // then it must NOT get a trailing slash. - var last = srcPath.slice(-1)[0]; - var hasTrailingSlash = ( - (result.host || relative.host || srcPath.length > 1) && - (last === '.' || last === '..') || last === ''); - - // strip single dots, resolve double dots to parent dir - // if the path tries to go above the root, `up` ends up > 0 - var up = 0; - for (var i = srcPath.length; i >= 0; i--) { - last = srcPath[i]; - if (last === '.') { - srcPath.splice(i, 1); - } else if (last === '..') { - srcPath.splice(i, 1); - up++; - } else if (up) { - srcPath.splice(i, 1); - up--; - } - } - - // if the path is allowed to go above the root, restore leading ..s - if (!mustEndAbs && !removeAllDots) { - for (; up--; up) { - srcPath.unshift('..'); - } - } - - if (mustEndAbs && srcPath[0] !== '' && - (!srcPath[0] || srcPath[0].charAt(0) !== '/')) { - srcPath.unshift(''); - } - - if (hasTrailingSlash && (srcPath.join('/').substr(-1) !== '/')) { - srcPath.push(''); - } - - var isAbsolute = srcPath[0] === '' || - (srcPath[0] && srcPath[0].charAt(0) === '/'); - - // put the host back - if (psychotic) { - result.hostname = result.host = isAbsolute ? '' : - srcPath.length ? srcPath.shift() : ''; - //occationaly the auth can get stuck only in host - //this especially happens in cases like - //url.resolveObject('mailto:local1@domain1', 'local2@domain2') - var authInHost = result.host && result.host.indexOf('@') > 0 ? - result.host.split('@') : false; - if (authInHost) { - result.auth = authInHost.shift(); - result.host = result.hostname = authInHost.shift(); - } - } - - mustEndAbs = mustEndAbs || (result.host && srcPath.length); - - if (mustEndAbs && !isAbsolute) { - srcPath.unshift(''); - } - - if (!srcPath.length) { - result.pathname = null; - result.path = null; - } else { - result.pathname = srcPath.join('/'); - } - - //to support request.http - if (!util.isNull(result.pathname) || !util.isNull(result.search)) { - result.path = (result.pathname ? result.pathname : '') + - (result.search ? result.search : ''); - } - result.auth = relative.auth || result.auth; - result.slashes = result.slashes || relative.slashes; - result.href = result.format(); - return result; -}; - -Url.prototype.parseHost = function() { - var host = this.host; - var port = portPattern.exec(host); - if (port) { - port = port[0]; - if (port !== ':') { - this.port = port.substr(1); - } - host = host.substr(0, host.length - port.length); - } - if (host) this.hostname = host; -}; - - -/***/ }), -/* 57 */ +/* 39 */ /***/ (function(module, exports) { module.exports = {"name":"discord.js","version":"12.0.0-dev","description":"A powerful library for interacting with the Discord API","main":"./src/index","types":"./typings/index.d.ts","scripts":{"test":"npm run lint && npm run docs:test","docs":"docgen --source src --custom docs/index.yml --output docs/docs.json --jsdoc jsdoc.json","docs:test":"docgen --source src --custom docs/index.yml --jsdoc jsdoc.json","lint":"eslint src *.js","lint:fix":"eslint --fix src","webpack":"parallel-webpack"},"repository":{"type":"git","url":"git+https://github.com/hydrabolt/discord.js.git"},"keywords":["discord","api","bot","client","node","discordapp"],"author":"Amish Shah ","license":"Apache-2.0","bugs":{"url":"https://github.com/hydrabolt/discord.js/issues"},"homepage":"https://github.com/hydrabolt/discord.js#readme","runkitExampleFilename":"./docs/examples/ping.js","dependencies":{"long":"^3.0.0","prism-media":"^0.0.1","snekfetch":"^3.0.0","tweetnacl":"^1.0.0","ws":"^3.0.0"},"peerDependencies":{"bufferutil":"^3.0.0","erlpack":"discordapp/erlpack","node-opus":"^0.2.0","opusscript":"^0.0.3","sodium":"^2.0.0","libsodium-wrappers":"^0.5.0","uws":"^8.14.0"},"devDependencies":{"@types/node":"^8.0.0","discord.js-docgen":"hydrabolt/discord.js-docgen","eslint":"^4.0.0","jsdoc-strip-async-await":"^0.1.0","parallel-webpack":"^2.0.0","uglifyjs-webpack-plugin":"^1.0.0-beta.2","webpack":"^3.0.0"},"engines":{"node":">=8.0.0"},"browser":{"ws":false,"uws":false,"erlpack":false,"prism-media":false,"opusscript":false,"node-opus":false,"tweetnacl":false,"sodium":false,"src/sharding/Shard.js":false,"src/sharding/ShardClientUtil.js":false,"src/sharding/ShardingManager.js":false,"src/client/voice/dispatcher/StreamDispatcher.js":false,"src/client/voice/opus/BaseOpusEngine.js":false,"src/client/voice/opus/NodeOpusEngine.js":false,"src/client/voice/opus/OpusEngineList.js":false,"src/client/voice/opus/OpusScriptEngine.js":false,"src/client/voice/pcm/ConverterEngine.js":false,"src/client/voice/pcm/ConverterEngineList.js":false,"src/client/voice/pcm/FfmpegConverterEngine.js":false,"src/client/voice/player/AudioPlayer.js":false,"src/client/voice/receiver/VoiceReadable.js":false,"src/client/voice/receiver/VoiceReceiver.js":false,"src/client/voice/util/Secretbox.js":false,"src/client/voice/util/SecretKey.js":false,"src/client/voice/util/VolumeInterface.js":false,"src/client/voice/ClientVoiceManager.js":false,"src/client/voice/VoiceBroadcast.js":false,"src/client/voice/VoiceConnection.js":false,"src/client/voice/VoiceUDPClient.js":false,"src/client/voice/VoiceWebSocket.js":false}} /***/ }), -/* 58 */ +/* 40 */ /***/ (function(module, exports, __webpack_require__) { // Heavily inspired by node's `internal/errors` module const kCode = Symbol('code'); const messages = new Map(); -const assert = __webpack_require__(111); -const util = __webpack_require__(40); +const assert = __webpack_require__(72); +const util = __webpack_require__(31); /** * Extend an error of some sort into a DiscordjsError. @@ -16225,13 +12549,13 @@ module.exports = { /***/ }), -/* 59 */ +/* 41 */ /***/ (function(module, exports, __webpack_require__) { -const UserAgentManager = __webpack_require__(116); -const handlers = __webpack_require__(117); -const APIRequest = __webpack_require__(121); -const routeBuilder = __webpack_require__(122); +const UserAgentManager = __webpack_require__(77); +const handlers = __webpack_require__(78); +const APIRequest = __webpack_require__(82); +const routeBuilder = __webpack_require__(83); const { Error } = __webpack_require__(4); const { Endpoints } = __webpack_require__(0); @@ -16304,7 +12628,7 @@ module.exports = RESTManager; /***/ }), -/* 60 */ +/* 42 */ /***/ (function(module, exports) { /** @@ -16364,17 +12688,17 @@ module.exports = DiscordAPIError; /***/ }), -/* 61 */ +/* 43 */ /***/ (function(module, exports, __webpack_require__) { -const User = __webpack_require__(30); +const User = __webpack_require__(22); const Collection = __webpack_require__(3); -const ClientUserSettings = __webpack_require__(76); -const ClientUserGuildSettings = __webpack_require__(77); +const ClientUserSettings = __webpack_require__(59); +const ClientUserGuildSettings = __webpack_require__(60); const { Events } = __webpack_require__(0); -const Util = __webpack_require__(6); -const DataResolver = __webpack_require__(13); -const Guild = __webpack_require__(34); +const Util = __webpack_require__(5); +const DataResolver = __webpack_require__(10); +const Guild = __webpack_require__(26); /** * Represents the logged in client's Discord user. @@ -16700,10 +13024,10 @@ module.exports = ClientUser; /***/ }), -/* 62 */ +/* 44 */ /***/ (function(module, exports, __webpack_require__) { -const Collector = __webpack_require__(42); +const Collector = __webpack_require__(34); const { Events } = __webpack_require__(0); /** @@ -16793,22 +13117,22 @@ module.exports = MessageCollector; /***/ }), -/* 63 */ +/* 45 */ /***/ (function(module, exports, __webpack_require__) { module.exports = { - search: __webpack_require__(130), - sendMessage: __webpack_require__(136), + search: __webpack_require__(91), + sendMessage: __webpack_require__(97), }; /***/ }), -/* 64 */ +/* 46 */ /***/ (function(module, exports, __webpack_require__) { -const Channel = __webpack_require__(17); -const TextBasedChannel = __webpack_require__(25); -const MessageStore = __webpack_require__(31); +const Channel = __webpack_require__(11); +const TextBasedChannel = __webpack_require__(19); +const MessageStore = __webpack_require__(23); /** * Represents a direct message channel between two users. @@ -16864,11 +13188,11 @@ module.exports = DMChannel; /***/ }), -/* 65 */ +/* 47 */ /***/ (function(module, exports, __webpack_require__) { const Collection = __webpack_require__(3); -const GuildMember = __webpack_require__(18); +const GuildMember = __webpack_require__(12); /** * Keeps track of mentions in a {@link Message}. @@ -17030,10 +13354,10 @@ module.exports = MessageMentions; /***/ }), -/* 66 */ +/* 48 */ /***/ (function(module, exports, __webpack_require__) { -const Collector = __webpack_require__(42); +const Collector = __webpack_require__(34); const Collection = __webpack_require__(3); const { Events } = __webpack_require__(0); @@ -17152,12 +13476,18 @@ module.exports = ReactionCollector; /***/ }), -/* 67 */ +/* 49 */ +/***/ (function(module, exports) { + + + +/***/ }), +/* 50 */ /***/ (function(module, exports, __webpack_require__) { const Collection = __webpack_require__(3); -const Emoji = __webpack_require__(45); -const ReactionEmoji = __webpack_require__(46); +const Emoji = __webpack_require__(37); +const ReactionEmoji = __webpack_require__(38); const { Error } = __webpack_require__(4); /** @@ -17278,14 +13608,14 @@ module.exports = MessageReaction; /***/ }), -/* 68 */ +/* 51 */ /***/ (function(module, exports, __webpack_require__) { -const Channel = __webpack_require__(17); -const TextBasedChannel = __webpack_require__(25); +const Channel = __webpack_require__(11); +const TextBasedChannel = __webpack_require__(19); const Collection = __webpack_require__(3); -const DataResolver = __webpack_require__(13); -const MessageStore = __webpack_require__(31); +const DataResolver = __webpack_require__(10); +const MessageStore = __webpack_require__(23); /* { type: 3, @@ -17520,15 +13850,15 @@ module.exports = GroupDMChannel; /***/ }), -/* 69 */ +/* 52 */ /***/ (function(module, exports, __webpack_require__) { -const GuildChannel = __webpack_require__(21); -const Webhook = __webpack_require__(22); -const TextBasedChannel = __webpack_require__(25); +const GuildChannel = __webpack_require__(15); +const Webhook = __webpack_require__(16); +const TextBasedChannel = __webpack_require__(19); const Collection = __webpack_require__(3); -const DataResolver = __webpack_require__(13); -const MessageStore = __webpack_require__(31); +const DataResolver = __webpack_require__(10); +const MessageStore = __webpack_require__(23); /** * Represents a guild text channel on Discord. @@ -17617,10 +13947,10 @@ module.exports = TextChannel; /***/ }), -/* 70 */ +/* 53 */ /***/ (function(module, exports, __webpack_require__) { -const Permissions = __webpack_require__(12); +const Permissions = __webpack_require__(9); /** * Represents a permission overwrite for a role or member in a guild channel. @@ -17687,10 +14017,10 @@ module.exports = PermissionOverwrites; /***/ }), -/* 71 */ +/* 54 */ /***/ (function(module, exports, __webpack_require__) { -const GuildChannel = __webpack_require__(21); +const GuildChannel = __webpack_require__(15); const Collection = __webpack_require__(3); const { Error } = __webpack_require__(4); @@ -17828,12 +14158,12 @@ module.exports = VoiceChannel; /***/ }), -/* 72 */ +/* 55 */ /***/ (function(module, exports, __webpack_require__) { const Collection = __webpack_require__(3); -const Snowflake = __webpack_require__(9); -const Webhook = __webpack_require__(22); +const Snowflake = __webpack_require__(6); +const Webhook = __webpack_require__(16); const Targets = { ALL: 'ALL', @@ -18163,7 +14493,7 @@ module.exports = GuildAuditLogs; /***/ }), -/* 73 */ +/* 56 */ /***/ (function(module, exports) { /** @@ -18219,12 +14549,12 @@ module.exports = VoiceRegion; /***/ }), -/* 74 */ +/* 57 */ /***/ (function(module, exports, __webpack_require__) { -const DataStore = __webpack_require__(11); -const Emoji = __webpack_require__(45); -const ReactionEmoji = __webpack_require__(46); +const DataStore = __webpack_require__(8); +const Emoji = __webpack_require__(37); +const ReactionEmoji = __webpack_require__(38); /** * Stores emojis. @@ -18296,11 +14626,11 @@ module.exports = EmojiStore; /***/ }), -/* 75 */ +/* 58 */ /***/ (function(module, exports, __webpack_require__) { -const DataStore = __webpack_require__(11); -const { Presence } = __webpack_require__(19); +const DataStore = __webpack_require__(8); +const { Presence } = __webpack_require__(13); /** * Stores presences. @@ -18354,11 +14684,11 @@ module.exports = PresenceStore; /***/ }), -/* 76 */ +/* 59 */ /***/ (function(module, exports, __webpack_require__) { const { UserSettingsMap } = __webpack_require__(0); -const Util = __webpack_require__(6); +const Util = __webpack_require__(5); const { Error } = __webpack_require__(4); /** @@ -18440,12 +14770,12 @@ module.exports = ClientUserSettings; /***/ }), -/* 77 */ +/* 60 */ /***/ (function(module, exports, __webpack_require__) { const { UserGuildSettingsMap } = __webpack_require__(0); const Collection = __webpack_require__(3); -const ClientUserChannelOverride = __webpack_require__(139); +const ClientUserChannelOverride = __webpack_require__(100); /** * A wrapper around the ClientUser's guild settings. @@ -18506,25 +14836,25 @@ module.exports = ClientUserGuildSettings; /***/ }), -/* 78 */ +/* 61 */ /***/ (function(module, exports, __webpack_require__) { /* WEBPACK VAR INJECTION */(function(Buffer) {const browser = typeof window !== 'undefined'; -const zlib = __webpack_require__(39); -const querystring = __webpack_require__(28); +const zlib = __webpack_require__(49); +const querystring = __webpack_require__(30); if (browser) { exports.WebSocket = window.WebSocket; // eslint-disable-line no-undef } else { try { - exports.WebSocket = __webpack_require__(176); + exports.WebSocket = __webpack_require__(137); } catch (err) { - exports.WebSocket = __webpack_require__(177); + exports.WebSocket = __webpack_require__(138); } } try { - var erlpack = __webpack_require__(178); + var erlpack = __webpack_require__(139); if (!erlpack.pack) erlpack = null; } catch (err) {} // eslint-disable-line no-empty @@ -18550,35 +14880,35 @@ exports.create = (gateway, query = {}, ...args) => { for (const state of ['CONNECTING', 'OPEN', 'CLOSING', 'CLOSED']) exports[state] = exports.WebSocket[state]; -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(5).Buffer)) +/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(17).Buffer)) /***/ }), -/* 79 */ +/* 62 */ /***/ (function(module, exports, __webpack_require__) { -const Util = __webpack_require__(6); +const Util = __webpack_require__(5); module.exports = { // "Root" classes (starting points) - BaseClient: __webpack_require__(41), - Client: __webpack_require__(123), - Shard: __webpack_require__(214), - ShardClientUtil: __webpack_require__(215), - ShardingManager: __webpack_require__(216), - WebhookClient: __webpack_require__(217), + BaseClient: __webpack_require__(32), + Client: __webpack_require__(84), + Shard: __webpack_require__(175), + ShardClientUtil: __webpack_require__(176), + ShardingManager: __webpack_require__(177), + WebhookClient: __webpack_require__(178), // Utilities Collection: __webpack_require__(3), Constants: __webpack_require__(0), - DataResolver: __webpack_require__(13), - DiscordAPIError: __webpack_require__(60), - EvaluatedPermissions: __webpack_require__(12), - Permissions: __webpack_require__(12), - Snowflake: __webpack_require__(9), - SnowflakeUtil: __webpack_require__(9), + DataResolver: __webpack_require__(10), + DiscordAPIError: __webpack_require__(42), + EvaluatedPermissions: __webpack_require__(9), + Permissions: __webpack_require__(9), + Snowflake: __webpack_require__(6), + SnowflakeUtil: __webpack_require__(6), Util: Util, util: Util, - version: __webpack_require__(57).version, + version: __webpack_require__(39).version, // Shortcuts to Util methods escapeMarkdown: Util.escapeMarkdown, @@ -18586,42 +14916,42 @@ module.exports = { splitMessage: Util.splitMessage, // Structures - Activity: __webpack_require__(19).Activity, - Channel: __webpack_require__(17), - ClientUser: __webpack_require__(61), - ClientUserSettings: __webpack_require__(76), - Collector: __webpack_require__(42), - DMChannel: __webpack_require__(64), - Emoji: __webpack_require__(45), - GroupDMChannel: __webpack_require__(68), - Guild: __webpack_require__(34), - GuildAuditLogs: __webpack_require__(72), - GuildChannel: __webpack_require__(21), - GuildMember: __webpack_require__(18), - Invite: __webpack_require__(33), - Message: __webpack_require__(43), - MessageAttachment: __webpack_require__(26), - MessageCollector: __webpack_require__(62), - MessageEmbed: __webpack_require__(20), - MessageMentions: __webpack_require__(65), - MessageReaction: __webpack_require__(67), - ClientApplication: __webpack_require__(44), - PermissionOverwrites: __webpack_require__(70), - Presence: __webpack_require__(19).Presence, - ReactionEmoji: __webpack_require__(46), - ReactionCollector: __webpack_require__(66), - Role: __webpack_require__(32), - TextChannel: __webpack_require__(69), - User: __webpack_require__(30), - VoiceChannel: __webpack_require__(71), - Webhook: __webpack_require__(22), + Activity: __webpack_require__(13).Activity, + Channel: __webpack_require__(11), + ClientUser: __webpack_require__(43), + ClientUserSettings: __webpack_require__(59), + Collector: __webpack_require__(34), + DMChannel: __webpack_require__(46), + Emoji: __webpack_require__(37), + GroupDMChannel: __webpack_require__(51), + Guild: __webpack_require__(26), + GuildAuditLogs: __webpack_require__(55), + GuildChannel: __webpack_require__(15), + GuildMember: __webpack_require__(12), + Invite: __webpack_require__(25), + Message: __webpack_require__(35), + MessageAttachment: __webpack_require__(20), + MessageCollector: __webpack_require__(44), + MessageEmbed: __webpack_require__(14), + MessageMentions: __webpack_require__(47), + MessageReaction: __webpack_require__(50), + ClientApplication: __webpack_require__(36), + PermissionOverwrites: __webpack_require__(53), + Presence: __webpack_require__(13).Presence, + ReactionEmoji: __webpack_require__(38), + ReactionCollector: __webpack_require__(48), + Role: __webpack_require__(24), + TextChannel: __webpack_require__(52), + User: __webpack_require__(22), + VoiceChannel: __webpack_require__(54), + Webhook: __webpack_require__(16), - WebSocket: __webpack_require__(78), + WebSocket: __webpack_require__(61), }; /***/ }), -/* 80 */ +/* 63 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -18742,7 +15072,7 @@ function fromByteArray (uint8) { /***/ }), -/* 81 */ +/* 64 */ /***/ (function(module, exports) { exports.read = function (buffer, offset, isLE, mLen, nBytes) { @@ -18832,32 +15162,31 @@ exports.write = function (buffer, value, offset, isLE, mLen, nBytes) { /***/ }), -/* 82 */ +/* 65 */ +/***/ (function(module, exports) { + +var toString = {}.toString; + +module.exports = Array.isArray || function (arr) { + return toString.call(arr) == '[object Array]'; +}; + + +/***/ }), +/* 66 */ /***/ (function(module, exports, __webpack_require__) { -/* WEBPACK VAR INJECTION */(function(Buffer) {__webpack_require__(48); -const zlib = __webpack_require__(39); -const qs = __webpack_require__(28); -const http = __webpack_require__(54); -const https = __webpack_require__(103); -const URL = __webpack_require__(56); -const Package = __webpack_require__(104); -const Stream = __webpack_require__(48); -const FormData = __webpack_require__(105); - -const transports = { - http, - https, - file: __webpack_require__(109), - http2: __webpack_require__(110), -}; +const browser = typeof window !== 'undefined'; +const qs = __webpack_require__(30); +const Package = __webpack_require__(69); +const transport = browser ? __webpack_require__(70) : __webpack_require__(71); /** * Snekfetch * @extends Stream.Readable * @extends Promise */ -class Snekfetch extends Stream.Readable { +class Snekfetch extends (transport.extension || Object) { /** * Create a request, but you probably wanna use `snekfetch#method` * @param {string} method HTTP method @@ -18869,15 +15198,8 @@ class Snekfetch extends Stream.Readable { */ constructor(method, url, opts = { headers: null, data: null, query: null, version: 1 }) { super(); - - const options = URL.parse(url); - options.method = method.toUpperCase(); - if (opts.headers) options.headers = opts.headers; - if ('agent' in opts) options.agent = opts.agent; - - const transport = opts.version === 2 ? transports.http2 : transports[options.protocol.replace(':', '')]; - this.request = transport.request(options); - this.request.followRedirects = opts.followRedirects; + this.options = opts; + this.request = transport.buildRequest.call(this, method, url, opts); if (opts.query) this.query(opts.query); if (opts.data) this.send(opts.data); } @@ -18890,8 +15212,11 @@ class Snekfetch extends Stream.Readable { */ query(name, value) { if (this.response) throw new Error('Cannot modify query after being sent!'); + if (!this.request.query) this.request.query = browser ? new URLSearchParams() : {}; if (name !== null && typeof name === 'object') { - this.request.query = Object.assign(this.request.query || {}, name); + for (const [k, v] of Object.entries(name)) this.query(k, v); + } else if (browser) { + this.request.query.set(name, value); } else { this.request.query[name] = value; } @@ -18937,7 +15262,7 @@ class Snekfetch extends Stream.Readable { */ send(data) { if (this.response) throw new Error('Cannot modify data after being sent!'); - if (data instanceof Buffer || data instanceof Stream) { + if (transport.shouldSendRaw(data)) { this.data = data; } else if (data !== null && typeof data === 'object') { const header = this._getRequestHeader('content-type'); @@ -18957,131 +15282,84 @@ class Snekfetch extends Stream.Readable { } then(resolver, rejector) { - return new Promise((resolve, reject) => { - const request = this.request; + transport.finalizeRequest.call(this, { + data: this.data ? this.data.end ? this.data.end() : this.data : null, + }) + .then(({ response, raw, redirect, headers }) => { + if (redirect) { + let method = this.request.method; + if ([301, 302].includes(response.statusCode)) { + if (method !== 'HEAD') method = 'GET'; + this.data = null; + } else if (response.statusCode === 303) { + method = 'GET'; + } - const handleError = (err) => { - if (!err) err = new Error('Unknown error occured'); - err.request = request; - reject(err); - }; + const redirectHeaders = {}; + if (this.request._headerNames) { + for (const name of Object.keys(this.request._headerNames)) { + if (name.toLowerCase() === 'host') continue; + redirectHeaders[this.request._headerNames[name]] = this.request._headers[name]; + } + } else { + for (const name of Object.keys(this.request._headers)) { + if (name.toLowerCase() === 'host') continue; + const header = this.request._headers[name]; + redirectHeaders[header.name] = header.value; + } + } - request.once('abort', handleError); - request.once('aborted', handleError); - request.once('error', handleError); - - request.once('response', (response) => { - const stream = new Stream.PassThrough(); - if (this._shouldUnzip(response)) { - response.pipe(zlib.createUnzip({ - flush: zlib.Z_SYNC_FLUSH, - finishFlush: zlib.Z_SYNC_FLUSH, - })).pipe(stream); - } else { - response.pipe(stream); + return new Snekfetch(method, redirect, { + data: this.data, + headers: redirectHeaders, + agent: this.options._req.agent, + }); } - const body = []; - - stream.on('data', (chunk) => { - if (!this.push(chunk)) this.pause(); - body.push(chunk); - }); - - stream.once('end', () => { - this.push(null); - const concated = Buffer.concat(body); - - if (this.request.followRedirects && this._shouldRedirect(response)) { - let method = this.request.method; - if ([301, 302].includes(response.statusCode)) { - if (method !== 'HEAD') method = 'GET'; - this.data = null; - } else if (response.statusCode === 303) { - method = 'GET'; - } - - const headers = {}; - if (this.request._headerNames) { - for (const name of Object.keys(this.request._headerNames)) { - if (name.toLowerCase() === 'host') continue; - headers[this.request._headerNames[name]] = this.request._headers[name]; + const statusCode = response.statusCode || response.status; + /** + * @typedef {Object} SnekfetchResponse + * @prop {HTTP.Request} request + * @prop {?string|object|Buffer} body Processed response body + * @prop {string} text Raw response body + * @prop {boolean} ok If the response code is >= 200 and < 300 + * @prop {number} status HTTP status code + * @prop {string} statusText Human readable HTTP status + */ + const res = { + request: this.request, + get body() { + delete res.body; + const type = this.headers['content-type']; + if (type && type.includes('application/json')) { + try { + res.body = JSON.parse(res.text); + } catch (err) { + res.body = res.text; } + } else if (type && type.includes('application/x-www-form-urlencoded')) { + res.body = qs.parse(res.text); } else { - for (const name of Object.keys(this.request._headers)) { - if (name.toLowerCase() === 'host') continue; - const header = this.request._headers[name]; - headers[header.name] = header.value; - } + res.body = raw; } - const newURL = /^https?:\/\//i.test(response.headers.location) ? - response.headers.location : - URL.resolve(makeURLFromRequest(request), response.headers.location); - resolve(new Snekfetch(method, newURL, { data: this.data, headers })); - return; - } + return res.body; + }, + text: raw.toString(), + ok: statusCode >= 200 && statusCode < 400, + headers: headers || response.headers, + status: statusCode, + statusText: response.statusText || transport.STATUS_CODES[response.statusCode], + }; - /** - * @typedef {Object} SnekfetchResponse - * @prop {HTTP.Request} request - * @prop {?string|object|Buffer} body Processed response body - * @prop {string} text Raw response body - * @prop {boolean} ok If the response code is >= 200 and < 300 - * @prop {number} status HTTP status code - * @prop {string} statusText Human readable HTTP status - */ - const res = { - request: this.request, - get body() { - delete res.body; - const type = response.headers['content-type']; - if (type && type.includes('application/json')) { - try { - res.body = JSON.parse(res.text); - } catch (err) { - res.body = res.text; - } // eslint-disable-line no-empty - } else if (type && type.includes('application/x-www-form-urlencoded')) { - res.body = qs.parse(res.text); - } else { - res.body = concated; - } - - return res.body; - }, - text: concated.toString(), - ok: response.statusCode >= 200 && response.statusCode < 400, - headers: response.headers, - status: response.statusCode, - statusText: response.statusText || http.STATUS_CODES[response.statusCode], - }; - - if (res.ok) { - resolve(res); - } else { - const err = new Error(`${res.status} ${res.statusText}`.trim()); - Object.assign(err, res); - reject(err); - } - }); - }); - - const data = this.data ? this.data.end ? this.data.end() : this.data : null; - this._addFinalHeaders(); - if (this.request.query) this.request.path = `${this.request.path}?${qs.stringify(this.request.query)}`; - if (Array.isArray(data)) { - for (const chunk of data) request.write(chunk); - request.end(); - } else if (data instanceof Stream) { - data.pipe(request); - } else if (data instanceof Buffer) { - this.set('Content-Length', Buffer.byteLength(data)); - request.end(data); - } else { - request.end(data); - } - }) + if (res.ok) { + return res; + } else { + const err = new Error(`${res.status} ${res.statusText}`.trim()); + Object.assign(err, res); + return Promise.reject(err); + } + }) .then(resolver, rejector); } @@ -19114,11 +15392,11 @@ class Snekfetch extends Stream.Readable { } _shouldRedirect(res) { - return [301, 302, 303, 307, 308].includes(res.statusCode); + return this.options.followRedirects !== false && [301, 302, 303, 307, 308].includes(res.statusCode); } _getFormData() { - if (!this._formData) this._formData = new FormData(); + if (!this._formData) this._formData = new transport.FormData(); return this._formData; } @@ -19147,520 +15425,16 @@ class Snekfetch extends Stream.Readable { Snekfetch.version = Package.version; -Snekfetch.METHODS = (http.METHODS || ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS', 'HEAD']).concat('BREW'); +Snekfetch.METHODS = transport.METHODS.concat('BREW'); for (const method of Snekfetch.METHODS) { Snekfetch[method === 'M-SEARCH' ? 'msearch' : method.toLowerCase()] = (url, opts) => new Snekfetch(method, url, opts); } -if (true) module.exports = Snekfetch; -else if (typeof window !== 'undefined') window.Snekfetch = Snekfetch; - -function makeURLFromRequest(request) { - return URL.format({ - protocol: request.connection.encrypted ? 'https:' : 'http:', - hostname: request.getHeader('host'), - pathname: request.path.split('?')[0], - query: request.query, - }); -} - -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(5).Buffer)) - -/***/ }), -/* 83 */ -/***/ (function(module, exports) { - -/* (ignored) */ - -/***/ }), -/* 84 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -/**/ - -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - -var Buffer = __webpack_require__(37).Buffer; -/**/ - -function copyBuffer(src, target, offset) { - src.copy(target, offset); -} - -module.exports = function () { - function BufferList() { - _classCallCheck(this, BufferList); - - this.head = null; - this.tail = null; - this.length = 0; - } - - BufferList.prototype.push = function push(v) { - var entry = { data: v, next: null }; - if (this.length > 0) this.tail.next = entry;else this.head = entry; - this.tail = entry; - ++this.length; - }; - - BufferList.prototype.unshift = function unshift(v) { - var entry = { data: v, next: this.head }; - if (this.length === 0) this.tail = entry; - this.head = entry; - ++this.length; - }; - - BufferList.prototype.shift = function shift() { - if (this.length === 0) return; - var ret = this.head.data; - if (this.length === 1) this.head = this.tail = null;else this.head = this.head.next; - --this.length; - return ret; - }; - - BufferList.prototype.clear = function clear() { - this.head = this.tail = null; - this.length = 0; - }; - - BufferList.prototype.join = function join(s) { - if (this.length === 0) return ''; - var p = this.head; - var ret = '' + p.data; - while (p = p.next) { - ret += s + p.data; - }return ret; - }; - - BufferList.prototype.concat = function concat(n) { - if (this.length === 0) return Buffer.alloc(0); - if (this.length === 1) return this.head.data; - var ret = Buffer.allocUnsafe(n >>> 0); - var p = this.head; - var i = 0; - while (p) { - copyBuffer(p.data, ret, i); - i += p.data.length; - p = p.next; - } - return ret; - }; - - return BufferList; -}(); - -/***/ }), -/* 85 */ -/***/ (function(module, exports, __webpack_require__) { - -var apply = Function.prototype.apply; - -// DOM APIs, for completeness - -exports.setTimeout = function() { - return new Timeout(apply.call(setTimeout, window, arguments), clearTimeout); -}; -exports.setInterval = function() { - return new Timeout(apply.call(setInterval, window, arguments), clearInterval); -}; -exports.clearTimeout = -exports.clearInterval = function(timeout) { - if (timeout) { - timeout.close(); - } -}; - -function Timeout(id, clearFn) { - this._id = id; - this._clearFn = clearFn; -} -Timeout.prototype.unref = Timeout.prototype.ref = function() {}; -Timeout.prototype.close = function() { - this._clearFn.call(window, this._id); -}; - -// Does not start the time, just sets up the members needed. -exports.enroll = function(item, msecs) { - clearTimeout(item._idleTimeoutId); - item._idleTimeout = msecs; -}; - -exports.unenroll = function(item) { - clearTimeout(item._idleTimeoutId); - item._idleTimeout = -1; -}; - -exports._unrefActive = exports.active = function(item) { - clearTimeout(item._idleTimeoutId); - - var msecs = item._idleTimeout; - if (msecs >= 0) { - item._idleTimeoutId = setTimeout(function onTimeout() { - if (item._onTimeout) - item._onTimeout(); - }, msecs); - } -}; - -// setimmediate attaches itself to the global object -__webpack_require__(86); -exports.setImmediate = setImmediate; -exports.clearImmediate = clearImmediate; +module.exports = Snekfetch; /***/ }), -/* 86 */ -/***/ (function(module, exports, __webpack_require__) { - -/* WEBPACK VAR INJECTION */(function(global, process) {(function (global, undefined) { - "use strict"; - - if (global.setImmediate) { - return; - } - - var nextHandle = 1; // Spec says greater than zero - var tasksByHandle = {}; - var currentlyRunningATask = false; - var doc = global.document; - var registerImmediate; - - function setImmediate(callback) { - // Callback can either be a function or a string - if (typeof callback !== "function") { - callback = new Function("" + callback); - } - // Copy function arguments - var args = new Array(arguments.length - 1); - for (var i = 0; i < args.length; i++) { - args[i] = arguments[i + 1]; - } - // Store and register the task - var task = { callback: callback, args: args }; - tasksByHandle[nextHandle] = task; - registerImmediate(nextHandle); - return nextHandle++; - } - - function clearImmediate(handle) { - delete tasksByHandle[handle]; - } - - function run(task) { - var callback = task.callback; - var args = task.args; - switch (args.length) { - case 0: - callback(); - break; - case 1: - callback(args[0]); - break; - case 2: - callback(args[0], args[1]); - break; - case 3: - callback(args[0], args[1], args[2]); - break; - default: - callback.apply(undefined, args); - break; - } - } - - function runIfPresent(handle) { - // From the spec: "Wait until any invocations of this algorithm started before this one have completed." - // So if we're currently running a task, we'll need to delay this invocation. - if (currentlyRunningATask) { - // Delay by doing a setTimeout. setImmediate was tried instead, but in Firefox 7 it generated a - // "too much recursion" error. - setTimeout(runIfPresent, 0, handle); - } else { - var task = tasksByHandle[handle]; - if (task) { - currentlyRunningATask = true; - try { - run(task); - } finally { - clearImmediate(handle); - currentlyRunningATask = false; - } - } - } - } - - function installNextTickImplementation() { - registerImmediate = function(handle) { - process.nextTick(function () { runIfPresent(handle); }); - }; - } - - function canUsePostMessage() { - // The test against `importScripts` prevents this implementation from being installed inside a web worker, - // where `global.postMessage` means something completely different and can't be used for this purpose. - if (global.postMessage && !global.importScripts) { - var postMessageIsAsynchronous = true; - var oldOnMessage = global.onmessage; - global.onmessage = function() { - postMessageIsAsynchronous = false; - }; - global.postMessage("", "*"); - global.onmessage = oldOnMessage; - return postMessageIsAsynchronous; - } - } - - function installPostMessageImplementation() { - // Installs an event handler on `global` for the `message` event: see - // * https://developer.mozilla.org/en/DOM/window.postMessage - // * http://www.whatwg.org/specs/web-apps/current-work/multipage/comms.html#crossDocumentMessages - - var messagePrefix = "setImmediate$" + Math.random() + "$"; - var onGlobalMessage = function(event) { - if (event.source === global && - typeof event.data === "string" && - event.data.indexOf(messagePrefix) === 0) { - runIfPresent(+event.data.slice(messagePrefix.length)); - } - }; - - if (global.addEventListener) { - global.addEventListener("message", onGlobalMessage, false); - } else { - global.attachEvent("onmessage", onGlobalMessage); - } - - registerImmediate = function(handle) { - global.postMessage(messagePrefix + handle, "*"); - }; - } - - function installMessageChannelImplementation() { - var channel = new MessageChannel(); - channel.port1.onmessage = function(event) { - var handle = event.data; - runIfPresent(handle); - }; - - registerImmediate = function(handle) { - channel.port2.postMessage(handle); - }; - } - - function installReadyStateChangeImplementation() { - var html = doc.documentElement; - registerImmediate = function(handle) { - // Create a