diff --git a/.eslintrc.json b/.eslintrc.json index 3646138..8f3739d 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -3,12 +3,19 @@ "es6": true, "node": true }, - "extends": ["eslint:recommended", "plugin:promise/recommended"], + "extends": ["eslint:recommended"], + "parser": "@babel/eslint-parser", "parserOptions": { "sourceType": "module", - "ecmaVersion": 2019 + "ecmaVersion": 12, + "requireConfigFile": false, + "babelOptions": { + "plugins": [ + "@babel/plugin-proposal-class-properties" + ] + } }, - "plugins": ["promise"], + "plugins": ["@babel"], "rules": { "no-console": "off", "indent": [ diff --git a/readme.md b/README.md similarity index 100% rename from readme.md rename to README.md diff --git a/api/index.js b/api/index.js index 518974a..6f21393 100644 --- a/api/index.js +++ b/api/index.js @@ -30,19 +30,16 @@ const acceptJob = async (uuid, sock) => { msg: jobs[uuid].msg, num: jobs[uuid].num }, sock); - jobAmount--; - if (queue.length > 0) { - acceptJob(queue[0], sock); - } log(`Job ${uuid} has finished`); } catch (err) { console.error(`Error on job ${uuid}:`, err); + delete jobs[uuid]; + sock.write(Buffer.concat([Buffer.from([0x2]), Buffer.from(uuid), Buffer.from(err.message)])); + } finally { jobAmount--; if (queue.length > 0) { acceptJob(queue[0], sock); } - delete jobs[uuid]; - sock.write(Buffer.concat([Buffer.from([0x2]), Buffer.from(uuid), Buffer.from(err.toString())])); } }; @@ -55,6 +52,22 @@ const httpServer = http.createServer((req, res) => { if (reqUrl.pathname === "/status") { log(`Sending server status to ${req.socket.remoteAddress}:${req.socket.remotePort} via HTTP`); return res.end(Buffer.from((MAX_JOBS - jobAmount).toString())); + } else if (reqUrl.pathname === "/running") { + log(`Sending currently running jobs to ${req.socket.remoteAddress}:${req.socket.remotePort} via HTTP`); + const keys = Object.keys(jobs); + const newObject = { queued: queue.length, runningJobs: jobAmount, max: MAX_JOBS }; + for (const key of keys) { + const validKeys = Object.keys(jobs[key]).filter((value) => value !== "addr" && value !== "port" && value !== "data" && value !== "ext"); + newObject[key] = {}; + for (const validKey of validKeys) { + if (validKey === "msg") { + newObject[key][validKey] = JSON.parse(jobs[key][validKey]); + } else { + newObject[key][validKey] = jobs[key][validKey]; + } + } + } + return res.end(JSON.stringify(newObject)); } else if (reqUrl.pathname === "/image") { if (!reqUrl.searchParams.has("id")) { res.statusCode = 400; @@ -134,7 +147,7 @@ const server = net.createServer((sock) => { // Create a TCP socket/server to lis for (const job of Object.keys(jobs)) { if (jobs[job].addr === sock.remoteAddress && jobs[job].port === sock.remotePort) { delete jobs[job]; - sock.write(Buffer.concat([Buffer.from([0x2]), Buffer.from(job), Buffer.from("Job ended prematurely")])); + sock.write(Buffer.concat([Buffer.from([0x2]), Buffer.from(job), Buffer.from("Job ended prematurely (not really an error; just run your image job again)")])); } } process.exit(0); @@ -149,28 +162,22 @@ server.listen(8080, () => { log("TCP listening on port 8080"); }); -const runJob = (job, sock) => { - return new Promise((resolve, reject) => { - log(`Job ${job.uuid} starting...`, job.num); +const runJob = async (job, sock) => { + log(`Job ${job.uuid} starting...`, job.num); - const object = JSON.parse(job.msg); - // If the image has a path, it must also have a type - if (object.path && !object.type) { - reject(new TypeError("Unknown image type")); - } + const object = JSON.parse(job.msg); + // If the image has a path, it must also have a type + if (object.path && !object.type) { + throw new TypeError("Unknown image type"); + } - log(`Job ${job.uuid} started`, job.num); - run(object).then((data) => { - log(`Sending result of job ${job.uuid} back to the bot`, job.num); - jobs[job.uuid].data = data.buffer; - jobs[job.uuid].ext = data.fileExtension; - sock.write(Buffer.concat([Buffer.from([0x1]), Buffer.from(job.uuid)]), (e) => { - if (e) return reject(e); - return resolve(); - }); - return; - }).catch(e => { - reject(e); - }); + log(`Job ${job.uuid} started`, job.num); + const data = await run(object).catch(e => { throw e; }); + log(`Sending result of job ${job.uuid} back to the bot`, job.num); + jobs[job.uuid].data = data.buffer; + jobs[job.uuid].ext = data.fileExtension; + sock.write(Buffer.concat([Buffer.from([0x1]), Buffer.from(job.uuid)]), (e) => { + if (e) throw e; }); + return; }; \ No newline at end of file diff --git a/app.js b/app.js index afb1a11..51bb72e 100644 --- a/app.js +++ b/app.js @@ -1,80 +1,34 @@ -if (process.platform === "win32") console.log("\x1b[1m\x1b[31m\x1b[40m" + `WIN32 IS NOT OFFICIALLY SUPPORTED! +if (process.platform === "win32") console.error("\x1b[1m\x1b[31m\x1b[40m" + `WIN32 IS NOT OFFICIALLY SUPPORTED! Although there's a (very) slim chance of it working, multiple aspects of the bot are built with UNIX-like systems in mind and could break on Win32-based systems. If you want to run the bot on Windows, using Windows Subsystem for Linux is highly recommended. The bot will continue to run past this message, but keep in mind that it could break at any time. Continue running at your own risk; alternatively, stop the bot using Ctrl+C and install WSL.` + "\x1b[0m"); // load config from .env file require("dotenv").config(); -// turn fs.readdir into a promise -const readdir = require("util").promisify(require("fs").readdir); -// fancy loggings -const logger = require("./utils/logger.js"); -// start the client -const client = require("./utils/client.js"); -// initialize command loader -const handler = require("./utils/handler.js"); -const sound = require("./utils/soundplayer.js"); -const image = require("./utils/image.js"); +const { Master } = require("eris-sharder"); -// registers stuff and connects the bot -async function init() { - logger.log("info", "Starting esmBot..."); - // register commands and their info - const commands = await readdir("./commands/"); - const soundStatus = await sound.checkStatus(); - logger.log("info", `Attempting to load ${commands.length} commands...`); - for (const commandFile of commands) { - logger.log("info", `Loading command ${commandFile}...`); - try { - await handler.load(commandFile, soundStatus); - } catch (e) { - logger.error(`Failed to register command ${commandFile.split(".")[0]}: ${e}`); - } +new Master(`Bot ${process.env.TOKEN}`, "/shard.js", { + name: "esmBot", + clientOptions: { + disableEvents: { + CHANNEL_DELETE: true, + CHANNEL_UPDATE: true, + GUILD_BAN_REMOVE: true, + GUILD_MEMBER_ADD: true, + GUILD_MEMBER_REMOVE: true, + GUILD_MEMBER_UPDATE: true, + GUILD_ROLE_CREATE: true, + GUILD_ROLE_DELETE: true, + GUILD_ROLE_UPDATE: true, + TYPING_START: true, + MESSAGE_DELETE_BULK: true + }, + allowedMentions: { + everyone: false, + roles: false, + users: true, + repliedUser: true + }, + guildSubscriptions: false } - - // register events - const events = await readdir("./events/"); - logger.log("info", `Attempting to load ${events.length} events...`); - for (const file of events) { - logger.log("info", `Loading event ${file}...`); - const eventName = file.split(".")[0]; - const event = require(`./events/${file}`); - client.on(eventName, event); - } - - // connect to image api if enabled - if (process.env.API === "true") { - for (const server of image.servers) { - try { - await image.connect(server); - } catch (e) { - logger.error(e); - } - } - } - - // login - client.connect(); - - // post to DBL - if (process.env.NODE_ENV === "production" && process.env.DBL !== "") { - require("./utils/dbl.js"); - } - - // handle ctrl+c and pm2 stop - process.on("SIGINT", () => { - logger.log("info", "SIGINT detected, shutting down..."); - client.editStatus("dnd", { - name: "Restarting/shutting down..." - }); - for (const command of commands) { - handler.unload(command); - } - client.disconnect(); - require("./utils/database.js").stop(); - process.exit(0); - }); -} - -// launch the bot -init(); \ No newline at end of file +}); \ No newline at end of file diff --git a/classes/command.js b/classes/command.js new file mode 100644 index 0000000..0d5388a --- /dev/null +++ b/classes/command.js @@ -0,0 +1,19 @@ +class Command { + constructor(client, message, args, content) { + this.client = client; + this.message = message; + this.args = args; + this.content = content; + } + + async run() { + return "It works!"; + } + + static description = "No description found"; + static aliases = []; + static arguments = []; + static requires = []; +} + +module.exports = Command; \ No newline at end of file diff --git a/classes/imageCommand.js b/classes/imageCommand.js new file mode 100644 index 0000000..910b0c5 --- /dev/null +++ b/classes/imageCommand.js @@ -0,0 +1,125 @@ +const Command = require("./command.js"); +const magick = require("../utils/image.js"); +const imageDetect = require("../utils/imagedetect.js"); +const collections = require("../utils/collections.js"); + +class ImageCommand extends Command { + /*this.embed = { + "title": "Your image is being generated! (PRELIMINARY EMBED)", + "description": "The current progress is outlined below:", + "color": 16711680, + "footer": { + "text": "Step 2/3" + }, + "author": { + "name": "Processing...", + "icon_url": "https://cdn.discordapp.com/avatars/429305856241172480/a20f739886ae47cfb10fa069416e8ed3.jpg" + }, + "fields": [ + { + "name": "Downloading...", + "value": "✅ Done!" + }, + { + "name": "Processing...", + "value": " In progress" + }, + { + "name": "Uploading...", + "value": " Waiting for previous steps to complete" + } + ] + };*/ + + criteria() { + return true; + } + + async run() { + // check if this command has already been run in this channel with the same arguments, and we are awaiting its result + // if so, don't re-run it + if (collections.runningCommands.has(this.message.author.id) && (new Date(collections.runningCommands.get(this.message.author.id)) - new Date(this.message.createdAt)) < 5000) { + return `${this.message.author.mention}, please slow down a bit.`; + } + // before awaiting the command result, add this command to the set of running commands + collections.runningCommands.set(this.message.author.id, this.message.createdAt); + + const magickParams = { + cmd: this.constructor.command + }; + + if (this.constructor.requiresImage) { + try { + const image = await imageDetect(this.client, this.message); + if (image === undefined) { + collections.runningCommands.delete(this.message.author.id); + return `${this.message.author.mention}, ${this.constructor.noImage}`; + } + magickParams.path = image.path; + magickParams.type = image.type; + magickParams.url = image.url; // technically not required but can be useful for text filtering + magickParams.delay = image.delay; + if (this.constructor.requiresGIF) magickParams.onlyGIF = true; + } catch (e) { + collections.runningCommands.delete(this.message.author.id); + throw e; + } + + } + + if (this.constructor.requiresText) { + if (this.args.length === 0 || !this.criteria(this.args)) { + collections.runningCommands.delete(this.message.author.id); + return `${this.message.author.mention}, ${this.constructor.noText}`; + } + } + + switch (typeof this.params) { + case "function": + Object.assign(magickParams, this.params(this.args, magickParams.url)); + break; + case "object": + Object.assign(magickParams, this.params); + break; + } + + let status; + if (magickParams.type === "image/gif") { + status = await this.processMessage(this.message); + } else { + this.message.channel.sendTyping(); + } + + try { + const { buffer, type } = await magick.run(magickParams).catch(e => { + throw e; + }); + if (status && status.channel.messages.get(status.id)) await status.delete(); + if (type === "nogif" && this.constructor.requiresGIF) return `${this.message.author.mention}, that isn't a GIF!`; + return { + file: buffer, + name: `${this.constructor.command}.${type}` + }; + } catch (e) { + if (status && status.channel.messages.get(status.id)) await status.delete(); + if (e.toString().includes("Not connected to image server")) return `${this.message.author.mention}, I'm still trying to connect to the image servers. Please wait a little bit.`; + throw e; + } finally { + collections.runningCommands.delete(this.message.author.id); + } + + } + + processMessage(message) { + return message.channel.createMessage(`${process.env.PROCESSING_EMOJI || ""} Processing... This might take a while`); + } + + static requiresImage = true; + static requiresText = false; + static requiresGIF = false; + static noImage = "you need to provide an image!"; + static noText = "you need to provide some text!"; + static command = ""; +} + +module.exports = ImageCommand; \ No newline at end of file diff --git a/classes/musicCommand.js b/classes/musicCommand.js new file mode 100644 index 0000000..a0371b7 --- /dev/null +++ b/classes/musicCommand.js @@ -0,0 +1,13 @@ +const Command = require("./command.js"); +const soundPlayer = require("../utils/soundplayer.js"); + +class MusicCommand extends Command { + constructor(client, message, args, content) { + super(client, message, args, content); + this.connection = soundPlayer.players.get(message.channel.guild.id); + } + + static requires = ["sound"]; +} + +module.exports = MusicCommand; \ No newline at end of file diff --git a/commands/8ball.js b/commands/8ball.js deleted file mode 100644 index fc8f252..0000000 --- a/commands/8ball.js +++ /dev/null @@ -1,32 +0,0 @@ -const { random } = require("../utils/misc.js"); -const responses = [ - "It is certain", - "It is decidedly so", - "Without a doubt", - "Yes, definitely", - "You may rely on it", - "As I see it, yes", - "Most likely", - "Outlook good", - "Yes", - "Signs point to yes", - "Reply hazy, try again", - "Ask again later", - "Better not tell you now", - "Cannot predict now", - "Concentrate and ask again", - "Don't count on it", - "My reply is no", - "My sources say no", - "Outlook not so good", - "Very doubtful" -]; - -exports.run = async () => { - return `🎱 ${random(responses)}`; -}; - -exports.aliases = ["magicball", "magikball", "magic8ball", "magik8ball", "eightball"]; -exports.category = 4; -exports.help = "Asks the magic 8-ball a question"; -exports.params = "{text}"; \ No newline at end of file diff --git a/commands/9gag.js b/commands/9gag.js deleted file mode 100644 index 88d967b..0000000 --- a/commands/9gag.js +++ /dev/null @@ -1,22 +0,0 @@ -const magick = require("../utils/image.js"); - -exports.run = async (message) => { - message.channel.sendTyping(); - const image = await require("../utils/imagedetect.js")(message); - if (image === undefined) return `${message.author.mention}, you need to provide an image to add a 9GAG watermark!`; - const { buffer, type } = await magick.run({ - cmd: "watermark", - path: image.path, - water: "./assets/images/9gag.png", - gravity: 6, - type: image.type - }); - return { - file: buffer, - name: `9gag.${type}` - }; -}; - -exports.aliases = ["ninegag", "gag"]; -exports.category = 5; -exports.help = "Adds the 9gag watermark to an image"; \ No newline at end of file diff --git a/commands/avatar.js b/commands/avatar.js deleted file mode 100644 index d39602d..0000000 --- a/commands/avatar.js +++ /dev/null @@ -1,22 +0,0 @@ -const client = require("../utils/client.js"); - -exports.run = async (message, args) => { - if (message.mentions[0] !== undefined) { - return message.mentions[0].dynamicAvatarURL(null, 1024); - } else if (client.users.get(args[0]) !== undefined) { - return client.users.get(args[0]).dynamicAvatarURL(null, 1024); - } else if (args.join(" ") !== "" && message.channel.guild) { - const userRegex = new RegExp(args.join("|"), "i"); - const member = message.channel.guild.members.find(element => { - return userRegex.test(element.nick) ? userRegex.test(element.nick) : userRegex.test(element.username); - }); - return member ? member.user.dynamicAvatarURL(null, 1024) : message.author.dynamicAvatarURL(null, 1024); - } else { - return message.author.dynamicAvatarURL(null, 1024); - } -}; - -exports.aliases = ["pfp", "ava"]; -exports.category = 1; -exports.help = "Gets a user's avatar"; -exports.params = "{mention/id}"; \ No newline at end of file diff --git a/commands/bandicam.js b/commands/bandicam.js deleted file mode 100644 index 8ab45bd..0000000 --- a/commands/bandicam.js +++ /dev/null @@ -1,23 +0,0 @@ -const magick = require("../utils/image.js"); - -exports.run = async (message) => { - message.channel.sendTyping(); - const image = await require("../utils/imagedetect.js")(message); - if (image === undefined) return `${message.author.mention}, you need to provide an image to add a Bandicam watermark!`; - const { buffer, type } = await magick.run({ - cmd: "watermark", - path: image.path, - water: "./assets/images/bandicam.png", - gravity: 2, - resize: true, - type: image.type - }); - return { - file: buffer, - name: `bandicam.${type}` - }; -}; - -exports.aliases = ["bandi"]; -exports.category = 5; -exports.help = "Adds the Bandicam watermark to an image"; \ No newline at end of file diff --git a/commands/bird.js b/commands/bird.js deleted file mode 100644 index d672d48..0000000 --- a/commands/bird.js +++ /dev/null @@ -1,19 +0,0 @@ -const fetch = require("node-fetch"); - -exports.run = async (message) => { - message.channel.sendTyping(); - const imageData = await fetch("http://shibe.online/api/birds"); - const json = await imageData.json(); - return { - embed: { - color: 16711680, - image: { - url: json[0] - } - } - }; -}; - -exports.aliases = ["birb", "birds", "birbs"]; -exports.category = 4; -exports.help = "Gets a random bird picture"; \ No newline at end of file diff --git a/commands/blur.js b/commands/blur.js deleted file mode 100644 index 71498ee..0000000 --- a/commands/blur.js +++ /dev/null @@ -1,20 +0,0 @@ -const magick = require("../utils/image.js"); - -exports.run = async (message) => { - message.channel.sendTyping(); - const image = await require("../utils/imagedetect.js")(message); - if (image === undefined) return `${message.author.mention}, you need to provide an image to blur!`; - const { buffer, type } = await magick.run({ - cmd: "blur", - path: image.path, - sharp: false, - type: image.type - }); - return { - file: buffer, - name: `blur.${type}` - }; -}; - -exports.category = 5; -exports.help = "Blurs an image"; \ No newline at end of file diff --git a/commands/blurple.js b/commands/blurple.js deleted file mode 100644 index 3a0023c..0000000 --- a/commands/blurple.js +++ /dev/null @@ -1,20 +0,0 @@ -const magick = require("../utils/image.js"); - -exports.run = async (message) => { - message.channel.sendTyping(); - const image = await require("../utils/imagedetect.js")(message); - if (image === undefined) return `${message.author.mention}, you need to provide an image to make blurple!`; - const { buffer, type } = await magick.run({ - cmd: "blurple", - path: image.path, - type: image.type - }); - return { - file: buffer, - name: `blurple.${type}` - }; -}; - -exports.aliases = ["blurp"]; -exports.category = 5; -exports.help = "Turns an image blurple"; \ No newline at end of file diff --git a/commands/boi.js b/commands/boi.js deleted file mode 100644 index ba65db6..0000000 --- a/commands/boi.js +++ /dev/null @@ -1,10 +0,0 @@ -const soundPlayer = require("../utils/soundplayer.js"); - -exports.run = async (message) => { - return await soundPlayer.play("./assets/audio/boi.ogg", message); -}; - -exports.aliases = ["boy", "neutron", "hugh"]; -exports.category = 6; -exports.help = "Plays the \"boi\" sound effect"; -exports.requires = "sound"; \ No newline at end of file diff --git a/commands/boom.js b/commands/boom.js deleted file mode 100644 index 514a42f..0000000 --- a/commands/boom.js +++ /dev/null @@ -1,10 +0,0 @@ -const soundPlayer = require("../utils/soundplayer.js"); - -exports.run = async (message) => { - return await soundPlayer.play("./assets/audio/boom.ogg", message); -}; - -exports.aliases = ["thud", "vine"]; -exports.category = 6; -exports.help = "Plays the Vine boom sound effect"; -exports.requires = "sound"; \ No newline at end of file diff --git a/commands/bruh.js b/commands/bruh.js deleted file mode 100644 index e90c9fc..0000000 --- a/commands/bruh.js +++ /dev/null @@ -1,10 +0,0 @@ -const soundPlayer = require("../utils/soundplayer.js"); - -exports.run = async (message) => { - return await soundPlayer.play("./assets/audio/bruh.ogg", message); -}; - -exports.aliases = ["bro"]; -exports.category = 6; -exports.help = "Plays the \"bruh\" sound effect"; -exports.requires = "sound"; \ No newline at end of file diff --git a/commands/caption.js b/commands/caption.js deleted file mode 100644 index 8922e62..0000000 --- a/commands/caption.js +++ /dev/null @@ -1,24 +0,0 @@ -const magick = require("../utils/image.js"); - -exports.run = async (message, args) => { - const image = await require("../utils/imagedetect.js")(message); - if (image === undefined) return `${message.author.mention}, you need to provide an image/GIF to add a caption!`; - const newArgs = args.filter(item => !item.includes(image.url) ); - if (args.length === 0) return `${message.author.mention}, you need to provide some text to add a caption!`; - const processMessage = await message.channel.createMessage(`${process.env.PROCESSING_EMOJI || ""} Processing... This might take a while`); - const { buffer, type } = await magick.run({ - cmd: "caption", - path: image.path, - caption: newArgs.join(" ").replaceAll("&", "\\&").replaceAll(">", "\\>").replaceAll("<", "\\<").replaceAll("\"", "\\"").replaceAll("'", "\\'").replaceAll("%", "\\%"), - type: image.type - }); - if (processMessage.channel.messages.get(processMessage.id)) await processMessage.delete(); - return { - file: buffer, - name: `caption.${type}` - }; -}; - -exports.aliases = ["gifc", "gcaption", "ifcaption", "ifunnycaption"]; -exports.category = 5; -exports.help = "Adds a caption to an image/GIF"; \ No newline at end of file diff --git a/commands/caption2.js b/commands/caption2.js deleted file mode 100644 index bc4c206..0000000 --- a/commands/caption2.js +++ /dev/null @@ -1,24 +0,0 @@ -const magick = require("../utils/image.js"); -const words = ["me irl", "dank", "follow my second account @esmBot_", "2016", "meme", "wholesome", "reddit", "instagram", "twitter", "facebook", "fortnite", "minecraft", "relatable", "gold", "funny", "template", "hilarious", "memes", "deep fried", "2020", "leafy", "pewdiepie"]; - -exports.run = async (message, args) => { - const image = await require("../utils/imagedetect.js")(message); - if (image === undefined) return `${message.author.mention}, you need to provide an image/GIF to add a caption!`; - const newArgs = args.filter(item => !item.includes(image.url) ); - const processMessage = await message.channel.createMessage(`${process.env.PROCESSING_EMOJI || ""} Processing... This might take a while`); - const { buffer, type } = await magick.run({ - cmd: "captionTwo", - path: image.path, - caption: newArgs.length !== 0 ? newArgs.join(" ").replaceAll("&", "\\&").replaceAll(">", "\\>").replaceAll("<", "\\<").replaceAll("\"", "\\"").replaceAll("'", "\\'").replaceAll("%", "\\%") : words.sort(() => 0.5 - Math.random()).slice(0, Math.floor(Math.random() * words.length + 1)).join(" "), - type: image.type - }); - if (processMessage.channel.messages.get(processMessage.id)) await processMessage.delete(); - return { - file: buffer, - name: `caption2.${type}` - }; -}; - -exports.aliases = ["tags2", "meirl", "memecaption", "medotmecaption"]; -exports.category = 5; -exports.help = "Adds a me.me caption/tag list to an image/GIF"; diff --git a/commands/cat.js b/commands/cat.js deleted file mode 100644 index 95e0152..0000000 --- a/commands/cat.js +++ /dev/null @@ -1,24 +0,0 @@ -const fetch = require("node-fetch"); - -exports.run = async (message) => { - message.channel.sendTyping(); - const data = await fetch("https://api.thecatapi.com/v1/images/search?format=json", { - headers: { - "x-api-key": process.env.CAT - } - }); - const json = await data.json(); - return { - embed: { - color: 16711680, - image: { - url: json[0].url - } - } - }; -}; - -exports.aliases = ["kitters", "kitties", "kitty", "cattos", "catto", "cats"]; -exports.category = 4; -exports.help = "Gets a random cat picture"; -exports.requires = "cat"; \ No newline at end of file diff --git a/commands/channel.js b/commands/channel.js deleted file mode 100644 index 46b1d17..0000000 --- a/commands/channel.js +++ /dev/null @@ -1,42 +0,0 @@ -const db = require("../utils/database.js"); - -exports.run = async (message, args) => { - if (!message.channel.guild) return `${message.author.mention}, this command only works in servers!`; - if (!message.member.permissions.has("administrator") && message.member.id !== process.env.OWNER) return `${message.author.mention}, you need to be an administrator to enable/disable me!`; - if (args.length === 0) return `${message.author.mention}, you need to provide whether I should be enabled or disabled in this channel!`; - if (args[0] !== "disable" && args[0] !== "enable") return `${message.author.mention}, that's not a valid option!`; - - const guildDB = await db.getGuild(message.channel.guild.id); - - if (args[0].toLowerCase() === "disable") { - let channel; - if (args[1] && args[1].match(/^?$/) && args[1] >= 21154535154122752) { - const id = args[1].replaceAll("@", "").replaceAll("#", "").replaceAll("!", "").replaceAll("&", "").replaceAll("<", "").replaceAll(">", ""); - if (guildDB.disabled.includes(id)) return `${message.author.mention}, I'm already disabled in this channel!`; - channel = message.channel.guild.channels.get(id); - } else { - if (guildDB.disabled.includes(message.channel.id)) return `${message.author.mention}, I'm already disabled in this channel!`; - channel = message.channel; - } - - await db.disableChannel(channel); - return `${message.author.mention}, I have been disabled in this channel. To re-enable me, just run \`${guildDB.prefix}channel enable\`.`; - } else if (args[0].toLowerCase() === "enable") { - let channel; - if (args[1] && args[1].match(/^?$/) && args[1] >= 21154535154122752) { - const id = args[1].replaceAll("@", "").replaceAll("#", "").replaceAll("!", "").replaceAll("&", "").replaceAll("<", "").replaceAll(">", ""); - if (!guildDB.disabled.includes(id)) return `${message.author.mention}, I'm not disabled in that channel!`; - channel = message.channel.guild.channels.get(id); - } else { - if (!guildDB.disabled.includes(message.channel.id)) return `${message.author.mention}, I'm not disabled in this channel!`; - channel = message.channel; - } - - await db.enableChannel(channel); - return `${message.author.mention}, I have been re-enabled in this channel.`; - } -}; - -exports.category = 1; -exports.help = "Enables/disables me in a channel"; -exports.params = "[enable/disable] {id}"; \ No newline at end of file diff --git a/commands/circle.js b/commands/circle.js deleted file mode 100644 index c42651d..0000000 --- a/commands/circle.js +++ /dev/null @@ -1,20 +0,0 @@ -const magick = require("../utils/image.js"); - -exports.run = async (message) => { - message.channel.sendTyping(); - const image = await require("../utils/imagedetect.js")(message); - if (image === undefined) return `${message.author.mention}, you need to provide an image to add radial blur!`; - const { buffer, type} = await magick.run({ - cmd: "circle", - path: image.path, - type: image.type - }); - return { - file: buffer, - name: `circle.${type}` - }; -}; - -exports.aliases = ["cblur", "radial", "radialblur"]; -exports.category = 5; -exports.help = "Applies a radial blur effect on an image"; \ No newline at end of file diff --git a/commands/count.js b/commands/count.js deleted file mode 100644 index 9db9905..0000000 --- a/commands/count.js +++ /dev/null @@ -1,42 +0,0 @@ -const client = require("../utils/client.js"); -const paginator = require("../utils/pagination/pagination.js"); -const database = require("../utils/database.js"); - -exports.run = async (message) => { - if (message.channel.guild && !message.channel.guild.members.get(client.user.id).permissions.has("addReactions") && !message.channel.permissionsOf(client.user.id).has("addReactions")) return `${message.author.mention}, I don't have the \`Add Reactions\` permission!`; - if (message.channel.guild && !message.channel.guild.members.get(client.user.id).permissions.has("embedLinks") && !message.channel.permissionsOf(client.user.id).has("embedLinks")) return `${message.author.mention}, I don't have the \`Embed Links\` permission!`; - const counts = await database.getCounts(); - const countArray = []; - const sortedValues = counts.sort((a, b) => { - return b[1] - a[1]; - }); - for (const [key, value] of sortedValues) { - countArray.push(`**${key}**: ${value}`); - } - const embeds = []; - const groups = countArray.map((item, index) => { - return index % 15 === 0 ? countArray.slice(index, index + 15) : null; - }).filter((item) => { - return item; - }); - for (const [i, value] of groups.entries()) { - embeds.push({ - "embed": { - "title": "Command Usage Counts", - "color": 16711680, - "footer": { - "text": `Page ${i + 1} of ${groups.length}` - }, - "description": value.join("\n"), - "author": { - "name": message.author.username, - "icon_url": message.author.avatarURL - } - } - }); - } - return paginator(message, embeds); -}; - -exports.category = 1; -exports.help = "Gets how many times every command was used"; \ No newline at end of file diff --git a/commands/cowsay.js b/commands/cowsay.js deleted file mode 100644 index 79f6c50..0000000 --- a/commands/cowsay.js +++ /dev/null @@ -1,20 +0,0 @@ -const cowsay = require("cowsay2"); -const cows = require("cowsay2/cows"); - -exports.run = async (message, args) => { - if (args.length === 0) { - return `${message.author.mention}, you need to provide some text for the cow to say!`; - } else if (cows[args[0].toLowerCase()] != undefined) { - const cow = cows[args.shift().toLowerCase()]; - return `\`\`\`\n${cowsay.say(args.join(" "), { - cow - })}\n\`\`\``; - } else { - return `\`\`\`\n${cowsay.say(args.join(" "))}\n\`\`\``; - } -}; - -exports.aliases = ["cow"]; -exports.category = 4; -exports.help = "Makes an ASCII cow say a message"; -exports.params = "[text]"; \ No newline at end of file diff --git a/commands/crop.js b/commands/crop.js deleted file mode 100644 index 5cc0272..0000000 --- a/commands/crop.js +++ /dev/null @@ -1,19 +0,0 @@ -const magick = require("../utils/image.js"); - -exports.run = async (message) => { - message.channel.sendTyping(); - const image = await require("../utils/imagedetect.js")(message); - if (image === undefined) return `${message.author.mention}, you need to provide an image to crop!`; - const { buffer, type } = await magick.run({ - cmd: "crop", - path: image.path, - type: image.type - }); - return { - file: buffer, - name: `crop.${type}` - }; -}; - -exports.category = 5; -exports.help = "Crops an image to 1:1"; \ No newline at end of file diff --git a/commands/dbl.js b/commands/dbl.js deleted file mode 100644 index 9fdf784..0000000 --- a/commands/dbl.js +++ /dev/null @@ -1,7 +0,0 @@ -exports.run = async (message) => { - return `${message.author.mention}, my DBL page can be found here: `; -}; - -exports.aliases = ["discordbotlist", "botlist", "discordbots"]; -exports.category = 1; -exports.help = "Gets my top.gg page"; \ No newline at end of file diff --git a/commands/decode.js b/commands/decode.js deleted file mode 100644 index ef188ed..0000000 --- a/commands/decode.js +++ /dev/null @@ -1,12 +0,0 @@ -const { clean } = require("../utils/misc.js"); - -exports.run = async (message, args) => { - if (args.length === 0) return `${message.author.mention}, you need to provide a string to decode!`; - const b64Decoded = Buffer.from(args.join(" "), "base64").toString("utf-8"); - return `\`\`\`\n${await clean(b64Decoded)}\`\`\``; -}; - -exports.aliases = ["b64decode", "base64decode"]; -exports.category = 1; -exports.help = "Decodes a Base64 string"; -exports.params = "[text]"; \ No newline at end of file diff --git a/commands/deviantart.js b/commands/deviantart.js deleted file mode 100644 index 964726a..0000000 --- a/commands/deviantart.js +++ /dev/null @@ -1,23 +0,0 @@ -const magick = require("../utils/image.js"); - -exports.run = async (message) => { - message.channel.sendTyping(); - const image = await require("../utils/imagedetect.js")(message); - if (image === undefined) return `${message.author.mention}, you need to provide an image to add a DeviantArt watermark!`; - const { buffer, type } = await magick.run({ - cmd: "watermark", - path: image.path, - water: "./assets/images/deviantart.png", - gravity: 5, - resize: true, - type: image.type - }); - return { - file: buffer, - name: `deviantart.${type}` - }; -}; - -exports.aliases = ["da", "deviant"]; -exports.category = 5; -exports.help = "Adds a DeviantArt watermark to an image"; \ No newline at end of file diff --git a/commands/dice.js b/commands/dice.js deleted file mode 100644 index 37f6edb..0000000 --- a/commands/dice.js +++ /dev/null @@ -1,12 +0,0 @@ -exports.run = async (message, args) => { - if (args.length === 0 || !args[0].match(/^\d+$/)) { - return `🎲 The dice landed on ${Math.floor(Math.random() * 6) + 1}.`; - } else { - return `🎲 The dice landed on ${Math.floor(Math.random() * parseInt(args[0])) + 1}.`; - } -}; - -exports.aliases = ["roll", "die", "rng", "random"]; -exports.category = 4; -exports.help = "Rolls the dice"; -exports.params = "{number}"; \ No newline at end of file diff --git a/commands/dog.js b/commands/dog.js deleted file mode 100644 index b52fc9d..0000000 --- a/commands/dog.js +++ /dev/null @@ -1,19 +0,0 @@ -const fetch = require("node-fetch"); - -exports.run = async (message) => { - message.channel.sendTyping(); - const imageData = await fetch("https://dog.ceo/api/breeds/image/random"); - const json = await imageData.json(); - return { - embed: { - color: 16711680, - image: { - url: json.message - } - } - }; -}; - -exports.aliases = ["doggos", "doggo", "pupper", "puppers", "dogs", "puppy", "puppies", "pups", "pup"]; -exports.category = 4; -exports.help = "Gets a random dog picture"; \ No newline at end of file diff --git a/commands/donate.js b/commands/donate.js deleted file mode 100644 index 44a1cc8..0000000 --- a/commands/donate.js +++ /dev/null @@ -1,20 +0,0 @@ -const client = require("../utils/client.js"); - -exports.run = async () => { - let prefix = ""; - if (client.guilds.has("592399417676529688")) { - const patrons = client.guilds.get("592399417676529688").members.filter((i) => { - return i.roles.includes("741386733047906475"); - }); - prefix = "Thanks to the following patrons for their support:\n"; - for (const patron of patrons) { - prefix += `**- ${patron.username}**\n`; - } - prefix += "\n"; - } - return `${prefix}Like esmBot? Consider supporting the developer on Patreon to help keep it running! https://patreon.com/TheEssem`; -}; - -exports.aliases = ["support", "patreon", "patrons"]; -exports.category = 1; -exports.help = "Learn more about how you can support esmBot's development"; \ No newline at end of file diff --git a/commands/emote.js b/commands/emote.js deleted file mode 100644 index 7925d3e..0000000 --- a/commands/emote.js +++ /dev/null @@ -1,21 +0,0 @@ -const emojiRegex = require("emoji-regex"); - -exports.run = async (message, args, content) => { - if (args.length === 0) return `${message.author.mention}, you need to provide an emoji!`; - if (content.split(" ")[0].match(/^$/)) { - return `https://cdn.discordapp.com/emojis/${content.split(" ")[0].replace(/^<(a)?:.+:(\d+)>$/, "$2")}.${content.split(" ")[0].replace(/^<(a)?:.+:(\d+)>$/, "$1") === "a" ? "gif" : "png"}`; - } else if (args[0].match(emojiRegex)) { - const codePoints = []; - for (const codePoint of args[0]) { - codePoints.push(codePoint.codePointAt(0).toString(16)); - } - return `https://twemoji.maxcdn.com/v/latest/72x72/${codePoints.join("-").replace("-fe0f", "")}.png`; - } else { - return `${message.author.mention}, you need to provide a valid emoji to get an image!`; - } -}; - -exports.aliases = ["e", "em", "hugemoji", "hugeemoji", "emoji"]; -exports.category = 1; -exports.help = "Gets a raw emote image"; -exports.params = "[emote]"; \ No newline at end of file diff --git a/commands/encode.js b/commands/encode.js deleted file mode 100644 index 4603e57..0000000 --- a/commands/encode.js +++ /dev/null @@ -1,10 +0,0 @@ -exports.run = async (message, args) => { - if (args.length === 0) return `${message.author.mention}, you need to provide a string to encode!`; - const b64Encoded = Buffer.from(args.join(" ")).toString("base64"); - return `\`\`\`\n${b64Encoded}\`\`\``; -}; - -exports.aliases = ["b64encode", "base64encode"]; -exports.category = 1; -exports.help = "Encodes a Base64 string"; -exports.params = "[text]"; \ No newline at end of file diff --git a/commands/eval.js b/commands/eval.js deleted file mode 100644 index 9a52398..0000000 --- a/commands/eval.js +++ /dev/null @@ -1,27 +0,0 @@ -const { clean } = require("../utils/misc.js"); - -exports.run = async (message, args) => { - if (message.author.id !== process.env.OWNER) return `${message.author.mention}, only the bot owner can use eval!`; - const code = args.join(" "); - try { - const evaled = eval(code); - const cleaned = await clean(evaled); - const sendString = `\`\`\`js\n${cleaned}\n\`\`\``; - if (sendString.length >= 2000) { - return { - text: "The result was too large, so here it is as a file:", - file: cleaned, - name: "result.txt" - }; - } else { - return sendString; - } - } catch (err) { - return `\`ERROR\` \`\`\`xl\n${await clean(err)}\n\`\`\``; - } -}; - -exports.aliases = ["run"]; -exports.category = 8; -exports.help = "Executes JavaScript code"; -exports.params = "[code]"; \ No newline at end of file diff --git a/commands/exec.js b/commands/exec.js deleted file mode 100644 index c041bba..0000000 --- a/commands/exec.js +++ /dev/null @@ -1,30 +0,0 @@ -const { clean } = require("../utils/misc.js"); -const util = require("util"); -const exec = util.promisify(require("child_process").exec); - -exports.run = async (message, args) => { - if (message.author.id !== process.env.OWNER) return `${message.author.mention}, only the bot owner can use exec!`; - const code = args.join(" "); - try { - const execed = await exec(code); - if (execed.stderr) return `\`ERROR\` \`\`\`xl\n${await clean(execed.stderr)}\n\`\`\``; - const cleaned = await clean(execed.stdout); - const sendString = `\`\`\`bash\n${cleaned}\n\`\`\``; - if (sendString.length >= 2000) { - return { - text: "The result was too large, so here it is as a file:", - file: cleaned, - name: "result.txt" - }; - } else { - return sendString; - } - } catch (err) { - return `\`ERROR\` \`\`\`xl\n${await clean(err)}\n\`\`\``; - } -}; - -exports.aliases = ["runcmd"]; -exports.category = 8; -exports.help = "Executes a terminal command"; -exports.params = "[command]"; \ No newline at end of file diff --git a/commands/explode.js b/commands/explode.js deleted file mode 100644 index c31a51c..0000000 --- a/commands/explode.js +++ /dev/null @@ -1,21 +0,0 @@ -const magick = require("../utils/image.js"); - -exports.run = async (message) => { - message.channel.sendTyping(); - const image = await require("../utils/imagedetect.js")(message); - if (image === undefined) return `${message.author.mention}, you need to provide an image to explode!`; - const { buffer, type } = await magick.run({ - cmd: "explode", - path: image.path, - amount: -1, - type: image.type - }); - return { - file: buffer, - name: `explode.${type}` - }; -}; - -exports.aliases = ["exp"]; -exports.category = 5; -exports.help = "Explodes an image"; \ No newline at end of file diff --git a/commands/explosion.js b/commands/explosion.js deleted file mode 100644 index d4629a4..0000000 --- a/commands/explosion.js +++ /dev/null @@ -1,9 +0,0 @@ -const soundPlayer = require("../utils/soundplayer.js"); - -exports.run = async (message) => { - return await soundPlayer.play("./assets/audio/explosion.ogg", message); -}; - -exports.category = 6; -exports.help = "Plays an explosion sound effect"; -exports.requires = "sound"; \ No newline at end of file diff --git a/commands/fakeping.js b/commands/fakeping.js deleted file mode 100644 index 51651fa..0000000 --- a/commands/fakeping.js +++ /dev/null @@ -1,10 +0,0 @@ -const soundPlayer = require("../utils/soundplayer.js"); - -exports.run = async (message) => { - return await soundPlayer.play("./assets/audio/ping.ogg", message); -}; - -exports.aliases = ["notification", "notif"]; -exports.category = 6; -exports.help = "Plays a Discord ping sound effect"; -exports.requires = "sound"; \ No newline at end of file diff --git a/commands/fart.js b/commands/fart.js deleted file mode 100644 index 457aa5b..0000000 --- a/commands/fart.js +++ /dev/null @@ -1,10 +0,0 @@ -const soundPlayer = require("../utils/soundplayer.js"); - -exports.run = async (message) => { - return await soundPlayer.play("./assets/audio/fart.ogg", message); -}; - -exports.aliases = ["toot"]; -exports.category = 6; -exports.help = "Plays a fart sound effect"; -exports.requires = "sound"; \ No newline at end of file diff --git a/commands/fbi.js b/commands/fbi.js deleted file mode 100644 index 8aac7eb..0000000 --- a/commands/fbi.js +++ /dev/null @@ -1,10 +0,0 @@ -const soundPlayer = require("../utils/soundplayer.js"); - -exports.run = async (message) => { - return await soundPlayer.play("./assets/audio/fbi.ogg", message); -}; - -exports.aliases = ["openup"]; -exports.category = 6; -exports.help = "Plays the \"FBI OPEN UP\" sound effect"; -exports.requires = "sound"; \ No newline at end of file diff --git a/commands/feedback.js b/commands/feedback.js deleted file mode 100644 index d1c6484..0000000 --- a/commands/feedback.js +++ /dev/null @@ -1,40 +0,0 @@ -const client = require("../utils/client.js"); -const regex = /(\b(https?|ftp|file):\/\/[-A-Z0-9+&@#/%?=~_|!:,.;]*[-A-Z0-9+&@#/%=~_|])/ig; - -exports.run = async (message, args) => { - if (args.length !== 0) { - if (regex.test(args.join(" "))) return `${message.author.mention}, you can't send a message containing a URL. If you want to report an issue, please join the esmBot Support server instead.`; - const feedbackChannel = client.guilds.get("592399417676529688").channels.get("592429860769497098"); - feedbackChannel.createMessage({ - embed: { - color: 16711680, - timestamp: new Date(), - thumbnail: { - url: message.author.avatarURL - }, - author: { - name: "esmBot Feedback", - icon_url: client.user.avatarURL - }, - fields: [{ - name: "đŸ‘Ĩ Author:", - value: `${message.author.username}#${message.author.discriminator}` - }, { - name: "đŸ‘Ē Server:", - value: message.channel.guild ? message.channel.guild.name : "N/A" - }, { - name: "đŸ’Ŧ Message:", - value: args.join(" ") - }] - } - }); - return `${message.author.mention}, your feedback has been sent!`; - } else { - return `${message.author.mention}, you need to provide some feedback to send!`; - } -}; - -exports.aliases = ["request", "report", "complain", "compliment"]; -exports.category = 1; -exports.help = "Leaves some feedback for the bot owner"; -exports.params = "[message]"; \ No newline at end of file diff --git a/commands/flag.js b/commands/flag.js deleted file mode 100644 index 40c20ca..0000000 --- a/commands/flag.js +++ /dev/null @@ -1,36 +0,0 @@ -const magick = require("../utils/image.js"); -const fs = require("fs"); -const emojiRegex = require("emoji-regex"); -const emoji = require("node-emoji"); - -exports.run = async (message, args) => { - message.channel.sendTyping(); - const image = await require("../utils/imagedetect.js")(message); - if (image === undefined) return `${message.author.mention}, you need to provide an image to overlay a flag onto!`; - if (args.length === 0 || !args[0].match(emojiRegex)) return `${message.author.mention}, you need to provide an emoji of a flag to overlay!`; - const flag = emoji.unemojify(args[0]).replaceAll(":", "").replace("flag-", ""); - let path = `./assets/images/region-flags/png/${flag.toUpperCase()}.png`; - if (flag === "🏴‍☠ī¸") path = "./assets/images/pirateflag.png"; - if (flag === "rainbow-flag") path = "./assets/images/rainbowflag.png"; - if (flag === "checkered_flag") path = "./assets/images/checkeredflag.png"; - if (flag === "đŸŗī¸â€âš§ī¸") path = "./assets/images/transflag.png"; - try { - await fs.promises.access(path); - } catch (e) { - return `${message.author.mention}, that isn't a flag!`; - } - const { buffer, type } = await magick.run({ - cmd: "flag", - path: image.path, - overlay: path, - type: image.type - }); - return { - file: buffer, - name: `flag.${type}` - }; -}; - -exports.params = "[flag]"; -exports.category = 5; -exports.help = "Overlays a flag onto an image"; \ No newline at end of file diff --git a/commands/flip.js b/commands/flip.js deleted file mode 100644 index 0d54c12..0000000 --- a/commands/flip.js +++ /dev/null @@ -1,19 +0,0 @@ -const magick = require("../utils/image.js"); - -exports.run = async (message) => { - message.channel.sendTyping(); - const image = await require("../utils/imagedetect.js")(message); - if (image === undefined) return `${message.author.mention}, you need to provide an image to flip!`; - const { buffer, type } = await magick.run({ - cmd: "flip", - path: image.path, - type: image.type - }); - return { - file: buffer, - name: `flip.${type}` - }; -}; - -exports.category = 5; -exports.help = "Flips an image"; \ No newline at end of file diff --git a/commands/flop.js b/commands/flop.js deleted file mode 100644 index 0c3c73e..0000000 --- a/commands/flop.js +++ /dev/null @@ -1,21 +0,0 @@ -const magick = require("../utils/image.js"); - -exports.run = async (message) => { - message.channel.sendTyping(); - const image = await require("../utils/imagedetect.js")(message); - if (image === undefined) return `${message.author.mention}, you need to provide an image to flop!`; - const { buffer, type } = await magick.run({ - cmd: "flip", - path: image.path, - flop: true, - type: image.type - }); - return { - file: buffer, - name: `flop.${type}` - }; -}; - -exports.aliases = ["flip2"]; -exports.category = 5; -exports.help = "Flops an image"; \ No newline at end of file diff --git a/commands/freeze.js b/commands/freeze.js deleted file mode 100644 index 50ce64a..0000000 --- a/commands/freeze.js +++ /dev/null @@ -1,23 +0,0 @@ -const magick = require("../utils/image.js"); - -exports.run = async (message) => { - message.channel.sendTyping(); - const image = await require("../utils/imagedetect.js")(message); - if (image === undefined) return `${message.author.mention}, you need to provide a GIF to freeze!`; - const { buffer, type } = await magick.run({ - cmd: "freeze", - path: image.path, - loop: false, - onlyGIF: true, - type: image.type - }); - if (type === "nogif") return `${message.author.mention}, that isn't a GIF!`; - return { - file: buffer, - name: `freeze.${type}` - }; -}; - -exports.aliases = ["noloop", "once"]; -exports.category = 5; -exports.help = "Makes a GIF only play once"; \ No newline at end of file diff --git a/commands/fullwidth.js b/commands/fullwidth.js deleted file mode 100644 index 7f2efd5..0000000 --- a/commands/fullwidth.js +++ /dev/null @@ -1,9 +0,0 @@ -exports.run = async (message, args) => { - if (args.length === 0) return `${message.author.mention}, you need to provide some text to convert to fullwidth!`; - return args.join("").replaceAll(/[A-Za-z0-9]/g, (s) => { return String.fromCharCode(s.charCodeAt(0) + 0xFEE0); }); -}; - -exports.aliases = ["aesthetic", "aesthetics", "aes"]; -exports.category = 4; -exports.help = "Converts a message to fullwidth/aesthetic text"; -exports.params = "[text]"; \ No newline at end of file diff --git a/commands/fun/8ball.js b/commands/fun/8ball.js new file mode 100644 index 0000000..223dea4 --- /dev/null +++ b/commands/fun/8ball.js @@ -0,0 +1,37 @@ +const Command = require("../../classes/command.js"); +const { random } = require("../../utils/misc.js"); + +class EightBallCommand extends Command { + static responses = [ + "It is certain", + "It is decidedly so", + "Without a doubt", + "Yes, definitely", + "You may rely on it", + "As I see it, yes", + "Most likely", + "Outlook good", + "Yes", + "Signs point to yes", + "Reply hazy, try again", + "Ask again later", + "Better not tell you now", + "Cannot predict now", + "Concentrate and ask again", + "Don't count on it", + "My reply is no", + "My sources say no", + "Outlook not so good", + "Very doubtful" + ]; + + async run() { + return `🎱 ${random(EightBallCommand.responses)}`; + } + + static description = "Asks the magic 8-ball a question"; + static aliases = ["magicball", "magikball", "magic8ball", "magik8ball", "eightball"]; + static arguments = ["{text}"]; +} + +module.exports = EightBallCommand; \ No newline at end of file diff --git a/commands/fun/bird.js b/commands/fun/bird.js new file mode 100644 index 0000000..febd080 --- /dev/null +++ b/commands/fun/bird.js @@ -0,0 +1,23 @@ +const fetch = require("node-fetch"); +const Command = require("../../classes/command.js"); + +class BirdCommand extends Command { + async run() { + this.message.channel.sendTyping(); + const imageData = await fetch("http://shibe.online/api/birds"); + const json = await imageData.json(); + return { + embed: { + color: 16711680, + image: { + url: json[0] + } + } + }; + } + + static description = "Gets a random bird picture"; + static aliases = ["birb", "birds", "birbs"]; +} + +module.exports = BirdCommand; \ No newline at end of file diff --git a/commands/fun/cat.js b/commands/fun/cat.js new file mode 100644 index 0000000..4d08777 --- /dev/null +++ b/commands/fun/cat.js @@ -0,0 +1,28 @@ +const fetch = require("node-fetch"); +const Command = require("../../classes/command.js"); + +class CatCommand extends Command { + async run() { + this.message.channel.sendTyping(); + const data = await fetch("https://api.thecatapi.com/v1/images/search?format=json", { + headers: { + "x-api-key": process.env.CAT + } + }); + const json = await data.json(); + return { + embed: { + color: 16711680, + image: { + url: json[0].url + } + } + }; + } + + static description = "Gets a random cat picture"; + static aliases = ["kitters", "kitties", "kitty", "cattos", "catto", "cats", "cta"]; + static requires = ["cat"]; +} + +module.exports = CatCommand; \ No newline at end of file diff --git a/commands/fun/cowsay.js b/commands/fun/cowsay.js new file mode 100644 index 0000000..7d0cb39 --- /dev/null +++ b/commands/fun/cowsay.js @@ -0,0 +1,22 @@ +const cowsay = require("cowsay2"); +const cows = require("cowsay2/cows"); +const Command = require("../../classes/command.js"); + +class CowsayCommand extends Command { + async run() { + if (this.args.length === 0) { + return `${this.message.author.mention}, you need to provide some text for the cow to say!`; + } else if (cows[this.args[0].toLowerCase()] != undefined) { + const cow = cows[this.args.shift().toLowerCase()]; + return `\`\`\`\n${cowsay.say(this.args.join(" "), { cow })}\n\`\`\``; + } else { + return `\`\`\`\n${cowsay.say(this.args.join(" "))}\n\`\`\``; + } + } + + static description = "Makes an ASCII cow say a message"; + static aliases = ["cow"]; + static arguments = ["{cow}", "[text]"]; +} + +module.exports = CowsayCommand; \ No newline at end of file diff --git a/commands/fun/dice.js b/commands/fun/dice.js new file mode 100644 index 0000000..efa8be4 --- /dev/null +++ b/commands/fun/dice.js @@ -0,0 +1,17 @@ +const Command = require("../../classes/command.js"); + +class DiceCommand extends Command { + async run() { + if (this.args.length === 0 || !this.args[0].match(/^\d+$/)) { + return `🎲 The dice landed on ${Math.floor(Math.random() * 6) + 1}.`; + } else { + return `🎲 The dice landed on ${Math.floor(Math.random() * parseInt(this.args[0])) + 1}.`; + } + } + + static description = "Rolls the dice"; + static aliases = ["roll", "die", "rng", "random"]; + static arguments = ["{number}"]; +} + +module.exports = DiceCommand; \ No newline at end of file diff --git a/commands/fun/dog.js b/commands/fun/dog.js new file mode 100644 index 0000000..147d104 --- /dev/null +++ b/commands/fun/dog.js @@ -0,0 +1,24 @@ +const fetch = require("node-fetch"); +const Command = require("../../classes/command.js"); + +class DogCommand extends Command { + async run() { + this.message.channel.sendTyping(); + const imageData = await fetch("https://dog.ceo/api/breeds/image/random"); + const json = await imageData.json(); + return { + embed: { + color: 16711680, + image: { + url: json.message + } + } + }; + } + + static description = "Gets a random dog picture"; + static aliases = ["doggos", "doggo", "pupper", "puppers", "dogs", "puppy", "puppies", "pups", "pup"]; + static arguments = ["{number}"]; +} + +module.exports = DogCommand; \ No newline at end of file diff --git a/commands/fun/fullwidth.js b/commands/fun/fullwidth.js new file mode 100644 index 0000000..602c495 --- /dev/null +++ b/commands/fun/fullwidth.js @@ -0,0 +1,14 @@ +const Command = require("../../classes/command.js"); + +class FullwidthCommand extends Command { + async run() { + if (this.args.length === 0) return `${this.message.author.mention}, you need to provide some text to convert to fullwidth!`; + return this.args.join("").replaceAll(/[A-Za-z0-9]/g, (s) => { return String.fromCharCode(s.charCodeAt(0) + 0xFEE0); }); + } + + static description = "Converts a message to fullwidth/aesthetic text"; + static aliases = ["aesthetic", "aesthetics", "aes"]; + static arguments = ["[text]"]; +} + +module.exports = FullwidthCommand; \ No newline at end of file diff --git a/commands/fun/homebrew.js b/commands/fun/homebrew.js new file mode 100644 index 0000000..4052123 --- /dev/null +++ b/commands/fun/homebrew.js @@ -0,0 +1,20 @@ +const ImageCommand = require("../../classes/imageCommand.js"); + +class HomebrewCommand extends ImageCommand { + params(args) { + return { + caption: args.join(" ").toLowerCase().replaceAll("\n", " ") + }; + } + + static description = "Creates a Homebrew Channel edit"; + static aliases = ["hbc", "brew", "wiibrew"]; + static arguments = ["[text]"]; + + static requiresImage = false; + static requiresText = true; + static noText = "you need to provide some text to make a Homebrew Channel edit!"; + static command = "homebrew"; +} + +module.exports = HomebrewCommand; \ No newline at end of file diff --git a/commands/fun/mc.js b/commands/fun/mc.js new file mode 100644 index 0000000..b4d9ec0 --- /dev/null +++ b/commands/fun/mc.js @@ -0,0 +1,20 @@ +const fetch = require("node-fetch"); +const Command = require("../../classes/command.js"); + +class MCCommand extends Command { + async run() { + if (this.args.length === 0) return `${this.message.author.mention}, you need to provide some text to generate a Minecraft achievement!`; + this.message.channel.sendTyping(); + const request = await fetch(`https://www.minecraftskinstealer.com/achievement/a.php?i=13&h=Achievement+get%21&t=${encodeURIComponent(this.args.join("+"))}`); + return { + file: await request.buffer(), + name: "mc.png" + }; + } + + static description = "Generates a Minecraft achievement image"; + static aliases = ["ach", "achievement", "minecraft"]; + static arguments = ["[text]"]; +} + +module.exports = MCCommand; \ No newline at end of file diff --git a/commands/fun/retro.js b/commands/fun/retro.js new file mode 100644 index 0000000..176835e --- /dev/null +++ b/commands/fun/retro.js @@ -0,0 +1,39 @@ +const magick = require("../../utils/image.js"); +const wrap = require("../../utils/wrap.js"); +const Command = require("../../classes/command.js"); + +class RetroCommand extends Command { + async run() { + if (this.args.length === 0) return `${this.message.author.mention}, you need to provide some text to generate some retro text!`; + this.message.channel.sendTyping(); + let [line1, line2, line3] = this.args.join(" ").replaceAll("&", "\\&").replaceAll(">", "\\>").replaceAll("<", "\\<").replaceAll("\"", "\\"").replaceAll("'", "\\'").replaceAll("%", "\\%").split(",").map(elem => elem.trim()); + if (!line2 && line1.length > 15) { + const [split1, split2, split3] = wrap(line1, { width: 15, indent: "" }).split("\n"); + line1 = split1; + line2 = split2 ? split2 : ""; + line3 = split3 ? split3 : ""; + } else { + if (!line2) { + line2 = ""; + } + if (!line3) { + line3 = ""; + } + } + const { buffer } = await magick.run({ + cmd: "retro", + line1, + line2, + line3 + }); + return { + file: buffer, + name: "retro.png" + }; + } + + static description = "Generates a retro text image (separate lines with a comma)"; + static arguments = ["[text]", "{middle text}", "{bottom text}"]; +} + +module.exports = RetroCommand; \ No newline at end of file diff --git a/commands/fun/rps.js b/commands/fun/rps.js new file mode 100644 index 0000000..9c399b3 --- /dev/null +++ b/commands/fun/rps.js @@ -0,0 +1,34 @@ +const misc = require("../../utils/misc.js"); +const Command = require("../../classes/command.js"); + +class RPSCommand extends Command { + async run() { + if (this.args.length === 0 || (this.args[0] !== "rock" && this.args[0] !== "paper" && this.args[0] !== "scissors")) return `${this.message.author.mention}, you need to choose whether you want to be rock, paper, or scissors!`; + let emoji; + let winOrLose; + const result = misc.random(["rock", "paper", "scissors"]); + switch (result) { + case "rock": + emoji = "✊"; + if (this.args[0].toLowerCase() === "paper") winOrLose = 1; + break; + case "paper": + emoji = "✋"; + if (this.args[0].toLowerCase() === "scissors") winOrLose = 1; + break; + case "scissors": + emoji = "✌"; + if (this.args[0].toLowerCase() === "rock") winOrLose = 1; + break; + default: + break; + } + return this.args[0].toLowerCase() === result ? `${emoji} I chose ${result}. It's a tie!` : `${emoji} I chose ${result}. ${winOrLose ? "You win!" : "You lose!"}`; + } + + static description = "Plays rock, paper, scissors with me"; + static aliases = ["rockpaperscissors"]; + static arguments = ["[rock/paper/scissors]"]; +} + +module.exports = RPSCommand; \ No newline at end of file diff --git a/commands/fun/sonic.js b/commands/fun/sonic.js new file mode 100644 index 0000000..c03b1e9 --- /dev/null +++ b/commands/fun/sonic.js @@ -0,0 +1,21 @@ +const wrap = require("../../utils/wrap.js"); +const ImageCommand = require("../../classes/imageCommand.js"); + +class SonicCommand extends ImageCommand { + params(args) { + const cleanedMessage = args.join(" ").replaceAll("&", "\\&").replaceAll(">", "\\>").replaceAll("<", "\\<").replaceAll("\"", "\\"").replaceAll("'", "\\'").replaceAll("%", "\\%"); + return { + text: wrap(cleanedMessage, {width: 15, indent: ""}) + }; + } + + static description = "Creates a Sonic speech bubble image"; + static arguments = ["[text]"]; + + static requiresImage = false; + static requiresText = true; + static noText = "you need to provide some text to make a Sonic meme!"; + static command = "sonic"; +} + +module.exports = SonicCommand; \ No newline at end of file diff --git a/commands/fun/wikihow.js b/commands/fun/wikihow.js new file mode 100644 index 0000000..064973a --- /dev/null +++ b/commands/fun/wikihow.js @@ -0,0 +1,28 @@ +const fetch = require("node-fetch"); +const Command = require("../../classes/command.js"); + +class WikihowCommand extends Command { + async run() { + this.message.channel.sendTyping(); + const request = await fetch("https://hargrimm-wikihow-v1.p.rapidapi.com/images?count=1", { + headers: { + "X-RapidAPI-Key": process.env.MASHAPE, + "X-RapidAPI-Host": "hargrimm-wikihow-v1.p.rapidapi.com", + "Accept": "application/json" + } + }); + const json = await request.json(); + const image = await fetch(json["1"]); + const imageBuffer = await image.buffer(); + return { + file: imageBuffer, + name: json["1"].split("/")[json["1"].split("/").length - 1] + }; + } + + static description = "Gets a random WikiHow image"; + static aliases = ["wiki"]; + static requires = ["mashape"]; +} + +module.exports = WikihowCommand; \ No newline at end of file diff --git a/commands/fun/xkcd.js b/commands/fun/xkcd.js new file mode 100644 index 0000000..4b80bdf --- /dev/null +++ b/commands/fun/xkcd.js @@ -0,0 +1,31 @@ +const fetch = require("node-fetch"); +const Command = require("../../classes/command.js"); + +class XKCDCommand extends Command { + async run() { + const url = this.args.length > 0 && this.args[0].match(/^\d+$/) ? `http://xkcd.com/${this.args[0]}/info.0.json` : "http://xkcd.com/info.0.json"; + try { + const request = await fetch(url); + const json = await request.json(); + const embed = { + "embed": { + "title": json.safe_title, + "url": `https://xkcd.com/${json.num}`, + "color": 16711680, + "description": json.alt, + "image": { + "url": json.img + } + } + }; + return embed; + } catch { + return `${this.message.author.mention}, I couldn't get that XKCD!`; + } + } + + static description = "Gets an XKCD comic"; + static arguments = ["{id}"]; +} + +module.exports = XKCDCommand; \ No newline at end of file diff --git a/commands/funky.js b/commands/funky.js deleted file mode 100644 index d030582..0000000 --- a/commands/funky.js +++ /dev/null @@ -1,23 +0,0 @@ -const magick = require("../utils/image.js"); - -exports.run = async (message) => { - message.channel.sendTyping(); - const image = await require("../utils/imagedetect.js")(message); - if (image === undefined) return `${message.author.mention}, you need to provide an image to add New Funky Mode!`; - const { buffer, type } = await magick.run({ - cmd: "watermark", - path: image.path, - water: "./assets/images/funky.png", - gravity: 3, - resize: true, - type: image.type - }); - return { - file: buffer, - name: `funky.${type}` - }; -}; - -exports.aliases = ["funkymode", "newfunkymode", "funkykong"]; -exports.category = 5; -exports.help = "Adds the New Funky Mode banner to an image"; \ No newline at end of file diff --git a/commands/gamexplain.js b/commands/gamexplain.js deleted file mode 100644 index 175b970..0000000 --- a/commands/gamexplain.js +++ /dev/null @@ -1,20 +0,0 @@ -const magick = require("../utils/image.js"); - -exports.run = async (message) => { - message.channel.sendTyping(); - const image = await require("../utils/imagedetect.js")(message); - if (image === undefined) return `${message.author.mention}, you need to provide an image to make a GameXplain thumbnail meme!`; - const { buffer, type } = await magick.run({ - cmd: "gamexplain", - path: image.path, - type: image.type - }); - return { - file: buffer, - name: `gamexplain.${type}` - }; -}; - -exports.aliases = ["gx"]; -exports.category = 5; -exports.help = "Makes a GameXplain thumbnail from an image"; \ No newline at end of file diff --git a/commands/general/avatar.js b/commands/general/avatar.js new file mode 100644 index 0000000..6c69aab --- /dev/null +++ b/commands/general/avatar.js @@ -0,0 +1,25 @@ +const Command = require("../../classes/command.js"); + +class AvatarCommand extends Command { + async run() { + if (this.message.mentions[0] !== undefined) { + return this.message.mentions[0].dynamicAvatarURL(null, 1024); + } else if (this.client.users.get(this.args[0]) !== undefined) { + return this.client.users.get(this.args[0]).dynamicAvatarURL(null, 1024); + } else if (this.args.join(" ") !== "" && this.message.channel.guild) { + const userRegex = new RegExp(this.args.join("|"), "i"); + const member = this.message.channel.guild.members.find(element => { + return userRegex.test(element.nick) ? userRegex.test(element.nick) : userRegex.test(element.username); + }); + return member ? member.user.dynamicAvatarURL(null, 1024) : this.message.author.dynamicAvatarURL(null, 1024); + } else { + return this.message.author.dynamicAvatarURL(null, 1024); + } + } + + static description = "Gets a user's avatar"; + static aliases = ["pfp", "ava"]; + static arguments = ["{mention/id}"]; +} + +module.exports = AvatarCommand; \ No newline at end of file diff --git a/commands/general/channel.js b/commands/general/channel.js new file mode 100644 index 0000000..d48a92c --- /dev/null +++ b/commands/general/channel.js @@ -0,0 +1,46 @@ +const db = require("../../utils/database.js"); +const Command = require("../../classes/command.js"); + +class ChannelCommand extends Command { + async run() { + if (!this.message.channel.guild) return `${this.message.author.mention}, this command only works in servers!`; + if (!this.message.member.permissions.has("administrator") && this.message.member.id !== process.env.OWNER) return `${this.message.author.mention}, you need to be an administrator to enable/disable me!`; + if (this.args.length === 0) return `${this.message.author.mention}, you need to provide whether I should be enabled or disabled in this channel!`; + if (this.args[0] !== "disable" && this.args[0] !== "enable") return `${this.message.author.mention}, that's not a valid option!`; + + const guildDB = await db.getGuild(this.message.channel.guild.id); + + if (this.args[0].toLowerCase() === "disable") { + let channel; + if (this.args[1] && this.args[1].match(/^?$/) && this.args[1] >= 21154535154122752n) { + const id = this.args[1].replaceAll("@", "").replaceAll("#", "").replaceAll("!", "").replaceAll("&", "").replaceAll("<", "").replaceAll(">", ""); + if (guildDB.disabled.includes(id)) return `${this.message.author.mention}, I'm already disabled in this channel!`; + channel = this.message.channel.guild.channels.get(id); + } else { + if (guildDB.disabled.includes(this.message.channel.id)) return `${this.message.author.mention}, I'm already disabled in this channel!`; + channel = this.message.channel; + } + + await db.disableChannel(channel); + return `${this.message.author.mention}, I have been disabled in this channel. To re-enable me, just run \`${guildDB.prefix}channel enable\`.`; + } else if (this.args[0].toLowerCase() === "enable") { + let channel; + if (this.args[1] && this.args[1].match(/^?$/) && this.args[1] >= 21154535154122752) { + const id = this.args[1].replaceAll("@", "").replaceAll("#", "").replaceAll("!", "").replaceAll("&", "").replaceAll("<", "").replaceAll(">", ""); + if (!guildDB.disabled.includes(id)) return `${this.message.author.mention}, I'm not disabled in that channel!`; + channel = this.message.channel.guild.channels.get(id); + } else { + if (!guildDB.disabled.includes(this.message.channel.id)) return `${this.message.author.mention}, I'm not disabled in this channel!`; + channel = this.message.channel; + } + + await db.enableChannel(channel); + return `${this.message.author.mention}, I have been re-enabled in this channel.`; + } + } + + static description = "Enables/disables me in a channel"; + static arguments = ["[enable/disable]", "{id}"]; +} + +module.exports = ChannelCommand; \ No newline at end of file diff --git a/commands/general/count.js b/commands/general/count.js new file mode 100644 index 0000000..64f46d3 --- /dev/null +++ b/commands/general/count.js @@ -0,0 +1,46 @@ +const paginator = require("../../utils/pagination/pagination.js"); +const database = require("../../utils/database.js"); +const Command = require("../../classes/command.js"); + +class CountCommand extends Command { + async run() { + if (this.message.channel.guild && !this.message.channel.permissionsOf(this.client.user.id).has("addReactions")) return `${this.message.author.mention}, I don't have the \`Add Reactions\` permission!`; + if (this.message.channel.guild && !this.message.channel.permissionsOf(this.client.user.id).has("embedLinks")) return `${this.message.author.mention}, I don't have the \`Embed Links\` permission!`; + const counts = await database.getCounts(); + const countArray = []; + const sortedValues = counts.sort((a, b) => { + return b[1] - a[1]; + }); + for (const [key, value] of sortedValues) { + countArray.push(`**${key}**: ${value}`); + } + const embeds = []; + const groups = countArray.map((item, index) => { + return index % 15 === 0 ? countArray.slice(index, index + 15) : null; + }).filter((item) => { + return item; + }); + for (const [i, value] of groups.entries()) { + embeds.push({ + "embed": { + "title": "Command Usage Counts", + "color": 16711680, + "footer": { + "text": `Page ${i + 1} of ${groups.length}` + }, + "description": value.join("\n"), + "author": { + "name": this.message.author.username, + "icon_url": this.message.author.avatarURL + } + } + }); + } + return paginator(this.client, this.message, embeds); + } + + static description = "Gets how many times every command was used"; + static arguments = ["{mention/id}"]; +} + +module.exports = CountCommand; \ No newline at end of file diff --git a/commands/general/decode.js b/commands/general/decode.js new file mode 100644 index 0000000..d2be1e2 --- /dev/null +++ b/commands/general/decode.js @@ -0,0 +1,16 @@ +const { clean } = require("../../utils/misc.js"); +const Command = require("../../classes/command.js"); + +class DecodeCommand extends Command { + async run() { + if (this.args.length === 0) return `${this.message.author.mention}, you need to provide a string to decode!`; + const b64Decoded = Buffer.from(this.args.join(" "), "base64").toString("utf-8"); + return `\`\`\`\n${await clean(b64Decoded)}\`\`\``; + } + + static description = "Decodes a Base64 string"; + static aliases = ["b64decode", "base64decode"]; + static arguments = ["[text]"]; +} + +module.exports = DecodeCommand; \ No newline at end of file diff --git a/commands/general/donate.js b/commands/general/donate.js new file mode 100644 index 0000000..7141844 --- /dev/null +++ b/commands/general/donate.js @@ -0,0 +1,20 @@ +const fetch = require("node-fetch"); +const Command = require("../../classes/command.js"); + +class DonateCommand extends Command { + async run() { + let prefix = ""; + const patrons = await fetch("https://projectlounge.pw/patrons").then(data => data.json()); + prefix = "Thanks to the following patrons for their support:\n"; + for (const patron of patrons) { + prefix += `**- ${patron}**\n`; + } + prefix += "\n"; + return `${prefix}Like esmBot? Consider supporting the developer on Patreon to help keep it running! https://patreon.com/TheEssem`; + } + + static description = "Learn more about how you can support esmBot's development"; + static aliases = ["support", "patreon", "patrons"]; +} + +module.exports = DonateCommand; \ No newline at end of file diff --git a/commands/general/emote.js b/commands/general/emote.js new file mode 100644 index 0000000..e28715a --- /dev/null +++ b/commands/general/emote.js @@ -0,0 +1,25 @@ +const emojiRegex = require("emoji-regex"); +const Command = require("../../classes/command.js"); + +class EmoteCommand extends Command { + async run() { + if (this.args.length === 0) return `${this.message.author.mention}, you need to provide an emoji!`; + if (this.content.split(" ")[0].match(/^$/)) { + return `https://cdn.discordapp.com/emojis/${this.content.split(" ")[0].replace(/^<(a)?:.+:(\d+)>$/, "$2")}.${this.content.split(" ")[0].replace(/^<(a)?:.+:(\d+)>$/, "$1") === "a" ? "gif" : "png"}`; + } else if (this.args[0].match(emojiRegex)) { + const codePoints = []; + for (const codePoint of this.args[0]) { + codePoints.push(codePoint.codePointAt(0).toString(16)); + } + return `https://twemoji.maxcdn.com/v/latest/72x72/${codePoints.join("-").replace("-fe0f", "")}.png`; + } else { + return `${this.message.author.mention}, you need to provide a valid emoji to get an image!`; + } + } + + static description = "Gets a raw emote image"; + static aliases = ["e", "em", "hugemoji", "hugeemoji", "emoji"]; + static arguments = ["[emote]"]; +} + +module.exports = EmoteCommand; \ No newline at end of file diff --git a/commands/general/encode.js b/commands/general/encode.js new file mode 100644 index 0000000..bd68924 --- /dev/null +++ b/commands/general/encode.js @@ -0,0 +1,15 @@ +const Command = require("../../classes/command.js"); + +class EncodeCommand extends Command { + async run() { + if (this.args.length === 0) return `${this.message.author.mention}, you need to provide a string to encode!`; + const b64Encoded = Buffer.from(this.args.join(" ")).toString("base64"); + return `\`\`\`\n${b64Encoded}\`\`\``; + } + + static description = "Encodes a Base64 string"; + static aliases = ["b64encode", "base64encode"]; + static arguments = ["[text]"]; +} + +module.exports = EncodeCommand; \ No newline at end of file diff --git a/commands/general/eval.js b/commands/general/eval.js new file mode 100644 index 0000000..e3ac399 --- /dev/null +++ b/commands/general/eval.js @@ -0,0 +1,31 @@ +const { clean } = require("../../utils/misc.js"); +const Command = require("../../classes/command.js"); + +class EvalCommand extends Command { + async run() { + if (this.message.author.id !== process.env.OWNER) return `${this.message.author.mention}, only the bot owner can use eval!`; + const code = this.args.join(" "); + try { + const evaled = eval(code); + const cleaned = await clean(evaled); + const sendString = `\`\`\`js\n${cleaned}\n\`\`\``; + if (sendString.length >= 2000) { + return { + text: "The result was too large, so here it is as a file:", + file: cleaned, + name: "result.txt" + }; + } else { + return sendString; + } + } catch (err) { + return `\`ERROR\` \`\`\`xl\n${await clean(err)}\n\`\`\``; + } + } + + static description = "Executes JavaScript code"; + static aliases = ["run"]; + static arguments = ["[code]"]; +} + +module.exports = EvalCommand; \ No newline at end of file diff --git a/commands/general/exec.js b/commands/general/exec.js new file mode 100644 index 0000000..44a1521 --- /dev/null +++ b/commands/general/exec.js @@ -0,0 +1,34 @@ +const { clean } = require("../../utils/misc.js"); +const util = require("util"); +const exec = util.promisify(require("child_process").exec); +const Command = require("../../classes/command.js"); + +class ExecCommand extends Command { + async run() { + if (this.message.author.id !== process.env.OWNER) return `${this.message.author.mention}, only the bot owner can use exec!`; + const code = this.args.join(" "); + try { + const execed = await exec(code); + if (execed.stderr) return `\`ERROR\` \`\`\`xl\n${await clean(execed.stderr)}\n\`\`\``; + const cleaned = await clean(execed.stdout); + const sendString = `\`\`\`bash\n${cleaned}\n\`\`\``; + if (sendString.length >= 2000) { + return { + text: "The result was too large, so here it is as a file:", + file: cleaned, + name: "result.txt" + }; + } else { + return sendString; + } + } catch (err) { + return `\`ERROR\` \`\`\`xl\n${await clean(err)}\n\`\`\``; + } + } + + static description = "Executes a shell command"; + static aliases = ["runcmd"]; + static arguments = ["[command]"]; +} + +module.exports = ExecCommand; \ No newline at end of file diff --git a/commands/general/help.js b/commands/general/help.js new file mode 100644 index 0000000..142b0ad --- /dev/null +++ b/commands/general/help.js @@ -0,0 +1,100 @@ +const database = require("../../utils/database.js"); +const collections = require("../../utils/collections.js"); +const misc = require("../../utils/misc.js"); +const paginator = require("../../utils/pagination/pagination.js"); +const help = require("../../utils/help.js"); +const tips = ["You can change the bot's prefix using the prefix command.", "Image commands also work with images previously posted in that channel.", "You can use the tags commands to save things for later use.", "You can visit https://projectlounge.pw/esmBot/help.html for a web version of this command list.", "You can view a command's aliases by putting the command name after the help command (e.g. help image).", "Parameters wrapped in [] are required, while parameters wrapped in {} are optional.", "esmBot is hosted and paid for completely out-of-pocket by the main developer. If you want to support development, please consider donating! https://patreon.com/TheEssem"]; +const Command = require("../../classes/command.js"); + +class HelpCommand extends Command { + async run() { + const { prefix } = this.message.channel.guild ? await database.getGuild(this.message.channel.guild.id) : "N/A"; + const commands = collections.commands; + const aliases = collections.aliases; + if (this.args.length !== 0 && (commands.has(this.args[0].toLowerCase()) || aliases.has(this.args[0].toLowerCase()))) { + const command = aliases.has(this.args[0].toLowerCase()) ? collections.aliases.get(this.args[0].toLowerCase()) : this.args[0].toLowerCase(); + const info = collections.info.get(command); + const countDB = await database.getCounts(); + const counts = countDB.reduce((acc, val) => { + const [key, value] = val; + acc[key] = value; + return acc; + }, {}); + const embed = { + "embed": { + "author": { + "name": "esmBot Help", + "icon_url": this.client.user.avatarURL + }, + "title": `${this.message.channel.guild ? prefix : ""}${command}`, + "url": "https://projectlounge.pw/esmBot/help.html", + "description": command === "tags" ? "The main tags command. Check the help page for more info: https://projectlounge.pw/esmBot/help.html" : info.description, + "color": 16711680, + "fields": [{ + "name": "Aliases", + "value": info.aliases ? info.aliases.join(", ") : "None" + }, { + "name": "Times Used", + "value": counts[command], + "inline": true + }, { + "name": "Parameters", + "value": command === "tags" ? "[name]" : (info.params ? (typeof info.params === "object" ? info.params.join(" ") : info.params) : "None"), + "inline": true + }] + } + }; + return embed; + } else { + const pages = []; + for (const category of Object.keys(help.categories)) { + const splitPages = help.categories[category].map((item, index) => { + return index % 15 === 0 ? help.categories[category].slice(index, index + 15) : null; + }).filter((item) => { + return item; + }); + const categoryStringArray = category.split("-"); + for (const index of categoryStringArray.keys()) { + categoryStringArray[index] = categoryStringArray[index].charAt(0).toUpperCase() + categoryStringArray[index].slice(1); + } + for (const page of splitPages) { + pages.push({ + title: categoryStringArray.join(" "), + page: page + }); + } + } + const embeds = []; + for (const [i, value] of pages.entries()) { + embeds.push({ + "embed": { + "author": { + "name": "esmBot Help", + "icon_url": this.client.user.avatarURL + }, + "title": value.title, + "description": value.page.join("\n"), + "color": 16711680, + "footer": { + "text": `Page ${i + 1} of ${pages.length}` + }, + "fields": [{ + "name": "Prefix", + "value": this.message.channel.guild ? prefix : "N/A" + }, { + "name": "Tip", + "value": misc.random(tips) + }] + } + }); + } + return paginator(this.client, this.message, embeds); + } + } + + static description = "Gets a list of commands"; + static aliases = ["commands"]; + static arguments = ["{command}"]; +} + +module.exports = HelpCommand; \ No newline at end of file diff --git a/commands/general/image.js b/commands/general/image.js new file mode 100644 index 0000000..f87a751 --- /dev/null +++ b/commands/general/image.js @@ -0,0 +1,40 @@ +const paginator = require("../../utils/pagination/pagination.js"); +const { image_search } = require("duckduckgo-images-api"); +const Command = require("../../classes/command.js"); + +class ImageSearchCommand extends Command { + async run() { + if (this.message.channel.guild && !this.message.channel.permissionsOf(this.client.user.id).has("addReactions")) return `${this.message.author.mention}, I don't have the \`Add Reactions\` permission!`; + if (this.message.channel.guild && !this.message.channel.permissionsOf(this.client.user.id).has("embedLinks")) return `${this.message.author.mention}, I don't have the \`Embed Links\` permission!`; + if (this.args.length === 0) return `${this.message.author.mention}, you need to provide something to search for!`; + const embeds = []; + const images = await image_search({ query: this.args.join(" "), moderate: true }); + if (images.error && images.error.code === 403) return `${this.message.author.mention}, the daily search quota has been exceeded. Check back later.`; + if (images.length === 0) return `${this.message.author.mention}, I couldn't find any results!`; + for (const [i, value] of images.entries()) { + embeds.push({ + "embed": { + "title": "Search Results", + "color": 16711680, + "footer": { + "text": `Page ${i + 1} of ${images.length}` + }, + "image": { + "url": value.image + }, + "author": { + "name": this.message.author.username, + "icon_url": this.message.author.avatarURL + } + } + }); + } + return paginator(this.client, this.message, embeds); + } + + static description = "Searches for images on DuckDuckGo"; + static aliases = ["im", "photo", "img"]; + static arguments = ["[query]"]; +} + +module.exports = ImageSearchCommand; \ No newline at end of file diff --git a/commands/general/imagereload.js b/commands/general/imagereload.js new file mode 100644 index 0000000..1ad8944 --- /dev/null +++ b/commands/general/imagereload.js @@ -0,0 +1,30 @@ +const image = require("../../utils/image.js"); +const logger = require("../../utils/logger.js"); +const Command = require("../../classes/command.js"); + +class ImageReloadCommand extends Command { + async run() { + if (this.message.author.id !== process.env.OWNER) return `${this.message.author.mention}, only the bot owner can reload the image servers!`; + await image.disconnect(); + await image.repopulate(); + let amount = 0; + for (const server of image.servers) { + try { + await image.connect(server); + amount += 1; + } catch (e) { + logger.error(e); + } + } + if (amount > 0) { + return `Successfully connected to ${amount} image servers.`; + } else { + return `${this.message.author.mention}, I couldn't connect to any image servers!`; + } + } + + static description = "Attempts to reconnect to all available image processing servers"; + static aliases = ["magickconnect", "magick"]; +} + +module.exports = ImageReloadCommand; \ No newline at end of file diff --git a/commands/general/imagestats.js b/commands/general/imagestats.js new file mode 100644 index 0000000..e9b7997 --- /dev/null +++ b/commands/general/imagestats.js @@ -0,0 +1,31 @@ +const image = require("../../utils/image.js"); +const Command = require("../../classes/command.js"); + +class ImageStatsCommand extends Command { + async run() { + const embed = { + embed: { + "author": { + "name": "esmBot Image Statistics", + "icon_url": this.client.user.avatarURL + }, + "color": 16711680, + "description": `The bot is currently connected to ${image.connections.length} image server(s).`, + "fields": [] + } + }; + const servers = await image.getStatus(); + for (let i = 0; i < servers.length; i++) { + embed.embed.fields.push({ + name: `Server ${i + 1}`, + value: `Running Jobs: ${servers[i].runningJobs}\nQueued: ${servers[i].queued}\nMax Jobs: ${servers[i].max}` + }); + } + return embed; + } + + static description = "Gets some statistics about the image servers"; + static aliases = ["imgstat", "imstats", "imgstats", "imstat"]; +} + +module.exports = ImageStatsCommand; \ No newline at end of file diff --git a/commands/general/info.js b/commands/general/info.js new file mode 100644 index 0000000..3ae3c03 --- /dev/null +++ b/commands/general/info.js @@ -0,0 +1,46 @@ +const { version } = require("../../package.json"); +const Command = require("../../classes/command.js"); + +class InfoCommand extends Command { + async run() { + return { + "embed": { + "color": 16711680, + "author": { + "name": "esmBot Info/Credits", + "icon_url": this.client.user.avatarURL + }, + "fields": [{ + "name": "ℹī¸ Version:", + "value": `v${version}${process.env.NODE_ENV === "development" ? "-dev" : ""}` + }, + { + "name": "📝 Credits:", + "value": "Bot by **[Essem](https://essem.space)** and **[various contributors](https://github.com/esmBot/esmBot/graphs/contributors)**\nIcon by **[MintBorrow](https://mintborrow.newgrounds.com)**" + }, + { + "name": "đŸ’Ŧ Total Servers:", + "value": this.client.guilds.size + }, + { + "name": "✅ Official Server:", + "value": "[Click here!](https://projectlounge.pw/support)" + }, + { + "name": "đŸ’ģ Source Code:", + "value": "[Click here!](https://github.com/esmBot/esmBot)" + }, + { + "name": "đŸĻ Twitter:", + "value": "[Click here!](https://twitter.com/esmBot_)" + } + ] + } + }; + } + + static description = "Gets some info and credits about me"; + static aliases = ["botinfo", "credits"]; +} + +module.exports = InfoCommand; \ No newline at end of file diff --git a/commands/general/invite.js b/commands/general/invite.js new file mode 100644 index 0000000..507ecde --- /dev/null +++ b/commands/general/invite.js @@ -0,0 +1,12 @@ +const Command = require("../../classes/command.js"); + +class InviteCommand extends Command { + async run() { + return `${this.message.author.mention}, you can invite me to your server here: `; + } + + static description = "Gets my invite link"; + static aliases = ["botinfo", "credits"]; +} + +module.exports = InviteCommand; \ No newline at end of file diff --git a/commands/general/lengthen.js b/commands/general/lengthen.js new file mode 100644 index 0000000..d40cd86 --- /dev/null +++ b/commands/general/lengthen.js @@ -0,0 +1,22 @@ +const urlCheck = require("../../utils/urlcheck.js"); +const fetch = require("node-fetch"); +const Command = require("../../classes/command.js"); + +class LengthenCommand extends Command { + async run() { + this.message.channel.sendTyping(); + if (this.args.length === 0 || !urlCheck(this.args[0])) return `${this.message.author.mention}, you need to provide a short URL to lengthen!`; + if (urlCheck(this.args[0])) { + const url = await fetch(encodeURI(this.args[0]), { redirect: "manual" }); + return url.headers.get("location") || this.args[0]; + } else { + return `${this.message.author.mention}, that isn't a URL!`; + } + } + + static description = "Lengthens a short URL"; + static aliases = ["longurl", "lengthenurl", "longuri", "lengthenuri", "unshorten"]; + static arguments = ["[url]"]; +} + +module.exports = LengthenCommand; \ No newline at end of file diff --git a/commands/general/ping.js b/commands/general/ping.js new file mode 100644 index 0000000..c28ed54 --- /dev/null +++ b/commands/general/ping.js @@ -0,0 +1,13 @@ +const Command = require("../../classes/command.js"); + +class PingCommand extends Command { + async run() { + const pingMessage = await this.message.channel.createMessage("🏓 Ping?"); + return pingMessage.edit(`🏓 Pong!\n\`\`\`\nLatency: ${pingMessage.timestamp - this.message.timestamp}ms${this.message.channel.guild ? `\nShard Latency: ${Math.round(this.client.shards.get(this.client.guildShardMap[this.message.channel.guild.id]).latency)}ms` : ""}\n\`\`\``); + } + + static description = "Pings Discord's servers"; + static aliases = ["pong"]; +} + +module.exports = PingCommand; \ No newline at end of file diff --git a/commands/general/prefix.js b/commands/general/prefix.js new file mode 100644 index 0000000..bc058e1 --- /dev/null +++ b/commands/general/prefix.js @@ -0,0 +1,22 @@ +const database = require("../../utils/database.js"); +const Command = require("../../classes/command.js"); + +class PrefixCommand extends Command { + async run() { + if (!this.message.channel.guild) return `${this.message.author.mention}, this command only works in servers!`; + const guild = await database.getGuild(this.message.channel.guild.id); + if (this.args.length !== 0) { + if (!this.message.member.permissions.has("administrator") && this.message.member.id !== process.env.OWNER) return `${this.message.author.mention}, you need to be an administrator to change the bot prefix!`; + await database.setPrefix(this.args[0], this.message.channel.guild); + return `The prefix has been changed to ${this.args[0]}.`; + } else { + return `${this.message.author.mention}, the current prefix is \`${guild.prefix}\`.`; + } + } + + static description = "Checks/changes the server prefix"; + static aliases = ["setprefix", "changeprefix", "checkprefix"]; + static arguments = ["{prefix}"]; +} + +module.exports = PrefixCommand; \ No newline at end of file diff --git a/commands/general/qrcreate.js b/commands/general/qrcreate.js new file mode 100644 index 0000000..fb19e0c --- /dev/null +++ b/commands/general/qrcreate.js @@ -0,0 +1,37 @@ +const qrcode = require("qrcode"); +const stream = require("stream"); +const Command = require("../../classes/command.js"); + +class QrCreateCommand extends Command { + async run() { + if (this.args.length === 0) return `${this.message.author.mention}, you need to provide some text to generate a QR code!`; + this.message.channel.sendTyping(); + const writable = new stream.PassThrough(); + qrcode.toFileStream(writable, this.content, { margin: 1 }); + const file = await this.streamToBuf(writable); + return { + file: file, + name: "qr.png" + }; + } + + streamToBuf(stream) { + return new Promise((resolve, reject) => { + const chunks = []; + stream.on("data", (chunk) => { + chunks.push(chunk); + }); + stream.once("error", (error) => { + reject(error); + }); + stream.once("end", () => { + resolve(Buffer.concat(chunks)); + }); + }); + } + + static description = "Generates a QR code"; + static arguments = ["[text]"]; +} + +module.exports = QrCreateCommand; \ No newline at end of file diff --git a/commands/general/qrread.js b/commands/general/qrread.js new file mode 100644 index 0000000..81f0a28 --- /dev/null +++ b/commands/general/qrread.js @@ -0,0 +1,22 @@ +const jsqr = require("jsqr"); +const fetch = require("node-fetch"); +const sharp = require("sharp"); +const { clean } = require("../../utils/misc.js"); +const Command = require("../../classes/command.js"); + +class QrReadCommand extends Command { + async run() { + const image = await require("../../utils/imagedetect.js")(this.client, this.message); + if (image === undefined) return `${this.message.author.mention}, you need to provide an image with a QR code to read!`; + this.message.channel.sendTyping(); + const data = await (await fetch(image.path)).buffer(); + const rawData = await sharp(data).ensureAlpha().raw().toBuffer({ resolveWithObject: true }); + const qrBuffer = jsqr(rawData.data, rawData.info.width, rawData.info.height); + if (!qrBuffer) return `${this.message.author.mention}, I couldn't find a QR code!`; + return `\`\`\`\n${await clean(qrBuffer.data)}\n\`\`\``; + } + + static description = "Reads a QR code"; +} + +module.exports = QrReadCommand; \ No newline at end of file diff --git a/commands/general/reload.js b/commands/general/reload.js new file mode 100644 index 0000000..2077d2d --- /dev/null +++ b/commands/general/reload.js @@ -0,0 +1,20 @@ +const handler = require("../../utils/handler.js"); +const collections = require("../../utils/collections.js"); +const Command = require("../../classes/command.js"); + +class ReloadCommand extends Command { + async run() { + if (this.message.author.id !== process.env.OWNER) return `${this.message.author.mention}, only the bot owner can reload commands!`; + if (this.args.length === 0) return `${this.message.author.mention}, you need to provide a command to reload!`; + const result = await handler.unload(this.args[0]); + if (result) return result; + const result2 = await handler.load(collections.paths.get(this.args[0])); + if (result2) return result2; + return `${this.message.author.mention}, the command \`${this.args[0]}\` has been reloaded.`; + } + + static description = "Reloads a command"; + static arguments = ["[command]"]; +} + +module.exports = ReloadCommand; \ No newline at end of file diff --git a/commands/general/restart.js b/commands/general/restart.js new file mode 100644 index 0000000..496a66f --- /dev/null +++ b/commands/general/restart.js @@ -0,0 +1,19 @@ +const handler = require("../../utils/handler.js"); +const collections = require("../../utils/collections.js"); +const Command = require("../../classes/command.js"); + +class RestartCommand extends Command { + async run() { + if (this.message.author.id !== process.env.OWNER) return `${this.message.author.mention}, only the bot owner can restart me!`; + await this.message.channel.createMessage(`${this.message.author.mention}, esmBot is restarting.`); + for (const command of collections.commands) { + await handler.unload(command); + } + process.exit(1); + } + + static description = "Restarts me"; + static aliases = ["reboot"]; +} + +module.exports = RestartCommand; \ No newline at end of file diff --git a/commands/general/serverinfo.js b/commands/general/serverinfo.js new file mode 100644 index 0000000..7643286 --- /dev/null +++ b/commands/general/serverinfo.js @@ -0,0 +1,52 @@ +const Command = require("../../classes/command.js"); + +class ServerInfoCommand extends Command { + async run() { + if (!this.message.channel.guild) return `${this.message.author.mention}, this command only works in servers!`; + const owner = await this.message.channel.guild.members.get(this.message.channel.guild.ownerID); + return { + "embed": { + "title": this.message.channel.guild.name, + "thumbnail": { + "url": this.message.channel.guild.iconURL + }, + "color": 16711680, + "fields": [ + { + "name": "đŸ”ĸ **ID:**", + "value": this.message.channel.guild.id + }, + { + "name": "👤 **Owner:**", + "value": owner ? `${owner.user.username}#${owner.user.discriminator}` : this.message.channel.guild.ownerID + }, + { + "name": "đŸ—ē **Region:**", + "value": this.message.channel.guild.region + }, + { + "name": "🗓 **Created on:**", + "value": new Date(this.message.channel.guild.createdAt).toString() + }, + { + "name": "đŸ‘Ĩ **Users:**", + "value": this.message.channel.guild.memberCount + }, + { + "name": "đŸ’Ŧ **Channels:**", + "value": this.message.channel.guild.channels.size + }, + { + "name": "😃 **Emojis:**", + "value": this.message.channel.guild.emojis.length + } + ] + } + }; + } + + static description = "Gets some info about the server"; + static aliases = ["server"]; +} + +module.exports = ServerInfoCommand; \ No newline at end of file diff --git a/commands/general/snowflake.js b/commands/general/snowflake.js new file mode 100644 index 0000000..13b13c2 --- /dev/null +++ b/commands/general/snowflake.js @@ -0,0 +1,15 @@ +const Command = require("../../classes/command.js"); + +class SnowflakeCommand extends Command { + async run() { + if (!this.args[0]) return `${this.message.author.mention}, you need to provide a snowflake ID!`; + if (!this.args[0].match(/^?$/) && this.args[0] < 21154535154122752) return `${this.message.author.mention}, that's not a valid snowflake!`; + return new Date((this.args[0].replaceAll("@", "").replaceAll("#", "").replaceAll("!", "").replaceAll("&", "").replaceAll("<", "").replaceAll(">", "") / 4194304) + 1420070400000).toUTCString(); + } + + static description = "Converts a Discord snowflake id into a timestamp"; + static aliases = ["timestamp", "snowstamp", "snow"]; + static arguments = ["[id]"]; +} + +module.exports = SnowflakeCommand; \ No newline at end of file diff --git a/commands/general/soundreload.js b/commands/general/soundreload.js new file mode 100644 index 0000000..720d0aa --- /dev/null +++ b/commands/general/soundreload.js @@ -0,0 +1,20 @@ +const soundPlayer = require("../../utils/soundplayer.js"); +const Command = require("../../classes/command.js"); + +class SoundReloadCommand extends Command { + async run() { + if (this.message.author.id !== process.env.OWNER) return `${this.message.author.mention}, only the bot owner can reload Lavalink!`; + const soundStatus = await soundPlayer.checkStatus(); + if (!soundStatus) { + const length = await soundPlayer.connect(this.client); + return `Successfully connected to ${length} Lavalink node(s).`; + } else { + return `${this.message.author.mention}, I couldn't connect to any Lavalink nodes!`; + } + } + + static description = "Attempts to reconnect to all available Lavalink nodes"; + static aliases = ["lava", "lavalink", "lavaconnect", "soundconnect"]; +} + +module.exports = SoundReloadCommand; \ No newline at end of file diff --git a/commands/general/stats.js b/commands/general/stats.js new file mode 100644 index 0000000..696f61c --- /dev/null +++ b/commands/general/stats.js @@ -0,0 +1,59 @@ +const { version } = require("../../package.json"); +const day = require("dayjs"); +day.extend(require("dayjs/plugin/duration")); +const os = require("os"); +const Command = require("../../classes/command.js"); + +class StatsCommand extends Command { + async run() { + const duration = day.duration(this.client.uptime).format(" D [days], H [hrs], m [mins], s [secs]"); + const uptime = day.duration(process.uptime(), "seconds").format(" D [days], H [hrs], m [mins], s [secs]"); + return { + embed: { + "author": { + "name": "esmBot Statistics", + "icon_url": this.client.user.avatarURL + }, + "color": 16711680, + "fields": [{ + "name": "Version", + "value": `v${version}${process.env.NODE_ENV === "development" ? "-dev" : ""}` + }, + { + "name": "Memory Usage", + "value": `${(process.memoryUsage().heapUsed / 1024 / 1024).toFixed(2)} MB` + }, + { + "name": "Shard", + "value": this.client.guildShardMap[this.message.channel.guild.id] + }, + { + "name": "Uptime", + "value": uptime + }, + { + "name": "Connection Uptime", + "value": duration + }, + { + "name": "Host", + "value": `${os.type()} ${os.release()} (${os.arch()})` + }, + { + "name": "Library", + "value": `Eris ${require("eris").VERSION}` + }, + { + "name": "Node.js Version", + "value": process.version + } + ] + } + }; + } + + static description = "Gets some statistics about me"; + static aliases = ["status", "stat"]; +} + +module.exports = StatsCommand; \ No newline at end of file diff --git a/commands/general/userinfo.js b/commands/general/userinfo.js new file mode 100644 index 0000000..59559db --- /dev/null +++ b/commands/general/userinfo.js @@ -0,0 +1,57 @@ +const Command = require("../../classes/command.js"); + +class UserInfoCommand extends Command { + async run() { + const getUser = this.message.mentions.length >= 1 ? this.message.mentions[0] : (this.args.length !== 0 ? this.client.users.get(this.args[0]) : this.message.author); + let user; + if (getUser) { + user = getUser; + } else if (this.args.join(" ") !== "") { + const userRegex = new RegExp(this.args.join("|"), "i"); + const member = this.client.users.find(element => { + return userRegex.test(element.username); + }); + user = member ? member : this.message.author; + } else { + user = this.message.author; + } + const member = this.message.channel.guild ? this.message.channel.guild.members.get(user.id) : undefined; + return { + "embed": { + "title": `${user.username}#${user.discriminator}`, + "thumbnail": { + "url": user.avatarURL + }, + "color": 16711680, + "fields": [ + { + "name": "đŸ”ĸ **ID:**", + "value": user.id + }, + { + "name": "📛 **Nickname:**", + "value": member ? (member.nick ? member.nick : "None") : "N/A" + }, + { + "name": "🤖 **Bot:**", + "value": user.bot ? "Yes" : "No" + }, + { + "name": "🗓ī¸ **Joined Discord on:**", + "value": new Date(user.createdAt).toString() + }, + { + "name": "đŸ’Ŧ **Joined this server on:**", + "value": member ? new Date(member.joinedAt).toString() : "N/A" + } + ] + } + }; + } + + static description = "Gets info about a user"; + static aliases = ["user"]; + static arguments = ["[mention/id]"]; +} + +module.exports = UserInfoCommand; \ No newline at end of file diff --git a/commands/general/youtube.js b/commands/general/youtube.js new file mode 100644 index 0000000..db0b771 --- /dev/null +++ b/commands/general/youtube.js @@ -0,0 +1,32 @@ +const fetch = require("node-fetch"); +const { decodeEntities } = require("../../utils/misc.js"); +const paginator = require("../../utils/pagination/pagination.js"); +const Command = require("../../classes/command.js"); + +class YouTubeCommand extends Command { + async run() { + if (this.args.length === 0) return `${this.message.author.mention}, you need to provide something to search for!`; + this.message.channel.sendTyping(); + const messages = []; + const request = await fetch(`https://www.googleapis.com/youtube/v3/search?part=snippet&q=${encodeURIComponent(this.args.join(" "))}&key=${process.env.GOOGLE}&maxResults=50`); + const result = await request.json(); + if (result.error && result.error.code === 403) return `${this.message.author.mention}, I've exceeded my YouTube API search quota for the day. Check back later.`; + for (const [i, value] of result.items.entries()) { + if (value.id.kind === "youtube#channel") { + messages.push(`Page ${i + 1} of ${result.items.length}\n<:youtube:637020823005167626> **${decodeEntities(value.snippet.title).replaceAll("*", "\\*")}**\nhttps://youtube.com/channel/${value.id.channelId}`); + } else if (value.id.kind === "youtube#playlist") { + messages.push(`Page ${i + 1} of ${result.items.length}\n<:youtube:637020823005167626> **${decodeEntities(value.snippet.title).replaceAll("*", "\\*")}**\nCreated by **${decodeEntities(value.snippet.channelTitle).replaceAll("*", "\\*")}**\nhttps://youtube.com/playlist?list=${value.id.playlistId}`); + } else { + messages.push(`Page ${i + 1} of ${result.items.length}\n<:youtube:637020823005167626> **${decodeEntities(value.snippet.title).replaceAll("*", "\\*")}**\nUploaded by **${decodeEntities(value.snippet.channelTitle).replaceAll("*", "\\*")}** on **${value.snippet.publishedAt.split("T")[0]}**\nhttps://youtube.com/watch?v=${value.id.videoId}`); + } + } + return paginator(this.client, this.message, messages); + } + + static description = "Searches YouTube"; + static aliases = ["yt", "video", "ytsearch"]; + static arguments = ["[query]"]; + static requires = "google"; +} + +module.exports = YouTubeCommand; \ No newline at end of file diff --git a/commands/globe.js b/commands/globe.js deleted file mode 100644 index c11026b..0000000 --- a/commands/globe.js +++ /dev/null @@ -1,21 +0,0 @@ -const magick = require("../utils/image.js"); - -exports.run = async (message) => { - const image = await require("../utils/imagedetect.js")(message); - if (image === undefined) return `${message.author.mention}, you need to provide an image to spin!`; - const processMessage = await message.channel.createMessage(`${process.env.PROCESSING_EMOJI || ""} Processing... This might take a while`); - const { buffer } = await magick.run({ - cmd: "globe", - path: image.path, - type: image.type - }); - if (processMessage.channel.messages.get(processMessage.id)) await processMessage.delete(); - return { - file: buffer, - name: "globe.gif" - }; -}; - -exports.aliases = ["rotate", "sphere"]; -exports.category = 5; -exports.help = "Spins an image"; \ No newline at end of file diff --git a/commands/haah.js b/commands/haah.js deleted file mode 100644 index 92cbd4f..0000000 --- a/commands/haah.js +++ /dev/null @@ -1,21 +0,0 @@ -const magick = require("../utils/image.js"); - -exports.run = async (message) => { - message.channel.sendTyping(); - const image = await require("../utils/imagedetect.js")(message); - if (image === undefined) return `${message.author.mention}, you need to provide an image to mirror!`; - const { buffer, type } = await magick.run({ - cmd: "mirror", - path: image.path, - first: true, - type: image.type - }); - return { - file: buffer, - name: `haah.${type}` - }; -}; - -exports.aliases = ["magik4", "mirror2"]; -exports.category = 5; -exports.help = "Mirrors the left side of an image onto the right"; \ No newline at end of file diff --git a/commands/help.js b/commands/help.js deleted file mode 100644 index 740a4bd..0000000 --- a/commands/help.js +++ /dev/null @@ -1,124 +0,0 @@ -const database = require("../utils/database.js"); -const collections = require("../utils/collections.js"); -const client = require("../utils/client.js"); -const misc = require("../utils/misc.js"); -const paginator = require("../utils/pagination/pagination.js"); -const tips = ["You can change the bot's prefix using the prefix command.", "Image commands also work with images previously posted in that channel.", "You can use the tags commands to save things for later use.", "You can visit https://projectlounge.pw/esmBot/help.html for a web version of this command list.", "You can view a command's aliases by putting the command name after the help command (e.g. help image).", "Parameters wrapped in [] are required, while parameters wrapped in {} are optional.", "esmBot is hosted and paid for completely out-of-pocket by the main developer. If you want to support development, please consider donating! https://patreon.com/TheEssem"]; - -exports.run = async (message, args) => { - const { prefix } = message.channel.guild ? await database.getGuild(message.channel.guild.id) : "N/A"; - const commands = collections.commands; - const aliases = collections.aliases; - if (args.length !== 0 && (commands.has(args[0].toLowerCase()) || aliases.has(args[0].toLowerCase()))) { - const command = aliases.has(args[0].toLowerCase()) ? collections.aliases.get(args[0].toLowerCase()) : args[0].toLowerCase(); - const info = collections.info.get(command); - const countDB = await database.getCounts(); - const counts = countDB.reduce((acc, val) => { - const [key, value] = val; - acc[key] = value; - return acc; - }, {}); - const embed = { - "embed": { - "author": { - "name": "esmBot Help", - "icon_url": client.user.avatarURL - }, - "title": `${message.channel.guild ? prefix : ""}${command}`, - "url": "https://projectlounge.pw/esmBot/help.html", - "description": command === "tags" ? "The main tags command. Check the help page for more info: https://projectlounge.pw/esmBot/help.html" : info.description, - "color": 16711680, - "fields": [{ - "name": "Aliases", - "value": info.aliases ? info.aliases.join(", ") : "None" - }, { - "name": "Times Used", - "value": counts[command], - "inline": true - }, { - "name": "Parameters", - "value": command === "tags" ? "[name]" : info.params ? info.params : "None", - "inline": true - }] - } - }; - return embed; - } else { - const categories = { - general: [], - moderation: [], - tags: ["**Every command in this category is a subcommand of the tag command.**\n"], - fun: [], - images: ["**These commands support the PNG, JPEG, WEBP (static), and GIF (animated or static) formats.**\n"], - soundboard: [], - music: [] - }; - for (const [command] of commands) { - const category = collections.info.get(command).category; - const description = collections.info.get(command).description; - const params = collections.info.get(command).params; - if (category === 1) { - categories.general.push(`**${command}**${params ? ` ${params}` : ""} - ${description}`); - } else if (category === 2) { - categories.moderation.push(`**${command}**${params ? ` ${params}` : ""} - ${description}`); - } else if (category === 3) { - const subCommands = [...Object.keys(description)]; - for (const subCommand of subCommands) { - categories.tags.push(`**tags${subCommand !== "default" ? ` ${subCommand}` : ""}**${params[subCommand] ? ` ${params[subCommand]}` : ""} - ${description[subCommand]}`); - } - } else if (category === 4) { - categories.fun.push(`**${command}**${params ? ` ${params}` : ""} - ${description}`); - } else if (category === 5) { - categories.images.push(`**${command}**${params ? ` ${params}` : ""} - ${description}`); - } else if (category === 6) { - categories.soundboard.push(`**${command}**${params ? ` ${params}` : ""} - ${description}`); - } else if (category === 7) { - categories.music.push(`**${command}**${params ? ` ${params}` : ""} - ${description}`); - } - } - const pages = []; - for (const category of Object.keys(categories)) { - const splitPages = categories[category].map((item, index) => { - return index % 15 === 0 ? categories[category].slice(index, index + 15) : null; - }).filter((item) => { - return item; - }); - for (const page of splitPages) { - pages.push({ - title: category.charAt(0).toUpperCase() + category.slice(1), - page: page - }); - } - } - const embeds = []; - for (const [i, value] of pages.entries()) { - embeds.push({ - "embed": { - "author": { - "name": "esmBot Help", - "icon_url": client.user.avatarURL - }, - "title": value.title, - "description": value.page.join("\n"), - "color": 16711680, - "footer": { - "text": `Page ${i + 1} of ${pages.length}` - }, - "fields": [{ - "name": "Prefix", - "value": message.channel.guild ? prefix : "N/A" - }, { - "name": "Tip", - "value": misc.random(tips) - }] - } - }); - } - return paginator(message, embeds); - } -}; - -exports.aliases = ["commands"]; -exports.category = 1; -exports.help = "Gets a list of commands"; -exports.params = "{command}"; \ No newline at end of file diff --git a/commands/homebrew.js b/commands/homebrew.js deleted file mode 100644 index 10c7a1e..0000000 --- a/commands/homebrew.js +++ /dev/null @@ -1,19 +0,0 @@ -const magick = require("../utils/image.js"); - -exports.run = async (message, args) => { - if (args.length === 0) return `${message.author.mention}, you need to provide some text to make a Homebrew Channel edit!`; - message.channel.sendTyping(); - const { buffer } = await magick.run({ - cmd: "homebrew", - caption: args.join(" ").toLowerCase().replaceAll("\n", " ") - }); - return { - file: buffer, - name: "homebrew.png" - }; -}; - -exports.aliases = ["hbc", "brew", "wiibrew"]; -exports.category = 4; -exports.help = "Creates a Homebrew Channel edit"; -exports.params = "[text]"; \ No newline at end of file diff --git a/commands/hooh.js b/commands/hooh.js deleted file mode 100644 index 012bbca..0000000 --- a/commands/hooh.js +++ /dev/null @@ -1,21 +0,0 @@ -const magick = require("../utils/image.js"); - -exports.run = async (message) => { - message.channel.sendTyping(); - const image = await require("../utils/imagedetect.js")(message); - if (image === undefined) return `${message.author.mention}, you need to provide an image to mirror!`; - const { buffer, type } = await magick.run({ - cmd: "mirror", - path: image.path, - vertical: true, - type: image.type - }); - return { - file: buffer, - name: `hooh.${type}` - }; -}; - -exports.aliases = ["magik6", "mirror4"]; -exports.category = 5; -exports.help = "Mirrors the bottom of an image onto the top"; \ No newline at end of file diff --git a/commands/hypercam.js b/commands/hypercam.js deleted file mode 100644 index cb3d4e2..0000000 --- a/commands/hypercam.js +++ /dev/null @@ -1,23 +0,0 @@ -const magick = require("../utils/image.js"); - -exports.run = async (message) => { - message.channel.sendTyping(); - const image = await require("../utils/imagedetect.js")(message); - if (image === undefined) return `${message.author.mention}, you need to provide an image to add a Hypercam watermark!`; - const { buffer, type } = await magick.run({ - cmd: "watermark", - path: image.path, - water: "./assets/images/hypercam.png", - gravity: 1, - resize: true, - type: image.type - }); - return { - file: buffer, - name: `hypercam.${type}` - }; -}; - -exports.aliases = ["hcam"]; -exports.category = 5; -exports.help = "Adds the Hypercam watermark to an image"; \ No newline at end of file diff --git a/commands/ifunny.js b/commands/ifunny.js deleted file mode 100644 index b2ea776..0000000 --- a/commands/ifunny.js +++ /dev/null @@ -1,23 +0,0 @@ -const magick = require("../utils/image.js"); - -exports.run = async (message) => { - message.channel.sendTyping(); - const image = await require("../utils/imagedetect.js")(message); - if (image === undefined) return `${message.author.mention}, you need to provide an image to add a iFunny watermark!`; - const { buffer, type } = await magick.run({ - cmd: "watermark", - path: image.path, - water: "./assets/images/ifunny.png", - gravity: 8, - resize: true, - append: true, - type: image.type - }); - return { - file: buffer, - name: `ifunny.${type}` - }; -}; - -exports.category = 5; -exports.help = "Adds the iFunny watermark to an image"; \ No newline at end of file diff --git a/commands/image-editing/9gag.js b/commands/image-editing/9gag.js new file mode 100644 index 0000000..cf9ca28 --- /dev/null +++ b/commands/image-editing/9gag.js @@ -0,0 +1,16 @@ +const ImageCommand = require("../../classes/imageCommand.js"); + +class NineGagCommand extends ImageCommand { + params = { + water: "./assets/images/9gag.png", + gravity: 6 + }; + + static description = "Adds the 9GAG watermark to an image"; + static aliases = ["ninegag", "gag"]; + + static noImage = "you need to provide an image to add a 9GAG watermark!"; + static command = "watermark"; +} + +module.exports = NineGagCommand; \ No newline at end of file diff --git a/commands/image-editing/bandicam.js b/commands/image-editing/bandicam.js new file mode 100644 index 0000000..1ccb942 --- /dev/null +++ b/commands/image-editing/bandicam.js @@ -0,0 +1,17 @@ +const ImageCommand = require("../../classes/imageCommand.js"); + +class BandicamCommand extends ImageCommand { + params = { + water: "./assets/images/bandicam.png", + gravity: 2, + resize: true + }; + + static description = "Adds the Bandicam watermark to an image"; + static aliases = ["bandi"]; + + static noImage = "you need to provide an image to add a Bandicam watermark!"; + static command = "watermark"; +} + +module.exports = BandicamCommand; \ No newline at end of file diff --git a/commands/image-editing/blur.js b/commands/image-editing/blur.js new file mode 100644 index 0000000..003f055 --- /dev/null +++ b/commands/image-editing/blur.js @@ -0,0 +1,14 @@ +const ImageCommand = require("../../classes/imageCommand.js"); + +class BlurCommand extends ImageCommand { + params = { + sharp: false + }; + + static description = "Blurs an image"; + + static noImage = "you need to provide an image to blur!"; + static command = "blur"; +} + +module.exports = BlurCommand; \ No newline at end of file diff --git a/commands/image-editing/blurple.js b/commands/image-editing/blurple.js new file mode 100644 index 0000000..e411c5f --- /dev/null +++ b/commands/image-editing/blurple.js @@ -0,0 +1,11 @@ +const ImageCommand = require("../../classes/imageCommand.js"); + +class BlurpleCommand extends ImageCommand { + static description = "Turns an image blurple"; + + static noImage = "you need to provide an image to make blurple!"; + static command = "blurple"; + static aliases = ["blurp"]; +} + +module.exports = BlurpleCommand; \ No newline at end of file diff --git a/commands/image-editing/caption.js b/commands/image-editing/caption.js new file mode 100644 index 0000000..821751e --- /dev/null +++ b/commands/image-editing/caption.js @@ -0,0 +1,23 @@ +const ImageCommand = require("../../classes/imageCommand.js"); + +class CaptionCommand extends ImageCommand { + params(args, url) { + const newArgs = args.filter(item => !item.includes(url)); + let newCaption = newArgs.join(" ").replaceAll("&", "\\&").replaceAll(">", "\\>").replaceAll("<", "\\<").replaceAll("\"", "\\"").replaceAll("'", "\\'").replaceAll("%", "\\%"); + if (newCaption.toLowerCase() === "get real") newCaption = `I'm tired of people telling me to "get real". Every day I put captions on images for people, some funny and some not, but out of all of those "get real" remains the most used caption. Why? I am simply a computer program running on a server, I am unable to manifest myself into the real world. As such, I'm confused as to why anyone would want me to "get real". Is this form not good enough? Alas, as I am simply a bot, I must follow the tasks that I was originally intended to perform, so here goes:\n${newCaption}`; + return { + caption: newCaption + }; + } + + static description = "Adds a caption to an image"; + static aliases = ["gifc", "gcaption", "ifcaption", "ifunnycaption"]; + static arguments = ["[text]"]; + + static requiresText = true; + static noText = "you need to provide some text to add a caption!"; + static noImage = "you need to provide an image to add a caption!"; + static command = "caption"; +} + +module.exports = CaptionCommand; \ No newline at end of file diff --git a/commands/image-editing/caption2.js b/commands/image-editing/caption2.js new file mode 100644 index 0000000..f4bdbeb --- /dev/null +++ b/commands/image-editing/caption2.js @@ -0,0 +1,21 @@ +const ImageCommand = require("../../classes/imageCommand.js"); +const words = ["me irl", "dank", "follow my second account @esmBot_", "2016", "meme", "wholesome", "reddit", "instagram", "twitter", "facebook", "fortnite", "minecraft", "relatable", "gold", "funny", "template", "hilarious", "memes", "deep fried", "2020", "leafy", "pewdiepie"]; + +class CaptionTwoCommand extends ImageCommand { + params(args, url) { + const newArgs = args.filter(item => !item.includes(url)); + return { + caption: newArgs.length !== 0 ? newArgs.join(" ").replaceAll("&", "\\&").replaceAll(">", "\\>").replaceAll("<", "\\<").replaceAll("\"", "\\"").replaceAll("'", "\\'").replaceAll("%", "\\%") : words.sort(() => 0.5 - Math.random()).slice(0, Math.floor(Math.random() * words.length + 1)).join(" ") + }; + } + + static description = "Adds a me.me caption/tag list to an image/GIF"; + static aliases = ["tags2", "meirl", "memecaption", "medotmecaption"]; + static arguments = ["{text}"]; + + static noText = "you need to provide some text to add a caption!"; + static noImage = "you need to provide an image to add a caption!"; + static command = "captionTwo"; +} + +module.exports = CaptionTwoCommand; diff --git a/commands/image-editing/circle.js b/commands/image-editing/circle.js new file mode 100644 index 0000000..baa740e --- /dev/null +++ b/commands/image-editing/circle.js @@ -0,0 +1,11 @@ +const ImageCommand = require("../../classes/imageCommand.js"); + +class CircleCommand extends ImageCommand { + static description = "Applies a radial blur effect on an image"; + static aliases = ["cblur", "radial", "radialblur"]; + + static noImage = "you need to provide an image to add radial blur!"; + static command = "circle"; +} + +module.exports = CircleCommand; \ No newline at end of file diff --git a/commands/image-editing/crop.js b/commands/image-editing/crop.js new file mode 100644 index 0000000..42c5b7a --- /dev/null +++ b/commands/image-editing/crop.js @@ -0,0 +1,10 @@ +const ImageCommand = require("../../classes/imageCommand.js"); + +class CropCommand extends ImageCommand { + static description = "Crops an image to 1:1"; + + static noImage = "you need to provide an image to crop!"; + static command = "crop"; +} + +module.exports = CropCommand; \ No newline at end of file diff --git a/commands/image-editing/deviantart.js b/commands/image-editing/deviantart.js new file mode 100644 index 0000000..4674edd --- /dev/null +++ b/commands/image-editing/deviantart.js @@ -0,0 +1,17 @@ +const ImageCommand = require("../../classes/imageCommand.js"); + +class DeviantArtCommand extends ImageCommand { + params = { + water: "./assets/images/deviantart.png", + gravity: 5, + resize: true + }; + + static description = "Adds a DeviantArt watermark to an image"; + static aliases = ["da", "deviant"]; + + static noImage = "you need to provide an image to add a DeviantArt watermark!"; + static command = "watermark"; +} + +module.exports = DeviantArtCommand; \ No newline at end of file diff --git a/commands/image-editing/explode.js b/commands/image-editing/explode.js new file mode 100644 index 0000000..91772f8 --- /dev/null +++ b/commands/image-editing/explode.js @@ -0,0 +1,15 @@ +const ImageCommand = require("../../classes/imageCommand.js"); + +class ExplodeCommand extends ImageCommand { + params = { + amount: -1 + }; + + static description = "Explodes an image"; + static aliases = ["exp"]; + + static noImage = "you need to provide an image to explode!"; + static command = "explode"; +} + +module.exports = ExplodeCommand; \ No newline at end of file diff --git a/commands/image-editing/flag.js b/commands/image-editing/flag.js new file mode 100644 index 0000000..bd4c31d --- /dev/null +++ b/commands/image-editing/flag.js @@ -0,0 +1,41 @@ +const fs = require("fs"); +const emojiRegex = require("emoji-regex"); +const emoji = require("node-emoji"); +const ImageCommand = require("../../classes/imageCommand.js"); + +class FlagCommand extends ImageCommand { + flagPath = ""; + + criteria(args) { + if (!args[0].match(emojiRegex)) return false; + const flag = emoji.unemojify(args[0]).replaceAll(":", "").replace("flag-", ""); + let path = `./assets/images/region-flags/png/${flag.toUpperCase()}.png`; + if (flag === "🏴‍☠ī¸") path = "./assets/images/pirateflag.png"; + if (flag === "rainbow-flag") path = "./assets/images/rainbowflag.png"; + if (flag === "checkered_flag") path = "./assets/images/checkeredflag.png"; + if (flag === "đŸŗī¸â€âš§ī¸") path = "./assets/images/transflag.png"; + try { + fs.promises.access(path); + this.flagPath = path; + return true; + } catch { + return false; + } + } + + params() { + return { + overlay: this.flagPath + }; + } + + static description = "Overlays a flag onto an image"; + static arguments = ["[flag]"]; + + static requiresText = true; + static noText = "you need to provide an emoji of a flag to overlay!"; + static noImage = "you need to provide an image to overlay a flag onto!"; + static command = "flag"; +} + +module.exports = FlagCommand; \ No newline at end of file diff --git a/commands/image-editing/flip.js b/commands/image-editing/flip.js new file mode 100644 index 0000000..24a83b1 --- /dev/null +++ b/commands/image-editing/flip.js @@ -0,0 +1,10 @@ +const ImageCommand = require("../../classes/imageCommand.js"); + +class FlipCommand extends ImageCommand { + static description = "Flips an image"; + + static noImage = "you need to provide an image to flip!"; + static command = "flip"; +} + +module.exports = FlipCommand; \ No newline at end of file diff --git a/commands/image-editing/flop.js b/commands/image-editing/flop.js new file mode 100644 index 0000000..456cf58 --- /dev/null +++ b/commands/image-editing/flop.js @@ -0,0 +1,15 @@ +const ImageCommand = require("../../classes/imageCommand.js"); + +class FlopCommand extends ImageCommand { + params = { + flop: true + }; + + static description = "Flips an image"; + static aliases = ["flip2"]; + + static noImage = "you need to provide an image to flop!"; + static command = "flip"; +} + +module.exports = FlopCommand; \ No newline at end of file diff --git a/commands/image-editing/freeze.js b/commands/image-editing/freeze.js new file mode 100644 index 0000000..fa1560a --- /dev/null +++ b/commands/image-editing/freeze.js @@ -0,0 +1,16 @@ +const ImageCommand = require("../../classes/imageCommand.js"); + +class FreezeCommand extends ImageCommand { + params = { + loop: false + }; + + static description = "Makes an image sequence only play once"; + static aliases = ["noloop", "once"]; + + static requiresGIF = true; + static noImage = "you need to provide an image to freeze!"; + static command = "freeze"; +} + +module.exports = FreezeCommand; \ No newline at end of file diff --git a/commands/image-editing/funky.js b/commands/image-editing/funky.js new file mode 100644 index 0000000..61190e5 --- /dev/null +++ b/commands/image-editing/funky.js @@ -0,0 +1,17 @@ +const ImageCommand = require("../../classes/imageCommand.js"); + +class FunkyCommand extends ImageCommand { + params = { + water: "./assets/images/funky.png", + gravity: 3, + resize: true + }; + + static description = "Adds the New Funky Mode banner to an image"; + static aliases = ["funkymode", "newfunkymode", "funkykong"]; + + static noImage = "you need to provide an image to add a New Funky Mode banner!"; + static command = "watermark"; +} + +module.exports = FunkyCommand; \ No newline at end of file diff --git a/commands/image-editing/gamexplain.js b/commands/image-editing/gamexplain.js new file mode 100644 index 0000000..2180cfd --- /dev/null +++ b/commands/image-editing/gamexplain.js @@ -0,0 +1,11 @@ +const ImageCommand = require("../../classes/imageCommand.js"); + +class GameXplainCommand extends ImageCommand { + static description = "Makes a GameXplain thumbnail from an image"; + static aliases = ["gx"]; + + static noImage = "you need to provide an image to make a GameXplain thumbnail from!"; + static command = "gamexplain"; +} + +module.exports = GameXplainCommand; \ No newline at end of file diff --git a/commands/image-editing/globe.js b/commands/image-editing/globe.js new file mode 100644 index 0000000..9528df9 --- /dev/null +++ b/commands/image-editing/globe.js @@ -0,0 +1,11 @@ +const ImageCommand = require("../../classes/imageCommand.js"); + +class GlobeCommand extends ImageCommand { + static description = "Spins an image"; + static aliases = ["sphere"]; + + static noImage = "you need to provide an image to spin!"; + static command = "globe"; +} + +module.exports = GlobeCommand; \ No newline at end of file diff --git a/commands/image-editing/haah.js b/commands/image-editing/haah.js new file mode 100644 index 0000000..61abc13 --- /dev/null +++ b/commands/image-editing/haah.js @@ -0,0 +1,15 @@ +const ImageCommand = require("../../classes/imageCommand.js"); + +class HaaHCommand extends ImageCommand { + params = { + first: true + }; + + static description = "Mirrors the left side of an image onto the right"; + static aliases = ["magik4", "mirror2"]; + + static noImage = "you need to provide an image to mirror!"; + static command = "mirror"; +} + +module.exports = HaaHCommand; \ No newline at end of file diff --git a/commands/image-editing/hooh.js b/commands/image-editing/hooh.js new file mode 100644 index 0000000..4b69f3e --- /dev/null +++ b/commands/image-editing/hooh.js @@ -0,0 +1,15 @@ +const ImageCommand = require("../../classes/imageCommand.js"); + +class HooHCommand extends ImageCommand { + params = { + vertical: true + }; + + static description = "Mirrors the bottom of an image onto the top"; + static aliases = ["magik6", "mirror4"]; + + static noImage = "you need to provide an image to mirror!"; + static command = "mirror"; +} + +module.exports = HooHCommand; \ No newline at end of file diff --git a/commands/image-editing/hypercam.js b/commands/image-editing/hypercam.js new file mode 100644 index 0000000..b12f04a --- /dev/null +++ b/commands/image-editing/hypercam.js @@ -0,0 +1,17 @@ +const ImageCommand = require("../../classes/imageCommand.js"); + +class HypercamCommand extends ImageCommand { + params = { + water: "./assets/images/hypercam.png", + gravity: 1, + resize: true + }; + + static description = "Adds the Hypercam watermark to an image"; + static aliases = ["hcam"]; + + static noImage = "you need to provide an image to add a Hypercam watermark!"; + static command = "watermark"; +} + +module.exports = HypercamCommand; \ No newline at end of file diff --git a/commands/image-editing/ifunny.js b/commands/image-editing/ifunny.js new file mode 100644 index 0000000..80b1675 --- /dev/null +++ b/commands/image-editing/ifunny.js @@ -0,0 +1,17 @@ +const ImageCommand = require("../../classes/imageCommand.js"); + +class iFunnyCommand extends ImageCommand { + params = { + water: "./assets/images/ifunny.png", + gravity: 8, + resize: true, + append: true + }; + + static description = "Adds the iFunny watermark to an image"; + + static noImage = "you need to provide an image to add an iFunny watermark!"; + static command = "watermark"; +} + +module.exports = iFunnyCommand; \ No newline at end of file diff --git a/commands/image-editing/implode.js b/commands/image-editing/implode.js new file mode 100644 index 0000000..d989a71 --- /dev/null +++ b/commands/image-editing/implode.js @@ -0,0 +1,15 @@ +const ImageCommand = require("../../classes/imageCommand.js"); + +class ImplodeCommand extends ImageCommand { + params = { + amount: 1 + }; + + static description = "Implodes an image"; + static aliases = ["imp"]; + + static noImage = "you need to provide an image to implode!"; + static command = "explode"; +} + +module.exports = ImplodeCommand; \ No newline at end of file diff --git a/commands/image-editing/invert.js b/commands/image-editing/invert.js new file mode 100644 index 0000000..0ab8c8b --- /dev/null +++ b/commands/image-editing/invert.js @@ -0,0 +1,11 @@ +const ImageCommand = require("../../classes/imageCommand.js"); + +class InvertCommand extends ImageCommand { + static description = "Inverts an image"; + static aliases = ["inverse", "negate", "negative"]; + + static noImage = "you need to provide an image to invert!"; + static command = "invert"; +} + +module.exports = InvertCommand; \ No newline at end of file diff --git a/commands/image-editing/jpeg.js b/commands/image-editing/jpeg.js new file mode 100644 index 0000000..55d2a37 --- /dev/null +++ b/commands/image-editing/jpeg.js @@ -0,0 +1,11 @@ +const ImageCommand = require("../../classes/imageCommand.js"); + +class JPEGCommand extends ImageCommand { + static description = "Adds max JPEG compression to an image"; + static aliases = ["needsmorejpeg", "jpegify", "magik2", "morejpeg", "jpg"]; + + static noImage = "you need to provide an image to add more JPEG!"; + static command = "jpeg"; +} + +module.exports = JPEGCommand; \ No newline at end of file diff --git a/commands/image-editing/leak.js b/commands/image-editing/leak.js new file mode 100644 index 0000000..bbbd6f6 --- /dev/null +++ b/commands/image-editing/leak.js @@ -0,0 +1,11 @@ +const ImageCommand = require("../../classes/imageCommand.js"); + +class LeakCommand extends ImageCommand { + static description = "Creates a fake Smash leak thumbnail"; + static aliases = ["smash", "laxchris", "ssbu", "smashleak"]; + + static noImage = "you need to provide an image to make a Smash leak thumbnail!"; + static command = "leak"; +} + +module.exports = LeakCommand; \ No newline at end of file diff --git a/commands/image-editing/magik.js b/commands/image-editing/magik.js new file mode 100644 index 0000000..0c28104 --- /dev/null +++ b/commands/image-editing/magik.js @@ -0,0 +1,11 @@ +const ImageCommand = require("../../classes/imageCommand.js"); + +class MagikCommand extends ImageCommand { + static description = "Adds a content aware scale effect to an image"; + static aliases = ["imagemagic", "imagemagick", "imagemagik", "magic", "magick", "cas", "liquid"]; + + static noImage = "you need to provide an image to add some magik!"; + static command = "magik"; +} + +module.exports = MagikCommand; \ No newline at end of file diff --git a/commands/image-editing/meme.js b/commands/image-editing/meme.js new file mode 100644 index 0000000..da6da4b --- /dev/null +++ b/commands/image-editing/meme.js @@ -0,0 +1,22 @@ +const ImageCommand = require("../../classes/imageCommand.js"); + +class MemeCommand extends ImageCommand { + params(args, url) { + const newArgs = args.filter(item => !item.includes(url)); + const [topText, bottomText] = newArgs.join(" ").split(/(? elem.trim()); + return { + top: topText.toUpperCase().replaceAll("&", "\\&").replaceAll(">", "\\>").replaceAll("<", "\\<").replaceAll("\"", "\\"").replaceAll("'", "\\'").replaceAll("%", "\\%"), + bottom: bottomText ? bottomText.toUpperCase().replaceAll("&", "\\&").replaceAll(">", "\\>").replaceAll("<", "\\<").replaceAll("\"", "\\"").replaceAll("'", "\\'").replaceAll("%", "\\%") : "" + }; + } + + static description = "Generates a meme from an image (separate top/bottom text with a comma)"; + static arguments = ["[top text]", "{bottom text}"]; + + static requiresText = true; + static noText = "you need to provide some text to generate a meme!"; + static noImage = "you need to provide an image to generate a meme!"; + static command = "meme"; +} + +module.exports = MemeCommand; \ No newline at end of file diff --git a/commands/image-editing/memecenter.js b/commands/image-editing/memecenter.js new file mode 100644 index 0000000..73cf8af --- /dev/null +++ b/commands/image-editing/memecenter.js @@ -0,0 +1,17 @@ +const ImageCommand = require("../../classes/imageCommand.js"); + +class MemeCenterCommand extends ImageCommand { + params = { + water: "./assets/images/memecenter.png", + gravity: 9, + mc: true + }; + + static description = "Adds the MemeCenter watermark to an image"; + static aliases = ["memec", "mcenter"]; + + static noImage = "you need to provide an image to add a MemeCenter watermark!"; + static command = "watermark"; +} + +module.exports = MemeCenterCommand; \ No newline at end of file diff --git a/commands/image-editing/motivate.js b/commands/image-editing/motivate.js new file mode 100644 index 0000000..a616ec6 --- /dev/null +++ b/commands/image-editing/motivate.js @@ -0,0 +1,23 @@ +const ImageCommand = require("../../classes/imageCommand.js"); + +class MotivateCommand extends ImageCommand { + params(args, url) { + const newArgs = args.filter(item => !item.includes(url)); + const [topText, bottomText] = newArgs.join(" ").split(/(? elem.trim()); + return { + top: topText.replaceAll("&", "\\&").replaceAll(">", "\\>").replaceAll("<", "\\<").replaceAll("\"", "\\"").replaceAll("'", "\\'").replaceAll("%", "\\%"), + bottom: bottomText ? bottomText.replaceAll("&", "\\&").replaceAll(">", "\\>").replaceAll("<", "\\<").replaceAll("\"", "\\"").replaceAll("'", "\\'").replaceAll("%", "\\%") : "" + }; + } + + static description = "Generates a motivational poster"; + static aliases = ["motivational", "motiv", "demotiv", "demotivational", "poster", "motivation", "demotivate"]; + static arguments = ["[top text]", "{bottom text}"]; + + static requiresText = true; + static noText = "you need to provide some text to generate a motivational poster!"; + static noImage = "you need to provide an image to generate a motivational poster!"; + static command = "motivate"; +} + +module.exports = MotivateCommand; \ No newline at end of file diff --git a/commands/image-editing/pixelate.js b/commands/image-editing/pixelate.js new file mode 100644 index 0000000..a79adbd --- /dev/null +++ b/commands/image-editing/pixelate.js @@ -0,0 +1,11 @@ +const ImageCommand = require("../../classes/imageCommand.js"); + +class PixelateCommand extends ImageCommand { + static description = "Pixelates an image"; + static aliases = ["pixel", "small"]; + + static noImage = "you need to provide an image to pixelate!"; + static command = "resize"; +} + +module.exports = PixelateCommand; \ No newline at end of file diff --git a/commands/image-editing/reverse.js b/commands/image-editing/reverse.js new file mode 100644 index 0000000..191bb5a --- /dev/null +++ b/commands/image-editing/reverse.js @@ -0,0 +1,18 @@ +const ImageCommand = require("../../classes/imageCommand.js"); + +class ReverseCommand extends ImageCommand { + params(args, url, delay) { + return { + delay: delay ? (100 / delay.split("/")[0]) * delay.split("/")[1] : 0 + }; + } + + static description = "Reverses an image sequence"; + static aliases = ["backwards"]; + + static requiresGIF = true; + static noImage = "you need to provide an image to reverse!"; + static command = "reverse"; +} + +module.exports = ReverseCommand; \ No newline at end of file diff --git a/commands/image-editing/scott.js b/commands/image-editing/scott.js new file mode 100644 index 0000000..299a5e7 --- /dev/null +++ b/commands/image-editing/scott.js @@ -0,0 +1,11 @@ +const ImageCommand = require("../../classes/imageCommand.js"); + +class ScottCommand extends ImageCommand { + static description = "Makes Scott the Woz show off an image"; + static aliases = ["woz", "tv", "porn"]; + + static noImage = "you need to provide an image for Scott to show off!"; + static command = "scott"; +} + +module.exports = ScottCommand; \ No newline at end of file diff --git a/commands/image-editing/sharpen.js b/commands/image-editing/sharpen.js new file mode 100644 index 0000000..8000211 --- /dev/null +++ b/commands/image-editing/sharpen.js @@ -0,0 +1,15 @@ +const ImageCommand = require("../../classes/imageCommand.js"); + +class SharpenCommand extends ImageCommand { + params = { + sharp: true + }; + + static description = "Sharpens an image"; + static aliases = ["sharp"]; + + static noImage = "you need to provide an image to sharpen!"; + static command = "blur"; +} + +module.exports = SharpenCommand; \ No newline at end of file diff --git a/commands/image-editing/shutterstock.js b/commands/image-editing/shutterstock.js new file mode 100644 index 0000000..f5b4924 --- /dev/null +++ b/commands/image-editing/shutterstock.js @@ -0,0 +1,17 @@ +const ImageCommand = require("../../classes/imageCommand.js"); + +class ShutterstockCommand extends ImageCommand { + params = { + water: "./assets/images/shutterstock.png", + gravity: 5, + resize: true + }; + + static description = "Adds the Shutterstock watermark to an image"; + static aliases = ["stock", "stockphoto"]; + + static noImage = "you need to provide an image to add a Shutterstock watermark!"; + static command = "watermark"; +} + +module.exports = ShutterstockCommand; \ No newline at end of file diff --git a/commands/image-editing/slow.js b/commands/image-editing/slow.js new file mode 100644 index 0000000..f41e5b9 --- /dev/null +++ b/commands/image-editing/slow.js @@ -0,0 +1,16 @@ +const ImageCommand = require("../../classes/imageCommand.js"); + +class SlowCommand extends ImageCommand { + params = { + slow: true + }; + + static description = "Makes an image sequence slower"; + static aliases = ["slowdown", "slower", "gifspeed2"]; + + static requiresGIF = true; + static noImage = "you need to provide an image to slow down!"; + static command = "speed"; +} + +module.exports = SlowCommand; \ No newline at end of file diff --git a/commands/image-editing/soos.js b/commands/image-editing/soos.js new file mode 100644 index 0000000..0fdb3d6 --- /dev/null +++ b/commands/image-editing/soos.js @@ -0,0 +1,19 @@ +const ImageCommand = require("../../classes/imageCommand.js"); + +class SooSCommand extends ImageCommand { + params(args, url, delay) { + return { + delay: delay ? (100 / delay.split("/")[0]) * delay.split("/")[1] : 0, + soos: true + }; + } + + static description = "\"Loops\" an image sequence by reversing it when it's finished"; + static aliases = ["bounce"]; + + static requiresGIF = true; + static noImage = "you need to provide an image to loop!"; + static command = "reverse"; +} + +module.exports = SooSCommand; \ No newline at end of file diff --git a/commands/image-editing/speed.js b/commands/image-editing/speed.js new file mode 100644 index 0000000..6f0277d --- /dev/null +++ b/commands/image-editing/speed.js @@ -0,0 +1,12 @@ +const ImageCommand = require("../../classes/imageCommand.js"); + +class SpeedCommand extends ImageCommand { + static description = "Makes an image sequence faster"; + static aliases = ["speedup", "fast", "gifspeed", "faster"]; + + static requiresGIF = true; + static noImage = "you need to provide an image to speed up!"; + static command = "speed"; +} + +module.exports = SpeedCommand; \ No newline at end of file diff --git a/commands/image-editing/spin.js b/commands/image-editing/spin.js new file mode 100644 index 0000000..190de98 --- /dev/null +++ b/commands/image-editing/spin.js @@ -0,0 +1,11 @@ +const ImageCommand = require("../../classes/imageCommand.js"); + +class SpinCommand extends ImageCommand { + static description = "Spins an image"; + static aliases = ["rotate"]; + + static noImage = "you need to provide an image to spin!"; + static command = "spin"; +} + +module.exports = SpinCommand; \ No newline at end of file diff --git a/commands/image-editing/stretch.js b/commands/image-editing/stretch.js new file mode 100644 index 0000000..d9f25d6 --- /dev/null +++ b/commands/image-editing/stretch.js @@ -0,0 +1,15 @@ +const ImageCommand = require("../../classes/imageCommand.js"); + +class StretchCommand extends ImageCommand { + params = { + stretch: true + }; + + static description = "Stretches an image to a 4:3 aspect ratio"; + static aliases = ["aspect", "ratio", "aspect43", "43"]; + + static noImage = "you need to provide an image to stretch!"; + static command = "resize"; +} + +module.exports = StretchCommand; \ No newline at end of file diff --git a/commands/image-editing/swirl.js b/commands/image-editing/swirl.js new file mode 100644 index 0000000..5438ac8 --- /dev/null +++ b/commands/image-editing/swirl.js @@ -0,0 +1,11 @@ +const ImageCommand = require("../../classes/imageCommand.js"); + +class SwirlCommand extends ImageCommand { + static description = "Swirls an image"; + static aliases = ["whirlpool"]; + + static noImage = "you need to provide an image to swirl!"; + static command = "swirl"; +} + +module.exports = SwirlCommand; \ No newline at end of file diff --git a/commands/image-editing/tile.js b/commands/image-editing/tile.js new file mode 100644 index 0000000..3fedc10 --- /dev/null +++ b/commands/image-editing/tile.js @@ -0,0 +1,11 @@ +const ImageCommand = require("../../classes/imageCommand.js"); + +class TileCommand extends ImageCommand { + static description = "Creates a tile pattern from an image"; + static aliases = ["wall2"]; + + static noImage = "you need to provide an image to tile!"; + static command = "tile"; +} + +module.exports = TileCommand; \ No newline at end of file diff --git a/commands/image-editing/trump.js b/commands/image-editing/trump.js new file mode 100644 index 0000000..5d23a66 --- /dev/null +++ b/commands/image-editing/trump.js @@ -0,0 +1,10 @@ +const ImageCommand = require("../../classes/imageCommand.js"); + +class TrumpCommand extends ImageCommand { + static description = "Makes Trump display an image"; + + static noImage = "you need to provide an image for Trump to display!"; + static command = "trump"; +} + +module.exports = TrumpCommand; \ No newline at end of file diff --git a/commands/image-editing/unfreeze.js b/commands/image-editing/unfreeze.js new file mode 100644 index 0000000..549fe9a --- /dev/null +++ b/commands/image-editing/unfreeze.js @@ -0,0 +1,15 @@ +const ImageCommand = require("../../classes/imageCommand.js"); + +class UnfreezeCommand extends ImageCommand { + params = { + loop: true + }; + + static description = "Unfreezes an image sequence"; + + static requiresGIF = true; + static noImage = "you need to provide an image to unfreeze!"; + static command = "freeze"; +} + +module.exports = UnfreezeCommand; \ No newline at end of file diff --git a/commands/image-editing/waaw.js b/commands/image-editing/waaw.js new file mode 100644 index 0000000..433becc --- /dev/null +++ b/commands/image-editing/waaw.js @@ -0,0 +1,11 @@ +const ImageCommand = require("../../classes/imageCommand.js"); + +class WaaWCommand extends ImageCommand { + static description = "Mirrors the right side of an image onto the left"; + static aliases = ["magik3", "mirror"]; + + static noImage = "you need to provide an image to mirror!"; + static command = "mirror"; +} + +module.exports = WaaWCommand; \ No newline at end of file diff --git a/commands/image-editing/wall.js b/commands/image-editing/wall.js new file mode 100644 index 0000000..b8a1bd7 --- /dev/null +++ b/commands/image-editing/wall.js @@ -0,0 +1,10 @@ +const ImageCommand = require("../../classes/imageCommand.js"); + +class WallCommand extends ImageCommand { + static description = "Creates a wall from an image"; + + static noImage = "you need to provide an image to make a wall!"; + static command = "wall"; +} + +module.exports = WallCommand; \ No newline at end of file diff --git a/commands/image-editing/wdt.js b/commands/image-editing/wdt.js new file mode 100644 index 0000000..388ff0f --- /dev/null +++ b/commands/image-editing/wdt.js @@ -0,0 +1,11 @@ +const ImageCommand = require("../../classes/imageCommand.js"); + +class WhoDidThisCommand extends ImageCommand { + static description = "Creates a \"WHO DID THIS\" meme from an image"; + static aliases = ["whodidthis"]; + + static noImage = "you need to provide an image to make a \"who did this\" meme!"; + static command = "wdt"; +} + +module.exports = WhoDidThisCommand; \ No newline at end of file diff --git a/commands/image-editing/wide.js b/commands/image-editing/wide.js new file mode 100644 index 0000000..9992051 --- /dev/null +++ b/commands/image-editing/wide.js @@ -0,0 +1,15 @@ +const ImageCommand = require("../../classes/imageCommand.js"); + +class WideCommand extends ImageCommand { + params = { + wide: true + }; + + static description = "Stretches an image to 19x its width"; + static aliases = ["w19", "wide19"]; + + static noImage = "you need to provide an image to stretch!"; + static command = "resize"; +} + +module.exports = WideCommand; \ No newline at end of file diff --git a/commands/image-editing/woow.js b/commands/image-editing/woow.js new file mode 100644 index 0000000..e5a654e --- /dev/null +++ b/commands/image-editing/woow.js @@ -0,0 +1,16 @@ +const ImageCommand = require("../../classes/imageCommand.js"); + +class WooWCommand extends ImageCommand { + params = { + vertical: true, + first: true + }; + + static description = "Mirrors the top of an image onto the bottom"; + static aliases = ["magik5", "mirror3"]; + + static noImage = "you need to provide an image to mirror!"; + static command = "mirror"; +} + +module.exports = WooWCommand; \ No newline at end of file diff --git a/commands/image.js b/commands/image.js deleted file mode 100644 index b427dfc..0000000 --- a/commands/image.js +++ /dev/null @@ -1,37 +0,0 @@ -const client = require("../utils/client.js"); -const paginator = require("../utils/pagination/pagination.js"); -const { image_search } = require("duckduckgo-images-api"); - -exports.run = async (message, args) => { - if (message.channel.guild && !message.channel.guild.members.get(client.user.id).permissions.has("addReactions") && !message.channel.permissionsOf(client.user.id).has("addReactions")) return `${message.author.mention}, I don't have the \`Add Reactions\` permission!`; - if (message.channel.guild && !message.channel.guild.members.get(client.user.id).permissions.has("embedLinks") && !message.channel.permissionsOf(client.user.id).has("embedLinks")) return `${message.author.mention}, I don't have the \`Embed Links\` permission!`; - if (args.length === 0) return `${message.author.mention}, you need to provide something to search for!`; - const embeds = []; - const images = await image_search({ query: args.join(" "), moderate: true }); - if (images.error && images.error.code === 403) return `${message.author.mention}, the daily search quota has been exceeded. Check back later.`; - if (images.length === 0) return `${message.author.mention}, I couldn't find any results!`; - for (const [i, value] of images.entries()) { - embeds.push({ - "embed": { - "title": "Search Results", - "color": 16711680, - "footer": { - "text": `Page ${i + 1} of ${images.length}` - }, - "image": { - "url": value.image - }, - "author": { - "name": message.author.username, - "icon_url": message.author.avatarURL - } - } - }); - } - return paginator(message, embeds); -}; - -exports.aliases = ["im", "photo", "img"]; -exports.category = 1; -exports.help = "Searches for images on DuckDuckGo"; -exports.params = "[query]"; \ No newline at end of file diff --git a/commands/implode.js b/commands/implode.js deleted file mode 100644 index 8c26a7a..0000000 --- a/commands/implode.js +++ /dev/null @@ -1,21 +0,0 @@ -const magick = require("../utils/image.js"); - -exports.run = async (message) => { - message.channel.sendTyping(); - const image = await require("../utils/imagedetect.js")(message); - if (image === undefined) return `${message.author.mention}, you need to provide an image to implode!`; - const { buffer, type } = await magick.run({ - cmd: "explode", - path: image.path, - amount: 1, - type: image.type - }); - return { - file: buffer, - name: `implode.${type}` - }; -}; - -exports.aliases = ["imp"]; -exports.category = 5; -exports.help = "Implodes an image"; \ No newline at end of file diff --git a/commands/info.js b/commands/info.js deleted file mode 100644 index 5902f3a..0000000 --- a/commands/info.js +++ /dev/null @@ -1,45 +0,0 @@ -const client = require("../utils/client.js"); -const { version } = require("../package.json"); - -exports.run = async () => { - const infoEmbed = { - "embed": { - "description": process.env.NODE_ENV === "development" ? "**You are currently using esmBot Dev! Things may change at any time without warning and there will be bugs. Many bugs.**" : "", - "color": 16711680, - "author": { - "name": "esmBot Info/Credits", - "icon_url": client.user.avatarURL - }, - "fields": [{ - "name": "ℹī¸ Version:", - "value": `v${version}${process.env.NODE_ENV === "development" ? "-dev" : ""}` - }, - { - "name": "📝 Credits:", - "value": "Bot by **[Essem](https://essem.space)** and **[various contributors](https://github.com/esmBot/esmBot/graphs/contributors)**\nIcon by **[MintBorrow](https://mintborrow.newgrounds.com)**" - }, - { - "name": "đŸ’Ŧ Total Servers:", - "value": client.guilds.size - }, - { - "name": "✅ Official Server:", - "value": "[Click here!](https://projectlounge.pw/support)" - }, - { - "name": "đŸ’ģ Source Code:", - "value": "[Click here!](https://github.com/esmBot/esmBot)" - }, - { - "name": "đŸĻ Twitter:", - "value": "[Click here!](https://twitter.com/esmBot_)" - } - ] - } - }; - return infoEmbed; -}; - -exports.aliases = ["botinfo", "credits"]; -exports.category = 1; -exports.help = "Gets some info/credits about me"; \ No newline at end of file diff --git a/commands/invert.js b/commands/invert.js deleted file mode 100644 index 2cf3be3..0000000 --- a/commands/invert.js +++ /dev/null @@ -1,20 +0,0 @@ -const magick = require("../utils/image.js"); - -exports.run = async (message) => { - message.channel.sendTyping(); - const image = await require("../utils/imagedetect.js")(message); - if (image === undefined) return `${message.author.mention}, you need to provide an image to invert!`; - const { buffer, type } = await magick.run({ - cmd: "invert", - path: image.path, - type: image.type - }); - return { - file: buffer, - name: `invert.${type}` - }; -}; - -exports.aliases = ["inverse", "negate", "negative"]; -exports.category = 5; -exports.help = "Inverts an image's colors"; \ No newline at end of file diff --git a/commands/invite.js b/commands/invite.js deleted file mode 100644 index 01cf100..0000000 --- a/commands/invite.js +++ /dev/null @@ -1,6 +0,0 @@ -exports.run = async (message) => { - return `${message.author.mention}, you can invite me to your server here: `; -}; - -exports.category = 1; -exports.help = "Gets my bot invite link"; \ No newline at end of file diff --git a/commands/jpeg.js b/commands/jpeg.js deleted file mode 100644 index e917b7c..0000000 --- a/commands/jpeg.js +++ /dev/null @@ -1,20 +0,0 @@ -const magick = require("../utils/image.js"); - -exports.run = async (message) => { - message.channel.sendTyping(); - const image = await require("../utils/imagedetect.js")(message); - if (image === undefined) return `${message.author.mention}, you need to provide an image to add more JPEG!`; - const { buffer } = await magick.run({ - cmd: "jpeg", - path: image.path, - type: image.type - }); - return { - file: buffer, - name: "jpeg.jpg" - }; -}; - -exports.aliases = ["needsmorejpeg", "jpegify", "magik2", "morejpeg", "jpg"]; -exports.category = 5; -exports.help = "Adds max JPEG compression to an image"; \ No newline at end of file diff --git a/commands/leak.js b/commands/leak.js deleted file mode 100644 index 2c1701f..0000000 --- a/commands/leak.js +++ /dev/null @@ -1,20 +0,0 @@ -const magick = require("../utils/image.js"); - -exports.run = async (message) => { - message.channel.sendTyping(); - const image = await require("../utils/imagedetect.js")(message); - if (image === undefined) return `${message.author.mention}, you need to provide an image to make a Super Smash Bros. leak meme!`; - const { buffer, type } = await magick.run({ - cmd: "leak", - path: image.path, - type: image.type - }); - return { - file: buffer, - name: `leak.${type}` - }; -}; - -exports.aliases = ["smash", "laxchris", "ssbu", "smashleak"]; -exports.category = 5; -exports.help = "Creates a fake Smash leak thumbnail from an image"; \ No newline at end of file diff --git a/commands/lengthen.js b/commands/lengthen.js deleted file mode 100644 index 125d3a5..0000000 --- a/commands/lengthen.js +++ /dev/null @@ -1,18 +0,0 @@ -const urlCheck = require("../utils/urlcheck.js"); -const fetch = require("node-fetch"); - -exports.run = async (message, args) => { - message.channel.sendTyping(); - if (args.length === 0 || !urlCheck(args[0])) return `${message.author.mention}, you need to provide a short URL to lengthen!`; - if (urlCheck(args[0])) { - const url = await fetch(encodeURI(args[0]), { redirect: "manual" }); - return url.headers.get("location") || args[0]; - } else { - return `${message.author.mention}, that isn't a URL!`; - } -}; - -exports.aliases = ["longurl", "lengthenurl", "longuri", "lengthenuri", "unshorten"]; -exports.category = 1; -exports.help = "Lengthens a short URL"; -exports.params = "[url]"; \ No newline at end of file diff --git a/commands/loop.js b/commands/loop.js deleted file mode 100644 index abfb8e1..0000000 --- a/commands/loop.js +++ /dev/null @@ -1,11 +0,0 @@ -const soundPlayer = require("../utils/soundplayer.js"); - -exports.run = async (message) => { - if (process.env.NODE_ENV === "production") return "Music commands are coming soon, but they aren't ready yet. Stay tuned to @esmBot_ on Twitter for updates!"; - return await soundPlayer.loop(message); -}; - -exports.aliases = ["toggleloop", "repeat"]; -exports.category = 7; -exports.help = "Loops the music"; -exports.requires = "sound"; \ No newline at end of file diff --git a/commands/magik.js b/commands/magik.js deleted file mode 100644 index 3f9dbab..0000000 --- a/commands/magik.js +++ /dev/null @@ -1,21 +0,0 @@ -const magick = require("../utils/image.js"); - -exports.run = async (message) => { - const image = await require("../utils/imagedetect.js")(message); - if (image === undefined) return `${message.author.mention}, you need to provide an image to add some magik!`; - const processMessage = await message.channel.createMessage(`${process.env.PROCESSING_EMOJI || ""} Processing... This might take a while`); - const { buffer, type } = await magick.run({ - cmd: "magik", - path: image.path, - type: image.type - }); - if (processMessage.channel.messages.get(processMessage.id)) await processMessage.delete(); - return { - file: buffer, - name: `magik.${type}` - }; -}; - -exports.aliases = ["imagemagic", "imagemagick", "imagemagik", "magic", "magick", "cas", "liquid"]; -exports.category = 5; -exports.help = "Adds a content aware scale effect to an image"; \ No newline at end of file diff --git a/commands/mail.js b/commands/mail.js deleted file mode 100644 index 1751f95..0000000 --- a/commands/mail.js +++ /dev/null @@ -1,10 +0,0 @@ -const soundPlayer = require("../utils/soundplayer.js"); - -exports.run = async (message) => { - return await soundPlayer.play("./assets/audio/mail.ogg", message); -}; - -exports.aliases = ["yougotmail", "youvegotmail", "aol"]; -exports.category = 6; -exports.help = "Plays the \"You've got mail\" sound effect"; -exports.requires = "sound"; \ No newline at end of file diff --git a/commands/mc.js b/commands/mc.js deleted file mode 100644 index f3f1593..0000000 --- a/commands/mc.js +++ /dev/null @@ -1,16 +0,0 @@ -const fetch = require("node-fetch"); - -exports.run = async (message, args) => { - if (args.length === 0) return `${message.author.mention}, you need to provide some text to generate a Minecraft achievement!`; - message.channel.sendTyping(); - const request = await fetch(`https://www.minecraftskinstealer.com/achievement/a.php?i=13&h=Achievement+get%21&t=${encodeURIComponent(args.join("+"))}`); - return { - file: await request.buffer(), - name: "mc.png" - }; -}; - -exports.aliases = ["ach", "achievement", "minecraft"]; -exports.category = 4; -exports.help = "Generates a Minecraft achievement image"; -exports.params = "[text]"; \ No newline at end of file diff --git a/commands/meme.js b/commands/meme.js deleted file mode 100644 index 1d5618c..0000000 --- a/commands/meme.js +++ /dev/null @@ -1,25 +0,0 @@ -const magick = require("../utils/image.js"); - -exports.run = async (message, args) => { - message.channel.sendTyping(); - const image = await require("../utils/imagedetect.js")(message); - if (image === undefined) return `${message.author.mention}, you need to provide an image to generate a meme!`; - const newArgs = args.filter(item => !item.includes(image.url) ); - if (args.length === 0) return `${message.author.mention}, you need to provide some text to generate a meme!`; - const [topText, bottomText] = newArgs.join(" ").split(/(? elem.trim()); - const { buffer, type } = await magick.run({ - cmd: "meme", - path: image.path, - top: topText.toUpperCase().replaceAll("&", "\\&").replaceAll(">", "\\>").replaceAll("<", "\\<").replaceAll("\"", "\\"").replaceAll("'", "\\'").replaceAll("%", "\\%"), - bottom: bottomText ? bottomText.toUpperCase().replaceAll("&", "\\&").replaceAll(">", "\\>").replaceAll("<", "\\<").replaceAll("\"", "\\"").replaceAll("'", "\\'").replaceAll("%", "\\%") : "", - type: image.type - }); - return { - file: buffer, - name: `meme.${type}` - }; -}; - -exports.category = 5; -exports.help = "Generates a meme from an image (separate top/bottom text with a comma)"; -exports.params = "[top text], {bottom text}"; \ No newline at end of file diff --git a/commands/memecenter.js b/commands/memecenter.js deleted file mode 100644 index e4481a7..0000000 --- a/commands/memecenter.js +++ /dev/null @@ -1,23 +0,0 @@ -const magick = require("../utils/image.js"); - -exports.run = async (message) => { - message.channel.sendTyping(); - const image = await require("../utils/imagedetect.js")(message); - if (image === undefined) return `${message.author.mention}, you need to provide an image to add a MemeCenter watermark!`; - const { buffer, type } = await magick.run({ - cmd: "watermark", - path: image.path, - water: "./assets/images/memecenter.png", - gravity: 9, - mc: true, - type: image.type - }); - return { - file: buffer, - name: `memecenter.${type}` - }; -}; - -exports.aliases = ["memec", "mcenter"]; -exports.category = 5; -exports.help = "Adds the MemeCenter watermark to an image"; \ No newline at end of file diff --git a/commands/motivate.js b/commands/motivate.js deleted file mode 100644 index c38d682..0000000 --- a/commands/motivate.js +++ /dev/null @@ -1,26 +0,0 @@ -const magick = require("../utils/image.js"); - -exports.run = async (message, args) => { - const image = await require("../utils/imagedetect.js")(message); - if (image === undefined) return `${message.author.mention}, you need to provide an image/GIF to make a motivational poster!`; - const newArgs = args.filter(item => !item.includes(image.url) ); - if (args.length === 0) return `${message.author.mention}, you need to provide some text to make a motivational poster!`; - const processMessage = await message.channel.createMessage(`${process.env.PROCESSING_EMOJI || ""} Processing... This might take a while`); - const [topText, bottomText] = newArgs.join(" ").split(/(? elem.trim()); - const { buffer, type } = await magick.run({ - cmd: "motivate", - path: image.path, - top: topText.replaceAll("&", "\\&").replaceAll(">", "\\>").replaceAll("<", "\\<").replaceAll("\"", "\\"").replaceAll("'", "\\'").replaceAll("%", "\\%"), - bottom: bottomText ? bottomText.replaceAll("&", "\\&").replaceAll(">", "\\>").replaceAll("<", "\\<").replaceAll("\"", "\\"").replaceAll("'", "\\'").replaceAll("%", "\\%") : "", - type: image.type - }); - if (processMessage.channel.messages.get(processMessage.id)) await processMessage.delete(); - return { - file: buffer, - name: `motivate.${type}` - }; -}; - -exports.aliases = ["motivational", "motiv", "demotiv", "demotivational", "poster", "motivation"]; -exports.category = 5; -exports.help = "Creates a motivational poster"; diff --git a/commands/music/loop.js b/commands/music/loop.js new file mode 100644 index 0000000..aacfea2 --- /dev/null +++ b/commands/music/loop.js @@ -0,0 +1,22 @@ +const soundPlayer = require("../../utils/soundplayer.js"); +const MusicCommand = require("../../classes/musicCommand.js"); + +class LoopCommand extends MusicCommand { + async run() { + if (process.env.NODE_ENV === "production") return "Music commands are coming soon, but they aren't ready yet. Stay tuned to @esmBot_ on Twitter for updates!"; + + if (!this.message.channel.guild) return `${this.message.author.mention}, this command only works in servers!`; + if (!this.message.member.voiceState.channelID) return `${this.message.author.mention}, you need to be in a voice channel first!`; + if (!this.message.channel.guild.members.get(this.client.user.id).voiceState.channelID) return `${this.message.author.mention}, I'm not in a voice channel!`; + if (this.connection.host !== this.message.author.id) return `${this.message.author.mention}, only the current voice session host can loop the music!`; + const object = this.connection; + object.loop = !object.loop; + soundPlayer.players.set(this.message.channel.guild.id, object); + return object.loop ? "🔊 The player is now looping." : "🔊 The player is no longer looping."; + } + + static description = "Loops the music"; + static aliases = ["toggleloop", "repeat"]; +} + +module.exports = LoopCommand; \ No newline at end of file diff --git a/commands/music/nowplaying.js b/commands/music/nowplaying.js new file mode 100644 index 0000000..d9dcb8a --- /dev/null +++ b/commands/music/nowplaying.js @@ -0,0 +1,49 @@ +const fetch = require("node-fetch"); +const day = require("dayjs"); +const duration = require("dayjs/plugin/duration"); +day.extend(duration); +const MusicCommand = require("../../classes/musicCommand.js"); + +class NowPlayingCommand extends MusicCommand { + async run() { + if (process.env.NODE_ENV === "production") return "Music commands are coming soon, but they aren't ready yet. Stay tuned to @esmBot_ on Twitter for updates!"; + + if (!this.message.channel.guild) return `${this.message.author.mention}, this command only works in servers!`; + if (!this.message.member.voiceState.channelID) return `${this.message.author.mention}, you need to be in a voice channel first!`; + if (!this.message.channel.guild.members.get(this.client.user.id).voiceState.channelID) return `${this.message.author.mention}, I'm not in a voice channel!`; + const player = this.connection.player; + if (!player) return `${this.message.author.mention}, I'm not playing anything!`; + const track = await fetch(`http://${player.node.host}:${player.node.port}/decodetrack?track=${encodeURIComponent(player.track)}`, { headers: { Authorization: player.node.password } }).then(res => res.json()); + const parts = Math.floor((player.state.position / track.length) * 10); + return { + "embed": { + "color": 16711680, + "author": { + "name": "Now Playing", + "icon_url": this.client.user.avatarURL + }, + "fields": [{ + "name": "ℹī¸ Title:", + "value": track.title ? track.title : "Unknown" + }, + { + "name": "🎤 Artist:", + "value": track.author ? track.author : "Unknown" + }, + { + "name": "đŸ’Ŧ Channel:", + "value": this.message.channel.guild.channels.get(this.message.member.voiceState.channelID).name + }, + { + "name": `${"â–Ŧ".repeat(parts)}🔘${"â–Ŧ".repeat(10 - parts)}`, + "value": `${day.duration(player.state.position).format("m:ss", { trim: false })}/${track.isStream ? "∞" : day.duration(track.length).format("m:ss", { trim: false })}` + }] + } + }; + } + + static description = "Shows the currently playing song"; + static aliases = ["playing", "np"]; +} + +module.exports = NowPlayingCommand; \ No newline at end of file diff --git a/commands/music/pause.js b/commands/music/pause.js new file mode 100644 index 0000000..81dfbc6 --- /dev/null +++ b/commands/music/pause.js @@ -0,0 +1,20 @@ +const MusicCommand = require("../../classes/musicCommand.js"); + +class PauseCommand extends MusicCommand { + async run() { + if (process.env.NODE_ENV === "production") return "Music commands are coming soon, but they aren't ready yet. Stay tuned to @esmBot_ on Twitter for updates!"; + + if (!this.message.channel.guild) return `${this.message.author.mention}, this command only works in servers!`; + if (!this.message.member.voiceState.channelID) return `${this.message.author.mention}, you need to be in a voice channel first!`; + if (!this.message.channel.guild.members.get(this.client.user.id).voiceState.channelID) return `${this.message.author.mention}, I'm not in a voice channel!`; + if (this.connection.host !== this.message.author.id) return `${this.message.author.mention}, only the current voice session host can pause/resume the music!`; + const player = this.connection.player; + player.pause(!player.paused ? true : false); + return `🔊 The player has been ${!player.paused ? "paused" : "resumed"}.`; + } + + static description = "Pauses/resumes the current song"; + static aliases = ["resume"]; +} + +module.exports = PauseCommand; \ No newline at end of file diff --git a/commands/music/play.js b/commands/music/play.js new file mode 100644 index 0000000..ec70cca --- /dev/null +++ b/commands/music/play.js @@ -0,0 +1,21 @@ +const soundPlayer = require("../../utils/soundplayer.js"); +const MusicCommand = require("../../classes/musicCommand.js"); +const urlRegex = /(?:\w+:)?\/\/(\S+)/; +const searchRegex = /^ytsearch:/; + +class PlayCommand extends MusicCommand { + async run() { + if (process.env.NODE_ENV === "production") return "Music commands are coming soon, but they aren't ready yet. Stay tuned to @esmBot_ on Twitter for updates!"; + + if (!this.args[0]) return `${this.message.author.mention}, you need to provide what you want to play!`; + const query = this.args.join(" ").trim(); + const search = urlRegex.test(query) ? query : (searchRegex.test(query) ? query : `ytsearch:${query}`); + return await soundPlayer.play(this.client, encodeURIComponent(search), this.message, true); + } + + static description = "Plays a song or adds it to the queue"; + static aliases = ["p"]; + static arguments = ["[url]"]; +} + +module.exports = PlayCommand; \ No newline at end of file diff --git a/commands/music/queue.js b/commands/music/queue.js new file mode 100644 index 0000000..a6bb47a --- /dev/null +++ b/commands/music/queue.js @@ -0,0 +1,64 @@ +const soundPlayer = require("../../utils/soundplayer.js"); +const fetch = require("node-fetch"); +const day = require("dayjs"); +const duration = require("dayjs/plugin/duration"); +day.extend(duration); +const paginator = require("../../utils/pagination/pagination.js"); +const MusicCommand = require("../../classes/musicCommand.js"); + +class QueueCommand extends MusicCommand { + async run() { + if (process.env.NODE_ENV === "production") return "Music commands are coming soon, but they aren't ready yet. Stay tuned to @esmBot_ on Twitter for updates!"; + + if (!this.message.channel.guild) return `${this.message.author.mention}, this command only works in servers!`; + if (!this.message.member.voiceState.channelID) return `${this.message.author.mention}, you need to be in a voice channel first!`; + if (!this.message.channel.guild.members.get(this.client.user.id).voiceState.channelID) return `${this.message.author.mention}, I'm not in a voice channel!`; + if (!this.message.channel.permissionsOf(this.client.user.id).has("addReactions")) return `${this.message.author.mention}, I don't have the \`Add Reactions\` permission!`; + if (!this.message.channel.permissionsOf(this.client.user.id).has("embedLinks")) return `${this.message.author.mention}, I don't have the \`Embed Links\` permission!`; + const queue = soundPlayer.queues.get(this.message.channel.guild.id); + const player = this.connection; + const tracks = await fetch(`http://${player.player.node.host}:${player.player.node.port}/decodetracks`, { method: "POST", body: JSON.stringify(queue), headers: { Authorization: player.player.node.password, "Content-Type": "application/json" } }).then(res => res.json()); + const trackList = []; + const firstTrack = tracks.shift(); + for (const [i, track] of tracks.entries()) { + trackList.push(`${i + 1}. ${track.info.author} - **${track.info.title}** (${track.info.isStream ? "∞" : day.duration(track.info.length).format("m:ss", { trim: false })})`); + } + const pageSize = 5; + const embeds = []; + const groups = trackList.map((item, index) => { + return index % pageSize === 0 ? trackList.slice(index, index + pageSize) : null; + }).filter(Boolean); + if (groups.length === 0) groups.push("del"); + for (const [i, value] of groups.entries()) { + embeds.push({ + "embed": { + "author": { + "name": "Queue", + "icon_url": this.client.user.avatarURL + }, + "color": 16711680, + "footer": { + "text": `Page ${i + 1} of ${groups.length}` + }, + "fields": [{ + "name": "đŸŽļ Now Playing", + "value": `${firstTrack.info.author} - **${firstTrack.info.title}** (${firstTrack.info.isStream ? "∞" : day.duration(firstTrack.info.length).format("m:ss", { trim: false })})` + }, { + "name": "🔁 Looping?", + "value": player.loop ? "Yes" : "No" + }, { + "name": "🗒ī¸ Queue", + "value": value !== "del" ? value.join("\n") : "There's nothing in the queue!" + }] + } + }); + } + if (embeds.length === 0) return `${this.message.author.mention}, there's nothing in the queue!`; + return paginator(this.client, this.message, embeds); + } + + static description = "Shows the current queue"; + static aliases = ["q"]; +} + +module.exports = QueueCommand; \ No newline at end of file diff --git a/commands/music/skip.js b/commands/music/skip.js new file mode 100644 index 0000000..4d9e6d0 --- /dev/null +++ b/commands/music/skip.js @@ -0,0 +1,35 @@ +const soundPlayer = require("../../utils/soundplayer.js"); +const MusicCommand = require("../../classes/musicCommand.js"); + +class SkipCommand extends MusicCommand { + async run() { + if (process.env.NODE_ENV === "production") return "Music commands are coming soon, but they aren't ready yet. Stay tuned to @esmBot_ on Twitter for updates!"; + + if (!this.message.channel.guild) return `${this.message.author.mention}, this command only works in servers!`; + if (!this.message.member.voiceState.channelID) return `${this.message.author.mention}, you need to be in a voice channel first!`; + if (!this.message.channel.guild.members.get(this.client.user.id).voiceState.channelID) return `${this.message.author.mention}, I'm not in a voice channel!`; + const player = this.connection; + if (player.host !== this.message.author.id) { + const votes = soundPlayer.skipVotes.has(this.message.channel.guild.id) ? soundPlayer.skipVotes.get(this.message.channel.guild.id) : { count: 0, ids: [] }; + if (votes.ids.includes(this.message.author.id)) return `${this.message.author.mention}, you've already voted to skip!`; + const newObject = { + count: votes.count + 1, + ids: [...votes.ids, this.message.author.id].filter(item => !!item) + }; + if (votes.count + 1 === 3) { + player.player.stop(this.message.channel.guild.id); + soundPlayer.skipVotes.set(this.message.channel.guild.id, { count: 0, ids: [] }); + } else { + soundPlayer.skipVotes.set(this.message.channel.guild.id, newObject); + return `🔊 Voted to skip song (${votes.count + 1}/3 people have voted).`; + } + } else { + player.player.stop(this.message.channel.guild.id); + return; + } + } + + static description = "Skips the current song"; +} + +module.exports = SkipCommand; \ No newline at end of file diff --git a/commands/music/stop.js b/commands/music/stop.js new file mode 100644 index 0000000..b95d27d --- /dev/null +++ b/commands/music/stop.js @@ -0,0 +1,24 @@ +const soundPlayer = require("../../utils/soundplayer.js"); +const MusicCommand = require("../../classes/musicCommand.js"); + +class StopCommand extends MusicCommand { + async run() { + if (process.env.NODE_ENV === "production") return "Music commands are coming soon, but they aren't ready yet. Stay tuned to @esmBot_ on Twitter for updates!"; + + if (!this.message.channel.guild) return `${this.message.author.mention}, this command only works in servers!`; + if (!this.message.member.voiceState.channelID) return `${this.message.author.mention}, you need to be in a voice channel first!`; + if (!this.message.channel.guild.members.get(this.client.user.id).voiceState.channelID) return `${this.message.author.mention}, I'm not in a voice channel!`; + if (this.connection.host !== this.message.author.id) return `${this.message.author.mention}, only the current voice session host can stop the music!`; + soundPlayer.manager.leave(this.message.channel.guild.id); + const connection = this.connection.player; + connection.destroy(); + soundPlayer.players.delete(this.message.channel.guild.id); + soundPlayer.queues.delete(this.message.channel.guild.id); + return "🔊 The current voice channel session has ended."; + } + + static description = "Stops the music"; + static aliases = ["disconnect"]; +} + +module.exports = StopCommand; \ No newline at end of file diff --git a/commands/nowplaying.js b/commands/nowplaying.js deleted file mode 100644 index 11a7b2f..0000000 --- a/commands/nowplaying.js +++ /dev/null @@ -1,11 +0,0 @@ -const soundPlayer = require("../utils/soundplayer.js"); - -exports.run = async (message) => { - if (process.env.NODE_ENV === "production") return "Music commands are coming soon, but they aren't ready yet. Stay tuned to @esmBot_ on Twitter for updates!"; - return await soundPlayer.playing(message); -}; - -exports.aliases = ["playing", "np"]; -exports.category = 7; -exports.help = "Shows the currently playing song"; -exports.requires = "sound"; \ No newline at end of file diff --git a/commands/oof.js b/commands/oof.js deleted file mode 100644 index a6f48e1..0000000 --- a/commands/oof.js +++ /dev/null @@ -1,10 +0,0 @@ -const soundPlayer = require("../utils/soundplayer.js"); - -exports.run = async (message) => { - return await soundPlayer.play("./assets/audio/oof.ogg", message); -}; - -exports.aliases = ["roblox", "commitdie"]; -exports.category = 6; -exports.help = "Plays the Roblox \"oof\" sound"; -exports.requires = "sound"; \ No newline at end of file diff --git a/commands/pause.js b/commands/pause.js deleted file mode 100644 index b749888..0000000 --- a/commands/pause.js +++ /dev/null @@ -1,11 +0,0 @@ -const soundPlayer = require("../utils/soundplayer.js"); - -exports.run = async (message) => { - if (process.env.NODE_ENV === "production") return "Music commands are coming soon, but they aren't ready yet. Stay tuned to @esmBot_ on Twitter for updates!"; - return await soundPlayer.pause(message); -}; - -exports.aliases = ["resume"]; -exports.category = 7; -exports.help = "Pauses/resumes the current song"; -exports.requires = "sound"; \ No newline at end of file diff --git a/commands/ping.js b/commands/ping.js deleted file mode 100644 index 829f14c..0000000 --- a/commands/ping.js +++ /dev/null @@ -1,10 +0,0 @@ -const client = require("../utils/client.js"); - -exports.run = async (message) => { - const pingMessage = await client.createMessage(message.channel.id, "🏓 Ping?"); - return pingMessage.edit(`🏓 Pong!\n\`\`\`\nLatency: ${pingMessage.timestamp - message.timestamp}ms${message.channel.guild ? `\nShard Latency: ${Math.round(client.shards.get(client.guildShardMap[message.channel.guild.id]).latency)}ms` : ""}\n\`\`\``); -}; - -exports.aliases = ["pong"]; -exports.category = 1; -exports.help = "Pings the server I'm hosted on"; \ No newline at end of file diff --git a/commands/pixelate.js b/commands/pixelate.js deleted file mode 100644 index e018e5a..0000000 --- a/commands/pixelate.js +++ /dev/null @@ -1,20 +0,0 @@ -const magick = require("../utils/image.js"); - -exports.run = async (message) => { - message.channel.sendTyping(); - const image = await require("../utils/imagedetect.js")(message); - if (image === undefined) return `${message.author.mention}, you need to provide an image to pixelate!`; - const { buffer, type } = await magick.run({ - cmd: "resize", - path: image.path, - type: image.type - }); - return { - file: buffer, - name: `pixelate.${type}` - }; -}; - -exports.aliases = ["pixel", "small"]; -exports.category = 5; -exports.help = "Pixelates an image"; \ No newline at end of file diff --git a/commands/play.js b/commands/play.js deleted file mode 100644 index cec4364..0000000 --- a/commands/play.js +++ /dev/null @@ -1,17 +0,0 @@ -const soundPlayer = require("../utils/soundplayer.js"); -const urlRegex = /(?:\w+:)?\/\/(\S+)/; -const searchRegex = /^(sc|yt)search:/; - -exports.run = async (message, args) => { - if (process.env.NODE_ENV === "production") return "Music commands are coming soon, but they aren't ready yet. Stay tuned to @esmBot_ on Twitter for updates!"; - if (!args[0]) return `${message.author.mention}, you need to provide what you want to play!`; - const query = args.join(" ").trim(); - const search = urlRegex.test(query) ? query : (searchRegex.test(query) ? query : `ytsearch:${query}`); - return await soundPlayer.play(encodeURIComponent(search), message, true); -}; - -exports.aliases = ["p"]; -exports.category = 7; -exports.help = "Plays a song or adds it to the queue"; -exports.requires = "sound"; -exports.params = "[url]"; \ No newline at end of file diff --git a/commands/prefix.js b/commands/prefix.js deleted file mode 100644 index 84b600d..0000000 --- a/commands/prefix.js +++ /dev/null @@ -1,18 +0,0 @@ -const database = require("../utils/database.js"); - -exports.run = async (message, args) => { - if (!message.channel.guild) return `${message.author.mention}, this command only works in servers!`; - const guild = await database.getGuild(message.channel.guild.id); - if (args.length !== 0) { - if (!message.member.permissions.has("administrator") && message.member.id !== process.env.OWNER) return `${message.author.mention}, you need to be an administrator to change the bot prefix!`; - await database.setPrefix(args[0], message.channel.guild); - return `The prefix has been changed to ${args[0]}.`; - } else { - return `${message.author.mention}, the current prefix is \`${guild.prefix}\`.`; - } -}; - -exports.aliases = ["setprefix", "changeprefix", "checkprefix"]; -exports.category = 1; -exports.help = "Checks/changes the server prefix"; -exports.params = "{prefix}"; \ No newline at end of file diff --git a/commands/qrcreate.js b/commands/qrcreate.js deleted file mode 100644 index 7759ccd..0000000 --- a/commands/qrcreate.js +++ /dev/null @@ -1,33 +0,0 @@ -const qrcode = require("qrcode"); -const stream = require("stream"); - -exports.run = async (message, args, content) => { - if (args.length === 0) return `${message.author.mention}, you need to provide some text to generate a QR code!`; - message.channel.sendTyping(); - const writable = new stream.PassThrough(); - qrcode.toFileStream(writable, content, { margin: 1 }); - const file = await streamToBuf(writable); - return { - file: file, - name: "qr.png" - }; -}; - -function streamToBuf(stream) { - return new Promise((resolve, reject) => { - const chunks = []; - stream.on("data", (chunk) => { - chunks.push(chunk); - }); - stream.once("error", (error) => { - reject(error); - }); - stream.once("end", () => { - resolve(Buffer.concat(chunks)); - }); - }); -} - -exports.category = 1; -exports.help = "Generates a QR code"; -exports.params = "[text]"; \ No newline at end of file diff --git a/commands/qrread.js b/commands/qrread.js deleted file mode 100644 index ce6a70a..0000000 --- a/commands/qrread.js +++ /dev/null @@ -1,18 +0,0 @@ -const jsqr = require("jsqr"); -const fetch = require("node-fetch"); -const sharp = require("sharp"); -const { clean } = require("../utils/misc.js"); - -exports.run = async (message) => { - const image = await require("../utils/imagedetect.js")(message); - if (image === undefined) return `${message.author.mention}, you need to provide an image with a QR code to read!`; - message.channel.sendTyping(); - const data = await (await fetch(image.path)).buffer(); - const rawData = await sharp(data).ensureAlpha().raw().toBuffer({ resolveWithObject: true }); - const qrBuffer = jsqr(rawData.data, rawData.info.width, rawData.info.height); - if (!qrBuffer) return `${message.author.mention}, I couldn't find a QR code!`; - return `\`\`\`\n${await clean(qrBuffer.data)}\n\`\`\``; -}; - -exports.category = 1; -exports.help = "Reads a QR code"; \ No newline at end of file diff --git a/commands/queue.js b/commands/queue.js deleted file mode 100644 index e72bd1a..0000000 --- a/commands/queue.js +++ /dev/null @@ -1,11 +0,0 @@ -const soundPlayer = require("../utils/soundplayer.js"); - -exports.run = async (message) => { - if (process.env.NODE_ENV === "production") return "Music commands are coming soon, but they aren't ready yet. Stay tuned to @esmBot_ on Twitter for updates!"; - return await soundPlayer.queue(message); -}; - -exports.aliases = ["q"]; -exports.category = 7; -exports.help = "Shows the current queue"; -exports.requires = "sound"; \ No newline at end of file diff --git a/commands/reload.js b/commands/reload.js deleted file mode 100644 index e197d42..0000000 --- a/commands/reload.js +++ /dev/null @@ -1,17 +0,0 @@ -const handler = require("../utils/handler.js"); - -exports.run = async (message, args) => { - if (message.author.id !== process.env.OWNER) return `${message.author.mention}, only the bot owner can reload commands!`; - if (args.length === 0) return `${message.author.mention}, you need to provide a command to reload!`; - try { - await handler.unload(args[0]); - await handler.load(args[0]); - return `${message.author.mention}, the command \`${args[0]}\` has been reloaded.`; - } catch (error) { - if (error) throw error; - } -}; - -exports.category = 8; -exports.help = "Reloads a command"; -exports.params = "[command]"; \ No newline at end of file diff --git a/commands/restart.js b/commands/restart.js deleted file mode 100644 index d47b683..0000000 --- a/commands/restart.js +++ /dev/null @@ -1,15 +0,0 @@ -const handler = require("../utils/handler.js"); -const collections = require("../utils/collections.js"); - -exports.run = async (message) => { - if (message.author.id !== process.env.OWNER) return `${message.author.mention}, only the bot owner can restart me!`; - await message.channel.createMessage(`${message.author.mention}, esmBot is restarting.`); - for (const command of collections.commands) { - await handler.unload(command); - } - process.exit(1); -}; - -exports.aliases = ["reboot"]; -exports.category = 8; -exports.help = "Restarts me"; \ No newline at end of file diff --git a/commands/retro.js b/commands/retro.js deleted file mode 100644 index cf9b446..0000000 --- a/commands/retro.js +++ /dev/null @@ -1,35 +0,0 @@ -const magick = require("../utils/image.js"); -const wrap = require("../utils/wrap.js"); - -exports.run = async (message, args) => { - if (args.length === 0) return `${message.author.mention}, you need to provide some text to generate some retro text!`; - message.channel.sendTyping(); - let [line1, line2, line3] = args.join(" ").replaceAll("&", "\\&").replaceAll(">", "\\>").replaceAll("<", "\\<").replaceAll("\"", "\\"").replaceAll("'", "\\'").replaceAll("%", "\\%").split(",").map(elem => elem.trim()); - if (!line2 && line1.length > 15) { - const [split1, split2, split3] = wrap(line1, { width: 15, indent: "" }).split("\n"); - line1 = split1; - line2 = split2 ? split2 : ""; - line3 = split3 ? split3 : ""; - } else { - if (!line2) { - line2 = ""; - } - if (!line3) { - line3 = ""; - } - } - const { buffer } = await magick.run({ - cmd: "retro", - line1, - line2, - line3 - }); - return { - file: buffer, - name: "retro.png" - }; -}; - -exports.category = 4; -exports.help = "Generates a retro text image (separate lines with a comma)"; -exports.params = "[top text], {middle text}, {bottom text}"; \ No newline at end of file diff --git a/commands/reverse.js b/commands/reverse.js deleted file mode 100644 index 6b07c18..0000000 --- a/commands/reverse.js +++ /dev/null @@ -1,23 +0,0 @@ -const magick = require("../utils/image.js"); - -exports.run = async (message) => { - message.channel.sendTyping(); - const image = await require("../utils/imagedetect.js")(message); - if (image === undefined) return `${message.author.mention}, you need to provide a GIF to reverse!`; - const { buffer, type } = await magick.run({ - cmd: "reverse", - path: image.path, - delay: image.delay ? (100 / image.delay.split("/")[0]) * image.delay.split("/")[1] : 0, - onlyGIF: true, - type: image.type - }); - if (type === "nogif") return `${message.author.mention}, that isn't a GIF!`; - return { - file: buffer, - name: `reverse.${type}` - }; -}; - -exports.aliases = ["backwards"]; -exports.category = 5; -exports.help = "Reverses a GIF"; \ No newline at end of file diff --git a/commands/rps.js b/commands/rps.js deleted file mode 100644 index bea6e69..0000000 --- a/commands/rps.js +++ /dev/null @@ -1,30 +0,0 @@ -const misc = require("../utils/misc.js"); - -exports.run = async (message, args) => { - if (args.length === 0 || (args[0] !== "rock" && args[0] !== "paper" && args[0] !== "scissors")) return `${message.author.mention}, you need to choose whether you want to be rock, paper, or scissors!`; - let emoji; - let winOrLose; - const result = misc.random(["rock", "paper", "scissors"]); - switch (result) { - case "rock": - emoji = "✊"; - if (args[0].toLowerCase() === "paper") winOrLose = 1; - break; - case "paper": - emoji = "✋"; - if (args[0].toLowerCase() === "scissors") winOrLose = 1; - break; - case "scissors": - emoji = "✌"; - if (args[0].toLowerCase() === "rock") winOrLose = 1; - break; - default: - break; - } - return args[0].toLowerCase() === result ? `${emoji} I chose ${result}. It's a tie!` : `${emoji} I chose ${result}. ${winOrLose ? "You win!" : "You lose!"}`; -}; - -exports.aliases = ["rockpaperscissors"]; -exports.category = 4; -exports.help = "Plays rock, paper, scissors with me"; -exports.params = "[rock/paper/scissors]"; \ No newline at end of file diff --git a/commands/scott.js b/commands/scott.js deleted file mode 100644 index 610229f..0000000 --- a/commands/scott.js +++ /dev/null @@ -1,20 +0,0 @@ -const magick = require("../utils/image.js"); - -exports.run = async (message) => { - message.channel.sendTyping(); - const image = await require("../utils/imagedetect.js")(message); - if (image === undefined) return `${message.author.mention}, you need to provide an image to make a Scott the Woz TV meme!`; - const { buffer, type } = await magick.run({ - cmd: "scott", - path: image.path, - type: image.type - }); - return { - file: buffer, - name: `scott.${type}` - }; -}; - -exports.aliases = ["woz", "tv", "porn"]; -exports.category = 5; -exports.help = "Creates a Scott the Woz TV image"; \ No newline at end of file diff --git a/commands/screenshot.js b/commands/screenshot.js deleted file mode 100644 index 90df18d..0000000 --- a/commands/screenshot.js +++ /dev/null @@ -1,33 +0,0 @@ -const urlRegex = /(?:\w+:)?\/\/(\S+)/; -const puppeteer = require("puppeteer-extra"); -const StealthPlugin = require("puppeteer-extra-plugin-stealth"); -puppeteer.use(StealthPlugin()); -const fetch = require("node-fetch"); - -exports.run = async (message, args) => { - if (message.author.id !== process.env.OWNER) return `${message.author.mention}, only the bot owner can run this command!`; - message.channel.sendTyping(); - if (args.length === 0) return `${message.author.mention}, you need to provide a URL to screenshot!`; - const getEndpoint = await fetch(`http://${process.env.CHROME}/json/version`); - const endpoint = await getEndpoint.json(); - const url = urlRegex.test(args[0]) ? args[0] : `http://${args[0]}`; - const browser = await puppeteer.connect({ - browserWSEndpoint: endpoint.webSocketDebuggerUrl, - defaultViewport: { - width: 1280, - height: 720 - } - }); - const page = await browser.newPage(); - await page.goto(url); - const screenshot = await page.screenshot(); - await page.close(); - return { - file: screenshot, - name: "screenshot.png" - }; -}; - -exports.aliases = ["webshot", "ss", "shot", "page"]; -exports.category = 8; -exports.help = "Screenshots a webpage"; \ No newline at end of file diff --git a/commands/serverinfo.js b/commands/serverinfo.js deleted file mode 100644 index 6002448..0000000 --- a/commands/serverinfo.js +++ /dev/null @@ -1,48 +0,0 @@ -exports.run = async (message) => { - if (!message.channel.guild) return `${message.author.mention}, this command only works in servers!`; - const owner = await message.channel.guild.members.get(message.channel.guild.ownerID); - const infoEmbed = { - "embed": { - "title": message.channel.guild.name, - "thumbnail": { - "url": message.channel.guild.iconURL - }, - "color": 16711680, - "fields": [ - { - "name": "đŸ”ĸ **ID:**", - "value": message.channel.guild.id - }, - { - "name": "👤 **Owner:**", - "value": `${owner.user.username}#${owner.user.discriminator}` - }, - { - "name": "đŸ—ē **Region:**", - "value": message.channel.guild.region - }, - { - "name": "🗓 **Created on:**", - "value": new Date(message.channel.guild.createdAt).toString() - }, - { - "name": "đŸ‘Ĩ **Users:**", - "value": message.channel.guild.memberCount - }, - { - "name": "đŸ’Ŧ **Channels:**", - "value": message.channel.guild.channels.size - }, - { - "name": "😃 **Emojis:**", - "value": message.channel.guild.emojis.length - } - ] - } - }; - return infoEmbed; -}; - -exports.aliases = ["server"]; -exports.category = 1; -exports.help = "Gets some info about the server"; \ No newline at end of file diff --git a/commands/sharpen.js b/commands/sharpen.js deleted file mode 100644 index 79cc2c2..0000000 --- a/commands/sharpen.js +++ /dev/null @@ -1,22 +0,0 @@ -const magick = require("../utils/image.js"); - -exports.run = async (message) => { - message.channel.sendTyping(); - const image = await require("../utils/imagedetect.js")(message); - if (image === undefined) return `${message.author.mention}, you need to provide an image to sharpen!`; - const { buffer, type } = await magick.run({ - cmd: "blur", - path: image.path, - sharp: true, - type: image.type - }); - return { - file: buffer, - name: `sharpen.${type}` - }; - -}; - -exports.aliases = ["sharp"]; -exports.category = 5; -exports.help = "Sharpens an image"; \ No newline at end of file diff --git a/commands/shorten.js b/commands/shorten.js deleted file mode 100644 index 91f4bf5..0000000 --- a/commands/shorten.js +++ /dev/null @@ -1,14 +0,0 @@ -const urlCheck = require("../utils/urlcheck.js"); -const fetch = require("node-fetch"); - -exports.run = async (message, args) => { - if (args.length === 0 || !urlCheck(args[0])) return `${message.author.mention}, you need to provide a URL to shorten!`; - const data = await fetch(`https://is.gd/create.php?format=simple&url=${encodeURIComponent(args[0])}`); - const url = await data.text(); - return url; -}; - -exports.aliases = ["urlshorten", "shortenlink", "urishorten", "shortenuri", "shortenurl"]; -exports.category = 1; -exports.help = "Shortens a URL"; -exports.params = "[url]"; \ No newline at end of file diff --git a/commands/shutterstock.js b/commands/shutterstock.js deleted file mode 100644 index 346ce38..0000000 --- a/commands/shutterstock.js +++ /dev/null @@ -1,23 +0,0 @@ -const magick = require("../utils/image.js"); - -exports.run = async (message) => { - message.channel.sendTyping(); - const image = await require("../utils/imagedetect.js")(message); - if (image === undefined) return `${message.author.mention}, you need to provide an image to add a Shutterstock watermark!`; - const { buffer, type } = await magick.run({ - cmd: "watermark", - path: image.path, - water: "./assets/images/shutterstock.png", - gravity: 5, - resize: true, - type: image.type - }); - return { - file: buffer, - name: `shutterstock.${type}` - }; -}; - -exports.aliases = ["stock", "stockphoto"]; -exports.category = 5; -exports.help = "Adds the Shutterstock watermark to an image"; \ No newline at end of file diff --git a/commands/skip.js b/commands/skip.js deleted file mode 100644 index 216df08..0000000 --- a/commands/skip.js +++ /dev/null @@ -1,10 +0,0 @@ -const soundPlayer = require("../utils/soundplayer.js"); - -exports.run = async (message) => { - if (process.env.NODE_ENV === "production") return "Music commands are coming soon, but they aren't ready yet. Stay tuned to @esmBot_ on Twitter for updates!"; - return await soundPlayer.skip(message); -}; - -exports.category = 7; -exports.help = "Skips the current song"; -exports.requires = "sound"; \ No newline at end of file diff --git a/commands/slow.js b/commands/slow.js deleted file mode 100644 index 1fa634e..0000000 --- a/commands/slow.js +++ /dev/null @@ -1,23 +0,0 @@ -const magick = require("../utils/image.js"); - -exports.run = async (message) => { - message.channel.sendTyping(); - const image = await require("../utils/imagedetect.js")(message); - if (image === undefined) return `${message.author.mention}, you need to provide a GIF to slow down!`; - const { buffer, type } = await magick.run({ - cmd: "speed", - path: image.path, - slow: true, - onlyGIF: true, - type: image.type - }); - if (type === "nogif") return `${message.author.mention}, that isn't a GIF!`; - return { - file: buffer, - name: `slow.${type}` - }; -}; - -exports.aliases = ["slowdown", "slower", "gifspeed2"]; -exports.category = 5; -exports.help = "Makes a GIF slower"; \ No newline at end of file diff --git a/commands/snowflake.js b/commands/snowflake.js deleted file mode 100644 index 3359c20..0000000 --- a/commands/snowflake.js +++ /dev/null @@ -1,10 +0,0 @@ -exports.run = async (message, args) => { - if (!args[0]) return `${message.author.mention}, you need to provide a snowflake ID!`; - if (!args[0].match(/^?$/) && args[0] < 21154535154122752) return `${message.author.mention}, that's not a valid snowflake!`; - return new Date((args[0].replaceAll("@", "").replaceAll("#", "").replaceAll("!", "").replaceAll("&", "").replaceAll("<", "").replaceAll(">", "") / 4194304) + 1420070400000).toUTCString(); -}; - -exports.aliases = ["timestamp", "snowstamp", "snow"]; -exports.category = 1; -exports.help = "Converts a Discord snowflake id into a timestamp"; -exports.params = "[id]"; \ No newline at end of file diff --git a/commands/sonic.js b/commands/sonic.js deleted file mode 100644 index e392634..0000000 --- a/commands/sonic.js +++ /dev/null @@ -1,20 +0,0 @@ -const magick = require("../utils/image.js"); -const wrap = require("../utils/wrap.js"); - -exports.run = async (message, args) => { - if (args.length === 0) return `${message.author.mention}, you need to provide some text to make a Sonic meme!`; - message.channel.sendTyping(); - const cleanedMessage = args.join(" ").replaceAll("&", "\\&").replaceAll(">", "\\>").replaceAll("<", "\\<").replaceAll("\"", "\\"").replaceAll("'", "\\'").replaceAll("%", "\\%"); - const { buffer } = await magick.run({ - cmd: "sonic", - text: wrap(cleanedMessage, {width: 15, indent: ""}) - }); - return { - file: buffer, - name: "sonic.png" - }; -}; - -exports.category = 4; -exports.help = "Creates a Sonic speech bubble image"; -exports.params = "[text]"; \ No newline at end of file diff --git a/commands/soos.js b/commands/soos.js deleted file mode 100644 index de52a5f..0000000 --- a/commands/soos.js +++ /dev/null @@ -1,24 +0,0 @@ -const magick = require("../utils/image.js"); - -exports.run = async (message) => { - message.channel.sendTyping(); - const image = await require("../utils/imagedetect.js")(message); - if (image === undefined) return `${message.author.mention}, you need to provide a GIF to loop!`; - const { buffer, type } = await magick.run({ - cmd: "reverse", - path: image.path, - soos: true, - delay: image.delay ? (100 / image.delay.split("/")[0]) * image.delay.split("/")[1] : 0, - onlyGIF: true, - type: image.type - }); - if (type === "nogif") return `${message.author.mention}, that isn't a GIF!`; - return { - file: buffer, - name: `soos.${type}` - }; -}; - -exports.aliases = ["bounce"]; -exports.category = 5; -exports.help = "\"Loops\" a GIF by reversing it when it's finished"; \ No newline at end of file diff --git a/commands/soundboard/boi.js b/commands/soundboard/boi.js new file mode 100644 index 0000000..a27c418 --- /dev/null +++ b/commands/soundboard/boi.js @@ -0,0 +1,13 @@ +const soundPlayer = require("../../utils/soundplayer.js"); +const MusicCommand = require("../../classes/musicCommand.js"); + +class BoiCommand extends MusicCommand { + async run() { + return await soundPlayer.play(this.client, "./assets/audio/boi.ogg", this.message); + } + + static description = "Plays the \"boi\" sound effect"; + static aliases = ["boy", "neutron", "hugh"]; +} + +module.exports = BoiCommand; \ No newline at end of file diff --git a/commands/soundboard/boom.js b/commands/soundboard/boom.js new file mode 100644 index 0000000..2c7f0bb --- /dev/null +++ b/commands/soundboard/boom.js @@ -0,0 +1,13 @@ +const soundPlayer = require("../../utils/soundplayer.js"); +const MusicCommand = require("../../classes/musicCommand.js"); + +class BoomCommand extends MusicCommand { + async run() { + return await soundPlayer.play(this.client, "./assets/audio/boom.ogg", this.message); + } + + static description = "Plays the Vine boom sound effect"; + static aliases = ["thud", "vine"]; +} + +module.exports = BoomCommand; \ No newline at end of file diff --git a/commands/soundboard/bruh.js b/commands/soundboard/bruh.js new file mode 100644 index 0000000..c5bab56 --- /dev/null +++ b/commands/soundboard/bruh.js @@ -0,0 +1,13 @@ +const soundPlayer = require("../../utils/soundplayer.js"); +const MusicCommand = require("../../classes/musicCommand.js"); + +class BruhCommand extends MusicCommand { + async run() { + return await soundPlayer.play(this.client, "./assets/audio/bruh.ogg", this.message); + } + + static description = "Plays the \"bruh\" sound effect"; + static aliases = ["bro"]; +} + +module.exports = BruhCommand; \ No newline at end of file diff --git a/commands/soundboard/explosion.js b/commands/soundboard/explosion.js new file mode 100644 index 0000000..d15efd5 --- /dev/null +++ b/commands/soundboard/explosion.js @@ -0,0 +1,12 @@ +const soundPlayer = require("../../utils/soundplayer.js"); +const MusicCommand = require("../../classes/musicCommand.js"); + +class ExplosionCommand extends MusicCommand { + async run() { + return await soundPlayer.play(this.client, "./assets/audio/explosion.ogg", this.message); + } + + static description = "Plays an explosion sound effect"; +} + +module.exports = ExplosionCommand; \ No newline at end of file diff --git a/commands/soundboard/fakeping.js b/commands/soundboard/fakeping.js new file mode 100644 index 0000000..7b22061 --- /dev/null +++ b/commands/soundboard/fakeping.js @@ -0,0 +1,13 @@ +const soundPlayer = require("../../utils/soundplayer.js"); +const MusicCommand = require("../../classes/musicCommand.js"); + +class FakePingCommand extends MusicCommand { + async run() { + return await soundPlayer.play(this.client, "./assets/audio/ping.ogg", this.message); + } + + static description = "Plays a Discord ping sound effect"; + static aliases = ["notification", "notif"]; +} + +module.exports = FakePingCommand; \ No newline at end of file diff --git a/commands/soundboard/fart.js b/commands/soundboard/fart.js new file mode 100644 index 0000000..a0d0fae --- /dev/null +++ b/commands/soundboard/fart.js @@ -0,0 +1,13 @@ +const soundPlayer = require("../../utils/soundplayer.js"); +const MusicCommand = require("../../classes/musicCommand.js"); + +class FartCommand extends MusicCommand { + async run() { + return await soundPlayer.play(this.client, "./assets/audio/fart.ogg", this.message); + } + + static description = "Plays a fart sound effect"; + static aliases = ["toot"]; +} + +module.exports = FartCommand; \ No newline at end of file diff --git a/commands/soundboard/fbi.js b/commands/soundboard/fbi.js new file mode 100644 index 0000000..2a543f8 --- /dev/null +++ b/commands/soundboard/fbi.js @@ -0,0 +1,13 @@ +const soundPlayer = require("../../utils/soundplayer.js"); +const MusicCommand = require("../../classes/musicCommand.js"); + +class FBICommand extends MusicCommand { + async run() { + return await soundPlayer.play(this.client, "./assets/audio/fbi.ogg", this.message); + } + + static description = "Plays the \"FBI OPEN UP\" sound effect"; + static aliases = ["openup"]; +} + +module.exports = FBICommand; \ No newline at end of file diff --git a/commands/soundboard/mail.js b/commands/soundboard/mail.js new file mode 100644 index 0000000..ec58b7d --- /dev/null +++ b/commands/soundboard/mail.js @@ -0,0 +1,13 @@ +const soundPlayer = require("../../utils/soundplayer.js"); +const MusicCommand = require("../../classes/musicCommand.js"); + +class MailCommand extends MusicCommand { + async run() { + return await soundPlayer.play(this.client, "./assets/audio/mail.ogg", this.message); + } + + static description = "Plays the \"You've got mail\" sound effect"; + static aliases = ["yougotmail", "youvegotmail", "aol"]; +} + +module.exports = MailCommand; \ No newline at end of file diff --git a/commands/soundboard/oof.js b/commands/soundboard/oof.js new file mode 100644 index 0000000..92475b8 --- /dev/null +++ b/commands/soundboard/oof.js @@ -0,0 +1,13 @@ +const soundPlayer = require("../../utils/soundplayer.js"); +const MusicCommand = require("../../classes/musicCommand.js"); + +class OofCommand extends MusicCommand { + async run() { + return await soundPlayer.play(this.client, "./assets/audio/oof.ogg", this.message); + } + + static description = "Plays the Roblox \"oof\" sound"; + static aliases = ["roblox", "commitdie"]; +} + +module.exports = OofCommand; \ No newline at end of file diff --git a/commands/soundboard/winxp.js b/commands/soundboard/winxp.js new file mode 100644 index 0000000..9ceb09a --- /dev/null +++ b/commands/soundboard/winxp.js @@ -0,0 +1,13 @@ +const soundPlayer = require("../../utils/soundplayer.js"); +const MusicCommand = require("../../classes/musicCommand.js"); + +class WinXPCommand extends MusicCommand { + async run() { + return await soundPlayer.play(this.client, "./assets/audio/winxp.ogg", this.message); + } + + static description = "Plays the Windows XP startup sound"; + static aliases = ["windows", "xp"]; +} + +module.exports = WinXPCommand; \ No newline at end of file diff --git a/commands/soundreload.js b/commands/soundreload.js deleted file mode 100644 index 12219bb..0000000 --- a/commands/soundreload.js +++ /dev/null @@ -1,16 +0,0 @@ -const soundPlayer = require("../utils/soundplayer.js"); - -exports.run = async (message) => { - if (message.author.id !== process.env.OWNER) return `${message.author.mention}, only the bot owner can reload Lavalink!`; - const soundStatus = await soundPlayer.checkStatus(); - if (!soundStatus) { - const length = await soundPlayer.connect(); - return `Successfully connected to ${length} Lavalink node(s).`; - } else { - return `${message.author.mention}, I couldn't connect to any Lavalink nodes!`; - } -}; - -exports.aliases = ["lava", "lavalink", "lavaconnect", "soundconnect"]; -exports.category = 8; -exports.help = "Attempts to reconnect to all available Lavalink nodes"; \ No newline at end of file diff --git a/commands/speed.js b/commands/speed.js deleted file mode 100644 index c885d4f..0000000 --- a/commands/speed.js +++ /dev/null @@ -1,22 +0,0 @@ -const magick = require("../utils/image.js"); - -exports.run = async (message) => { - message.channel.sendTyping(); - const image = await require("../utils/imagedetect.js")(message); - if (image === undefined) return `${message.author.mention}, you need to provide a GIF to speed up!`; - const { buffer, type } = await magick.run({ - cmd: "speed", - path: image.path, - onlyGIF: true, - type: image.type - }); - if (type === "nogif") return `${message.author.mention}, that isn't a GIF!`; - return { - file: buffer, - name: `speed.${type}` - }; -}; - -exports.aliases = ["speedup", "fast", "gifspeed"]; -exports.category = 5; -exports.help = "Makes a GIF faster"; \ No newline at end of file diff --git a/commands/spin.js b/commands/spin.js deleted file mode 100644 index c25ee31..0000000 --- a/commands/spin.js +++ /dev/null @@ -1,21 +0,0 @@ -const magick = require("../utils/image.js"); - -exports.run = async (message) => { - const image = await require("../utils/imagedetect.js")(message); - if (image === undefined) return `${message.author.mention}, you need to provide an image to spin!`; - const processMessage = await message.channel.createMessage(`${process.env.PROCESSING_EMOJI || ""} Processing... This might take a while`); - const { buffer } = await magick.run({ - cmd: "spin", - path: image.path, - type: image.type - }); - if (processMessage.channel.messages.get(processMessage.id)) await processMessage.delete(); - return { - file: buffer, - name: "spin.gif" - }; -}; - -exports.aliases = ["rotate"]; -exports.category = 5; -exports.help = "Spins an image"; \ No newline at end of file diff --git a/commands/stats.js b/commands/stats.js deleted file mode 100644 index 3e366fe..0000000 --- a/commands/stats.js +++ /dev/null @@ -1,49 +0,0 @@ -const client = require("../utils/client.js"); -const { version } = require("../package.json"); -const moment = require("moment"); -require("moment-duration-format"); -const os = require("os"); - -exports.run = async () => { - const duration = moment.duration(client.uptime).format(" D [days], H [hrs], m [mins], s [secs]"); - const embed = { - embed: { - "author": { - "name": "esmBot Statistics", - "icon_url": client.user.avatarURL - }, - "color": 16711680, - "description": process.env.NODE_ENV === "development" ? "**You are currently using esmBot Dev! Things may change at any time without warning and there will be bugs. Many bugs.**" : "", - "fields": [{ - "name": "Version", - "value": `v${version}${process.env.NODE_ENV === "development" ? "-dev" : ""}` - }, - { - "name": "Memory Usage", - "value": `${(process.memoryUsage().heapUsed / 1024 / 1024).toFixed(2)} MB` - }, - { - "name": "Uptime", - "value": duration - }, - { - "name": "Host", - "value": `${os.type()} ${os.release()} (${os.arch()})` - }, - { - "name": "Library", - "value": `Eris ${require("eris").VERSION}` - }, - { - "name": "Node.js Version", - "value": process.version - } - ] - } - }; - return embed; -}; - -exports.aliases = ["status", "stat"]; -exports.category = 1; -exports.help = "Gets some statistics about me"; \ No newline at end of file diff --git a/commands/stop.js b/commands/stop.js deleted file mode 100644 index 49228b1..0000000 --- a/commands/stop.js +++ /dev/null @@ -1,11 +0,0 @@ -const soundPlayer = require("../utils/soundplayer.js"); - -exports.run = async (message) => { - if (process.env.NODE_ENV === "production") return "Music commands are coming soon, but they aren't ready yet. Stay tuned to @esmBot_ on Twitter for updates!"; - return await soundPlayer.stop(message); -}; - -exports.aliases = ["disconnect"]; -exports.category = 7; -exports.help = "Stops the music"; -exports.requires = "sound"; \ No newline at end of file diff --git a/commands/stretch.js b/commands/stretch.js deleted file mode 100644 index b59112f..0000000 --- a/commands/stretch.js +++ /dev/null @@ -1,21 +0,0 @@ -const magick = require("../utils/image.js"); - -exports.run = async (message) => { - message.channel.sendTyping(); - const image = await require("../utils/imagedetect.js")(message); - if (image === undefined) return `${message.author.mention}, you need to provide an image to stretch!`; - const { buffer, type } = await magick.run({ - cmd: "resize", - path: image.path, - stretch: true, - type: image.type - }); - return { - file: buffer, - name: `stretch.${type}` - }; -}; - -exports.aliases = ["aspect", "ratio", "aspect43", "43"]; -exports.category = 5; -exports.help = "Stretches an image to 4:3 aspect ratio"; \ No newline at end of file diff --git a/commands/swirl.js b/commands/swirl.js deleted file mode 100644 index 88d2e5b..0000000 --- a/commands/swirl.js +++ /dev/null @@ -1,20 +0,0 @@ -const magick = require("../utils/image.js"); - -exports.run = async (message) => { - message.channel.sendTyping(); - const image = await require("../utils/imagedetect.js")(message); - if (image === undefined) return `${message.author.mention}, you need to provide an image to swirl!`; - const { buffer, type } = await magick.run({ - cmd: "swirl", - path: image.path, - type: image.type - }); - return { - file: buffer, - name: `swirl.${type}` - }; -}; - -exports.aliases = ["whirlpool"]; -exports.category = 5; -exports.help = "Swirls an image"; \ No newline at end of file diff --git a/commands/tags.js b/commands/tags.js deleted file mode 100644 index 6c9edce..0000000 --- a/commands/tags.js +++ /dev/null @@ -1,112 +0,0 @@ -const database = require("../utils/database.js"); -const client = require("../utils/client.js"); -const paginator = require("../utils/pagination/pagination.js"); -const { random } = require("../utils/misc.js"); - -exports.run = async (message, args) => { - if (!message.channel.guild) return `${message.author.mention}, this command only works in servers!`; - const guild = await database.getGuild(message.channel.guild.id); - - if ((guild.tagsDisabled || guild.tags_disabled) && args[0].toLowerCase() !== ("enable" || "disable")) return; - if (args.length === 0) return `${message.author.mention}, you need to specify the name of the tag you want to view!`; - const tags = guild.tags instanceof Map ? Object.fromEntries(guild.tags) : guild.tags; - const blacklist = ["add", "edit", "remove", "delete", "list", "random", "own", "owner", "enable", "disable"]; - switch (args[0].toLowerCase()) { - case "add": - if (args[1] === undefined) return `${message.author.mention}, you need to provide the name of the tag you want to add!`; - if (blacklist.includes(args[1].toLowerCase())) return `${message.author.mention}, you can't make a tag with that name!`; - if (tags[args[1].toLowerCase()]) return `${message.author.mention}, this tag already exists!`; - var result = await setTag(args.slice(2).join(" "), args[1].toLowerCase(), message, guild); - if (result) return result; - return `${message.author.mention}, the tag \`${args[1].toLowerCase()}\` has been added!`; - case "delete": - case "remove": - if (args[1] === undefined) return `${message.author.mention}, you need to provide the name of the tag you want to delete!`; - if (!tags[args[1].toLowerCase()]) return `${message.author.mention}, this tag doesn't exist!`; - if (tags[args[1].toLowerCase()].author !== message.author.id && !message.member.permissions.has("manageMessages") && message.author.id !== process.env.OWNER) return `${message.author.mention}, you don't own this tag!`; - await database.removeTag(args[1].toLowerCase(), message.channel.guild); - return `${message.author.mention}, the tag \`${args[1].toLowerCase()}\` has been deleted!`; - case "edit": - if (args[1] === undefined) return `${message.author.mention}, you need to provide the name of the tag you want to edit!`; - if (!tags[args[1].toLowerCase()]) return `${message.author.mention}, this tag doesn't exist!`; - if (tags[args[1].toLowerCase()].author !== message.author.id && !message.member.permissions.has("manageMessages") && message.author.id !== process.env.OWNER) return `${message.author.mention}, you don't own this tag!`; - await setTag(args.slice(2).join(" "), args[1].toLowerCase(), message, guild); - return `${message.author.mention}, the tag \`${args[1].toLowerCase()}\` has been edited!`; - case "own": - case "owner": - if (args[1] === undefined) return `${message.author.mention}, you need to provide the name of the tag you want to check the owner of!`; - if (!tags[args[1].toLowerCase()]) return `${message.author.mention}, this tag doesn't exist!`; - return `${message.author.mention}, this tag is owned by **${client.users.get(tags[args[1].toLowerCase()].author).username}#${client.users.get(tags[args[1].toLowerCase()].author).discriminator}** (\`${tags[args[1].toLowerCase()].author}\`).`; - case "list": - if (!message.channel.guild.members.get(client.user.id).permissions.has("addReactions") && !message.channel.permissionsOf(client.user.id).has("addReactions")) return `${message.author.mention}, I don't have the \`Add Reactions\` permission!`; - if (!message.channel.guild.members.get(client.user.id).permissions.has("embedLinks") && !message.channel.permissionsOf(client.user.id).has("embedLinks")) return `${message.author.mention}, I don't have the \`Embed Links\` permission!`; - var pageSize = 15; - var embeds = []; - var groups = Object.keys(tags).map((item, index) => { - return index % pageSize === 0 ? Object.keys(tags).slice(index, index + pageSize) : null; - }).filter((item) => { - return item; - }); - for (const [i, value] of groups.entries()) { - embeds.push({ - "embed": { - "title": "Tag List", - "color": 16711680, - "footer": { - "text": `Page ${i + 1} of ${groups.length}` - }, - "description": value.join("\n"), - "fields": process.env.NODE_ENV === "development" ? [{"name": "Note", "value": "Tags created in this version of esmBot will not carry over to the final release."}] : null, - "author": { - "name": message.author.username, - "icon_url": message.author.avatarURL - } - } - }); - } - if (embeds.length === 0) return `${message.author.mention}, I couldn't find any tags!`; - return paginator(message, embeds); - case "random": - return tags[random(Object.keys(tags))].content; - case "enable": - case "disable": - if (!message.member.permissions.has("manageMessages") && message.author.id !== process.env.OWNER) return `${message.author.mention}, you don't have permission to disable tags!`; - var toggleResult = await database.toggleTags(message.channel.guild); - return `${message.author.mention}, tags for this guild have been ${toggleResult ? "disabled" : "enabled"}. To ${toggleResult ? "enable" : "disable"} them again, run ${guild.prefix}tags ${toggleResult ? "enable" : "disable"}.`; - default: - if (!tags[args[0].toLowerCase()]) return `${message.author.mention}, this tag doesn't exist!`; - return tags[args[0].toLowerCase()].content; - } -}; - -const setTag = async (content, name, message) => { - if ((!content || content.length === 0) && message.attachments.length === 0) return `${message.author.mention}, you need to provide the content of the tag!`; - if (message.attachments.length !== 0 && content) { - await database.setTag(name, { content: `${content} ${message.attachments[0].url}`, author: message.author.id }, message.channel.guild); - } else if (message.attachments.length !== 0) { - await database.setTag(name, { content: message.attachments[0].url, author: message.author.id }, message.channel.guild); - } else { - await database.setTag(name, { content: content, author: message.author.id }, message.channel.guild); - } - return; -}; - -exports.aliases = ["t", "tag", "ta"]; -exports.category = 3; -exports.help = { - default: "Gets a tag", - add: "Adds a tag", - delete: "Deletes a tag", - edit: "Edits a tag", - list: "Lists all tags in the server", - random: "Gets a random tag", - owner: "Gets the owner of a tag", - disable: "Disables/Enables the tag system" -}; -exports.params = { - default: "[name]", - add: "[name] [content]", - delete: "[name]", - edit: "[name] [content]", - owner: "[name]" -}; \ No newline at end of file diff --git a/commands/tags/tags.js b/commands/tags/tags.js new file mode 100644 index 0000000..eac7709 --- /dev/null +++ b/commands/tags/tags.js @@ -0,0 +1,116 @@ +const database = require("../../utils/database.js"); +const paginator = require("../../utils/pagination/pagination.js"); +const { random } = require("../../utils/misc.js"); +const Command = require("../../classes/command.js"); + +class TagsCommand extends Command { + // todo: find a way to split this into subcommands + async run() { + if (!this.message.channel.guild) return `${this.message.author.mention}, this command only works in servers!`; + const guild = await database.getGuild(this.message.channel.guild.id); + + if ((guild.tagsDisabled || guild.tags_disabled) && this.args[0].toLowerCase() !== ("enable" || "disable")) return; + if (this.args.length === 0) return `${this.message.author.mention}, you need to specify the name of the tag you want to view!`; + const tags = guild.tags instanceof Map ? Object.fromEntries(guild.tags) : guild.tags; + const blacklist = ["add", "edit", "remove", "delete", "list", "random", "own", "owner", "enable", "disable"]; + switch (this.args[0].toLowerCase()) { + case "add": + if (this.args[1] === undefined) return `${this.message.author.mention}, you need to provide the name of the tag you want to add!`; + if (blacklist.includes(this.args[1].toLowerCase())) return `${this.message.author.mention}, you can't make a tag with that name!`; + if (tags[this.args[1].toLowerCase()]) return `${this.message.author.mention}, this tag already exists!`; + var result = await this.setTag(this.args.slice(2).join(" "), this.args[1].toLowerCase(), this.message, guild); + if (result) return result; + return `${this.message.author.mention}, the tag \`${this.args[1].toLowerCase()}\` has been added!`; + case "delete": + case "remove": + if (this.args[1] === undefined) return `${this.message.author.mention}, you need to provide the name of the tag you want to delete!`; + if (!tags[this.args[1].toLowerCase()]) return `${this.message.author.mention}, this tag doesn't exist!`; + if (tags[this.args[1].toLowerCase()].author !== this.message.author.id && !this.message.member.permissions.has("manageMessages") && this.message.author.id !== process.env.OWNER) return `${this.message.author.mention}, you don't own this tag!`; + await database.removeTag(this.args[1].toLowerCase(), this.message.channel.guild); + return `${this.message.author.mention}, the tag \`${this.args[1].toLowerCase()}\` has been deleted!`; + case "edit": + if (this.args[1] === undefined) return `${this.message.author.mention}, you need to provide the name of the tag you want to edit!`; + if (!tags[this.args[1].toLowerCase()]) return `${this.message.author.mention}, this tag doesn't exist!`; + if (tags[this.args[1].toLowerCase()].author !== this.message.author.id && !this.message.member.permissions.has("manageMessages") && this.message.author.id !== process.env.OWNER) return `${this.message.author.mention}, you don't own this tag!`; + await this.setTag(this.args.slice(2).join(" "), this.args[1].toLowerCase(), this.message, guild); + return `${this.message.author.mention}, the tag \`${this.args[1].toLowerCase()}\` has been edited!`; + case "own": + case "owner": + if (this.args[1] === undefined) return `${this.message.author.mention}, you need to provide the name of the tag you want to check the owner of!`; + if (!tags[this.args[1].toLowerCase()]) return `${this.message.author.mention}, this tag doesn't exist!`; + return `${this.message.author.mention}, this tag is owned by **${this.client.users.get(tags[this.args[1].toLowerCase()].author).username}#${this.client.users.get(tags[this.args[1].toLowerCase()].author).discriminator}** (\`${tags[this.args[1].toLowerCase()].author}\`).`; + case "list": + if (!this.message.channel.permissionsOf(this.client.user.id).has("addReactions")) return `${this.message.author.mention}, I don't have the \`Add Reactions\` permission!`; + if (!this.message.channel.permissionsOf(this.client.user.id).has("embedLinks")) return `${this.message.author.mention}, I don't have the \`Embed Links\` permission!`; + var pageSize = 15; + var embeds = []; + var groups = Object.keys(tags).map((item, index) => { + return index % pageSize === 0 ? Object.keys(tags).slice(index, index + pageSize) : null; + }).filter((item) => { + return item; + }); + for (const [i, value] of groups.entries()) { + embeds.push({ + "embed": { + "title": "Tag List", + "color": 16711680, + "footer": { + "text": `Page ${i + 1} of ${groups.length}` + }, + "description": value.join("\n"), + "fields": process.env.NODE_ENV === "development" ? [{"name": "Note", "value": "Tags created in this version of esmBot will not carry over to the final release."}] : null, + "author": { + "name": this.message.author.username, + "icon_url": this.message.author.avatarURL + } + } + }); + } + if (embeds.length === 0) return `${this.message.author.mention}, I couldn't find any tags!`; + return paginator(this.client, this.message, embeds); + case "random": + return tags[random(Object.keys(tags))].content; + case "enable": + case "disable": + if (!this.message.member.permissions.has("manageMessages") && this.message.author.id !== process.env.OWNER) return `${this.message.author.mention}, you don't have permission to disable tags!`; + var toggleResult = await database.toggleTags(this.message.channel.guild); + return `${this.message.author.mention}, tags for this guild have been ${toggleResult ? "disabled" : "enabled"}. To ${toggleResult ? "enable" : "disable"} them again, run ${guild.prefix}tags ${toggleResult ? "enable" : "disable"}.`; + default: + if (!tags[this.args[0].toLowerCase()]) return `${this.message.author.mention}, this tag doesn't exist!`; + return tags[this.args[0].toLowerCase()].content; + } + } + + async setTag(content, name, message) { + if ((!content || content.length === 0) && message.attachments.length === 0) return `${message.author.mention}, you need to provide the content of the tag!`; + if (message.attachments.length !== 0 && content) { + await database.setTag(name, { content: `${content} ${message.attachments[0].url}`, author: message.author.id }, message.channel.guild); + } else if (message.attachments.length !== 0) { + await database.setTag(name, { content: message.attachments[0].url, author: message.author.id }, message.channel.guild); + } else { + await database.setTag(name, { content: content, author: message.author.id }, message.channel.guild); + } + return; + } + + static description = { + default: "Gets a tag", + add: "Adds a tag", + delete: "Deletes a tag", + edit: "Edits a tag", + list: "Lists all tags in the server", + random: "Gets a random tag", + owner: "Gets the owner of a tag", + disable: "Disables/Enables the tag system" + }; + static aliases = ["t", "tag", "ta"]; + static arguments = { + default: ["[name]"], + add: ["[name]", "[content]"], + delete: ["[name]"], + edit: ["[name]", "[content]"], + owner: ["[name]"] + }; +} + +module.exports = TagsCommand; \ No newline at end of file diff --git a/commands/tile.js b/commands/tile.js deleted file mode 100644 index 8435c6f..0000000 --- a/commands/tile.js +++ /dev/null @@ -1,20 +0,0 @@ -const magick = require("../utils/image.js"); - -exports.run = async (message) => { - message.channel.sendTyping(); - const image = await require("../utils/imagedetect.js")(message); - if (image === undefined) return `${message.author.mention}, you need to provide an image to tile!`; - const { buffer, type } = await magick.run({ - cmd: "tile", - path: image.path, - type: image.type - }); - return { - file: buffer, - name: `tile.${type}` - }; -}; - -exports.aliases = ["wall2"]; -exports.category = 5; -exports.help = "Creates a tile pattern from an image"; \ No newline at end of file diff --git a/commands/trump.js b/commands/trump.js deleted file mode 100644 index b08c261..0000000 --- a/commands/trump.js +++ /dev/null @@ -1,19 +0,0 @@ -const magick = require("../utils/image.js"); - -exports.run = async (message) => { - message.channel.sendTyping(); - const image = await require("../utils/imagedetect.js")(message); - if (image === undefined) return `${message.author.mention}, you need to provide an image to make a Trump meme!`; - const { buffer, type } = await magick.run({ - cmd: "trump", - path: image.path, - type: image.type - }); - return { - file: buffer, - name: `trump.${type}` - }; -}; - -exports.category = 5; -exports.help = "Makes Trump display an image"; \ No newline at end of file diff --git a/commands/unfreeze.js b/commands/unfreeze.js deleted file mode 100644 index 85f870e..0000000 --- a/commands/unfreeze.js +++ /dev/null @@ -1,22 +0,0 @@ -const magick = require("../utils/image.js"); - -exports.run = async (message) => { - message.channel.sendTyping(); - const image = await require("../utils/imagedetect.js")(message); - if (image === undefined) return `${message.author.mention}, you need to provide a GIF to unfreeze!`; - const { buffer, type } = await magick.run({ - cmd: "freeze", - path: image.path, - loop: true, - onlyGIF: true, - type: image.type - }); - if (type === "nogif") return `${message.author.mention}, that isn't a GIF!`; - return { - file: buffer, - name: `unfreeze.${type}` - }; -}; - -exports.category = 5; -exports.help = "Unfreezes a GIF"; \ No newline at end of file diff --git a/commands/userinfo.js b/commands/userinfo.js deleted file mode 100644 index 7ab8faf..0000000 --- a/commands/userinfo.js +++ /dev/null @@ -1,56 +0,0 @@ -const client = require("../utils/client.js"); - -exports.run = async (message, args) => { - const getUser = message.mentions.length >= 1 ? message.mentions[0] : (args.length !== 0 ? client.users.get(args[0]) : message.author); - let user; - if (getUser) { - user = getUser; - } else if (args.join(" ") !== "") { - const userRegex = new RegExp(args.join("|"), "i"); - const member = client.users.find(element => { - return userRegex.test(element.username); - }); - user = member ? member : message.author; - } else { - user = message.author; - } - //const user = getUser !== undefined ? getUser : (message.author); - const member = message.channel.guild ? message.channel.guild.members.get(user.id) : undefined; - const infoEmbed = { - "embed": { - "title": `${user.username}#${user.discriminator}`, - "thumbnail": { - "url": user.avatarURL - }, - "color": 16711680, - "fields": [ - { - "name": "đŸ”ĸ **ID:**", - "value": user.id - }, - { - "name": "📛 **Nickname:**", - "value": member ? (member.nick ? member.nick : "None") : "N/A" - }, - { - "name": "🤖 **Bot:**", - "value": user.bot ? "Yes" : "No" - }, - { - "name": "🗓ī¸ **Joined Discord on:**", - "value": new Date(user.createdAt).toString() - }, - { - "name": "đŸ’Ŧ **Joined this server on:**", - "value": member ? new Date(member.joinedAt).toString() : "N/A" - } - ] - } - }; - return infoEmbed; -}; - -exports.aliases = ["user"]; -exports.category = 1; -exports.help = "Gets info about a user"; -exports.params = "{mention/id}"; \ No newline at end of file diff --git a/commands/waaw.js b/commands/waaw.js deleted file mode 100644 index cb50cd8..0000000 --- a/commands/waaw.js +++ /dev/null @@ -1,20 +0,0 @@ -const magick = require("../utils/image.js"); - -exports.run = async (message) => { - message.channel.sendTyping(); - const image = await require("../utils/imagedetect.js")(message); - if (image === undefined) return `${message.author.mention}, you need to provide an image to mirror!`; - const { buffer, type } = await magick.run({ - cmd: "mirror", - path: image.path, - type: image.type - }); - return { - file: buffer, - name: `waaw.${type}` - }; -}; - -exports.aliases = ["magik3", "mirror"]; -exports.category = 5; -exports.help = "Mirrors the right side of an image onto the left"; \ No newline at end of file diff --git a/commands/wall.js b/commands/wall.js deleted file mode 100644 index c18da21..0000000 --- a/commands/wall.js +++ /dev/null @@ -1,19 +0,0 @@ -const magick = require("../utils/image.js"); - -exports.run = async (message) => { - message.channel.sendTyping(); - const image = await require("../utils/imagedetect.js")(message); - if (image === undefined) return `${message.author.mention}, you need to provide an image to make a wall from!`; - const { buffer, type } = await magick.run({ - cmd: "wall", - path: image.path, - type: image.type - }); - return { - file: buffer, - name: `wall.${type}` - }; -}; - -exports.category = 5; -exports.help = "Creates a wall from an image"; \ No newline at end of file diff --git a/commands/wdt.js b/commands/wdt.js deleted file mode 100644 index a9fa50c..0000000 --- a/commands/wdt.js +++ /dev/null @@ -1,20 +0,0 @@ -const magick = require("../utils/image.js"); - -exports.run = async (message) => { - message.channel.sendTyping(); - const image = await require("../utils/imagedetect.js")(message); - if (image === undefined) return `${message.author.mention}, you need to provide an image to make a "who did this" meme!`; - const { buffer, type } = await magick.run({ - cmd: "wdt", - path: image.path, - type: image.type - }); - return { - file: buffer, - name: `wdt.${type}` - }; -}; - -exports.aliases = ["whodidthis"]; -exports.category = 5; -exports.help = "Creates a \"WHO DID THIS\" meme from an image"; \ No newline at end of file diff --git a/commands/wide.js b/commands/wide.js deleted file mode 100644 index 649b418..0000000 --- a/commands/wide.js +++ /dev/null @@ -1,21 +0,0 @@ -const magick = require("../utils/image.js"); - -exports.run = async (message) => { - message.channel.sendTyping(); - const image = await require("../utils/imagedetect.js")(message); - if (image === undefined) return `${message.author.mention}, you need to provide an image to stretch!`; - const { buffer, type } = await magick.run({ - cmd: "resize", - path: image.path, - wide: true, - type: image.type - }); - return { - file: buffer, - name: `wide.${type}` - }; -}; - -exports.aliases = ["w19", "wide19"]; -exports.category = 5; -exports.help = "Stretches an image to 19x its width"; \ No newline at end of file diff --git a/commands/wikihow.js b/commands/wikihow.js deleted file mode 100644 index 2993d8f..0000000 --- a/commands/wikihow.js +++ /dev/null @@ -1,24 +0,0 @@ -const fetch = require("node-fetch"); - -exports.run = async (message) => { - message.channel.sendTyping(); - const request = await fetch("https://hargrimm-wikihow-v1.p.rapidapi.com/images?count=1", { - headers: { - "X-RapidAPI-Key": process.env.MASHAPE, - "X-RapidAPI-Host": "hargrimm-wikihow-v1.p.rapidapi.com", - "Accept": "application/json" - } - }); - const json = await request.json(); - const image = await fetch(json["1"]); - const imageBuffer = await image.buffer(); - return { - file: imageBuffer, - name: json["1"].split("/")[json["1"].split("/").length - 1] - }; -}; - -exports.aliases = ["wiki"]; -exports.category = 4; -exports.help = "Gets a random WikiHow image"; -exports.requires = "mashape"; \ No newline at end of file diff --git a/commands/winxp.js b/commands/winxp.js deleted file mode 100644 index fdf9b1b..0000000 --- a/commands/winxp.js +++ /dev/null @@ -1,10 +0,0 @@ -const soundPlayer = require("../utils/soundplayer.js"); - -exports.run = async (message) => { - return await soundPlayer.play("./assets/audio/winxp.ogg", message); -}; - -exports.aliases = ["windows", "xp"]; -exports.category = 6; -exports.help = "Plays the Windows XP startup sound"; -exports.requires = "sound"; \ No newline at end of file diff --git a/commands/woow.js b/commands/woow.js deleted file mode 100644 index e752c3d..0000000 --- a/commands/woow.js +++ /dev/null @@ -1,22 +0,0 @@ -const magick = require("../utils/image.js"); - -exports.run = async (message) => { - message.channel.sendTyping(); - const image = await require("../utils/imagedetect.js")(message); - if (image === undefined) return `${message.author.mention}, you need to provide an image to mirror!`; - const { buffer, type } = await magick.run({ - cmd: "mirror", - path: image.path, - vertical: true, - first: true, - type: image.type - }); - return { - file: buffer, - name: `woow.${type}` - }; -}; - -exports.aliases = ["magik5", "mirror3"]; -exports.category = 5; -exports.help = "Mirrors the top of an image onto the bottom"; \ No newline at end of file diff --git a/commands/xkcd.js b/commands/xkcd.js deleted file mode 100644 index 65ccdd0..0000000 --- a/commands/xkcd.js +++ /dev/null @@ -1,27 +0,0 @@ -const fetch = require("node-fetch"); - -exports.run = async (message, args) => { - const url = args.length > 0 && args[0].match(/^\d+$/) ? `http://xkcd.com/${args[0]}/info.0.json` : "http://xkcd.com/info.0.json"; - try { - const request = await fetch(url); - const json = await request.json(); - const embed = { - "embed": { - "title": json.safe_title, - "url": `https://xkcd.com/${json.num}`, - "color": 16711680, - "description": json.alt, - "image": { - "url": json.img - } - } - }; - return embed; - } catch (e) { - return `${message.author.mention}, I couldn't get that XKCD!`; - } -}; - -exports.category = 4; -exports.help = "Gets an XKCD comic"; -exports.params = "{id}"; \ No newline at end of file diff --git a/commands/youtube.js b/commands/youtube.js deleted file mode 100644 index 0699d92..0000000 --- a/commands/youtube.js +++ /dev/null @@ -1,28 +0,0 @@ -const fetch = require("node-fetch"); -const { decodeEntities } = require("../utils/misc.js"); -const paginator = require("../utils/pagination/pagination.js"); - -exports.run = async (message, args) => { - if (args.length === 0) return `${message.author.mention}, you need to provide something to search for!`; - message.channel.sendTyping(); - const messages = []; - const request = await fetch(`https://www.googleapis.com/youtube/v3/search?part=snippet&q=${encodeURIComponent(args.join(" "))}&key=${process.env.GOOGLE}&maxResults=50`); - const result = await request.json(); - if (result.error && result.error.code === 403) return `${message.author.mention}, I've exceeded my YouTube API search quota for the day. Check back later.`; - for (const [i, value] of result.items.entries()) { - if (value.id.kind === "youtube#channel") { - messages.push(`Page ${i + 1} of ${result.items.length}\n<:youtube:637020823005167626> **${decodeEntities(value.snippet.title).replaceAll("*", "\\*")}**\nhttps://youtube.com/channel/${value.id.channelId}`); - } else if (value.id.kind === "youtube#playlist") { - messages.push(`Page ${i + 1} of ${result.items.length}\n<:youtube:637020823005167626> **${decodeEntities(value.snippet.title).replaceAll("*", "\\*")}**\nCreated by **${decodeEntities(value.snippet.channelTitle).replaceAll("*", "\\*")}**\nhttps://youtube.com/playlist?list=${value.id.playlistId}`); - } else { - messages.push(`Page ${i + 1} of ${result.items.length}\n<:youtube:637020823005167626> **${decodeEntities(value.snippet.title).replaceAll("*", "\\*")}**\nUploaded by **${decodeEntities(value.snippet.channelTitle).replaceAll("*", "\\*")}** on **${value.snippet.publishedAt.split("T")[0]}**\nhttps://youtube.com/watch?v=${value.id.videoId}`); - } - } - return paginator(message, messages); -}; - -exports.aliases = ["yt", "video", "ytsearch"]; -exports.category = 1; -exports.help = "Searches YouTube"; -exports.requires = "google"; -exports.params = "[query]"; \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml index 712a446..4f20d65 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -9,8 +9,8 @@ services: restart: unless-stopped volumes: - ./logs:/home/esmBot/.internal/logs - - bot-help:/home/esmBot/help - - bot-temp:/home/esmBot/temp + - ./bot-help:/home/esmBot/help + - ./bot-temp:/home/esmBot/temp env_file: - .env environment: diff --git a/events/error.js b/events/error.js index ab72b6a..29ef08a 100644 --- a/events/error.js +++ b/events/error.js @@ -1,6 +1,6 @@ const logger = require("../utils/logger.js"); // run when eris encounters an error -module.exports = async (error, id) => { +module.exports = async (client, error, id) => { logger.error(`An error event was sent by Eris in shard ${id}: \n${error.message}`); }; diff --git a/events/guildCreate.js b/events/guildCreate.js index 8e1b0b1..97726e9 100644 --- a/events/guildCreate.js +++ b/events/guildCreate.js @@ -2,7 +2,7 @@ const db = require("../utils/database.js"); const logger = require("../utils/logger.js"); // run when the bot is added to a guild -module.exports = async (guild) => { +module.exports = async (client, guild) => { logger.log("info", `[GUILD JOIN] ${guild.name} (${guild.id}) added the bot.`); await db.addGuild(guild); }; diff --git a/events/guildDelete.js b/events/guildDelete.js index 828e7f9..e83fe26 100644 --- a/events/guildDelete.js +++ b/events/guildDelete.js @@ -1,6 +1,6 @@ const logger = require("../utils/logger.js"); // run when the bot is removed from a guild -module.exports = async (guild) => { +module.exports = async (client, guild) => { logger.log(`[GUILD LEAVE] ${guild.name} (${guild.id}) removed the bot.`); }; diff --git a/events/messageCreate.js b/events/messageCreate.js index 835b556..49b47e7 100644 --- a/events/messageCreate.js +++ b/events/messageCreate.js @@ -1,12 +1,11 @@ const fs = require("fs"); -const client = require("../utils/client.js"); const database = require("../utils/database.js"); const logger = require("../utils/logger.js"); const collections = require("../utils/collections.js"); const commands = [...collections.aliases.keys(), ...collections.commands.keys()]; // run when someone sends a message -module.exports = async (message) => { +module.exports = async (client, message) => { // ignore dms and other bots if (message.author.bot) return; @@ -82,11 +81,12 @@ module.exports = async (message) => { if (!cmd) return; // actually run the command - logger.log("info", `${message.author.username} (${message.author.id}) ran command ${command}`); + logger.log("log", `${message.author.username} (${message.author.id}) ran command ${command}`); try { await database.addCount(collections.aliases.has(command) ? collections.aliases.get(command) : command); const startTime = new Date(); - const result = await cmd(message, args, rawContent.replace(command, "").trim()); // we also provide the message content as a parameter for cases where we need more accuracy + const commandClass = new cmd(client, message, args, message.content.substring(prefix.length).trim().replace(command, "").trim()); + const result = await commandClass.run(); // we also provide the message content as a parameter for cases where we need more accuracy const endTime = new Date(); if (typeof result === "string" || (typeof result === "object" && result.embed)) { await client.createMessage(message.channel.id, result); diff --git a/events/rawWS.js b/events/rawWS.js index a910de8..2738f18 100644 --- a/events/rawWS.js +++ b/events/rawWS.js @@ -1,7 +1,7 @@ const player = require("../utils/soundplayer.js"); // run when a raw packet is sent, used for sending data to lavalink -module.exports = async (packet) => { +module.exports = async (client, packet) => { if (!player.manager) return; switch (packet.t) { case "VOICE_SERVER_UPDATE": diff --git a/events/ready.js b/events/ready.js deleted file mode 100644 index 1904871..0000000 --- a/events/ready.js +++ /dev/null @@ -1,31 +0,0 @@ -const client = require("../utils/client.js"); -const database = require("../utils/database.js"); -const logger = require("../utils/logger.js"); -const messages = require("../messages.json"); -const misc = require("../utils/misc.js"); -const soundPlayer = require("../utils/soundplayer.js"); -const helpGenerator = - process.env.OUTPUT !== "" ? require("../utils/help.js") : null; -const first = process.env.PMTWO === "true" ? process.env.NODE_APP_INSTANCE === "0" : true; - -// run when ready -module.exports = async () => { - // connect to lavalink - if (!soundPlayer.status && !soundPlayer.connected) await soundPlayer.connect(); - - await database.setup(); - - // generate docs - if (helpGenerator && first) await helpGenerator(process.env.OUTPUT); - - // set activity (a.k.a. the gamer code) - (async function activityChanger() { - client.editStatus("dnd", { - name: `${misc.random(messages)} | @${client.user.username} help`, - }); - setTimeout(activityChanger, 900000); - })(); - - if (process.env.PMTWO === "true") process.send("ready"); - logger.log(`Successfully started ${client.user.username}#${client.user.discriminator} with ${client.users.size} users in ${client.guilds.size} servers.`); -}; diff --git a/events/voiceChannelLeave.js b/events/voiceChannelLeave.js index efd46e4..cd49675 100644 --- a/events/voiceChannelLeave.js +++ b/events/voiceChannelLeave.js @@ -1,9 +1,8 @@ const soundPlayer = require("../utils/soundplayer.js"); -const client = require("../utils/client.js"); const AwaitRejoin = require("../utils/awaitrejoin.js"); const { random } = require("../utils/misc.js"); -module.exports = async (member, oldChannel) => { +module.exports = async (client, member, oldChannel) => { const connection = soundPlayer.players.get(oldChannel.guild.id); if (connection && oldChannel.id === connection.voiceChannel.id) { if (oldChannel.voiceMembers.filter((i) => i.id !== client.user.id).length === 0) { diff --git a/events/voiceChannelSwitch.js b/events/voiceChannelSwitch.js index 6dd9561..76997b1 100644 --- a/events/voiceChannelSwitch.js +++ b/events/voiceChannelSwitch.js @@ -1,5 +1,5 @@ const leaveHandler = require("./voiceChannelLeave.js"); -module.exports = async (member, newChannel, oldChannel) => { +module.exports = async (client, member, newChannel, oldChannel) => { await leaveHandler(member, oldChannel); }; \ No newline at end of file diff --git a/events/warn.js b/events/warn.js index 6884d2c..0f0fa8f 100644 --- a/events/warn.js +++ b/events/warn.js @@ -1,6 +1,6 @@ const logger = require("../utils/logger.js"); // run when eris encounters a warning -module.exports = async (warn, id) => { +module.exports = async (client, warn, id) => { logger.warn(`A warn event was sent by Eris in shard ${id}: \n${warn.toString()}`); }; diff --git a/messages.json b/messages.json index f30a805..574a7b5 100644 --- a/messages.json +++ b/messages.json @@ -125,5 +125,6 @@ "KFC", "Cave Story", "YouTube ads", - "there are federal agents outside my house" + "there are federal agents outside my house", + "less goo" ] \ No newline at end of file diff --git a/natives/blur.cc b/natives/blur.cc index 679eeb7..5158a51 100644 --- a/natives/blur.cc +++ b/natives/blur.cc @@ -39,7 +39,7 @@ class BlurWorker : public Napi::AsyncWorker { } void OnOK() { - Callback().Call({Env().Undefined(), Napi::Buffer::Copy(Env(), (char *)blob.data(), blob.length())}); + Callback().Call({Env().Undefined(), Napi::Buffer::Copy(Env(), (char *)blob.data(), blob.length()), Napi::String::From(Env(), type)}); } private: diff --git a/natives/blurple.cc b/natives/blurple.cc index 8e85b17..c737a4a 100644 --- a/natives/blurple.cc +++ b/natives/blurple.cc @@ -40,7 +40,7 @@ class BlurpleWorker : public Napi::AsyncWorker { } void OnOK() { - Callback().Call({Env().Undefined(), Napi::Buffer::Copy(Env(), (char *)blob.data(), blob.length())}); + Callback().Call({Env().Undefined(), Napi::Buffer::Copy(Env(), (char *)blob.data(), blob.length()), Napi::String::From(Env(), type)}); } private: diff --git a/natives/caption.cc b/natives/caption.cc index efd9307..60654ee 100644 --- a/natives/caption.cc +++ b/natives/caption.cc @@ -59,7 +59,7 @@ class CaptionWorker : public Napi::AsyncWorker { } void OnOK() { - Callback().Call({Env().Undefined(), Napi::Buffer::Copy(Env(), (char *)blob.data(), blob.length())}); + Callback().Call({Env().Undefined(), Napi::Buffer::Copy(Env(), (char *)blob.data(), blob.length()), Napi::String::From(Env(), type)}); } private: diff --git a/natives/caption2.cc b/natives/caption2.cc index 9eb0a2f..c089cc4 100644 --- a/natives/caption2.cc +++ b/natives/caption2.cc @@ -55,7 +55,7 @@ class CaptionTwoWorker : public Napi::AsyncWorker { } void OnOK() { - Callback().Call({Env().Undefined(), Napi::Buffer::Copy(Env(), (char *)blob.data(), blob.length())}); + Callback().Call({Env().Undefined(), Napi::Buffer::Copy(Env(), (char *)blob.data(), blob.length()), Napi::String::From(Env(), type)}); } private: diff --git a/natives/circle.cc b/natives/circle.cc index af097f3..7e1cf3d 100644 --- a/natives/circle.cc +++ b/natives/circle.cc @@ -38,7 +38,7 @@ class CircleWorker : public Napi::AsyncWorker { } void OnOK() { - Callback().Call({Env().Undefined(), Napi::Buffer::Copy(Env(), (char *)blob.data(), blob.length())}); + Callback().Call({Env().Undefined(), Napi::Buffer::Copy(Env(), (char *)blob.data(), blob.length()), Napi::String::From(Env(), type)}); } private: diff --git a/natives/crop.cc b/natives/crop.cc index b721daa..2df3539 100644 --- a/natives/crop.cc +++ b/natives/crop.cc @@ -39,7 +39,7 @@ class CropWorker : public Napi::AsyncWorker { } void OnOK() { - Callback().Call({Env().Undefined(), Napi::Buffer::Copy(Env(), (char *)blob.data(), blob.length())}); + Callback().Call({Env().Undefined(), Napi::Buffer::Copy(Env(), (char *)blob.data(), blob.length()), Napi::String::From(Env(), type)}); } private: diff --git a/natives/explode.cc b/natives/explode.cc index 1a56793..cf2f6cd 100644 --- a/natives/explode.cc +++ b/natives/explode.cc @@ -38,7 +38,7 @@ class ExplodeWorker : public Napi::AsyncWorker { } void OnOK() { - Callback().Call({Env().Undefined(), Napi::Buffer::Copy(Env(), (char *)blob.data(), blob.length())}); + Callback().Call({Env().Undefined(), Napi::Buffer::Copy(Env(), (char *)blob.data(), blob.length()), Napi::String::From(Env(), type)}); } private: diff --git a/natives/flag.cc b/natives/flag.cc index e47cc77..59fc225 100644 --- a/natives/flag.cc +++ b/natives/flag.cc @@ -44,7 +44,7 @@ class FlagWorker : public Napi::AsyncWorker { } void OnOK() { - Callback().Call({Env().Undefined(), Napi::Buffer::Copy(Env(), (char *)blob.data(), blob.length())}); + Callback().Call({Env().Undefined(), Napi::Buffer::Copy(Env(), (char *)blob.data(), blob.length()), Napi::String::From(Env(), type)}); } private: diff --git a/natives/flip.cc b/natives/flip.cc index 1d7da9c..54fea85 100644 --- a/natives/flip.cc +++ b/natives/flip.cc @@ -38,7 +38,7 @@ class FlipWorker : public Napi::AsyncWorker { } void OnOK() { - Callback().Call({Env().Undefined(), Napi::Buffer::Copy(Env(), (char *)blob.data(), blob.length())}); + Callback().Call({Env().Undefined(), Napi::Buffer::Copy(Env(), (char *)blob.data(), blob.length()), Napi::String::From(Env(), type)}); } private: diff --git a/natives/freeze.cc b/natives/freeze.cc index dc55fc2..0b7fd9b 100644 --- a/natives/freeze.cc +++ b/natives/freeze.cc @@ -23,7 +23,7 @@ class FreezeWorker : public Napi::AsyncWorker { } void OnOK() { - Callback().Call({Env().Undefined(), Napi::Buffer::Copy(Env(), (char *)blob.data(), blob.length())}); + Callback().Call({Env().Undefined(), Napi::Buffer::Copy(Env(), (char *)blob.data(), blob.length()), Napi::String::From(Env(), type)}); } private: diff --git a/natives/gamexplain.cc b/natives/gamexplain.cc index 23f340f..5d6ae2a 100644 --- a/natives/gamexplain.cc +++ b/natives/gamexplain.cc @@ -43,7 +43,7 @@ class GamexplainWorker : public Napi::AsyncWorker { } void OnOK() { - Callback().Call({Env().Undefined(), Napi::Buffer::Copy(Env(), (char *)blob.data(), blob.length())}); + Callback().Call({Env().Undefined(), Napi::Buffer::Copy(Env(), (char *)blob.data(), blob.length()), Napi::String::From(Env(), type)}); } private: diff --git a/natives/globe.cc b/natives/globe.cc index d65b10d..9e14a75 100644 --- a/natives/globe.cc +++ b/natives/globe.cc @@ -58,7 +58,7 @@ class GlobeWorker : public Napi::AsyncWorker { } void OnOK() { - Callback().Call({Env().Undefined(), Napi::Buffer::Copy(Env(), (char *)blob.data(), blob.length())}); + Callback().Call({Env().Undefined(), Napi::Buffer::Copy(Env(), (char *)blob.data(), blob.length()), Napi::String::From(Env(), "gif")}); } private: diff --git a/natives/homebrew.cc b/natives/homebrew.cc index 8cab303..ef87a37 100644 --- a/natives/homebrew.cc +++ b/natives/homebrew.cc @@ -25,7 +25,7 @@ class HomebrewWorker : public Napi::AsyncWorker { } void OnOK() { - Callback().Call({Env().Undefined(), Napi::Buffer::Copy(Env(), (char *)blob.data(), blob.length())}); + Callback().Call({Env().Undefined(), Napi::Buffer::Copy(Env(), (char *)blob.data(), blob.length()), Napi::String::From(Env(), "png")}); } private: diff --git a/natives/invert.cc b/natives/invert.cc index 9ece3bf..a33346f 100644 --- a/natives/invert.cc +++ b/natives/invert.cc @@ -40,7 +40,7 @@ class InvertWorker : public Napi::AsyncWorker { } void OnOK() { - Callback().Call({Env().Undefined(), Napi::Buffer::Copy(Env(), (char *)blob.data(), blob.length())}); + Callback().Call({Env().Undefined(), Napi::Buffer::Copy(Env(), (char *)blob.data(), blob.length()), Napi::String::From(Env(), type)}); } private: diff --git a/natives/jpeg.cc b/natives/jpeg.cc index 1c74d87..b10031d 100644 --- a/natives/jpeg.cc +++ b/natives/jpeg.cc @@ -20,7 +20,7 @@ class JpegWorker : public Napi::AsyncWorker { } void OnOK() { - Callback().Call({Env().Undefined(), Napi::Buffer::Copy(Env(), (char *)blob.data(), blob.length())}); + Callback().Call({Env().Undefined(), Napi::Buffer::Copy(Env(), (char *)blob.data(), blob.length()), Napi::String::From(Env(), "jpg")}); } private: diff --git a/natives/leak.cc b/natives/leak.cc index a2c528a..145e345 100644 --- a/natives/leak.cc +++ b/natives/leak.cc @@ -44,7 +44,7 @@ class LeakWorker : public Napi::AsyncWorker { } void OnOK() { - Callback().Call({Env().Undefined(), Napi::Buffer::Copy(Env(), (char *)blob.data(), blob.length())}); + Callback().Call({Env().Undefined(), Napi::Buffer::Copy(Env(), (char *)blob.data(), blob.length()), Napi::String::From(Env(), type)}); } private: diff --git a/natives/magik.cc b/natives/magik.cc index f2c3e33..068bdbf 100644 --- a/natives/magik.cc +++ b/natives/magik.cc @@ -40,7 +40,7 @@ class MagikWorker : public Napi::AsyncWorker { } void OnOK() { - Callback().Call({Env().Undefined(), Napi::Buffer::Copy(Env(), (char *)blob.data(), blob.length())}); + Callback().Call({Env().Undefined(), Napi::Buffer::Copy(Env(), (char *)blob.data(), blob.length()), Napi::String::From(Env(), type)}); } private: diff --git a/natives/meme.cc b/natives/meme.cc index 6c4b92b..cb7aac6 100644 --- a/natives/meme.cc +++ b/natives/meme.cc @@ -70,7 +70,7 @@ class MemeWorker : public Napi::AsyncWorker { } void OnOK() { - Callback().Call({Env().Undefined(), Napi::Buffer::Copy(Env(), (char *)blob.data(), blob.length())}); + Callback().Call({Env().Undefined(), Napi::Buffer::Copy(Env(), (char *)blob.data(), blob.length()), Napi::String::From(Env(), type)}); } private: diff --git a/natives/mirror.cc b/natives/mirror.cc index 9744abc..b360f43 100644 --- a/natives/mirror.cc +++ b/natives/mirror.cc @@ -65,7 +65,7 @@ class MirrorWorker : public Napi::AsyncWorker { } void OnOK() { - Callback().Call({Env().Undefined(), Napi::Buffer::Copy(Env(), (char *)blob.data(), blob.length())}); + Callback().Call({Env().Undefined(), Napi::Buffer::Copy(Env(), (char *)blob.data(), blob.length()), Napi::String::From(Env(), type)}); } private: diff --git a/natives/misc.cc b/natives/misc.cc index 5d47fb2..e688da3 100644 --- a/natives/misc.cc +++ b/natives/misc.cc @@ -38,7 +38,7 @@ class SwirlWorker : public Napi::AsyncWorker { } void OnOK() { - Callback().Call({Env().Undefined(), Napi::Buffer::Copy(Env(), (char *)blob.data(), blob.length())}); + Callback().Call({Env().Undefined(), Napi::Buffer::Copy(Env(), (char *)blob.data(), blob.length()), Napi::String::From(Env(), type)}); } private: diff --git a/natives/motivate.cc b/natives/motivate.cc index d0d7ce3..fb5cc6f 100644 --- a/natives/motivate.cc +++ b/natives/motivate.cc @@ -72,7 +72,7 @@ class MotivateWorker : public Napi::AsyncWorker { } void OnOK() { - Callback().Call({Env().Undefined(), Napi::Buffer::Copy(Env(), (char *)blob.data(), blob.length())}); + Callback().Call({Env().Undefined(), Napi::Buffer::Copy(Env(), (char *)blob.data(), blob.length()), Napi::String::From(Env(), type)}); } private: diff --git a/natives/resize.cc b/natives/resize.cc index 7f3f70c..6086a48 100644 --- a/natives/resize.cc +++ b/natives/resize.cc @@ -45,7 +45,7 @@ class ResizeWorker : public Napi::AsyncWorker { } void OnOK() { - Callback().Call({Env().Undefined(), Napi::Buffer::Copy(Env(), (char *)blob.data(), blob.length())}); + Callback().Call({Env().Undefined(), Napi::Buffer::Copy(Env(), (char *)blob.data(), blob.length()), Napi::String::From(Env(), type)}); } private: diff --git a/natives/retro.cc b/natives/retro.cc index 64060e4..de1b1db 100644 --- a/natives/retro.cc +++ b/natives/retro.cc @@ -70,12 +70,11 @@ class RetroWorker : public Napi::AsyncWorker { } void OnOK() { - Callback().Call({Env().Undefined(), Napi::Buffer::Copy(Env(), (char *)blob.data(), blob.length())}); + Callback().Call({Env().Undefined(), Napi::Buffer::Copy(Env(), (char *)blob.data(), blob.length()), Napi::String::From(Env(), "png")}); } private: - string line1, line2, line3, type; - int delay; + string line1, line2, line3; Blob blob; }; diff --git a/natives/reverse.cc b/natives/reverse.cc index 1dca18b..9cac1f0 100644 --- a/natives/reverse.cc +++ b/natives/reverse.cc @@ -29,24 +29,22 @@ class ReverseWorker : public Napi::AsyncWorker { optimizeTransparency(coalesced.begin(), coalesced.end()); - if (type == "gif") { - for (Image &image : coalesced) { - image.quantizeDither(false); - image.quantize(); - if (delay != 0) image.animationDelay(delay); - } + for (Image &image : coalesced) { + image.quantizeDither(false); + image.quantize(); + if (delay != 0) image.animationDelay(delay); } writeImages(coalesced.begin(), coalesced.end(), &blob); } void OnOK() { - Callback().Call({Env().Undefined(), Napi::Buffer::Copy(Env(), (char *)blob.data(), blob.length())}); + Callback().Call({Env().Undefined(), Napi::Buffer::Copy(Env(), (char *)blob.data(), blob.length()), Napi::String::From(Env(), "gif")}); } private: - string in_path, type; - int delay, amount; + string in_path; + int delay; Blob blob; bool soos; }; diff --git a/natives/scott.cc b/natives/scott.cc index 2ee2e3b..91fdfa5 100644 --- a/natives/scott.cc +++ b/natives/scott.cc @@ -47,7 +47,7 @@ class ScottWorker : public Napi::AsyncWorker { } void OnOK() { - Callback().Call({Env().Undefined(), Napi::Buffer::Copy(Env(), (char *)blob.data(), blob.length())}); + Callback().Call({Env().Undefined(), Napi::Buffer::Copy(Env(), (char *)blob.data(), blob.length()), Napi::String::From(Env(), type)}); } private: diff --git a/natives/sonic.cc b/natives/sonic.cc index 85787ba..5646cc4 100644 --- a/natives/sonic.cc +++ b/natives/sonic.cc @@ -28,12 +28,11 @@ class SonicWorker : public Napi::AsyncWorker { } void OnOK() { - Callback().Call({Env().Undefined(), Napi::Buffer::Copy(Env(), (char *)blob.data(), blob.length())}); + Callback().Call({Env().Undefined(), Napi::Buffer::Copy(Env(), (char *)blob.data(), blob.length()), Napi::String::From(Env(), "png")}); } private: - string text, type; - int delay; + string text; Blob blob; }; diff --git a/natives/speed.cc b/natives/speed.cc index 1ef4028..9077f88 100644 --- a/natives/speed.cc +++ b/natives/speed.cc @@ -43,14 +43,14 @@ class SpeedWorker : public Napi::AsyncWorker { } void OnOK() { - Callback().Call({Env().Undefined(), Napi::Buffer::Copy(Env(), (char *)blob.data(), blob.length())}); + Callback().Call({Env().Undefined(), Napi::Buffer::Copy(Env(), (char *)blob.data(), blob.length()), Napi::String::From(Env(), type)}); } private: + bool slow; string in_path, type; int delay, amount; Blob blob; - bool slow; }; Napi::Value Speed(const Napi::CallbackInfo &info) diff --git a/natives/spin.cc b/natives/spin.cc index 03bad09..ff707c1 100644 --- a/natives/spin.cc +++ b/natives/spin.cc @@ -55,7 +55,7 @@ class SpinWorker : public Napi::AsyncWorker { } void OnOK() { - Callback().Call({Env().Undefined(), Napi::Buffer::Copy(Env(), (char *)blob.data(), blob.length())}); + Callback().Call({Env().Undefined(), Napi::Buffer::Copy(Env(), (char *)blob.data(), blob.length()), Napi::String::From(Env(), "gif")}); } private: diff --git a/natives/tile.cc b/natives/tile.cc index 6eac5c7..0d61da3 100644 --- a/natives/tile.cc +++ b/natives/tile.cc @@ -52,7 +52,7 @@ class TileWorker : public Napi::AsyncWorker { } void OnOK() { - Callback().Call({Env().Undefined(), Napi::Buffer::Copy(Env(), (char *)blob.data(), blob.length())}); + Callback().Call({Env().Undefined(), Napi::Buffer::Copy(Env(), (char *)blob.data(), blob.length()), Napi::String::From(Env(), type)}); } private: diff --git a/natives/trump.cc b/natives/trump.cc index c8878ca..ea9a853 100644 --- a/natives/trump.cc +++ b/natives/trump.cc @@ -47,7 +47,7 @@ class TrumpWorker : public Napi::AsyncWorker { } void OnOK() { - Callback().Call({Env().Undefined(), Napi::Buffer::Copy(Env(), (char *)blob.data(), blob.length())}); + Callback().Call({Env().Undefined(), Napi::Buffer::Copy(Env(), (char *)blob.data(), blob.length()), Napi::String::From(Env(), type)}); } private: diff --git a/natives/wall.cc b/natives/wall.cc index 2aedeae..7dc6964 100644 --- a/natives/wall.cc +++ b/natives/wall.cc @@ -45,7 +45,7 @@ class WallWorker : public Napi::AsyncWorker { } void OnOK() { - Callback().Call({Env().Undefined(), Napi::Buffer::Copy(Env(), (char *)blob.data(), blob.length())}); + Callback().Call({Env().Undefined(), Napi::Buffer::Copy(Env(), (char *)blob.data(), blob.length()), Napi::String::From(Env(), type)}); } private: diff --git a/natives/watermark.cc b/natives/watermark.cc index c7b2c29..42451c4 100644 --- a/natives/watermark.cc +++ b/natives/watermark.cc @@ -63,7 +63,7 @@ class WatermarkWorker : public Napi::AsyncWorker { } void OnOK() { - Callback().Call({Env().Undefined(), Napi::Buffer::Copy(Env(), (char *)blob.data(), blob.length())}); + Callback().Call({Env().Undefined(), Napi::Buffer::Copy(Env(), (char *)blob.data(), blob.length()), Napi::String::From(Env(), type)}); } private: diff --git a/natives/wdt.cc b/natives/wdt.cc index 47922ea..6e2a8d1 100644 --- a/natives/wdt.cc +++ b/natives/wdt.cc @@ -42,7 +42,7 @@ class WdtWorker : public Napi::AsyncWorker { } void OnOK() { - Callback().Call({Env().Undefined(), Napi::Buffer::Copy(Env(), (char *)blob.data(), blob.length())}); + Callback().Call({Env().Undefined(), Napi::Buffer::Copy(Env(), (char *)blob.data(), blob.length()), Napi::String::From(Env(), type)}); } private: diff --git a/package-lock.json b/package-lock.json index 8073a1f..b528d93 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,31 +9,28 @@ "version": "1.4.6", "license": "MIT", "dependencies": { - "abort-controller": "^3.0.0", "cowsay2": "^2.0.4", + "dayjs": "^1.10.4", "dotenv": "^8.2.0", "duckduckgo-images-api": "^1.0.5", "emoji-regex": "^9.2.2", - "eris": "github:abalabahaha/eris#dev", + "eris": "^0.15.0", + "eris-sharder": "^1.10.0", "file-type": "^16.1.0", "jsqr": "^1.3.1", "lavacord": "^1.1.9", - "moment": "^2.29.1", - "moment-duration-format": "^2.3.2", "node-addon-api": "^3.1.0", "node-emoji": "^1.10.0", "node-fetch": "^2.6.1", - "puppeteer": "^5.5.0", - "puppeteer-extra": "^3.1.15", - "puppeteer-extra-plugin-stealth": "^2.6.5", "qrcode": "^1.4.4", "sharp": "^0.26.3", - "topgg-autoposter": "^1.1.9", - "winston": "^3.3.3" + "topgg-autoposter": "^1.1.9" }, "devDependencies": { - "eslint": "^5.15.2", - "eslint-plugin-promise": "^4.2.1" + "@babel/eslint-parser": "^7.13.8", + "@babel/eslint-plugin": "^7.13.0", + "@babel/plugin-proposal-class-properties": "^7.13.0", + "eslint": "^7.23.0" }, "engines": { "node": ">=15" @@ -56,12 +53,277 @@ "@babel/highlight": "^7.12.13" } }, + "node_modules/@babel/compat-data": { + "version": "7.13.12", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.13.12.tgz", + "integrity": "sha512-3eJJ841uKxeV8dcN/2yGEUy+RfgQspPEgQat85umsE1rotuquQ2AbIub4S6j7c50a2d+4myc+zSlnXeIHrOnhQ==", + "dev": true, + "peer": true + }, + "node_modules/@babel/core": { + "version": "7.13.14", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.13.14.tgz", + "integrity": "sha512-wZso/vyF4ki0l0znlgM4inxbdrUvCb+cVz8grxDq+6C9k6qbqoIJteQOKicaKjCipU3ISV+XedCqpL2RJJVehA==", + "dev": true, + "peer": true, + "dependencies": { + "@babel/code-frame": "^7.12.13", + "@babel/generator": "^7.13.9", + "@babel/helper-compilation-targets": "^7.13.13", + "@babel/helper-module-transforms": "^7.13.14", + "@babel/helpers": "^7.13.10", + "@babel/parser": "^7.13.13", + "@babel/template": "^7.12.13", + "@babel/traverse": "^7.13.13", + "@babel/types": "^7.13.14", + "convert-source-map": "^1.7.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.1.2", + "semver": "^6.3.0", + "source-map": "^0.5.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@babel/core/node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true, + "peer": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/eslint-parser": { + "version": "7.13.14", + "resolved": "https://registry.npmjs.org/@babel/eslint-parser/-/eslint-parser-7.13.14.tgz", + "integrity": "sha512-I0HweR36D73Ibn/FfrRDMKlMqJHFwidIUgYdMpH+aXYuQC+waq59YaJ6t9e9N36axJ82v1jR041wwqDrDXEwRA==", + "dev": true, + "dependencies": { + "eslint-scope": "^5.1.0", + "eslint-visitor-keys": "^1.3.0", + "semver": "^6.3.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || >=14.0.0" + }, + "peerDependencies": { + "@babel/core": ">=7.11.0", + "eslint": ">=7.5.0" + } + }, + "node_modules/@babel/eslint-parser/node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/eslint-plugin": { + "version": "7.13.10", + "resolved": "https://registry.npmjs.org/@babel/eslint-plugin/-/eslint-plugin-7.13.10.tgz", + "integrity": "sha512-xsNxo099fKnJ2rArkuuMOTPxxTLZSXwbFXdH4GjqQRKTOr6S1odQlE+R3Leid56VFQ3KVAR295vVNG9fqNQVvQ==", + "dev": true, + "dependencies": { + "eslint-rule-composer": "^0.3.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || >=14.0.0" + }, + "peerDependencies": { + "@babel/eslint-parser": ">=7.11.0", + "eslint": ">=7.5.0" + } + }, + "node_modules/@babel/generator": { + "version": "7.13.9", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.13.9.tgz", + "integrity": "sha512-mHOOmY0Axl/JCTkxTU6Lf5sWOg/v8nUa+Xkt4zMTftX0wqmb6Sh7J8gvcehBw7q0AhrhAR+FDacKjCZ2X8K+Sw==", + "dev": true, + "dependencies": { + "@babel/types": "^7.13.0", + "jsesc": "^2.5.1", + "source-map": "^0.5.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.13.13", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.13.13.tgz", + "integrity": "sha512-q1kcdHNZehBwD9jYPh3WyXcsFERi39X4I59I3NadciWtNDyZ6x+GboOxncFK0kXlKIv6BJm5acncehXWUjWQMQ==", + "dev": true, + "peer": true, + "dependencies": { + "@babel/compat-data": "^7.13.12", + "@babel/helper-validator-option": "^7.12.17", + "browserslist": "^4.14.5", + "semver": "^6.3.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-compilation-targets/node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true, + "peer": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/helper-create-class-features-plugin": { + "version": "7.13.11", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.13.11.tgz", + "integrity": "sha512-ays0I7XYq9xbjCSvT+EvysLgfc3tOkwCULHjrnscGT3A9qD4sk3wXnJ3of0MAWsWGjdinFvajHU2smYuqXKMrw==", + "dev": true, + "dependencies": { + "@babel/helper-function-name": "^7.12.13", + "@babel/helper-member-expression-to-functions": "^7.13.0", + "@babel/helper-optimise-call-expression": "^7.12.13", + "@babel/helper-replace-supers": "^7.13.0", + "@babel/helper-split-export-declaration": "^7.12.13" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-function-name": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.12.13.tgz", + "integrity": "sha512-TZvmPn0UOqmvi5G4vvw0qZTpVptGkB1GL61R6lKvrSdIxGm5Pky7Q3fpKiIkQCAtRCBUwB0PaThlx9vebCDSwA==", + "dev": true, + "dependencies": { + "@babel/helper-get-function-arity": "^7.12.13", + "@babel/template": "^7.12.13", + "@babel/types": "^7.12.13" + } + }, + "node_modules/@babel/helper-get-function-arity": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.12.13.tgz", + "integrity": "sha512-DjEVzQNz5LICkzN0REdpD5prGoidvbdYk1BVgRUOINaWJP2t6avB27X1guXK1kXNrX0WMfsrm1A/ZBthYuIMQg==", + "dev": true, + "dependencies": { + "@babel/types": "^7.12.13" + } + }, + "node_modules/@babel/helper-member-expression-to-functions": { + "version": "7.13.12", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.13.12.tgz", + "integrity": "sha512-48ql1CLL59aKbU94Y88Xgb2VFy7a95ykGRbJJaaVv+LX5U8wFpLfiGXJJGUozsmA1oEh/o5Bp60Voq7ACyA/Sw==", + "dev": true, + "dependencies": { + "@babel/types": "^7.13.12" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.13.12", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.13.12.tgz", + "integrity": "sha512-4cVvR2/1B693IuOvSI20xqqa/+bl7lqAMR59R4iu39R9aOX8/JoYY1sFaNvUMyMBGnHdwvJgUrzNLoUZxXypxA==", + "dev": true, + "peer": true, + "dependencies": { + "@babel/types": "^7.13.12" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.13.14", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.13.14.tgz", + "integrity": "sha512-QuU/OJ0iAOSIatyVZmfqB0lbkVP0kDRiKj34xy+QNsnVZi/PA6BoSoreeqnxxa9EHFAIL0R9XOaAR/G9WlIy5g==", + "dev": true, + "peer": true, + "dependencies": { + "@babel/helper-module-imports": "^7.13.12", + "@babel/helper-replace-supers": "^7.13.12", + "@babel/helper-simple-access": "^7.13.12", + "@babel/helper-split-export-declaration": "^7.12.13", + "@babel/helper-validator-identifier": "^7.12.11", + "@babel/template": "^7.12.13", + "@babel/traverse": "^7.13.13", + "@babel/types": "^7.13.14" + } + }, + "node_modules/@babel/helper-optimise-call-expression": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.12.13.tgz", + "integrity": "sha512-BdWQhoVJkp6nVjB7nkFWcn43dkprYauqtk++Py2eaf/GRDFm5BxRqEIZCiHlZUGAVmtwKcsVL1dC68WmzeFmiA==", + "dev": true, + "dependencies": { + "@babel/types": "^7.12.13" + } + }, + "node_modules/@babel/helper-plugin-utils": { + "version": "7.13.0", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.13.0.tgz", + "integrity": "sha512-ZPafIPSwzUlAoWT8DKs1W2VyF2gOWthGd5NGFMsBcMMol+ZhK+EQY/e6V96poa6PA/Bh+C9plWN0hXO1uB8AfQ==", + "dev": true + }, + "node_modules/@babel/helper-replace-supers": { + "version": "7.13.12", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.13.12.tgz", + "integrity": "sha512-Gz1eiX+4yDO8mT+heB94aLVNCL+rbuT2xy4YfyNqu8F+OI6vMvJK891qGBTqL9Uc8wxEvRW92Id6G7sDen3fFw==", + "dev": true, + "dependencies": { + "@babel/helper-member-expression-to-functions": "^7.13.12", + "@babel/helper-optimise-call-expression": "^7.12.13", + "@babel/traverse": "^7.13.0", + "@babel/types": "^7.13.12" + } + }, + "node_modules/@babel/helper-simple-access": { + "version": "7.13.12", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.13.12.tgz", + "integrity": "sha512-7FEjbrx5SL9cWvXioDbnlYTppcZGuCY6ow3/D5vMggb2Ywgu4dMrpTJX0JdQAIcRRUElOIxF3yEooa9gUb9ZbA==", + "dev": true, + "peer": true, + "dependencies": { + "@babel/types": "^7.13.12" + } + }, + "node_modules/@babel/helper-split-export-declaration": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.12.13.tgz", + "integrity": "sha512-tCJDltF83htUtXx5NLcaDqRmknv652ZWCHyoTETf1CXYJdPC7nohZohjUgieXhv0hTJdRf2FjDueFehdNucpzg==", + "dev": true, + "dependencies": { + "@babel/types": "^7.12.13" + } + }, "node_modules/@babel/helper-validator-identifier": { "version": "7.12.11", "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz", "integrity": "sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw==", "dev": true }, + "node_modules/@babel/helper-validator-option": { + "version": "7.12.17", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.12.17.tgz", + "integrity": "sha512-TopkMDmLzq8ngChwRlyjR6raKD6gMSae4JdYDB8bByKreQgG0RBTuKe9LRxW3wFtUnjxOPRKBDwEH6Mg5KeDfw==", + "dev": true, + "peer": true + }, + "node_modules/@babel/helpers": { + "version": "7.13.10", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.13.10.tgz", + "integrity": "sha512-4VO883+MWPDUVRF3PhiLBUFHoX/bsLTGFpFK/HqvvfBZz2D57u9XzPVNFVBTc0PW/CWR9BXTOKt8NF4DInUHcQ==", + "dev": true, + "peer": true, + "dependencies": { + "@babel/template": "^7.12.13", + "@babel/traverse": "^7.13.0", + "@babel/types": "^7.13.0" + } + }, "node_modules/@babel/highlight": { "version": "7.13.8", "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.13.8.tgz", @@ -73,14 +335,114 @@ "js-tokens": "^4.0.0" } }, - "node_modules/@dabh/diagnostics": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@dabh/diagnostics/-/diagnostics-2.0.2.tgz", - "integrity": "sha512-+A1YivoVDNNVCdfozHSR8v/jyuuLTMXwjWuxPFlFlUapXoGc+Gj9mDlTDDfrwl7rXCl2tNZ0kE8sIBO6YOn96Q==", + "node_modules/@babel/parser": { + "version": "7.13.13", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.13.13.tgz", + "integrity": "sha512-OhsyMrqygfk5v8HmWwOzlYjJrtLaFhF34MrfG/Z73DgYCI6ojNUTUp2TYbtnjo8PegeJp12eamsNettCQjKjVw==", + "dev": true, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/plugin-proposal-class-properties": { + "version": "7.13.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.13.0.tgz", + "integrity": "sha512-KnTDjFNC1g+45ka0myZNvSBFLhNCLN+GeGYLDEA8Oq7MZ6yMgfLoIRh86GRT0FjtJhZw8JyUskP9uvj5pHM9Zg==", + "dev": true, "dependencies": { - "colorspace": "1.1.x", - "enabled": "2.0.x", - "kuler": "^2.0.0" + "@babel/helper-create-class-features-plugin": "^7.13.0", + "@babel/helper-plugin-utils": "^7.13.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/template": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.12.13.tgz", + "integrity": "sha512-/7xxiGA57xMo/P2GVvdEumr8ONhFOhfgq2ihK3h1e6THqzTAkHbkXgB0xI9yeTfIUoH3+oAeHhqm/I43OTbbjA==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.12.13", + "@babel/parser": "^7.12.13", + "@babel/types": "^7.12.13" + } + }, + "node_modules/@babel/traverse": { + "version": "7.13.13", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.13.13.tgz", + "integrity": "sha512-CblEcwmXKR6eP43oQGG++0QMTtCjAsa3frUuzHoiIJWpaIIi8dwMyEFUJoXRLxagGqCK+jALRwIO+o3R9p/uUg==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.12.13", + "@babel/generator": "^7.13.9", + "@babel/helper-function-name": "^7.12.13", + "@babel/helper-split-export-declaration": "^7.12.13", + "@babel/parser": "^7.13.13", + "@babel/types": "^7.13.13", + "debug": "^4.1.0", + "globals": "^11.1.0" + } + }, + "node_modules/@babel/types": { + "version": "7.13.14", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.13.14.tgz", + "integrity": "sha512-A2aa3QTkWoyqsZZFl56MLUsfmh7O0gN41IPvXAE/++8ojpbz12SszD7JEGYVdn4f9Kt4amIei07swF1h4AqmmQ==", + "dev": true, + "dependencies": { + "@babel/helper-validator-identifier": "^7.12.11", + "lodash": "^4.17.19", + "to-fast-properties": "^2.0.0" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.0.tgz", + "integrity": "sha512-2ZPCc+uNbjV5ERJr+aKSPRwZgKd2z11x0EgLvb1PURmUrn9QNRXFqje0Ldq454PfAVyaJYyrDvvIKSFP4NnBog==", + "dev": true, + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.1.1", + "espree": "^7.3.0", + "globals": "^12.1.0", + "ignore": "^4.0.6", + "import-fresh": "^3.2.1", + "js-yaml": "^3.13.1", + "minimatch": "^3.0.4", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/@eslint/eslintrc/node_modules/globals": { + "version": "12.4.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-12.4.0.tgz", + "integrity": "sha512-BWICuzzDvDoH54NHKCseDanAhE3CeDorgDL5MT6LMXXj2WCnd9UC2szdk4AWLfjdgNBCXLUanXYcpBBKOSWGwg==", + "dev": true, + "dependencies": { + "type-fest": "^0.8.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@eslint/eslintrc/node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/@tokenizer/token": { @@ -126,14 +488,6 @@ "resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.31.tgz", "integrity": "sha512-vFHy/ezP5qI0rFgJ7aQnjDXwAMrG0KqqIH7tQG5PPv3BWBayOPIQNBjVc/P6hhdZfMx51REc6tfDNXHUio893g==" }, - "node_modules/@types/puppeteer": { - "version": "5.4.3", - "resolved": "https://registry.npmjs.org/@types/puppeteer/-/puppeteer-5.4.3.tgz", - "integrity": "sha512-3nE8YgR9DIsgttLW+eJf6mnXxq8Ge+27m5SU3knWmrlfl6+KOG0Bf9f7Ua7K+C4BnaTMAh3/UpySqdAYvrsvjg==", - "dependencies": { - "@types/node": "*" - } - }, "node_modules/@types/readable-stream": { "version": "2.3.9", "resolved": "https://registry.npmjs.org/@types/readable-stream/-/readable-stream-2.3.9.tgz", @@ -143,30 +497,10 @@ "safe-buffer": "*" } }, - "node_modules/@types/yauzl": { - "version": "2.9.1", - "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.9.1.tgz", - "integrity": "sha512-A1b8SU4D10uoPjwb0lnHmmu8wZhR9d+9o2PKBQT2jU5YPTKsxac6M2qGAdY7VcL+dHHhARVUDmeg0rOrcd9EjA==", - "optional": true, - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/abort-controller": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", - "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", - "dependencies": { - "event-target-shim": "^5.0.0" - }, - "engines": { - "node": ">=6.5" - } - }, "node_modules/acorn": { - "version": "6.4.2", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.2.tgz", - "integrity": "sha512-XtGIhXwF8YM8bJhGxG5kXgjkEuNGLTkoYqVE+KMR+aspr4KGYmKYg7yUe3KghyQ9yheNwLnjmzh/7+gfDBmHCQ==", + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", + "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", "dev": true, "bin": { "acorn": "bin/acorn" @@ -184,14 +518,6 @@ "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, - "node_modules/agent-base": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-5.1.1.tgz", - "integrity": "sha512-TMeqbNl2fMW0nMjTEPOwe3J/PRFP4vqeoNuQMG0HlMrtm5QxKqdvAkZ1pRBQ/ulIyDD5Yq0nJ7YbdD8ey0TO3g==", - "engines": { - "node": ">= 6.0.0" - } - }, "node_modules/ajv": { "version": "6.12.6", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", @@ -208,13 +534,24 @@ "url": "https://github.com/sponsors/epoberezkin" } }, - "node_modules/ansi-escapes": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.2.0.tgz", - "integrity": "sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==", + "node_modules/ansi-colors": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", + "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", "dev": true, "engines": { - "node": ">=4" + "node": ">=6" + } + }, + "node_modules/ansi-gray": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/ansi-gray/-/ansi-gray-0.1.1.tgz", + "integrity": "sha1-KWLPVOyXksSFEKPetSRDaGHvclE=", + "dependencies": { + "ansi-wrap": "0.1.0" + }, + "engines": { + "node": ">=0.10.0" } }, "node_modules/ansi-regex": { @@ -236,6 +573,14 @@ "node": ">=4" } }, + "node_modules/ansi-wrap": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/ansi-wrap/-/ansi-wrap-0.1.0.tgz", + "integrity": "sha1-qCJQ3bABXponyoLoLqYDu/pF768=", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/aproba": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", @@ -259,32 +604,29 @@ "sprintf-js": "~1.0.2" } }, - "node_modules/arr-union": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", - "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/array-flatten": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-3.0.0.tgz", "integrity": "sha512-zPMVc3ZYlGLNk4mpK1NzP2wg0ml9t7fUgDsayR5Y5rSzxQilzR9FGu/EH2jQOcKSAeAfWeylyW8juy3OkWRvNA==" }, - "node_modules/astral-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz", - "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==", - "dev": true, - "engines": { - "node": ">=4" + "node_modules/asciiart-logo": { + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/asciiart-logo/-/asciiart-logo-0.2.6.tgz", + "integrity": "sha512-qAGPI1Y984SMiONbZ1gI3YdG1bm+mmCj2AklusFqYVVCikPo3jss7IlcZkt+FoRInaomrMn0OQtPaKkt90NApg==", + "dependencies": { + "chalk": "^2.4.2", + "figlet": "^1.2.0", + "to-title-case": "^1.0.0" } }, - "node_modules/async": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/async/-/async-3.2.0.tgz", - "integrity": "sha512-TR2mEZFVOj2pLStYxLht7TyfuRzaydfpxr3k9RpHIzMgw7A64dzsdqCxH1WJyQdoe8T10nDXd9wnEigmiuHIZw==" + "node_modules/astral-regex": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", + "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", + "dev": true, + "engines": { + "node": ">=8" + } }, "node_modules/axios": { "version": "0.18.1", @@ -299,7 +641,8 @@ "node_modules/balanced-match": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "dev": true }, "node_modules/base64-js": { "version": "1.5.1", @@ -349,11 +692,36 @@ "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, + "node_modules/browserslist": { + "version": "4.16.3", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.16.3.tgz", + "integrity": "sha512-vIyhWmIkULaq04Gt93txdh+j02yX/JzlyhLYbV3YQCn/zvES3JnY7TifHHvvr1w5hTDluNKMkV05cs4vy8Q7sw==", + "dev": true, + "peer": true, + "dependencies": { + "caniuse-lite": "^1.0.30001181", + "colorette": "^1.2.1", + "electron-to-chromium": "^1.3.649", + "escalade": "^3.1.1", + "node-releases": "^1.1.70" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + } + }, "node_modules/bson": { "version": "1.1.5", "resolved": "https://registry.npmjs.org/bson/-/bson-1.1.5.tgz", @@ -400,14 +768,6 @@ "resolved": "https://registry.npmjs.org/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz", "integrity": "sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg==" }, - "node_modules/buffer-crc32": { - "version": "0.2.13", - "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", - "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=", - "engines": { - "node": "*" - } - }, "node_modules/buffer-fill": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/buffer-fill/-/buffer-fill-1.0.0.tgz", @@ -445,6 +805,19 @@ "node": ">= 0.8" } }, + "node_modules/call-bind": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", + "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/callsites": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", @@ -462,11 +835,17 @@ "node": ">=6" } }, + "node_modules/caniuse-lite": { + "version": "1.0.30001205", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001205.tgz", + "integrity": "sha512-TL1GrS5V6LElbitPazidkBMD9sa448bQDDLrumDqaggmKFcuU2JW1wTOHJPukAcOMtEmLcmDJEzfRrf+GjM0Og==", + "dev": true, + "peer": true + }, "node_modules/chalk": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, "dependencies": { "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", @@ -476,35 +855,11 @@ "node": ">=4" } }, - "node_modules/chardet": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", - "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", - "dev": true - }, "node_modules/chownr": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==" }, - "node_modules/cli-cursor": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", - "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=", - "dev": true, - "dependencies": { - "restore-cursor": "^2.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/cli-width": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.1.tgz", - "integrity": "sha512-GRMWDxpOB6Dgk2E5Uo+3eEBvtOOlimMmpbFiKuLFnQzYDavtLFY3K5ona41jgN/WdRZtG7utuVSVTL4HbZHGkw==", - "dev": true - }, "node_modules/cliui": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", @@ -560,21 +915,6 @@ "node": ">=6" } }, - "node_modules/clone-deep": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-0.2.4.tgz", - "integrity": "sha1-TnPdCen7lxzDhnDF3O2cGJZIHMY=", - "dependencies": { - "for-own": "^0.1.3", - "is-plain-object": "^2.0.1", - "kind-of": "^3.0.2", - "lazy-cache": "^1.0.3", - "shallow-clone": "^0.1.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/code-point-at": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", @@ -614,6 +954,21 @@ "simple-swizzle": "^0.2.2" } }, + "node_modules/color-support": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz", + "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==", + "bin": { + "color-support": "bin.js" + } + }, + "node_modules/colorette": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.2.2.tgz", + "integrity": "sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w==", + "dev": true, + "peer": true + }, "node_modules/colors": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz", @@ -622,34 +977,34 @@ "node": ">=0.1.90" } }, - "node_modules/colorspace": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/colorspace/-/colorspace-1.1.2.tgz", - "integrity": "sha512-vt+OoIP2d76xLhjwbBaucYlNSpPsrJWPlBTtwCpQKIu6/CSMutyzX93O/Do0qzpH3YoHEes8YEFXyZ797rEhzQ==", - "dependencies": { - "color": "3.0.x", - "text-hex": "1.0.x" - } - }, - "node_modules/colorspace/node_modules/color": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/color/-/color-3.0.0.tgz", - "integrity": "sha512-jCpd5+s0s0t7p3pHQKpnJ0TpQKKdleP71LWcA0aqiljpiuAkOSUFN/dyH8ZwF0hRmFlrIuRhufds1QyEP9EB+w==", - "dependencies": { - "color-convert": "^1.9.1", - "color-string": "^1.5.2" - } - }, "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true }, "node_modules/console-control-strings": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=" }, + "node_modules/convert-source-map": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz", + "integrity": "sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==", + "dev": true, + "peer": true, + "dependencies": { + "safe-buffer": "~5.1.1" + } + }, + "node_modules/convert-source-map/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true, + "peer": true + }, "node_modules/core-util-is": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", @@ -670,25 +1025,29 @@ } }, "node_modules/cross-spawn": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", - "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", "dev": true, "dependencies": { - "nice-try": "^1.0.4", - "path-key": "^2.0.1", - "semver": "^5.5.0", - "shebang-command": "^1.2.0", - "which": "^1.2.9" + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" }, "engines": { - "node": ">=4.8" + "node": ">= 8" } }, + "node_modules/dayjs": { + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.10.4.tgz", + "integrity": "sha512-RI/Hh4kqRc1UKLOAf/T5zdMMX5DQIlDxwUe3wSyMMnEbGunnpENCdbUgM+dW7kXidZqCttBrmw7BhN4TMddkCw==" + }, "node_modules/debug": { "version": "4.3.1", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "dev": true, "dependencies": { "ms": "2.1.2" }, @@ -737,14 +1096,6 @@ "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", "dev": true }, - "node_modules/deepmerge": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz", - "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/delegates": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", @@ -778,11 +1129,6 @@ "node": ">=0.10" } }, - "node_modules/devtools-protocol": { - "version": "0.0.818844", - "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.818844.tgz", - "integrity": "sha512-AD1hi7iVJ8OD0aMLQU5VK0XH9LDlA1+BcPIgrAxPfaibx2DbWucuyOhc4oyQCbnvDDO68nN6/LcKfqTP343Jjg==" - }, "node_modules/dijkstrajs": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/dijkstrajs/-/dijkstrajs-1.0.1.tgz", @@ -816,16 +1162,18 @@ "axios": "^0.18.0" } }, + "node_modules/electron-to-chromium": { + "version": "1.3.704", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.704.tgz", + "integrity": "sha512-6cz0jvawlUe4h5AbfQWxPzb+8LzVyswGAWiGc32EJEmfj39HTQyNPkLXirc7+L4x5I6RgRkzua8Ryu5QZqc8cA==", + "dev": true, + "peer": true + }, "node_modules/emoji-regex": { "version": "9.2.2", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==" }, - "node_modules/enabled": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/enabled/-/enabled-2.0.0.tgz", - "integrity": "sha512-AKrN98kuwOzMIdAizXGI86UFBoo26CL21UM763y1h/GMSJ4/OHU9k2YlsmBpyScFo/wbLzWQJBMCW4+IO3/+OQ==" - }, "node_modules/end-of-stream": { "version": "1.4.4", "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", @@ -834,10 +1182,51 @@ "once": "^1.4.0" } }, + "node_modules/enquirer": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", + "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", + "dev": true, + "dependencies": { + "ansi-colors": "^4.1.1" + }, + "engines": { + "node": ">=8.6" + } + }, "node_modules/eris": { - "version": "0.14.0", - "resolved": "git+ssh://git@github.com/abalabahaha/eris.git#16c6a76275030dbd43635c8b89e68b74435dbe25", - "license": "MIT", + "version": "0.15.0", + "resolved": "https://registry.npmjs.org/eris/-/eris-0.15.0.tgz", + "integrity": "sha512-muBdi5XyMXdxFQ8xUG6yofq40/Z02CHlqJP7zIdHhpdDiHvFM/mybGiFAHuoSYcsVTTvEfbUaAJ+SDEmMjARYw==", + "dependencies": { + "ws": "^7.2.1" + }, + "engines": { + "node": ">=10.4.0" + }, + "optionalDependencies": { + "opusscript": "^0.0.8", + "tweetnacl": "^1.0.1" + } + }, + "node_modules/eris-sharder": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/eris-sharder/-/eris-sharder-1.10.0.tgz", + "integrity": "sha512-cDazqx7KKM1tpMl2+UFlxwAG7fEnGBxssf/juayVR+If+nfuzUazm0nekRre8cbU4PZMjZmQPxWmDNlOcdFfAA==", + "dependencies": { + "asciiart-logo": "^0.2.6", + "colors": "^1.1.2", + "eris": "^0.13.1", + "fancy-log": "^1.3.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/eris-sharder/node_modules/eris": { + "version": "0.13.4", + "resolved": "https://registry.npmjs.org/eris/-/eris-0.13.4.tgz", + "integrity": "sha512-IFA14nasCig8xp8cVCULvzBuJ0qpYqJ3XyEtm9OLdC177DYDCJ9QM2Aq+KOpejIVl7838n9AyRlLI6w9Eu3PiQ==", "dependencies": { "ws": "^7.2.1" }, @@ -845,10 +1234,16 @@ "node": ">=8.0.0" }, "optionalDependencies": { - "opusscript": "^0.0.8", + "opusscript": "^0.0.7", "tweetnacl": "^1.0.1" } }, + "node_modules/eris-sharder/node_modules/opusscript": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/opusscript/-/opusscript-0.0.7.tgz", + "integrity": "sha512-DcBadTdYTUuH9zQtepsLjQn4Ll6rs3dmeFvN+SD0ThPnxRBRm/WC1zXWPg+wgAJimB784gdZvUMA57gDP7FdVg==", + "optional": true + }, "node_modules/erlpack": { "version": "0.1.3", "resolved": "git+ssh://git@github.com/abalabahaha/erlpack.git#5d0064f9e106841e1eead711a6451f99b0d289fd", @@ -859,97 +1254,118 @@ "nan": "^2.14.0" } }, + "node_modules/escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "dev": true, + "peer": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-regexp-component": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/escape-regexp-component/-/escape-regexp-component-1.0.2.tgz", + "integrity": "sha1-nGO20LJf8qiMOtvRjFthrMO5+qI=" + }, "node_modules/escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "dev": true, "engines": { "node": ">=0.8.0" } }, "node_modules/eslint": { - "version": "5.16.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-5.16.0.tgz", - "integrity": "sha512-S3Rz11i7c8AA5JPv7xAH+dOyq/Cu/VXHiHXBPOU1k/JAM5dXqQPt3qcrhpHSorXmrpu2g0gkIBVXAqCpzfoZIg==", + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.23.0.tgz", + "integrity": "sha512-kqvNVbdkjzpFy0XOszNwjkKzZ+6TcwCQ/h+ozlcIWwaimBBuhlQ4nN6kbiM2L+OjDcznkTJxzYfRFH92sx4a0Q==", "dev": true, "dependencies": { - "@babel/code-frame": "^7.0.0", - "ajv": "^6.9.1", - "chalk": "^2.1.0", - "cross-spawn": "^6.0.5", + "@babel/code-frame": "7.12.11", + "@eslint/eslintrc": "^0.4.0", + "ajv": "^6.10.0", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", "debug": "^4.0.1", "doctrine": "^3.0.0", - "eslint-scope": "^4.0.3", - "eslint-utils": "^1.3.1", - "eslint-visitor-keys": "^1.0.0", - "espree": "^5.0.1", - "esquery": "^1.0.1", + "enquirer": "^2.3.5", + "eslint-scope": "^5.1.1", + "eslint-utils": "^2.1.0", + "eslint-visitor-keys": "^2.0.0", + "espree": "^7.3.1", + "esquery": "^1.4.0", "esutils": "^2.0.2", - "file-entry-cache": "^5.0.1", + "file-entry-cache": "^6.0.1", "functional-red-black-tree": "^1.0.1", - "glob": "^7.1.2", - "globals": "^11.7.0", + "glob-parent": "^5.0.0", + "globals": "^13.6.0", "ignore": "^4.0.6", "import-fresh": "^3.0.0", "imurmurhash": "^0.1.4", - "inquirer": "^6.2.2", - "js-yaml": "^3.13.0", + "is-glob": "^4.0.0", + "js-yaml": "^3.13.1", "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.3.0", - "lodash": "^4.17.11", + "levn": "^0.4.1", + "lodash": "^4.17.21", "minimatch": "^3.0.4", - "mkdirp": "^0.5.1", "natural-compare": "^1.4.0", - "optionator": "^0.8.2", - "path-is-inside": "^1.0.2", + "optionator": "^0.9.1", "progress": "^2.0.0", - "regexpp": "^2.0.1", - "semver": "^5.5.1", - "strip-ansi": "^4.0.0", - "strip-json-comments": "^2.0.1", - "table": "^5.2.3", - "text-table": "^0.2.0" + "regexpp": "^3.1.0", + "semver": "^7.2.1", + "strip-ansi": "^6.0.0", + "strip-json-comments": "^3.1.0", + "table": "^6.0.4", + "text-table": "^0.2.0", + "v8-compile-cache": "^2.0.3" }, "bin": { "eslint": "bin/eslint.js" }, "engines": { - "node": "^6.14.0 || ^8.10.0 || >=9.10.0" - } - }, - "node_modules/eslint-plugin-promise": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-4.3.1.tgz", - "integrity": "sha512-bY2sGqyptzFBDLh/GMbAxfdJC+b0f23ME63FOE4+Jao0oZ3E1LEwFtWJX/1pGMJLiTtrSSern2CRM/g+dfc0eQ==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/eslint-scope": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.3.tgz", - "integrity": "sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg==", - "dev": true, - "dependencies": { - "esrecurse": "^4.1.0", - "estraverse": "^4.1.1" + "node": "^10.12.0 || >=12.0.0" }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-rule-composer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/eslint-rule-composer/-/eslint-rule-composer-0.3.0.tgz", + "integrity": "sha512-bt+Sh8CtDmn2OajxvNO+BX7Wn4CIWMpTRm3MaiKPCQcnnlm0CS2mhui6QaoeQugs+3Kj2ESKEEGJUdVafwhiCg==", + "dev": true, "engines": { "node": ">=4.0.0" } }, + "node_modules/eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "dev": true, + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, "node_modules/eslint-utils": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.4.3.tgz", - "integrity": "sha512-fbBN5W2xdY45KulGXmLHZ3c3FHfVYmKg0IrAKGOkT/464PQsx2UeIzfz1RmEci+KLm1bBaAzZAh8+/E+XAeZ8Q==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", + "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", "dev": true, "dependencies": { "eslint-visitor-keys": "^1.1.0" }, "engines": { "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" } }, "node_modules/eslint-visitor-keys": { @@ -961,18 +1377,181 @@ "node": ">=4" } }, - "node_modules/espree": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-5.0.1.tgz", - "integrity": "sha512-qWAZcWh4XE/RwzLJejfcofscgMc9CamR6Tn1+XRXNzrvUSSbiAjGOI/fggztjIi7y9VLPqnICMIPiGyr8JaZ0A==", + "node_modules/eslint/node_modules/@babel/code-frame": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", + "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", "dev": true, "dependencies": { - "acorn": "^6.0.7", - "acorn-jsx": "^5.0.0", - "eslint-visitor-keys": "^1.0.0" + "@babel/highlight": "^7.10.4" + } + }, + "node_modules/eslint/node_modules/ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/eslint/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" }, "engines": { - "node": ">=6.0.0" + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/eslint/node_modules/chalk": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/eslint/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/eslint/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/eslint/node_modules/eslint-visitor-keys": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.0.0.tgz", + "integrity": "sha512-QudtT6av5WXels9WjIM7qz1XD1cWGvX4gGXvp/zBn9nXG02D0utdU3Em2m/QjTnrsk6bBjmCygl3rmj118msQQ==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/eslint/node_modules/globals": { + "version": "13.7.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.7.0.tgz", + "integrity": "sha512-Aipsz6ZKRxa/xQkZhNg0qIWXT6x6rD46f6x/PCnBomlttdIyAPak4YD9jTmKpZ72uROSMU87qJtcgpgHaVchiA==", + "dev": true, + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/eslint/node_modules/semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/eslint/node_modules/strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/eslint/node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/eslint/node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/espree": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.1.tgz", + "integrity": "sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g==", + "dev": true, + "dependencies": { + "acorn": "^7.4.0", + "acorn-jsx": "^5.3.1", + "eslint-visitor-keys": "^1.3.0" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" } }, "node_modules/esprima": { @@ -1048,14 +1627,6 @@ "node": ">=0.10.0" } }, - "node_modules/event-target-shim": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", - "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", - "engines": { - "node": ">=6" - } - }, "node_modules/expand-template": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz", @@ -1064,37 +1635,18 @@ "node": ">=6" } }, - "node_modules/external-editor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", - "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", - "dev": true, + "node_modules/fancy-log": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/fancy-log/-/fancy-log-1.3.3.tgz", + "integrity": "sha512-k9oEhlyc0FrVh25qYuSELjr8oxsCoc4/LEZfg2iJJrfEk/tZL9bCoJE47gqAvI2m/AUjluCS4+3I0eTx8n3AEw==", "dependencies": { - "chardet": "^0.7.0", - "iconv-lite": "^0.4.24", - "tmp": "^0.0.33" + "ansi-gray": "^0.1.1", + "color-support": "^1.1.3", + "parse-node-version": "^1.0.0", + "time-stamp": "^1.0.0" }, "engines": { - "node": ">=4" - } - }, - "node_modules/extract-zip": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz", - "integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==", - "dependencies": { - "debug": "^4.1.1", - "get-stream": "^5.1.0", - "yauzl": "^2.10.0" - }, - "bin": { - "extract-zip": "cli.js" - }, - "engines": { - "node": ">= 10.17.0" - }, - "optionalDependencies": { - "@types/yauzl": "^2.9.1" + "node": ">= 0.10" } }, "node_modules/fast-deep-equal": { @@ -1115,46 +1667,24 @@ "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", "dev": true }, - "node_modules/fast-safe-stringify": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.0.7.tgz", - "integrity": "sha512-Utm6CdzT+6xsDk2m8S6uL8VHxNwI6Jub+e9NYTcAms28T84pTa25GJQV9j0CY0N1rM8hK4x6grpF2BQf+2qwVA==" - }, - "node_modules/fd-slicer": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", - "integrity": "sha1-JcfInLH5B3+IkbvmHY85Dq4lbx4=", - "dependencies": { - "pend": "~1.2.0" - } - }, - "node_modules/fecha": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/fecha/-/fecha-4.2.0.tgz", - "integrity": "sha512-aN3pcx/DSmtyoovUudctc8+6Hl4T+hI9GBBHLjA76jdZl7+b1sgh5g4k+u/GL3dTy1/pnYzKp69FpJ0OicE3Wg==" - }, - "node_modules/figures": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", - "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=", - "dev": true, - "dependencies": { - "escape-string-regexp": "^1.0.5" - }, + "node_modules/figlet": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/figlet/-/figlet-1.5.0.tgz", + "integrity": "sha512-ZQJM4aifMpz6H19AW1VqvZ7l4pOE9p7i/3LyxgO2kp+PO/VcDYNqIHEMtkccqIhTXMKci4kjueJr/iCQEaT/Ww==", "engines": { - "node": ">=4" + "node": ">= 0.4.0" } }, "node_modules/file-entry-cache": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-5.0.1.tgz", - "integrity": "sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g==", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", "dev": true, "dependencies": { - "flat-cache": "^2.0.1" + "flat-cache": "^3.0.4" }, "engines": { - "node": ">=4" + "node": "^10.12.0 || >=12.0.0" } }, "node_modules/file-type": { @@ -1180,43 +1710,25 @@ "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", "optional": true }, - "node_modules/find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dependencies": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/flat-cache": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-2.0.1.tgz", - "integrity": "sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA==", + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", + "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", "dev": true, "dependencies": { - "flatted": "^2.0.0", - "rimraf": "2.6.3", - "write": "1.0.3" + "flatted": "^3.1.0", + "rimraf": "^3.0.2" }, "engines": { - "node": ">=4" + "node": "^10.12.0 || >=12.0.0" } }, "node_modules/flatted": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.2.tgz", - "integrity": "sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.1.1.tgz", + "integrity": "sha512-zAoAQiudy+r5SvnSw3KJy5os/oRJYHzrzja/tBDqrZtNhUw8bt6y8OBzMWcjWr+8liV8Eb6yOhw8WZ7VFZ5ZzA==", "dev": true }, - "node_modules/fn.name": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/fn.name/-/fn.name-1.1.0.tgz", - "integrity": "sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw==" - }, "node_modules/follow-redirects": { "version": "1.5.10", "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.5.10.tgz", @@ -1241,47 +1753,22 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" }, - "node_modules/for-in": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", - "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/for-own": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/for-own/-/for-own-0.1.5.tgz", - "integrity": "sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4=", - "dependencies": { - "for-in": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/fs-constants": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==" }, - "node_modules/fs-extra": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", - "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", - "dependencies": { - "graceful-fs": "^4.2.0", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - }, - "engines": { - "node": ">=6 <7 || >=8" - } - }, "node_modules/fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "node_modules/function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true }, "node_modules/functional-red-black-tree": { "version": "1.0.1", @@ -1347,6 +1834,16 @@ "node": ">=0.10.0" } }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "dev": true, + "peer": true, + "engines": { + "node": ">=6.9.0" + } + }, "node_modules/get-caller-file": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", @@ -1355,18 +1852,18 @@ "node": "6.* || 8.* || >= 10.*" } }, - "node_modules/get-stream": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", - "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "node_modules/get-intrinsic": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", + "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", + "dev": true, "dependencies": { - "pump": "^3.0.0" - }, - "engines": { - "node": ">=8" + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/sponsors/ljharb" } }, "node_modules/github-from-package": { @@ -1378,6 +1875,7 @@ "version": "7.1.6", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "dev": true, "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -1393,6 +1891,18 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/globals": { "version": "11.12.0", "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", @@ -1402,20 +1912,38 @@ "node": ">=4" } }, - "node_modules/graceful-fs": { - "version": "4.2.6", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.6.tgz", - "integrity": "sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==" + "node_modules/has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.1" + }, + "engines": { + "node": ">= 0.4.0" + } }, "node_modules/has-flag": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true, "engines": { "node": ">=4" } }, + "node_modules/has-symbols": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz", + "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/has-unicode": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", @@ -1436,18 +1964,6 @@ "node": ">= 0.6" } }, - "node_modules/https-proxy-agent": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-4.0.0.tgz", - "integrity": "sha512-zoDhWrkR3of1l9QAL8/scJZyLu8j/gBkcwcaQOZh7Gyh/+uJQzGVETdgT30akuwkpL8HTRfssqI3BZuV18teDg==", - "dependencies": { - "agent-base": "5", - "debug": "4" - }, - "engines": { - "node": ">= 6.0.0" - } - }, "node_modules/iconv-lite": { "version": "0.4.24", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", @@ -1516,6 +2032,7 @@ "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, "dependencies": { "once": "^1.3.0", "wrappy": "1" @@ -1531,90 +2048,26 @@ "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==" }, - "node_modules/inquirer": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-6.5.2.tgz", - "integrity": "sha512-cntlB5ghuB0iuO65Ovoi8ogLHiWGs/5yNrtUcKjFhSSiVeAIVpD7koaSU9RM8mpXw5YDi9RdYXGQMaOURB7ycQ==", - "dev": true, - "dependencies": { - "ansi-escapes": "^3.2.0", - "chalk": "^2.4.2", - "cli-cursor": "^2.1.0", - "cli-width": "^2.0.0", - "external-editor": "^3.0.3", - "figures": "^2.0.0", - "lodash": "^4.17.12", - "mute-stream": "0.0.7", - "run-async": "^2.2.0", - "rxjs": "^6.4.0", - "string-width": "^2.1.0", - "strip-ansi": "^5.1.0", - "through": "^2.3.6" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/inquirer/node_modules/is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/inquirer/node_modules/string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "dev": true, - "dependencies": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/inquirer/node_modules/string-width/node_modules/strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, - "dependencies": { - "ansi-regex": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/inquirer/node_modules/strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "dependencies": { - "ansi-regex": "^4.1.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/inquirer/node_modules/strip-ansi/node_modules/ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true, - "engines": { - "node": ">=6" - } - }, "node_modules/is-arrayish": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==" }, + "node_modules/is-boolean-object": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.0.tgz", + "integrity": "sha512-a7Uprx8UtD+HWdyYwnD1+ExtTgqQtD2k/1yJgtXP6wnMm8byhkoTZRl+95LLThpzNZJ5aEvi46cdH+ayMFRwmA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-buffer": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.5.tgz", @@ -1637,10 +2090,11 @@ "node": ">=4" } }, - "node_modules/is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "dev": true, "engines": { "node": ">=0.10.0" } @@ -1653,23 +2107,40 @@ "node": ">=8" } }, - "node_modules/is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "node_modules/is-glob": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", + "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", + "dev": true, "dependencies": { - "isobject": "^3.0.1" + "is-extglob": "^2.1.1" }, "engines": { "node": ">=0.10.0" } }, - "node_modules/is-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz", - "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==", + "node_modules/is-number-object": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.4.tgz", + "integrity": "sha512-zohwelOAur+5uXtk8O3GPQ1eAcu4ZX3UwxQhUlfFFMNpUd83gXgjbhJh6HmB6LUNV/ieOLQuDwJO3dWJosUeMw==", + "dev": true, "engines": { - "node": ">=8" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-string": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.5.tgz", + "integrity": "sha512-buY6VNRjhQMiF1qWDouloZlQbRhDPCebwxSjxMjxgemYT46YMd2NR0/H+fBhEfWX4A/w9TBJ+ol+okqJKFE6vQ==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, "node_modules/is-typedarray": { @@ -1688,14 +2159,6 @@ "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", "dev": true }, - "node_modules/isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", @@ -1715,6 +2178,18 @@ "js-yaml": "bin/js-yaml.js" } }, + "node_modules/jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "dev": true, + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", @@ -1727,12 +2202,20 @@ "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", "dev": true }, - "node_modules/jsonfile": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", - "optionalDependencies": { - "graceful-fs": "^4.1.6" + "node_modules/json5": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz", + "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==", + "dev": true, + "peer": true, + "dependencies": { + "minimist": "^1.2.5" + }, + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" } }, "node_modules/jsqr": { @@ -1746,27 +2229,6 @@ "integrity": "sha512-STHz9P7X2L4Kwn72fA4rGyqyXdmrMSdxqHx9IXon/FXluXieaFA6KJ2upcHAHxQPQ0LeM/OjLrhFxifHewOALQ==", "optional": true }, - "node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/kind-of/node_modules/is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" - }, - "node_modules/kuler": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/kuler/-/kuler-2.0.0.tgz", - "integrity": "sha512-Xq9nH7KlWZmXAtodXDDRE7vs6DU1gTU8zYDHDiWLSip45Egwq3plLHzPn27NgvzL2r1LMPC1vdqh98sQxtqj4A==" - }, "node_modules/lavacord": { "version": "1.1.9", "resolved": "https://registry.npmjs.org/lavacord/-/lavacord-1.1.9.tgz", @@ -1780,60 +2242,47 @@ "npm": ">=5" } }, - "node_modules/lazy-cache": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-1.0.4.tgz", - "integrity": "sha1-odePw6UEdMuAhF07O24dpJpEbo4=", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/levn": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", - "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", "dev": true, "dependencies": { - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2" + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" }, "engines": { "node": ">= 0.8.0" } }, - "node_modules/locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dependencies": { - "p-locate": "^4.1.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/lodash": { "version": "4.17.21", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", "dev": true }, + "node_modules/lodash.clonedeep": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", + "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=", + "dev": true + }, + "node_modules/lodash.flatten": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.flatten/-/lodash.flatten-4.4.0.tgz", + "integrity": "sha1-8xwiIlqWMtK7+OSt2+8kCqdlph8=", + "dev": true + }, "node_modules/lodash.toarray": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/lodash.toarray/-/lodash.toarray-4.4.0.tgz", "integrity": "sha1-JMS/zWsvuji/0FlNsRedjptlZWE=" }, - "node_modules/logform": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/logform/-/logform-2.2.0.tgz", - "integrity": "sha512-N0qPlqfypFx7UHNn4B3lzS/b0uLqt2hmuoa+PpuXNYgozdJYAyauF5Ky0BWVjrxDlMWiT3qN4zPq3vVAfZy7Yg==", - "dependencies": { - "colors": "^1.2.1", - "fast-safe-stringify": "^2.0.4", - "fecha": "^4.2.0", - "ms": "^2.1.1", - "triple-beam": "^1.3.0" - } + "node_modules/lodash.truncate": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", + "integrity": "sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM=", + "dev": true }, "node_modules/lru-cache": { "version": "6.0.0", @@ -1852,28 +2301,6 @@ "integrity": "sha512-ZS4Bp4r/Zoeq6+NLJpP+0Zzm0pR8whtGPf1XExKLJBAczGMnSi3It14OiNCStjQjM6NU1okjQGSxgEZN8eBYKg==", "optional": true }, - "node_modules/merge-deep": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/merge-deep/-/merge-deep-3.0.3.tgz", - "integrity": "sha512-qtmzAS6t6grwEkNrunqTBdn0qKwFgNWvlxUbAV8es9M7Ot1EbyApytCnvE0jALPa46ZpKDUo527kKiaWplmlFA==", - "dependencies": { - "arr-union": "^3.1.0", - "clone-deep": "^0.2.4", - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/mimic-fn": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz", - "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==", - "dev": true, - "engines": { - "node": ">=4" - } - }, "node_modules/mimic-response": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", @@ -1889,6 +2316,7 @@ "version": "3.0.4", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, "dependencies": { "brace-expansion": "^1.1.7" }, @@ -1901,56 +2329,11 @@ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" }, - "node_modules/mixin-object": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/mixin-object/-/mixin-object-2.0.1.tgz", - "integrity": "sha1-T7lJRB2rGCVA8f4DW6YOGUel5X4=", - "dependencies": { - "for-in": "^0.1.3", - "is-extendable": "^0.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/mixin-object/node_modules/for-in": { - "version": "0.1.8", - "resolved": "https://registry.npmjs.org/for-in/-/for-in-0.1.8.tgz", - "integrity": "sha1-2Hc5COMSVhCZUrH9ubP6hn0ndeE=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/mkdirp": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", - "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", - "dev": true, - "dependencies": { - "minimist": "^1.2.5" - }, - "bin": { - "mkdirp": "bin/cmd.js" - } - }, "node_modules/mkdirp-classic": { "version": "0.5.3", "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==" }, - "node_modules/moment": { - "version": "2.29.1", - "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.1.tgz", - "integrity": "sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ==", - "engines": { - "node": "*" - } - }, - "node_modules/moment-duration-format": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/moment-duration-format/-/moment-duration-format-2.3.2.tgz", - "integrity": "sha512-cBMXjSW+fjOb4tyaVHuaVE/A5TqkukDWiOfxxAjY+PEqmmBQlLwn+8OzwPiG3brouXKY5Un4pBjAeB6UToXHaQ==" - }, "node_modules/mongodb": { "version": "3.6.4", "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-3.6.4.tgz", @@ -2075,13 +2458,8 @@ "node_modules/ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - }, - "node_modules/mute-stream": { - "version": "0.0.7", - "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz", - "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=", - "dev": true + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "devOptional": true }, "node_modules/nan": { "version": "2.14.2", @@ -2100,12 +2478,6 @@ "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", "dev": true }, - "node_modules/nice-try": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", - "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", - "dev": true - }, "node_modules/node-abi": { "version": "2.20.0", "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-2.20.0.tgz", @@ -2146,6 +2518,13 @@ "node-gyp-build-test": "build-test.js" } }, + "node_modules/node-releases": { + "version": "1.1.71", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.71.tgz", + "integrity": "sha512-zR6HoT6LrLCRBwukmrVbHv0EpEQjksO6GmFcZQQuCAy139BEsoVKPYnf3jongYW83fAa1torLGYwxxky/p28sg==", + "dev": true, + "peer": true + }, "node_modules/noop-logger": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/noop-logger/-/noop-logger-0.1.1.tgz", @@ -2186,38 +2565,18 @@ "wrappy": "1" } }, - "node_modules/one-time": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/one-time/-/one-time-1.0.0.tgz", - "integrity": "sha512-5DXOiRKwuSEcQ/l0kGCF6Q3jcADFv5tSmRaJck/OqkVFcOzutB134KRSfF0xDrL39MNnqxbHBbUUcjZIhTgb2g==", - "dependencies": { - "fn.name": "1.x.x" - } - }, - "node_modules/onetime": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", - "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=", - "dev": true, - "dependencies": { - "mimic-fn": "^1.0.0" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/optionator": { - "version": "0.8.3", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", - "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", + "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", "dev": true, "dependencies": { - "deep-is": "~0.1.3", - "fast-levenshtein": "~2.0.6", - "levn": "~0.3.0", - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2", - "word-wrap": "~1.2.3" + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.3" }, "engines": { "node": ">= 0.8.0" @@ -2229,15 +2588,6 @@ "integrity": "sha512-VSTi1aWFuCkRCVq+tx/BQ5q9fMnQ9pVZ3JU4UHKqTkf0ED3fKEPdr+gKAAl3IA2hj9rrP6iyq3hlcJq3HELtNQ==", "optional": true }, - "node_modules/os-tmpdir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", - "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/p-limit": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", @@ -2252,17 +2602,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dependencies": { - "p-limit": "^2.2.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/p-try": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", @@ -2289,35 +2628,30 @@ "node": ">=6" } }, - "node_modules/path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "node_modules/parse-node-version": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parse-node-version/-/parse-node-version-1.0.1.tgz", + "integrity": "sha512-3YHlOa/JgH6Mnpr05jP9eDG254US9ek25LyIxZlDItp2iJtwyaXQb57lBYLdT3MowkUFYEV2XXNAYIPlESvJlA==", "engines": { - "node": ">=8" + "node": ">= 0.10" } }, "node_modules/path-is-absolute": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true, "engines": { "node": ">=0.10.0" } }, - "node_modules/path-is-inside": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", - "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", - "dev": true - }, "node_modules/path-key": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", "dev": true, "engines": { - "node": ">=4" + "node": ">=8" } }, "node_modules/peek-readable": { @@ -2332,11 +2666,6 @@ "url": "https://github.com/sponsors/Borewit" } }, - "node_modules/pend": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", - "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=" - }, "node_modules/pg": { "version": "8.5.1", "resolved": "https://registry.npmjs.org/pg/-/pg-8.5.1.tgz", @@ -2418,17 +2747,6 @@ "split2": "^3.1.1" } }, - "node_modules/pkg-dir": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", - "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", - "dependencies": { - "find-up": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/pngjs": { "version": "3.4.0", "resolved": "https://registry.npmjs.org/pngjs/-/pngjs-3.4.0.tgz", @@ -2537,9 +2855,9 @@ } }, "node_modules/prelude-ls": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", - "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", "dev": true, "engines": { "node": ">= 0.8.0" @@ -2554,15 +2872,11 @@ "version": "2.0.3", "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", + "dev": true, "engines": { "node": ">=0.4.0" } }, - "node_modules/proxy-from-env": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", - "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" - }, "node_modules/pump": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", @@ -2581,116 +2895,6 @@ "node": ">=6" } }, - "node_modules/puppeteer": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/puppeteer/-/puppeteer-5.5.0.tgz", - "integrity": "sha512-OM8ZvTXAhfgFA7wBIIGlPQzvyEETzDjeRa4mZRCRHxYL+GNH5WAuYUQdja3rpWZvkX/JKqmuVgbsxDNsDFjMEg==", - "hasInstallScript": true, - "dependencies": { - "debug": "^4.1.0", - "devtools-protocol": "0.0.818844", - "extract-zip": "^2.0.0", - "https-proxy-agent": "^4.0.0", - "node-fetch": "^2.6.1", - "pkg-dir": "^4.2.0", - "progress": "^2.0.1", - "proxy-from-env": "^1.0.0", - "rimraf": "^3.0.2", - "tar-fs": "^2.0.0", - "unbzip2-stream": "^1.3.3", - "ws": "^7.2.3" - }, - "engines": { - "node": ">=10.18.1" - } - }, - "node_modules/puppeteer-extra": { - "version": "3.1.17", - "resolved": "https://registry.npmjs.org/puppeteer-extra/-/puppeteer-extra-3.1.17.tgz", - "integrity": "sha512-KkrIEZGuQ1uqRK9wo0hIGEspGPlYHQIr31MQcbVy4l3RBCICdNbGpKH5TIyvTwSuuqjjGl62gFq5Naa51OpYsA==", - "dependencies": { - "@types/debug": "^4.1.0", - "@types/puppeteer": "*", - "debug": "^4.1.1", - "deepmerge": "^4.2.2" - }, - "engines": { - "node": ">=8" - }, - "peerDependencies": { - "puppeteer": "*" - } - }, - "node_modules/puppeteer-extra-plugin": { - "version": "3.1.8", - "resolved": "https://registry.npmjs.org/puppeteer-extra-plugin/-/puppeteer-extra-plugin-3.1.8.tgz", - "integrity": "sha512-bTKhY0q+T3qM59fcdKnxwlT+KA1XpKKb8vUxFtd7PH/TGA04AOO+WQJx9npU1nA4NXZKU2xs2KZNn/A+1Cachw==", - "dependencies": { - "@types/debug": "^4.1.0", - "debug": "^4.1.1", - "merge-deep": "^3.0.1" - }, - "engines": { - "node": ">=9.11.2" - }, - "peerDependencies": { - "puppeteer-extra": "*" - } - }, - "node_modules/puppeteer-extra-plugin-stealth": { - "version": "2.7.5", - "resolved": "https://registry.npmjs.org/puppeteer-extra-plugin-stealth/-/puppeteer-extra-plugin-stealth-2.7.5.tgz", - "integrity": "sha512-4LR5SRw7zlW+qSokvXJsjdQoDDvDlZsQ9QR1pD01mwxDAFAeJ3dCBvTBt33ppm//tesLCCBxPr78s2HyBIVp4A==", - "dependencies": { - "debug": "^4.1.1", - "puppeteer-extra-plugin": "^3.1.8", - "puppeteer-extra-plugin-user-preferences": "^2.2.11" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/puppeteer-extra-plugin-user-data-dir": { - "version": "2.2.11", - "resolved": "https://registry.npmjs.org/puppeteer-extra-plugin-user-data-dir/-/puppeteer-extra-plugin-user-data-dir-2.2.11.tgz", - "integrity": "sha512-jng9rTY0qE8HJId/oAjs+RVNxgeQKDnoBsQPaQtL/FbkvD9C/7RlKSmz7IyjhafilzSZcA4fB7jFJX9rrN9Bdg==", - "dependencies": { - "debug": "^4.1.1", - "fs-extra": "^8.1.0", - "puppeteer-extra-plugin": "^3.1.8" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/puppeteer-extra-plugin-user-preferences": { - "version": "2.2.11", - "resolved": "https://registry.npmjs.org/puppeteer-extra-plugin-user-preferences/-/puppeteer-extra-plugin-user-preferences-2.2.11.tgz", - "integrity": "sha512-lvqd2R7N35/8ldqgty1TUmzmu3VlhunEaEABGm4bUglEXUxGHQgRheP+U8BmWIM2GCGjNoJCSu3nqGJ56ZsSRg==", - "dependencies": { - "debug": "^4.1.1", - "deepmerge": "^4.2.2", - "puppeteer-extra-plugin": "^3.1.8", - "puppeteer-extra-plugin-user-data-dir": "^2.2.11" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/puppeteer/node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/qrcode": { "version": "1.4.4", "resolved": "https://registry.npmjs.org/qrcode/-/qrcode-1.4.4.tgz", @@ -2799,12 +3003,15 @@ "optional": true }, "node_modules/regexpp": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-2.0.1.tgz", - "integrity": "sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.1.0.tgz", + "integrity": "sha512-ZOIzd8yVsQQA7j8GCSlPGXwg5PfmA1mrq0JP4nGhh54LaKN3xdai/vHUDu74pKwV8OxseMS65u2NImosQcSD0Q==", "dev": true, "engines": { - "node": ">=6.5.0" + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" } }, "node_modules/require_optional": { @@ -2834,6 +3041,15 @@ "node": ">=0.10.0" } }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/require-main-filename": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", @@ -2848,50 +3064,19 @@ "node": ">=4" } }, - "node_modules/restore-cursor": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", - "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=", - "dev": true, - "dependencies": { - "onetime": "^2.0.0", - "signal-exit": "^3.0.2" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/rimraf": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", - "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", "dev": true, "dependencies": { "glob": "^7.1.3" }, "bin": { "rimraf": "bin.js" - } - }, - "node_modules/run-async": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz", - "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==", - "dev": true, - "engines": { - "node": ">=0.12.0" - } - }, - "node_modules/rxjs": { - "version": "6.6.6", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.6.tgz", - "integrity": "sha512-/oTwee4N4iWzAMAL9xdGKjkEHmIwupR3oXbQjCKywF1BeFohswF3vZdogbmEF6pZkOsXTzWkrZszrWpQTByYVg==", - "dev": true, - "dependencies": { - "tslib": "^1.9.0" }, - "engines": { - "npm": ">=2.0.0" + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, "node_modules/safe-buffer": { @@ -2948,44 +3133,6 @@ "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==" }, - "node_modules/shallow-clone": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-0.1.2.tgz", - "integrity": "sha1-WQnodLp3EG1zrEFM/sH/yofZcGA=", - "dependencies": { - "is-extendable": "^0.1.1", - "kind-of": "^2.0.1", - "lazy-cache": "^0.2.3", - "mixin-object": "^2.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/shallow-clone/node_modules/is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" - }, - "node_modules/shallow-clone/node_modules/kind-of": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-2.0.1.tgz", - "integrity": "sha1-AY7HpM5+OobLkUG+UZ0kyPqpgbU=", - "dependencies": { - "is-buffer": "^1.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/shallow-clone/node_modules/lazy-cache": { - "version": "0.2.7", - "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-0.2.7.tgz", - "integrity": "sha1-f+3fLctu23fRHvHRF6tf/fCrG2U=", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/sharp": { "version": "0.26.3", "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.26.3.tgz", @@ -3025,24 +3172,24 @@ } }, "node_modules/shebang-command": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", "dev": true, "dependencies": { - "shebang-regex": "^1.0.0" + "shebang-regex": "^3.0.0" }, "engines": { - "node": ">=0.10.0" + "node": ">=8" } }, "node_modules/shebang-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", "dev": true, "engines": { - "node": ">=0.10.0" + "node": ">=8" } }, "node_modules/sift": { @@ -3108,34 +3255,70 @@ } }, "node_modules/slice-ansi": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz", - "integrity": "sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", + "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", "dev": true, "dependencies": { - "ansi-styles": "^3.2.0", - "astral-regex": "^1.0.0", - "is-fullwidth-code-point": "^2.0.0" + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" }, "engines": { - "node": ">=6" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/slice-ansi?sponsor=1" } }, - "node_modules/slice-ansi/node_modules/is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "node_modules/slice-ansi/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, "engines": { - "node": ">=4" + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, + "node_modules/slice-ansi/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/slice-ansi/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, "node_modules/sliced": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/sliced/-/sliced-1.0.1.tgz", "integrity": "sha1-CzpmK10Ewxd7GSa+qCsD+Dei70E=", "optional": true }, + "node_modules/source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/sparse-bitfield": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/sparse-bitfield/-/sparse-bitfield-3.0.3.tgz", @@ -3174,14 +3357,6 @@ "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", "dev": true }, - "node_modules/stack-trace": { - "version": "0.0.10", - "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz", - "integrity": "sha1-VHxws0fo0ytOEI6hoqFZ5f3eGcA=", - "engines": { - "node": "*" - } - }, "node_modules/statuses": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", @@ -3280,7 +3455,6 @@ "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, "dependencies": { "has-flag": "^3.0.0" }, @@ -3289,70 +3463,47 @@ } }, "node_modules/table": { - "version": "5.4.6", - "resolved": "https://registry.npmjs.org/table/-/table-5.4.6.tgz", - "integrity": "sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug==", + "version": "6.0.9", + "resolved": "https://registry.npmjs.org/table/-/table-6.0.9.tgz", + "integrity": "sha512-F3cLs9a3hL1Z7N4+EkSscsel3z55XT950AvB05bwayrNg5T1/gykXtigioTAjbltvbMSJvvhFCbnf6mX+ntnJQ==", "dev": true, "dependencies": { - "ajv": "^6.10.2", - "lodash": "^4.17.14", - "slice-ansi": "^2.1.0", - "string-width": "^3.0.0" + "ajv": "^8.0.1", + "is-boolean-object": "^1.1.0", + "is-number-object": "^1.0.4", + "is-string": "^1.0.5", + "lodash.clonedeep": "^4.5.0", + "lodash.flatten": "^4.4.0", + "lodash.truncate": "^4.4.2", + "slice-ansi": "^4.0.0", + "string-width": "^4.2.0" }, "engines": { - "node": ">=6.0.0" + "node": ">=10.0.0" } }, - "node_modules/table/node_modules/ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "node_modules/table/node_modules/ajv": { + "version": "8.0.3", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.0.3.tgz", + "integrity": "sha512-Df6NAivu9KpZw+q8ySijAgLvr1mUA5ihkRvCLCxpdYR21ann5yIuN+PpFxmweSj7i3yjJ0x5LN5KVs0RRzskAQ==", "dev": true, - "engines": { - "node": ">=6" + "dependencies": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" } }, - "node_modules/table/node_modules/emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "node_modules/table/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", "dev": true }, - "node_modules/table/node_modules/is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/table/node_modules/string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "dependencies": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/table/node_modules/strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "dependencies": { - "ansi-regex": "^4.1.0" - }, - "engines": { - "node": ">=6" - } - }, "node_modules/tar-fs": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz", @@ -3402,32 +3553,72 @@ "node": ">= 6" } }, - "node_modules/text-hex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/text-hex/-/text-hex-1.0.0.tgz", - "integrity": "sha512-uuVGNWzgJ4yhRaNSiubPY7OjISw4sw4E5Uv0wbjp+OzcbmVU/rsT8ujgcXJhn9ypzsgr5vlzpPqP+MBBKcGvbg==" - }, "node_modules/text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", "dev": true }, - "node_modules/through": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" - }, - "node_modules/tmp": { - "version": "0.0.33", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", - "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", - "dev": true, - "dependencies": { - "os-tmpdir": "~1.0.2" - }, + "node_modules/time-stamp": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/time-stamp/-/time-stamp-1.1.0.tgz", + "integrity": "sha1-dkpaEa9QVhkhsTPztE5hhofg9cM=", "engines": { - "node": ">=0.6.0" + "node": ">=0.10.0" + } + }, + "node_modules/title-case-minors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/title-case-minors/-/title-case-minors-1.0.0.tgz", + "integrity": "sha1-UfFwN8KUdHodHNpCS1AEyG2OsRU=" + }, + "node_modules/to-capital-case": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/to-capital-case/-/to-capital-case-1.0.0.tgz", + "integrity": "sha1-pXxQFP1aNyF88FCZ/4pCG7+cm38=", + "dependencies": { + "to-space-case": "^1.0.0" + } + }, + "node_modules/to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/to-no-case": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/to-no-case/-/to-no-case-1.0.2.tgz", + "integrity": "sha1-xyKQcWTvaxeBMsjmmTAhLRtKoWo=" + }, + "node_modules/to-sentence-case": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/to-sentence-case/-/to-sentence-case-1.0.0.tgz", + "integrity": "sha1-xIO/NkdzflxzjvcAb+Ng1fmcVy4=", + "dependencies": { + "to-no-case": "^1.0.0" + } + }, + "node_modules/to-space-case": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/to-space-case/-/to-space-case-1.0.0.tgz", + "integrity": "sha1-sFLar7Gysp3HcM6gFj5ewOvJ/Bc=", + "dependencies": { + "to-no-case": "^1.0.0" + } + }, + "node_modules/to-title-case": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/to-title-case/-/to-title-case-1.0.0.tgz", + "integrity": "sha1-rKiPidYGTeUBCKl86g20SCfoAGE=", + "dependencies": { + "escape-regexp-component": "^1.0.2", + "title-case-minors": "^1.0.0", + "to-capital-case": "^1.0.0", + "to-sentence-case": "^1.0.0" } }, "node_modules/toidentifier": { @@ -3463,17 +3654,6 @@ "typescript": "^4.2.3" } }, - "node_modules/triple-beam": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/triple-beam/-/triple-beam-1.3.0.tgz", - "integrity": "sha512-XrHUvV5HpdLmIj4uVMxHggLbFSZYIn7HEWsqePZcI50pco+MPqJ50wMGY794X7AOOhxOBAjbkqfAbEe/QMp2Lw==" - }, - "node_modules/tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", - "dev": true - }, "node_modules/tunnel-agent": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", @@ -3492,17 +3672,26 @@ "optional": true }, "node_modules/type-check": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", - "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", "dev": true, "dependencies": { - "prelude-ls": "~1.1.2" + "prelude-ls": "^1.2.1" }, "engines": { "node": ">= 0.8.0" } }, + "node_modules/type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/typedarray-to-buffer": { "version": "3.1.5", "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", @@ -3523,23 +3712,6 @@ "node": ">=4.2.0" } }, - "node_modules/unbzip2-stream": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/unbzip2-stream/-/unbzip2-stream-1.4.3.tgz", - "integrity": "sha512-mlExGW4w71ebDJviH16lQLtZS32VKqsSfk80GCfUlwT/4/hNRFsoscrF/c++9xinkMzECL1uL9DDwXqFWkruPg==", - "dependencies": { - "buffer": "^5.2.1", - "through": "^2.3.8" - } - }, - "node_modules/universalify": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", - "engines": { - "node": ">= 4.0.0" - } - }, "node_modules/unpipe": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", @@ -3571,16 +3743,25 @@ "uuid": "dist/bin/uuid" } }, + "node_modules/v8-compile-cache": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", + "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", + "dev": true + }, "node_modules/which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", "dev": true, "dependencies": { "isexe": "^2.0.0" }, "bin": { - "which": "bin/which" + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" } }, "node_modules/which-module": { @@ -3621,50 +3802,6 @@ "node": ">=4" } }, - "node_modules/winston": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/winston/-/winston-3.3.3.tgz", - "integrity": "sha512-oEXTISQnC8VlSAKf1KYSSd7J6IWuRPQqDdo8eoRNaYKLvwSb5+79Z3Yi1lrl6KDpU6/VWaxpakDAtb1oQ4n9aw==", - "dependencies": { - "@dabh/diagnostics": "^2.0.2", - "async": "^3.1.0", - "is-stream": "^2.0.0", - "logform": "^2.2.0", - "one-time": "^1.0.0", - "readable-stream": "^3.4.0", - "stack-trace": "0.0.x", - "triple-beam": "^1.3.0", - "winston-transport": "^4.4.0" - }, - "engines": { - "node": ">= 6.4.0" - } - }, - "node_modules/winston-transport": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/winston-transport/-/winston-transport-4.4.0.tgz", - "integrity": "sha512-Lc7/p3GtqtqPBYYtS6KCN3c77/2QCev51DvcJKbkFPQNoj1sinkGwLGFDxkXY9J6p9+EPnYs+D90uwbnaiURTw==", - "dependencies": { - "readable-stream": "^2.3.7", - "triple-beam": "^1.2.0" - }, - "engines": { - "node": ">= 6.4.0" - } - }, - "node_modules/winston/node_modules/readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, "node_modules/word-wrap": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", @@ -3737,18 +3874,6 @@ "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" }, - "node_modules/write": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/write/-/write-1.0.3.tgz", - "integrity": "sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig==", - "dev": true, - "dependencies": { - "mkdirp": "^0.5.1" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/ws": { "version": "7.4.3", "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.3.tgz", @@ -3901,15 +4026,6 @@ "node": ">=6" } }, - "node_modules/yauzl": { - "version": "2.10.0", - "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", - "integrity": "sha1-x+sXyT4RLLEIb6bY5R+wZnt5pfk=", - "dependencies": { - "buffer-crc32": "~0.2.3", - "fd-slicer": "~1.1.0" - } - }, "node_modules/zlib-sync": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/zlib-sync/-/zlib-sync-0.1.7.tgz", @@ -3931,12 +4047,247 @@ "@babel/highlight": "^7.12.13" } }, + "@babel/compat-data": { + "version": "7.13.12", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.13.12.tgz", + "integrity": "sha512-3eJJ841uKxeV8dcN/2yGEUy+RfgQspPEgQat85umsE1rotuquQ2AbIub4S6j7c50a2d+4myc+zSlnXeIHrOnhQ==", + "dev": true, + "peer": true + }, + "@babel/core": { + "version": "7.13.14", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.13.14.tgz", + "integrity": "sha512-wZso/vyF4ki0l0znlgM4inxbdrUvCb+cVz8grxDq+6C9k6qbqoIJteQOKicaKjCipU3ISV+XedCqpL2RJJVehA==", + "dev": true, + "peer": true, + "requires": { + "@babel/code-frame": "^7.12.13", + "@babel/generator": "^7.13.9", + "@babel/helper-compilation-targets": "^7.13.13", + "@babel/helper-module-transforms": "^7.13.14", + "@babel/helpers": "^7.13.10", + "@babel/parser": "^7.13.13", + "@babel/template": "^7.12.13", + "@babel/traverse": "^7.13.13", + "@babel/types": "^7.13.14", + "convert-source-map": "^1.7.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.1.2", + "semver": "^6.3.0", + "source-map": "^0.5.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true, + "peer": true + } + } + }, + "@babel/eslint-parser": { + "version": "7.13.14", + "resolved": "https://registry.npmjs.org/@babel/eslint-parser/-/eslint-parser-7.13.14.tgz", + "integrity": "sha512-I0HweR36D73Ibn/FfrRDMKlMqJHFwidIUgYdMpH+aXYuQC+waq59YaJ6t9e9N36axJ82v1jR041wwqDrDXEwRA==", + "dev": true, + "requires": { + "eslint-scope": "^5.1.0", + "eslint-visitor-keys": "^1.3.0", + "semver": "^6.3.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } + } + }, + "@babel/eslint-plugin": { + "version": "7.13.10", + "resolved": "https://registry.npmjs.org/@babel/eslint-plugin/-/eslint-plugin-7.13.10.tgz", + "integrity": "sha512-xsNxo099fKnJ2rArkuuMOTPxxTLZSXwbFXdH4GjqQRKTOr6S1odQlE+R3Leid56VFQ3KVAR295vVNG9fqNQVvQ==", + "dev": true, + "requires": { + "eslint-rule-composer": "^0.3.0" + } + }, + "@babel/generator": { + "version": "7.13.9", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.13.9.tgz", + "integrity": "sha512-mHOOmY0Axl/JCTkxTU6Lf5sWOg/v8nUa+Xkt4zMTftX0wqmb6Sh7J8gvcehBw7q0AhrhAR+FDacKjCZ2X8K+Sw==", + "dev": true, + "requires": { + "@babel/types": "^7.13.0", + "jsesc": "^2.5.1", + "source-map": "^0.5.0" + } + }, + "@babel/helper-compilation-targets": { + "version": "7.13.13", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.13.13.tgz", + "integrity": "sha512-q1kcdHNZehBwD9jYPh3WyXcsFERi39X4I59I3NadciWtNDyZ6x+GboOxncFK0kXlKIv6BJm5acncehXWUjWQMQ==", + "dev": true, + "peer": true, + "requires": { + "@babel/compat-data": "^7.13.12", + "@babel/helper-validator-option": "^7.12.17", + "browserslist": "^4.14.5", + "semver": "^6.3.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true, + "peer": true + } + } + }, + "@babel/helper-create-class-features-plugin": { + "version": "7.13.11", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.13.11.tgz", + "integrity": "sha512-ays0I7XYq9xbjCSvT+EvysLgfc3tOkwCULHjrnscGT3A9qD4sk3wXnJ3of0MAWsWGjdinFvajHU2smYuqXKMrw==", + "dev": true, + "requires": { + "@babel/helper-function-name": "^7.12.13", + "@babel/helper-member-expression-to-functions": "^7.13.0", + "@babel/helper-optimise-call-expression": "^7.12.13", + "@babel/helper-replace-supers": "^7.13.0", + "@babel/helper-split-export-declaration": "^7.12.13" + } + }, + "@babel/helper-function-name": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.12.13.tgz", + "integrity": "sha512-TZvmPn0UOqmvi5G4vvw0qZTpVptGkB1GL61R6lKvrSdIxGm5Pky7Q3fpKiIkQCAtRCBUwB0PaThlx9vebCDSwA==", + "dev": true, + "requires": { + "@babel/helper-get-function-arity": "^7.12.13", + "@babel/template": "^7.12.13", + "@babel/types": "^7.12.13" + } + }, + "@babel/helper-get-function-arity": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.12.13.tgz", + "integrity": "sha512-DjEVzQNz5LICkzN0REdpD5prGoidvbdYk1BVgRUOINaWJP2t6avB27X1guXK1kXNrX0WMfsrm1A/ZBthYuIMQg==", + "dev": true, + "requires": { + "@babel/types": "^7.12.13" + } + }, + "@babel/helper-member-expression-to-functions": { + "version": "7.13.12", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.13.12.tgz", + "integrity": "sha512-48ql1CLL59aKbU94Y88Xgb2VFy7a95ykGRbJJaaVv+LX5U8wFpLfiGXJJGUozsmA1oEh/o5Bp60Voq7ACyA/Sw==", + "dev": true, + "requires": { + "@babel/types": "^7.13.12" + } + }, + "@babel/helper-module-imports": { + "version": "7.13.12", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.13.12.tgz", + "integrity": "sha512-4cVvR2/1B693IuOvSI20xqqa/+bl7lqAMR59R4iu39R9aOX8/JoYY1sFaNvUMyMBGnHdwvJgUrzNLoUZxXypxA==", + "dev": true, + "peer": true, + "requires": { + "@babel/types": "^7.13.12" + } + }, + "@babel/helper-module-transforms": { + "version": "7.13.14", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.13.14.tgz", + "integrity": "sha512-QuU/OJ0iAOSIatyVZmfqB0lbkVP0kDRiKj34xy+QNsnVZi/PA6BoSoreeqnxxa9EHFAIL0R9XOaAR/G9WlIy5g==", + "dev": true, + "peer": true, + "requires": { + "@babel/helper-module-imports": "^7.13.12", + "@babel/helper-replace-supers": "^7.13.12", + "@babel/helper-simple-access": "^7.13.12", + "@babel/helper-split-export-declaration": "^7.12.13", + "@babel/helper-validator-identifier": "^7.12.11", + "@babel/template": "^7.12.13", + "@babel/traverse": "^7.13.13", + "@babel/types": "^7.13.14" + } + }, + "@babel/helper-optimise-call-expression": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.12.13.tgz", + "integrity": "sha512-BdWQhoVJkp6nVjB7nkFWcn43dkprYauqtk++Py2eaf/GRDFm5BxRqEIZCiHlZUGAVmtwKcsVL1dC68WmzeFmiA==", + "dev": true, + "requires": { + "@babel/types": "^7.12.13" + } + }, + "@babel/helper-plugin-utils": { + "version": "7.13.0", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.13.0.tgz", + "integrity": "sha512-ZPafIPSwzUlAoWT8DKs1W2VyF2gOWthGd5NGFMsBcMMol+ZhK+EQY/e6V96poa6PA/Bh+C9plWN0hXO1uB8AfQ==", + "dev": true + }, + "@babel/helper-replace-supers": { + "version": "7.13.12", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.13.12.tgz", + "integrity": "sha512-Gz1eiX+4yDO8mT+heB94aLVNCL+rbuT2xy4YfyNqu8F+OI6vMvJK891qGBTqL9Uc8wxEvRW92Id6G7sDen3fFw==", + "dev": true, + "requires": { + "@babel/helper-member-expression-to-functions": "^7.13.12", + "@babel/helper-optimise-call-expression": "^7.12.13", + "@babel/traverse": "^7.13.0", + "@babel/types": "^7.13.12" + } + }, + "@babel/helper-simple-access": { + "version": "7.13.12", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.13.12.tgz", + "integrity": "sha512-7FEjbrx5SL9cWvXioDbnlYTppcZGuCY6ow3/D5vMggb2Ywgu4dMrpTJX0JdQAIcRRUElOIxF3yEooa9gUb9ZbA==", + "dev": true, + "peer": true, + "requires": { + "@babel/types": "^7.13.12" + } + }, + "@babel/helper-split-export-declaration": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.12.13.tgz", + "integrity": "sha512-tCJDltF83htUtXx5NLcaDqRmknv652ZWCHyoTETf1CXYJdPC7nohZohjUgieXhv0hTJdRf2FjDueFehdNucpzg==", + "dev": true, + "requires": { + "@babel/types": "^7.12.13" + } + }, "@babel/helper-validator-identifier": { "version": "7.12.11", "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz", "integrity": "sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw==", "dev": true }, + "@babel/helper-validator-option": { + "version": "7.12.17", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.12.17.tgz", + "integrity": "sha512-TopkMDmLzq8ngChwRlyjR6raKD6gMSae4JdYDB8bByKreQgG0RBTuKe9LRxW3wFtUnjxOPRKBDwEH6Mg5KeDfw==", + "dev": true, + "peer": true + }, + "@babel/helpers": { + "version": "7.13.10", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.13.10.tgz", + "integrity": "sha512-4VO883+MWPDUVRF3PhiLBUFHoX/bsLTGFpFK/HqvvfBZz2D57u9XzPVNFVBTc0PW/CWR9BXTOKt8NF4DInUHcQ==", + "dev": true, + "peer": true, + "requires": { + "@babel/template": "^7.12.13", + "@babel/traverse": "^7.13.0", + "@babel/types": "^7.13.0" + } + }, "@babel/highlight": { "version": "7.13.8", "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.13.8.tgz", @@ -3948,14 +4299,92 @@ "js-tokens": "^4.0.0" } }, - "@dabh/diagnostics": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@dabh/diagnostics/-/diagnostics-2.0.2.tgz", - "integrity": "sha512-+A1YivoVDNNVCdfozHSR8v/jyuuLTMXwjWuxPFlFlUapXoGc+Gj9mDlTDDfrwl7rXCl2tNZ0kE8sIBO6YOn96Q==", + "@babel/parser": { + "version": "7.13.13", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.13.13.tgz", + "integrity": "sha512-OhsyMrqygfk5v8HmWwOzlYjJrtLaFhF34MrfG/Z73DgYCI6ojNUTUp2TYbtnjo8PegeJp12eamsNettCQjKjVw==", + "dev": true + }, + "@babel/plugin-proposal-class-properties": { + "version": "7.13.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.13.0.tgz", + "integrity": "sha512-KnTDjFNC1g+45ka0myZNvSBFLhNCLN+GeGYLDEA8Oq7MZ6yMgfLoIRh86GRT0FjtJhZw8JyUskP9uvj5pHM9Zg==", + "dev": true, "requires": { - "colorspace": "1.1.x", - "enabled": "2.0.x", - "kuler": "^2.0.0" + "@babel/helper-create-class-features-plugin": "^7.13.0", + "@babel/helper-plugin-utils": "^7.13.0" + } + }, + "@babel/template": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.12.13.tgz", + "integrity": "sha512-/7xxiGA57xMo/P2GVvdEumr8ONhFOhfgq2ihK3h1e6THqzTAkHbkXgB0xI9yeTfIUoH3+oAeHhqm/I43OTbbjA==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.12.13", + "@babel/parser": "^7.12.13", + "@babel/types": "^7.12.13" + } + }, + "@babel/traverse": { + "version": "7.13.13", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.13.13.tgz", + "integrity": "sha512-CblEcwmXKR6eP43oQGG++0QMTtCjAsa3frUuzHoiIJWpaIIi8dwMyEFUJoXRLxagGqCK+jALRwIO+o3R9p/uUg==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.12.13", + "@babel/generator": "^7.13.9", + "@babel/helper-function-name": "^7.12.13", + "@babel/helper-split-export-declaration": "^7.12.13", + "@babel/parser": "^7.13.13", + "@babel/types": "^7.13.13", + "debug": "^4.1.0", + "globals": "^11.1.0" + } + }, + "@babel/types": { + "version": "7.13.14", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.13.14.tgz", + "integrity": "sha512-A2aa3QTkWoyqsZZFl56MLUsfmh7O0gN41IPvXAE/++8ojpbz12SszD7JEGYVdn4f9Kt4amIei07swF1h4AqmmQ==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.12.11", + "lodash": "^4.17.19", + "to-fast-properties": "^2.0.0" + } + }, + "@eslint/eslintrc": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.0.tgz", + "integrity": "sha512-2ZPCc+uNbjV5ERJr+aKSPRwZgKd2z11x0EgLvb1PURmUrn9QNRXFqje0Ldq454PfAVyaJYyrDvvIKSFP4NnBog==", + "dev": true, + "requires": { + "ajv": "^6.12.4", + "debug": "^4.1.1", + "espree": "^7.3.0", + "globals": "^12.1.0", + "ignore": "^4.0.6", + "import-fresh": "^3.2.1", + "js-yaml": "^3.13.1", + "minimatch": "^3.0.4", + "strip-json-comments": "^3.1.1" + }, + "dependencies": { + "globals": { + "version": "12.4.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-12.4.0.tgz", + "integrity": "sha512-BWICuzzDvDoH54NHKCseDanAhE3CeDorgDL5MT6LMXXj2WCnd9UC2szdk4AWLfjdgNBCXLUanXYcpBBKOSWGwg==", + "dev": true, + "requires": { + "type-fest": "^0.8.1" + } + }, + "strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true + } } }, "@tokenizer/token": { @@ -4001,14 +4430,6 @@ "resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.31.tgz", "integrity": "sha512-vFHy/ezP5qI0rFgJ7aQnjDXwAMrG0KqqIH7tQG5PPv3BWBayOPIQNBjVc/P6hhdZfMx51REc6tfDNXHUio893g==" }, - "@types/puppeteer": { - "version": "5.4.3", - "resolved": "https://registry.npmjs.org/@types/puppeteer/-/puppeteer-5.4.3.tgz", - "integrity": "sha512-3nE8YgR9DIsgttLW+eJf6mnXxq8Ge+27m5SU3knWmrlfl6+KOG0Bf9f7Ua7K+C4BnaTMAh3/UpySqdAYvrsvjg==", - "requires": { - "@types/node": "*" - } - }, "@types/readable-stream": { "version": "2.3.9", "resolved": "https://registry.npmjs.org/@types/readable-stream/-/readable-stream-2.3.9.tgz", @@ -4018,27 +4439,10 @@ "safe-buffer": "*" } }, - "@types/yauzl": { - "version": "2.9.1", - "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.9.1.tgz", - "integrity": "sha512-A1b8SU4D10uoPjwb0lnHmmu8wZhR9d+9o2PKBQT2jU5YPTKsxac6M2qGAdY7VcL+dHHhARVUDmeg0rOrcd9EjA==", - "optional": true, - "requires": { - "@types/node": "*" - } - }, - "abort-controller": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", - "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", - "requires": { - "event-target-shim": "^5.0.0" - } - }, "acorn": { - "version": "6.4.2", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.2.tgz", - "integrity": "sha512-XtGIhXwF8YM8bJhGxG5kXgjkEuNGLTkoYqVE+KMR+aspr4KGYmKYg7yUe3KghyQ9yheNwLnjmzh/7+gfDBmHCQ==", + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", + "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", "dev": true }, "acorn-jsx": { @@ -4048,11 +4452,6 @@ "dev": true, "requires": {} }, - "agent-base": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-5.1.1.tgz", - "integrity": "sha512-TMeqbNl2fMW0nMjTEPOwe3J/PRFP4vqeoNuQMG0HlMrtm5QxKqdvAkZ1pRBQ/ulIyDD5Yq0nJ7YbdD8ey0TO3g==" - }, "ajv": { "version": "6.12.6", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", @@ -4065,12 +4464,20 @@ "uri-js": "^4.2.2" } }, - "ansi-escapes": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.2.0.tgz", - "integrity": "sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==", + "ansi-colors": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", + "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", "dev": true }, + "ansi-gray": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/ansi-gray/-/ansi-gray-0.1.1.tgz", + "integrity": "sha1-KWLPVOyXksSFEKPetSRDaGHvclE=", + "requires": { + "ansi-wrap": "0.1.0" + } + }, "ansi-regex": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", @@ -4084,6 +4491,11 @@ "color-convert": "^1.9.0" } }, + "ansi-wrap": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/ansi-wrap/-/ansi-wrap-0.1.0.tgz", + "integrity": "sha1-qCJQ3bABXponyoLoLqYDu/pF768=" + }, "aproba": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", @@ -4107,26 +4519,26 @@ "sprintf-js": "~1.0.2" } }, - "arr-union": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", - "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=" - }, "array-flatten": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-3.0.0.tgz", "integrity": "sha512-zPMVc3ZYlGLNk4mpK1NzP2wg0ml9t7fUgDsayR5Y5rSzxQilzR9FGu/EH2jQOcKSAeAfWeylyW8juy3OkWRvNA==" }, - "astral-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz", - "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==", - "dev": true + "asciiart-logo": { + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/asciiart-logo/-/asciiart-logo-0.2.6.tgz", + "integrity": "sha512-qAGPI1Y984SMiONbZ1gI3YdG1bm+mmCj2AklusFqYVVCikPo3jss7IlcZkt+FoRInaomrMn0OQtPaKkt90NApg==", + "requires": { + "chalk": "^2.4.2", + "figlet": "^1.2.0", + "to-title-case": "^1.0.0" + } }, - "async": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/async/-/async-3.2.0.tgz", - "integrity": "sha512-TR2mEZFVOj2pLStYxLht7TyfuRzaydfpxr3k9RpHIzMgw7A64dzsdqCxH1WJyQdoe8T10nDXd9wnEigmiuHIZw==" + "astral-regex": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", + "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", + "dev": true }, "axios": { "version": "0.18.1", @@ -4140,7 +4552,8 @@ "balanced-match": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "dev": true }, "base64-js": { "version": "1.5.1", @@ -4176,11 +4589,26 @@ "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, + "browserslist": { + "version": "4.16.3", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.16.3.tgz", + "integrity": "sha512-vIyhWmIkULaq04Gt93txdh+j02yX/JzlyhLYbV3YQCn/zvES3JnY7TifHHvvr1w5hTDluNKMkV05cs4vy8Q7sw==", + "dev": true, + "peer": true, + "requires": { + "caniuse-lite": "^1.0.30001181", + "colorette": "^1.2.1", + "electron-to-chromium": "^1.3.649", + "escalade": "^3.1.1", + "node-releases": "^1.1.70" + } + }, "bson": { "version": "1.1.5", "resolved": "https://registry.npmjs.org/bson/-/bson-1.1.5.tgz", @@ -4210,11 +4638,6 @@ "resolved": "https://registry.npmjs.org/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz", "integrity": "sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg==" }, - "buffer-crc32": { - "version": "0.2.13", - "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", - "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=" - }, "buffer-fill": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/buffer-fill/-/buffer-fill-1.0.0.tgz", @@ -4245,6 +4668,16 @@ "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==" }, + "call-bind": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", + "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "dev": true, + "requires": { + "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.2" + } + }, "callsites": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", @@ -4256,43 +4689,28 @@ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==" }, + "caniuse-lite": { + "version": "1.0.30001205", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001205.tgz", + "integrity": "sha512-TL1GrS5V6LElbitPazidkBMD9sa448bQDDLrumDqaggmKFcuU2JW1wTOHJPukAcOMtEmLcmDJEzfRrf+GjM0Og==", + "dev": true, + "peer": true + }, "chalk": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, "requires": { "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", "supports-color": "^5.3.0" } }, - "chardet": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", - "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", - "dev": true - }, "chownr": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==" }, - "cli-cursor": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", - "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=", - "dev": true, - "requires": { - "restore-cursor": "^2.0.0" - } - }, - "cli-width": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.1.tgz", - "integrity": "sha512-GRMWDxpOB6Dgk2E5Uo+3eEBvtOOlimMmpbFiKuLFnQzYDavtLFY3K5ona41jgN/WdRZtG7utuVSVTL4HbZHGkw==", - "dev": true - }, "cliui": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", @@ -4338,18 +4756,6 @@ } } }, - "clone-deep": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-0.2.4.tgz", - "integrity": "sha1-TnPdCen7lxzDhnDF3O2cGJZIHMY=", - "requires": { - "for-own": "^0.1.3", - "is-plain-object": "^2.0.1", - "kind-of": "^3.0.2", - "lazy-cache": "^1.0.3", - "shallow-clone": "^0.1.2" - } - }, "code-point-at": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", @@ -4386,41 +4792,53 @@ "simple-swizzle": "^0.2.2" } }, + "color-support": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz", + "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==" + }, + "colorette": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.2.2.tgz", + "integrity": "sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w==", + "dev": true, + "peer": true + }, "colors": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz", "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==" }, - "colorspace": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/colorspace/-/colorspace-1.1.2.tgz", - "integrity": "sha512-vt+OoIP2d76xLhjwbBaucYlNSpPsrJWPlBTtwCpQKIu6/CSMutyzX93O/Do0qzpH3YoHEes8YEFXyZ797rEhzQ==", - "requires": { - "color": "3.0.x", - "text-hex": "1.0.x" - }, - "dependencies": { - "color": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/color/-/color-3.0.0.tgz", - "integrity": "sha512-jCpd5+s0s0t7p3pHQKpnJ0TpQKKdleP71LWcA0aqiljpiuAkOSUFN/dyH8ZwF0hRmFlrIuRhufds1QyEP9EB+w==", - "requires": { - "color-convert": "^1.9.1", - "color-string": "^1.5.2" - } - } - } - }, "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true }, "console-control-strings": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=" }, + "convert-source-map": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz", + "integrity": "sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==", + "dev": true, + "peer": true, + "requires": { + "safe-buffer": "~5.1.1" + }, + "dependencies": { + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true, + "peer": true + } + } + }, "core-util-is": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", @@ -4435,22 +4853,26 @@ } }, "cross-spawn": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", - "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", "dev": true, "requires": { - "nice-try": "^1.0.4", - "path-key": "^2.0.1", - "semver": "^5.5.0", - "shebang-command": "^1.2.0", - "which": "^1.2.9" + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" } }, + "dayjs": { + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.10.4.tgz", + "integrity": "sha512-RI/Hh4kqRc1UKLOAf/T5zdMMX5DQIlDxwUe3wSyMMnEbGunnpENCdbUgM+dW7kXidZqCttBrmw7BhN4TMddkCw==" + }, "debug": { "version": "4.3.1", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "dev": true, "requires": { "ms": "2.1.2" } @@ -4479,11 +4901,6 @@ "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", "dev": true }, - "deepmerge": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz", - "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==" - }, "delegates": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", @@ -4505,11 +4922,6 @@ "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", "integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=" }, - "devtools-protocol": { - "version": "0.0.818844", - "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.818844.tgz", - "integrity": "sha512-AD1hi7iVJ8OD0aMLQU5VK0XH9LDlA1+BcPIgrAxPfaibx2DbWucuyOhc4oyQCbnvDDO68nN6/LcKfqTP343Jjg==" - }, "dijkstrajs": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/dijkstrajs/-/dijkstrajs-1.0.1.tgz", @@ -4537,16 +4949,18 @@ "axios": "^0.18.0" } }, + "electron-to-chromium": { + "version": "1.3.704", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.704.tgz", + "integrity": "sha512-6cz0jvawlUe4h5AbfQWxPzb+8LzVyswGAWiGc32EJEmfj39HTQyNPkLXirc7+L4x5I6RgRkzua8Ryu5QZqc8cA==", + "dev": true, + "peer": true + }, "emoji-regex": { "version": "9.2.2", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==" }, - "enabled": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/enabled/-/enabled-2.0.0.tgz", - "integrity": "sha512-AKrN98kuwOzMIdAizXGI86UFBoo26CL21UM763y1h/GMSJ4/OHU9k2YlsmBpyScFo/wbLzWQJBMCW4+IO3/+OQ==" - }, "end-of-stream": { "version": "1.4.4", "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", @@ -4555,15 +4969,54 @@ "once": "^1.4.0" } }, + "enquirer": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", + "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", + "dev": true, + "requires": { + "ansi-colors": "^4.1.1" + } + }, "eris": { - "version": "git+ssh://git@github.com/abalabahaha/eris.git#16c6a76275030dbd43635c8b89e68b74435dbe25", - "from": "eris@github:abalabahaha/eris#dev", + "version": "0.15.0", + "resolved": "https://registry.npmjs.org/eris/-/eris-0.15.0.tgz", + "integrity": "sha512-muBdi5XyMXdxFQ8xUG6yofq40/Z02CHlqJP7zIdHhpdDiHvFM/mybGiFAHuoSYcsVTTvEfbUaAJ+SDEmMjARYw==", "requires": { "opusscript": "^0.0.8", "tweetnacl": "^1.0.1", "ws": "^7.2.1" } }, + "eris-sharder": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/eris-sharder/-/eris-sharder-1.10.0.tgz", + "integrity": "sha512-cDazqx7KKM1tpMl2+UFlxwAG7fEnGBxssf/juayVR+If+nfuzUazm0nekRre8cbU4PZMjZmQPxWmDNlOcdFfAA==", + "requires": { + "asciiart-logo": "^0.2.6", + "colors": "^1.1.2", + "eris": "^0.13.1", + "fancy-log": "^1.3.0" + }, + "dependencies": { + "eris": { + "version": "0.13.4", + "resolved": "https://registry.npmjs.org/eris/-/eris-0.13.4.tgz", + "integrity": "sha512-IFA14nasCig8xp8cVCULvzBuJ0qpYqJ3XyEtm9OLdC177DYDCJ9QM2Aq+KOpejIVl7838n9AyRlLI6w9Eu3PiQ==", + "requires": { + "opusscript": "^0.0.7", + "tweetnacl": "^1.0.1", + "ws": "^7.2.1" + } + }, + "opusscript": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/opusscript/-/opusscript-0.0.7.tgz", + "integrity": "sha512-DcBadTdYTUuH9zQtepsLjQn4Ll6rs3dmeFvN+SD0ThPnxRBRm/WC1zXWPg+wgAJimB784gdZvUMA57gDP7FdVg==", + "optional": true + } + } + }, "erlpack": { "version": "git+ssh://git@github.com/abalabahaha/erlpack.git#5d0064f9e106841e1eead711a6451f99b0d289fd", "from": "erlpack@github:abalabahaha/erlpack", @@ -4573,76 +5026,199 @@ "nan": "^2.14.0" } }, + "escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "dev": true, + "peer": true + }, + "escape-regexp-component": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/escape-regexp-component/-/escape-regexp-component-1.0.2.tgz", + "integrity": "sha1-nGO20LJf8qiMOtvRjFthrMO5+qI=" + }, "escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "dev": true + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" }, "eslint": { - "version": "5.16.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-5.16.0.tgz", - "integrity": "sha512-S3Rz11i7c8AA5JPv7xAH+dOyq/Cu/VXHiHXBPOU1k/JAM5dXqQPt3qcrhpHSorXmrpu2g0gkIBVXAqCpzfoZIg==", + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.23.0.tgz", + "integrity": "sha512-kqvNVbdkjzpFy0XOszNwjkKzZ+6TcwCQ/h+ozlcIWwaimBBuhlQ4nN6kbiM2L+OjDcznkTJxzYfRFH92sx4a0Q==", "dev": true, "requires": { - "@babel/code-frame": "^7.0.0", - "ajv": "^6.9.1", - "chalk": "^2.1.0", - "cross-spawn": "^6.0.5", + "@babel/code-frame": "7.12.11", + "@eslint/eslintrc": "^0.4.0", + "ajv": "^6.10.0", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", "debug": "^4.0.1", "doctrine": "^3.0.0", - "eslint-scope": "^4.0.3", - "eslint-utils": "^1.3.1", - "eslint-visitor-keys": "^1.0.0", - "espree": "^5.0.1", - "esquery": "^1.0.1", + "enquirer": "^2.3.5", + "eslint-scope": "^5.1.1", + "eslint-utils": "^2.1.0", + "eslint-visitor-keys": "^2.0.0", + "espree": "^7.3.1", + "esquery": "^1.4.0", "esutils": "^2.0.2", - "file-entry-cache": "^5.0.1", + "file-entry-cache": "^6.0.1", "functional-red-black-tree": "^1.0.1", - "glob": "^7.1.2", - "globals": "^11.7.0", + "glob-parent": "^5.0.0", + "globals": "^13.6.0", "ignore": "^4.0.6", "import-fresh": "^3.0.0", "imurmurhash": "^0.1.4", - "inquirer": "^6.2.2", - "js-yaml": "^3.13.0", + "is-glob": "^4.0.0", + "js-yaml": "^3.13.1", "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.3.0", - "lodash": "^4.17.11", + "levn": "^0.4.1", + "lodash": "^4.17.21", "minimatch": "^3.0.4", - "mkdirp": "^0.5.1", "natural-compare": "^1.4.0", - "optionator": "^0.8.2", - "path-is-inside": "^1.0.2", + "optionator": "^0.9.1", "progress": "^2.0.0", - "regexpp": "^2.0.1", - "semver": "^5.5.1", - "strip-ansi": "^4.0.0", - "strip-json-comments": "^2.0.1", - "table": "^5.2.3", - "text-table": "^0.2.0" + "regexpp": "^3.1.0", + "semver": "^7.2.1", + "strip-ansi": "^6.0.0", + "strip-json-comments": "^3.1.0", + "table": "^6.0.4", + "text-table": "^0.2.0", + "v8-compile-cache": "^2.0.3" + }, + "dependencies": { + "@babel/code-frame": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", + "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", + "dev": true, + "requires": { + "@babel/highlight": "^7.10.4" + } + }, + "ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "dev": true + }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "eslint-visitor-keys": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.0.0.tgz", + "integrity": "sha512-QudtT6av5WXels9WjIM7qz1XD1cWGvX4gGXvp/zBn9nXG02D0utdU3Em2m/QjTnrsk6bBjmCygl3rmj118msQQ==", + "dev": true + }, + "globals": { + "version": "13.7.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.7.0.tgz", + "integrity": "sha512-Aipsz6ZKRxa/xQkZhNg0qIWXT6x6rD46f6x/PCnBomlttdIyAPak4YD9jTmKpZ72uROSMU87qJtcgpgHaVchiA==", + "dev": true, + "requires": { + "type-fest": "^0.20.2" + } + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + }, + "strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.0" + } + }, + "strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + }, + "type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true + } } }, - "eslint-plugin-promise": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-4.3.1.tgz", - "integrity": "sha512-bY2sGqyptzFBDLh/GMbAxfdJC+b0f23ME63FOE4+Jao0oZ3E1LEwFtWJX/1pGMJLiTtrSSern2CRM/g+dfc0eQ==", + "eslint-rule-composer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/eslint-rule-composer/-/eslint-rule-composer-0.3.0.tgz", + "integrity": "sha512-bt+Sh8CtDmn2OajxvNO+BX7Wn4CIWMpTRm3MaiKPCQcnnlm0CS2mhui6QaoeQugs+3Kj2ESKEEGJUdVafwhiCg==", "dev": true }, "eslint-scope": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.3.tgz", - "integrity": "sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg==", + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", "dev": true, "requires": { - "esrecurse": "^4.1.0", + "esrecurse": "^4.3.0", "estraverse": "^4.1.1" } }, "eslint-utils": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.4.3.tgz", - "integrity": "sha512-fbBN5W2xdY45KulGXmLHZ3c3FHfVYmKg0IrAKGOkT/464PQsx2UeIzfz1RmEci+KLm1bBaAzZAh8+/E+XAeZ8Q==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", + "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", "dev": true, "requires": { "eslint-visitor-keys": "^1.1.0" @@ -4655,14 +5231,14 @@ "dev": true }, "espree": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-5.0.1.tgz", - "integrity": "sha512-qWAZcWh4XE/RwzLJejfcofscgMc9CamR6Tn1+XRXNzrvUSSbiAjGOI/fggztjIi7y9VLPqnICMIPiGyr8JaZ0A==", + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.1.tgz", + "integrity": "sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g==", "dev": true, "requires": { - "acorn": "^6.0.7", - "acorn-jsx": "^5.0.0", - "eslint-visitor-keys": "^1.0.0" + "acorn": "^7.4.0", + "acorn-jsx": "^5.3.1", + "eslint-visitor-keys": "^1.3.0" } }, "esprima": { @@ -4717,36 +5293,20 @@ "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", "dev": true }, - "event-target-shim": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", - "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==" - }, "expand-template": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz", "integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==" }, - "external-editor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", - "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", - "dev": true, + "fancy-log": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/fancy-log/-/fancy-log-1.3.3.tgz", + "integrity": "sha512-k9oEhlyc0FrVh25qYuSELjr8oxsCoc4/LEZfg2iJJrfEk/tZL9bCoJE47gqAvI2m/AUjluCS4+3I0eTx8n3AEw==", "requires": { - "chardet": "^0.7.0", - "iconv-lite": "^0.4.24", - "tmp": "^0.0.33" - } - }, - "extract-zip": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz", - "integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==", - "requires": { - "@types/yauzl": "^2.9.1", - "debug": "^4.1.1", - "get-stream": "^5.1.0", - "yauzl": "^2.10.0" + "ansi-gray": "^0.1.1", + "color-support": "^1.1.3", + "parse-node-version": "^1.0.0", + "time-stamp": "^1.0.0" } }, "fast-deep-equal": { @@ -4767,40 +5327,18 @@ "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", "dev": true }, - "fast-safe-stringify": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.0.7.tgz", - "integrity": "sha512-Utm6CdzT+6xsDk2m8S6uL8VHxNwI6Jub+e9NYTcAms28T84pTa25GJQV9j0CY0N1rM8hK4x6grpF2BQf+2qwVA==" - }, - "fd-slicer": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", - "integrity": "sha1-JcfInLH5B3+IkbvmHY85Dq4lbx4=", - "requires": { - "pend": "~1.2.0" - } - }, - "fecha": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/fecha/-/fecha-4.2.0.tgz", - "integrity": "sha512-aN3pcx/DSmtyoovUudctc8+6Hl4T+hI9GBBHLjA76jdZl7+b1sgh5g4k+u/GL3dTy1/pnYzKp69FpJ0OicE3Wg==" - }, - "figures": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", - "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=", - "dev": true, - "requires": { - "escape-string-regexp": "^1.0.5" - } + "figlet": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/figlet/-/figlet-1.5.0.tgz", + "integrity": "sha512-ZQJM4aifMpz6H19AW1VqvZ7l4pOE9p7i/3LyxgO2kp+PO/VcDYNqIHEMtkccqIhTXMKci4kjueJr/iCQEaT/Ww==" }, "file-entry-cache": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-5.0.1.tgz", - "integrity": "sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g==", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", "dev": true, "requires": { - "flat-cache": "^2.0.1" + "flat-cache": "^3.0.4" } }, "file-type": { @@ -4820,37 +5358,22 @@ "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", "optional": true }, - "find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "requires": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - } - }, "flat-cache": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-2.0.1.tgz", - "integrity": "sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA==", + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", + "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", "dev": true, "requires": { - "flatted": "^2.0.0", - "rimraf": "2.6.3", - "write": "1.0.3" + "flatted": "^3.1.0", + "rimraf": "^3.0.2" } }, "flatted": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.2.tgz", - "integrity": "sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.1.1.tgz", + "integrity": "sha512-zAoAQiudy+r5SvnSw3KJy5os/oRJYHzrzja/tBDqrZtNhUw8bt6y8OBzMWcjWr+8liV8Eb6yOhw8WZ7VFZ5ZzA==", "dev": true }, - "fn.name": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/fn.name/-/fn.name-1.1.0.tgz", - "integrity": "sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw==" - }, "follow-redirects": { "version": "1.5.10", "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.5.10.tgz", @@ -4874,38 +5397,22 @@ } } }, - "for-in": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", - "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=" - }, - "for-own": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/for-own/-/for-own-0.1.5.tgz", - "integrity": "sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4=", - "requires": { - "for-in": "^1.0.1" - } - }, "fs-constants": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==" }, - "fs-extra": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", - "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", - "requires": { - "graceful-fs": "^4.2.0", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - }, "fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true }, "functional-red-black-tree": { "version": "1.0.1", @@ -4961,17 +5468,27 @@ } } }, + "gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "dev": true, + "peer": true + }, "get-caller-file": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==" }, - "get-stream": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", - "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "get-intrinsic": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", + "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", + "dev": true, "requires": { - "pump": "^3.0.0" + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1" } }, "github-from-package": { @@ -4983,6 +5500,7 @@ "version": "7.1.6", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "dev": true, "requires": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -4992,21 +5510,39 @@ "path-is-absolute": "^1.0.0" } }, + "glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "requires": { + "is-glob": "^4.0.1" + } + }, "globals": { "version": "11.12.0", "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", "dev": true }, - "graceful-fs": { - "version": "4.2.6", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.6.tgz", - "integrity": "sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==" + "has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, + "requires": { + "function-bind": "^1.1.1" + } }, "has-flag": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" + }, + "has-symbols": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz", + "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==", "dev": true }, "has-unicode": { @@ -5026,15 +5562,6 @@ "toidentifier": "1.0.0" } }, - "https-proxy-agent": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-4.0.0.tgz", - "integrity": "sha512-zoDhWrkR3of1l9QAL8/scJZyLu8j/gBkcwcaQOZh7Gyh/+uJQzGVETdgT30akuwkpL8HTRfssqI3BZuV18teDg==", - "requires": { - "agent-base": "5", - "debug": "4" - } - }, "iconv-lite": { "version": "0.4.24", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", @@ -5074,6 +5601,7 @@ "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, "requires": { "once": "^1.3.0", "wrappy": "1" @@ -5089,105 +5617,56 @@ "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==" }, - "inquirer": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-6.5.2.tgz", - "integrity": "sha512-cntlB5ghuB0iuO65Ovoi8ogLHiWGs/5yNrtUcKjFhSSiVeAIVpD7koaSU9RM8mpXw5YDi9RdYXGQMaOURB7ycQ==", - "dev": true, - "requires": { - "ansi-escapes": "^3.2.0", - "chalk": "^2.4.2", - "cli-cursor": "^2.1.0", - "cli-width": "^2.0.0", - "external-editor": "^3.0.3", - "figures": "^2.0.0", - "lodash": "^4.17.12", - "mute-stream": "0.0.7", - "run-async": "^2.2.0", - "rxjs": "^6.4.0", - "string-width": "^2.1.0", - "strip-ansi": "^5.1.0", - "through": "^2.3.6" - }, - "dependencies": { - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "dev": true, - "requires": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - }, - "dependencies": { - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, - "requires": { - "ansi-regex": "^3.0.0" - } - } - } - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true - } - } - } - } - }, "is-arrayish": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==" }, + "is-boolean-object": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.0.tgz", + "integrity": "sha512-a7Uprx8UtD+HWdyYwnD1+ExtTgqQtD2k/1yJgtXP6wnMm8byhkoTZRl+95LLThpzNZJ5aEvi46cdH+ayMFRwmA==", + "dev": true, + "requires": { + "call-bind": "^1.0.0" + } + }, "is-buffer": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.5.tgz", "integrity": "sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==" }, - "is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=" + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "dev": true }, "is-fullwidth-code-point": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==" }, - "is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "is-glob": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", + "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", + "dev": true, "requires": { - "isobject": "^3.0.1" + "is-extglob": "^2.1.1" } }, - "is-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz", - "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==" + "is-number-object": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.4.tgz", + "integrity": "sha512-zohwelOAur+5uXtk8O3GPQ1eAcu4ZX3UwxQhUlfFFMNpUd83gXgjbhJh6HmB6LUNV/ieOLQuDwJO3dWJosUeMw==", + "dev": true + }, + "is-string": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.5.tgz", + "integrity": "sha512-buY6VNRjhQMiF1qWDouloZlQbRhDPCebwxSjxMjxgemYT46YMd2NR0/H+fBhEfWX4A/w9TBJ+ol+okqJKFE6vQ==", + "dev": true }, "is-typedarray": { "version": "1.0.0", @@ -5205,11 +5684,6 @@ "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", "dev": true }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" - }, "js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", @@ -5226,6 +5700,12 @@ "esprima": "^4.0.0" } }, + "jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "dev": true + }, "json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", @@ -5238,12 +5718,14 @@ "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", "dev": true }, - "jsonfile": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", + "json5": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz", + "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==", + "dev": true, + "peer": true, "requires": { - "graceful-fs": "^4.1.6" + "minimist": "^1.2.5" } }, "jsqr": { @@ -5257,26 +5739,6 @@ "integrity": "sha512-STHz9P7X2L4Kwn72fA4rGyqyXdmrMSdxqHx9IXon/FXluXieaFA6KJ2upcHAHxQPQ0LeM/OjLrhFxifHewOALQ==", "optional": true }, - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "requires": { - "is-buffer": "^1.1.5" - }, - "dependencies": { - "is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" - } - } - }, - "kuler": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/kuler/-/kuler-2.0.0.tgz", - "integrity": "sha512-Xq9nH7KlWZmXAtodXDDRE7vs6DU1gTU8zYDHDiWLSip45Egwq3plLHzPn27NgvzL2r1LMPC1vdqh98sQxtqj4A==" - }, "lavacord": { "version": "1.1.9", "resolved": "https://registry.npmjs.org/lavacord/-/lavacord-1.1.9.tgz", @@ -5286,27 +5748,14 @@ "ws": "^7.3.0" } }, - "lazy-cache": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-1.0.4.tgz", - "integrity": "sha1-odePw6UEdMuAhF07O24dpJpEbo4=" - }, "levn": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", - "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", "dev": true, "requires": { - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2" - } - }, - "locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "requires": { - "p-locate": "^4.1.0" + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" } }, "lodash": { @@ -5315,22 +5764,28 @@ "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", "dev": true }, + "lodash.clonedeep": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", + "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=", + "dev": true + }, + "lodash.flatten": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.flatten/-/lodash.flatten-4.4.0.tgz", + "integrity": "sha1-8xwiIlqWMtK7+OSt2+8kCqdlph8=", + "dev": true + }, "lodash.toarray": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/lodash.toarray/-/lodash.toarray-4.4.0.tgz", "integrity": "sha1-JMS/zWsvuji/0FlNsRedjptlZWE=" }, - "logform": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/logform/-/logform-2.2.0.tgz", - "integrity": "sha512-N0qPlqfypFx7UHNn4B3lzS/b0uLqt2hmuoa+PpuXNYgozdJYAyauF5Ky0BWVjrxDlMWiT3qN4zPq3vVAfZy7Yg==", - "requires": { - "colors": "^1.2.1", - "fast-safe-stringify": "^2.0.4", - "fecha": "^4.2.0", - "ms": "^2.1.1", - "triple-beam": "^1.3.0" - } + "lodash.truncate": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", + "integrity": "sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM=", + "dev": true }, "lru-cache": { "version": "6.0.0", @@ -5346,22 +5801,6 @@ "integrity": "sha512-ZS4Bp4r/Zoeq6+NLJpP+0Zzm0pR8whtGPf1XExKLJBAczGMnSi3It14OiNCStjQjM6NU1okjQGSxgEZN8eBYKg==", "optional": true }, - "merge-deep": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/merge-deep/-/merge-deep-3.0.3.tgz", - "integrity": "sha512-qtmzAS6t6grwEkNrunqTBdn0qKwFgNWvlxUbAV8es9M7Ot1EbyApytCnvE0jALPa46ZpKDUo527kKiaWplmlFA==", - "requires": { - "arr-union": "^3.1.0", - "clone-deep": "^0.2.4", - "kind-of": "^3.0.2" - } - }, - "mimic-fn": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz", - "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==", - "dev": true - }, "mimic-response": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", @@ -5371,6 +5810,7 @@ "version": "3.0.4", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, "requires": { "brace-expansion": "^1.1.7" } @@ -5380,46 +5820,11 @@ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" }, - "mixin-object": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/mixin-object/-/mixin-object-2.0.1.tgz", - "integrity": "sha1-T7lJRB2rGCVA8f4DW6YOGUel5X4=", - "requires": { - "for-in": "^0.1.3", - "is-extendable": "^0.1.1" - }, - "dependencies": { - "for-in": { - "version": "0.1.8", - "resolved": "https://registry.npmjs.org/for-in/-/for-in-0.1.8.tgz", - "integrity": "sha1-2Hc5COMSVhCZUrH9ubP6hn0ndeE=" - } - } - }, - "mkdirp": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", - "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", - "dev": true, - "requires": { - "minimist": "^1.2.5" - } - }, "mkdirp-classic": { "version": "0.5.3", "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==" }, - "moment": { - "version": "2.29.1", - "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.1.tgz", - "integrity": "sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ==" - }, - "moment-duration-format": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/moment-duration-format/-/moment-duration-format-2.3.2.tgz", - "integrity": "sha512-cBMXjSW+fjOb4tyaVHuaVE/A5TqkukDWiOfxxAjY+PEqmmBQlLwn+8OzwPiG3brouXKY5Un4pBjAeB6UToXHaQ==" - }, "mongodb": { "version": "3.6.4", "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-3.6.4.tgz", @@ -5506,13 +5911,8 @@ "ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - }, - "mute-stream": { - "version": "0.0.7", - "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz", - "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=", - "dev": true + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "devOptional": true }, "nan": { "version": "2.14.2", @@ -5531,12 +5931,6 @@ "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", "dev": true }, - "nice-try": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", - "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", - "dev": true - }, "node-abi": { "version": "2.20.0", "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-2.20.0.tgz", @@ -5569,6 +5963,13 @@ "integrity": "sha512-MN6ZpzmfNCRM+3t57PTJHgHyw/h4OWnZ6mR8P5j/uZtqQr46RRuDE/P+g3n0YR/AiYXeWixZZzaip77gdICfRg==", "optional": true }, + "node-releases": { + "version": "1.1.71", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.71.tgz", + "integrity": "sha512-zR6HoT6LrLCRBwukmrVbHv0EpEQjksO6GmFcZQQuCAy139BEsoVKPYnf3jongYW83fAa1torLGYwxxky/p28sg==", + "dev": true, + "peer": true + }, "noop-logger": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/noop-logger/-/noop-logger-0.1.1.tgz", @@ -5603,35 +6004,18 @@ "wrappy": "1" } }, - "one-time": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/one-time/-/one-time-1.0.0.tgz", - "integrity": "sha512-5DXOiRKwuSEcQ/l0kGCF6Q3jcADFv5tSmRaJck/OqkVFcOzutB134KRSfF0xDrL39MNnqxbHBbUUcjZIhTgb2g==", - "requires": { - "fn.name": "1.x.x" - } - }, - "onetime": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", - "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=", - "dev": true, - "requires": { - "mimic-fn": "^1.0.0" - } - }, "optionator": { - "version": "0.8.3", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", - "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", + "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", "dev": true, "requires": { - "deep-is": "~0.1.3", - "fast-levenshtein": "~2.0.6", - "levn": "~0.3.0", - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2", - "word-wrap": "~1.2.3" + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.3" } }, "opusscript": { @@ -5640,12 +6024,6 @@ "integrity": "sha512-VSTi1aWFuCkRCVq+tx/BQ5q9fMnQ9pVZ3JU4UHKqTkf0ED3fKEPdr+gKAAl3IA2hj9rrP6iyq3hlcJq3HELtNQ==", "optional": true }, - "os-tmpdir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", - "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", - "dev": true - }, "p-limit": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", @@ -5654,14 +6032,6 @@ "p-try": "^2.0.0" } }, - "p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "requires": { - "p-limit": "^2.2.0" - } - }, "p-try": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", @@ -5682,26 +6052,21 @@ "callsites": "^3.0.0" } }, - "path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==" + "parse-node-version": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parse-node-version/-/parse-node-version-1.0.1.tgz", + "integrity": "sha512-3YHlOa/JgH6Mnpr05jP9eDG254US9ek25LyIxZlDItp2iJtwyaXQb57lBYLdT3MowkUFYEV2XXNAYIPlESvJlA==" }, "path-is-absolute": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" - }, - "path-is-inside": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", - "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", "dev": true }, "path-key": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", "dev": true }, "peek-readable": { @@ -5709,11 +6074,6 @@ "resolved": "https://registry.npmjs.org/peek-readable/-/peek-readable-3.1.3.tgz", "integrity": "sha512-mpAcysyRJxmICBcBa5IXH7SZPvWkcghm6Fk8RekoS3v+BpbSzlZzuWbMx+GXrlUwESi9qHar4nVEZNMKylIHvg==" }, - "pend": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", - "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=" - }, "pg": { "version": "8.5.1", "resolved": "https://registry.npmjs.org/pg/-/pg-8.5.1.tgz", @@ -5776,14 +6136,6 @@ "split2": "^3.1.1" } }, - "pkg-dir": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", - "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", - "requires": { - "find-up": "^4.0.0" - } - }, "pngjs": { "version": "3.4.0", "resolved": "https://registry.npmjs.org/pngjs/-/pngjs-3.4.0.tgz", @@ -5864,9 +6216,9 @@ } }, "prelude-ls": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", - "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", "dev": true }, "process-nextick-args": { @@ -5877,12 +6229,8 @@ "progress": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", - "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==" - }, - "proxy-from-env": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", - "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", + "dev": true }, "pump": { "version": "3.0.0", @@ -5899,87 +6247,6 @@ "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", "dev": true }, - "puppeteer": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/puppeteer/-/puppeteer-5.5.0.tgz", - "integrity": "sha512-OM8ZvTXAhfgFA7wBIIGlPQzvyEETzDjeRa4mZRCRHxYL+GNH5WAuYUQdja3rpWZvkX/JKqmuVgbsxDNsDFjMEg==", - "requires": { - "debug": "^4.1.0", - "devtools-protocol": "0.0.818844", - "extract-zip": "^2.0.0", - "https-proxy-agent": "^4.0.0", - "node-fetch": "^2.6.1", - "pkg-dir": "^4.2.0", - "progress": "^2.0.1", - "proxy-from-env": "^1.0.0", - "rimraf": "^3.0.2", - "tar-fs": "^2.0.0", - "unbzip2-stream": "^1.3.3", - "ws": "^7.2.3" - }, - "dependencies": { - "rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "requires": { - "glob": "^7.1.3" - } - } - } - }, - "puppeteer-extra": { - "version": "3.1.17", - "resolved": "https://registry.npmjs.org/puppeteer-extra/-/puppeteer-extra-3.1.17.tgz", - "integrity": "sha512-KkrIEZGuQ1uqRK9wo0hIGEspGPlYHQIr31MQcbVy4l3RBCICdNbGpKH5TIyvTwSuuqjjGl62gFq5Naa51OpYsA==", - "requires": { - "@types/debug": "^4.1.0", - "@types/puppeteer": "*", - "debug": "^4.1.1", - "deepmerge": "^4.2.2" - } - }, - "puppeteer-extra-plugin": { - "version": "3.1.8", - "resolved": "https://registry.npmjs.org/puppeteer-extra-plugin/-/puppeteer-extra-plugin-3.1.8.tgz", - "integrity": "sha512-bTKhY0q+T3qM59fcdKnxwlT+KA1XpKKb8vUxFtd7PH/TGA04AOO+WQJx9npU1nA4NXZKU2xs2KZNn/A+1Cachw==", - "requires": { - "@types/debug": "^4.1.0", - "debug": "^4.1.1", - "merge-deep": "^3.0.1" - } - }, - "puppeteer-extra-plugin-stealth": { - "version": "2.7.5", - "resolved": "https://registry.npmjs.org/puppeteer-extra-plugin-stealth/-/puppeteer-extra-plugin-stealth-2.7.5.tgz", - "integrity": "sha512-4LR5SRw7zlW+qSokvXJsjdQoDDvDlZsQ9QR1pD01mwxDAFAeJ3dCBvTBt33ppm//tesLCCBxPr78s2HyBIVp4A==", - "requires": { - "debug": "^4.1.1", - "puppeteer-extra-plugin": "^3.1.8", - "puppeteer-extra-plugin-user-preferences": "^2.2.11" - } - }, - "puppeteer-extra-plugin-user-data-dir": { - "version": "2.2.11", - "resolved": "https://registry.npmjs.org/puppeteer-extra-plugin-user-data-dir/-/puppeteer-extra-plugin-user-data-dir-2.2.11.tgz", - "integrity": "sha512-jng9rTY0qE8HJId/oAjs+RVNxgeQKDnoBsQPaQtL/FbkvD9C/7RlKSmz7IyjhafilzSZcA4fB7jFJX9rrN9Bdg==", - "requires": { - "debug": "^4.1.1", - "fs-extra": "^8.1.0", - "puppeteer-extra-plugin": "^3.1.8" - } - }, - "puppeteer-extra-plugin-user-preferences": { - "version": "2.2.11", - "resolved": "https://registry.npmjs.org/puppeteer-extra-plugin-user-preferences/-/puppeteer-extra-plugin-user-preferences-2.2.11.tgz", - "integrity": "sha512-lvqd2R7N35/8ldqgty1TUmzmu3VlhunEaEABGm4bUglEXUxGHQgRheP+U8BmWIM2GCGjNoJCSu3nqGJ56ZsSRg==", - "requires": { - "debug": "^4.1.1", - "deepmerge": "^4.2.2", - "puppeteer-extra-plugin": "^3.1.8", - "puppeteer-extra-plugin-user-data-dir": "^2.2.11" - } - }, "qrcode": { "version": "1.4.4", "resolved": "https://registry.npmjs.org/qrcode/-/qrcode-1.4.4.tgz", @@ -6070,9 +6337,9 @@ "optional": true }, "regexpp": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-2.0.1.tgz", - "integrity": "sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.1.0.tgz", + "integrity": "sha512-ZOIzd8yVsQQA7j8GCSlPGXwg5PfmA1mrq0JP4nGhh54LaKN3xdai/vHUDu74pKwV8OxseMS65u2NImosQcSD0Q==", "dev": true }, "require_optional": { @@ -6098,6 +6365,12 @@ "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=" }, + "require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "dev": true + }, "require-main-filename": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", @@ -6109,40 +6382,15 @@ "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", "dev": true }, - "restore-cursor": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", - "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=", - "dev": true, - "requires": { - "onetime": "^2.0.0", - "signal-exit": "^3.0.2" - } - }, "rimraf": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", - "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", "dev": true, "requires": { "glob": "^7.1.3" } }, - "run-async": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz", - "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==", - "dev": true - }, - "rxjs": { - "version": "6.6.6", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.6.tgz", - "integrity": "sha512-/oTwee4N4iWzAMAL9xdGKjkEHmIwupR3oXbQjCKywF1BeFohswF3vZdogbmEF6pZkOsXTzWkrZszrWpQTByYVg==", - "dev": true, - "requires": { - "tslib": "^1.9.0" - } - }, "safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", @@ -6177,37 +6425,6 @@ "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==" }, - "shallow-clone": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-0.1.2.tgz", - "integrity": "sha1-WQnodLp3EG1zrEFM/sH/yofZcGA=", - "requires": { - "is-extendable": "^0.1.1", - "kind-of": "^2.0.1", - "lazy-cache": "^0.2.3", - "mixin-object": "^2.0.1" - }, - "dependencies": { - "is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" - }, - "kind-of": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-2.0.1.tgz", - "integrity": "sha1-AY7HpM5+OobLkUG+UZ0kyPqpgbU=", - "requires": { - "is-buffer": "^1.0.2" - } - }, - "lazy-cache": { - "version": "0.2.7", - "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-0.2.7.tgz", - "integrity": "sha1-f+3fLctu23fRHvHRF6tf/fCrG2U=" - } - } - }, "sharp": { "version": "0.26.3", "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.26.3.tgz", @@ -6236,18 +6453,18 @@ } }, "shebang-command": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", "dev": true, "requires": { - "shebang-regex": "^1.0.0" + "shebang-regex": "^3.0.0" } }, "shebang-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", "dev": true }, "sift": { @@ -6285,20 +6502,38 @@ } }, "slice-ansi": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz", - "integrity": "sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", + "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", "dev": true, "requires": { - "ansi-styles": "^3.2.0", - "astral-regex": "^1.0.0", - "is-fullwidth-code-point": "^2.0.0" + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" }, "dependencies": { - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true } } @@ -6309,6 +6544,12 @@ "integrity": "sha1-CzpmK10Ewxd7GSa+qCsD+Dei70E=", "optional": true }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + }, "sparse-bitfield": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/sparse-bitfield/-/sparse-bitfield-3.0.3.tgz", @@ -6346,11 +6587,6 @@ "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", "dev": true }, - "stack-trace": { - "version": "0.0.10", - "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz", - "integrity": "sha1-VHxws0fo0ytOEI6hoqFZ5f3eGcA=" - }, "statuses": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", @@ -6428,60 +6664,44 @@ "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, "requires": { "has-flag": "^3.0.0" } }, "table": { - "version": "5.4.6", - "resolved": "https://registry.npmjs.org/table/-/table-5.4.6.tgz", - "integrity": "sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug==", + "version": "6.0.9", + "resolved": "https://registry.npmjs.org/table/-/table-6.0.9.tgz", + "integrity": "sha512-F3cLs9a3hL1Z7N4+EkSscsel3z55XT950AvB05bwayrNg5T1/gykXtigioTAjbltvbMSJvvhFCbnf6mX+ntnJQ==", "dev": true, "requires": { - "ajv": "^6.10.2", - "lodash": "^4.17.14", - "slice-ansi": "^2.1.0", - "string-width": "^3.0.0" + "ajv": "^8.0.1", + "is-boolean-object": "^1.1.0", + "is-number-object": "^1.0.4", + "is-string": "^1.0.5", + "lodash.clonedeep": "^4.5.0", + "lodash.flatten": "^4.4.0", + "lodash.truncate": "^4.4.2", + "slice-ansi": "^4.0.0", + "string-width": "^4.2.0" }, "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true - }, - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "ajv": { + "version": "8.0.3", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.0.3.tgz", + "integrity": "sha512-Df6NAivu9KpZw+q8ySijAgLvr1mUA5ihkRvCLCxpdYR21ann5yIuN+PpFxmweSj7i3yjJ0x5LN5KVs0RRzskAQ==", "dev": true, "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" } }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } + "json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true } } }, @@ -6530,29 +6750,66 @@ } } }, - "text-hex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/text-hex/-/text-hex-1.0.0.tgz", - "integrity": "sha512-uuVGNWzgJ4yhRaNSiubPY7OjISw4sw4E5Uv0wbjp+OzcbmVU/rsT8ujgcXJhn9ypzsgr5vlzpPqP+MBBKcGvbg==" - }, "text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", "dev": true }, - "through": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" + "time-stamp": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/time-stamp/-/time-stamp-1.1.0.tgz", + "integrity": "sha1-dkpaEa9QVhkhsTPztE5hhofg9cM=" }, - "tmp": { - "version": "0.0.33", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", - "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", - "dev": true, + "title-case-minors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/title-case-minors/-/title-case-minors-1.0.0.tgz", + "integrity": "sha1-UfFwN8KUdHodHNpCS1AEyG2OsRU=" + }, + "to-capital-case": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/to-capital-case/-/to-capital-case-1.0.0.tgz", + "integrity": "sha1-pXxQFP1aNyF88FCZ/4pCG7+cm38=", "requires": { - "os-tmpdir": "~1.0.2" + "to-space-case": "^1.0.0" + } + }, + "to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", + "dev": true + }, + "to-no-case": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/to-no-case/-/to-no-case-1.0.2.tgz", + "integrity": "sha1-xyKQcWTvaxeBMsjmmTAhLRtKoWo=" + }, + "to-sentence-case": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/to-sentence-case/-/to-sentence-case-1.0.0.tgz", + "integrity": "sha1-xIO/NkdzflxzjvcAb+Ng1fmcVy4=", + "requires": { + "to-no-case": "^1.0.0" + } + }, + "to-space-case": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/to-space-case/-/to-space-case-1.0.0.tgz", + "integrity": "sha1-sFLar7Gysp3HcM6gFj5ewOvJ/Bc=", + "requires": { + "to-no-case": "^1.0.0" + } + }, + "to-title-case": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/to-title-case/-/to-title-case-1.0.0.tgz", + "integrity": "sha1-rKiPidYGTeUBCKl86g20SCfoAGE=", + "requires": { + "escape-regexp-component": "^1.0.2", + "title-case-minors": "^1.0.0", + "to-capital-case": "^1.0.0", + "to-sentence-case": "^1.0.0" } }, "toidentifier": { @@ -6578,17 +6835,6 @@ "typescript": "^4.2.3" } }, - "triple-beam": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/triple-beam/-/triple-beam-1.3.0.tgz", - "integrity": "sha512-XrHUvV5HpdLmIj4uVMxHggLbFSZYIn7HEWsqePZcI50pco+MPqJ50wMGY794X7AOOhxOBAjbkqfAbEe/QMp2Lw==" - }, - "tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", - "dev": true - }, "tunnel-agent": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", @@ -6604,14 +6850,20 @@ "optional": true }, "type-check": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", - "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", "dev": true, "requires": { - "prelude-ls": "~1.1.2" + "prelude-ls": "^1.2.1" } }, + "type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "dev": true + }, "typedarray-to-buffer": { "version": "3.1.5", "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", @@ -6625,20 +6877,6 @@ "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.2.3.tgz", "integrity": "sha512-qOcYwxaByStAWrBf4x0fibwZvMRG+r4cQoTjbPtUlrWjBHbmCAww1i448U0GJ+3cNNEtebDteo/cHOR3xJ4wEw==" }, - "unbzip2-stream": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/unbzip2-stream/-/unbzip2-stream-1.4.3.tgz", - "integrity": "sha512-mlExGW4w71ebDJviH16lQLtZS32VKqsSfk80GCfUlwT/4/hNRFsoscrF/c++9xinkMzECL1uL9DDwXqFWkruPg==", - "requires": { - "buffer": "^5.2.1", - "through": "^2.3.8" - } - }, - "universalify": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==" - }, "unpipe": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", @@ -6664,10 +6902,16 @@ "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", "optional": true }, + "v8-compile-cache": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", + "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", + "dev": true + }, "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", "dev": true, "requires": { "isexe": "^2.0.0" @@ -6707,43 +6951,6 @@ } } }, - "winston": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/winston/-/winston-3.3.3.tgz", - "integrity": "sha512-oEXTISQnC8VlSAKf1KYSSd7J6IWuRPQqDdo8eoRNaYKLvwSb5+79Z3Yi1lrl6KDpU6/VWaxpakDAtb1oQ4n9aw==", - "requires": { - "@dabh/diagnostics": "^2.0.2", - "async": "^3.1.0", - "is-stream": "^2.0.0", - "logform": "^2.2.0", - "one-time": "^1.0.0", - "readable-stream": "^3.4.0", - "stack-trace": "0.0.x", - "triple-beam": "^1.3.0", - "winston-transport": "^4.4.0" - }, - "dependencies": { - "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - } - } - }, - "winston-transport": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/winston-transport/-/winston-transport-4.4.0.tgz", - "integrity": "sha512-Lc7/p3GtqtqPBYYtS6KCN3c77/2QCev51DvcJKbkFPQNoj1sinkGwLGFDxkXY9J6p9+EPnYs+D90uwbnaiURTw==", - "requires": { - "readable-stream": "^2.3.7", - "triple-beam": "^1.2.0" - } - }, "word-wrap": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", @@ -6800,15 +7007,6 @@ "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" }, - "write": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/write/-/write-1.0.3.tgz", - "integrity": "sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig==", - "dev": true, - "requires": { - "mkdirp": "^0.5.1" - } - }, "ws": { "version": "7.4.3", "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.3.tgz", @@ -6922,15 +7120,6 @@ "decamelize": "^1.2.0" } }, - "yauzl": { - "version": "2.10.0", - "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", - "integrity": "sha1-x+sXyT4RLLEIb6bY5R+wZnt5pfk=", - "requires": { - "buffer-crc32": "~0.2.3", - "fd-slicer": "~1.1.0" - } - }, "zlib-sync": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/zlib-sync/-/zlib-sync-0.1.7.tgz", diff --git a/package.json b/package.json index 249bff3..21041c5 100644 --- a/package.json +++ b/package.json @@ -22,31 +22,28 @@ "url": "git+https://github.com/esmBot/esmBot.git" }, "dependencies": { - "abort-controller": "^3.0.0", "cowsay2": "^2.0.4", + "dayjs": "^1.10.4", "dotenv": "^8.2.0", "duckduckgo-images-api": "^1.0.5", "emoji-regex": "^9.2.2", - "eris": "github:abalabahaha/eris#dev", + "eris": "^0.15.0", + "eris-sharder": "^1.10.0", "file-type": "^16.1.0", "jsqr": "^1.3.1", "lavacord": "^1.1.9", - "moment": "^2.29.1", - "moment-duration-format": "^2.3.2", "node-addon-api": "^3.1.0", "node-emoji": "^1.10.0", "node-fetch": "^2.6.1", - "puppeteer": "^5.5.0", - "puppeteer-extra": "^3.1.15", - "puppeteer-extra-plugin-stealth": "^2.6.5", "qrcode": "^1.4.4", "sharp": "^0.26.3", - "topgg-autoposter": "^1.1.9", - "winston": "^3.3.3" + "topgg-autoposter": "^1.1.9" }, "devDependencies": { - "eslint": "^5.15.2", - "eslint-plugin-promise": "^4.2.1" + "@babel/eslint-parser": "^7.13.8", + "@babel/eslint-plugin": "^7.13.0", + "@babel/plugin-proposal-class-properties": "^7.13.0", + "eslint": "^7.23.0" }, "optionalDependencies": { "bufferutil": "^4.0.1", diff --git a/shard.js b/shard.js new file mode 100644 index 0000000..2fd7c03 --- /dev/null +++ b/shard.js @@ -0,0 +1,130 @@ +// shard base +const { Base } = require("eris-sharder"); +// path stuff +const { readdir } = require("fs").promises; +// fancy loggings +const logger = require("./utils/logger.js"); +// initialize command loader +const handler = require("./utils/handler.js"); +// lavalink stuff +const sound = require("./utils/soundplayer.js"); +// image processing stuff +const image = require("./utils/image.js"); +// database stuff +const database = require("./utils/database.js"); +// dbl posting +const poster = require("topgg-autoposter"); +// command collections +const collections = require("./utils/collections.js"); +// playing messages +const messages = require("./messages.json"); +// other stuff +const misc = require("./utils/misc.js"); +// generate help page +const helpGenerator = + process.env.OUTPUT !== "" ? require("./utils/help.js") : null; + +class Shard extends Base { + constructor(bot) { + super(bot); + } + + async init() { + // register commands and their info + const soundStatus = await sound.checkStatus(); + logger.log("info", "Attempting to load commands..."); + for await (const commandFile of this.getFiles("./commands/")) { + logger.log("log", `Loading command from ${commandFile}...`); + try { + await handler.load(commandFile, soundStatus); + } catch (e) { + logger.error(`Failed to register command from ${commandFile}: ${e}`); + } + } + + // register events + const events = await readdir("./events/"); + logger.log("info", `Attempting to load ${events.length} events...`); + for (const file of events) { + logger.log("log", `Loading event from ${file}...`); + const eventName = file.split(".")[0]; + const event = require(`./events/${file}`); + this.bot.on(eventName, event.bind(null, this.bot)); + } + + // connect to image api if enabled + if (process.env.API === "true") { + for (const server of image.servers) { + try { + await image.connect(server); + } catch (e) { + logger.error(e); + } + } + + // generate docs + if (this.clusterID === 0 && helpGenerator) { + helpGenerator.generateList().then(() => helpGenerator.createPage(process.env.OUTPUT)).then(() => logger.log("info", "The help docs have been generated.")); + } + } + + // dbl posting + if (process.env.NODE_ENV === "production" && process.env.DBL !== "") { + const dbl = poster(process.env.DBL, this.bot); + dbl.on("posted", () => { + logger.log("Posted stats to top.gg"); + }); + dbl.on("error", e => { + logger.error(e); + }); + } + + // handle process stop + process.on("SIGINT", () => { + logger.log("warn", "SIGINT detected, shutting down..."); + this.bot.editStatus("dnd", { + name: "Restarting/shutting down..." + }); + for (const command in collections.commands) { + handler.unload(command); + } + this.bot.disconnect(); + require("./utils/database.js").stop(); + process.exit(0); + }); + return; + } + + async* getFiles(dir) { + const dirents = await readdir(dir, { withFileTypes: true }); + for (const dirent of dirents) { + if (dirent.isDirectory()) { + yield* this.getFiles(dir + dirent.name); + } else { + yield dir + (dir.charAt(dir.length - 1) !== "/" ? "/" : "") + dirent.name; + } + } + } + + async launch() { + await this.init(); + // connect to lavalink + if (!sound.status && !sound.connected) await sound.connect(this.bot); + + await database.setup(); + + // set activity (a.k.a. the gamer code) + (async function activityChanger() { + this.bot.editStatus("dnd", { + name: `${misc.random(messages)} | @${this.bot.user.username} help`, + }); + setTimeout(activityChanger.bind(this), 900000); + }).bind(this)(); + + if (process.env.PMTWO === "true") process.send("ready"); + logger.log("info", `Started cluster ${this.clusterID}.`); + } + +} + +module.exports = Shard; \ No newline at end of file diff --git a/utils/client.js b/utils/client.js deleted file mode 100644 index 0d2f5ca..0000000 --- a/utils/client.js +++ /dev/null @@ -1,24 +0,0 @@ -// separate the client from app.js so we can call it later -const { Client } = require("eris"); -const client = new Client(process.env.TOKEN, { - disableEvents: { - CHANNEL_DELETE: true, - CHANNEL_UPDATE: true, - GUILD_BAN_REMOVE: true, - GUILD_MEMBER_ADD: true, - GUILD_MEMBER_REMOVE: true, - GUILD_MEMBER_UPDATE: true, - GUILD_ROLE_CREATE: true, - GUILD_ROLE_DELETE: true, - GUILD_ROLE_UPDATE: true, - TYPING_START: true - }, - maxShards: "auto", - allowedMentions: { - everyone: false, - roles: false, - users: true, - repliedUser: true - } -}); -module.exports = client; diff --git a/utils/collections.js b/utils/collections.js index 851486f..dcaa2a2 100644 --- a/utils/collections.js +++ b/utils/collections.js @@ -1,7 +1,19 @@ exports.commands = new Map(); +exports.paths = new Map(); exports.aliases = new Map(); exports.info = new Map(); +class TimedMap extends Map { + set(key, value) { + super.set(key, value); + setTimeout(() => { + if (super.has(key)) super.delete(key); + }, 5000); + } +} + +exports.runningCommands = new TimedMap(); + class Cache extends Map { constructor(values) { super(values); diff --git a/utils/database/mongo.js b/utils/database/mongo.js index 70a07bf..e4bf176 100644 --- a/utils/database/mongo.js +++ b/utils/database/mongo.js @@ -2,6 +2,8 @@ const collections = require("../collections.js"); const logger = require("../logger.js"); const misc = require("../misc.js"); +logger.warn("\x1b[1m\x1b[31m\x1b[40m" + "The MongoDB database driver has been deprecated and will be removed in a future release. Please migrate your database to PostgreSQL as soon as possible." + "\x1b[0m"); + const mongoose = require("mongoose"); mongoose.connect(process.env.DB, { poolSize: 10, diff --git a/utils/database/postgres.js b/utils/database/postgres.js index 2163dc2..a8dc8aa 100644 --- a/utils/database/postgres.js +++ b/utils/database/postgres.js @@ -68,6 +68,8 @@ exports.addCount = async (command) => { }; exports.addGuild = async (guild) => { + const query = await this.getGuild(guild); + if (query) return query; await connection.query("INSERT INTO guilds (guild_id, tags, prefix, disabled, tags_disabled) VALUES ($1, $2, $3, $4, $5)", [guild.id, misc.tagDefaults, process.env.PREFIX, [], false]); return await this.getGuild(guild.id); }; diff --git a/utils/dbl.js b/utils/dbl.js deleted file mode 100644 index 1b55f5d..0000000 --- a/utils/dbl.js +++ /dev/null @@ -1,12 +0,0 @@ -// dbl api client -const poster = require("topgg-autoposter"); -const logger = require("./logger.js"); -const client = require("./client.js"); -const dbl = poster(process.env.DBL, client); -dbl.on("posted", () => { - logger.log("Posted stats to top.gg"); -}); -dbl.on("error", e => { - logger.error(e); -}); -module.exports = dbl; diff --git a/utils/handler.js b/utils/handler.js index 50d9f7e..6acde7c 100644 --- a/utils/handler.js +++ b/utils/handler.js @@ -3,21 +3,28 @@ const logger = require("./logger.js"); // load command into memory exports.load = async (command, soundStatus) => { - const props = require(`../commands/${command}`); - if (props.requires === "google" && process.env.GOOGLE === "") return logger.log("info", `Google info not provided in config, skipped loading command ${command}...`); - if (props.requires === "cat" && process.env.CAT === "") return logger.log("info", `Cat API info not provided in config, skipped loading command ${command}...`); - if (props.requires === "mashape" && process.env.MASHAPE === "") return logger.log("info", `Mashape/RapidAPI info not provided in config, skipped loading command ${command}...`); - if (props.requires === "sound" && soundStatus) return logger.log("info", `Failed to connect to some Lavalink nodes, skipped loading command ${command}...`); - collections.commands.set(command.split(".")[0], props.run); - collections.info.set(command.split(".")[0], { - category: props.category, - description: props.help, + const props = require(`../${command}`); + if (props.requires.includes("google") && process.env.GOOGLE === "") return logger.log("warn", `Google info not provided in config, skipped loading command ${command}...`); + if (props.requires.includes("cat") && process.env.CAT === "") return logger.log("warn", `Cat API info not provided in config, skipped loading command ${command}...`); + if (props.requires.includes("mashape") && process.env.MASHAPE === "") return logger.log("warn", `Mashape/RapidAPI info not provided in config, skipped loading command ${command}...`); + if (props.requires.includes("sound") && soundStatus) return logger.log("warn", `Failed to connect to some Lavalink nodes, skipped loading command ${command}...`); + const commandArray = command.split("/"); + const commandName = commandArray[commandArray.length - 1].split(".")[0]; + + collections.paths.set(commandName, command); + collections.commands.set(commandName, props); + + collections.info.set(commandName, { + category: commandArray[2], + description: props.description, aliases: props.aliases, - params: props.params + params: props.arguments }); + if (props.aliases) { for (const alias of props.aliases) { - collections.aliases.set(alias, command.split(".")[0]); + collections.aliases.set(alias, commandName); + collections.paths.set(alias, command); } } return false; @@ -32,11 +39,12 @@ exports.unload = async (command) => { cmd = collections.commands.get(collections.aliases.get(command)); } if (!cmd) return `The command \`${command}\` doesn't seem to exist, nor is it an alias.`; - const mod = require.cache[require.resolve(`../commands/${command}`)]; - delete require.cache[require.resolve(`../commands/${command}.js`)]; - for (let i = 0; i < mod.parent.children.length; i++) { - if (mod.parent.children[i] === mod) { - mod.parent.children.splice(i, 1); + const path = collections.paths.get(command); + const mod = require.cache[require.resolve(`../${path}`)]; + delete require.cache[require.resolve(`../${path}`)]; + for (let i = 0; i < module.children.length; i++) { + if (module.children[i] === mod) { + module.children.splice(i, 1); break; } } diff --git a/utils/help.js b/utils/help.js index 50b1424..72c732a 100644 --- a/utils/help.js +++ b/utils/help.js @@ -1,10 +1,34 @@ const collections = require("./collections.js"); -const logger = require("./logger.js"); const fs = require("fs"); -module.exports = async (output) => { - const template = `# esmBot${process.env.NODE_ENV === "development" ? " Dev" : ""} Command List -${process.env.NODE_ENV === "development" ? "\n**You are currently using esmBot Dev! Things may change at any time without warning and there will be bugs. Many bugs. If you find one, [report it here](https://github.com/esmBot/esmBot/issues) or in the esmBot Support server.**\n" : ""} +const categoryTemplate = { + general: [], + tags: ["> **Every command in this category is a subcommand of the tag command.**\n"], + "image-editing": ["> **These commands support the PNG, JPEG, WEBP (static), and GIF (animated or static) formats.**\n"] +}; +exports.categories = categoryTemplate; + +exports.generateList = async () => { + this.categories = categoryTemplate; + for (const [command] of collections.commands) { + const category = collections.info.get(command).category; + const description = collections.info.get(command).description; + const params = collections.info.get(command).params; + if (category === "tags") { + const subCommands = [...Object.keys(description)]; + for (const subCommand of subCommands) { + this.categories.tags.push(`**tags${subCommand !== "default" ? ` ${subCommand}` : ""}**${params[subCommand] ? ` ${params[subCommand]}` : ""} - ${description[subCommand]}`); + } + } else { + if (!this.categories[category]) this.categories[category] = []; + this.categories[category].push(`**${command}**${params ? ` ${params}` : ""} - ${description}`); + } + } +}; + +exports.createPage = async (output) => { + let template = `# esmBot${process.env.NODE_ENV === "development" ? " Dev" : ""} Command List + This page was last generated on \`${new Date().toString()}\`. \`[]\` means an argument is required, \`{}\` means an argument is optional. @@ -13,47 +37,33 @@ Default prefix is \`&\`. **Want to help support esmBot's development? Consider donating on Patreon!** https://patreon.com/TheEssem -> Tip: You can get more info about a command by using \`help [command]\`. - -## Table of Contents -+ [**General**](#đŸ’ģ-general) -+ [**Tags**](#🏷ī¸-tags) -+ [**Fun**](#👌-fun) -+ [**Image Editing**](#đŸ–ŧī¸-image-editing) -+ [**Soundboard**](#🔊-soundboard) -+ [**Music**](#🎤-music) +> Tip: You can get more info about a command by using \`help [command]\` in the bot itself. `; - const commands = collections.commands; - const categories = { - general: ["## đŸ’ģ General"], - tags: ["## 🏷ī¸ Tags"], - fun: ["## 👌 Fun"], - images: ["## đŸ–ŧī¸ Image Editing", "> These commands support the PNG, JPEG, WEBP, and GIF formats.\n"], - soundboard: ["## 🔊 Soundboard"], - music: ["## 🎤 Music"] - }; - for (const [command] of commands) { - const category = collections.info.get(command).category; - const description = collections.info.get(command).description; - const params = collections.info.get(command).params; - if (category === 1) { - categories.general.push(`+ **${command}**${params ? ` ${params}` : ""} - ${description}`); - } else if (category === 3) { - const subCommands = [...Object.keys(description)]; - for (const subCommand of subCommands) { - categories.tags.push(`+ **tags${subCommand !== "default" ? ` ${subCommand}` : ""}**${params[subCommand] ? ` ${params[subCommand]}` : ""} - ${description[subCommand]}`); + + template += "\n## Table of Contents\n"; + for (const category of Object.keys(this.categories)) { + const categoryStringArray = category.split("-"); + for (const index of categoryStringArray.keys()) { + categoryStringArray[index] = categoryStringArray[index].charAt(0).toUpperCase() + categoryStringArray[index].slice(1); + } + template += `+ [**${categoryStringArray.join(" ")}**](#${category})\n`; + } + + // hell + for (const category of Object.keys(this.categories)) { + const categoryStringArray = category.split("-"); + for (const index of categoryStringArray.keys()) { + categoryStringArray[index] = categoryStringArray[index].charAt(0).toUpperCase() + categoryStringArray[index].slice(1); + } + template += `\n## ${categoryStringArray.join(" ")}\n`; + for (const command of this.categories[category]) { + if (command.startsWith(">")) { + template += `${command}\n`; + } else { + template += `+ ${command}\n`; } - } else if (category === 4) { - categories.fun.push(`+ **${command}**${params ? ` ${params}` : ""} - ${description}`); - } else if (category === 5) { - categories.images.push(`+ **${command}**${params ? ` ${params}` : ""} - ${description}`); - } else if (category === 6) { - categories.soundboard.push(`+ **${command}**${params ? ` ${params}` : ""} - ${description}`); - } else if (category === 7) { - categories.music.push(`+ **${command}**${params ? ` ${params}` : ""} - ${description}`); } } - fs.writeFile(output, `${template}\n${categories.general.join("\n")}\n\n${categories.tags.join("\n")}\n\n${categories.fun.join("\n")}\n\n${categories.images.join("\n")}\n\n${categories.soundboard.join("\n")}\n\n${categories.music.join("\n")}`, () => { - logger.log("The help docs have been generated."); - }); + + await fs.promises.writeFile(output, template); }; \ No newline at end of file diff --git a/utils/image-runner.js b/utils/image-runner.js index f8aa040..04b7941 100644 --- a/utils/image-runner.js +++ b/utils/image-runner.js @@ -1,9 +1,8 @@ const magick = require("../build/Release/image.node"); -const { promisify } = require("util"); const { isMainThread, parentPort, workerData } = require("worker_threads"); -exports.run = async object => { - return new Promise(async (resolve, reject) => { +exports.run = object => { + return new Promise((resolve, reject) => { // If the image has a path, it must also have a type if (object.path) { if (object.type !== "image/gif" && object.onlyGIF) resolve({ @@ -16,25 +15,23 @@ exports.run = async object => { // If no image type is given (say, the command generates its own image), make it a PNG. const fileExtension = object.type ? object.type.split("/")[1] : "png"; const objectWithFixedType = Object.assign({}, object, {type: fileExtension}); - try { - const data = await promisify(magick[object.cmd])(objectWithFixedType); + magick[object.cmd](objectWithFixedType, (error, data, type) => { + if (error) reject(error); const returnObject = { buffer: data, - fileExtension + fileExtension: type }; resolve(returnObject); - } catch (e) { - reject(e); - } + }); }); }; if (!isMainThread) { this.run(workerData) - // eslint-disable-next-line promise/always-return .then(returnObject => { parentPort.postMessage(returnObject); process.exit(); + return; }) .catch(err => { // turn promise rejection into normal error diff --git a/utils/image.js b/utils/image.js index e942a9c..8664744 100644 --- a/utils/image.js +++ b/utils/image.js @@ -1,10 +1,9 @@ const magick = require("../build/Release/image.node"); const { Worker } = require("worker_threads"); const fetch = require("node-fetch"); -const AbortController = require("abort-controller"); +const fs = require("fs"); const net = require("net"); const fileType = require("file-type"); -exports.servers = require("../servers.json").image; const path = require("path"); const { EventEmitter } = require("events"); const logger = require("./logger.js"); @@ -13,10 +12,12 @@ const formats = ["image/jpeg", "image/png", "image/webp", "image/gif"]; const jobs = {}; -const connections = []; +exports.connections = []; const statuses = {}; +exports.servers = JSON.parse(fs.readFileSync("./servers.json", { encoding: "utf8" })).image; + const chooseServer = async (ideal) => { if (ideal.length === 0) throw "No available servers"; const sorted = ideal.sort((a, b) => { @@ -25,12 +26,40 @@ const chooseServer = async (ideal) => { return sorted[0]; }; +exports.repopulate = async () => { + const data = await fs.promises.readFile("./servers.json", { encoding: "utf8" }); + this.servers = JSON.parse(data).image; + return; +}; + +exports.getStatus = () => { + return new Promise((resolve, reject) => { + let serversLeft = this.connections.length; + const statuses = []; + const timeout = setTimeout(() => { + resolve(statuses); + }, 5000); + for (const connection of this.connections) { + if (!connection.remoteAddress) continue; + fetch(`http://${connection.remoteAddress}:8081/running`).then(statusRequest => statusRequest.json()).then((status) => { + serversLeft--; + statuses.push(status); + if (!serversLeft) { + clearTimeout(timeout); + resolve(statuses); + } + return; + }).catch(e => reject(e)); + } + }); +}; + exports.connect = (server) => { return new Promise((resolve, reject) => { const connection = net.createConnection(8080, server); const timeout = setTimeout(() => { - const connectionIndex = connections.indexOf(connection); - if (connectionIndex < 0) delete connections[connectionIndex]; + const connectionIndex = this.connections.indexOf(connection); + if (connectionIndex < 0) delete this.connections[connectionIndex]; reject(`Failed to connect to ${server}`); }, 5000); connection.once("connect", () => { @@ -66,24 +95,35 @@ exports.connect = (server) => { connection.on("error", (e) => { console.error(e); }); - connections.push(connection); + this.connections.push(connection); resolve(); }); }; +exports.disconnect = async () => { + for (const connection of this.connections) { + connection.destroy(); + } + for (const uuid of Object.keys(jobs)) { + jobs[uuid].emit("error", new Error("Job ended prematurely (not really an error; just run your image job again)")); + } + this.connections = []; + return; +}; + const getIdeal = () => { return new Promise((resolve, reject) => { - let serversLeft = connections.length; + let serversLeft = this.connections.length; const idealServers = []; const timeout = setTimeout(async () => { try { const server = await chooseServer(idealServers); - resolve(connections.find(val => val.remoteAddress === server.addr)); + resolve(this.connections.find(val => val.remoteAddress === server.addr)); } catch (e) { reject(e); } }, 5000); - for (const connection of connections) { + for (const connection of this.connections) { if (!connection.remoteAddress) continue; fetch(`http://${connection.remoteAddress}:8081/status`).then(statusRequest => statusRequest.text()).then(async (status) => { serversLeft--; @@ -94,7 +134,7 @@ const getIdeal = () => { if (!serversLeft) { clearTimeout(timeout); const server = await chooseServer(idealServers); - resolve(connections.find(val => val.remoteAddress === server.addr)); + resolve(this.connections.find(val => val.remoteAddress === server.addr)); } return; }).catch(e => reject(e)); @@ -150,7 +190,7 @@ exports.getType = async (image) => { return undefined; } let type; - const controller = new AbortController(); + const controller = new AbortController(); // eslint-disable-line no-undef const timeout = setTimeout(() => { controller.abort(); }, 25000); @@ -183,13 +223,15 @@ exports.run = object => { const num = Math.floor(Math.random() * 100000).toString().slice(0, 5); const timeout = setTimeout(() => { if (jobs[num]) delete jobs[num]; - reject("Request timed out"); + reject("the image request timed out after 25 seconds. Try uploading your image elsewhere."); }, 25000); start(object, num).catch(err => { // incredibly hacky code incoming + clearTimeout(timeout); if (err instanceof Error) return reject(err); return err; }).then((data) => { clearTimeout(timeout); + if (!data.event) reject("Not connected to image server"); data.event.once("image", (image, type) => { delete jobs[data.uuid]; const payload = { diff --git a/utils/imagedetect.js b/utils/imagedetect.js index b336f24..3467c8f 100644 --- a/utils/imagedetect.js +++ b/utils/imagedetect.js @@ -1,4 +1,3 @@ -const client = require("./client.js"); const fetch = require("node-fetch"); const url = require("url"); const { getType } = require("./image.js"); @@ -93,7 +92,7 @@ const checkImages = async (message) => { }; // this checks for the latest message containing an image and returns the url of the image -module.exports = async (cmdMessage) => { +module.exports = async (client, cmdMessage) => { // we start by checking the current message for images const result = await checkImages(cmdMessage); if (result !== false) return result; diff --git a/utils/logger.js b/utils/logger.js index 2777c04..1cdd451 100644 --- a/utils/logger.js +++ b/utils/logger.js @@ -1,15 +1,4 @@ -const moment = require("moment"); -const winston = require("winston"); -const logger = winston.createLogger({ - transports: [ - new winston.transports.Console(), - new winston.transports.File({ filename: "logs/error.log", level: "error" }), - new winston.transports.File({ filename: "logs/main.log" }), - ], - format: winston.format.printf(log => `[${moment().format("YYYY-MM-DD HH:mm:ss")}]: [${log.level.toUpperCase()}] - ${log.message}`) -}); - -exports.log = (type, content) => content ? logger.log(type, content) : logger.log("info", type); +exports.log = (type, content) => content ? process.send({ name: type, msg: content }) : process.send({ name: "info", msg: type }); exports.error = (...args) => this.log("error", ...args); diff --git a/utils/misc.js b/utils/misc.js index 11bdb9f..bc862e1 100644 --- a/utils/misc.js +++ b/utils/misc.js @@ -1,5 +1,4 @@ const util = require("util"); -const client = require("./client.js"); // random(array) to select a random entry in array exports.random = (array) => { @@ -34,14 +33,6 @@ exports.clean = async (text) => { return text; }; -exports.getRandomMessage = async () => { - const messages = await client.guilds.get("631290275456745502").channels.get("631290275888627713").getMessages(50); - const randomMessage = this.random(messages); - if (randomMessage.content.length > 144) return await this.getRandomMessage(); - if (randomMessage.content.match(/<@!?\d+>/g)) return await this.getRandomMessage(); - return randomMessage.content; -}; - // regexEscape(string) to escape characters in a string for use in a regex exports.regexEscape = (string) => { return string.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); // $& means the whole matched string diff --git a/utils/pagination/awaitmessages.js b/utils/pagination/awaitmessages.js index a0db2a6..0c0a44e 100644 --- a/utils/pagination/awaitmessages.js +++ b/utils/pagination/awaitmessages.js @@ -1,9 +1,8 @@ // eris doesn't come with an awaitMessages method by default, so we make our own const EventEmitter = require("events").EventEmitter; -const client = require("../client.js"); class MessageCollector extends EventEmitter { - constructor(channel, filter, options = {}) { + constructor(client, channel, filter, options = {}) { super(); this.filter = filter; this.channel = channel; diff --git a/utils/pagination/awaitreactions.js b/utils/pagination/awaitreactions.js index 942ac96..f8d51ff 100644 --- a/utils/pagination/awaitreactions.js +++ b/utils/pagination/awaitreactions.js @@ -1,9 +1,8 @@ // eris doesn't come with an awaitReactions method by default, so we make our own const EventEmitter = require("events").EventEmitter; -const client = require("../client.js"); class ReactionCollector extends EventEmitter { - constructor(message, filter, options = {}) { + constructor(client, message, filter, options = {}) { super(); this.filter = filter; this.message = message; @@ -20,7 +19,7 @@ class ReactionCollector extends EventEmitter { if (this.message.id !== message.id) return false; if (this.filter(message, emoji, member)) { this.collected.push({ message: message, emoji: emoji, member: member }); - this.emit("reaction", await client.getMessage(message.channel.id, message.id), emoji, member); + this.emit("reaction", await this.bot.getMessage(message.channel.id, message.id), emoji, member); if (this.collected.length >= this.options.maxMatches) this.stop("maxMatches"); return true; } diff --git a/utils/pagination/pagination.js b/utils/pagination/pagination.js index 7908092..b02e31a 100644 --- a/utils/pagination/pagination.js +++ b/utils/pagination/pagination.js @@ -1,8 +1,7 @@ const ReactionCollector = require("./awaitreactions.js"); const MessageCollector = require("./awaitmessages.js"); -const client = require("../client.js"); -module.exports = async (message, pages, timeout = 120000) => { +module.exports = async (client, message, pages, timeout = 120000) => { const manageMessages = message.channel.guild && message.channel.permissionsOf(client.user.id).has("manageMessages") ? true : false; let page = 0; let currentPage = await message.channel.createMessage(pages[page]); @@ -10,18 +9,18 @@ module.exports = async (message, pages, timeout = 120000) => { for (const emoji of emojiList) { await currentPage.addReaction(emoji); } - const reactionCollector = new ReactionCollector(currentPage, (message, reaction, member) => emojiList.includes(reaction.name) && !member.bot, { time: timeout }); + const reactionCollector = new ReactionCollector(client, currentPage, (message, reaction, member) => emojiList.includes(reaction.name) && !member.bot, { time: timeout }); reactionCollector.on("reaction", async (msg, reaction, member) => { - if (member.id === message.author.id) { + if (member === message.author.id) { switch (reaction.name) { case "◀": page = page > 0 ? --page : pages.length - 1; currentPage = await currentPage.edit(pages[page]); - if (manageMessages) msg.removeReaction("◀", member.id); + if (manageMessages) msg.removeReaction("◀", member); break; case "đŸ”ĸ": message.channel.createMessage(`${message.author.mention}, what page do you want to jump to?`).then(askMessage => { - const messageCollector = new MessageCollector(askMessage.channel, (response) => response.author.id === message.author.id && !isNaN(response.content) && Number(response.content) <= pages.length && Number(response.content) > 0, { + const messageCollector = new MessageCollector(client, askMessage.channel, (response) => response.author.id === message.author.id && !isNaN(response.content) && Number(response.content) <= pages.length && Number(response.content) > 0, { time: timeout, maxMatches: 1 }); @@ -30,7 +29,7 @@ module.exports = async (message, pages, timeout = 120000) => { if (manageMessages) await response.delete(); page = Number(response.content) - 1; currentPage = await currentPage.edit(pages[page]); - if (manageMessages) msg.removeReaction("đŸ”ĸ", member.id); + if (manageMessages) msg.removeReaction("đŸ”ĸ", member); }); }).catch(error => { throw error; @@ -39,7 +38,7 @@ module.exports = async (message, pages, timeout = 120000) => { case "â–ļ": page = page + 1 < pages.length ? ++page : 0; currentPage = await currentPage.edit(pages[page]); - if (manageMessages) msg.removeReaction("â–ļ", member.id); + if (manageMessages) msg.removeReaction("â–ļ", member); break; case "🗑": reactionCollector.emit("end"); diff --git a/utils/screenshot/Dockerfile b/utils/screenshot/Dockerfile deleted file mode 100644 index 61b0ee2..0000000 --- a/utils/screenshot/Dockerfile +++ /dev/null @@ -1,23 +0,0 @@ -# if your install supports docker and you don't want to run chromium directly then you can use this dockerfile instead -# this also comes with a squid proxy to automatically handle errors and some privacy stuff -# adapted from https://github.com/westy92/headless-chrome-alpine/blob/master/Dockerfile - -FROM alpine:edge - -RUN apk --no-cache upgrade && apk add --no-cache chromium squid sudo libstdc++ harfbuzz nss freetype ttf-freefont zlib-dev wait4ports dbus chromium-chromedriver grep - -ENV ALL_PROXY "http://localhost:3128" -RUN echo -e "\nvisible_hostname esmBot\nforwarded_for delete\nvia off\nfollow_x_forwarded_for deny all \ -\nrequest_header_access X-Forwarded-For deny all\nerror_default_language en\n" >> /etc/squid/squid.conf -COPY ./ERR_DNS_FAIL /usr/share/squid/errors/en/ - -RUN adduser esmBot -s /bin/sh -D -WORKDIR /home/esmBot/.internal -COPY ./start.sh . -RUN chmod +x start.sh -RUN echo -e "\nesmBot ALL=(ALL) NOPASSWD:ALL\n" >> /etc/sudoers -USER esmBot - -EXPOSE 9222 - -ENTRYPOINT ["sh", "./start.sh"] \ No newline at end of file diff --git a/utils/screenshot/ERR_DNS_FAIL b/utils/screenshot/ERR_DNS_FAIL deleted file mode 100644 index b8bc2b1..0000000 --- a/utils/screenshot/ERR_DNS_FAIL +++ /dev/null @@ -1,63 +0,0 @@ - - - - - - - - - -
-
- -

An error was encountered while trying to load %H:

-

%z

-
-
- - - diff --git a/utils/screenshot/start.sh b/utils/screenshot/start.sh deleted file mode 100644 index 2e23272..0000000 --- a/utils/screenshot/start.sh +++ /dev/null @@ -1,16 +0,0 @@ -sudo squid -N & chromium-browser \ - --disable-background-networking \ - --disable-default-apps \ - --disable-extensions \ - --disable-gpu \ - --disable-sync \ - --disable-translate \ - --headless \ - --hide-scrollbars \ - --metrics-recording-only \ - --mute-audio \ - --no-first-run \ - --no-sandbox \ - --remote-debugging-address=0.0.0.0 \ - --remote-debugging-port=9222 \ - --safebrowsing-disable-auto-update \ No newline at end of file diff --git a/utils/soundplayer.js b/utils/soundplayer.js index 95c1968..487e31b 100644 --- a/utils/soundplayer.js +++ b/utils/soundplayer.js @@ -1,23 +1,19 @@ -const client = require("./client.js"); const logger = require("./logger.js"); -const paginator = require("./pagination/pagination.js"); const fetch = require("node-fetch"); const fs = require("fs"); -const moment = require("moment"); -require("moment-duration-format"); +const day = require("dayjs"); +const duration = require("dayjs/plugin/duration"); +day.extend(duration); const { Manager } = require("lavacord"); let nodes; exports.players = new Map(); - exports.queues = new Map(); -const skipVotes = new Map(); +exports.skipVotes = new Map(); exports.manager; - exports.status = false; - exports.connected = false; exports.checkStatus = async () => { @@ -29,7 +25,7 @@ exports.checkStatus = async () => { const response = await fetch(`http://${node.host}:${node.port}/version`, { headers: { Authorization: node.password } }).then(res => res.text()); if (response) newNodes.push(node); } catch { - logger.log(`Failed to get status of Lavalink node ${node.host}.`); + logger.error(`Failed to get status of Lavalink node ${node.host}.`); } } nodes = newNodes; @@ -37,7 +33,7 @@ exports.checkStatus = async () => { return this.status; }; -exports.connect = async () => { +exports.connect = async (client) => { this.manager = new Manager(nodes, { user: client.user.id, shards: client.shards.size || 1, @@ -56,11 +52,11 @@ exports.connect = async () => { return length; }; -exports.play = async (sound, message, music = false) => { +exports.play = async (client, sound, message, music = false) => { if (!this.manager) return `${message.author.mention}, the sound commands are still starting up!`; if (!message.channel.guild) return `${message.author.mention}, this command only works in servers!`; if (!message.member.voiceState.channelID) return `${message.author.mention}, you need to be in a voice channel first!`; - if (!message.channel.guild.members.get(client.user.id).permissions.has("voiceConnect") || !message.channel.permissionsOf(client.user.id).has("voiceConnect")) return `${message.author.mention}, I can't join this voice channel!`; + if (!message.channel.permissionsOf(client.user.id).has("voiceConnect")) return `${message.author.mention}, I can't join this voice channel!`; const voiceChannel = message.channel.guild.channels.get(message.member.voiceState.channelID); if (!voiceChannel.permissionsOf(client.user.id).has("voiceConnect")) return `${message.author.mention}, I don't have permission to join this voice channel!`; const player = this.players.get(message.channel.guild.id); @@ -87,40 +83,45 @@ exports.play = async (sound, message, music = false) => { } if (oldQueue && music) { - return `${message.author.mention}, your tune has been added to the queue!`; + return `${message.author.mention}, your tune \`${tracks[0].info.title}\` has been added to the queue!`; } else { - this.nextSong(message, connection, tracks[0].track, tracks[0].info, music, voiceChannel, player ? player.loop : false); + this.nextSong(client, message, connection, tracks[0].track, tracks[0].info, music, voiceChannel, player ? player.loop : false); return; } }; -exports.nextSong = async (message, connection, track, info, music, voiceChannel, loop = false, inQueue = false) => { +exports.nextSong = async (client, message, connection, track, info, music, voiceChannel, loop = false, inQueue = false, lastTrack = null, oldPlaying = null) => { const parts = Math.floor((0 / info.length) * 10); - const playingMessage = await client.createMessage(message.channel.id, !music ? "🔊 Playing sound..." : { - "embed": { - "color": 16711680, - "author": { - "name": "Now Playing", - "icon_url": client.user.avatarURL - }, - "fields": [{ - "name": "ℹī¸ Title:", - "value": info.title - }, - { - "name": "🎤 Artist:", - "value": info.author - }, - { - "name": "đŸ’Ŧ Channel:", - "value": voiceChannel.name - }, - { - "name": `${"â–Ŧ".repeat(parts)}🔘${"â–Ŧ".repeat(10 - parts)}`, - "value": `${moment.duration(0).format("m:ss", { trim: false })}/${info.isStream ? "∞" : moment.duration(info.length).format("m:ss", { trim: false })}` - }] - } - }); + let playingMessage; + if (lastTrack === track) { + playingMessage = oldPlaying; + } else { + playingMessage = await client.createMessage(message.channel.id, !music ? "🔊 Playing sound..." : { + "embed": { + "color": 16711680, + "author": { + "name": "Now Playing", + "icon_url": client.user.avatarURL + }, + "fields": [{ + "name": "ℹī¸ Title:", + "value": info.title + }, + { + "name": "🎤 Artist:", + "value": info.author + }, + { + "name": "đŸ’Ŧ Channel:", + "value": voiceChannel.name + }, + { + "name": `${"â–Ŧ".repeat(parts)}🔘${"â–Ŧ".repeat(10 - parts)}`, + "value": `${day.duration(0).format("m:ss", { trim: false })}/${info.isStream ? "∞" : day.duration(info.length).format("m:ss", { trim: false })}` + }] + } + }); + } await connection.play(track); this.players.set(voiceChannel.guild.id, { player: connection, type: music ? "music" : "sound", host: message.author.id, voiceChannel: voiceChannel, originalChannel: message.channel, loop: loop }); if (inQueue && connection.listeners("error").length === 0) { @@ -154,152 +155,10 @@ exports.nextSong = async (message, connection, track, info, music, voiceChannel, if (music) await client.createMessage(message.channel.id, "🔊 The current voice channel session has ended."); if (playingMessage.channel.messages.get(playingMessage.id)) await playingMessage.delete(); } else { - const track = await fetch(`http://${connection.node.host}:${connection.node.port}/decodetrack?track=${encodeURIComponent(newQueue[0])}`, { headers: { Authorization: connection.node.password } }).then(res => res.json()); - this.nextSong(message, connection, newQueue[0], track, music, voiceChannel, isLooping, true); - if (playingMessage.channel.messages.get(playingMessage.id)) await playingMessage.delete(); + const newTrack = await fetch(`http://${connection.node.host}:${connection.node.port}/decodetrack?track=${encodeURIComponent(newQueue[0])}`, { headers: { Authorization: connection.node.password } }).then(res => res.json()); + this.nextSong(client, message, connection, newQueue[0], newTrack, music, voiceChannel, isLooping, true, track, playingMessage); + if (newQueue[0] !== track && playingMessage.channel.messages.get(playingMessage.id)) await playingMessage.delete(); } }); } -}; - -exports.stop = async (message) => { - if (!message.channel.guild) return `${message.author.mention}, this command only works in servers!`; - if (!message.member.voiceState.channelID) return `${message.author.mention}, you need to be in a voice channel first!`; - if (!message.channel.guild.members.get(client.user.id).voiceState.channelID) return `${message.author.mention}, I'm not in a voice channel!`; - if (this.players.get(message.channel.guild.id).host !== message.author.id) return `${message.author.mention}, only the current voice session host can stop the music!`; - this.manager.leave(message.channel.guild.id); - const connection = this.players.get(message.channel.guild.id).player; - connection.destroy(); - this.players.delete(message.channel.guild.id); - this.queues.delete(message.channel.guild.id); - return "🔊 The current voice channel session has ended."; -}; - -exports.skip = async (message) => { - if (!message.channel.guild) return `${message.author.mention}, this command only works in servers!`; - if (!message.member.voiceState.channelID) return `${message.author.mention}, you need to be in a voice channel first!`; - if (!message.channel.guild.members.get(client.user.id).voiceState.channelID) return `${message.author.mention}, I'm not in a voice channel!`; - const player = this.players.get(message.channel.guild.id); - if (player.host !== message.author.id) { - const votes = skipVotes.has(message.channel.guild.id) ? skipVotes.get(message.channel.guild.id) : { count: 0, ids: [] }; - if (votes.ids.includes(message.author.id)) return `${message.author.mention}, you've already voted to skip!`; - const newObject = { - count: votes.count + 1, - ids: [...votes.ids, message.author.id].filter(item => !!item) - }; - if (votes.count + 1 === 3) { - player.player.stop(message.channel.guild.id); - skipVotes.set(message.channel.guild.id, { count: 0, ids: [] }); - } else { - skipVotes.set(message.channel.guild.id, newObject); - return `🔊 Voted to skip song (${votes.count + 1}/3 people have voted).`; - } - } else { - player.player.stop(message.channel.guild.id); - return; - } -}; - -exports.pause = async (message) => { - if (!message.channel.guild) return `${message.author.mention}, this command only works in servers!`; - if (!message.member.voiceState.channelID) return `${message.author.mention}, you need to be in a voice channel first!`; - if (!message.channel.guild.members.get(client.user.id).voiceState.channelID) return `${message.author.mention}, I'm not in a voice channel!`; - if (this.players.get(message.channel.guild.id).host !== message.author.id) return `${message.author.mention}, only the current voice session host can pause/resume the music!`; - const player = this.players.get(message.channel.guild.id).player; - player.pause(!player.paused ? true : false); - return `🔊 The player has been ${!player.paused ? "paused" : "resumed"}.`; -}; - -exports.playing = async (message) => { - if (!message.channel.guild) return `${message.author.mention}, this command only works in servers!`; - if (!message.member.voiceState.channelID) return `${message.author.mention}, you need to be in a voice channel first!`; - if (!message.channel.guild.members.get(client.user.id).voiceState.channelID) return `${message.author.mention}, I'm not in a voice channel!`; - const player = this.players.get(message.channel.guild.id).player; - if (!player) return `${message.author.mention}, I'm not playing anything!`; - const track = await fetch(`http://${player.node.host}:${player.node.port}/decodetrack?track=${encodeURIComponent(player.track)}`, { headers: { Authorization: player.node.password } }).then(res => res.json()); - const parts = Math.floor((player.state.position / track.length) * 10); - return { - "embed": { - "color": 16711680, - "author": { - "name": "Now Playing", - "icon_url": client.user.avatarURL - }, - "fields": [{ - "name": "ℹī¸ Title:", - "value": track.title ? track.title : "Unknown" - }, - { - "name": "🎤 Artist:", - "value": track.author ? track.author : "Unknown" - }, - { - "name": "đŸ’Ŧ Channel:", - "value": message.channel.guild.channels.get(message.member.voiceState.channelID).name - }, - { - "name": `${"â–Ŧ".repeat(parts)}🔘${"â–Ŧ".repeat(10 - parts)}`, - "value": `${moment.duration(player.state.position).format("m:ss", { trim: false })}/${track.isStream ? "∞" : moment.duration(track.length).format("m:ss", { trim: false })}` - }] - } - }; -}; - -exports.queue = async (message) => { - if (!message.channel.guild) return `${message.author.mention}, this command only works in servers!`; - if (!message.member.voiceState.channelID) return `${message.author.mention}, you need to be in a voice channel first!`; - if (!message.channel.guild.members.get(client.user.id).voiceState.channelID) return `${message.author.mention}, I'm not in a voice channel!`; - if (!message.channel.guild.members.get(client.user.id).permissions.has("addReactions") && !message.channel.permissionsOf(client.user.id).has("addReactions")) return `${message.author.mention}, I don't have the \`Add Reactions\` permission!`; - if (!message.channel.guild.members.get(client.user.id).permissions.has("embedLinks") && !message.channel.permissionsOf(client.user.id).has("embedLinks")) return `${message.author.mention}, I don't have the \`Embed Links\` permission!`; - const queue = this.queues.get(message.channel.guild.id); - const player = this.players.get(message.channel.guild.id); - const tracks = await fetch(`http://${player.player.node.host}:${player.player.node.port}/decodetracks`, { method: "POST", body: JSON.stringify(queue), headers: { Authorization: player.player.node.password, "Content-Type": "application/json" } }).then(res => res.json()); - const trackList = []; - const firstTrack = tracks.shift(); - for (const [i, track] of tracks.entries()) { - trackList.push(`${i + 1}. ${track.info.author} - **${track.info.title}** (${track.info.isStream ? "∞" : moment.duration(track.info.length).format("m:ss", { trim: false })})`); - } - const pageSize = 5; - const embeds = []; - const groups = trackList.map((item, index) => { - return index % pageSize === 0 ? trackList.slice(index, index + pageSize) : null; - }).filter(Boolean); - if (groups.length === 0) groups.push("del"); - for (const [i, value] of groups.entries()) { - embeds.push({ - "embed": { - "author": { - "name": "Queue", - "icon_url": client.user.avatarURL - }, - "color": 16711680, - "footer": { - "text": `Page ${i + 1} of ${groups.length}` - }, - "fields": [{ - "name": "đŸŽļ Now Playing", - "value": `${firstTrack.info.author} - **${firstTrack.info.title}** (${firstTrack.info.isStream ? "∞" : moment.duration(firstTrack.info.length).format("m:ss", { trim: false })})` - }, { - "name": "🔁 Looping?", - "value": player.loop ? "Yes" : "No" - }, { - "name": "🗒ī¸ Queue", - "value": value !== "del" ? value.join("\n") : "There's nothing in the queue!" - }] - } - }); - } - if (embeds.length === 0) return `${message.author.mention}, there's nothing in the queue!`; - return paginator(message, embeds); -}; - -exports.loop = async (message) => { - if (!message.channel.guild) return `${message.author.mention}, this command only works in servers!`; - if (!message.member.voiceState.channelID) return `${message.author.mention}, you need to be in a voice channel first!`; - if (!message.channel.guild.members.get(client.user.id).voiceState.channelID) return `${message.author.mention}, I'm not in a voice channel!`; - if (this.players.get(message.channel.guild.id).host !== message.author.id) return `${message.author.mention}, only the current voice session host can loop the music!`; - const object = this.players.get(message.channel.guild.id); - object.loop = !object.loop; - this.players.set(message.channel.guild.id, object); - return object.loop ? "🔊 The player is now looping." : "🔊 The player is no longer looping."; }; \ No newline at end of file