From 99779de823e1751c3da13e0b7b0f639ddecca7da Mon Sep 17 00:00:00 2001 From: ame Date: Tue, 26 Sep 2023 23:12:35 -0500 Subject: init --- .env-example | 4 + .eslintrc.json | 13 + .gitattributes | 2 + .gitignore | 73 + .prettierrc | 6 + .replit | 2 + app.json | 7 + buildconfig.sh | 9 + commands/games/battleship.js | 200 +++ commands/games/defaults/battleship.js.json | 2 + commands/mod/autoreact.js | 57 + commands/mod/defaults/autoreact.js.json | 2 + commands/mod/defaults/log.js.json | 2 + commands/mod/defaults/motw.js.json | 2 + commands/mod/defaults/search.js.json | 2 + commands/mod/defaults/sticky.js.json | 2 + commands/mod/defaults/ticket.js.json | 2 + commands/mod/defaults/timed-message.js.json | 2 + commands/mod/defaults/whois.js.json | 2 + commands/mod/log.js | 27 + commands/mod/motw.js | 34 + commands/mod/search.js | 70 + commands/mod/sticky.js | 57 + commands/mod/ticket.js | 96 + commands/mod/timed-message.js | 76 + commands/mod/whois.js | 120 ++ commands/util/defaults/emote.js.json | 45 + commands/util/defaults/help.js.json | 2 + commands/util/defaults/poll.js.json | 2 + commands/util/defaults/say.js.json | 2 + commands/util/defaults/status.js.json | 2 + commands/util/emote.js | 47 + commands/util/help.js | 140 ++ commands/util/poll.js | 61 + commands/util/say.js | 36 + commands/util/status.js | 63 + events/defaults/dm.js.json | 5 + events/defaults/interaction.js.json | 3 + events/defaults/message.js.json | 6 + events/defaults/reaction-remove.js.json | 1 + events/defaults/ready.js.json | 5 + events/dm.js | 104 ++ events/interaction.js | 57 + events/message.js | 100 ++ events/reaction-remove.js | 20 + events/ready.js | 87 + html/settings.html | 0 html/tickets.html | 541 ++++++ img/battleship-board-sel.png | Bin 0 -> 685 bytes img/battleship-board.png | Bin 0 -> 2977 bytes img/fire.png | Bin 0 -> 3205 bytes index.js | 128 ++ license.md | 11 + package.json | 37 + pnpm-lock.yaml | 2532 +++++++++++++++++++++++++++ readme.md | 26 + snschan.sh | 7 + src/db.js | 69 + src/settings.js | 17 + src/util.js | 104 ++ src/webui.js | 40 + 61 files changed, 5171 insertions(+) create mode 100644 .env-example create mode 100644 .eslintrc.json create mode 100644 .gitattributes create mode 100644 .gitignore create mode 100644 .prettierrc create mode 100644 .replit create mode 100644 app.json create mode 100644 buildconfig.sh create mode 100644 commands/games/battleship.js create mode 100644 commands/games/defaults/battleship.js.json create mode 100644 commands/mod/autoreact.js create mode 100644 commands/mod/defaults/autoreact.js.json create mode 100644 commands/mod/defaults/log.js.json create mode 100644 commands/mod/defaults/motw.js.json create mode 100644 commands/mod/defaults/search.js.json create mode 100644 commands/mod/defaults/sticky.js.json create mode 100644 commands/mod/defaults/ticket.js.json create mode 100644 commands/mod/defaults/timed-message.js.json create mode 100644 commands/mod/defaults/whois.js.json create mode 100644 commands/mod/log.js create mode 100644 commands/mod/motw.js create mode 100644 commands/mod/search.js create mode 100644 commands/mod/sticky.js create mode 100644 commands/mod/ticket.js create mode 100644 commands/mod/timed-message.js create mode 100644 commands/mod/whois.js create mode 100644 commands/util/defaults/emote.js.json create mode 100644 commands/util/defaults/help.js.json create mode 100644 commands/util/defaults/poll.js.json create mode 100644 commands/util/defaults/say.js.json create mode 100644 commands/util/defaults/status.js.json create mode 100644 commands/util/emote.js create mode 100644 commands/util/help.js create mode 100644 commands/util/poll.js create mode 100644 commands/util/say.js create mode 100644 commands/util/status.js create mode 100644 events/defaults/dm.js.json create mode 100644 events/defaults/interaction.js.json create mode 100644 events/defaults/message.js.json create mode 100644 events/defaults/reaction-remove.js.json create mode 100644 events/defaults/ready.js.json create mode 100644 events/dm.js create mode 100644 events/interaction.js create mode 100644 events/message.js create mode 100644 events/reaction-remove.js create mode 100644 events/ready.js create mode 100644 html/settings.html create mode 100644 html/tickets.html create mode 100644 img/battleship-board-sel.png create mode 100644 img/battleship-board.png create mode 100644 img/fire.png create mode 100644 index.js create mode 100644 license.md create mode 100644 package.json create mode 100644 pnpm-lock.yaml create mode 100644 readme.md create mode 100644 snschan.sh create mode 100644 src/db.js create mode 100644 src/settings.js create mode 100644 src/util.js create mode 100644 src/webui.js diff --git a/.env-example b/.env-example new file mode 100644 index 0000000..8909c1e --- /dev/null +++ b/.env-example @@ -0,0 +1,4 @@ +TOKEN= +YOUTUBE_API_KEY= +WEEBY_TOKEN= +WEBUI_KEY= \ No newline at end of file diff --git a/.eslintrc.json b/.eslintrc.json new file mode 100644 index 0000000..ba32633 --- /dev/null +++ b/.eslintrc.json @@ -0,0 +1,13 @@ +{ + "env": { + "browser": true, + "commonjs": true, + "es2021": true + }, + "extends": "eslint:recommended", + "parserOptions": { + "ecmaVersion": "latest" + }, + "rules": { + } +} diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..dfe0770 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,2 @@ +# Auto detect text files and perform LF normalization +* text=auto diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..f2d781a --- /dev/null +++ b/.gitignore @@ -0,0 +1,73 @@ +/config.json +/env +/.idea +/.vscode +/package-lock.json + +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +# Runtime data +pids +*.pid +*.seed +*.pid.lock + +# Directory for instrumented libs generated by jscoverage/JSCover +lib-cov + +# Coverage directory used by tools like istanbul +coverage + +# nyc test coverage +.nyc_output + +# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) +.grunt + +# Bower dependency directory (https://bower.io/) +bower_components + +# node-waf configuration +.lock-wscript + +# Compiled binary addons (https://nodejs.org/api/addons.html) +build/Release + +# Dependency directories +node_modules/ +jspm_packages/ + +# TypeScript v1 declaration files +typings/ + +# Optional npm cache directory +.npm + +# Optional eslint cache +.eslintcache + +# Optional REPL history +.node_repl_history + +# Output of 'npm pack' +*.tgz + +# Yarn Integrity file +.yarn-integrity + + +#ignore configs +events/*.json +commands/*/*.json + +#ignore database (duh) +db/* + +#aaaaand any client secrets +.env +log \ No newline at end of file diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 0000000..d411adf --- /dev/null +++ b/.prettierrc @@ -0,0 +1,6 @@ +{ + "printWidth": 110, + "tabWidth": 2, + "useTabs": false, + "trailingComma": "none" +} diff --git a/.replit b/.replit new file mode 100644 index 0000000..d409ef8 --- /dev/null +++ b/.replit @@ -0,0 +1,2 @@ +language = "nodejs" +run = "npm start" \ No newline at end of file diff --git a/app.json b/app.json new file mode 100644 index 0000000..7e1617f --- /dev/null +++ b/app.json @@ -0,0 +1,7 @@ +{ + "name": "SNS Chan", + "description": "Supernoobs Custom Bot", + "repository": "https://github.com/ryzyx/sns-chan", + "logo": "https://i.imgur.com/JFxgbWH.png", + "keywords": ["discord", "discordjs", "music", "bot"] +} diff --git a/buildconfig.sh b/buildconfig.sh new file mode 100644 index 0000000..6d48fa3 --- /dev/null +++ b/buildconfig.sh @@ -0,0 +1,9 @@ +for file in events/defaults/*; do + cp "$file" events/ +done + +for folder in commands/*; do + for file in "$folder"/defaults/*; do + cp "$file" $folder/ + done +done \ No newline at end of file diff --git a/commands/games/battleship.js b/commands/games/battleship.js new file mode 100644 index 0000000..3c32cd5 --- /dev/null +++ b/commands/games/battleship.js @@ -0,0 +1,200 @@ +const fs = require('fs') +const path = require("path"); +let config_loc = __filename+".json" +const { PermissionsBitField, EmbedBuilder, AttachmentBuilder,ActionRowBuilder,ButtonBuilder,ButtonStyle } = require('discord.js'); +let config = JSON.parse(fs.readFileSync(config_loc)) +const util = require("../../src/util.js") +const sharp = require("sharp"); +const db = require("../../src/db.js") +module.exports = { + name : "battleship", + command: ["battleship"], + mod_only: true, + config:config, + config_loc:config_loc, + async main (client,Discord,message,args){ + let uid2 = args[1]; + if(uid2[0]=='<') uid2 = (args[1].substring(2,args[1].length-1)) + this.exec(client,{action:args[0],message:message,user2:uid2}) + }, + async board_prev(args){ + const move_y = 82 + const move_x = 66 + let pos = {x:0,rx:32,y:0,ry:14,rotated:false} + let max = {x:8,y:7} + let embed = new EmbedBuilder() + .setTitle("battleship") + .setImage("attachment://battleship-board.png") + + const left = new ButtonBuilder() + .setCustomId('left') + .setEmoji('⬅️') + .setStyle(ButtonStyle.Primary); + const up = new ButtonBuilder() + .setCustomId('up') + .setEmoji('⬆️') + .setStyle(ButtonStyle.Primary); + const down = new ButtonBuilder() + .setCustomId('down') + .setEmoji('⬇️') + .setStyle(ButtonStyle.Primary); + const right = new ButtonBuilder() + .setCustomId('right') + .setEmoji('➡️') + .setStyle(ButtonStyle.Primary); + const turn = new ButtonBuilder() + .setCustomId('turn') + .setEmoji('🔄') + .setStyle(ButtonStyle.Primary); + const row1 = new ActionRowBuilder() + .addComponents(left,up,down,right,turn); + + const shoot = new ButtonBuilder() + .setCustomId('shoot') + .setEmoji('🎯') + .setStyle(ButtonStyle.Primary); + const row2 = new ActionRowBuilder() + .addComponents(shoot); + //! TODO: randomize file name + let to_add = [{ + input: "./img/battleship-board-sel.png", + top: pos.rx, + left: pos.ry, + },] + if(args.len!=null){ + for(let i = 1; i i.user.id === args.message.author.id; + try { + const confirmation = await mess.awaitMessageComponent({ filter: collectorFilter, time: 60000000 }); + let oldpos = util.deepCopy(pos); + if(confirmation.customId == "down"){ + pos.x--; + pos.rx+=move_x; + } else if(confirmation.customId == "up"){ + pos.x++; + pos.rx-=move_x; + } else if(confirmation.customId == "right"){ + pos.y++; + pos.ry+=move_y; + } else if(confirmation.customId == "left"){ + pos.y--; + pos.ry-=move_y; + + } else if(confirmation.customId == "shoot"){ + //await mess.delete() + pos.mm = mess; + await confirmation.deferUpdate() + return pos; + } else if(confirmation.customId == "turn"){ + pos.rotated = !pos.rotated + } + + let outofbounds = false + if(!pos.rotated||args.len==0){ + outofbounds ||= (args.len!=0&&-pos.x+args.len>max.x); + outofbounds ||= (args.len==0&&-pos.x>=max.x); + outofbounds ||= (pos.y>=max.y); + } else { + outofbounds ||= (args.len!=0&&pos.y+args.len>max.y); + //outofbounds ||= (args.len==0&&pos.y>max.y); + outofbounds ||= (-pos.x>=max.x); + } + outofbounds ||= (pos.x==1||pos.y==-1); + + if(outofbounds){ + pos = oldpos; + await confirmation.deferUpdate() + return rec_edit(mess) + } + let to_add = [{ + input: "./img/battleship-board-sel.png", + top: pos.rx, + left: pos.ry, + }, + ] + if(args.len!=null&&args.len!=0){ + for(let i = 1; i upload_limit(message.guild)) + return message.reply("file too large:( file is "+stats.size / (1024*1024)+"mb") + message.reply({files:[filename]}) + break; + default: + message.reply("unknown action, try `sns help react`") + } + + }, +} \ No newline at end of file diff --git a/commands/mod/defaults/autoreact.js.json b/commands/mod/defaults/autoreact.js.json new file mode 100644 index 0000000..7f976dc --- /dev/null +++ b/commands/mod/defaults/autoreact.js.json @@ -0,0 +1,2 @@ +{"cooldown":-1,"desc":"React to every new post in channel:3","restrict":[],"restricted":[], +"usage":"{command} {add {channel} {emote}|rem {channel}|dump}"} \ No newline at end of file diff --git a/commands/mod/defaults/log.js.json b/commands/mod/defaults/log.js.json new file mode 100644 index 0000000..a5edd7d --- /dev/null +++ b/commands/mod/defaults/log.js.json @@ -0,0 +1,2 @@ +{"cooldown":-1,"desc":"Print logs","restrict":[],"restricted":[], +"usage":"{command}"} \ No newline at end of file diff --git a/commands/mod/defaults/motw.js.json b/commands/mod/defaults/motw.js.json new file mode 100644 index 0000000..9412b0b --- /dev/null +++ b/commands/mod/defaults/motw.js.json @@ -0,0 +1,2 @@ +{"cooldown":-1,"desc":"Announce the Member of the Week","restrict":[],"restricted":[], +"usage":"{command} {user} {image}"} \ No newline at end of file diff --git a/commands/mod/defaults/search.js.json b/commands/mod/defaults/search.js.json new file mode 100644 index 0000000..0ef94c9 --- /dev/null +++ b/commands/mod/defaults/search.js.json @@ -0,0 +1,2 @@ +{"cooldown":-1,"desc":"Search for a username/nickname","restrict":[],"restricted":[], +"usage":"{command} {name} [percent (end with %)]"} \ No newline at end of file diff --git a/commands/mod/defaults/sticky.js.json b/commands/mod/defaults/sticky.js.json new file mode 100644 index 0000000..4717847 --- /dev/null +++ b/commands/mod/defaults/sticky.js.json @@ -0,0 +1,2 @@ +{"cooldown":-1,"desc":"Make a message sticky (i douse it in honey)! Message will always stay at the bottom of the feed","restrict":[],"restricted":[], +"usage":"{command} {add {channel} {message}|rem {channel}|dump} [embed]","embed_color":"#fcc356"} \ No newline at end of file diff --git a/commands/mod/defaults/ticket.js.json b/commands/mod/defaults/ticket.js.json new file mode 100644 index 0000000..095cdef --- /dev/null +++ b/commands/mod/defaults/ticket.js.json @@ -0,0 +1,2 @@ +{"cooldown":-1,"desc":"Interact with the tickets database, and respond to them.","restrict":[],"restricted":[], +"usage":"{command} {reply {ticket} [message] [attachments]|close {ticket}|dump {ticket}"} \ No newline at end of file diff --git a/commands/mod/defaults/timed-message.js.json b/commands/mod/defaults/timed-message.js.json new file mode 100644 index 0000000..a330425 --- /dev/null +++ b/commands/mod/defaults/timed-message.js.json @@ -0,0 +1,2 @@ +{"cooldown":-1,"desc":"Send a message per interval:)","restrict":[],"restricted":[], +"usage":"{command} {add {channel} {message} {delay (in s,m,h,d)} |rem {channel}|dump} [embed]","embed_color":"#fcc356"} \ No newline at end of file diff --git a/commands/mod/defaults/whois.js.json b/commands/mod/defaults/whois.js.json new file mode 100644 index 0000000..ef027ae --- /dev/null +++ b/commands/mod/defaults/whois.js.json @@ -0,0 +1,2 @@ +{"cooldown":-1,"desc":"Get info on user or role","restrict":[],"restricted":[], +"usage":"{command} {userid|roleid|mention}"} \ No newline at end of file diff --git a/commands/mod/log.js b/commands/mod/log.js new file mode 100644 index 0000000..170f48e --- /dev/null +++ b/commands/mod/log.js @@ -0,0 +1,27 @@ +const Discord = require("discord.js") +const settings = require("../../src/settings") +const fs = require('fs') +const {upload_limit} = require("../../src/util") +const path = require('path') +let config_loc = __filename+".json" +let config = JSON.parse(fs.readFileSync(config_loc)) +module.exports = { + name: "log", + command: ["log"], + mod_only:true, + config:config, + config_loc:config_loc, + main(client,Discord,message,args) { + this.exec(message) + }, + s_main(client,Discord,interaction){ + this.exec(interaction) + }, + exec(message){ + let filename = path.join(__dirname+"../../../log") + let stats = fs.statSync(filename) + if(stats.size / (1024*1024) > upload_limit(message.guild)) + return message.reply("file too large:( file is "+stats.size / (1024*1024)+"mb") + message.reply({files:[filename]}) + } +}; \ No newline at end of file diff --git a/commands/mod/motw.js b/commands/mod/motw.js new file mode 100644 index 0000000..a5984c4 --- /dev/null +++ b/commands/mod/motw.js @@ -0,0 +1,34 @@ +const Discord = require("discord.js") +const { EmbedBuilder } = require("discord.js"); +const { PermissionsBitField } = require('discord.js'); +const settings = require("../../src/settings") +const fs = require('fs') +let config_loc = __filename+".json" +let config = JSON.parse(fs.readFileSync(config_loc)) +module.exports = { + name: "motw", + command: ["motw"], + mod_only:true, + config:config, + config_loc:config_loc, + main(client,Discord,message,args) { + var cmd = message.content.slice(9).split(/ +/g); + var name = cmd.shift(); + var image = cmd.join(" "); + this.exec(client,{message:message,name:name,image:image}) + }, + s_options:[{type:"user",name:"user",desc:"member of the week!",required:true,autocomplete:false}, + {type:"string",name:"image",desc:"your fancy motw image:3",required:true,autocomplete:false}], + s_main(client,Discord,interaction){ + this.exec(client,{name:"<@!"+interaction.options.getUser("user").id+">",image:interaction.options.getString("image"),message:interaction}) + interaction.reply({content:"all done:3",ephemeral: true}) + }, + exec(client,param){ + const motw = new EmbedBuilder() + .setTitle("Member of the Week") + .setColor(settings.defaultColor) + .setDescription(param.name) + .setImage(param.image); + param.message.channel.send({ embeds: [motw] }); + } +}; \ No newline at end of file diff --git a/commands/mod/search.js b/commands/mod/search.js new file mode 100644 index 0000000..e81c3c8 --- /dev/null +++ b/commands/mod/search.js @@ -0,0 +1,70 @@ +const Discord = require("discord.js") +const { EmbedBuilder } = require("discord.js"); +const { PermissionsBitField } = require('discord.js'); +const settings = require("../../src/settings") +const {similarity} = require("../../src/util") +const fs = require('fs') +let config_loc = __filename+".json" +let config = JSON.parse(fs.readFileSync(config_loc)) +module.exports = { + name: "search", + command: ["search"], + mod_only:true, + config:config, + config_loc:config_loc, + async main(client,Discord,message,args) { + let per = 60; + for(let a of args){ + if(a.length>=2&&a[a.length-1]=="%"&&a[a.length-2]!="%"){ + a[a.length-1]="" + per = parseInt(a) + args.splice(args.indexOf(a), 1); + } + } + let dec = per/100 + let mem = Object.fromEntries(await message.guild.members.fetch()) + let found = [] + let count = 0 + for(let k of Object.keys(mem)){ + let s = similarity(mem[k].user.username.toLowerCase(),args[0].toLowerCase()) + if(mem[k].nickname!=null){ + s=Math.max(s,similarity(mem[k].nickname.toLowerCase(),args[0].toLowerCase())) + } + if(s>dec){ + found.push({sim:s,id:mem[k].id}) + count++; + } + } + if(count==0) + return message.reply("no usernames/nicknames found (within a "+per+"% similarity)") + for(let i = 0; ifound[i].sim){ + let t = found[i+1] + found[i+1] = found[i] + found[i] = t + i-=2; + } + } + let p_found = "" + for(let i = 0; i!=count; i++){ + let new_m = "(<@"+found[i].id+"> @ " + Math.floor(found[i].sim * 100) + "%) " + if((p_found+new_m).length>1024-3){ + p_found+="..." + break; + } + p_found+=new_m + } + message.channel.send("loading ids").then(async(m)=>{ + await m.edit(p_found) + m.delete() + }) + let embed = new EmbedBuilder() + .setTitle("Usernames close to '"+args[0]+"' (≥"+per+"%)") + .setDescription(p_found) + .setColor(settings.defaultColor) + .setFooter({text:count+' user(s) found • Up to '+Math.floor(found[0].sim * 100) + '% similarity'}) + message.channel.send({embeds:[embed]}) + + } +}; \ No newline at end of file diff --git a/commands/mod/sticky.js b/commands/mod/sticky.js new file mode 100644 index 0000000..b3dc055 --- /dev/null +++ b/commands/mod/sticky.js @@ -0,0 +1,57 @@ +const fs = require('fs') +const path = require("path"); +const db = require("../../src/db") +let config_loc = __filename+".json" +let config = JSON.parse(fs.readFileSync(config_loc)) +const {upload_limit} = require("../../src/util") +module.exports = { + name : "sticky", + command: ["sticky"], + mod_only: true, + config:config, + config_loc:config_loc, + async main (client,Discord,message,args){ + switch(args[0]){ + case 'add': + case 'a': + if(args.length<3){ + message.reply("not enough parameters, try `sns help sticky`") + break; + } + db.Sticky.create({channel:args[1],message:args[2],last_message:'null',embed:args.includes("embed"),embed_color:config.embed_color}); + message.react("✅") + break; + case 'rem': + case 'remove': + case 'r': + if(args.length<2){ + message.reply("not enough parameters, try `sns help sticky`") + break; + } + let initial = await db.Sticky.count() + await db.Sticky.destroy({ + where: { + channel: args[1] + } + }); + message.reply("removed "+(initial-(await db.Sticky.count()))+" item(s)") + break; + case 'dump': + case 'list': + let list = await db.Sticky.findAll() + let flist = "channelid : message : last message\n" + for(let l of list) + flist+=l.channel+" : "+l.message+" : "+l.last_message+"\n" + let filename = "/tmp/sticky.json" + fs.writeFileSync(filename,flist) + let stats = fs.statSync(filename) + if(stats.size / (1024*1024) > upload_limit(message.guild)) + return message.reply("file too large:( file is "+stats.size / (1024*1024)+"mb") + message.reply({files:[filename]}) + break; + default: + message.reply("unknown action, try `sns help sticky`") + } + + }, +} \ No newline at end of file diff --git a/commands/mod/ticket.js b/commands/mod/ticket.js new file mode 100644 index 0000000..5e69ed7 --- /dev/null +++ b/commands/mod/ticket.js @@ -0,0 +1,96 @@ +const Discord = require("discord.js") +const { EmbedBuilder } = require("discord.js"); +const { PermissionsBitField, MessageAttachment } = require('discord.js'); +const {upload_limit} = require("../../src/util") +const settings = require("../../src/settings") +const fs = require('fs'); +let db = require("../../src/db") +let config_loc = __filename+".json" +let config = JSON.parse(fs.readFileSync(config_loc)) +module.exports = { + name: "ticket", + command: ["ticket"], + mod_only:true, + config:config, + config_loc:config_loc, + async main(client,Discord,message,args) { + let matt = Array.from(message.attachments, ([name, value]) => ({ name, value })) + + let action = args[0]; + let ticket_id = args[1]; + args.shift();args.shift(); + let r_message = args.join(' ') + + this.exec(client,{att:matt,action:action,ticket_id:ticket_id,r_message:r_message,message:message}) + }, + s_options:[{type:"string",name:"ticket",desc:"ticket id",required:true,autocomplete: async function(){ let tik = await db.Tickets.findAll({attributes:['ticket'],where:{status:'open'}}); let out = []; for(let t of tik) out.push(t.ticket); return out; }}, + {type:"string",name:"action",desc:"operation to perform",required:true,autocomplete:["reply","close","dump"]}, + {type:"string",name:"message",desc:"message to reply with",required:false,autocomplete:false}, + {type:"attachment",name:"attachment",desc:"attachment to reply with",required:false,autocomplete:false}], + async s_main(client,Discord,interaction){ + this.exec(client,{message:interaction,att:[interaction.options.getAttachment("attachment")] ?? [],action:interaction.options.getString("action"), + ticket_id:interaction.options.getString("ticket"),r_message:interaction.options.getString("message")}) + }, + async exec(client,param){ + let tickets; + let date = new Date().toLocaleString() + switch(param.action){ + case 'reply': + case 'respond': + case 'r': + if(param.r_message==null&¶m.att==null) + return param.message.reply("you must provide a message or attachment") + tickets = await db.Tickets.findAll({where:{status:'open',ticket:param.ticket_id}}) + if(tickets.length==0){ + tickets = await db.Tickets.findAll({where:{ticket:param.ticket_id}}) + if(tickets.length==0) + return param.message.reply("ticket not found:c") + return param.message.reply("ticket is not open") + } + let ticket = tickets[0] + let messages = JSON.parse(ticket.messages) + messages.push({message:param.r_message,attachments:param.att,mod:true}) + db.Tickets.update({'messages':JSON.stringify(messages)},{where:{id:ticket.id}}) + + const embed = new EmbedBuilder() + .setTitle("Updated Ticket | "+ticket.ticket) + .setColor(settings.defaultColor) + .setDescription("Message: '"+param.r_message+"'") + .setFooter({text:"Created: "+date}) + let smatt = [] + for(let att of param.att){ + if(att!=null) + smatt.push({attachment:att?.value?.url ?? att?.url}) + } + param.message.client.users.cache.get(ticket.author).send({embeds:[embed],files:smatt}) + param.message.reply("updated ticket "+ticket.ticket); + break; + case 'close': + tickets = await db.Tickets.findAll({where:{status:'open',ticket:param.ticket_id}}) + if(tickets.length==0){ + tickets = await db.Tickets.findAll({where:{ticket:param.ticket_id}}) + if(ticket.length==0) + return param.message.reply("ticket not found:c") + return param.message.reply("ticket is already closed") + } + db.Tickets.update({'status':'closed'},{where:{id:tickets[0].id}}) + param.message.reply("closed ticket "+tickets[0].ticket); + break; + case 'dump': + case 'list': + tickets = await db.Tickets.findAll({where:{ticket:param.ticket_id}}) + if(tickets.length==0){ + return param.message.reply("ticket not found:c") + } + let filename = "/tmp/"+tickets[0].ticket+".json" + fs.writeFileSync(filename,tickets[0].messages) + let stats = fs.statSync(filename) + if(stats.size / (1024*1024) > upload_limit(param.message.guild)) + return param.message.reply("file too large:( file is "+stats.size / (1024*1024)+"mb") + param.message.reply({files:[filename]}) + break; + default: + param.message.reply("unknown action, try `sns help ticket`") + } + } +}; \ No newline at end of file diff --git a/commands/mod/timed-message.js b/commands/mod/timed-message.js new file mode 100644 index 0000000..35789da --- /dev/null +++ b/commands/mod/timed-message.js @@ -0,0 +1,76 @@ +const fs = require('fs') +const path = require("path"); +const db = require("../../src/db") +let config_loc = __filename+".json" +let config = JSON.parse(fs.readFileSync(config_loc)) +const {upload_limit} = require("../../src/util") +let valid_times = {"s":1000,"m":60000,"h":3.6e+6,"d":8.64e+7} +module.exports = { + name : "timed message", + command: ["timed"], + mod_only: true, + config:config, + config_loc:config_loc, + async main (client,Discord,message,args){ + switch(args[0]){ + case 'add': + case 'a': + if(args.length<3){ + message.reply("not enough parameters, try `sns help timed`") + break; + } + let del_ind = args.indexOf("delay") + if(del_ind==-1||del_ind==args.length-1){ + message.reply("invalid usage! i need a delay") + break; + } + if(!Object.keys(valid_times).includes(args[del_ind+1][args[del_ind+1].length-1])){ + message.reply("please end your delay with either s,m,h, or d") + break; + } + let time = args[del_ind+1] + let ind = time[time.length-1] + time[time.length-1] = ''; + time = valid_times[ind] * parseInt(time) + if(time==NaN){ + message.reply("invalid delay") + break; + } + db.Timed_Message.create({channel:args[1],message:args[2],last_message:'null',last_message_time:'null',embed:args.includes("embed"),embed_color:config.embed_color,delay:time,guild:message.guild.id}) + //db.Sticky.create({channel:args[1],message:args[2],last_message:'null',embed:args.includes("embed"),embed_color:config.embed_color}); + message.react("✅") + break; + case 'rem': + case 'remove': + case 'r': + if(args.length<2){ + message.reply("not enough parameters, try `sns help timed`") + break; + } + let initial = await db.Timed_Message.count() + await db.Timed_Message.destroy({ + where: { + channel: args[1] + } + }); + message.reply("removed "+(initial-(await db.Timed_Message.count()))+" item(s)") + break; + case 'dump': + case 'list': + let list = await db.Timed_Message.findAll() + let flist = "channelid : message : last message : last message time : delay : color\n" + for(let l of list) + flist+=l.channel+" : "+l.message+" : "+l.last_message+" : "+l.last_message_time+" : " + l.delay + " : " + l.embed_color + "\n" + let filename = "/tmp/timed.json" + fs.writeFileSync(filename,flist) + let stats = fs.statSync(filename) + if(stats.size / (1024*1024) > upload_limit(message.guild)) + return message.reply("file too large:( file is "+stats.size / (1024*1024)+"mb") + message.reply({files:[filename]}) + break; + default: + message.reply("unknown action, try `sns help timed`") + } + + }, +} \ No newline at end of file diff --git a/commands/mod/whois.js b/commands/mod/whois.js new file mode 100644 index 0000000..56d2645 --- /dev/null +++ b/commands/mod/whois.js @@ -0,0 +1,120 @@ +const Discord = require("discord.js") +const settings = require("../../src/settings") +const { EmbedBuilder, PermissionsBitField } = require("discord.js"); +const fs = require('fs') +const {upload_limit} = require("../../src/util") +const path = require('path') +let config_loc = __filename+".json" +let config = JSON.parse(fs.readFileSync(config_loc)) +module.exports = { + name: "whois", + command: ["whois","getuser","getrole"], + mod_only:true, + config:config, + config_loc:config_loc, + async main(client,Discord,message,args) { + if(args.length==0) + return message.reply("bad usage, try `sns help whois`") + await message.guild.members.fetch() + + let error = "" + let users_m = Object.fromEntries(message.mentions.users) + for(let k of Object.keys(users_m)){ + let user = message.guild.members.cache.get(users_m[k].id) + if(user==null) + error+=("user "+users_m[k].id+" not found\n") + else + this.p_user(client,Discord,message,user) + } + let roles_m = Object.fromEntries(message.mentions.roles) + for(let k of Object.keys(roles_m)){ + let role = message.guild.roles.cache.get(roles_m[k].id) + if(role==null) + error+=("role "+roles_m[k].id+" not found\n") + else + this.p_role(client,Discord,message,role) + } + for(let a of args){ + if(a[0]!='<'){ + let role = message.guild.roles.cache.get(a) + let user = message.guild.members.cache.get(a) + if(role!=null) + this.p_role(client,Discord,message,role) + else if(user!=null) + this.p_user(client,Discord,message,user) + else + error+=("user or role "+a+" not found\n") + } + } + if(error!="") + message.reply(error) + //this.p_user(client,Discord,message,user) + }, + s_options:[{type:"role",name:"role",desc:"roles to get info on",required:false,autocomplete:false}, + {type:"user",name:"user",desc:"users to get info on",required:false,autocomplete:false}], + async s_main(client,Discord,interaction){ + let role = interaction.options.getRole("role") + let user = interaction.options.getUser("user") + if(role==null&&user==null) + return interaction.reply({content:"select atleast one option",ephemeral: true}) + if(role!=null) + this.p_role(client,Discord,interaction,role) + if(user!=null){ + await interaction.guild.members.fetch() + user = interaction.guild.members.cache.get(user.id) + this.p_user(client,Discord,interaction,user) + } + }, + p_user(client,Discord,message,user){ + let join = new Date(parseInt(user.joinedTimestamp / 1000, 10)*1000).toLocaleDateString(undefined,{ weekday: 'long', year: 'numeric', month: 'long', day: 'numeric' }); + let created = new Date(parseInt(user.user.createdAt / 1000, 10)*1000).toLocaleDateString(undefined,{ weekday: 'long', year: 'numeric', month: 'long', day: 'numeric' }); + let mod = user.permissions!=null&&user.permissions?.has(PermissionsBitField.Flags.KickMembers) + let roles = "" + //console.log(message.mentions.users) + message.channel.send("loading ids").then(async(m)=>{ + await m.edit("<@!"+user.id+">") + m.delete() + }) + for(let r of user._roles) + roles+="<@&"+r+"> " + const embed = new EmbedBuilder() + .setAuthor({name:user.user.username,iconURL:user.displayAvatarURL()}) + .setThumbnail(user.displayAvatarURL()) + .setDescription("<@!"+user.id+">"+(mod?" +able to use mod commands":"")) + .addFields([{ name: 'Joined', value:join , inline: true }, + { name: 'Created', value:created , inline: true }, + { name: 'Roles ['+user._roles.length+']', value:roles }]) + .setFooter({text:"id:"+user.id}) + .setColor(settings.defaultColor) + message.reply({embeds:[embed]}) + }, + async p_role(client,Discord,message,role){ + let members = " " + //console.log(message.guild.members) + let members_m = Object.fromEntries(message.guild.roles.cache.get(role.id).members) + let members_a = [] + for(let k of Object.keys(members_m)){ + let new_m = "<@"+members_m[k].id+"> " + if((members+new_m).length>1024-3){ + members+="..." + break; + } + members+=new_m + } + if(members!=" "){ + message.channel.send("loading ids").then(async(m)=>{ + await m.edit(members) + m.delete() + }) + } + let mod = role.permissions!=null&&role.permissions?.has(PermissionsBitField.Flags.KickMembers) + const embed = new EmbedBuilder() + .setTitle(role.name) + .setDescription("<@&"+role.id+">"+(mod?" +able to use mod commands":"")) + .addFields([{ name: 'Mentionable', value:(role.mentionable?"true":"false"), inline: true }, + {name: 'Users ['+role.members.size+"]",value:members}]) + .setFooter({text:"id:"+role.id}) + .setColor(settings.defaultColor) + message.reply({embeds:[embed]}) + } +}; diff --git a/commands/util/defaults/emote.js.json b/commands/util/defaults/emote.js.json new file mode 100644 index 0000000..9dd461b --- /dev/null +++ b/commands/util/defaults/emote.js.json @@ -0,0 +1,45 @@ +{"avaliable_multi":{"value":{ + "hug":"hugged", + "bite":"bit", + "boop":"booped", + "bonk":"bonked", + "cuddle":"cuddled", + "dance":"danced with", + "feed":"fed", + "handhold":"held hands with", + "highfive":"highfived", + "kiss":"kissed", + "lick":"licked", + "love":"loved", + "nom":"nommed", + "nuzzle":"nuzzled", + "pat":"pat", + "poke":"poked", + "punch":"punched", + "slap":"slapped", + "stare":"stared down", + "throw":"threw", + "tickle":"tickled" +}},"avaliable_solo":{"value":{ + "bath":"bathed", + "boom":"exploded", + "blush":"blushed", + "clap":"clapped", + "cookie":"had a cookie", + "cringe":"cringed", + "cry":"cried", + "dab":"dabbed", + "facepalm":"facepalmed", + "grin":"grinned", + "laugh":"laughed", + "lurk":"lurked", + "panic":"panicked", + "pout":"pouted", + "sip":"sipped", + "think":"thought", + "run":"ran", + "triggered":"triggered", + "wag":"wagged", + "wink":"winked" +}},"cooldown":3600,"desc":"Sends a gif","restrict":[],"restricted":[], +"usage":"{command} [user]"} \ No newline at end of file diff --git a/commands/util/defaults/help.js.json b/commands/util/defaults/help.js.json new file mode 100644 index 0000000..8908911 --- /dev/null +++ b/commands/util/defaults/help.js.json @@ -0,0 +1,2 @@ +{"cooldown":3,"desc":"Lists commands and info on them!","restrict":["695872127487967233"],"restricted":[], +"usage":"{command} [command]"} \ No newline at end of file diff --git a/commands/util/defaults/poll.js.json b/commands/util/defaults/poll.js.json new file mode 100644 index 0000000..b45d084 --- /dev/null +++ b/commands/util/defaults/poll.js.json @@ -0,0 +1,2 @@ +{"cooldown":3,"desc":"Create a poll","restrict":[],"restricted":[], +"usage":"{command} {title} [option,.. (up to 10)]"} \ No newline at end of file diff --git a/commands/util/defaults/say.js.json b/commands/util/defaults/say.js.json new file mode 100644 index 0000000..4247fd2 --- /dev/null +++ b/commands/util/defaults/say.js.json @@ -0,0 +1,2 @@ +{"cooldown":-1,"desc":"Make me say something","restrict":[],"restricted":[], +"usage":"{command} [channel] {message}"} \ No newline at end of file diff --git a/commands/util/defaults/status.js.json b/commands/util/defaults/status.js.json new file mode 100644 index 0000000..53080f3 --- /dev/null +++ b/commands/util/defaults/status.js.json @@ -0,0 +1,2 @@ +{"cooldown":3,"desc":"Lists server status for snschan","restrict":[],"restricted":[], +"usage":"{command}"} \ No newline at end of file diff --git a/commands/util/emote.js b/commands/util/emote.js new file mode 100644 index 0000000..b06bbef --- /dev/null +++ b/commands/util/emote.js @@ -0,0 +1,47 @@ +const fs = require('fs') +const path = require("path"); +const WeebyAPI = require("weeby-js"); +let settings = require("../../src/settings") +const { EmbedBuilder } = require("discord.js"); +let config_loc = __filename+".json" +let config = JSON.parse(fs.readFileSync(config_loc)) +let subs = [...Object.keys(config.avaliable_solo.value),...Object.keys(config.avaliable_multi.value)] +module.exports = { + name : "emote", + command: subs, + mod_only: false, + config:config, + config_loc:config_loc, + async main (client,Discord,message,args,call){ + let mentioned = message.mentions.users.first(); + this.exec(client,{message:message,emote:call,mentioned:mentioned}) + }, + s_options:[{type:"string",name:"emote",desc:"emote to send",required:true,autocomplete:subs}, + {type:"user",name:"user",desc:"user to emote to (may be optional)",required:false,autocomplete:false}], + async s_main (client,Discord,interaction){ + this.exec(client,{message:interaction,emote:interaction.options.getString("emote"),mentioned:interaction.options.getUser("user")}) + }, + async exec(client,param){ + let msg = ""; + if(Object.keys(config.avaliable_multi.value).includes(param.emote)){ + //let user = await client.users.fetch(userc.id).catch(() => null); + if(!param.mentioned) + return param.message.reply({content:"please mention someone", ephemeral: true}) + if(param.mentioned.id==param.message.author.id) + msg="<@"+param.message.author.id+"> "+config.avaliable_multi.value[param.emote]+" themselves" + else if(param.mentioned.id=="762561860150362142") + msg="<@"+param.message.author.id+"> "+config.avaliable_multi.value[param.emote]+" me!" + else + msg="<@"+param.message.author.id+"> "+config.avaliable_multi.value[param.emote]+" <@"+param.mentioned+">" + } else { + msg="<@"+param.message.author.id+"> "+config.avaliable_solo.value[param.emote] + } + const weeby = new WeebyAPI(client.env.WEEBY_TOKEN); + let gif = await weeby.gif.fetch(param.emote); + let emoteembed = new EmbedBuilder() + .setDescription(msg) + .setImage(gif) + .setColor(settings.defaultColor) + param.message.reply({embeds:[emoteembed]}) + } +} \ No newline at end of file diff --git a/commands/util/help.js b/commands/util/help.js new file mode 100644 index 0000000..b52ee12 --- /dev/null +++ b/commands/util/help.js @@ -0,0 +1,140 @@ +const fs = require('fs') +const path = require("path"); +const { EmbedBuilder,ActionRowBuilder,ButtonBuilder,ButtonStyle } = require("discord.js"); +let config_loc = __filename+".json" +let settings = require("../../src/settings") +let config = JSON.parse(fs.readFileSync(config_loc)) + +//get command names +let command_names = ["help"] +fs.readdirSync(path.join(__dirname+"/..")).forEach(folder => { + fs.readdirSync(path.join(__dirname+"/../"+folder)).forEach(file => { + if(path.extname(file)==".js"){ + if(path.join(__dirname+"/../"+folder+"/"+file)!=__filename){ + let info = require("../"+folder+"/"+file) + //let commands = info.command.length>3?info.command.slice(0,3).join(",")+"...":info.command.join(",") + command_names.push(info.name) + } + + } + }) +}) +// + +module.exports = { + name : "help", + command: ["help"], + mod_only: false, + config:config, + config_loc:config_loc, + async main (client,Discord,message,args){ + this.exec(client,{message:message,specify:args[0]}) + }, + s_options:[{type:"string",name:"command",desc:"command to be specified",required:false,autocomplete:command_names}], + async s_main(client,Discord,interaction){ + this.exec(client,{message:interaction,specify:interaction.options.getString("command")}) + }, + async exec(client,param){ + if(param.specify!=null){ + let info = null + fs.readdirSync(path.join(__dirname+"/..")).forEach(folder => { + fs.readdirSync(path.join(__dirname+"/../"+folder)).forEach(file => { + if(path.extname(file)==".js"){ + let tinfo = require("../"+folder+"/"+file) + if(tinfo.name==param.specify||tinfo.command.includes(param.specify)) + info=tinfo + } + }) + }) + if(info==null) + return param.message.reply({content:"command not found:c",ephemeral: true}) + let restricted = info.config.restricted.length==0?"undefined":info.config.restricted.join(",") + let restrict = info.config.restrict.length==0?"undefined":info.config.restrict.join(",") + const embed = new EmbedBuilder() + .setTitle(info.name) + .setColor(settings.defaultColor) + .addFields([{ + name:"commands/subcommands", + value:info.command.join(",") + },{ + name:"description", + value: info.config.desc == undefined ? "undefined" : info.config.desc + },{ + name:"usage", + value: info.config.usage == undefined ? "undefined" : info.config.usage + },{ + name:"misc", + value:"cooldown: "+info.config.cooldown+", restricted channels: ["+restricted+"], restrict to channels: ["+restrict+"], "+(info.s_main!=null?"supports slash commands":"does not support slash commands") + }]) + param.message.reply({embeds:[embed]}) + return + } + //message.reply("not done yet:( give ans-chan some hugs and headpats for faster development") + let pages = [] + let page = 0 + fs.readdirSync(path.join(__dirname+"/..")).forEach(folder => { + const embed = new EmbedBuilder() + .setTitle(folder) + .setColor(settings.defaultColor) + let count = 0; + fs.readdirSync(path.join(__dirname+"/../"+folder)).forEach(file => { + if(path.extname(file)==".js"){ + count++; + let info = require("../"+folder+"/"+file) + let commands = info.command.length>3?info.command.slice(0,3).join(",")+"...":info.command.join(",") + embed.addFields([{ + name:info.name + " [" + commands + "]", + value:info.config.desc + }]) + /*page.push({ + name:info.name, + subcommands:info.command, + desc:info.desc, + cooldown:cooldown + })*/ + + } + }) + embed.setFooter({text:"use `sns help {command}` to get more info • "+count+" items"}) + pages.push(embed) + }) + const last = new ButtonBuilder() + .setCustomId('last') + .setEmoji('⬅️') + .setStyle(ButtonStyle.Primary) + const next = new ButtonBuilder() + .setCustomId('next') + .setEmoji('➡️') + .setStyle(ButtonStyle.Primary) + const row = new ActionRowBuilder() + .addComponents(last,next); + let mess = await param.message.reply({embeds:[pages[page]],components:[row]}) + async function rec_edit(mess,page){ + const collectorFilter = i => i.user.id === param.message.author.id; + try { + const confirmation = await mess.awaitMessageComponent({ filter: collectorFilter, time: 60000000 }); + if(confirmation.customId == "next"){ + if(page+1=0) + page--; + else + page=pages.length-1; + mess.edit({embeds:[pages[page]]}) + rec_edit(mess,page) + confirmation.deferUpdate() + } + } catch (e) { + + } + } + await rec_edit(mess,page) + } +} \ No newline at end of file diff --git a/commands/util/poll.js b/commands/util/poll.js new file mode 100644 index 0000000..39d4e92 --- /dev/null +++ b/commands/util/poll.js @@ -0,0 +1,61 @@ +const fs = require('fs') +const path = require("path"); +let config_loc = __filename+".json" +const { PermissionsBitField, EmbedBuilder } = require('discord.js'); +let config = JSON.parse(fs.readFileSync(config_loc)) +const numbers = ["1️⃣" ,"2️⃣", "3️⃣" ,"4️⃣" ,"5️⃣", "6️⃣", "7️⃣", "8️⃣" ,"9️⃣" ,"🔟"] +let settings = require("../../src/settings") +module.exports = { + name : "poll", + command: ["poll"], + mod_only: true, + config:config, + config_loc:config_loc, + async main (client,Discord,message,args){ + let title = args[0]; + args.shift(); + if(args.length>10)return message.reply("too many options") + this.exec(client,{message:message,title:title,options:args}) + }, + s_options:[{type:"string",name:"title",desc:"title of poll",required:true,autocomplete:false}, + {type:"string",name:"option-1",desc:"poll option",required:true,autocomplete:false}, + {type:"string",name:"option-2",desc:"poll option",required:false,autocomplete:false}, + {type:"string",name:"option-3",desc:"poll option",required:false,autocomplete:false}, + {type:"string",name:"option-4",desc:"poll option",required:false,autocomplete:false}, + {type:"string",name:"option-5",desc:"poll option",required:false,autocomplete:false}, + {type:"string",name:"option-6",desc:"poll option",required:false,autocomplete:false}, + {type:"string",name:"option-7",desc:"poll option",required:false,autocomplete:false}, + {type:"string",name:"option-8",desc:"poll option",required:false,autocomplete:false}, + {type:"string",name:"option-9",desc:"poll option",required:false,autocomplete:false}, + {type:"string",name:"option-10",desc:"poll option",required:false,autocomplete:false},], + async s_main (client,Discord,interaction){ + this.exec(client, + {message:interaction,options:[ + interaction.options.getString("option-1"), + interaction.options.getString("option-2") , + interaction.options.getString("option-3") , + interaction.options.getString("option-4") , + interaction.options.getString("option-5") , + interaction.options.getString("option-6") , + interaction.options.getString("option-7") , + interaction.options.getString("option-8") , + interaction.options.getString("option-9") , + interaction.options.getString("option-10") , + ].filter(n => n),title:interaction.options.getString("title")}) + }, + async exec(client,info){ + let embed = new EmbedBuilder() + .setTitle(info.title) + let desc = ""; + for(let a in info.options){ + desc+=numbers[a]+" "+info.options[a]+"\n"; + } + embed.setDescription(desc) + .setColor(settings.defaultColor) + .setFooter({text: 'poll:'+info.options.length+' | '+info.message.author.username}) + let m = await info.message.reply({embeds:[embed],fetchReply: true }) + for(let a in info.options){ + m.react(numbers[a]) + } + } +} \ No newline at end of file diff --git a/commands/util/say.js b/commands/util/say.js new file mode 100644 index 0000000..17af382 --- /dev/null +++ b/commands/util/say.js @@ -0,0 +1,36 @@ +const fs = require('fs') +const path = require("path"); +let config_loc = __filename+".json" +const { PermissionsBitField } = require('discord.js'); +let config = JSON.parse(fs.readFileSync(config_loc)) +module.exports = { + name : "say", + command: ["say"], + mod_only: true, + config:config, + config_loc:config_loc, + async main (client,Discord,message,args){ + let id = message.mentions.channels.first() + let echo = message.content.slice(8) + if(id){ + echo = echo.split(/ +/g); + echo.shift(); + echo = echo.join(' ') + } else { + id = message.channel + } + this.exec(client,{id:id,echo:echo}) + }, + s_options:[{type:"string",name:"echo",desc:"message to be said",required:true,autocomplete:false}, + {type:"channel",name:"channel",desc:"channel to be sent to",required:false,autocomplete:false}], + async s_main (client,Discord,interaction){ + this.exec(client, + {echo:interaction.options.getString("echo"), + id:interaction.options.getChannel("channel") ?? interaction.channel}) + await interaction.reply({ content:'sent', ephemeral: true }) + interaction.deleteReply() + }, + async exec(client,info){ + return info.id.send(info.echo) + } +} \ No newline at end of file diff --git a/commands/util/status.js b/commands/util/status.js new file mode 100644 index 0000000..27f1e03 --- /dev/null +++ b/commands/util/status.js @@ -0,0 +1,63 @@ +const fs = require('fs') +const path = require("path"); +let settings = require("../../src/settings") +let {limit_exp} = require("../../src/util") +const { EmbedBuilder,ActionRowBuilder,ButtonBuilder,ButtonStyle } = require("discord.js"); +const {getLastCommit} = require("git-last-commit") +var os = require('os'); +let config_loc = __filename+".json" +let config = JSON.parse(fs.readFileSync(config_loc)) +module.exports = { + name : "status", + command: ["status","server","uptime","vote","twitter","𝕏"], + mod_only: false, + config:config, + config_loc:config_loc, + async main (client,Discord,message,args){ + this.exec(client,message) + }, + async s_main (client,Discord,interaction){ + this.exec(client,interaction) + }, + async exec(client,message){ + getLastCommit((err,commit)=>{ + let seconds = Math.floor(message.client.uptime / 1000); + let minutes = Math.floor(seconds / 60); + let hours = Math.floor(minutes / 60); + let days = Math.floor(hours / 24); + let uptime = "online for: "; + if(days>0)uptime+=days+" days" + else if(hours>0)uptime+=hours+"h" + else if(minutes>0)uptime+=minutes+"m" + else uptime+=seconds+"s" + uptime+=" | "+limit_exp((message.client.uptime*1000).toExponential(),2)+"μs" + const vote = new ButtonBuilder() + .setLabel('Vote') + .setStyle(ButtonStyle.Link) + .setURL('https://top.gg/servers/486957006628847626/vote') + /*const twitter = new ButtonBuilder() //0% chance i will call this 𝕏 + .setLabel('Twitter') + .setStyle(ButtonStyle.Link) + .setURL('https://twitter.com/sns_chan')*/ + const discord = new ButtonBuilder() + .setLabel('Discord') + .setStyle(ButtonStyle.Link) + .setURL('https://discord.gg/supernoobs') + const github = new ButtonBuilder() + .setLabel('Github') + .setStyle(ButtonStyle.Link) + .setURL('https://github.com/iamAGFX/snschan-bot') + const row = new ActionRowBuilder() + .addComponents(vote,discord,github); + let conv = 1024 * 1024 * 1024 + let sys = "system: cpus: "+os.cpus().length+", ram (free): "+Math.floor(os.freemem()/conv)+"/"+Math.floor(os.totalmem()/conv)+"gb\nkernel: "+os.release() + let emoteembed = new EmbedBuilder() + .setThumbnail(client.user.displayAvatarURL()) + .setTitle("Server info") + .setDescription(uptime+"\n"+sys) + .setColor(settings.defaultColor) + .setFooter({text:"running "+commit.shortHash+" ("+commit.branch+")"}) + message.reply({embeds:[emoteembed],components:[row]}) + }) + } +} \ No newline at end of file diff --git a/events/defaults/dm.js.json b/events/defaults/dm.js.json new file mode 100644 index 0000000..c11cbb9 --- /dev/null +++ b/events/defaults/dm.js.json @@ -0,0 +1,5 @@ +{ + "ticket-id-chars":{"value":"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"}, + "ticket-id-length":{"value":7}, + "ticket-id-split":{"value":3} +} \ No newline at end of file diff --git a/events/defaults/interaction.js.json b/events/defaults/interaction.js.json new file mode 100644 index 0000000..544b7b4 --- /dev/null +++ b/events/defaults/interaction.js.json @@ -0,0 +1,3 @@ +{ + +} \ No newline at end of file diff --git a/events/defaults/message.js.json b/events/defaults/message.js.json new file mode 100644 index 0000000..4e863a9 --- /dev/null +++ b/events/defaults/message.js.json @@ -0,0 +1,6 @@ +{ +"restrict-channels":{"value":["825023574221783102","754582601766928456","545076257369358338"]}, +"error-message":{"value":"failed to execute command:("},"error-timeout":{"value":10000}, +"error-message-auth":{"value":"you are not authorized to use this:(("}, +"error-message-not-found":{"value":"i couldnt find that command:( were you talking to me?"}, +"error-message-not-here":{"value":"cant use that here!"}} \ No newline at end of file diff --git a/events/defaults/reaction-remove.js.json b/events/defaults/reaction-remove.js.json new file mode 100644 index 0000000..9e26dfe --- /dev/null +++ b/events/defaults/reaction-remove.js.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/events/defaults/ready.js.json b/events/defaults/ready.js.json new file mode 100644 index 0000000..4ee756c --- /dev/null +++ b/events/defaults/ready.js.json @@ -0,0 +1,5 @@ +{ + "status":{"value":"dm to report an issue"}, + "type":{"value":"Playing","options":["Listening","Playing","Streaming","Watching"]}, + "timed_interval":{"value":5000} +} \ No newline at end of file diff --git a/events/dm.js b/events/dm.js new file mode 100644 index 0000000..dfb7f51 --- /dev/null +++ b/events/dm.js @@ -0,0 +1,104 @@ +const { ActivityType, ButtonBuilder, ButtonStyle, ActionRowBuilder} = require("discord.js"); +const { EmbedBuilder } = require("discord.js"); +const fs = require('fs') +const path = require("path"); +let db = require("../src/db") +let settings = require("../src/settings") +let config_loc = __filename+".json" +module.exports = { + name : "dm", + config_loc : config_loc, + async main (client,Discord,message){ + if(message==null||message.author.bot)return; + let config = JSON.parse(fs.readFileSync(config_loc)) + //start tickets + let date = new Date().toLocaleString() + let tickets = await db.Tickets.findAll({where:{status:'open',author:message.author.id}}) + let matt = Array.from(message.attachments, ([name, value]) => ({ name, value })) + let smatt = [] + for(let att of matt){ + smatt.push({attachment:att.value.url}) + } + if(tickets.length==0){ + let nticket = this.generate_id() + const embed = new EmbedBuilder() + .setTitle("New Ticket | "+nticket) + .setAuthor({name: message.author.tag, iconURL: message.author.displayAvatarURL()}) + .setColor(settings.defaultColor) + .setDescription("Message: "+message.content) + .setFooter({text:"Created by: "+message.author.id+" | Created: "+date}) + + const confirm = new ButtonBuilder() + .setCustomId('confirm') + .setLabel('Confirm') + .setStyle(ButtonStyle.Primary); + const row = new ActionRowBuilder() + .addComponents(confirm); + + let mess = await message.channel.send({embeds:[embed],components:[row],files:smatt}); + + const collectorFilter = i => true; + + try { + const confirmation = await mess.awaitMessageComponent({ filter: collectorFilter, time: 60000000 }); + if(confirmation.customId == "confirm"){ + + let nt = await db.Tickets.create({ + ticket:nticket, + message: message.content, + attachments: JSON.stringify(matt), + status: "open", + author: message.author.id, + name: message.author.tag, + created: date, + messages: JSON.stringify([]), + pfp: message.author.displayAvatarURL() + }) + + const aembed = new EmbedBuilder() + .setTitle("New Ticket | "+nticket) + .setAuthor({name: message.author.tag, iconURL: message.author.displayAvatarURL()}) + .setColor(settings.defaultColor) + .setDescription("Message: '"+message.content+"'\n\nUse `/ticket` or `sns ticket reply "+nticket+" {message}`") + .setFooter({text:"Created by: "+message.author.id+" | Created: "+date}) + + global.channels["admin-chan"].send({embeds:[aembed],files:smatt}) + confirmation.deferUpdate() + } + } catch (e) { + const confirm_timeout = new ButtonBuilder() + .setCustomId('confirm') + .setLabel('Confirm') + .setStyle(ButtonStyle.Primary) + .setDisabled(true); + const row_timeout = new ActionRowBuilder() + .addComponents(confirm_timeout); + await mess.edit({ components: [row_timeout] }); + } + } else { + let ticket = tickets[0] + let messages = JSON.parse(ticket.messages) + messages.push({message:message.content,attachments:matt}) + db.Tickets.update({'messages':JSON.stringify(messages)},{where:{id:ticket.id}}) + const aembed = new EmbedBuilder() + .setTitle("Updated Ticket | "+ticket.ticket) + .setAuthor({name: message.author.tag, iconURL: message.author.displayAvatarURL()}) + .setColor(settings.defaultColor) + .setDescription("Message: '"+message.content+"'\n\nReply with `sns ticket reply "+ticket.ticket+" {message}`") + .setFooter({text:"Created by: "+message.author.id+" | Created: "+date}) + + global.channels["admin-chan"].send({embeds:[aembed],files:smatt}) + } + //done w/ tickets + }, + generate_id(){ + let config = JSON.parse(fs.readFileSync(config_loc)) + var ticket = ""; + var characters = config["ticket-id-chars"].value; + for (var i = 0; i < config["ticket-id-length"].value; i++) { + ticket += characters.charAt(Math.floor(Math.random() * characters.length)); + if (i == config["ticket-id-split"].value) ticket += "-"; + } + return ticket + } +} \ No newline at end of file diff --git a/events/interaction.js b/events/interaction.js new file mode 100644 index 0000000..3a3b32a --- /dev/null +++ b/events/interaction.js @@ -0,0 +1,57 @@ +const { ActivityType , PermissionsBitField} = require("discord.js"); +const fs = require('fs') +const path = require("path"); +const { EmbedBuilder } = require("discord.js"); +let db = require("../src/db") +let settings = require('../src/settings') +let config_loc = __filename+".json" +module.exports = { + name : "interactionCreate", + config_loc : config_loc, + async main (client,Discord){ + await db._raw.sync() + let config = JSON.parse(fs.readFileSync(config_loc)) + client.on("interactionCreate", async(interaction) => { + if(interaction.guild==null)return + if(!settings["allowed-servers"].includes(interaction.guild.id)) + return console.log("denied interaction from (guild)"+interaction.guild.id) + let date = new Date() + if(interaction.isChatInputCommand()){ + + await interaction.guild.members.fetch() + interaction.user = interaction.guild.members.cache.get(interaction.user.id) + let mod = interaction.user.permissions!=null&&interaction.user.permissions?.has(PermissionsBitField.Flags.KickMembers) + let command = global.s_commands.find(o => o.name === interaction.commandName) + if(!((!command.command.config.restrict||command.command.config.restrict.includes(interaction.channel.id))&& + (!command.command.config.restricted||!command.command.config.restricted.includes(interaction.channel.id)))&&!mod) + return interaction.reply({content:"you cannot send this here! try `sns help` for more info",ephemeral:true}) + if(command==null) + return; + interaction.author = interaction.user + let uid = interaction.user.id; + + if(!mod&&command.command.last_command[uid]!=null&&(date.getTime()-command.command.last_command[uid].getTime())/1000 o.name === interaction.commandName) + let subcommand = command.opt.find(o => o.name === focused.name) + let autocomplete = (typeof subcommand.autocomplete === 'function' ? await subcommand.autocomplete() : subcommand.autocomplete); + const filtered = autocomplete.filter(choice => choice.startsWith(focused.value)); + if(filtered.length>25) + filtered.length=25 + await interaction.respond( + filtered.map(choice => ({ name: choice, value: choice })), + ); + + } + }) + + }, +} \ No newline at end of file diff --git a/events/message.js b/events/message.js new file mode 100644 index 0000000..817a592 --- /dev/null +++ b/events/message.js @@ -0,0 +1,100 @@ +const fs = require('fs') +const path = require("path"); +let db = require("../src/db"); +const { parse_inp } = require("../src/util") +const { channel } = require('diagnostics_channel'); +const { PermissionsBitField } = require('discord.js'); +const { EmbedBuilder } = require("discord.js"); +let settings = require('../src/settings') +let config_loc = __filename+".json" +module.exports = { + name : "messageCreate", + config_loc : config_loc, + async main (client,Discord){ + let config = JSON.parse(fs.readFileSync(config_loc)) + client.on("messageCreate", async (message) => { + if(message.guild==null) + return require("./dm").main(client,Discord,message) + if(!settings["allowed-servers"].includes(message.guild.id)||message.author.bot||message.member==null) + return; + //handle sticky messages + let stickies = await db.Sticky.findAll(); + for(let s of stickies){ + if(message.channel.id==s.channel && message.author.id!="762561860150362142"){ + let m; + if(s.embed){ + let embed = new EmbedBuilder() + .setDescription(s.message) + .setColor(s.embed_color) + m = await message.channel.send({embeds:[embed]}) + } else { + m = await message.channel.send(s.message) + } + if(s.last_message!='null'){ + try{ + let msg = await message.channel.messages.fetch(s.last_message) + msg.delete() + + } catch(e){} + } + db.Sticky.update({last_message: m.id},{ where: {id: s.id}}) + } + + } + //done w/ sticky + + //handle auto reactions + let a_react = await db.Auto_React.findAll(); + for(let a of a_react){ + if(message.channel.id==a.channel && message.author.id!="762561860150362142"){ + try{ + let m = await message.react(a.emote) + } catch(e){} + } + + } + //done w/ auto reactions + + //deal with commands + let remove = function(msg) {setTimeout(async()=>{try{await msg.delete()}catch(e){}},config["error-timeout"].value)} + let date = new Date() + let uid = message.member.id; + let mod = message.member.permissions!=null&&message.member.permissions?.has(PermissionsBitField.Flags.KickMembers) + if(message.content.startsWith("sns ")&&(!config["restrict-channels"].value.includes(message.channel.id)||(mod))){ + let com_string = message.content.split(" ") + com_string.shift() + let found = false; + let com_call = com_string[0].trim() + //keep this as a for loop incase we want to do sequential commands + for(let com of global.commands){ + if(com.command.includes(com_call)){ + found = true; + if(com.mod_only&&!mod){ + message.reply(config["error-message-auth"].value).then((msg)=>{remove(msg)}) + break; + } + com_string.shift() + com_string = parse_inp(com_string.join(" ")) + try{ + if(((!com.config.restrict||com.config.restrict.includes(message.channel))&& + (!com.config.restricted||!com.config.restricted.includes(message.channel)))||mod) + if(mod||com.config.cooldown==null||com.last_command[uid]==null||(date.getTime()-com.last_command[uid].getTime())/1000>com.config.cooldown){ + await com.main(client,Discord,message,com_string,com_call) + com.last_command[uid] = new Date() + } else message.reply("this command is on cooldown for "+((date.getTime()-com.last_command[uid].getTime())/1000).toFixed(2)+"/"+com.config.cooldown+"s").then((msg)=>{remove(msg)}) + else + message.reply(config["error-message-not-here"].value).then((msg)=>{remove(msg)}) + } catch(e) { + message.reply(config["error-message"].value + "\n```"+e.stack+"```").then((msg)=>{remove(msg)}) + console.log(e.stack) + } + break; + } + } + if(!found) + message.reply(config["error-message-not-found"].value).then((msg)=>{remove(msg)}) + } + //done w/ commands + }) + }, +} \ No newline at end of file diff --git a/events/reaction-remove.js b/events/reaction-remove.js new file mode 100644 index 0000000..b46595b --- /dev/null +++ b/events/reaction-remove.js @@ -0,0 +1,20 @@ +const { ActivityType , PermissionsBitField} = require("discord.js"); +const fs = require('fs') +const path = require("path"); +const { EmbedBuilder } = require("discord.js"); +let db = require("../src/db") +let settings = require("../src/settings") +let config_loc = __filename+".json" +module.exports = { + name : "messageReactionRemove", + config_loc : config_loc, + async main (client,Discord){ + client.on("messageReactionRemoveEmoji",(m)=>{ + global.channels.logging.send({embeds:[new EmbedBuilder().setTitle("Emoji removed").setDescription((m.count??1)+" "+m.emoji.name+"(s) have been removed from "+m.message.url).setTimestamp(Date.now()).setColor(settings.defaultColor)]}) + }) + client.on("messageReactionRemoveAll",(m)=>{ + global.channels.logging.send({embeds:[new EmbedBuilder().setTitle("Bulk emoji remove").setDescription("All emojis have been removed from "+m.url).setTimestamp(Date.now()).setColor(settings.defaultColor)]}) + }) + + }, +} \ No newline at end of file diff --git a/events/ready.js b/events/ready.js new file mode 100644 index 0000000..c694c00 --- /dev/null +++ b/events/ready.js @@ -0,0 +1,87 @@ +const { ActivityType } = require("discord.js"); +const fs = require('fs') +const path = require("path"); +const { EmbedBuilder } = require("discord.js"); +let db = require("../src/db") +let settings = require('../src/settings') +let config_loc = __filename+".json" +module.exports = { + name : "ready", + config_loc : config_loc, + async main (client,Discord){ + await db._raw.sync() + let config = JSON.parse(fs.readFileSync(config_loc)) + client.once("ready", () => { + //preload + global.channels = {} + for(let guild of Object.keys(settings.preloads)){ + + for(let chan of Object.keys(settings.preloads[guild])){ + let t_add = client.guilds.cache.get(guild).channels.cache.get(chan) + if(t_add==null) + console.log("failed to load "+chan+" from "+guild+", skipping"); + else + global.channels[settings.preloads[guild][chan].name] = t_add + } + } + //end + + //register slash commands + let passed = 0; + let failed = 0; + client.guilds.cache.forEach((g)=>{ + if(settings["allowed-servers"].includes(g.id)){ + g.commands.set(global.s_commands).catch((e)=>{ + console.log("unable to load commands for " + g.id + "\n\n****\n") + console.log(e) + }) + passed++; + } else { + failed++; + } + }) + console.log("loaded "+global.s_commands.length+" slash commands for "+passed+" guilds, and denied "+failed+" guilds") + //done w/ slash commands + + console.log("online!") + function set_pres() { + client.user.setPresence({ + activities: [{ name: config.status.value, type: ActivityType[config.type.value] }] + }); + } + set_pres() + setInterval(set_pres,36000) + setInterval(async()=>{ + //timed messages + let timed = await db.Timed_Message.findAll(); + let cur = new Date() + for(let t of timed){ + let delay = parseInt(t.delay) + if(t.last_message_time!='null') + t.last_message_time = parseInt(t.last_message_time) + //console.log(new Date(parseInt(t.last_message_time)),(new Date(t.last_message_time)).getTime(),delay) + if(t.last_message_time=='null'||cur.getTime()-(new Date(t.last_message_time)).getTime()>delay){ + + let gu = await client.guilds.fetch(t.guild) + let channel = await gu.channels.fetch(t.channel) + if(t.embed){ + let embed = new EmbedBuilder() + .setDescription(t.message) + .setColor(t.embed_color) + channel.send({embeds:[embed]}) + } else { + channel.send(t.message) + } + //console.log(new Date(t.last_message_time).getTime(),(new Date(t.last_message_time)).getTime()+delay) + if(t.last_message_time=='null') + db.Timed_Message.update({last_message_time : cur.getTime().toString()},{ where: {id: t.id}}) + else + db.Timed_Message.update({last_message_time : (new Date((new Date(t.last_message_time)).getTime()+delay)).getTime().toString()},{ where: {id: t.id}}) + } + } + //done w/ timed messages + },config.timed_interval.value) + }) + + }, +} \ No newline at end of file diff --git a/html/settings.html b/html/settings.html new file mode 100644 index 0000000..e69de29 diff --git a/html/tickets.html b/html/tickets.html new file mode 100644 index 0000000..78f3bd3 --- /dev/null +++ b/html/tickets.html @@ -0,0 +1,541 @@ + + + + + + + + + + + + sns-chan + + + + + + + + + + + diff --git a/img/battleship-board-sel.png b/img/battleship-board-sel.png new file mode 100644 index 0000000..ba1f56d Binary files /dev/null and b/img/battleship-board-sel.png differ diff --git a/img/battleship-board.png b/img/battleship-board.png new file mode 100644 index 0000000..4b2fe24 Binary files /dev/null and b/img/battleship-board.png differ diff --git a/img/fire.png b/img/fire.png new file mode 100644 index 0000000..fe6863c Binary files /dev/null and b/img/fire.png differ diff --git a/index.js b/index.js new file mode 100644 index 0000000..be5ab38 --- /dev/null +++ b/index.js @@ -0,0 +1,128 @@ +//process mods redirection +const fs = require("fs"); +var access = fs.createWriteStream('./log'); +process.stdout.write = process.stderr.write = (function(write) { + return function(string, encoding, fd) { + write.apply(process.stdout, arguments) + access.write(string) + } +})(process.stdout.write) +process.title = "sns-chan" +/** + * Module Imports + */ +const { Client, Collection, EmbedBuilder, ActivityType, GatewayIntentBits, Partials, Events, SlashCommandBuilder, PermissionsBitField} = require("discord.js"); +const Discord = require('discord.js'); +const dotenv = require("dotenv").config(); +const TOKEN = process.env.TOKEN; +const path = require("path"); +let db = require("./src/db"); + +const client = new Client({ + intents: [ + GatewayIntentBits.Guilds, + GatewayIntentBits.GuildMessages, + GatewayIntentBits.DirectMessages, + GatewayIntentBits.Guilds, + GatewayIntentBits.GuildBans, + GatewayIntentBits.GuildMessages, + GatewayIntentBits.MessageContent, + GatewayIntentBits.GuildVoiceStates, + GatewayIntentBits.GuildMessageReactions, + GatewayIntentBits.DirectMessages, + GatewayIntentBits.GuildMembers, + GatewayIntentBits.DirectMessageReactions, + GatewayIntentBits.DirectMessageTyping, + //GatewayIntentBits.GuildPresences + ], + partials: [Partials.Message, Partials.Channel, Partials.Reaction, Partials.User] +}); + +client.login(TOKEN); + +let commands = [] +let s_commands = [] +fs.readdirSync("./commands/").forEach(folder => { + fs.readdirSync("./commands/"+folder).forEach(file => { + if(path.extname(file)==".js"){ + try{ + let com = require("./commands/"+folder+"/"+file) + com.last_command = {}; + commands.push(com) + if(com.s_main!=null){ + let scom = new SlashCommandBuilder() + .setName(com.name.replace(/ /g,'-')) + .setDescription(com.config.desc) + if(com.mod_only) + scom.setDefaultMemberPermissions(PermissionsBitField.Flags.KickMembers) + if(com.s_options!=null){ + for(let opt of com.s_options){ + switch(opt.type){ + case 'string': + scom.addStringOption(option => + option.setName(opt.name) + .setDescription(opt.desc) + .setRequired(opt.required) + .setAutocomplete(opt.autocomplete!=null&&opt.autocomplete!=false)) + break; + case 'channel': + scom.addChannelOption(option => + option.setName(opt.name) + .setDescription(opt.desc) + .setRequired(opt.required)) + break; + case 'user': + scom.addUserOption(option => + option.setName(opt.name) + .setDescription(opt.desc) + .setRequired(opt.required)) + break; + case 'role': + scom.addRoleOption(option => + option.setName(opt.name) + .setDescription(opt.desc) + .setRequired(opt.required)) + break; + case 'attachment': + scom.addAttachmentOption(option => + option.setName(opt.name) + .setDescription(opt.desc) + .setRequired(opt.required)) + break; + } + + } + scom.opt = com.s_options + } + scom = scom.toJSON() + scom.command = com + s_commands.push(scom) + } + } catch (e) { + if(e.code=="ENOENT"){ + console.log("[ENOENT] missing some config files:( run 'sh buildconfig.sh' to get them\nexiting~") + process.exit(e.errno) + } + console.log("["+e.code+"]"+" unexpected error:( something is wrong with the ./commands/*/* files\n****\n") + console.log(e) + + process.exit(e.errno) + } + } + }) +}) + +client.env = process.env +global.commands = commands; +global.s_commands = s_commands; + +fs.readdirSync("./events/").forEach(file => { + if(path.extname(file)==".js") + require("./events/"+file).main(client,Discord) +}) + +try{ + require("./src/webui") +} catch(e) { + console.log("failed loading webui:c") +} diff --git a/license.md b/license.md new file mode 100644 index 0000000..fd5dea9 --- /dev/null +++ b/license.md @@ -0,0 +1,11 @@ +Copyright <2023> + +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. + +3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/package.json b/package.json new file mode 100644 index 0000000..140e8bf --- /dev/null +++ b/package.json @@ -0,0 +1,37 @@ +{ + "name": "snschan", + "version": "0.10.0", + "description": "Discord music bot built with discord.js", + "main": "index.js", + "author": "Ryzyx", + "private": true, + "homepage": "https://github.com/ryzyx/sns-chan", + "repository": "github:ryzyx/sns-chan", + "bugs": "https://github.com/ryzyx/sns-chan/issues", + "engines": { + "node": "=16.6.1" + }, + "dependencies": { + "@discordjs/opus": "^0.5.0", + "@discordjs/voice": "^0.11.0", + "discord-embedbuilder": "^4.0.0", + "discord-together": "^1.3.3", + "discord.js": "^14.8.0", + "dotenv": "^9.0.2", + "express": "^4.17.1", + "ffmpeg-static": "^4.2.3", + "git-last-commit": "^1.0.1", + "os-utils": "^0.0.14", + "sequelize": "^6.32.1", + "sharp": "^0.32.6", + "sqlite3": "^5.1.6", + "weeby-js": "^1.0.3" + }, + "scripts": { + "start": "node index.js" + }, + "devDependencies": { + "@types/node": "^18.7.19", + "eslint": "^8.47.0" + } +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml new file mode 100644 index 0000000..fdbd78d --- /dev/null +++ b/pnpm-lock.yaml @@ -0,0 +1,2532 @@ +lockfileVersion: '6.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +dependencies: + '@discordjs/opus': + specifier: ^0.5.0 + version: 0.5.3 + '@discordjs/voice': + specifier: ^0.11.0 + version: 0.11.0(@discordjs/opus@0.5.3)(ffmpeg-static@4.4.1) + discord-embedbuilder: + specifier: ^4.0.0 + version: 4.0.0 + discord-together: + specifier: ^1.3.3 + version: 1.3.31 + discord.js: + specifier: ^14.8.0 + version: 14.13.0 + dotenv: + specifier: ^9.0.2 + version: 9.0.2 + express: + specifier: ^4.17.1 + version: 4.18.2 + ffmpeg-static: + specifier: ^4.2.3 + version: 4.4.1 + git-last-commit: + specifier: ^1.0.1 + version: 1.0.1 + os-utils: + specifier: ^0.0.14 + version: 0.0.14 + sequelize: + specifier: ^6.32.1 + version: 6.33.0(sqlite3@5.1.6) + sharp: + specifier: ^0.32.6 + version: 0.32.6 + sqlite3: + specifier: ^5.1.6 + version: 5.1.6 + weeby-js: + specifier: ^1.0.3 + version: 1.3.0 + +devDependencies: + '@types/node': + specifier: ^18.7.19 + version: 18.17.17 + eslint: + specifier: ^8.47.0 + version: 8.49.0 + +packages: + + /@aashutoshrathi/word-wrap@1.2.6: + resolution: {integrity: sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==} + engines: {node: '>=0.10.0'} + dev: true + + /@derhuerst/http-basic@8.2.4: + resolution: {integrity: sha512-F9rL9k9Xjf5blCz8HsJRO4diy111cayL2vkY2XE4r4t3n0yPXVYy3KD3nJ1qbrSn9743UWSXH4IwuCa/HWlGFw==} + engines: {node: '>=6.0.0'} + dependencies: + caseless: 0.12.0 + concat-stream: 2.0.0 + http-response-object: 3.0.2 + parse-cache-control: 1.0.1 + dev: false + + /@discordjs/builders@1.6.5: + resolution: {integrity: sha512-SdweyCs/+mHj+PNhGLLle7RrRFX9ZAhzynHahMCLqp5Zeq7np7XC6/mgzHc79QoVlQ1zZtOkTTiJpOZu5V8Ufg==} + engines: {node: '>=16.11.0'} + dependencies: + '@discordjs/formatters': 0.3.2 + '@discordjs/util': 1.0.1 + '@sapphire/shapeshift': 3.9.2 + discord-api-types: 0.37.50 + fast-deep-equal: 3.1.3 + ts-mixer: 6.0.3 + tslib: 2.6.2 + dev: false + + /@discordjs/collection@1.5.3: + resolution: {integrity: sha512-SVb428OMd3WO1paV3rm6tSjM4wC+Kecaa1EUGX7vc6/fddvw/6lg90z4QtCqm21zvVe92vMMDt9+DkIvjXImQQ==} + engines: {node: '>=16.11.0'} + dev: false + + /@discordjs/formatters@0.3.2: + resolution: {integrity: sha512-lE++JZK8LSSDRM5nLjhuvWhGuKiXqu+JZ/DsOR89DVVia3z9fdCJVcHF2W/1Zxgq0re7kCzmAJlCMMX3tetKpA==} + engines: {node: '>=16.11.0'} + dependencies: + discord-api-types: 0.37.50 + dev: false + + /@discordjs/node-pre-gyp@0.4.5: + resolution: {integrity: sha512-YJOVVZ545x24mHzANfYoy0BJX5PDyeZlpiJjDkUBM/V/Ao7TFX9lcUvCN4nr0tbr5ubeaXxtEBILUrHtTphVeQ==} + hasBin: true + dependencies: + detect-libc: 2.0.2 + https-proxy-agent: 5.0.1 + make-dir: 3.1.0 + node-fetch: 2.7.0 + nopt: 5.0.0 + npmlog: 5.0.1 + rimraf: 3.0.2 + semver: 7.5.4 + tar: 6.2.0 + transitivePeerDependencies: + - encoding + - supports-color + dev: false + + /@discordjs/opus@0.5.3: + resolution: {integrity: sha512-IQhCwCy2WKXLe+qkOkwO1Wjgk20uqeAbqM62tCbzIqbTsXX4YAge8Me9RFnI77Lx+UTkgm4rSVM3VPVdS/GsUw==} + engines: {node: '>=12.0.0'} + deprecated: no longer supported + requiresBuild: true + dependencies: + '@discordjs/node-pre-gyp': 0.4.5 + node-addon-api: 3.2.1 + transitivePeerDependencies: + - encoding + - supports-color + dev: false + + /@discordjs/rest@2.0.1: + resolution: {integrity: sha512-/eWAdDRvwX/rIE2tuQUmKaxmWeHmGealttIzGzlYfI4+a7y9b6ZoMp8BG/jaohs8D8iEnCNYaZiOFLVFLQb8Zg==} + engines: {node: '>=16.11.0'} + dependencies: + '@discordjs/collection': 1.5.3 + '@discordjs/util': 1.0.1 + '@sapphire/async-queue': 1.5.0 + '@sapphire/snowflake': 3.5.1 + '@vladfrangu/async_event_emitter': 2.2.2 + discord-api-types: 0.37.50 + magic-bytes.js: 1.0.17 + tslib: 2.6.2 + undici: 5.22.1 + dev: false + + /@discordjs/util@1.0.1: + resolution: {integrity: sha512-d0N2yCxB8r4bn00/hvFZwM7goDcUhtViC5un4hPj73Ba4yrChLSJD8fy7Ps5jpTLg1fE9n4K0xBLc1y9WGwSsA==} + engines: {node: '>=16.11.0'} + dev: false + + /@discordjs/voice@0.11.0(@discordjs/opus@0.5.3)(ffmpeg-static@4.4.1): + resolution: {integrity: sha512-6+9cj1dxzBJm7WJ9qyG2XZZQ8rcLl6x2caW0C0OxuTtMLAaEDntpb6lqMTFiBg/rDc4Rd59g1w0gJmib33CuHw==} + engines: {node: '>=16.9.0'} + dependencies: + '@types/ws': 8.5.5 + discord-api-types: 0.36.3 + prism-media: 1.3.5(@discordjs/opus@0.5.3)(ffmpeg-static@4.4.1) + tslib: 2.6.2 + ws: 8.14.2 + transitivePeerDependencies: + - '@discordjs/opus' + - bufferutil + - ffmpeg-static + - node-opus + - opusscript + - utf-8-validate + dev: false + + /@discordjs/ws@1.0.1: + resolution: {integrity: sha512-avvAolBqN3yrSvdBPcJ/0j2g42ABzrv3PEL76e3YTp2WYMGH7cuspkjfSyNWaqYl1J+669dlLp+YFMxSVQyS5g==} + engines: {node: '>=16.11.0'} + dependencies: + '@discordjs/collection': 1.5.3 + '@discordjs/rest': 2.0.1 + '@discordjs/util': 1.0.1 + '@sapphire/async-queue': 1.5.0 + '@types/ws': 8.5.5 + '@vladfrangu/async_event_emitter': 2.2.2 + discord-api-types: 0.37.50 + tslib: 2.6.2 + ws: 8.14.2 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + dev: false + + /@eslint-community/eslint-utils@4.4.0(eslint@8.49.0): + resolution: {integrity: sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 + dependencies: + eslint: 8.49.0 + eslint-visitor-keys: 3.4.3 + dev: true + + /@eslint-community/regexpp@4.8.1: + resolution: {integrity: sha512-PWiOzLIUAjN/w5K17PoF4n6sKBw0gqLHPhywmYHP4t1VFQQVYeb1yWsJwnMVEMl3tUHME7X/SJPZLmtG7XBDxQ==} + engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} + dev: true + + /@eslint/eslintrc@2.1.2: + resolution: {integrity: sha512-+wvgpDsrB1YqAMdEUCcnTlpfVBH7Vqn6A/NT3D8WVXFIaKMlErPIZT3oCIAVCOtarRpMtelZLqJeU3t7WY6X6g==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + dependencies: + ajv: 6.12.6 + debug: 4.3.4 + espree: 9.6.1 + globals: 13.21.0 + ignore: 5.2.4 + import-fresh: 3.3.0 + js-yaml: 4.1.0 + minimatch: 3.1.2 + strip-json-comments: 3.1.1 + transitivePeerDependencies: + - supports-color + dev: true + + /@eslint/js@8.49.0: + resolution: {integrity: sha512-1S8uAY/MTJqVx0SC4epBq+N2yhuwtNwLbJYNZyhL2pO1ZVKn5HFXav5T41Ryzy9K9V7ZId2JB2oy/W4aCd9/2w==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + dev: true + + /@gar/promisify@1.1.3: + resolution: {integrity: sha512-k2Ty1JcVojjJFwrg/ThKi2ujJ7XNLYaFGNB/bWT9wGR+oSMJHMa5w+CUq6p/pVrKeNNgA7pCqEcjSnHVoqJQFw==} + requiresBuild: true + dev: false + optional: true + + /@humanwhocodes/config-array@0.11.11: + resolution: {integrity: sha512-N2brEuAadi0CcdeMXUkhbZB84eskAc8MEX1By6qEchoVywSgXPIjou4rYsl0V3Hj0ZnuGycGCjdNgockbzeWNA==} + engines: {node: '>=10.10.0'} + dependencies: + '@humanwhocodes/object-schema': 1.2.1 + debug: 4.3.4 + minimatch: 3.1.2 + transitivePeerDependencies: + - supports-color + dev: true + + /@humanwhocodes/module-importer@1.0.1: + resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==} + engines: {node: '>=12.22'} + dev: true + + /@humanwhocodes/object-schema@1.2.1: + resolution: {integrity: sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==} + dev: true + + /@mapbox/node-pre-gyp@1.0.11: + resolution: {integrity: sha512-Yhlar6v9WQgUp/He7BdgzOz8lqMQ8sU+jkCq7Wx8Myc5YFJLbEe7lgui/V7G1qB1DJykHSGwreceSaD60Y0PUQ==} + hasBin: true + dependencies: + detect-libc: 2.0.2 + https-proxy-agent: 5.0.1 + make-dir: 3.1.0 + node-fetch: 2.7.0 + nopt: 5.0.0 + npmlog: 5.0.1 + rimraf: 3.0.2 + semver: 7.5.4 + tar: 6.2.0 + transitivePeerDependencies: + - encoding + - supports-color + dev: false + + /@nodelib/fs.scandir@2.1.5: + resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} + engines: {node: '>= 8'} + dependencies: + '@nodelib/fs.stat': 2.0.5 + run-parallel: 1.2.0 + dev: true + + /@nodelib/fs.stat@2.0.5: + resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} + engines: {node: '>= 8'} + dev: true + + /@nodelib/fs.walk@1.2.8: + resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} + engines: {node: '>= 8'} + dependencies: + '@nodelib/fs.scandir': 2.1.5 + fastq: 1.15.0 + dev: true + + /@npmcli/fs@1.1.1: + resolution: {integrity: sha512-8KG5RD0GVP4ydEzRn/I4BNDuxDtqVbOdm8675T49OIG/NGhaK0pjPX7ZcDlvKYbA+ulvVK3ztfcF4uBdOxuJbQ==} + requiresBuild: true + dependencies: + '@gar/promisify': 1.1.3 + semver: 7.5.4 + dev: false + optional: true + + /@npmcli/move-file@1.1.2: + resolution: {integrity: sha512-1SUf/Cg2GzGDyaf15aR9St9TWlb+XvbZXWpDx8YKs7MLzMH/BCeopv+y9vzrzgkfykCGuWOlSu3mZhj2+FQcrg==} + engines: {node: '>=10'} + deprecated: This functionality has been moved to @npmcli/fs + requiresBuild: true + dependencies: + mkdirp: 1.0.4 + rimraf: 3.0.2 + dev: false + optional: true + + /@sapphire/async-queue@1.5.0: + resolution: {integrity: sha512-JkLdIsP8fPAdh9ZZjrbHWR/+mZj0wvKS5ICibcLrRI1j84UmLMshx5n9QmL8b95d4onJ2xxiyugTgSAX7AalmA==} + engines: {node: '>=v14.0.0', npm: '>=7.0.0'} + dev: false + + /@sapphire/shapeshift@3.9.2: + resolution: {integrity: sha512-YRbCXWy969oGIdqR/wha62eX8GNHsvyYi0Rfd4rNW6tSVVa8p0ELiMEuOH/k8rgtvRoM+EMV7Csqz77YdwiDpA==} + engines: {node: '>=v14.0.0', npm: '>=7.0.0'} + dependencies: + fast-deep-equal: 3.1.3 + lodash: 4.17.21 + dev: false + + /@sapphire/snowflake@3.5.1: + resolution: {integrity: sha512-BxcYGzgEsdlG0dKAyOm0ehLGm2CafIrfQTZGWgkfKYbj+pNNsorZ7EotuZukc2MT70E0UbppVbtpBrqpzVzjNA==} + engines: {node: '>=v14.0.0', npm: '>=7.0.0'} + dev: false + + /@tootallnate/once@1.1.2: + resolution: {integrity: sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==} + engines: {node: '>= 6'} + requiresBuild: true + dev: false + optional: true + + /@types/debug@4.1.8: + resolution: {integrity: sha512-/vPO1EPOs306Cvhwv7KfVfYvOJqA/S/AXjaHQiJboCZzcNDb+TIJFN9/2C9DZ//ijSKWioNyUxD792QmDJ+HKQ==} + dependencies: + '@types/ms': 0.7.31 + dev: false + + /@types/ms@0.7.31: + resolution: {integrity: sha512-iiUgKzV9AuaEkZqkOLDIvlQiL6ltuZd9tGcW3gwpnX8JbuiuhFlEGmmFXEXkN50Cvq7Os88IY2v0dkDqXYWVgA==} + dev: false + + /@types/node@10.17.60: + resolution: {integrity: sha512-F0KIgDJfy2nA3zMLmWGKxcH2ZVEtCZXHHdOQs2gSaQ27+lNeEfGxzkIw90aXswATX7AZ33tahPbzy6KAfUreVw==} + dev: false + + /@types/node@18.17.17: + resolution: {integrity: sha512-cOxcXsQ2sxiwkykdJqvyFS+MLQPLvIdwh5l6gNg8qF6s+C7XSkEWOZjK+XhUZd+mYvHV/180g2cnCcIl4l06Pw==} + + /@types/validator@13.11.1: + resolution: {integrity: sha512-d/MUkJYdOeKycmm75Arql4M5+UuXmf4cHdHKsyw1GcvnNgL6s77UkgSgJ8TE/rI5PYsnwYq5jkcWBLuN/MpQ1A==} + dev: false + + /@types/ws@8.5.5: + resolution: {integrity: sha512-lwhs8hktwxSjf9UaZ9tG5M03PGogvFaH8gUgLNbN9HKIg0dvv6q+gkSuJ8HN4/VbyxkuLzCjlN7GquQ0gUJfIg==} + dependencies: + '@types/node': 18.17.17 + dev: false + + /@vladfrangu/async_event_emitter@2.2.2: + resolution: {integrity: sha512-HIzRG7sy88UZjBJamssEczH5q7t5+axva19UbZLO6u0ySbYPrwzWiXBcC0WuHyhKKoeCyneH+FvYzKQq/zTtkQ==} + engines: {node: '>=v14.0.0', npm: '>=7.0.0'} + dev: false + + /abbrev@1.1.1: + resolution: {integrity: sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==} + dev: false + + /accepts@1.3.8: + resolution: {integrity: sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==} + engines: {node: '>= 0.6'} + dependencies: + mime-types: 2.1.35 + negotiator: 0.6.3 + dev: false + + /acorn-jsx@5.3.2(acorn@8.10.0): + resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} + peerDependencies: + acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 + dependencies: + acorn: 8.10.0 + dev: true + + /acorn@8.10.0: + resolution: {integrity: sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==} + engines: {node: '>=0.4.0'} + hasBin: true + dev: true + + /agent-base@6.0.2: + resolution: {integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==} + engines: {node: '>= 6.0.0'} + dependencies: + debug: 4.3.4 + transitivePeerDependencies: + - supports-color + dev: false + + /agentkeepalive@4.5.0: + resolution: {integrity: sha512-5GG/5IbQQpC9FpkRGsSvZI5QYeSCzlJHdpBQntCsuTOxhKD8lqKhrleg2Yi7yvMIf82Ycmmqln9U8V9qwEiJew==} + engines: {node: '>= 8.0.0'} + requiresBuild: true + dependencies: + humanize-ms: 1.2.1 + dev: false + optional: true + + /aggregate-error@3.1.0: + resolution: {integrity: sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==} + engines: {node: '>=8'} + requiresBuild: true + dependencies: + clean-stack: 2.2.0 + indent-string: 4.0.0 + dev: false + optional: true + + /ajv@6.12.6: + resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} + dependencies: + fast-deep-equal: 3.1.3 + fast-json-stable-stringify: 2.1.0 + json-schema-traverse: 0.4.1 + uri-js: 4.4.1 + dev: true + + /ansi-regex@5.0.1: + resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} + engines: {node: '>=8'} + + /ansi-styles@4.3.0: + resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} + engines: {node: '>=8'} + dependencies: + color-convert: 2.0.1 + + /aproba@2.0.0: + resolution: {integrity: sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==} + dev: false + + /are-we-there-yet@2.0.0: + resolution: {integrity: sha512-Ci/qENmwHnsYo9xKIcUJN5LeDKdJ6R1Z1j9V/J5wyq8nh/mYPEpIKJbBZXtZjG04HiK7zV/p6Vs9952MrMeUIw==} + engines: {node: '>=10'} + dependencies: + delegates: 1.0.0 + readable-stream: 3.6.2 + dev: false + + /are-we-there-yet@3.0.1: + resolution: {integrity: sha512-QZW4EDmGwlYur0Yyf/b2uGucHQMa8aFUP7eu9ddR73vvhFyt4V0Vl3QHPcTNJ8l6qYOBdxgXdnBXQrHilfRQBg==} + engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + requiresBuild: true + dependencies: + delegates: 1.0.0 + readable-stream: 3.6.2 + dev: false + optional: true + + /argparse@2.0.1: + resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + dev: true + + /array-flatten@1.1.1: + resolution: {integrity: sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==} + dev: false + + /asynckit@0.4.0: + resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} + dev: false + + /b4a@1.6.4: + resolution: {integrity: sha512-fpWrvyVHEKyeEvbKZTVOeZF3VSKKWtJxFIxX/jaVPf+cLbGUSitjb49pHLqPV2BUNNZ0LcoeEGfE/YCpyDYHIw==} + dev: false + + /balanced-match@1.0.2: + resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + + /base64-js@1.5.1: + resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} + dev: false + + /bl@4.1.0: + resolution: {integrity: sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==} + dependencies: + buffer: 5.7.1 + inherits: 2.0.4 + readable-stream: 3.6.2 + dev: false + + /body-parser@1.20.1: + resolution: {integrity: sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==} + engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} + dependencies: + bytes: 3.1.2 + content-type: 1.0.5 + debug: 2.6.9 + depd: 2.0.0 + destroy: 1.2.0 + http-errors: 2.0.0 + iconv-lite: 0.4.24 + on-finished: 2.4.1 + qs: 6.11.0 + raw-body: 2.5.1 + type-is: 1.6.18 + unpipe: 1.0.0 + transitivePeerDependencies: + - supports-color + dev: false + + /brace-expansion@1.1.11: + resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} + dependencies: + balanced-match: 1.0.2 + concat-map: 0.0.1 + + /buffer-from@1.1.2: + resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} + dev: false + + /buffer@5.7.1: + resolution: {integrity: sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==} + dependencies: + base64-js: 1.5.1 + ieee754: 1.2.1 + dev: false + + /busboy@1.6.0: + resolution: {integrity: sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==} + engines: {node: '>=10.16.0'} + dependencies: + streamsearch: 1.1.0 + dev: false + + /bytes@3.1.2: + resolution: {integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==} + engines: {node: '>= 0.8'} + dev: false + + /cacache@15.3.0: + resolution: {integrity: sha512-VVdYzXEn+cnbXpFgWs5hTT7OScegHVmLhJIR8Ufqk3iFD6A6j5iSX1KuBTfNEv4tdJWE2PzA6IVFtcLC7fN9wQ==} + engines: {node: '>= 10'} + requiresBuild: true + dependencies: + '@npmcli/fs': 1.1.1 + '@npmcli/move-file': 1.1.2 + chownr: 2.0.0 + fs-minipass: 2.1.0 + glob: 7.2.3 + infer-owner: 1.0.4 + lru-cache: 6.0.0 + minipass: 3.3.6 + minipass-collect: 1.0.2 + minipass-flush: 1.0.5 + minipass-pipeline: 1.2.4 + mkdirp: 1.0.4 + p-map: 4.0.0 + promise-inflight: 1.0.1 + rimraf: 3.0.2 + ssri: 8.0.1 + tar: 6.2.0 + unique-filename: 1.1.1 + transitivePeerDependencies: + - bluebird + dev: false + optional: true + + /call-bind@1.0.2: + resolution: {integrity: sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==} + dependencies: + function-bind: 1.1.1 + get-intrinsic: 1.2.1 + dev: false + + /callsites@3.1.0: + resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} + engines: {node: '>=6'} + dev: true + + /caseless@0.12.0: + resolution: {integrity: sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==} + dev: false + + /chalk@4.1.2: + resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} + engines: {node: '>=10'} + dependencies: + ansi-styles: 4.3.0 + supports-color: 7.2.0 + + /chownr@1.1.4: + resolution: {integrity: sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==} + dev: false + + /chownr@2.0.0: + resolution: {integrity: sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==} + engines: {node: '>=10'} + dev: false + + /clean-stack@2.2.0: + resolution: {integrity: sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==} + engines: {node: '>=6'} + requiresBuild: true + dev: false + optional: true + + /color-convert@2.0.1: + resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} + engines: {node: '>=7.0.0'} + dependencies: + color-name: 1.1.4 + + /color-name@1.1.4: + resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + + /color-string@1.9.1: + resolution: {integrity: sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==} + dependencies: + color-name: 1.1.4 + simple-swizzle: 0.2.2 + dev: false + + /color-support@1.1.3: + resolution: {integrity: sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==} + hasBin: true + dev: false + + /color@4.2.3: + resolution: {integrity: sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==} + engines: {node: '>=12.5.0'} + dependencies: + color-convert: 2.0.1 + color-string: 1.9.1 + dev: false + + /combined-stream@1.0.8: + resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} + engines: {node: '>= 0.8'} + dependencies: + delayed-stream: 1.0.0 + dev: false + + /concat-map@0.0.1: + resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} + + /concat-stream@2.0.0: + resolution: {integrity: sha512-MWufYdFw53ccGjCA+Ol7XJYpAlW6/prSMzuPOTRnJGcGzuhLn4Scrz7qf6o8bROZ514ltazcIFJZevcfbo0x7A==} + engines: {'0': node >= 6.0} + dependencies: + buffer-from: 1.1.2 + inherits: 2.0.4 + readable-stream: 3.6.2 + typedarray: 0.0.6 + dev: false + + /console-control-strings@1.1.0: + resolution: {integrity: sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==} + dev: false + + /content-disposition@0.5.4: + resolution: {integrity: sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==} + engines: {node: '>= 0.6'} + dependencies: + safe-buffer: 5.2.1 + dev: false + + /content-type@1.0.5: + resolution: {integrity: sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==} + engines: {node: '>= 0.6'} + dev: false + + /cookie-signature@1.0.6: + resolution: {integrity: sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==} + dev: false + + /cookie@0.5.0: + resolution: {integrity: sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==} + engines: {node: '>= 0.6'} + dev: false + + /cross-spawn@7.0.3: + resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==} + engines: {node: '>= 8'} + dependencies: + path-key: 3.1.1 + shebang-command: 2.0.0 + which: 2.0.2 + dev: true + + /debug@2.6.9: + resolution: {integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + dependencies: + ms: 2.0.0 + dev: false + + /debug@4.3.4: + resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + dependencies: + ms: 2.1.2 + + /decompress-response@6.0.0: + resolution: {integrity: sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==} + engines: {node: '>=10'} + dependencies: + mimic-response: 3.1.0 + dev: false + + /deep-extend@0.6.0: + resolution: {integrity: sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==} + engines: {node: '>=4.0.0'} + dev: false + + /deep-is@0.1.4: + resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} + dev: true + + /delayed-stream@1.0.0: + resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} + engines: {node: '>=0.4.0'} + dev: false + + /delegates@1.0.0: + resolution: {integrity: sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==} + dev: false + + /depd@2.0.0: + resolution: {integrity: sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==} + engines: {node: '>= 0.8'} + dev: false + + /destroy@1.2.0: + resolution: {integrity: sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==} + engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} + dev: false + + /detect-libc@2.0.2: + resolution: {integrity: sha512-UX6sGumvvqSaXgdKGUsgZWqcUyIXZ/vZTrlRT/iobiKhGL0zL4d3osHj3uqllWJK+i+sixDS/3COVEOFbupFyw==} + engines: {node: '>=8'} + dev: false + + /discord-api-types@0.36.3: + resolution: {integrity: sha512-bz/NDyG0KBo/tY14vSkrwQ/n3HKPf87a0WFW/1M9+tXYK+vp5Z5EksawfCWo2zkAc6o7CClc0eff1Pjrqznlwg==} + dev: false + + /discord-api-types@0.37.50: + resolution: {integrity: sha512-X4CDiMnDbA3s3RaUXWXmgAIbY1uxab3fqe3qwzg5XutR3wjqi7M3IkgQbsIBzpqBN2YWr/Qdv7JrFRqSgb4TFg==} + dev: false + + /discord-embedbuilder@4.0.0: + resolution: {integrity: sha512-ZOiEEFUO7AJglSdAvVB6A61A14wx87vf63d7K/jBzR/bJAUdYS5RwqZZ7JW9UHkH/insSSczQTzE68Ej2HmCrQ==} + dependencies: + discord.js: 14.13.0 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + dev: false + + /discord-together@1.3.31: + resolution: {integrity: sha512-BOHLmSkMw376qTvmDdKfgPQ83CYV9UR1YNRPVX9Cq57fu0PDCl9eGx/NfilThzJx7DdojRiliVyp17PlfKlR3w==} + dependencies: + discord.js: 14.13.0 + node-fetch: 2.7.0 + transitivePeerDependencies: + - bufferutil + - encoding + - utf-8-validate + dev: false + + /discord.js@14.13.0: + resolution: {integrity: sha512-Kufdvg7fpyTEwANGy9x7i4od4yu5c6gVddGi5CKm4Y5a6sF0VBODObI3o0Bh7TGCj0LfNT8Qp8z04wnLFzgnbA==} + engines: {node: '>=16.11.0'} + dependencies: + '@discordjs/builders': 1.6.5 + '@discordjs/collection': 1.5.3 + '@discordjs/formatters': 0.3.2 + '@discordjs/rest': 2.0.1 + '@discordjs/util': 1.0.1 + '@discordjs/ws': 1.0.1 + '@sapphire/snowflake': 3.5.1 + '@types/ws': 8.5.5 + discord-api-types: 0.37.50 + fast-deep-equal: 3.1.3 + lodash.snakecase: 4.1.1 + tslib: 2.6.2 + undici: 5.22.1 + ws: 8.14.2 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + dev: false + + /doctrine@3.0.0: + resolution: {integrity: sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==} + engines: {node: '>=6.0.0'} + dependencies: + esutils: 2.0.3 + dev: true + + /dotenv@9.0.2: + resolution: {integrity: sha512-I9OvvrHp4pIARv4+x9iuewrWycX6CcZtoAu1XrzPxc5UygMJXJZYmBsynku8IkrJwgypE5DGNjDPmPRhDCptUg==} + engines: {node: '>=10'} + dev: false + + /dottie@2.0.6: + resolution: {integrity: sha512-iGCHkfUc5kFekGiqhe8B/mdaurD+lakO9txNnTvKtA6PISrw86LgqHvRzWYPyoE2Ph5aMIrCw9/uko6XHTKCwA==} + dev: false + + /ee-first@1.1.1: + resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==} + dev: false + + /emoji-regex@8.0.0: + resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} + dev: false + + /encodeurl@1.0.2: + resolution: {integrity: sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==} + engines: {node: '>= 0.8'} + dev: false + + /encoding@0.1.13: + resolution: {integrity: sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==} + requiresBuild: true + dependencies: + iconv-lite: 0.6.3 + dev: false + optional: true + + /end-of-stream@1.4.4: + resolution: {integrity: sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==} + dependencies: + once: 1.4.0 + dev: false + + /env-paths@2.2.1: + resolution: {integrity: sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==} + engines: {node: '>=6'} + dev: false + + /err-code@2.0.3: + resolution: {integrity: sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==} + requiresBuild: true + dev: false + optional: true + + /escape-html@1.0.3: + resolution: {integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==} + dev: false + + /escape-string-regexp@4.0.0: + resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} + engines: {node: '>=10'} + dev: true + + /eslint-scope@7.2.2: + resolution: {integrity: sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + dependencies: + esrecurse: 4.3.0 + estraverse: 5.3.0 + dev: true + + /eslint-visitor-keys@3.4.3: + resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + dev: true + + /eslint@8.49.0: + resolution: {integrity: sha512-jw03ENfm6VJI0jA9U+8H5zfl5b+FvuU3YYvZRdZHOlU2ggJkxrlkJH4HcDrZpj6YwD8kuYqvQM8LyesoazrSOQ==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + hasBin: true + dependencies: + '@eslint-community/eslint-utils': 4.4.0(eslint@8.49.0) + '@eslint-community/regexpp': 4.8.1 + '@eslint/eslintrc': 2.1.2 + '@eslint/js': 8.49.0 + '@humanwhocodes/config-array': 0.11.11 + '@humanwhocodes/module-importer': 1.0.1 + '@nodelib/fs.walk': 1.2.8 + ajv: 6.12.6 + chalk: 4.1.2 + cross-spawn: 7.0.3 + debug: 4.3.4 + doctrine: 3.0.0 + escape-string-regexp: 4.0.0 + eslint-scope: 7.2.2 + eslint-visitor-keys: 3.4.3 + espree: 9.6.1 + esquery: 1.5.0 + esutils: 2.0.3 + fast-deep-equal: 3.1.3 + file-entry-cache: 6.0.1 + find-up: 5.0.0 + glob-parent: 6.0.2 + globals: 13.21.0 + graphemer: 1.4.0 + ignore: 5.2.4 + imurmurhash: 0.1.4 + is-glob: 4.0.3 + is-path-inside: 3.0.3 + js-yaml: 4.1.0 + json-stable-stringify-without-jsonify: 1.0.1 + levn: 0.4.1 + lodash.merge: 4.6.2 + minimatch: 3.1.2 + natural-compare: 1.4.0 + optionator: 0.9.3 + strip-ansi: 6.0.1 + text-table: 0.2.0 + transitivePeerDependencies: + - supports-color + dev: true + + /espree@9.6.1: + resolution: {integrity: sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + dependencies: + acorn: 8.10.0 + acorn-jsx: 5.3.2(acorn@8.10.0) + eslint-visitor-keys: 3.4.3 + dev: true + + /esquery@1.5.0: + resolution: {integrity: sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==} + engines: {node: '>=0.10'} + dependencies: + estraverse: 5.3.0 + dev: true + + /esrecurse@4.3.0: + resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} + engines: {node: '>=4.0'} + dependencies: + estraverse: 5.3.0 + dev: true + + /estraverse@5.3.0: + resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} + engines: {node: '>=4.0'} + dev: true + + /esutils@2.0.3: + resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} + engines: {node: '>=0.10.0'} + dev: true + + /etag@1.8.1: + resolution: {integrity: sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==} + engines: {node: '>= 0.6'} + dev: false + + /expand-template@2.0.3: + resolution: {integrity: sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==} + engines: {node: '>=6'} + dev: false + + /express@4.18.2: + resolution: {integrity: sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==} + engines: {node: '>= 0.10.0'} + dependencies: + accepts: 1.3.8 + array-flatten: 1.1.1 + body-parser: 1.20.1 + content-disposition: 0.5.4 + content-type: 1.0.5 + cookie: 0.5.0 + cookie-signature: 1.0.6 + debug: 2.6.9 + depd: 2.0.0 + encodeurl: 1.0.2 + escape-html: 1.0.3 + etag: 1.8.1 + finalhandler: 1.2.0 + fresh: 0.5.2 + http-errors: 2.0.0 + merge-descriptors: 1.0.1 + methods: 1.1.2 + on-finished: 2.4.1 + parseurl: 1.3.3 + path-to-regexp: 0.1.7 + proxy-addr: 2.0.7 + qs: 6.11.0 + range-parser: 1.2.1 + safe-buffer: 5.2.1 + send: 0.18.0 + serve-static: 1.15.0 + setprototypeof: 1.2.0 + statuses: 2.0.1 + type-is: 1.6.18 + utils-merge: 1.0.1 + vary: 1.1.2 + transitivePeerDependencies: + - supports-color + dev: false + + /fast-deep-equal@3.1.3: + resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} + + /fast-fifo@1.3.2: + resolution: {integrity: sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==} + dev: false + + /fast-json-stable-stringify@2.1.0: + resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} + dev: true + + /fast-levenshtein@2.0.6: + resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} + dev: true + + /fastq@1.15.0: + resolution: {integrity: sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==} + dependencies: + reusify: 1.0.4 + dev: true + + /ffmpeg-static@4.4.1: + resolution: {integrity: sha512-gyGTIf5kgmLDmH7Rwj8vMmNK46bjXKKofHS2gY+LUqoTe/iybVuTuvnhJQR2tZHlKlDG7A/BIH7cRa2jWDKgWw==} + engines: {node: '>=10'} + requiresBuild: true + dependencies: + '@derhuerst/http-basic': 8.2.4 + env-paths: 2.2.1 + https-proxy-agent: 5.0.1 + progress: 2.0.3 + transitivePeerDependencies: + - supports-color + dev: false + + /file-entry-cache@6.0.1: + resolution: {integrity: sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==} + engines: {node: ^10.12.0 || >=12.0.0} + dependencies: + flat-cache: 3.1.0 + dev: true + + /finalhandler@1.2.0: + resolution: {integrity: sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==} + engines: {node: '>= 0.8'} + dependencies: + debug: 2.6.9 + encodeurl: 1.0.2 + escape-html: 1.0.3 + on-finished: 2.4.1 + parseurl: 1.3.3 + statuses: 2.0.1 + unpipe: 1.0.0 + transitivePeerDependencies: + - supports-color + dev: false + + /find-up@5.0.0: + resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} + engines: {node: '>=10'} + dependencies: + locate-path: 6.0.0 + path-exists: 4.0.0 + dev: true + + /flat-cache@3.1.0: + resolution: {integrity: sha512-OHx4Qwrrt0E4jEIcI5/Xb+f+QmJYNj2rrK8wiIdQOIrB9WrrJL8cjZvXdXuBTkkEwEqLycb5BeZDV1o2i9bTew==} + engines: {node: '>=12.0.0'} + dependencies: + flatted: 3.2.9 + keyv: 4.5.3 + rimraf: 3.0.2 + dev: true + + /flatted@3.2.9: + resolution: {integrity: sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ==} + dev: true + + /form-data@4.0.0: + resolution: {integrity: sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==} + engines: {node: '>= 6'} + dependencies: + asynckit: 0.4.0 + combined-stream: 1.0.8 + mime-types: 2.1.35 + dev: false + + /forwarded@0.2.0: + resolution: {integrity: sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==} + engines: {node: '>= 0.6'} + dev: false + + /fresh@0.5.2: + resolution: {integrity: sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==} + engines: {node: '>= 0.6'} + dev: false + + /fs-constants@1.0.0: + resolution: {integrity: sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==} + dev: false + + /fs-minipass@2.1.0: + resolution: {integrity: sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==} + engines: {node: '>= 8'} + dependencies: + minipass: 3.3.6 + dev: false + + /fs.realpath@1.0.0: + resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} + requiresBuild: true + + /function-bind@1.1.1: + resolution: {integrity: sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==} + dev: false + + /gauge@3.0.2: + resolution: {integrity: sha512-+5J6MS/5XksCuXq++uFRsnUd7Ovu1XenbeuIuNRJxYWjgQbPuFhT14lAvsWfqfAmnwluf1OwMjz39HjfLPci0Q==} + engines: {node: '>=10'} + dependencies: + aproba: 2.0.0 + color-support: 1.1.3 + console-control-strings: 1.1.0 + has-unicode: 2.0.1 + object-assign: 4.1.1 + signal-exit: 3.0.7 + string-width: 4.2.3 + strip-ansi: 6.0.1 + wide-align: 1.1.5 + dev: false + + /gauge@4.0.4: + resolution: {integrity: sha512-f9m+BEN5jkg6a0fZjleidjN51VE1X+mPFQ2DJ0uv1V39oCLCbsGe6yjbBnp7eK7z/+GAon99a3nHuqbuuthyPg==} + engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + requiresBuild: true + dependencies: + aproba: 2.0.0 + color-support: 1.1.3 + console-control-strings: 1.1.0 + has-unicode: 2.0.1 + signal-exit: 3.0.7 + string-width: 4.2.3 + strip-ansi: 6.0.1 + wide-align: 1.1.5 + dev: false + optional: true + + /get-intrinsic@1.2.1: + resolution: {integrity: sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw==} + dependencies: + function-bind: 1.1.1 + has: 1.0.3 + has-proto: 1.0.1 + has-symbols: 1.0.3 + dev: false + + /git-last-commit@1.0.1: + resolution: {integrity: sha512-FDSgeMqa7GnJDxt/q0AbrxbfeTyxp4ImxEw1e4nw6NUHA5FMhFUq33dTXI4Xdgcj1VQ1q5QLWF6WxFrJ8KCBOg==} + dev: false + + /github-from-package@0.0.0: + resolution: {integrity: sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==} + dev: false + + /glob-parent@6.0.2: + resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} + engines: {node: '>=10.13.0'} + dependencies: + is-glob: 4.0.3 + dev: true + + /glob@7.2.3: + resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} + dependencies: + fs.realpath: 1.0.0 + inflight: 1.0.6 + inherits: 2.0.4 + minimatch: 3.1.2 + once: 1.4.0 + path-is-absolute: 1.0.1 + + /globals@13.21.0: + resolution: {integrity: sha512-ybyme3s4yy/t/3s35bewwXKOf7cvzfreG2lH0lZl0JB7I4GxRP2ghxOK/Nb9EkRXdbBXZLfq/p/0W2JUONB/Gg==} + engines: {node: '>=8'} + dependencies: + type-fest: 0.20.2 + dev: true + + /graceful-fs@4.2.11: + resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} + requiresBuild: true + dev: false + optional: true + + /graphemer@1.4.0: + resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==} + dev: true + + /has-flag@4.0.0: + resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} + engines: {node: '>=8'} + + /has-proto@1.0.1: + resolution: {integrity: sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==} + engines: {node: '>= 0.4'} + dev: false + + /has-symbols@1.0.3: + resolution: {integrity: sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==} + engines: {node: '>= 0.4'} + dev: false + + /has-unicode@2.0.1: + resolution: {integrity: sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==} + dev: false + + /has@1.0.3: + resolution: {integrity: sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==} + engines: {node: '>= 0.4.0'} + dependencies: + function-bind: 1.1.1 + dev: false + + /http-cache-semantics@4.1.1: + resolution: {integrity: sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==} + requiresBuild: true + dev: false + optional: true + + /http-errors@2.0.0: + resolution: {integrity: sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==} + engines: {node: '>= 0.8'} + dependencies: + depd: 2.0.0 + inherits: 2.0.4 + setprototypeof: 1.2.0 + statuses: 2.0.1 + toidentifier: 1.0.1 + dev: false + + /http-proxy-agent@4.0.1: + resolution: {integrity: sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==} + engines: {node: '>= 6'} + requiresBuild: true + dependencies: + '@tootallnate/once': 1.1.2 + agent-base: 6.0.2 + debug: 4.3.4 + transitivePeerDependencies: + - supports-color + dev: false + optional: true + + /http-response-object@3.0.2: + resolution: {integrity: sha512-bqX0XTF6fnXSQcEJ2Iuyr75yVakyjIDCqroJQ/aHfSdlM743Cwqoi2nDYMzLGWUcuTWGWy8AAvOKXTfiv6q9RA==} + dependencies: + '@types/node': 10.17.60 + dev: false + + /https-proxy-agent@5.0.1: + resolution: {integrity: sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==} + engines: {node: '>= 6'} + dependencies: + agent-base: 6.0.2 + debug: 4.3.4 + transitivePeerDependencies: + - supports-color + dev: false + + /humanize-ms@1.2.1: + resolution: {integrity: sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==} + requiresBuild: true + dependencies: + ms: 2.1.3 + dev: false + optional: true + + /iconv-lite@0.4.24: + resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==} + engines: {node: '>=0.10.0'} + dependencies: + safer-buffer: 2.1.2 + dev: false + + /iconv-lite@0.6.3: + resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==} + engines: {node: '>=0.10.0'} + requiresBuild: true + dependencies: + safer-buffer: 2.1.2 + dev: false + optional: true + + /ieee754@1.2.1: + resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} + dev: false + + /ignore@5.2.4: + resolution: {integrity: sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==} + engines: {node: '>= 4'} + dev: true + + /import-fresh@3.3.0: + resolution: {integrity: sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==} + engines: {node: '>=6'} + dependencies: + parent-module: 1.0.1 + resolve-from: 4.0.0 + dev: true + + /imurmurhash@0.1.4: + resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} + engines: {node: '>=0.8.19'} + + /indent-string@4.0.0: + resolution: {integrity: sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==} + engines: {node: '>=8'} + requiresBuild: true + dev: false + optional: true + + /infer-owner@1.0.4: + resolution: {integrity: sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==} + requiresBuild: true + dev: false + optional: true + + /inflection@1.13.4: + resolution: {integrity: sha512-6I/HUDeYFfuNCVS3td055BaXBwKYuzw7K3ExVMStBowKo9oOAMJIXIHvdyR3iboTCp1b+1i5DSkIZTcwIktuDw==} + engines: {'0': node >= 0.4.0} + dev: false + + /inflight@1.0.6: + resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} + requiresBuild: true + dependencies: + once: 1.4.0 + wrappy: 1.0.2 + + /inherits@2.0.4: + resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} + + /ini@1.3.8: + resolution: {integrity: sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==} + dev: false + + /ip@2.0.0: + resolution: {integrity: sha512-WKa+XuLG1A1R0UWhl2+1XQSi+fZWMsYKffMZTTYsiZaUD8k2yDAj5atimTUD2TZkyCkNEeYE5NhFZmupOGtjYQ==} + requiresBuild: true + dev: false + optional: true + + /ipaddr.js@1.9.1: + resolution: {integrity: sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==} + engines: {node: '>= 0.10'} + dev: false + + /is-arrayish@0.3.2: + resolution: {integrity: sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==} + dev: false + + /is-extglob@2.1.1: + resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} + engines: {node: '>=0.10.0'} + dev: true + + /is-fullwidth-code-point@3.0.0: + resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} + engines: {node: '>=8'} + dev: false + + /is-glob@4.0.3: + resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} + engines: {node: '>=0.10.0'} + dependencies: + is-extglob: 2.1.1 + dev: true + + /is-lambda@1.0.1: + resolution: {integrity: sha512-z7CMFGNrENq5iFB9Bqo64Xk6Y9sg+epq1myIcdHaGnbMTYOxvzsEtdYqQUylB7LxfkvgrrjP32T6Ywciio9UIQ==} + requiresBuild: true + dev: false + optional: true + + /is-path-inside@3.0.3: + resolution: {integrity: sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==} + engines: {node: '>=8'} + dev: true + + /isexe@2.0.0: + resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + + /js-yaml@4.1.0: + resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} + hasBin: true + dependencies: + argparse: 2.0.1 + dev: true + + /json-buffer@3.0.1: + resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} + dev: true + + /json-schema-traverse@0.4.1: + resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} + dev: true + + /json-stable-stringify-without-jsonify@1.0.1: + resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} + dev: true + + /keyv@4.5.3: + resolution: {integrity: sha512-QCiSav9WaX1PgETJ+SpNnx2PRRapJ/oRSXM4VO5OGYGSjrxbKPVFVhB3l2OCbLCk329N8qyAtsJjSjvVBWzEug==} + dependencies: + json-buffer: 3.0.1 + dev: true + + /levn@0.4.1: + resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} + engines: {node: '>= 0.8.0'} + dependencies: + prelude-ls: 1.2.1 + type-check: 0.4.0 + dev: true + + /locate-path@6.0.0: + resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} + engines: {node: '>=10'} + dependencies: + p-locate: 5.0.0 + dev: true + + /lodash.merge@4.6.2: + resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} + dev: true + + /lodash.snakecase@4.1.1: + resolution: {integrity: sha512-QZ1d4xoBHYUeuouhEq3lk3Uq7ldgyFXGBhg04+oRLnIz8o9T65Eh+8YdroUwn846zchkA9yDsDl5CVVaV2nqYw==} + dev: false + + /lodash@4.17.21: + resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} + dev: false + + /lru-cache@6.0.0: + resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==} + engines: {node: '>=10'} + dependencies: + yallist: 4.0.0 + dev: false + + /magic-bytes.js@1.0.17: + resolution: {integrity: sha512-PEDpPzHpKe5AxkVmQrNPHFRvPN2ELkkj3eIg4IZO9JdhBiAY3aU53lgYXs9j8B7lpza+QiW0UA4QHCH7EskSeg==} + dev: false + + /make-dir@3.1.0: + resolution: {integrity: sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==} + engines: {node: '>=8'} + dependencies: + semver: 6.3.1 + dev: false + + /make-fetch-happen@9.1.0: + resolution: {integrity: sha512-+zopwDy7DNknmwPQplem5lAZX/eCOzSvSNNcSKm5eVwTkOBzoktEfXsa9L23J/GIRhxRsaxzkPEhrJEpE2F4Gg==} + engines: {node: '>= 10'} + requiresBuild: true + dependencies: + agentkeepalive: 4.5.0 + cacache: 15.3.0 + http-cache-semantics: 4.1.1 + http-proxy-agent: 4.0.1 + https-proxy-agent: 5.0.1 + is-lambda: 1.0.1 + lru-cache: 6.0.0 + minipass: 3.3.6 + minipass-collect: 1.0.2 + minipass-fetch: 1.4.1 + minipass-flush: 1.0.5 + minipass-pipeline: 1.2.4 + negotiator: 0.6.3 + promise-retry: 2.0.1 + socks-proxy-agent: 6.2.1 + ssri: 8.0.1 + transitivePeerDependencies: + - bluebird + - supports-color + dev: false + optional: true + + /media-typer@0.3.0: + resolution: {integrity: sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==} + engines: {node: '>= 0.6'} + dev: false + + /merge-descriptors@1.0.1: + resolution: {integrity: sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==} + dev: false + + /methods@1.1.2: + resolution: {integrity: sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==} + engines: {node: '>= 0.6'} + dev: false + + /mime-db@1.52.0: + resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} + engines: {node: '>= 0.6'} + dev: false + + /mime-types@2.1.35: + resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} + engines: {node: '>= 0.6'} + dependencies: + mime-db: 1.52.0 + dev: false + + /mime@1.6.0: + resolution: {integrity: sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==} + engines: {node: '>=4'} + hasBin: true + dev: false + + /mimic-response@3.1.0: + resolution: {integrity: sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==} + engines: {node: '>=10'} + dev: false + + /minimatch@3.1.2: + resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} + dependencies: + brace-expansion: 1.1.11 + + /minimist@1.2.8: + resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} + dev: false + + /minipass-collect@1.0.2: + resolution: {integrity: sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA==} + engines: {node: '>= 8'} + requiresBuild: true + dependencies: + minipass: 3.3.6 + dev: false + optional: true + + /minipass-fetch@1.4.1: + resolution: {integrity: sha512-CGH1eblLq26Y15+Azk7ey4xh0J/XfJfrCox5LDJiKqI2Q2iwOLOKrlmIaODiSQS8d18jalF6y2K2ePUm0CmShw==} + engines: {node: '>=8'} + requiresBuild: true + dependencies: + minipass: 3.3.6 + minipass-sized: 1.0.3 + minizlib: 2.1.2 + optionalDependencies: + encoding: 0.1.13 + dev: false + optional: true + + /minipass-flush@1.0.5: + resolution: {integrity: sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw==} + engines: {node: '>= 8'} + requiresBuild: true + dependencies: + minipass: 3.3.6 + dev: false + optional: true + + /minipass-pipeline@1.2.4: + resolution: {integrity: sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A==} + engines: {node: '>=8'} + requiresBuild: true + dependencies: + minipass: 3.3.6 + dev: false + optional: true + + /minipass-sized@1.0.3: + resolution: {integrity: sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g==} + engines: {node: '>=8'} + requiresBuild: true + dependencies: + minipass: 3.3.6 + dev: false + optional: true + + /minipass@3.3.6: + resolution: {integrity: sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==} + engines: {node: '>=8'} + dependencies: + yallist: 4.0.0 + dev: false + + /minipass@5.0.0: + resolution: {integrity: sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==} + engines: {node: '>=8'} + dev: false + + /minizlib@2.1.2: + resolution: {integrity: sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==} + engines: {node: '>= 8'} + dependencies: + minipass: 3.3.6 + yallist: 4.0.0 + dev: false + + /mkdirp-classic@0.5.3: + resolution: {integrity: sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==} + dev: false + + /mkdirp@1.0.4: + resolution: {integrity: sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==} + engines: {node: '>=10'} + hasBin: true + dev: false + + /moment-timezone@0.5.43: + resolution: {integrity: sha512-72j3aNyuIsDxdF1i7CEgV2FfxM1r6aaqJyLB2vwb33mXYyoyLly+F1zbWqhA3/bVIoJ4szlUoMbUnVdid32NUQ==} + dependencies: + moment: 2.29.4 + dev: false + + /moment@2.29.4: + resolution: {integrity: sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w==} + dev: false + + /ms@2.0.0: + resolution: {integrity: sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==} + dev: false + + /ms@2.1.2: + resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} + + /ms@2.1.3: + resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + dev: false + + /napi-build-utils@1.0.2: + resolution: {integrity: sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg==} + dev: false + + /natural-compare@1.4.0: + resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} + dev: true + + /negotiator@0.6.3: + resolution: {integrity: sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==} + engines: {node: '>= 0.6'} + dev: false + + /node-abi@3.47.0: + resolution: {integrity: sha512-2s6B2CWZM//kPgwnuI0KrYwNjfdByE25zvAaEpq9IH4zcNsarH8Ihu/UuX6XMPEogDAxkuUFeZn60pXNHAqn3A==} + engines: {node: '>=10'} + dependencies: + semver: 7.5.4 + dev: false + + /node-addon-api@3.2.1: + resolution: {integrity: sha512-mmcei9JghVNDYydghQmeDX8KoAm0FAiYyIcUt/N4nhyAipB17pllZQDOJD2fotxABnt4Mdz+dKTO7eftLg4d0A==} + dev: false + + /node-addon-api@4.3.0: + resolution: {integrity: sha512-73sE9+3UaLYYFmDsFZnqCInzPyh3MqIwZO9cw58yIqAZhONrrabrYyYe3TuIqtIiOuTXVhsGau8hcrhhwSsDIQ==} + dev: false + + /node-addon-api@6.1.0: + resolution: {integrity: sha512-+eawOlIgy680F0kBzPUNFhMZGtJ1YmqM6l4+Crf4IkImjYrO/mqPwRMh352g23uIaQKFItcQ64I7KMaJxHgAVA==} + dev: false + + /node-fetch@2.7.0: + resolution: {integrity: sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==} + engines: {node: 4.x || >=6.0.0} + peerDependencies: + encoding: ^0.1.0 + peerDependenciesMeta: + encoding: + optional: true + dependencies: + whatwg-url: 5.0.0 + dev: false + + /node-gyp@8.4.1: + resolution: {integrity: sha512-olTJRgUtAb/hOXG0E93wZDs5YiJlgbXxTwQAFHyNlRsXQnYzUaF2aGgujZbw+hR8aF4ZG/rST57bWMWD16jr9w==} + engines: {node: '>= 10.12.0'} + hasBin: true + requiresBuild: true + dependencies: + env-paths: 2.2.1 + glob: 7.2.3 + graceful-fs: 4.2.11 + make-fetch-happen: 9.1.0 + nopt: 5.0.0 + npmlog: 6.0.2 + rimraf: 3.0.2 + semver: 7.5.4 + tar: 6.2.0 + which: 2.0.2 + transitivePeerDependencies: + - bluebird + - supports-color + dev: false + optional: true + + /node-superfetch@0.2.3: + resolution: {integrity: sha512-xOqifvw/3N+tIeeC80/TNJXkoxDZm8JWc7/0VBkJ86ttQTlJvoicuVaeJlKKHYRlmC2O6ygNIhNPwLYX4bxqdA==} + engines: {node: '>=8'} + dependencies: + form-data: 4.0.0 + node-fetch: 2.7.0 + transitivePeerDependencies: + - encoding + dev: false + + /nopt@5.0.0: + resolution: {integrity: sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==} + engines: {node: '>=6'} + hasBin: true + dependencies: + abbrev: 1.1.1 + dev: false + + /npmlog@5.0.1: + resolution: {integrity: sha512-AqZtDUWOMKs1G/8lwylVjrdYgqA4d9nu8hc+0gzRxlDb1I10+FHBGMXs6aiQHFdCUUlqH99MUMuLfzWDNDtfxw==} + dependencies: + are-we-there-yet: 2.0.0 + console-control-strings: 1.1.0 + gauge: 3.0.2 + set-blocking: 2.0.0 + dev: false + + /npmlog@6.0.2: + resolution: {integrity: sha512-/vBvz5Jfr9dT/aFWd0FIRf+T/Q2WBsLENygUaFUqstqsycmZAP/t5BvFJTK0viFmSUxiUKTUplWy5vt+rvKIxg==} + engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + requiresBuild: true + dependencies: + are-we-there-yet: 3.0.1 + console-control-strings: 1.1.0 + gauge: 4.0.4 + set-blocking: 2.0.0 + dev: false + optional: true + + /object-assign@4.1.1: + resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} + engines: {node: '>=0.10.0'} + dev: false + + /object-inspect@1.12.3: + resolution: {integrity: sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==} + dev: false + + /on-finished@2.4.1: + resolution: {integrity: sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==} + engines: {node: '>= 0.8'} + dependencies: + ee-first: 1.1.1 + dev: false + + /once@1.4.0: + resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} + dependencies: + wrappy: 1.0.2 + + /optionator@0.9.3: + resolution: {integrity: sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==} + engines: {node: '>= 0.8.0'} + dependencies: + '@aashutoshrathi/word-wrap': 1.2.6 + deep-is: 0.1.4 + fast-levenshtein: 2.0.6 + levn: 0.4.1 + prelude-ls: 1.2.1 + type-check: 0.4.0 + dev: true + + /os-utils@0.0.14: + resolution: {integrity: sha512-ajB8csaHLBvJOYsHJkp8YdO2FvlBbf/ZxaYQwXXRDyQ84UoE+uTuLXxqd0shekXMX6Qr/pt/DDyLMRAMsgfWzg==} + dev: false + + /p-limit@3.1.0: + resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} + engines: {node: '>=10'} + dependencies: + yocto-queue: 0.1.0 + dev: true + + /p-locate@5.0.0: + resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} + engines: {node: '>=10'} + dependencies: + p-limit: 3.1.0 + dev: true + + /p-map@4.0.0: + resolution: {integrity: sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==} + engines: {node: '>=10'} + requiresBuild: true + dependencies: + aggregate-error: 3.1.0 + dev: false + optional: true + + /parent-module@1.0.1: + resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} + engines: {node: '>=6'} + dependencies: + callsites: 3.1.0 + dev: true + + /parse-cache-control@1.0.1: + resolution: {integrity: sha512-60zvsJReQPX5/QP0Kzfd/VrpjScIQ7SHBW6bFCYfEP+fp0Eppr1SHhIO5nd1PjZtvclzSzES9D/p5nFJurwfWg==} + dev: false + + /parseurl@1.3.3: + resolution: {integrity: sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==} + engines: {node: '>= 0.8'} + dev: false + + /path-exists@4.0.0: + resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} + engines: {node: '>=8'} + dev: true + + /path-is-absolute@1.0.1: + resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} + engines: {node: '>=0.10.0'} + requiresBuild: true + + /path-key@3.1.1: + resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} + engines: {node: '>=8'} + dev: true + + /path-to-regexp@0.1.7: + resolution: {integrity: sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==} + dev: false + + /pg-connection-string@2.6.2: + resolution: {integrity: sha512-ch6OwaeaPYcova4kKZ15sbJ2hKb/VP48ZD2gE7i1J+L4MspCtBMAx8nMgz7bksc7IojCIIWuEhHibSMFH8m8oA==} + dev: false + + /prebuild-install@7.1.1: + resolution: {integrity: sha512-jAXscXWMcCK8GgCoHOfIr0ODh5ai8mj63L2nWrjuAgXE6tDyYGnx4/8o/rCgU+B4JSyZBKbeZqzhtwtC3ovxjw==} + engines: {node: '>=10'} + hasBin: true + dependencies: + detect-libc: 2.0.2 + expand-template: 2.0.3 + github-from-package: 0.0.0 + minimist: 1.2.8 + mkdirp-classic: 0.5.3 + napi-build-utils: 1.0.2 + node-abi: 3.47.0 + pump: 3.0.0 + rc: 1.2.8 + simple-get: 4.0.1 + tar-fs: 2.1.1 + tunnel-agent: 0.6.0 + dev: false + + /prelude-ls@1.2.1: + resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} + engines: {node: '>= 0.8.0'} + dev: true + + /prism-media@1.3.5(@discordjs/opus@0.5.3)(ffmpeg-static@4.4.1): + resolution: {integrity: sha512-IQdl0Q01m4LrkN1EGIE9lphov5Hy7WWlH6ulf5QdGePLlPas9p2mhgddTEHrlaXYjjFToM1/rWuwF37VF4taaA==} + peerDependencies: + '@discordjs/opus': '>=0.8.0 <1.0.0' + ffmpeg-static: ^5.0.2 || ^4.2.7 || ^3.0.0 || ^2.4.0 + node-opus: ^0.3.3 + opusscript: ^0.0.8 + peerDependenciesMeta: + '@discordjs/opus': + optional: true + ffmpeg-static: + optional: true + node-opus: + optional: true + opusscript: + optional: true + dependencies: + '@discordjs/opus': 0.5.3 + ffmpeg-static: 4.4.1 + dev: false + + /progress@2.0.3: + resolution: {integrity: sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==} + engines: {node: '>=0.4.0'} + dev: false + + /promise-inflight@1.0.1: + resolution: {integrity: sha512-6zWPyEOFaQBJYcGMHBKTKJ3u6TBsnMFOIZSa6ce1e/ZrrsOlnHRHbabMjLiBYKp+n44X9eUI6VUPaukCXHuG4g==} + requiresBuild: true + peerDependencies: + bluebird: '*' + peerDependenciesMeta: + bluebird: + optional: true + dev: false + optional: true + + /promise-retry@2.0.1: + resolution: {integrity: sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g==} + engines: {node: '>=10'} + requiresBuild: true + dependencies: + err-code: 2.0.3 + retry: 0.12.0 + dev: false + optional: true + + /proxy-addr@2.0.7: + resolution: {integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==} + engines: {node: '>= 0.10'} + dependencies: + forwarded: 0.2.0 + ipaddr.js: 1.9.1 + dev: false + + /pump@3.0.0: + resolution: {integrity: sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==} + dependencies: + end-of-stream: 1.4.4 + once: 1.4.0 + dev: false + + /punycode@2.3.0: + resolution: {integrity: sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==} + engines: {node: '>=6'} + dev: true + + /qs@6.11.0: + resolution: {integrity: sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==} + engines: {node: '>=0.6'} + dependencies: + side-channel: 1.0.4 + dev: false + + /queue-microtask@1.2.3: + resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} + dev: true + + /queue-tick@1.0.1: + resolution: {integrity: sha512-kJt5qhMxoszgU/62PLP1CJytzd2NKetjSRnyuj31fDd3Rlcz3fzlFdFLD1SItunPwyqEOkca6GbV612BWfaBag==} + dev: false + + /range-parser@1.2.1: + resolution: {integrity: sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==} + engines: {node: '>= 0.6'} + dev: false + + /raw-body@2.5.1: + resolution: {integrity: sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==} + engines: {node: '>= 0.8'} + dependencies: + bytes: 3.1.2 + http-errors: 2.0.0 + iconv-lite: 0.4.24 + unpipe: 1.0.0 + dev: false + + /rc@1.2.8: + resolution: {integrity: sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==} + hasBin: true + dependencies: + deep-extend: 0.6.0 + ini: 1.3.8 + minimist: 1.2.8 + strip-json-comments: 2.0.1 + dev: false + + /readable-stream@3.6.2: + resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==} + engines: {node: '>= 6'} + dependencies: + inherits: 2.0.4 + string_decoder: 1.3.0 + util-deprecate: 1.0.2 + dev: false + + /resolve-from@4.0.0: + resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} + engines: {node: '>=4'} + dev: true + + /retry-as-promised@7.0.4: + resolution: {integrity: sha512-XgmCoxKWkDofwH8WddD0w85ZfqYz+ZHlr5yo+3YUCfycWawU56T5ckWXsScsj5B8tqUcIG67DxXByo3VUgiAdA==} + dev: false + + /retry@0.12.0: + resolution: {integrity: sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==} + engines: {node: '>= 4'} + requiresBuild: true + dev: false + optional: true + + /reusify@1.0.4: + resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==} + engines: {iojs: '>=1.0.0', node: '>=0.10.0'} + dev: true + + /rimraf@3.0.2: + resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==} + hasBin: true + dependencies: + glob: 7.2.3 + + /run-parallel@1.2.0: + resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} + dependencies: + queue-microtask: 1.2.3 + dev: true + + /safe-buffer@5.2.1: + resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} + dev: false + + /safer-buffer@2.1.2: + resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} + dev: false + + /semver@6.3.1: + resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} + hasBin: true + dev: false + + /semver@7.5.4: + resolution: {integrity: sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==} + engines: {node: '>=10'} + hasBin: true + dependencies: + lru-cache: 6.0.0 + dev: false + + /send@0.18.0: + resolution: {integrity: sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==} + engines: {node: '>= 0.8.0'} + dependencies: + debug: 2.6.9 + depd: 2.0.0 + destroy: 1.2.0 + encodeurl: 1.0.2 + escape-html: 1.0.3 + etag: 1.8.1 + fresh: 0.5.2 + http-errors: 2.0.0 + mime: 1.6.0 + ms: 2.1.3 + on-finished: 2.4.1 + range-parser: 1.2.1 + statuses: 2.0.1 + transitivePeerDependencies: + - supports-color + dev: false + + /sequelize-pool@7.1.0: + resolution: {integrity: sha512-G9c0qlIWQSK29pR/5U2JF5dDQeqqHRragoyahj/Nx4KOOQ3CPPfzxnfqFPCSB7x5UgjOgnZ61nSxz+fjDpRlJg==} + engines: {node: '>= 10.0.0'} + dev: false + + /sequelize@6.33.0(sqlite3@5.1.6): + resolution: {integrity: sha512-GkeCbqgaIcpyZ1EyXrDNIwktbfMldHAGOVXHGM4x8bxGSRAOql5htDWofPvwpfL/FoZ59CaFmfO3Mosv1lDbQw==} + engines: {node: '>=10.0.0'} + peerDependencies: + ibm_db: '*' + mariadb: '*' + mysql2: '*' + oracledb: '*' + pg: '*' + pg-hstore: '*' + snowflake-sdk: '*' + sqlite3: '*' + tedious: '*' + peerDependenciesMeta: + ibm_db: + optional: true + mariadb: + optional: true + mysql2: + optional: true + oracledb: + optional: true + pg: + optional: true + pg-hstore: + optional: true + snowflake-sdk: + optional: true + sqlite3: + optional: true + tedious: + optional: true + dependencies: + '@types/debug': 4.1.8 + '@types/validator': 13.11.1 + debug: 4.3.4 + dottie: 2.0.6 + inflection: 1.13.4 + lodash: 4.17.21 + moment: 2.29.4 + moment-timezone: 0.5.43 + pg-connection-string: 2.6.2 + retry-as-promised: 7.0.4 + semver: 7.5.4 + sequelize-pool: 7.1.0 + sqlite3: 5.1.6 + toposort-class: 1.0.1 + uuid: 8.3.2 + validator: 13.11.0 + wkx: 0.5.0 + transitivePeerDependencies: + - supports-color + dev: false + + /serve-static@1.15.0: + resolution: {integrity: sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==} + engines: {node: '>= 0.8.0'} + dependencies: + encodeurl: 1.0.2 + escape-html: 1.0.3 + parseurl: 1.3.3 + send: 0.18.0 + transitivePeerDependencies: + - supports-color + dev: false + + /set-blocking@2.0.0: + resolution: {integrity: sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==} + dev: false + + /setprototypeof@1.2.0: + resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==} + dev: false + + /sharp@0.32.6: + resolution: {integrity: sha512-KyLTWwgcR9Oe4d9HwCwNM2l7+J0dUQwn/yf7S0EnTtb0eVS4RxO0eUSvxPtzT4F3SY+C4K6fqdv/DO27sJ/v/w==} + engines: {node: '>=14.15.0'} + requiresBuild: true + dependencies: + color: 4.2.3 + detect-libc: 2.0.2 + node-addon-api: 6.1.0 + prebuild-install: 7.1.1 + semver: 7.5.4 + simple-get: 4.0.1 + tar-fs: 3.0.4 + tunnel-agent: 0.6.0 + dev: false + + /shebang-command@2.0.0: + resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} + engines: {node: '>=8'} + dependencies: + shebang-regex: 3.0.0 + dev: true + + /shebang-regex@3.0.0: + resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} + engines: {node: '>=8'} + dev: true + + /side-channel@1.0.4: + resolution: {integrity: sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==} + dependencies: + call-bind: 1.0.2 + get-intrinsic: 1.2.1 + object-inspect: 1.12.3 + dev: false + + /signal-exit@3.0.7: + resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} + dev: false + + /simple-concat@1.0.1: + resolution: {integrity: sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==} + dev: false + + /simple-get@4.0.1: + resolution: {integrity: sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==} + dependencies: + decompress-response: 6.0.0 + once: 1.4.0 + simple-concat: 1.0.1 + dev: false + + /simple-swizzle@0.2.2: + resolution: {integrity: sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==} + dependencies: + is-arrayish: 0.3.2 + dev: false + + /smart-buffer@4.2.0: + resolution: {integrity: sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==} + engines: {node: '>= 6.0.0', npm: '>= 3.0.0'} + requiresBuild: true + dev: false + optional: true + + /socks-proxy-agent@6.2.1: + resolution: {integrity: sha512-a6KW9G+6B3nWZ1yB8G7pJwL3ggLy1uTzKAgCb7ttblwqdz9fMGJUuTy3uFzEP48FAs9FLILlmzDlE2JJhVQaXQ==} + engines: {node: '>= 10'} + requiresBuild: true + dependencies: + agent-base: 6.0.2 + debug: 4.3.4 + socks: 2.7.1 + transitivePeerDependencies: + - supports-color + dev: false + optional: true + + /socks@2.7.1: + resolution: {integrity: sha512-7maUZy1N7uo6+WVEX6psASxtNlKaNVMlGQKkG/63nEDdLOWNbiUMoLK7X4uYoLhQstau72mLgfEWcXcwsaHbYQ==} + engines: {node: '>= 10.13.0', npm: '>= 3.0.0'} + requiresBuild: true + dependencies: + ip: 2.0.0 + smart-buffer: 4.2.0 + dev: false + optional: true + + /sqlite3@5.1.6: + resolution: {integrity: sha512-olYkWoKFVNSSSQNvxVUfjiVbz3YtBwTJj+mfV5zpHmqW3sELx2Cf4QCdirMelhM5Zh+KDVaKgQHqCxrqiWHybw==} + requiresBuild: true + peerDependenciesMeta: + node-gyp: + optional: true + dependencies: + '@mapbox/node-pre-gyp': 1.0.11 + node-addon-api: 4.3.0 + tar: 6.2.0 + optionalDependencies: + node-gyp: 8.4.1 + transitivePeerDependencies: + - bluebird + - encoding + - supports-color + dev: false + + /ssri@8.0.1: + resolution: {integrity: sha512-97qShzy1AiyxvPNIkLWoGua7xoQzzPjQ0HAH4B0rWKo7SZ6USuPcrUiAFrws0UH8RrbWmgq3LMTObhPIHbbBeQ==} + engines: {node: '>= 8'} + requiresBuild: true + dependencies: + minipass: 3.3.6 + dev: false + optional: true + + /statuses@2.0.1: + resolution: {integrity: sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==} + engines: {node: '>= 0.8'} + dev: false + + /streamsearch@1.1.0: + resolution: {integrity: sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==} + engines: {node: '>=10.0.0'} + dev: false + + /streamx@2.15.1: + resolution: {integrity: sha512-fQMzy2O/Q47rgwErk/eGeLu/roaFWV0jVsogDmrszM9uIw8L5OA+t+V93MgYlufNptfjmYR1tOMWhei/Eh7TQA==} + dependencies: + fast-fifo: 1.3.2 + queue-tick: 1.0.1 + dev: false + + /string-width@4.2.3: + resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} + engines: {node: '>=8'} + dependencies: + emoji-regex: 8.0.0 + is-fullwidth-code-point: 3.0.0 + strip-ansi: 6.0.1 + dev: false + + /string_decoder@1.3.0: + resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==} + dependencies: + safe-buffer: 5.2.1 + dev: false + + /strip-ansi@6.0.1: + resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} + engines: {node: '>=8'} + dependencies: + ansi-regex: 5.0.1 + + /strip-json-comments@2.0.1: + resolution: {integrity: sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==} + engines: {node: '>=0.10.0'} + dev: false + + /strip-json-comments@3.1.1: + resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} + engines: {node: '>=8'} + dev: true + + /supports-color@7.2.0: + resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} + engines: {node: '>=8'} + dependencies: + has-flag: 4.0.0 + + /tar-fs@2.1.1: + resolution: {integrity: sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==} + dependencies: + chownr: 1.1.4 + mkdirp-classic: 0.5.3 + pump: 3.0.0 + tar-stream: 2.2.0 + dev: false + + /tar-fs@3.0.4: + resolution: {integrity: sha512-5AFQU8b9qLfZCX9zp2duONhPmZv0hGYiBPJsyUdqMjzq/mqVpy/rEUSeHk1+YitmxugaptgBh5oDGU3VsAJq4w==} + dependencies: + mkdirp-classic: 0.5.3 + pump: 3.0.0 + tar-stream: 3.1.6 + dev: false + + /tar-stream@2.2.0: + resolution: {integrity: sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==} + engines: {node: '>=6'} + dependencies: + bl: 4.1.0 + end-of-stream: 1.4.4 + fs-constants: 1.0.0 + inherits: 2.0.4 + readable-stream: 3.6.2 + dev: false + + /tar-stream@3.1.6: + resolution: {integrity: sha512-B/UyjYwPpMBv+PaFSWAmtYjwdrlEaZQEhMIBFNC5oEG8lpiW8XjcSdmEaClj28ArfKScKHs2nshz3k2le6crsg==} + dependencies: + b4a: 1.6.4 + fast-fifo: 1.3.2 + streamx: 2.15.1 + dev: false + + /tar@6.2.0: + resolution: {integrity: sha512-/Wo7DcT0u5HUV486xg675HtjNd3BXZ6xDbzsCUZPt5iw8bTQ63bP0Raut3mvro9u+CUyq7YQd8Cx55fsZXxqLQ==} + engines: {node: '>=10'} + dependencies: + chownr: 2.0.0 + fs-minipass: 2.1.0 + minipass: 5.0.0 + minizlib: 2.1.2 + mkdirp: 1.0.4 + yallist: 4.0.0 + dev: false + + /text-table@0.2.0: + resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==} + dev: true + + /toidentifier@1.0.1: + resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==} + engines: {node: '>=0.6'} + dev: false + + /toposort-class@1.0.1: + resolution: {integrity: sha512-OsLcGGbYF3rMjPUf8oKktyvCiUxSbqMMS39m33MAjLTC1DVIH6x3WSt63/M77ihI09+Sdfk1AXvfhCEeUmC7mg==} + dev: false + + /tr46@0.0.3: + resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} + dev: false + + /ts-mixer@6.0.3: + resolution: {integrity: sha512-k43M7uCG1AkTyxgnmI5MPwKoUvS/bRvLvUb7+Pgpdlmok8AoqmUaZxUUw8zKM5B1lqZrt41GjYgnvAi0fppqgQ==} + dev: false + + /tslib@2.6.2: + resolution: {integrity: sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==} + dev: false + + /tunnel-agent@0.6.0: + resolution: {integrity: sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==} + dependencies: + safe-buffer: 5.2.1 + dev: false + + /type-check@0.4.0: + resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} + engines: {node: '>= 0.8.0'} + dependencies: + prelude-ls: 1.2.1 + dev: true + + /type-fest@0.20.2: + resolution: {integrity: sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==} + engines: {node: '>=10'} + dev: true + + /type-is@1.6.18: + resolution: {integrity: sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==} + engines: {node: '>= 0.6'} + dependencies: + media-typer: 0.3.0 + mime-types: 2.1.35 + dev: false + + /typedarray@0.0.6: + resolution: {integrity: sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==} + dev: false + + /undici@5.22.1: + resolution: {integrity: sha512-Ji2IJhFXZY0x/0tVBXeQwgPlLWw13GVzpsWPQ3rV50IFMMof2I55PZZxtm4P6iNq+L5znYN9nSTAq0ZyE6lSJw==} + engines: {node: '>=14.0'} + dependencies: + busboy: 1.6.0 + dev: false + + /unique-filename@1.1.1: + resolution: {integrity: sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ==} + requiresBuild: true + dependencies: + unique-slug: 2.0.2 + dev: false + optional: true + + /unique-slug@2.0.2: + resolution: {integrity: sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w==} + requiresBuild: true + dependencies: + imurmurhash: 0.1.4 + dev: false + optional: true + + /unpipe@1.0.0: + resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==} + engines: {node: '>= 0.8'} + dev: false + + /uri-js@4.4.1: + resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} + dependencies: + punycode: 2.3.0 + dev: true + + /util-deprecate@1.0.2: + resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} + dev: false + + /utils-merge@1.0.1: + resolution: {integrity: sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==} + engines: {node: '>= 0.4.0'} + dev: false + + /uuid@8.3.2: + resolution: {integrity: sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==} + hasBin: true + dev: false + + /validator@13.11.0: + resolution: {integrity: sha512-Ii+sehpSfZy+At5nPdnyMhx78fEoPDkR2XW/zimHEL3MyGJQOCQ7WeP20jPYRz7ZCpcKLB21NxuXHF3bxjStBQ==} + engines: {node: '>= 0.10'} + dev: false + + /vary@1.1.2: + resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==} + engines: {node: '>= 0.8'} + dev: false + + /webidl-conversions@3.0.1: + resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} + dev: false + + /weeby-js@1.3.0: + resolution: {integrity: sha512-yCajTSN8KYz3Ek+qtVThqHICrQ/8f6OAh0qrmUKcnXbO/8u4S6STUfi+LEVMAq1reiuL9qHmKL3YsIkU5eDIiw==} + dependencies: + chalk: 4.1.2 + node-superfetch: 0.2.3 + transitivePeerDependencies: + - encoding + dev: false + + /whatwg-url@5.0.0: + resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==} + dependencies: + tr46: 0.0.3 + webidl-conversions: 3.0.1 + dev: false + + /which@2.0.2: + resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} + engines: {node: '>= 8'} + hasBin: true + dependencies: + isexe: 2.0.0 + + /wide-align@1.1.5: + resolution: {integrity: sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==} + dependencies: + string-width: 4.2.3 + dev: false + + /wkx@0.5.0: + resolution: {integrity: sha512-Xng/d4Ichh8uN4l0FToV/258EjMGU9MGcA0HV2d9B/ZpZB3lqQm7nkOdZdm5GhKtLLhAE7PiVQwN4eN+2YJJUg==} + dependencies: + '@types/node': 18.17.17 + dev: false + + /wrappy@1.0.2: + resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} + + /ws@8.14.2: + resolution: {integrity: sha512-wEBG1ftX4jcglPxgFCMJmZ2PLtSbJ2Peg6TmpJFTbe9GZYOQCDPdMYu/Tm0/bGZkw8paZnJY45J4K2PZrLYq8g==} + engines: {node: '>=10.0.0'} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: '>=5.0.2' + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + dev: false + + /yallist@4.0.0: + resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==} + dev: false + + /yocto-queue@0.1.0: + resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} + engines: {node: '>=10'} + dev: true diff --git a/readme.md b/readme.md new file mode 100644 index 0000000..36bed50 --- /dev/null +++ b/readme.md @@ -0,0 +1,26 @@ +# SNS Chan +Official Custom Discord Bot for Supernoobs Discord Server + + +## running +--- +made for linux or unix systems, running elsewhere isnt supported but should probably work:3 +(for windows you can probably use msys or git bash) + +- `npm i` +- put tokens and api keys in .env-example, and move it to .env +- `sh buildconfig.sh` +- `node .` or `sh snschan.sh` (to restart on error) + + +## todo ~ +--- +- [x] settings for each command +- [x] restricted channels +- [x] restrict to a channel +- [x] cooldown +- [ ] test commands +- [ ] reset/refresh command +- [ ] settings webui +- [ ] settings via discord commands +- [ ] slash commands diff --git a/snschan.sh b/snschan.sh new file mode 100644 index 0000000..a0b60ad --- /dev/null +++ b/snschan.sh @@ -0,0 +1,7 @@ +echo Starting.. +while true +do +node index.js +wait +sleep 10 +done diff --git a/src/db.js b/src/db.js new file mode 100644 index 0000000..aba84f0 --- /dev/null +++ b/src/db.js @@ -0,0 +1,69 @@ +const path = require('path'); +const { Sequelize, DataTypes } = require('sequelize'); + +const _db_raw = new Sequelize({ + dialect: 'sqlite', + storage: path.join(__dirname, '../db/db.sqlite'), + logging:false +}); +let db = {_raw:_db_raw} + +db.Tickets = _db_raw.define('Tickets', { + ticket: DataTypes.TEXT, + message: DataTypes.TEXT, + status: DataTypes.TEXT, + author: DataTypes.TEXT, + name: DataTypes.TEXT, + created: DataTypes.TEXT, + messages: DataTypes.STRING, + attachments: DataTypes.STRING, + pfp: DataTypes.STRING, +}, { +}); + +db.Sticky = _db_raw.define('Sticky', { + embed: DataTypes.BOOLEAN, + embed_color: DataTypes.TEXT, + channel: DataTypes.TEXT, + message: DataTypes.TEXT, + last_message: DataTypes.TEXT, +}, { +}); + +db.Auto_React = _db_raw.define('Auto_React', { + channel: DataTypes.TEXT, + emote: DataTypes.TEXT, +}, { +}); + +db.Timed_Message = _db_raw.define('Timed_Message', { + embed: DataTypes.BOOLEAN, + embed_color: DataTypes.TEXT, + guild: DataTypes.TEXT, + channel: DataTypes.TEXT, + message: DataTypes.TEXT, + last_message: DataTypes.TEXT, + last_message_time: DataTypes.TEXT, + delay: DataTypes.TEXT, +}, { +}); + +db.BattleShip = _db_raw.define('BattleShip', { + turn: DataTypes.INTEGER, + p1_id: DataTypes.TEXT, + p2_id: DataTypes.TEXT, + p1_board: DataTypes.TEXT, + p2_board: DataTypes.TEXT, +}, { +}); + +try { + db._raw.authenticate(); + console.log('db connected'); +} catch (error) { + console.error('Unable to connect to the database:', error); +} + +_db_raw.sync() + +module.exports = db \ No newline at end of file diff --git a/src/settings.js b/src/settings.js new file mode 100644 index 0000000..87ba87b --- /dev/null +++ b/src/settings.js @@ -0,0 +1,17 @@ +let debug = 0; +let server = debug?"545076257369358336":"486957006628847626"; +let admin_c = debug?"545076257369358338":"753145819820982282"; +module.exports = { + "defaultColor": [43,45,49], + "allowed-servers":["486957006628847626","545076257369358336"], + "preloads": { + [server]: { + [admin_c]:{ + name: "admin-chan", + }, + "748790869938929737":{ + name: "logging", + } + } + } +} \ No newline at end of file diff --git a/src/util.js b/src/util.js new file mode 100644 index 0000000..ef1cf50 --- /dev/null +++ b/src/util.js @@ -0,0 +1,104 @@ +const rem_emp = function (e) {return e !== "";} + +module.exports = { + upload_limit(guild){ + //https://stackoverflow.com/questions/66396146/get-channels-filesize-limit + switch (guild.premiumTier) { + case 'TIER_3': return 100 + case 'TIER_2': return 50 + default: return 8 + } + }, + limit_exp(exp,length){ + exp = exp.split('e') + for(let i = 0; i!=length; i++) + exp[0]+="0" + exp[0] = exp[0].substring(0,length+2) + return exp.join('e') + }, + rem_emp, + parse_inp(str){ + let open = false; + let out = [] + let cur = "" + for(let c of str){ + if(c=='"'){ + if(open){ + out.push(cur) + cur="" + } + open=!open; + } + else { + if(!open){ + if(c==' '){ + out.push(cur) + cur="" + } else { + cur+=c + } + } else { + cur+=c + } + + } + } + out.push(cur) + return out.filter(rem_emp) + }, + similarity(s1, s2) { + //https://stackoverflow.com/questions/10473745/compare-strings-javascript-return-of-likely + function editDistance(s1, s2) { + s1 = s1.toLowerCase(); + s2 = s2.toLowerCase(); + + var costs = new Array(); + for (var i = 0; i <= s1.length; i++) { + var lastValue = i; + for (var j = 0; j <= s2.length; j++) { + if (i == 0) + costs[j] = j; + else { + if (j > 0) { + var newValue = costs[j - 1]; + if (s1.charAt(i - 1) != s2.charAt(j - 1)) + newValue = Math.min(Math.min(newValue, lastValue), + costs[j]) + 1; + costs[j - 1] = lastValue; + lastValue = newValue; + } + } + } + if (i > 0) + costs[s2.length] = lastValue; + } + return costs[s2.length]; + } + var longer = s1; + var shorter = s2; + if (s1.length < s2.length) { + longer = s2; + shorter = s1; + } + var longerLength = longer.length; + if (longerLength == 0) { + return 1.0; + } + return (longerLength - editDistance(longer, shorter)) / parseFloat(longerLength); + }, + + deepCopy(src) { + //https://stackoverflow.com/questions/122102/what-is-the-most-efficient-way-to-deep-clone-an-object-in-javascript/49497485 + let target = Array.isArray(src) ? [] : {}; + for (let prop in src) { + let value = src[prop]; + if(value && typeof value === 'object') { + target[prop] = deepCopy(value); + } else { + target[prop] = value; + } + } + return target; + } + +} \ No newline at end of file diff --git a/src/webui.js b/src/webui.js new file mode 100644 index 0000000..8a9fa56 --- /dev/null +++ b/src/webui.js @@ -0,0 +1,40 @@ + +const key = process.env.WEBUI_KEY +const bodyParser = require("body-parser"); +const express = require('express'); +let db = require("../src/db"); +const path = require("path") +const Tickets = db.Tickets + +const app = express(); +app.use(bodyParser.urlencoded({ extended: false })); +app.use(bodyParser.json()); +const port = 7001; +app.get('/tickets', async (req, res) => { + res.sendFile(path.join(__dirname+'/../html/tickets.html')) +}) +app.post('/tickets/data', async (req, res) => { + if(req.body.key == key) + res.send(await Tickets.findAll()) + else + res.send('failed') +}) +app.post('/tickets/edit', async (req, res) => { + if(req.body.key == key){ + console.log('pass') + res.send('pass') + } + else + res.send('failed') +}) + +app.get('/settings', async (req, res) => { + res.sendFile(path.join(__dirname+'/../html/settings.html')) +}) +app.post('/settings/data', async (req, res) => { + if(req.body.key == key) + res.send('todo:P') + else + res.send('failed') +}) +app.listen(port, () => console.log(`listening at http://localhost:${port}`)); -- cgit v1.2.3