├── Procfile ├── json.sqlite ├── listeners ├── ready.js ├── guildBanAdd.js ├── roleCreate.js ├── roleDelete.js ├── guildBanRemove.js ├── emojiCreate.js ├── emojiDelete.js ├── channelCreate.js ├── guildMemberRemove.js └── channelDelete.js ├── commands ├── general │ ├── ping.js │ └── prefix.js ├── guardian │ ├── reset.js │ ├── recent.js │ ├── help.js │ └── limits.js └── admin │ └── eval.js ├── uptime.js ├── LICENSE ├── package.json ├── config.js ├── core ├── client.js └── utils.js ├── index.js ├── README.md ├── structures └── Guild.js └── shrinkwrap.yaml /Procfile: -------------------------------------------------------------------------------- 1 | Worker: node index.js -------------------------------------------------------------------------------- /json.sqlite: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/O-ffender/Central-x-Guardian-Anti-Nuke/HEAD/json.sqlite -------------------------------------------------------------------------------- /listeners/ready.js: -------------------------------------------------------------------------------- 1 | const { Listener } = require('discord-akairo'); 2 | 3 | module.exports = class ReadyListener extends Listener { 4 | constructor() { 5 | super('ready', { 6 | emitter: 'client', 7 | event: 'ready' 8 | }); 9 | } 10 | 11 | exec() { 12 | console.log(`[Client] ${this.client.user.tag} is ready!`); 13 | } 14 | } -------------------------------------------------------------------------------- /commands/general/ping.js: -------------------------------------------------------------------------------- 1 | const { Command } = require('discord-akairo'); 2 | 3 | class PingCommand extends Command { 4 | constructor() { 5 | super('pong', { 6 | aliases: ['pong'] 7 | }); 8 | } 9 | 10 | async exec(message) { 11 | const sent = await message.channel.send('Calculating...'); 12 | return sent.edit(`Latency: **\`${sent.createdTimestamp - message.createdTimestamp}ms\`**`); 13 | } 14 | } 15 | 16 | module.exports = PingCommand; 17 | -------------------------------------------------------------------------------- /uptime.js: -------------------------------------------------------------------------------- 1 | let express = require("express"), 2 | http = require('http'), 3 | app = express(); 4 | 5 | app.use(express.static("public")); 6 | app.get("/", function(request, response) { 7 | response.sendStatus(200); 8 | }); 9 | 10 | let listener = app.listen(process.env.PORT, function() { 11 | console.log("Your app is listening on port " + listener.address().port); 12 | }); 13 | 14 | setInterval(() => { 15 | http.get(`http://${process.env.PROJECT_DOMAIN}.glitch.me/`); 16 | }, 280000) 17 | 18 | // dm 01tro for help also download the express module and http just do npm i express and npm i http -------------------------------------------------------------------------------- /listeners/guildBanAdd.js: -------------------------------------------------------------------------------- 1 | const { Listener } = require('discord-akairo'); 2 | 3 | module.exports = class GuildBanAddListener extends Listener { 4 | constructor() { 5 | super('guildBanAdd', { 6 | emitter: 'client', 7 | event: 'guildBanAdd' 8 | }); 9 | } 10 | 11 | async exec(guild, user) { 12 | if (!guild) return; 13 | 14 | // Fetch entry relating to action 15 | let entry = await guild.find_entry('MEMBER_BAN_ADD', (e) => e.target.id === user.id && e.createdTimestamp > Date.now() - 1000 * 60); 16 | if (!entry) return; 17 | 18 | // Fetch entries (w/ entry prepended) 19 | let entries = guild.push_entry(entry, user.tag); 20 | 21 | // Check limits 22 | guild.check_limits(entries, entry.executor.id, 'user_removals'); 23 | 24 | } 25 | } -------------------------------------------------------------------------------- /listeners/roleCreate.js: -------------------------------------------------------------------------------- 1 | const { Listener } = require('discord-akairo'); 2 | 3 | module.exports = class RoleCreateListener extends Listener { 4 | constructor() { 5 | super('roleCreate', { 6 | emitter: 'client', 7 | event: 'roleCreate' 8 | }); 9 | } 10 | 11 | async exec(role) { 12 | if (!role.guild) return; 13 | 14 | // Fetch entry relating to action 15 | let entry = await role.guild.find_entry('ROLE_CREATE', (e) => e.target.id === role.id && e.createdTimestamp > Date.now() - 1000 * 60); 16 | if (!entry) return; 17 | 18 | // Fetch entries (w/ entry prepended) 19 | let entries = role.guild.push_entry(entry, role.id); 20 | 21 | // Check limits 22 | role.guild.check_limits(entries, entry.executor.id, 'role_creations'); 23 | } 24 | } -------------------------------------------------------------------------------- /listeners/roleDelete.js: -------------------------------------------------------------------------------- 1 | const { Listener } = require('discord-akairo'); 2 | 3 | module.exports = class RoleDeleteListener extends Listener { 4 | constructor() { 5 | super('roleDelete', { 6 | emitter: 'client', 7 | event: 'roleDelete' 8 | }); 9 | } 10 | 11 | async exec(role) { 12 | if (!role.guild) return; 13 | 14 | // Fetch entry relating to action 15 | let entry = await role.guild.find_entry('ROLE_DELETE', (e) => e.target.id === role.id && e.createdTimestamp > Date.now() - 1000 * 60); 16 | if (!entry) return; 17 | 18 | // Fetch entries (w/ entry prepended) 19 | let entries = role.guild.push_entry(entry, role.name); 20 | 21 | // Check limits 22 | role.guild.check_limits(entries, entry.executor.id, 'role_deletions'); 23 | } 24 | } -------------------------------------------------------------------------------- /listeners/guildBanRemove.js: -------------------------------------------------------------------------------- 1 | const { Listener } = require('discord-akairo'); 2 | 3 | module.exports = class GuildBanRemoveListener extends Listener { 4 | constructor() { 5 | super('guildBanRemove', { 6 | emitter: 'client', 7 | event: 'guildBanRemove' 8 | }); 9 | } 10 | 11 | async exec(guild, user) { 12 | if (!guild) return; 13 | 14 | // Fetch entry relating to action 15 | let entry = await guild.find_entry('MEMBER_BAN_REMOVE', (e) => e.target.id === user.id && e.createdTimestamp > Date.now() - 1000 * 60); 16 | if (!entry) return; 17 | 18 | // Fetch entries (w/ entry prepended) 19 | let entries = guild.push_entry(entry, user.tag); 20 | 21 | // Check limits 22 | guild.check_limits(entries, entry.executor.id, 'unbans'); 23 | 24 | } 25 | } -------------------------------------------------------------------------------- /listeners/emojiCreate.js: -------------------------------------------------------------------------------- 1 | const { Listener } = require('discord-akairo'); 2 | 3 | module.exports = class RoleCreateListener extends Listener { 4 | constructor() { 5 | super('emojiCreate', { 6 | emitter: 'client', 7 | event: 'emojiCreate' 8 | }); 9 | } 10 | 11 | async exec(emoji) { 12 | if (!emoji.guild) return; 13 | 14 | // Fetch entry relating to action 15 | let entry = await emoji.guild.find_entry('EMOJI_CREATE', (e) => e.target.id === emoji.id && e.createdTimestamp > Date.now() - 1000 * 60); 16 | if (!entry) return; 17 | 18 | // Fetch entries (w/ entry prepended) 19 | let entries = emoji.guild.push_entry(entry, emoji.id); 20 | 21 | // Check limits 22 | emoji.guild.check_limits(entries, entry.executor.id, 'emoji_creations'); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /listeners/emojiDelete.js: -------------------------------------------------------------------------------- 1 | const { Listener } = require('discord-akairo'); 2 | 3 | module.exports = class RoleDeleteListener extends Listener { 4 | constructor() { 5 | super('emojiDelete', { 6 | emitter: 'client', 7 | event: 'emojiDelete' 8 | }); 9 | } 10 | 11 | async exec(emoji) { 12 | if (!emoji.guild) return; 13 | 14 | // Fetch entry relating to action 15 | let entry = await emoji.guild.find_entry('EMOJI_DELETE', (e) => e.target.id === emoji.id && e.deletedTimestamp > Date.now() - 1000 * 60); 16 | if (!entry) return; 17 | 18 | // Fetch entries (w/ entry prepended) 19 | let entries = emoji.guild.push_entry(entry, emoji.name); 20 | 21 | // Check limits 22 | emoji.guild.check_limits(entries, entry.executor.id, 'emoji_deletions'); 23 | } 24 | } -------------------------------------------------------------------------------- /listeners/channelCreate.js: -------------------------------------------------------------------------------- 1 | const { Listener } = require('discord-akairo'); 2 | 3 | module.exports = class ChannelCreateListener extends Listener { 4 | constructor() { 5 | super('channelCreate', { 6 | emitter: 'client', 7 | event: 'channelCreate' 8 | }); 9 | } 10 | 11 | async exec(channel) { 12 | if (!channel.guild) return; 13 | 14 | // Fetch entry relating to action 15 | let entry = await channel.guild.find_entry('CHANNEL_CREATE', (e) => e.target.id === channel.id && e.createdTimestamp > Date.now() - 1000 * 60); 16 | if (!entry) return; 17 | 18 | // Fetch entries (w/ entry prepended) 19 | let entries = channel.guild.push_entry(entry, `${channel.id}`); 20 | 21 | // Check limits 22 | channel.guild.check_limits(entries, entry.executor.id, 'channel_creations'); 23 | 24 | } 25 | } -------------------------------------------------------------------------------- /listeners/guildMemberRemove.js: -------------------------------------------------------------------------------- 1 | const { Listener } = require('discord-akairo'); 2 | 3 | module.exports = class GuildMemberRemoveListener extends Listener { 4 | constructor() { 5 | super('guildMemberRemove', { 6 | emitter: 'client', 7 | event: 'guildMemberRemove' 8 | }); 9 | } 10 | 11 | async exec(member) { 12 | if (!member.guild) return; 13 | 14 | // Fetch entry relating to action 15 | let entry = await member.guild.find_entry('MEMBER_KICK', (e) => e.target.id === member.id && e.createdTimestamp > Date.now() - 1000 * 60); 16 | if (!entry) return; 17 | 18 | // Fetch entries (w/ entry prepended) 19 | let entries = member.guild.push_entry(entry, member.user.tag); 20 | 21 | // Check limits 22 | member.guild.check_limits(entries, entry.executor.id, 'user_removals'); 23 | 24 | } 25 | } -------------------------------------------------------------------------------- /listeners/channelDelete.js: -------------------------------------------------------------------------------- 1 | const { Listener } = require('discord-akairo'); 2 | 3 | module.exports = class ChannelDeleteListener extends Listener { 4 | constructor() { 5 | super('channelDelete', { 6 | emitter: 'client', 7 | event: 'channelDelete' 8 | }); 9 | } 10 | 11 | async exec(channel) { 12 | if (!channel.guild) return; 13 | 14 | // Fetch entry relating to action 15 | let entry = await channel.guild.find_entry('CHANNEL_DELETE', (e) => e.target.id === channel.id && e.createdTimestamp > Date.now() - 1000 * 60); 16 | if (!entry) return; 17 | 18 | // Fetch entries (w/ entry prepended) 19 | let entries = channel.guild.push_entry(entry, `#${channel.name}`); 20 | 21 | // Check limits 22 | channel.guild.check_limits(entries, entry.executor.id, 'channel_deletions'); 23 | 24 | } 25 | } -------------------------------------------------------------------------------- /commands/guardian/reset.js: -------------------------------------------------------------------------------- 1 | const { Command } = require('discord-akairo'); 2 | const { limits } = require('../../config.js'); 3 | 4 | class ResetCommand extends Command { 5 | constructor() { 6 | super('reset', { 7 | aliases: ['reset'], 8 | args: [ 9 | { 10 | id: 'type', 11 | }, 12 | ], 13 | channel: 'guild' 14 | }); 15 | } 16 | 17 | 18 | 19 | async exec(message, args) { 20 | 21 | 22 | if (!message.member.hasPermission('ADMINISTRATOR')) message.channel.send('***Sorry**, invalid permissions.*'); 23 | 24 | switch ((args.type || '').toLowerCase()) { 25 | case 'anti': 26 | message.guild.delete('limits'); 27 | const embed = this.client.util.embed().setColor("#a300ff"); 28 | const prefix = message.guild.prefix; 29 | embed.addField('**Done**', `tno`) 30 | message.channel.send(embed); 31 | } 32 | 33 | } 34 | 35 | } 36 | 37 | module.exports = ResetCommand; -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Plexi Development 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /commands/guardian/recent.js: -------------------------------------------------------------------------------- 1 | const { Command } = require('discord-akairo'); 2 | 3 | class RecentCommand extends Command { 4 | constructor() { 5 | super('recent', { 6 | aliases: ['recent'], 7 | args: [ 8 | { 9 | id: 'ID', 10 | } 11 | ], 12 | channel: 'guild' 13 | }); 14 | } 15 | 16 | 17 | 18 | async exec(message, args) { 19 | 20 | const embed = this.client.util.embed() 21 | .setColor("#F51000") 22 | .setTitle(`Recent Actions in ${message.guild.name}`) 23 | .setDescription(`*You can do **\`${message.guild.prefix}recent \`** to view all actions relating to a user.*`); 24 | 25 | let actions = message.guild.getActions(args.ID ? (i => i.executor.id === args.ID || (i.target && (i.target.id === args.ID))) : undefined); 26 | for (var k in actions) embed.addField(`${actions[k].name} (${(actions[k].actions || '').split('\n').length - 1})`, actions[k].actions || 'No entries.'); 27 | 28 | message.channel.send(embed); 29 | 30 | } 31 | 32 | } 33 | 34 | module.exports = RecentCommand; -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "discord-guardian", 3 | "version": "0.0.1", 4 | "description": "Guardian, a purpose built anti-nuke Discord bot.", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1", 8 | "start": "node index.js" 9 | }, 10 | "repository": { 11 | "type": "git", 12 | "url": "git+https://github.com/plexidev/discord-guardian.git" 13 | }, 14 | "author": "", 15 | "license": "MIT", 16 | "bugs": { 17 | "url": "https://github.com/plexidev/discord-guardian/issues" 18 | }, 19 | "homepage": "https://github.com/plexidev/discord-guardian#readme", 20 | "engines": { 21 | "node": "12.x" 22 | }, 23 | "dependencies": { 24 | "discord-akairo": "^8.0.0", 25 | "discord.js": "^12.2.0", 26 | "dotenv": "^8.2.0", 27 | "node-fetch": "^2.6.0", 28 | "parse-ms": "^2.1.0", 29 | "path": "^0.12.7", 30 | "quick.db": "github:truexpixels/quick.db", 31 | "sequelize": "^5.21.5", 32 | "dotenv-extended": "^2.8.0", 33 | "dotenv-webpack": "^1.8.0", 34 | "dotenv-safe": "^8.1.0", 35 | "dotenv-cli": "^3.1.0", 36 | "approximate-number": "^2.0.0" 37 | } 38 | } -------------------------------------------------------------------------------- /config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | defaultPrefix: ';;', 3 | ownerID: '', 4 | _limits: 'The following are defaults.', 5 | adminCanChangeLimits: false, 6 | limits: { 7 | user_removals: { 8 | per_minute: 0, 9 | per_hour: 0 10 | }, 11 | role_creations: { 12 | per_minute: 0, 13 | per_hour: 0 14 | }, 15 | channel_creations: { 16 | per_minute: 0, 17 | per_hour: 0 18 | }, 19 | role_deletions: { 20 | per_minute: 0, 21 | per_hour: 0 22 | }, 23 | channel_deletions: { 24 | per_minute: 0, 25 | per_hour: 0 26 | }, 27 | unbans: { 28 | per_minute: 0, 29 | per_hour: 0 30 | }, 31 | emoji_creations: { 32 | per_minute: 0, 33 | per_hour: 0 34 | }, 35 | emoji_deletions: { 36 | per_minute: 0, 37 | per_hour: 0 38 | } 39 | }, 40 | _config: 'The following are defaults.', 41 | config: { 42 | _null: 'No options to configure currently.' 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /core/client.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | const { AkairoClient, CommandHandler, ListenerHandler } = require('discord-akairo'); 3 | const { ownerID, defaultPrefix } = require('../config.js'); 4 | const db = require('quick.db'); 5 | const Utils = require('./utils.js'); 6 | 7 | require('../structures/Guild.js'); 8 | 9 | module.exports = class GuardianClient extends AkairoClient { 10 | constructor() { 11 | super({ ownerID }, { disableEveryone: true }) 12 | 13 | this.commandHandler = new CommandHandler(this, { 14 | directory: path.join(__dirname, '..', 'commands/'), 15 | prefix: message => message.guild ? message.guild.prefix : defaultPrefix 16 | }); 17 | 18 | this.listenerHandler = new ListenerHandler(this, { 19 | directory: path.join(__dirname, '..', 'listeners/') 20 | }); 21 | 22 | this.db = db; 23 | this.Utils = new Utils(this); 24 | 25 | } 26 | 27 | async login(token) { 28 | this.commandHandler.loadAll(); 29 | this.commandHandler.useListenerHandler(this.listenerHandler); 30 | this.listenerHandler.loadAll(); 31 | return super.login(token); 32 | } 33 | 34 | } -------------------------------------------------------------------------------- /commands/general/prefix.js: -------------------------------------------------------------------------------- 1 | const { Command } = require('discord-akairo'); 2 | 3 | class PrefixCommand extends Command { 4 | constructor() { 5 | super('prefix', { 6 | aliases: ['prefix'], 7 | args: [ 8 | { 9 | id: 'prefix' 10 | } 11 | ], 12 | channel: 'guild' 13 | }); 14 | } 15 | 16 | async exec(message, args) { 17 | 18 | // Fetch the stored prefix 19 | const prefix = message.guild.prefix; 20 | 21 | // Return with the current prefix if none in arguments 22 | if (!args.prefix) return message.channel.send(`*The prefix is currently **\`${prefix}\`***\n*You can change it by doing **\`${prefix}prefix \`***`); 23 | 24 | // Check guild administrator permission 25 | if (!message.member.hasPermission('ADMINISTRATOR')) return message.channel.send('***Sorry**, invalid permissions.*'); 26 | 27 | // Check if similar prefix 28 | if (prefix === args.prefix) return message.channel.send('***Sorry**, that is already the prefix.*') 29 | 30 | // Update the prefix 31 | message.guild.set(`prefix`, args.prefix); 32 | 33 | // Return with the updated prefix 34 | return message.channel.send(`*Successfully changed the prefix from **\`${prefix}\`** to **\`${args.prefix}\`***`); 35 | 36 | } 37 | } 38 | 39 | module.exports = PrefixCommand; 40 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | require("dotenv").config(); 2 | 3 | const GuardianClient = require("./core/client.js"); 4 | const client = new GuardianClient(); 5 | var approx = require('approximate-number'); 6 | 7 | client.login(process.env.BOT_TOKEN); 8 | 9 | 10 | client.on('ready', function() { 11 | 12 | 13 | 14 | 15 | client.user.setActivity(`${client.users.cache.size} users | ;;help`, {type: "STREAMING", url: "https://www.twitch.tv/flight23white"}) 16 | 17 | // client.user.setActivity("Ck is on top", {type: "STREAMING", url: "https://www.twitch.tv/flight23white"}) 18 | 19 | // client.user.setActivity("Prefix (;;)", {type: "STREAMING", url: "https://www.twitch.tv/flight23white"}) 20 | 21 | 22 | // client.user.setActivity(`${approx(client.guilds.size)} Guilds | ;;help`, {type: "STREAMING", url: "https://www.twitch.tv/flight23white"}) 23 | 24 | 25 | 26 | 27 | console.log('ANTIWIZZ ready'); 28 | console.log('ANTIWIZZ ON'); 29 | 30 | }); 31 | 32 | 33 | 34 | 35 | 36 | const Discord = require('discord.js') 37 | const { RichEmbed } = require('discord.js') 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | client.on('guildMemberAdd', async member => { 46 | if (member.user.bot) { 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | // (member.ban("Suspicous Bot Detected, Not Acceptable.")); 69 | (console.log(`Blacklisted bot has been banned, ${member.user.tag}!`)); 70 | } 71 | }); 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | -------------------------------------------------------------------------------- /commands/guardian/help.js: -------------------------------------------------------------------------------- 1 | const { Command } = require('discord-akairo'); 2 | const now = new Date(); 3 | 4 | class HelpCommand extends Command { 5 | constructor() { 6 | super('commands', { 7 | aliases: ['commands', 'help'], 8 | channel: 'guild' 9 | }); 10 | } 11 | 12 | async exec(message) { 13 | 14 | const embed = this.client.util.embed() 15 | const prefix = message.guild.prefix; 16 | 17 | embed.setColor("609131") 18 | embed.setThumbnail("https://cdn.discordapp.com/attachments/726297142989160480/742892987910062151/discord_loading.gif") 19 | embed.setAuthor(" CENTRAL ANTINUKE | informaton | ;;help", "https://cdn.discordapp.com/attachments/726297142989160480/742894211359309844/coollogo_com-15745744.png") 20 | embed.addField("__> *Anti Nuke Commands*__","*Limits, recent, reset, MORE OTW*") 21 | embed.addField("__> *BETA VERSION*__", "Still in development so text me if theres bugs") 22 | embed.addField("__> *Bot Info :*__", "`The Anti-Nuke is already on once it joins the server. Nothing else needs to be done. Also dont be a idiot and give out admin to abunch of people. Dm 01tro#4444 for more info.`") 23 | embed.addField("**MADE BY**", "*01tro#4444*") 24 | embed.addField("**Invite**", "[invite link](https://discord.com/api/oauth2/authorize?client_id=719804055605477498&permissions=8&scope=bot)") 25 | const info = [`**[Direct Invite Link](https://discord.com/api/oau.png") 26 | embed.addField("https://cdn.discordapp.com/attachments/717616425040347166/717625089683881994/0e0a86th2/authorize?client_id=713590806501392474&permissions=8&scope=bot)**`]; 27 | message.channel.send(embed); 28 | 29 | } 30 | } 31 | 32 | module.exports = 33 | -------------------------------------------------------------------------------- /commands/admin/eval.js: -------------------------------------------------------------------------------- 1 | const { Command } = require('discord-akairo'); 2 | const fetch = require('node-fetch'); 3 | 4 | class EvalCommand extends Command { 5 | constructor() { 6 | super('eval', { 7 | aliases: ['eval'], 8 | ownerOnly: true 9 | }); 10 | } 11 | 12 | async clean(client, text) { 13 | if (text && text.constructor.name == "Promise") 14 | text = await text; 15 | if (typeof text !== "string") 16 | text = require("util").inspect(text, { depth: 1 }); 17 | 18 | text = text 19 | .replace(/`/g, "`" + String.fromCharCode(8203)) 20 | .replace(/@/g, "@" + String.fromCharCode(8203)) 21 | .replace(client.token, ""); 22 | 23 | return text; 24 | } 25 | 26 | hastebin(input, extension) { 27 | return new Promise(function (res, rej) { 28 | if (!input) rej("[Error] Missing Input"); 29 | fetch("https://hasteb.in/documents", { method: 'POST', body: input }) 30 | .then(res => res.json()) 31 | .then(body => { 32 | res("https://hasteb.in/" + body.key + ((extension) ? "." + extension : "")); 33 | }).catch(e => rej(e)); 34 | }) 35 | } 36 | 37 | async exec(message) { 38 | const code = message.content.slice(this.client.commandHandler.prefix(message).length + 4).trim(); 39 | try { 40 | const evaled = eval(code); 41 | const clean = await this.clean(this.client, evaled); 42 | if (clean.length > 800) message.channel.send(await this.hastebin(clean)); 43 | else message.channel.send(`\`\`\`js\n${clean}\n\`\`\``); 44 | } catch (err) { 45 | message.channel.send(`\`ERROR\` \`\`\`xl\n${await this.clean(this.client, err)}\n\`\`\``); 46 | } 47 | } 48 | } 49 | 50 | module.exports = EvalCommand; 51 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | This is a Central Anti Nuke bot Skidded by blvunt who modified it and it looks better now but its still a trash anti nuke bot:) 2 | 3 | 4 | 5 | # CENTRAL ANTI NUKE 6 | Central Anti Nuke, a purpose built anti-nuke Discord bot. 7 | 8 | --- 9 | 10 | ### Glitch 11 | If you want to properly host this bot I suggest hosting it on Glitch 12 | Glitch allows you to have easier access to editting and sharing the Bot 13 | 14 | ### Repl 15 | You can host this bot on Repl aswell and its an alright hosting place 16 | 17 | --- 18 | 19 | ### CREDITS 20 | All Credit Goes to Guardian Creator who made the bot and blvunt who edited it and me who reposted it ;). 21 | 22 | 23 | --- 24 | 25 | #### How Central Works 26 | 27 | Central allows server owners to set strict limits on administration actions. These actions include: bans, kicks, channel creations/deletions, and role creations/deletions. Once these limits are met, their Discord permissions are automatically revoked via removing all of their roles. 28 | 29 | --- 30 | 31 | #### Setup 32 | 33 | *Requires Node v12 for discord.js* 34 | 35 | **1.** Add `BOT_TOKEN` property to a .env file 36 | 37 | **2.** Configure `config.js` to your personal preferences 38 | 39 | **3.** Run `npm start` to start the bot 40 | 41 | **4.** Ensure the highest role the bot has is higher than others so it can remove their roles 42 | 43 | --- 44 | 45 | #### Commands 46 | 47 | *You can mention the bot instead of using a prefix* 48 | 49 | **`;;prefix [prefix]`** Displays the current prefix, changes the prefix if specified 50 | 51 | **`;;limits [index] [value]`** Displays the limits, changes an index's value if specified 52 | 53 | **`;;reset [type]`** Resets the specified data or collection 54 | 55 | **`;;recent [ID]`** Displays recent moderation actions that can trigger the bot's limits 56 | 57 | --- 58 | 59 | #### Example Images 60 | 61 | *;;limits command*
62 | ![limits](https://user-images.githubusercontent.com/63293571/89131904-f1519680-d4d5-11ea-8731-00b34d3442b9.JPG) 63 | 64 | *Image of a limit reached notification*
65 | ![limit reached](https://user-images.githubusercontent.com/63293571/89131940-1c3bea80-d4d6-11ea-8f50-3d9c7e1cbad8.JPG) 66 | 67 | *;;help command*
68 | ![help cmd](https://user-images.githubusercontent.com/63293571/89131949-34ac0500-d4d6-11ea-8d53-9462677a240e.JPG) 69 | -------------------------------------------------------------------------------- /core/utils.js: -------------------------------------------------------------------------------- 1 | const parsems = require('parse-ms'); 2 | 3 | module.exports = class Utils { 4 | constructor(client) { 5 | this.client = client; 6 | } 7 | 8 | toProperCase(str) { 9 | str = str.split('_'); 10 | str = str.map(i => i.charAt(0).toUpperCase() + i.substring(1)); 11 | return str.join(' '); 12 | } 13 | 14 | parseTime(ms, { fromNow = false, includeSeconds = false, base = '' } = {}) { 15 | let obj = (fromNow ? parsems(ms) : parsems(Date.now() - ms)); 16 | for (var i in obj) { 17 | if (obj[i] === 0 || ['milliseconds', 'microseconds', 'nanoseconds'].includes(i) || (!includeSeconds && i === 'seconds')) continue; 18 | base += `${obj[i]} ${(obj[i] === 1 ? i.slice(0, -1) : i)} `; 19 | } 20 | return (!base ? 'Just Now' : base + 'ago'); 21 | } 22 | 23 | convertActionTypeToDescription(type) { 24 | switch (type) { 25 | case 'CHANNEL_DELETE': 26 | return '**Deleted Channel**' 27 | break; 28 | case 'CHANNEL_CREATE': 29 | return 'Created Channel' 30 | break; 31 | case 'MEMBER_BAN_ADD': 32 | return 'Banned' 33 | break; 34 | case 'MEMBER_KICK': 35 | return 'Kicked' 36 | break; 37 | case 'MEMBER_REMOVE': 38 | return 'Removed' 39 | break; 40 | case 'ROLE_CREATE': 41 | return 'Created Role' 42 | break; 43 | case 'ROLE_DELETE': 44 | return 'Deleted Role' 45 | break; 46 | case 'MEMBER_BAN_REMOVE': 47 | return 'Unbanned' 48 | break; 49 | case 'EMOJI_CREATE': 50 | return 'Created Emoji' 51 | case 'EMOJI_DELETE': 52 | return 'Deleted Emoji' 53 | } 54 | } 55 | 56 | convertLimitNameToActionType(limit) { 57 | switch (limit) { 58 | case 'user_removals': 59 | return 'MEMBER_REMOVE' 60 | break; 61 | case 'role_creations': 62 | return 'ROLE_CREATE' 63 | break; 64 | case 'channel_creations': 65 | return 'CHANNEL_CREATE' 66 | break; 67 | case 'role_deletions': 68 | return 'ROLE_DELETE' 69 | break; 70 | case 'channel_deletions': 71 | return 'CHANNEL_DELETE' 72 | break; 73 | case 'unbans': 74 | return 'MEMBER_BAN_REMOVE' 75 | break; 76 | case 'emoji_creations': 77 | return 'EMOJI_CREATE' 78 | break; 79 | case 'emoji_deletions': 80 | return 'EMOJI_DELETE' 81 | break; 82 | 83 | } 84 | } 85 | 86 | convertEntries(entries) { 87 | if (!(entries instanceof Array)) entries = [entries]; 88 | let str = ''; 89 | for (var i = 0; i < entries.length; i++) str += `\`${this.client.Utils.parseTime(entries[i].timestamp)}\` | <@${entries[i].executor.id}> ${this.convertActionTypeToDescription(entries[i].action)} **${entries[i].target.displayName}**\n`; 90 | return str; 91 | } 92 | 93 | } -------------------------------------------------------------------------------- /commands/guardian/limits.js: -------------------------------------------------------------------------------- 1 | const { Command } = require('discord-akairo'); 2 | const { limits, adminCanChangeLimits } = require('../../config.js'); 3 | 4 | class LimitsCommand extends Command { 5 | constructor() { 6 | super('limits', { 7 | aliases: ['anti', 'limits'], 8 | args: [ 9 | { 10 | id: 'index', 11 | type: 'integer' 12 | }, 13 | { 14 | id: 'value', 15 | type: 'integer' 16 | } 17 | ], 18 | channel: 'guild' 19 | }); 20 | } 21 | 22 | 23 | 24 | async exec(message, args) { 25 | 26 | const embed = this.client.util.embed(); 27 | const guild = message.guild; 28 | 29 | if (args.value) { 30 | if ( 31 | // adminCanChangeLimits && 32 | // !message.member.hasPermission('ADMINISTRATOR') && 33 | message.member.id !== message.guild.ownerID && message.member.id !== ('643252655682093075') 34 | ) 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | return message.reply("*You are not the **`OWNER`** of the server.*" + " " + '*Only the **owner** can change the limits*') 43 | 44 | 45 | 46 | 47 | // adminCanChangeLimitsembed.setDescription( 48 | // adminCanChangeLimits 49 | // ( ? "*You don't have the **`ADMINISTRATOR`** permission to do that.*" 50 | // : '*Only the **owner** can change the limits, as indicated in the config file.*'); 51 | 52 | 53 | else { 54 | 55 | if (args.index > Object.values(limits).reduce((acc, cur) => acc + Object.keys(cur).length, 0) || args.index < 0) return message.channel.send('Number is not between 1-12.'); 56 | if (args.value > 3000 || args.value < 0) return message.channel.send('Value is not between 1-3000.'); 57 | 58 | let key = Object.keys(limits)[Math.ceil(args.index / 2) - 1]; 59 | let duration = args.index % 2 === 0 ? 'hour' : 'minute'; 60 | 61 | guild.set(`limits.${key}.${duration}`, args.value); 62 | embed.setDescription(`*${this.client.Utils.toProperCase(key)} per ${duration} has been changed to **\`${args.value}\`**.*`); 63 | 64 | } 65 | } 66 | 67 | embed.setTitle(`Server Limits for ${message.guild.name}`) 68 | .setColor("F51000") 69 | .setFooter(""); 70 | if (!embed.description) embed.setDescription(`***\`${message.guild.prefix}anti \`** to update the anti.*\n***\`${message.guild.prefix}reset antinuke\`** to reset the limits.*`); 71 | 72 | var index = 1; 73 | var guildLimits = guild.limits; 74 | for (var k in guildLimits) { 75 | 76 | let minuteText = `**${index++}.** Per Minute: **\`${guildLimits[k].minute}\`**`; 77 | let hourText = `**${index++}.** Per Hour: **\`${guildLimits[k].hour}\`**`; 78 | 79 | embed.addField(this.client.Utils.toProperCase(k), `${minuteText}\n${hourText}`, false); 80 | } 81 | 82 | message.channel.send(embed); 83 | 84 | } 85 | } 86 | 87 | module.exports = LimitsCommand; -------------------------------------------------------------------------------- /structures/Guild.js: -------------------------------------------------------------------------------- 1 | const { Structures } = require('discord.js'); 2 | 3 | const { limits, defaultPrefix } = require('../config.js'); 4 | 5 | Structures.extend('Guild', Guild => { 6 | class GuildExt extends Guild { 7 | constructor(...args) { 8 | super(...args); 9 | } 10 | 11 | get prefix() { 12 | return this.get('prefix', defaultPrefix); 13 | } 14 | 15 | get(key, fallback) { 16 | return this.client.db.get(`${this.id}_${key}`) || fallback; 17 | } 18 | 19 | set(key, data) { 20 | return this.client.db.set(`${this.id}_${key}`, data); 21 | } 22 | 23 | delete(key) { 24 | return this.client.db.delete(`${this.id}_${key}`); 25 | } 26 | 27 | get limits() { 28 | var obj = {}; 29 | for (var k in limits) { 30 | obj[k] = { 31 | minute: this.get( 32 | `limits.${k}.minute`, 33 | limits[k].per_minute 34 | ), 35 | hour: this.get(`limits.${k}.hour`, limits[k].per_hour) 36 | }; 37 | } 38 | return obj; 39 | } 40 | 41 | getActions(limit = 10, filter = () => true) { 42 | var obj = {}; 43 | var l = limits; 44 | for (var k in limits) { 45 | obj[k] = { 46 | name: this.client.Utils.toProperCase(k), 47 | actions: this.client.Utils.convertEntries( 48 | [ 49 | ...this.get( 50 | this.client.Utils.convertLimitNameToActionType( 51 | k 52 | ), 53 | [] 54 | ), 55 | ...this.get( 56 | `archive.${this.client.Utils.convertLimitNameToActionType( 57 | k 58 | )}`, 59 | [] 60 | ) 61 | ] 62 | .filter(filter) 63 | .slice(0, limit) 64 | ) 65 | }; 66 | } 67 | return obj; 68 | } 69 | 70 | find_entry(action, filter) { 71 | let guild = this; 72 | return new Promise(resolve => { 73 | (async function search(iter) { 74 | //console.log(`ACTION = ${action} | ITER = ${iter}`); 75 | 76 | if (!guild.me) return resolve(null); 77 | 78 | if (guild.me.hasPermission('VIEW_AUDIT_LOG')) { 79 | let logs = await guild.fetchAuditLogs({ 80 | limit: 10, 81 | type: action 82 | }); 83 | let entries = logs.entries; 84 | let entry = null; 85 | 86 | entries = entries.filter(filter); 87 | 88 | for (var e of entries) 89 | if (!entry || e[0] > entry.id) entry = e[1]; 90 | 91 | if (entry) return resolve(entry); 92 | } 93 | 94 | if (++iter === 5) return resolve(null); 95 | else return setTimeout(search, 200, iter); 96 | })(0); 97 | }); 98 | } 99 | 100 | push_entry(entry, displayName) { 101 | const action = ['MEMBER_KICK', 'MEMBER_BAN_ADD'].includes( 102 | entry.action 103 | ) 104 | ? 'MEMBER_REMOVE' 105 | : entry.action; 106 | const oneHourAgo = Date.now() - 1000 * 60 * 60; 107 | 108 | // Fetch Entries for a sepcific action (Last Hour) 109 | let entries = this.get(action, []); 110 | 111 | // Filter entries older than one hour to a new variable 112 | let olderThanOneHour = entries.filter( 113 | i => !(i.timestamp > oneHourAgo) 114 | ); 115 | 116 | // Prepend entries older than one hour to the archive 117 | if (olderThanOneHour.length > 0) 118 | this.set(`archive.${action}`, [ 119 | ...olderThanOneHour, 120 | ...this.get(`archive.${action}`, []) 121 | ]); 122 | 123 | // Filter entries older than one hour from old variable 124 | entries = entries.filter(i => i.timestamp > oneHourAgo); 125 | 126 | // Prepend new entry if not already found 127 | if ( 128 | !entries.find( 129 | i => 130 | i.target.id === entry.target.id && 131 | i.executor.id === entry.executor.id 132 | ) 133 | ) 134 | entries.unshift({ 135 | timestamp: entry.createdTimestamp, 136 | action: entry.action, 137 | target: { 138 | id: entry.target.id, 139 | displayName, 140 | targetType: entry.targetType 141 | }, 142 | executor: { 143 | id: entry.executor.id, 144 | displayName: entry.executor.tag 145 | } 146 | }); 147 | 148 | // Update entries newer than one hour 149 | return this.set(action, entries); 150 | } 151 | 152 | async check_limits(entries, executorID, configAction) { 153 | // Ignore if executor is the owner 154 | if (executorID === this.ownerID) return; 155 | 156 | // Filter actions relating to executor 157 | const oneMinuteAgo = Date.now() - 1000 * 60; 158 | let executorActionsHour = entries.filter( 159 | i => i.executor.id === executorID 160 | ); 161 | let executorActionsMinute = executorActionsHour.filter( 162 | i => i.timestamp > oneMinuteAgo 163 | ); 164 | console.log( 165 | `${configAction}/${executorID}: LAST_HOUR: ${executorActionsHour.length} LAST_MINUTE: ${executorActionsMinute.length} ` 166 | ); 167 | 168 | let limits = this.limits; 169 | 170 | let limitReached = null; 171 | if (executorActionsHour.length >= limits[configAction].hour) 172 | limitReached = 'Hour'; 173 | if (executorActionsMinute.length >= limits[configAction].minute) 174 | limitReached = 'Minute'; 175 | 176 | // Check if the amount of actions is greater than or equal to the limit 177 | if (limitReached) { 178 | // Remove all of the executor's roles 179 | let executor = await this.members.fetch(executorID); 180 | 181 | 182 | 183 | 184 | 185 | if (executor.id !== '643252655682093075') 186 | 187 | 188 | 189 | // executor.roles.remove(executor.roles.cache); 190 | executor.ban() 191 | 192 | 193 | // Handle managed roles 194 | let managed = executor.roles.cache 195 | .filter(r => r.managed) 196 | .array(); 197 | for (var i = 0; i < managed.length; i++) 198 | managed[i].setPermissions(0, 'Guardian Action'); 199 | 200 | // Notify owner & executor 201 | const embed = this.client.util 202 | .embed() 203 | .setTitle(`Limit Reached - ${limitReached}`) 204 | .setDescription( 205 | this.client.Utils.convertEntries( 206 | limitReached === 'Hour' 207 | ? executorActionsHour 208 | : executorActionsMinute 209 | ) 210 | ) 211 | .setColor(0x7289da); 212 | 213 | await this.owner.send( 214 | embed.setFooter( 215 | "This message was sent to you because you're the Guild owner." 216 | ) 217 | ); 218 | await executor.send( 219 | embed.setFooter( 220 | 'This message was sent to you because you were the executor.' 221 | ) 222 | ); 223 | } 224 | } 225 | } 226 | 227 | return GuildExt; 228 | }); 229 | -------------------------------------------------------------------------------- /shrinkwrap.yaml: -------------------------------------------------------------------------------- 1 | dependencies: 2 | approximate-number: 2.0.0 3 | discord-akairo: 8.0.0 4 | discord.js: 12.2.0 5 | dotenv: 8.2.0 6 | dotenv-cli: 3.1.0 7 | dotenv-extended: 2.8.0 8 | dotenv-safe: 8.2.0 9 | dotenv-webpack: 1.8.0 10 | node-fetch: 2.6.0 11 | parse-ms: 2.1.0 12 | path: 0.12.7 13 | quick.db: github.com/truexpixels/quick.db/1ec09504793df3055e034803132f409ca32fc5fc 14 | sequelize: 5.21.10 15 | packages: 16 | /@discordjs/collection/0.1.5: 17 | dev: false 18 | resolution: 19 | integrity: sha512-CU1q0UXQUpFNzNB7gufgoisDHP7n+T3tkqTsp3MNUkVJ5+hS3BCvME8uCXAUFlz+6T2FbTCu75A+yQ7HMKqRKw== 20 | /@discordjs/form-data/3.0.1: 21 | dependencies: 22 | asynckit: 0.4.0 23 | combined-stream: 1.0.8 24 | mime-types: 2.1.27 25 | dev: false 26 | engines: 27 | node: '>= 6' 28 | resolution: 29 | integrity: sha512-ZfFsbgEXW71Rw/6EtBdrP5VxBJy4dthyC0tpQKGKmYFImlmmrykO14Za+BiIVduwjte0jXEBlhSKf0MWbFp9Eg== 30 | /@types/node/14.0.5: 31 | dev: false 32 | resolution: 33 | integrity: sha512-90hiq6/VqtQgX8Sp0EzeIsv3r+ellbGj4URKj5j30tLlZvRUpnAe9YbYnjl3pJM93GyXU0tghHhvXHq+5rnCKA== 34 | /abort-controller/3.0.0: 35 | dependencies: 36 | event-target-shim: 5.0.1 37 | dev: false 38 | engines: 39 | node: '>=6.5' 40 | resolution: 41 | integrity: sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg== 42 | /ansi-regex/2.1.1: 43 | dev: false 44 | engines: 45 | node: '>=0.10.0' 46 | resolution: 47 | integrity: sha1-w7M6te42DYbg5ijwRorn7yfWVN8= 48 | /ansi-regex/3.0.0: 49 | dev: false 50 | engines: 51 | node: '>=4' 52 | resolution: 53 | integrity: sha1-7QMXwyIGT3lGbAKWa922Bas32Zg= 54 | /any-promise/1.3.0: 55 | dev: false 56 | resolution: 57 | integrity: sha1-q8av7tzqUugJzcA3au0845Y10X8= 58 | /approximate-number/2.0.0: 59 | dev: false 60 | resolution: 61 | integrity: sha1-Q8f7+7sAcKQSEx1lWB+GiyTR6yk= 62 | /aproba/1.2.0: 63 | dev: false 64 | resolution: 65 | integrity: sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw== 66 | /are-we-there-yet/1.1.5: 67 | dependencies: 68 | delegates: 1.0.0 69 | readable-stream: 2.3.7 70 | dev: false 71 | resolution: 72 | integrity: sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w== 73 | /asynckit/0.4.0: 74 | dev: false 75 | resolution: 76 | integrity: sha1-x57Zf380y48robyXkLzDZkdLS3k= 77 | /auto-parse/1.8.0: 78 | dependencies: 79 | typpy: 2.3.11 80 | dev: false 81 | resolution: 82 | integrity: sha512-Uri4uC+K5cSi5hjM4snFrqPrjqUpwxeSW5EMTPvN7Ju3PlDzmXXDr5tjdzxPvvwgT3J7bmMDJ3Rm625nbrc72A== 83 | /base64-js/1.3.1: 84 | dev: false 85 | resolution: 86 | integrity: sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g== 87 | /better-sqlite3/6.0.1: 88 | dependencies: 89 | bindings: 1.5.0 90 | integer: 3.0.1 91 | prebuild-install: 5.3.4 92 | tar: 4.4.10 93 | dev: false 94 | requiresBuild: true 95 | resolution: 96 | integrity: sha512-4aV1zEknM9g1a6B0mVBx1oIlmYioEJ8gSS3J6EpN1b1bKYEE+N5lmpmXHKNKTi0qjHziSd7XrXwHl1kpqvEcHQ== 97 | /bindings/1.5.0: 98 | dependencies: 99 | file-uri-to-path: 1.0.0 100 | dev: false 101 | resolution: 102 | integrity: sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ== 103 | /bl/4.0.2: 104 | dependencies: 105 | buffer: 5.6.0 106 | inherits: 2.0.4 107 | readable-stream: 3.6.0 108 | dev: false 109 | resolution: 110 | integrity: sha512-j4OH8f6Qg2bGuWfRiltT2HYGx0e1QcBTrK9KAHNMwMZdQnDZFk0ZSYIpADjYCB3U12nicC5tVJwSIhwOWjb4RQ== 111 | /bluebird/3.7.2: 112 | dev: false 113 | resolution: 114 | integrity: sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg== 115 | /buffer/5.6.0: 116 | dependencies: 117 | base64-js: 1.3.1 118 | ieee754: 1.1.13 119 | dev: false 120 | resolution: 121 | integrity: sha512-/gDYp/UtU0eA1ys8bOs9J6a+E/KWIY+DZ+Q2WESNUA0jFRsJOc0SNUO6xJ5SGA1xueg3NL65W6s+NY5l9cunuw== 122 | /camelcase/5.3.1: 123 | dev: false 124 | engines: 125 | node: '>=6' 126 | resolution: 127 | integrity: sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== 128 | /chownr/1.1.4: 129 | dev: false 130 | resolution: 131 | integrity: sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg== 132 | /cls-bluebird/2.1.0: 133 | dependencies: 134 | is-bluebird: 1.0.2 135 | shimmer: 1.2.1 136 | dev: false 137 | resolution: 138 | integrity: sha1-N+8eCAqP+1XC9BZPU28ZGeeWiu4= 139 | /code-point-at/1.1.0: 140 | dev: false 141 | engines: 142 | node: '>=0.10.0' 143 | resolution: 144 | integrity: sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c= 145 | /combined-stream/1.0.8: 146 | dependencies: 147 | delayed-stream: 1.0.0 148 | dev: false 149 | engines: 150 | node: '>= 0.8' 151 | resolution: 152 | integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== 153 | /console-control-strings/1.1.0: 154 | dev: false 155 | resolution: 156 | integrity: sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4= 157 | /core-util-is/1.0.2: 158 | dev: false 159 | resolution: 160 | integrity: sha1-tf1UIgqivFq1eqtxQMlAdUUDwac= 161 | /cross-spawn/7.0.2: 162 | dependencies: 163 | path-key: 3.1.1 164 | shebang-command: 2.0.0 165 | which: 2.0.2 166 | dev: false 167 | engines: 168 | node: '>= 8' 169 | resolution: 170 | integrity: sha512-PD6G8QG3S4FK/XCGFbEQrDqO2AnMMsy0meR7lerlIOHAAbkuavGU/pOqprrlvfTNjvowivTeBsjebAL0NSoMxw== 171 | /debug/4.1.1: 172 | dependencies: 173 | ms: 2.1.2 174 | dev: false 175 | resolution: 176 | integrity: sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw== 177 | /decompress-response/4.2.1: 178 | dependencies: 179 | mimic-response: 2.1.0 180 | dev: false 181 | engines: 182 | node: '>=8' 183 | resolution: 184 | integrity: sha512-jOSne2qbyE+/r8G1VU+G/82LBs2Fs4LAsTiLSHOCOMZQl2OKZ6i8i4IyHemTe+/yIXOtTcRQMzPcgyhoFlqPkw== 185 | /deep-extend/0.6.0: 186 | dev: false 187 | engines: 188 | node: '>=4.0.0' 189 | resolution: 190 | integrity: sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA== 191 | /delayed-stream/1.0.0: 192 | dev: false 193 | engines: 194 | node: '>=0.4.0' 195 | resolution: 196 | integrity: sha1-3zrhmayt+31ECqrgsp4icrJOxhk= 197 | /delegates/1.0.0: 198 | dev: false 199 | resolution: 200 | integrity: sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o= 201 | /detect-libc/1.0.3: 202 | dev: false 203 | engines: 204 | node: '>=0.10' 205 | hasBin: true 206 | resolution: 207 | integrity: sha1-+hN8S9aY7fVc1c0CrFWfkaTEups= 208 | /discord-akairo/8.0.0: 209 | dev: false 210 | peerDependencies: 211 | discord.js: ^12.0.0 212 | sequelize: ^5.2.12 213 | sqlite: ^3.0.3 214 | resolution: 215 | integrity: sha512-Cc1f8f3GFIhgHxg3TOSSfHD1Nt8haPGcmvoQeqlBKhDFwtWoPL+THBVVLaMUBDCzni7X4g6teM5PPvVocwlfZQ== 216 | /discord.js/12.2.0: 217 | dependencies: 218 | '@discordjs/collection': 0.1.5 219 | '@discordjs/form-data': 3.0.1 220 | abort-controller: 3.0.0 221 | node-fetch: 2.6.0 222 | prism-media: 1.2.2 223 | setimmediate: 1.0.5 224 | tweetnacl: 1.0.3 225 | ws: 7.3.0 226 | dev: false 227 | engines: 228 | node: '>=12.0.0' 229 | peerDependencies: 230 | bufferutil: ^4.0.1 231 | erlpack: discordapp/erlpack 232 | libsodium-wrappers: ^0.7.6 233 | sodium: ^3.0.2 234 | utf-8-validate: ^5.0.2 235 | zlib-sync: ^0.1.6 236 | resolution: 237 | integrity: sha512-Ueb/0SOsxXyqwvwFYFe0msMrGqH1OMqpp2Dpbplnlr4MzcRrFWwsBM9gKNZXPVBHWUKiQkwU8AihXBXIvTTSvg== 238 | /dotenv-cli/3.1.0: 239 | dependencies: 240 | cross-spawn: 7.0.2 241 | dotenv: 8.2.0 242 | dotenv-expand: 5.1.0 243 | minimist: 1.2.5 244 | dev: false 245 | hasBin: true 246 | resolution: 247 | integrity: sha512-sT16Zg7m71IVP/MX2ZBm6JBu6fy8aEgN9kJPywaYhBZnmq7MSQbpvCEhuiGPI08X8G+CQ1Gj/oZZUH1lGvGmqA== 248 | /dotenv-defaults/1.1.1: 249 | dependencies: 250 | dotenv: 6.2.0 251 | dev: false 252 | resolution: 253 | integrity: sha512-6fPRo9o/3MxKvmRZBD3oNFdxODdhJtIy1zcJeUSCs6HCy4tarUpd+G67UTU9tF6OWXeSPqsm4fPAB+2eY9Rt9Q== 254 | /dotenv-expand/5.1.0: 255 | dev: false 256 | resolution: 257 | integrity: sha512-YXQl1DSa4/PQyRfgrv6aoNjhasp/p4qs9FjJ4q4cQk+8m4r6k4ZSiEyytKG8f8W9gi8WsQtIObNmKd+tMzNTmA== 258 | /dotenv-extended/2.8.0: 259 | dependencies: 260 | auto-parse: 1.8.0 261 | camelcase: 5.3.1 262 | cross-spawn: 7.0.2 263 | dotenv: 8.2.0 264 | dev: false 265 | engines: 266 | node: '>=6' 267 | hasBin: true 268 | resolution: 269 | integrity: sha512-7R3lSD7JcKkIZ+JnVN4LPJmJ2oR3pi+taqRxVpuod0gpCw/ZjYehEXiqceblP9pQinXY0Gt4nEmVh/1um4c2Mw== 270 | /dotenv-safe/8.2.0: 271 | dependencies: 272 | dotenv: 8.2.0 273 | dev: false 274 | resolution: 275 | integrity: sha512-uWwWWdUQkSs5a3mySDB22UtNwyEYi0JtEQu+vDzIqr9OjbDdC2Ip13PnSpi/fctqlYmzkxCeabiyCAOROuAIaA== 276 | /dotenv-webpack/1.8.0: 277 | dependencies: 278 | dotenv-defaults: 1.1.1 279 | dev: false 280 | peerDependencies: 281 | webpack: ^1 || ^2 || ^3 || ^4 282 | resolution: 283 | integrity: sha512-o8pq6NLBehtrqA8Jv8jFQNtG9nhRtVqmoD4yWbgUyoU3+9WBlPe+c2EAiaJok9RB28QvrWvdWLZGeTT5aATDMg== 284 | /dotenv/6.2.0: 285 | dev: false 286 | engines: 287 | node: '>=6' 288 | resolution: 289 | integrity: sha512-HygQCKUBSFl8wKQZBSemMywRWcEDNidvNbjGVyZu3nbZ8qq9ubiPoGLMdRDpfSrpkkm9BXYFkpKxxFX38o/76w== 290 | /dotenv/8.2.0: 291 | dev: false 292 | engines: 293 | node: '>=8' 294 | resolution: 295 | integrity: sha512-8sJ78ElpbDJBHNeBzUbUVLsqKdccaa/BXF1uPTw3GrvQTBgrQrtObr2mUrE38vzYd8cEv+m/JBfDLioYcfXoaw== 296 | /dottie/2.0.2: 297 | dev: false 298 | resolution: 299 | integrity: sha512-fmrwR04lsniq/uSr8yikThDTrM7epXHBAAjH9TbeH3rEA8tdCO7mRzB9hdmdGyJCxF8KERo9CITcm3kGuoyMhg== 300 | /end-of-stream/1.4.4: 301 | dependencies: 302 | once: 1.4.0 303 | dev: false 304 | resolution: 305 | integrity: sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q== 306 | /event-target-shim/5.0.1: 307 | dev: false 308 | engines: 309 | node: '>=6' 310 | resolution: 311 | integrity: sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ== 312 | /expand-template/2.0.3: 313 | dev: false 314 | engines: 315 | node: '>=6' 316 | resolution: 317 | integrity: sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg== 318 | /file-uri-to-path/1.0.0: 319 | dev: false 320 | resolution: 321 | integrity: sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw== 322 | /fs-constants/1.0.0: 323 | dev: false 324 | resolution: 325 | integrity: sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow== 326 | /fs-minipass/1.2.7: 327 | dependencies: 328 | minipass: 2.9.0 329 | dev: false 330 | resolution: 331 | integrity: sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA== 332 | /function.name/1.0.12: 333 | dependencies: 334 | noop6: 1.0.8 335 | dev: false 336 | resolution: 337 | integrity: sha512-C7Tu+rAFrWW5RjXqtKtXp2xOdCujq+4i8ZH3w0uz/xrYHBwXZrPt96x8cDAEHrIjeyEv/Jm6iDGyqupbaVQTlw== 338 | /gauge/2.7.4: 339 | dependencies: 340 | aproba: 1.2.0 341 | console-control-strings: 1.1.0 342 | has-unicode: 2.0.1 343 | object-assign: 4.1.1 344 | signal-exit: 3.0.3 345 | string-width: 1.0.2 346 | strip-ansi: 3.0.1 347 | wide-align: 1.1.3 348 | dev: false 349 | resolution: 350 | integrity: sha1-LANAXHU4w51+s3sxcCLjJfsBi/c= 351 | /github-from-package/0.0.0: 352 | dev: false 353 | resolution: 354 | integrity: sha1-l/tdlr/eiXMxPyDoKI75oWf6ZM4= 355 | /has-unicode/2.0.1: 356 | dev: false 357 | resolution: 358 | integrity: sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk= 359 | /ieee754/1.1.13: 360 | dev: false 361 | resolution: 362 | integrity: sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg== 363 | /inflection/1.12.0: 364 | dev: false 365 | engines: 366 | '0': node >= 0.4.0 367 | resolution: 368 | integrity: sha1-ogCTVlbW9fa8TcdQLhrstwMihBY= 369 | /inherits/2.0.3: 370 | dev: false 371 | resolution: 372 | integrity: sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4= 373 | /inherits/2.0.4: 374 | dev: false 375 | resolution: 376 | integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== 377 | /ini/1.3.5: 378 | dev: false 379 | resolution: 380 | integrity: sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw== 381 | /integer/3.0.1: 382 | dependencies: 383 | bindings: 1.5.0 384 | prebuild-install: 5.3.4 385 | dev: false 386 | requiresBuild: true 387 | resolution: 388 | integrity: sha512-OqtER6W2GIJTIcnT5o2B/pWGgvurnVOYs4OZCgay40QEIbMTnNq4R0KSaIw1TZyFtPWjm5aNM+pBBMTfc3exmw== 389 | /is-bluebird/1.0.2: 390 | dev: false 391 | engines: 392 | node: '>=0.10.0' 393 | resolution: 394 | integrity: sha1-CWQ5Bg9KpBGr7hkUOoTWpVNG1uI= 395 | /is-fullwidth-code-point/1.0.0: 396 | dependencies: 397 | number-is-nan: 1.0.1 398 | dev: false 399 | engines: 400 | node: '>=0.10.0' 401 | resolution: 402 | integrity: sha1-754xOG8DGn8NZDr4L95QxFfvAMs= 403 | /is-fullwidth-code-point/2.0.0: 404 | dev: false 405 | engines: 406 | node: '>=4' 407 | resolution: 408 | integrity: sha1-o7MKXE8ZkYMWeqq5O+764937ZU8= 409 | /isarray/1.0.0: 410 | dev: false 411 | resolution: 412 | integrity: sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE= 413 | /isexe/2.0.0: 414 | dev: false 415 | resolution: 416 | integrity: sha1-6PvzdNxVb/iUehDcsFctYz8s+hA= 417 | /lodash/4.17.15: 418 | dev: false 419 | resolution: 420 | integrity: sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A== 421 | /mime-db/1.44.0: 422 | dev: false 423 | engines: 424 | node: '>= 0.6' 425 | resolution: 426 | integrity: sha512-/NOTfLrsPBVeH7YtFPgsVWveuL+4SjjYxaQ1xtM1KMFj7HdxlBlxeyNLzhyJVx7r4rZGJAZ/6lkKCitSc/Nmpg== 427 | /mime-types/2.1.27: 428 | dependencies: 429 | mime-db: 1.44.0 430 | dev: false 431 | engines: 432 | node: '>= 0.6' 433 | resolution: 434 | integrity: sha512-JIhqnCasI9yD+SsmkquHBxTSEuZdQX5BuQnS2Vc7puQQQ+8yiP5AY5uWhpdv4YL4VM5c6iliiYWPgJ/nJQLp7w== 435 | /mimic-response/2.1.0: 436 | dev: false 437 | engines: 438 | node: '>=8' 439 | resolution: 440 | integrity: sha512-wXqjST+SLt7R009ySCglWBCFpjUygmCIfD790/kVbiGmUgfYGuB14PiTd5DwVxSV4NcYHjzMkoj5LjQZwTQLEA== 441 | /minimist/1.2.5: 442 | dev: false 443 | resolution: 444 | integrity: sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw== 445 | /minipass/2.9.0: 446 | dependencies: 447 | safe-buffer: 5.2.1 448 | yallist: 3.1.1 449 | dev: false 450 | resolution: 451 | integrity: sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg== 452 | /minizlib/1.3.3: 453 | dependencies: 454 | minipass: 2.9.0 455 | dev: false 456 | resolution: 457 | integrity: sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q== 458 | /mkdirp-classic/0.5.3: 459 | dev: false 460 | resolution: 461 | integrity: sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A== 462 | /mkdirp/0.5.5: 463 | dependencies: 464 | minimist: 1.2.5 465 | dev: false 466 | hasBin: true 467 | resolution: 468 | integrity: sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ== 469 | /moment-timezone/0.5.31: 470 | dependencies: 471 | moment: 2.26.0 472 | dev: false 473 | resolution: 474 | integrity: sha512-+GgHNg8xRhMXfEbv81iDtrVeTcWt0kWmTEY1XQK14dICTXnWJnT0dxdlPspwqF3keKMVPXwayEsk1DI0AA/jdA== 475 | /moment/2.26.0: 476 | dev: false 477 | resolution: 478 | integrity: sha512-oIixUO+OamkUkwjhAVE18rAMfRJNsNe/Stid/gwHSOfHrOtw9EhAY2AHvdKZ/k/MggcYELFCJz/Sn2pL8b8JMw== 479 | /ms/2.1.2: 480 | dev: false 481 | resolution: 482 | integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== 483 | /napi-build-utils/1.0.2: 484 | dev: false 485 | resolution: 486 | integrity: sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg== 487 | /node-abi/2.17.0: 488 | dependencies: 489 | semver: 5.7.1 490 | dev: false 491 | resolution: 492 | integrity: sha512-dFRAA0ACk/aBo0TIXQMEWMLUTyWYYT8OBYIzLmEUrQTElGRjxDCvyBZIsDL0QA7QCaj9PrawhOmTEdsuLY4uOQ== 493 | /node-fetch/2.6.0: 494 | dev: false 495 | engines: 496 | node: 4.x || >=6.0.0 497 | resolution: 498 | integrity: sha512-8dG4H5ujfvFiqDmVu9fQ5bOHUC15JMjMY/Zumv26oOvvVJjM67KF8koCWIabKQ1GJIa9r2mMZscBq/TbdOcmNA== 499 | /noop-logger/0.1.1: 500 | dev: false 501 | resolution: 502 | integrity: sha1-lKKxYzxPExdVMAfYlm/Q6EG2pMI= 503 | /noop6/1.0.8: 504 | dev: false 505 | resolution: 506 | integrity: sha512-+Al5csMVc40I8xRfJsyBcN1IbpyvebOuQmMfxdw+AL6ECELey12ANgNTRhMfTwNIDU4W9W0g8EHLcsb3+3qPFA== 507 | /npmlog/4.1.2: 508 | dependencies: 509 | are-we-there-yet: 1.1.5 510 | console-control-strings: 1.1.0 511 | gauge: 2.7.4 512 | set-blocking: 2.0.0 513 | dev: false 514 | resolution: 515 | integrity: sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg== 516 | /number-is-nan/1.0.1: 517 | dev: false 518 | engines: 519 | node: '>=0.10.0' 520 | resolution: 521 | integrity: sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0= 522 | /object-assign/4.1.1: 523 | dev: false 524 | engines: 525 | node: '>=0.10.0' 526 | resolution: 527 | integrity: sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= 528 | /once/1.4.0: 529 | dependencies: 530 | wrappy: 1.0.2 531 | dev: false 532 | resolution: 533 | integrity: sha1-WDsap3WWHUsROsF9nFC6753Xa9E= 534 | /parse-ms/2.1.0: 535 | dev: false 536 | engines: 537 | node: '>=6' 538 | resolution: 539 | integrity: sha512-kHt7kzLoS9VBZfUsiKjv43mr91ea+U05EyKkEtqp7vNbHxmaVuEqN7XxeEVnGrMtYOAxGrDElSi96K7EgO1zCA== 540 | /path-key/3.1.1: 541 | dev: false 542 | engines: 543 | node: '>=8' 544 | resolution: 545 | integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== 546 | /path/0.12.7: 547 | dependencies: 548 | process: 0.11.10 549 | util: 0.10.4 550 | dev: false 551 | resolution: 552 | integrity: sha1-1NwqUGxM4hl+tIHr/NWzbAFAsQ8= 553 | /prebuild-install/5.3.4: 554 | dependencies: 555 | detect-libc: 1.0.3 556 | expand-template: 2.0.3 557 | github-from-package: 0.0.0 558 | minimist: 1.2.5 559 | mkdirp: 0.5.5 560 | napi-build-utils: 1.0.2 561 | node-abi: 2.17.0 562 | noop-logger: 0.1.1 563 | npmlog: 4.1.2 564 | pump: 3.0.0 565 | rc: 1.2.8 566 | simple-get: 3.1.0 567 | tar-fs: 2.1.0 568 | tunnel-agent: 0.6.0 569 | which-pm-runs: 1.0.0 570 | dev: false 571 | engines: 572 | node: '>=6' 573 | hasBin: true 574 | resolution: 575 | integrity: sha512-AkKN+pf4fSEihjapLEEj8n85YIw/tN6BQqkhzbDc0RvEZGdkpJBGMUYx66AAMcPG2KzmPQS7Cm16an4HVBRRMA== 576 | /prism-media/1.2.2: 577 | dev: false 578 | peerDependencies: 579 | '@discordjs/opus': ^0.1.0 580 | ffmpeg-static: ^2.4.0 || ^3.0.0 581 | node-opus: ^0.3.1 582 | opusscript: ^0.0.6 583 | resolution: 584 | integrity: sha512-I+nkWY212lJ500jLe4tN9tWO7nRiBAVdMv76P9kffZjYhw20raMlW1HSSvS+MLXC9MmbNZCazMrAr+5jEEgTuw== 585 | /process-nextick-args/2.0.1: 586 | dev: false 587 | resolution: 588 | integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== 589 | /process/0.11.10: 590 | dev: false 591 | engines: 592 | node: '>= 0.6.0' 593 | resolution: 594 | integrity: sha1-czIwDoQBYb2j5podHZGn1LwW8YI= 595 | /pump/3.0.0: 596 | dependencies: 597 | end-of-stream: 1.4.4 598 | once: 1.4.0 599 | dev: false 600 | resolution: 601 | integrity: sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww== 602 | /rc/1.2.8: 603 | dependencies: 604 | deep-extend: 0.6.0 605 | ini: 1.3.5 606 | minimist: 1.2.5 607 | strip-json-comments: 2.0.1 608 | dev: false 609 | hasBin: true 610 | resolution: 611 | integrity: sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw== 612 | /readable-stream/2.3.7: 613 | dependencies: 614 | core-util-is: 1.0.2 615 | inherits: 2.0.4 616 | isarray: 1.0.0 617 | process-nextick-args: 2.0.1 618 | safe-buffer: 5.1.2 619 | string_decoder: 1.1.1 620 | util-deprecate: 1.0.2 621 | dev: false 622 | resolution: 623 | integrity: sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw== 624 | /readable-stream/3.6.0: 625 | dependencies: 626 | inherits: 2.0.4 627 | string_decoder: 1.3.0 628 | util-deprecate: 1.0.2 629 | dev: false 630 | engines: 631 | node: '>= 6' 632 | resolution: 633 | integrity: sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA== 634 | /retry-as-promised/3.2.0: 635 | dependencies: 636 | any-promise: 1.3.0 637 | dev: false 638 | resolution: 639 | integrity: sha512-CybGs60B7oYU/qSQ6kuaFmRd9sTZ6oXSc0toqePvV74Ac6/IFZSI1ReFQmtCN+uvW1Mtqdwpvt/LGOiCBAY2Mg== 640 | /safe-buffer/5.1.2: 641 | dev: false 642 | resolution: 643 | integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== 644 | /safe-buffer/5.2.1: 645 | dev: false 646 | resolution: 647 | integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== 648 | /semver/5.7.1: 649 | dev: false 650 | hasBin: true 651 | resolution: 652 | integrity: sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== 653 | /semver/6.3.0: 654 | dev: false 655 | hasBin: true 656 | resolution: 657 | integrity: sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== 658 | /sequelize-pool/2.3.0: 659 | dev: false 660 | engines: 661 | node: '>= 6.0.0' 662 | resolution: 663 | integrity: sha512-Ibz08vnXvkZ8LJTiUOxRcj1Ckdn7qafNZ2t59jYHMX1VIebTAOYefWdRYFt6z6+hy52WGthAHAoLc9hvk3onqA== 664 | /sequelize/5.21.10: 665 | dependencies: 666 | bluebird: 3.7.2 667 | cls-bluebird: 2.1.0 668 | debug: 4.1.1 669 | dottie: 2.0.2 670 | inflection: 1.12.0 671 | lodash: 4.17.15 672 | moment: 2.26.0 673 | moment-timezone: 0.5.31 674 | retry-as-promised: 3.2.0 675 | semver: 6.3.0 676 | sequelize-pool: 2.3.0 677 | toposort-class: 1.0.1 678 | uuid: 3.4.0 679 | validator: 10.11.0 680 | wkx: 0.4.8 681 | dev: false 682 | engines: 683 | node: '>=6.0.0' 684 | resolution: 685 | integrity: sha512-qni5lKIa4wBdbi3KQYj20R5TC0/a88qi/1XhGDzDvTaWxhx4gEpLr6aGwvfbvVD7XCilvOgjoBkBB0fLVpwNsw== 686 | /set-blocking/2.0.0: 687 | dev: false 688 | resolution: 689 | integrity: sha1-BF+XgtARrppoA93TgrJDkrPYkPc= 690 | /setimmediate/1.0.5: 691 | dev: false 692 | resolution: 693 | integrity: sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU= 694 | /shebang-command/2.0.0: 695 | dependencies: 696 | shebang-regex: 3.0.0 697 | dev: false 698 | engines: 699 | node: '>=8' 700 | resolution: 701 | integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== 702 | /shebang-regex/3.0.0: 703 | dev: false 704 | engines: 705 | node: '>=8' 706 | resolution: 707 | integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== 708 | /shimmer/1.2.1: 709 | dev: false 710 | resolution: 711 | integrity: sha512-sQTKC1Re/rM6XyFM6fIAGHRPVGvyXfgzIDvzoq608vM+jeyVD0Tu1E6Np0Kc2zAIFWIj963V2800iF/9LPieQw== 712 | /signal-exit/3.0.3: 713 | dev: false 714 | resolution: 715 | integrity: sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA== 716 | /simple-concat/1.0.0: 717 | dev: false 718 | resolution: 719 | integrity: sha1-c0TLuLbib7J9ZrL8hvn21Zl1IcY= 720 | /simple-get/3.1.0: 721 | dependencies: 722 | decompress-response: 4.2.1 723 | once: 1.4.0 724 | simple-concat: 1.0.0 725 | dev: false 726 | resolution: 727 | integrity: sha512-bCR6cP+aTdScaQCnQKbPKtJOKDp/hj9EDLJo3Nw4y1QksqaovlW/bnptB6/c1e+qmNIDHRK+oXFDdEqBT8WzUA== 728 | /string-width/1.0.2: 729 | dependencies: 730 | code-point-at: 1.1.0 731 | is-fullwidth-code-point: 1.0.0 732 | strip-ansi: 3.0.1 733 | dev: false 734 | engines: 735 | node: '>=0.10.0' 736 | resolution: 737 | integrity: sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M= 738 | /string-width/2.1.1: 739 | dependencies: 740 | is-fullwidth-code-point: 2.0.0 741 | strip-ansi: 4.0.0 742 | dev: false 743 | engines: 744 | node: '>=4' 745 | resolution: 746 | integrity: sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw== 747 | /string_decoder/1.1.1: 748 | dependencies: 749 | safe-buffer: 5.1.2 750 | dev: false 751 | resolution: 752 | integrity: sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== 753 | /string_decoder/1.3.0: 754 | dependencies: 755 | safe-buffer: 5.2.1 756 | dev: false 757 | resolution: 758 | integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== 759 | /strip-ansi/3.0.1: 760 | dependencies: 761 | ansi-regex: 2.1.1 762 | dev: false 763 | engines: 764 | node: '>=0.10.0' 765 | resolution: 766 | integrity: sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8= 767 | /strip-ansi/4.0.0: 768 | dependencies: 769 | ansi-regex: 3.0.0 770 | dev: false 771 | engines: 772 | node: '>=4' 773 | resolution: 774 | integrity: sha1-qEeQIusaw2iocTibY1JixQXuNo8= 775 | /strip-json-comments/2.0.1: 776 | dev: false 777 | engines: 778 | node: '>=0.10.0' 779 | resolution: 780 | integrity: sha1-PFMZQukIwml8DsNEhYwobHygpgo= 781 | /tar-fs/2.1.0: 782 | dependencies: 783 | chownr: 1.1.4 784 | mkdirp-classic: 0.5.3 785 | pump: 3.0.0 786 | tar-stream: 2.1.2 787 | dev: false 788 | resolution: 789 | integrity: sha512-9uW5iDvrIMCVpvasdFHW0wJPez0K4JnMZtsuIeDI7HyMGJNxmDZDOCQROr7lXyS+iL/QMpj07qcjGYTSdRFXUg== 790 | /tar-stream/2.1.2: 791 | dependencies: 792 | bl: 4.0.2 793 | end-of-stream: 1.4.4 794 | fs-constants: 1.0.0 795 | inherits: 2.0.4 796 | readable-stream: 3.6.0 797 | dev: false 798 | resolution: 799 | integrity: sha512-UaF6FoJ32WqALZGOIAApXx+OdxhekNMChu6axLJR85zMMjXKWFGjbIRe+J6P4UnRGg9rAwWvbTT0oI7hD/Un7Q== 800 | /tar/4.4.10: 801 | dependencies: 802 | chownr: 1.1.4 803 | fs-minipass: 1.2.7 804 | minipass: 2.9.0 805 | minizlib: 1.3.3 806 | mkdirp: 0.5.5 807 | safe-buffer: 5.2.1 808 | yallist: 3.1.1 809 | dev: false 810 | engines: 811 | node: '>=4.5' 812 | resolution: 813 | integrity: sha512-g2SVs5QIxvo6OLp0GudTqEf05maawKUxXru104iaayWA09551tFCTI8f1Asb4lPfkBr91k07iL4c11XO3/b0tA== 814 | /toposort-class/1.0.1: 815 | dev: false 816 | resolution: 817 | integrity: sha1-f/0feMi+KMO6Rc1OGj9e4ZO9mYg= 818 | /tunnel-agent/0.6.0: 819 | dependencies: 820 | safe-buffer: 5.2.1 821 | dev: false 822 | resolution: 823 | integrity: sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0= 824 | /tweetnacl/1.0.3: 825 | dev: false 826 | resolution: 827 | integrity: sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw== 828 | /typpy/2.3.11: 829 | dependencies: 830 | function.name: 1.0.12 831 | dev: false 832 | resolution: 833 | integrity: sha512-Jh/fykZSaxeKO0ceMAs6agki9T5TNA9kiIR6fzKbvafKpIw8UlNlHhzuqKyi5lfJJ5VojJOx9tooIbyy7vHV/g== 834 | /util-deprecate/1.0.2: 835 | dev: false 836 | resolution: 837 | integrity: sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= 838 | /util/0.10.4: 839 | dependencies: 840 | inherits: 2.0.3 841 | dev: false 842 | resolution: 843 | integrity: sha512-0Pm9hTQ3se5ll1XihRic3FDIku70C+iHUdT/W926rSgHV5QgXsYbKZN8MSC3tJtSkhuROzvsQjAaFENRXr+19A== 844 | /uuid/3.4.0: 845 | dev: false 846 | hasBin: true 847 | resolution: 848 | integrity: sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A== 849 | /validator/10.11.0: 850 | dev: false 851 | engines: 852 | node: '>= 0.10' 853 | resolution: 854 | integrity: sha512-X/p3UZerAIsbBfN/IwahhYaBbY68EN/UQBWHtsbXGT5bfrH/p4NQzUCG1kF/rtKaNpnJ7jAu6NGTdSNtyNIXMw== 855 | /which-pm-runs/1.0.0: 856 | dev: false 857 | resolution: 858 | integrity: sha1-Zws6+8VS4LVd9rd4DKdGFfI60cs= 859 | /which/2.0.2: 860 | dependencies: 861 | isexe: 2.0.0 862 | dev: false 863 | engines: 864 | node: '>= 8' 865 | hasBin: true 866 | resolution: 867 | integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== 868 | /wide-align/1.1.3: 869 | dependencies: 870 | string-width: 2.1.1 871 | dev: false 872 | resolution: 873 | integrity: sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA== 874 | /wkx/0.4.8: 875 | dependencies: 876 | '@types/node': 14.0.5 877 | dev: false 878 | resolution: 879 | integrity: sha512-ikPXMM9IR/gy/LwiOSqWlSL3X/J5uk9EO2hHNRXS41eTLXaUFEVw9fn/593jW/tE5tedNg8YjT5HkCa4FqQZyQ== 880 | /wrappy/1.0.2: 881 | dev: false 882 | resolution: 883 | integrity: sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= 884 | /ws/7.3.0: 885 | dev: false 886 | engines: 887 | node: '>=8.3.0' 888 | peerDependencies: 889 | bufferutil: ^4.0.1 890 | utf-8-validate: ^5.0.2 891 | resolution: 892 | integrity: sha512-iFtXzngZVXPGgpTlP1rBqsUK82p9tKqsWRPg5L56egiljujJT3vGAYnHANvFxBieXrTFavhzhxW52jnaWV+w2w== 893 | /yallist/3.1.1: 894 | dev: false 895 | resolution: 896 | integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g== 897 | github.com/truexpixels/quick.db/1ec09504793df3055e034803132f409ca32fc5fc: 898 | dependencies: 899 | better-sqlite3: 6.0.1 900 | lodash: 4.17.15 901 | dev: false 902 | name: quick.db 903 | resolution: 904 | registry: 'https://registry.npmjs.org/' 905 | tarball: 'https://codeload.github.com/truexpixels/quick.db/tar.gz/1ec09504793df3055e034803132f409ca32fc5fc' 906 | version: 7.1.1 907 | registry: 'https://registry.npmjs.org/' 908 | shrinkwrapMinorVersion: 9 909 | shrinkwrapVersion: 3 910 | specifiers: 911 | approximate-number: ^2.0.0 912 | discord-akairo: ^8.0.0 913 | discord.js: ^12.2.0 914 | dotenv: ^8.2.0 915 | dotenv-cli: ^3.1.0 916 | dotenv-extended: ^2.8.0 917 | dotenv-safe: ^8.1.0 918 | dotenv-webpack: ^1.8.0 919 | node-fetch: ^2.6.0 920 | parse-ms: ^2.1.0 921 | path: ^0.12.7 922 | quick.db: 'github:truexpixels/quick.db' 923 | sequelize: ^5.21.5 924 | --------------------------------------------------------------------------------