From 6c96cb0ca204542295a9594225d1d653576558a0 Mon Sep 17 00:00:00 2001 From: Ioannis Tsiakkas Date: Fri, 8 Jan 2021 21:16:43 +0200 Subject: [PATCH] Typescript refactor (#41) * small part of transition done * a lot or architectural changes and progress on typescript transition * first compile after beginning the transition to typescript * all seem to work well, must proceed with complete refactor to reach a working state * A lot of progress but a lot more to be finished * types and libs finished * small fixes * upodated half the events * message reaction event transitioned * finished with events * small updates * fully working events not commands need to get updated and transition can go to next stage of refinement and testing * update compilation problems * half commands done corona only new has been updated old will remain js * 1/3 of commands remaining * finished with commands testing and transition is complete * updated portal channel creation to be unified among portal types and fixed announcements * portal spawn and movement of users fixed * bug fixes * a lot of fixes * a lot of bug fixes and save json fixed * remove on log back on for all data variables controlled by portal * updates and new tree command to see what portal controls in current server * setup has been fixed * renamed auth_role commands to full authorise and updated bug fixes * bulk delete has been implemented and role renamed to role_assigner * updated help to be easier for a beginner to comprehend * regex interpreter has been update, fixed attribute recognition * updated help with structures and help description * set attributes has been fixed * updated the way portal tree displays information * removed debugging console logs and client write and client talk functions * git token test * weather command implemented, and updated design of embedded messages * cleaned up *** from the project updated a lot of things and cleaned up code. Also implemented translate and whoami commands * set ranks and ranks has been fixed * role giver and assigner update need more work * fixed role giving messages and reactions to them plus reactions to music video * updated to 1.5.0 and fixed small problems with guild insertion and updated design of state * small update * changed prefix for merge * updated annoying messages and readme file, plus some bug fixes, yml and tests Co-authored-by: Ioannis Tsiakkas --- .eslintrc.js | 90 +- .github/workflows/nodejs.yml | 4 +- .vscode/settings.json | 3 + assets/classes/guild_class.js | 20 - assets/classes/member_class.js | 10 - assets/classes/portal_class.js | 19 - assets/classes/role_class.js | 5 - assets/classes/voice_class.js | 15 - assets/jsons/cooldown_list.json | 182 - config.json | 10 - database/PortalDB/models/guild.model.js | 24 - database/PortalDB/models/member.model.js | 10 - database/PortalDB/models/music_data.model.js | 12 - database/PortalDB/models/portal.model.js | 21 - database/PortalDB/models/role.model.js | 11 - database/PortalDB/models/voice.model.js | 34 - database/PortalDB/mongo_connection.js | 22 - database/PortalDB/mongo_schema_script.js | 0 database/guild_list.json | 1 - docs/Attributes.md | 1 - docs/README.md | 66 +- package-lock.json | 8822 +---------------- package.json | 74 +- src/portal.js => portal.js.txt | 26 +- {assets => src/assets}/img/logo.png | Bin {assets => src/assets}/img/spotify.png | Bin src/assets/jsons/cooldown_list.json | 236 + .../assets}/jsons/country_codes.json | 0 .../assets}/jsons/country_codes_2.json | 0 {assets => src/assets}/jsons/game_list.json | 0 .../assets}/jsons/profane_word_list.json | 3 +- .../assets}/jsons/program_list.json | 0 .../assets}/mp3s/de/announce/announce_0.mp3 | Bin .../assets}/mp3s/de/announce/announce_1.mp3 | Bin .../assets}/mp3s/de/announce/announce_2.mp3 | Bin .../assets}/mp3s/de/fail/fail_0.mp3 | Bin .../assets}/mp3s/de/fail/fail_1.mp3 | Bin .../assets}/mp3s/de/fail/fail_2.mp3 | Bin .../assets}/mp3s/de/join/join_0.mp3 | Bin .../assets}/mp3s/de/join/join_1.mp3 | Bin .../assets}/mp3s/de/join/join_2.mp3 | Bin .../assets}/mp3s/de/leave/leave_0.mp3 | Bin .../assets}/mp3s/de/leave/leave_1.mp3 | Bin .../assets}/mp3s/de/leave/leave_2.mp3 | Bin .../assets}/mp3s/de/leave/leave_3.mp3 | Bin .../assets}/mp3s/de/read_only/read_only_0.mp3 | Bin .../assets}/mp3s/de/read_only/read_only_1.mp3 | Bin .../assets}/mp3s/de/read_only/read_only_2.mp3 | Bin .../assets}/mp3s/de/spotify/spotify_0.mp3 | Bin .../assets}/mp3s/de/spotify/spotify_1.mp3 | Bin .../assets}/mp3s/de/spotify/spotify_2.mp3 | Bin {assets => src/assets}/mp3s/de/url/url_0.mp3 | Bin {assets => src/assets}/mp3s/de/url/url_1.mp3 | Bin {assets => src/assets}/mp3s/de/url/url_2.mp3 | Bin .../de/user_connected/user_connected_0.mp3 | Bin .../de/user_connected/user_connected_1.mp3 | Bin .../de/user_connected/user_connected_2.mp3 | Bin .../user_disconnected/user_disconnected_0.mp3 | Bin .../user_disconnected/user_disconnected_1.mp3 | Bin .../user_disconnected/user_disconnected_2.mp3 | Bin .../assets}/mp3s/en/announce/announce_0.mp3 | Bin .../assets}/mp3s/en/announce/announce_1.mp3 | Bin .../assets}/mp3s/en/announce/announce_2.mp3 | Bin .../assets}/mp3s/en/fail/fail_0.mp3 | Bin .../assets}/mp3s/en/fail/fail_1.mp3 | Bin .../assets}/mp3s/en/fail/fail_2.mp3 | Bin .../assets}/mp3s/en/join/join_0.mp3 | Bin .../assets}/mp3s/en/join/join_1.mp3 | Bin .../assets}/mp3s/en/join/join_2.mp3 | Bin .../assets}/mp3s/en/leave/leave_0.mp3 | Bin .../assets}/mp3s/en/leave/leave_1.mp3 | Bin .../assets}/mp3s/en/leave/leave_2.mp3 | Bin .../assets}/mp3s/en/read_only/read_only_0.mp3 | Bin .../assets}/mp3s/en/read_only/read_only_1.mp3 | Bin .../assets}/mp3s/en/read_only/read_only_2.mp3 | Bin .../assets}/mp3s/en/spotify/spotify_0.mp3 | Bin .../assets}/mp3s/en/spotify/spotify_1.mp3 | Bin .../assets}/mp3s/en/spotify/spotify_2.mp3 | Bin {assets => src/assets}/mp3s/en/url/url_0.mp3 | Bin {assets => src/assets}/mp3s/en/url/url_1.mp3 | Bin {assets => src/assets}/mp3s/en/url/url_2.mp3 | Bin .../en/user_connected/user_connected_0.mp3 | Bin .../en/user_connected/user_connected_1.mp3 | Bin .../en/user_connected/user_connected_2.mp3 | Bin .../user_disconnected/user_disconnected_0.mp3 | Bin .../user_disconnected/user_disconnected_1.mp3 | Bin .../user_disconnected/user_disconnected_2.mp3 | Bin .../assets}/mp3s/gr/announce/announce_0.mp3 | Bin .../assets}/mp3s/gr/announce/announce_1.mp3 | Bin .../assets}/mp3s/gr/announce/announce_2.mp3 | Bin .../assets}/mp3s/gr/fail/fail_0.mp3 | Bin .../assets}/mp3s/gr/fail/fail_1.mp3 | Bin .../assets}/mp3s/gr/fail/fail_2.mp3 | Bin .../assets}/mp3s/gr/join/join_0.mp3 | Bin .../assets}/mp3s/gr/join/join_1.mp3 | Bin .../assets}/mp3s/gr/join/join_2.mp3 | Bin .../assets}/mp3s/gr/join/join_3.mp3 | Bin .../assets}/mp3s/gr/join/join_4.mp3 | Bin {assets => src/assets}/mp3s/gr/joke_0.mp3 | Bin .../assets}/mp3s/gr/leave/leave_0.mp3 | Bin .../assets}/mp3s/gr/leave/leave_1.mp3 | Bin .../assets}/mp3s/gr/leave/leave_2.mp3 | Bin .../assets}/mp3s/gr/read_only/read_only_0.mp3 | Bin .../assets}/mp3s/gr/read_only/read_only_1.mp3 | Bin .../assets}/mp3s/gr/read_only/read_only_2.mp3 | Bin .../assets}/mp3s/gr/spotify/spotify_0.mp3 | Bin .../assets}/mp3s/gr/spotify/spotify_1.mp3 | Bin .../assets}/mp3s/gr/spotify/spotify_2.mp3 | Bin {assets => src/assets}/mp3s/gr/url/url_0.mp3 | Bin {assets => src/assets}/mp3s/gr/url/url_1.mp3 | Bin {assets => src/assets}/mp3s/gr/url/url_2.mp3 | Bin .../gr/user_connected/user_connected_0.mp3 | Bin .../gr/user_connected/user_connected_1.mp3 | Bin .../gr/user_connected/user_connected_2.mp3 | Bin .../user_disconnected/user_disconnected_0.mp3 | Bin .../user_disconnected/user_disconnected_1.mp3 | Bin .../user_disconnected/user_disconnected_2.mp3 | Bin src/commands/about.js | 68 - src/commands/about.ts | 43 + src/commands/announce.js | 29 - src/commands/announce.ts | 42 + src/commands/announcement.js | 79 - src/commands/announcement.ts | 103 + src/commands/auth_role_add.js | 23 - src/commands/auth_role_rem.js | 23 - src/commands/auth_roles.js | 20 - src/commands/authorise.ts | 42 + src/commands/authorised_roles.ts | 31 + src/commands/corona.js | 122 - src/commands/corona.ts | 148 + src/commands/corona_old.js | 310 +- src/commands/deauthorise.ts | 38 + src/commands/delete.ts | 28 + src/commands/focus.js | 98 - src/commands/focus.ts | 111 + src/commands/force.js | 100 - src/commands/force.ts | 125 + src/commands/help.js | 92 - src/commands/help.ts | 144 + src/commands/join.js | 34 - src/commands/join.ts | 19 + src/commands/joke.js | 24 - src/commands/joke.ts | 34 + src/commands/leaderboard.js | 70 - src/commands/leaderboard.ts | 91 + src/commands/leave.js | 15 - src/commands/leave.ts | 22 + src/commands/level.js | 30 - src/commands/level.ts | 39 + src/commands/music.js | 87 - src/commands/music.ts | 98 + src/commands/news.js | 231 +- src/commands/ping.js | 19 - src/commands/ping.ts | 26 + src/commands/portal.js | 37 - src/commands/portal.ts | 88 + src/commands/purge.js | 52 +- src/commands/ranks.js | 36 - src/commands/ranks.ts | 48 + src/commands/role.js | 104 - src/commands/role_assigner.ts | 95 + src/commands/roll.js | 21 - src/commands/roll.ts | 33 + src/commands/run.js | 45 - src/commands/run.ts | 71 + src/commands/save.js | 9 - src/commands/save.ts | 18 + src/commands/set.js | 95 - src/commands/set.ts | 98 + src/commands/set_ranks.js | 61 - src/commands/set_ranks.ts | 76 + src/commands/setup.js | 37 - src/commands/setup.ts | 113 + src/commands/spotify.js | 68 - src/commands/spotify.ts | 104 + src/commands/state.ts | 86 + src/commands/translate.ts | 48 + src/commands/url.js | 64 - src/commands/url.ts | 93 + src/commands/weather.ts | 114 + src/commands/whoami.ts | 43 + src/config.json | 19 + src/database/guild_list.json | 1 + src/events/channelDelete.js | 24 - src/events/channelDelete.ts | 31 + src/events/guildCreate.js | 17 - src/events/guildCreate.ts | 64 + src/events/guildDelete.js | 12 - src/events/guildDelete.ts | 17 + src/events/guildMemberAdd.js | 21 - src/events/guildMemberAdd.ts | 41 + src/events/guildMemberRemove.js | 20 - src/events/guildMemberRemove.ts | 40 + src/events/messageDelete.js | 33 - src/events/messageDelete.ts | 50 + src/events/messageReactionAdd.js | 220 - src/events/messageReactionAdd.ts | 237 + src/events/presenceUpdate.js | 97 - src/events/presenceUpdate.ts | 130 + src/events/ready.js | 15 - src/events/ready.ts | 48 + src/events/shardReconnecting.js | 3 - src/events/shardResume.ts | 48 + src/events/shardStart.ts | 48 + src/events/voiceStateUpdate.js | 245 - src/events/voiceStateUpdate.ts | 295 + src/functions/guild_manager.js | 751 -- src/functions/help_manager.js | 375 - src/functions/http_requests.js | 17 - src/functions/localization_manager.js | 181 - src/functions/music_manager.js | 229 - src/functions/status_manager.js | 79 - src/functions/user_manager.js | 120 - src/libraries/guildOps.ts | 678 ++ src/libraries/helpOps.ts | 517 + src/libraries/httpOps.ts | 16 + src/libraries/localizationOps.ts | 238 + src/libraries/modOps.ts | 38 + src/libraries/musicOps.ts | 310 + src/libraries/statusOps.ts | 79 + src/libraries/userOps.ts | 201 + src/moderation/profanity.js | 29 - src/portal.ts | 354 +- src/properties/attribute_list.js | 356 - src/properties/command_list.js | 295 - src/properties/pipe_list.js | 152 - src/properties/structure_list.js | 66 - src/properties/variable_list.js | 342 - src/types/classes/GiveRolePrtl.ts | 28 + src/types/classes/GuildPrtl.ts | 75 + src/types/classes/MemberPrtl.ts | 27 + src/types/classes/PortalChannelPrtl.ts | 47 + src/types/classes/RolePrtl.ts | 9 + src/types/classes/VoiceChannelPrtl.ts | 33 + src/types/interfaces/Attribute.ts | 397 + src/types/interfaces/Command.ts | 442 + src/types/interfaces/InterfacesPrtl.ts | 109 + src/types/interfaces/Pipe.ts | 180 + src/types/interfaces/Structure.ts | 80 + src/types/interfaces/Variable.ts | 401 + tests/commands/roll.test.js | 28 +- tests/moderation/profanity.test.js | 14 +- tests/portal.test.js | 14 +- tsconfig.json | 17 + 244 files changed, 8611 insertions(+), 14625 deletions(-) create mode 100644 .vscode/settings.json delete mode 100644 assets/classes/guild_class.js delete mode 100644 assets/classes/member_class.js delete mode 100644 assets/classes/portal_class.js delete mode 100644 assets/classes/role_class.js delete mode 100644 assets/classes/voice_class.js delete mode 100644 assets/jsons/cooldown_list.json delete mode 100644 config.json delete mode 100644 database/PortalDB/models/guild.model.js delete mode 100644 database/PortalDB/models/member.model.js delete mode 100644 database/PortalDB/models/music_data.model.js delete mode 100644 database/PortalDB/models/portal.model.js delete mode 100644 database/PortalDB/models/role.model.js delete mode 100644 database/PortalDB/models/voice.model.js delete mode 100644 database/PortalDB/mongo_connection.js delete mode 100644 database/PortalDB/mongo_schema_script.js delete mode 100644 database/guild_list.json rename src/portal.js => portal.js.txt (92%) rename {assets => src/assets}/img/logo.png (100%) rename {assets => src/assets}/img/spotify.png (100%) create mode 100644 src/assets/jsons/cooldown_list.json rename {assets => src/assets}/jsons/country_codes.json (100%) rename {assets => src/assets}/jsons/country_codes_2.json (100%) rename {assets => src/assets}/jsons/game_list.json (100%) rename {assets => src/assets}/jsons/profane_word_list.json (99%) rename {assets => src/assets}/jsons/program_list.json (100%) rename {assets => src/assets}/mp3s/de/announce/announce_0.mp3 (100%) rename {assets => src/assets}/mp3s/de/announce/announce_1.mp3 (100%) rename {assets => src/assets}/mp3s/de/announce/announce_2.mp3 (100%) rename {assets => src/assets}/mp3s/de/fail/fail_0.mp3 (100%) rename {assets => src/assets}/mp3s/de/fail/fail_1.mp3 (100%) rename {assets => src/assets}/mp3s/de/fail/fail_2.mp3 (100%) rename {assets => src/assets}/mp3s/de/join/join_0.mp3 (100%) rename {assets => src/assets}/mp3s/de/join/join_1.mp3 (100%) rename {assets => src/assets}/mp3s/de/join/join_2.mp3 (100%) rename {assets => src/assets}/mp3s/de/leave/leave_0.mp3 (100%) rename {assets => src/assets}/mp3s/de/leave/leave_1.mp3 (100%) rename {assets => src/assets}/mp3s/de/leave/leave_2.mp3 (100%) rename {assets => src/assets}/mp3s/de/leave/leave_3.mp3 (100%) rename {assets => src/assets}/mp3s/de/read_only/read_only_0.mp3 (100%) rename {assets => src/assets}/mp3s/de/read_only/read_only_1.mp3 (100%) rename {assets => src/assets}/mp3s/de/read_only/read_only_2.mp3 (100%) rename {assets => src/assets}/mp3s/de/spotify/spotify_0.mp3 (100%) rename {assets => src/assets}/mp3s/de/spotify/spotify_1.mp3 (100%) rename {assets => src/assets}/mp3s/de/spotify/spotify_2.mp3 (100%) rename {assets => src/assets}/mp3s/de/url/url_0.mp3 (100%) rename {assets => src/assets}/mp3s/de/url/url_1.mp3 (100%) rename {assets => src/assets}/mp3s/de/url/url_2.mp3 (100%) rename {assets => src/assets}/mp3s/de/user_connected/user_connected_0.mp3 (100%) rename {assets => src/assets}/mp3s/de/user_connected/user_connected_1.mp3 (100%) rename {assets => src/assets}/mp3s/de/user_connected/user_connected_2.mp3 (100%) rename {assets => src/assets}/mp3s/de/user_disconnected/user_disconnected_0.mp3 (100%) rename {assets => src/assets}/mp3s/de/user_disconnected/user_disconnected_1.mp3 (100%) rename {assets => src/assets}/mp3s/de/user_disconnected/user_disconnected_2.mp3 (100%) rename {assets => src/assets}/mp3s/en/announce/announce_0.mp3 (100%) rename {assets => src/assets}/mp3s/en/announce/announce_1.mp3 (100%) rename {assets => src/assets}/mp3s/en/announce/announce_2.mp3 (100%) rename {assets => src/assets}/mp3s/en/fail/fail_0.mp3 (100%) rename {assets => src/assets}/mp3s/en/fail/fail_1.mp3 (100%) rename {assets => src/assets}/mp3s/en/fail/fail_2.mp3 (100%) rename {assets => src/assets}/mp3s/en/join/join_0.mp3 (100%) rename {assets => src/assets}/mp3s/en/join/join_1.mp3 (100%) rename {assets => src/assets}/mp3s/en/join/join_2.mp3 (100%) rename {assets => src/assets}/mp3s/en/leave/leave_0.mp3 (100%) rename {assets => src/assets}/mp3s/en/leave/leave_1.mp3 (100%) rename {assets => src/assets}/mp3s/en/leave/leave_2.mp3 (100%) rename {assets => src/assets}/mp3s/en/read_only/read_only_0.mp3 (100%) rename {assets => src/assets}/mp3s/en/read_only/read_only_1.mp3 (100%) rename {assets => src/assets}/mp3s/en/read_only/read_only_2.mp3 (100%) rename {assets => src/assets}/mp3s/en/spotify/spotify_0.mp3 (100%) rename {assets => src/assets}/mp3s/en/spotify/spotify_1.mp3 (100%) rename {assets => src/assets}/mp3s/en/spotify/spotify_2.mp3 (100%) rename {assets => src/assets}/mp3s/en/url/url_0.mp3 (100%) rename {assets => src/assets}/mp3s/en/url/url_1.mp3 (100%) rename {assets => src/assets}/mp3s/en/url/url_2.mp3 (100%) rename {assets => src/assets}/mp3s/en/user_connected/user_connected_0.mp3 (100%) rename {assets => src/assets}/mp3s/en/user_connected/user_connected_1.mp3 (100%) rename {assets => src/assets}/mp3s/en/user_connected/user_connected_2.mp3 (100%) rename {assets => src/assets}/mp3s/en/user_disconnected/user_disconnected_0.mp3 (100%) rename {assets => src/assets}/mp3s/en/user_disconnected/user_disconnected_1.mp3 (100%) rename {assets => src/assets}/mp3s/en/user_disconnected/user_disconnected_2.mp3 (100%) rename {assets => src/assets}/mp3s/gr/announce/announce_0.mp3 (100%) rename {assets => src/assets}/mp3s/gr/announce/announce_1.mp3 (100%) rename {assets => src/assets}/mp3s/gr/announce/announce_2.mp3 (100%) rename {assets => src/assets}/mp3s/gr/fail/fail_0.mp3 (100%) rename {assets => src/assets}/mp3s/gr/fail/fail_1.mp3 (100%) rename {assets => src/assets}/mp3s/gr/fail/fail_2.mp3 (100%) rename {assets => src/assets}/mp3s/gr/join/join_0.mp3 (100%) rename {assets => src/assets}/mp3s/gr/join/join_1.mp3 (100%) rename {assets => src/assets}/mp3s/gr/join/join_2.mp3 (100%) rename {assets => src/assets}/mp3s/gr/join/join_3.mp3 (100%) rename {assets => src/assets}/mp3s/gr/join/join_4.mp3 (100%) rename {assets => src/assets}/mp3s/gr/joke_0.mp3 (100%) rename {assets => src/assets}/mp3s/gr/leave/leave_0.mp3 (100%) rename {assets => src/assets}/mp3s/gr/leave/leave_1.mp3 (100%) rename {assets => src/assets}/mp3s/gr/leave/leave_2.mp3 (100%) rename {assets => src/assets}/mp3s/gr/read_only/read_only_0.mp3 (100%) rename {assets => src/assets}/mp3s/gr/read_only/read_only_1.mp3 (100%) rename {assets => src/assets}/mp3s/gr/read_only/read_only_2.mp3 (100%) rename {assets => src/assets}/mp3s/gr/spotify/spotify_0.mp3 (100%) rename {assets => src/assets}/mp3s/gr/spotify/spotify_1.mp3 (100%) rename {assets => src/assets}/mp3s/gr/spotify/spotify_2.mp3 (100%) rename {assets => src/assets}/mp3s/gr/url/url_0.mp3 (100%) rename {assets => src/assets}/mp3s/gr/url/url_1.mp3 (100%) rename {assets => src/assets}/mp3s/gr/url/url_2.mp3 (100%) rename {assets => src/assets}/mp3s/gr/user_connected/user_connected_0.mp3 (100%) rename {assets => src/assets}/mp3s/gr/user_connected/user_connected_1.mp3 (100%) rename {assets => src/assets}/mp3s/gr/user_connected/user_connected_2.mp3 (100%) rename {assets => src/assets}/mp3s/gr/user_disconnected/user_disconnected_0.mp3 (100%) rename {assets => src/assets}/mp3s/gr/user_disconnected/user_disconnected_1.mp3 (100%) rename {assets => src/assets}/mp3s/gr/user_disconnected/user_disconnected_2.mp3 (100%) delete mode 100644 src/commands/about.js create mode 100644 src/commands/about.ts delete mode 100644 src/commands/announce.js create mode 100644 src/commands/announce.ts delete mode 100644 src/commands/announcement.js create mode 100644 src/commands/announcement.ts delete mode 100644 src/commands/auth_role_add.js delete mode 100644 src/commands/auth_role_rem.js delete mode 100644 src/commands/auth_roles.js create mode 100644 src/commands/authorise.ts create mode 100644 src/commands/authorised_roles.ts delete mode 100644 src/commands/corona.js create mode 100644 src/commands/corona.ts create mode 100644 src/commands/deauthorise.ts create mode 100644 src/commands/delete.ts delete mode 100644 src/commands/focus.js create mode 100644 src/commands/focus.ts delete mode 100644 src/commands/force.js create mode 100644 src/commands/force.ts delete mode 100644 src/commands/help.js create mode 100644 src/commands/help.ts delete mode 100644 src/commands/join.js create mode 100644 src/commands/join.ts delete mode 100644 src/commands/joke.js create mode 100644 src/commands/joke.ts delete mode 100644 src/commands/leaderboard.js create mode 100644 src/commands/leaderboard.ts delete mode 100644 src/commands/leave.js create mode 100644 src/commands/leave.ts delete mode 100644 src/commands/level.js create mode 100644 src/commands/level.ts delete mode 100644 src/commands/music.js create mode 100644 src/commands/music.ts delete mode 100644 src/commands/ping.js create mode 100644 src/commands/ping.ts delete mode 100644 src/commands/portal.js create mode 100644 src/commands/portal.ts delete mode 100644 src/commands/ranks.js create mode 100644 src/commands/ranks.ts delete mode 100644 src/commands/role.js create mode 100644 src/commands/role_assigner.ts delete mode 100644 src/commands/roll.js create mode 100644 src/commands/roll.ts delete mode 100644 src/commands/run.js create mode 100644 src/commands/run.ts delete mode 100644 src/commands/save.js create mode 100644 src/commands/save.ts delete mode 100644 src/commands/set.js create mode 100644 src/commands/set.ts delete mode 100644 src/commands/set_ranks.js create mode 100644 src/commands/set_ranks.ts delete mode 100644 src/commands/setup.js create mode 100644 src/commands/setup.ts delete mode 100644 src/commands/spotify.js create mode 100644 src/commands/spotify.ts create mode 100644 src/commands/state.ts create mode 100644 src/commands/translate.ts delete mode 100644 src/commands/url.js create mode 100644 src/commands/url.ts create mode 100644 src/commands/weather.ts create mode 100644 src/commands/whoami.ts create mode 100644 src/config.json create mode 100644 src/database/guild_list.json delete mode 100644 src/events/channelDelete.js create mode 100644 src/events/channelDelete.ts delete mode 100644 src/events/guildCreate.js create mode 100644 src/events/guildCreate.ts delete mode 100644 src/events/guildDelete.js create mode 100644 src/events/guildDelete.ts delete mode 100644 src/events/guildMemberAdd.js create mode 100644 src/events/guildMemberAdd.ts delete mode 100644 src/events/guildMemberRemove.js create mode 100644 src/events/guildMemberRemove.ts delete mode 100644 src/events/messageDelete.js create mode 100644 src/events/messageDelete.ts delete mode 100644 src/events/messageReactionAdd.js create mode 100644 src/events/messageReactionAdd.ts delete mode 100644 src/events/presenceUpdate.js create mode 100644 src/events/presenceUpdate.ts delete mode 100644 src/events/ready.js create mode 100644 src/events/ready.ts delete mode 100644 src/events/shardReconnecting.js create mode 100644 src/events/shardResume.ts create mode 100644 src/events/shardStart.ts delete mode 100644 src/events/voiceStateUpdate.js create mode 100644 src/events/voiceStateUpdate.ts delete mode 100644 src/functions/guild_manager.js delete mode 100644 src/functions/help_manager.js delete mode 100644 src/functions/http_requests.js delete mode 100644 src/functions/localization_manager.js delete mode 100644 src/functions/music_manager.js delete mode 100644 src/functions/status_manager.js delete mode 100644 src/functions/user_manager.js create mode 100644 src/libraries/guildOps.ts create mode 100644 src/libraries/helpOps.ts create mode 100644 src/libraries/httpOps.ts create mode 100644 src/libraries/localizationOps.ts create mode 100644 src/libraries/modOps.ts create mode 100644 src/libraries/musicOps.ts create mode 100644 src/libraries/statusOps.ts create mode 100644 src/libraries/userOps.ts delete mode 100644 src/moderation/profanity.js delete mode 100644 src/properties/attribute_list.js delete mode 100644 src/properties/command_list.js delete mode 100644 src/properties/pipe_list.js delete mode 100644 src/properties/structure_list.js delete mode 100644 src/properties/variable_list.js create mode 100644 src/types/classes/GiveRolePrtl.ts create mode 100644 src/types/classes/GuildPrtl.ts create mode 100644 src/types/classes/MemberPrtl.ts create mode 100644 src/types/classes/PortalChannelPrtl.ts create mode 100644 src/types/classes/RolePrtl.ts create mode 100644 src/types/classes/VoiceChannelPrtl.ts create mode 100644 src/types/interfaces/Attribute.ts create mode 100644 src/types/interfaces/Command.ts create mode 100644 src/types/interfaces/InterfacesPrtl.ts create mode 100644 src/types/interfaces/Pipe.ts create mode 100644 src/types/interfaces/Structure.ts create mode 100644 src/types/interfaces/Variable.ts create mode 100644 tsconfig.json diff --git a/.eslintrc.js b/.eslintrc.js index 3df5dc3c..387d5f9c 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -1,46 +1,46 @@ module.exports = { - 'extends': 'eslint:recommended', - 'env': { - 'node': true, - 'es6': true, - }, - 'parserOptions': { - 'ecmaVersion': 2019, - }, - 'rules': { - 'brace-style': ['error', 'stroustrup', { 'allowSingleLine': true }], - 'comma-dangle': ['error', 'always-multiline'], - 'comma-spacing': 'error', - 'comma-style': 'error', - 'curly': ['error', 'multi-line', 'consistent'], - 'dot-location': ['error', 'property'], - 'handle-callback-err': 'off', - 'indent': ['error', 'tab'], - 'max-nested-callbacks': ['error', { 'max': 4 }], - 'max-statements-per-line': ['error', { 'max': 2 }], - 'no-console': 'off', - 'no-empty-function': 'error', - 'no-floating-decimal': 'error', - 'no-lonely-if': 'error', - 'no-multi-spaces': 'error', - 'no-multiple-empty-lines': ['error', { 'max': 2, 'maxEOF': 1, 'maxBOF': 0 }], - 'no-shadow': ['error', { 'allow': ['err', 'resolve', 'reject'] }], - 'no-trailing-spaces': ['error'], - 'no-var': 'error', - 'object-curly-spacing': ['error', 'always'], - 'prefer-const': 'error', - 'quotes': ['error', 'single'], - 'semi': ['error', 'always'], - 'space-before-blocks': 'error', - 'space-before-function-paren': ['error', { - 'anonymous': 'never', - 'named': 'never', - 'asyncArrow': 'always', - }], - 'space-in-parens': 'error', - 'space-infix-ops': 'error', - 'space-unary-ops': 'error', - 'spaced-comment': 'error', - 'yoda': 'error', - }, -}; + 'extends': 'eslint:recommended', + 'env': { + 'node': true, + 'es6': true, + }, + 'parserOptions': { + 'ecmaVersion': 2019, + }, + 'rules': { + 'brace-style': ['error', 'stroustrup', { 'allowSingleLine': true }], + 'comma-dangle': ['error', 'always-multiline'], + 'comma-spacing': 'error', + 'comma-style': 'error', + 'curly': ['error', 'multi-line', 'consistent'], + 'dot-location': ['error', 'property'], + 'handle-callback-err': 'off', + 'indent': ['error', 'space'], + 'max-nested-callbacks': ['error', { 'max': 4 }], + 'max-statements-per-line': ['error', { 'max': 2 }], + 'no-console': 'off', + 'no-empty-function': 'error', + 'no-floating-decimal': 'error', + 'no-lonely-if': 'error', + 'no-multi-spaces': 'error', + 'no-multiple-empty-lines': ['error', { 'max': 2, 'maxEOF': 1, 'maxBOF': 0 }], + 'no-shadow': ['error', { 'allow': ['err', 'resolve', 'reject'] }], + 'no-trailing-spaces': ['error'], + 'no-var': 'error', + 'object-curly-spacing': ['error', 'always'], + 'prefer-const': 'error', + 'quotes': ['error', 'single'], + 'semi': ['error', 'always'], + 'space-before-blocks': 'error', + 'space-before-function-paren': ['error', { + 'anonymous': 'never', + 'named': 'never', + 'asyncArrow': 'always', + }], + 'space-in-parens': 'error', + 'space-infix-ops': 'error', + 'space-unary-ops': 'error', + 'spaced-comment': 'error', + 'yoda': 'error', + }, +}; \ No newline at end of file diff --git a/.github/workflows/nodejs.yml b/.github/workflows/nodejs.yml index 2a3039a1..3b8c617e 100644 --- a/.github/workflows/nodejs.yml +++ b/.github/workflows/nodejs.yml @@ -21,5 +21,5 @@ jobs: check-latest: true - run: npm install - run: npm ci - - run: npm lint - - run: npm run build --if-present + - run: npm test + - run: npm start diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 00000000..a1c49108 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "compile-hero.disable-compile-files-on-did-save-code": true +} \ No newline at end of file diff --git a/assets/classes/guild_class.js b/assets/classes/guild_class.js deleted file mode 100644 index 9018e25c..00000000 --- a/assets/classes/guild_class.js +++ /dev/null @@ -1,20 +0,0 @@ -module.exports = class { - constructor(portal_list, member_list, url_list, role_list, ranks, auth_role, spotify, - music_data, music_queue, dispatcher, announcement, locale, announce, level_speed, premium) { - this.portal_list = portal_list; - this.member_list = member_list; - this.url_list = url_list; - this.role_list = role_list; - this.ranks = ranks; - this.auth_role = auth_role; - this.spotify = spotify; - this.music_data = music_data; - this.music_queue = music_queue; - this.dispatcher = dispatcher; - this.announcement = announcement; - this.locale = locale; - this.announce = announce; - this.level_speed = level_speed; - this.premium = premium; - } -}; \ No newline at end of file diff --git a/assets/classes/member_class.js b/assets/classes/member_class.js deleted file mode 100644 index 4a3fabea..00000000 --- a/assets/classes/member_class.js +++ /dev/null @@ -1,10 +0,0 @@ -module.exports = class { - constructor(level, rank, tier, points, timestamp) { - this.level = level; - this.rank = rank; - this.tier = tier; - this.points = points; - - this.timestamp = timestamp; - } -}; \ No newline at end of file diff --git a/assets/classes/portal_class.js b/assets/classes/portal_class.js deleted file mode 100644 index 9020e06f..00000000 --- a/assets/classes/portal_class.js +++ /dev/null @@ -1,19 +0,0 @@ -module.exports = class { - constructor(creator_id, regex_portal, regex_voice, voice_list, - no_bots, limit_portal, time_to_live, refresh_rate, locale, - ann_announce, ann_user) { - - this.creator_id = creator_id; - this.regex_portal = regex_portal; - this.regex_voice = regex_voice; - this.voice_list = voice_list; - this.no_bots = no_bots; - this.limit_portal = limit_portal; - this.time_to_live = time_to_live; - this.refresh_rate = refresh_rate; - this.locale = locale; - - this.ann_announce = ann_announce; - this.ann_user = ann_user; - } -}; diff --git a/assets/classes/role_class.js b/assets/classes/role_class.js deleted file mode 100644 index c7025e08..00000000 --- a/assets/classes/role_class.js +++ /dev/null @@ -1,5 +0,0 @@ -module.exports = class { - constructor(role_emote_map) { - this.role_emote_map = role_emote_map; - } -}; diff --git a/assets/classes/voice_class.js b/assets/classes/voice_class.js deleted file mode 100644 index 85d2ea20..00000000 --- a/assets/classes/voice_class.js +++ /dev/null @@ -1,15 +0,0 @@ -module.exports = class { - constructor(creator_id, regex, no_bots, time_to_live, - refresh_rate, locale, ann_announce, ann_user) { - - this.creator_id = creator_id; - this.regex = regex; - this.no_bots = no_bots; - this.time_to_live = time_to_live; - this.refresh_rate = refresh_rate; - this.locale = locale; - - this.ann_announce = ann_announce; - this.ann_user = ann_user; - } -}; diff --git a/assets/jsons/cooldown_list.json b/assets/jsons/cooldown_list.json deleted file mode 100644 index 148184a4..00000000 --- a/assets/jsons/cooldown_list.json +++ /dev/null @@ -1,182 +0,0 @@ -{ - "guild": { - "purge": { - "time": 10, - "auth": true, - "premium": true, - "auto_delete": true - }, - "save": { - "time": 5, - "auth": true, - "premium": true, - "auto_delete": true - }, - "setup": { - "time": 10, - "auth": true, - "premium": true, - "auto_delete": true - }, - "set_ranks": { - "time": 10, - "auth": true, - "premium": true, - "auto_delete": true - } - }, - "member": { - "join": { - "time": 1, - "auth": false, - "premium": true, - "auto_delete": true - }, - "announce": { - "time": 2, - "auth": false, - "premium": true, - "auto_delete": true - }, - "force": { - "time": 5, - "auth": true, - "premium": true, - "auto_delete": true - } - }, - "none": { - "leaderboard": { - "time": 0, - "auth": false, - "premium": false, - "auto_delete": true - }, - "ranks": { - "time": 0, - "auth": false, - "premium": true, - "auto_delete": true - }, - "level": { - "time": 0, - "auth": false, - "premium": false, - "auto_delete": true - }, - "about": { - "time": 0, - "auth": false, - "premium": false, - "auto_delete": true - }, - "portal": { - "time": 0, - "auth": true, - "premium": false, - "auto_delete": true - }, - "help": { - "time": 0, - "auth": false, - "premium": false, - "auto_delete": true - }, - "ping": { - "time": 0, - "auth": false, - "premium": false, - "auto_delete": true - }, - "set": { - "time": 0, - "auth": false, - "premium": true, - "auto_delete": true - }, - "role": { - "time": 0, - "auth": false, - "premium": true, - "auto_delete": true - }, - "spotify": { - "time": 0, - "auth": true, - "premium": true, - "auto_delete": true - }, - "music": { - "time": 0, - "auth": true, - "premium": true, - "auto_delete": true - }, - "announcement": { - "time": 0, - "auth": true, - "premium": true, - "auto_delete": true - }, - "url": { - "time": 0, - "auth": true, - "premium": true, - "auto_delete": true - }, - "leave": { - "time": 0, - "auth": false, - "premium": true, - "auto_delete": true - }, - "focus": { - "time": 0, - "auth": false, - "premium": true, - "auto_delete": true - }, - "corona": { - "time": 0, - "auth": false, - "premium": false, - "auto_delete": false - }, - "roll": { - "time": 0, - "auth": false, - "premium": false, - "auto_delete": false - }, - "run": { - "time": 0, - "auth": false, - "premium": true, - "auto_delete": true - }, - "auth_roles": { - "time": 0, - "auth": true, - "premium": true, - "auto_delete": true - }, - "auth_role_add": { - "time": 0, - "auth": true, - "premium": true, - "auto_delete": true - }, - "auth_role_rem": { - "time": 0, - "auth": true, - "premium": true, - "auto_delete": true - }, - "joke": { - "time": 0, - "auth": false, - "premium": false, - "auto_delete": false - } - } -} \ No newline at end of file diff --git a/config.json b/config.json deleted file mode 100644 index 0f11e719..00000000 --- a/config.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "token" : "NzA0NDAwODc2ODYwNzM1NTY5.Xqdexg.BkhxqAkXpNZfcIzalW68jFw5DTI", - "token_dev" : "NzU1ODI1ODcwMTAyNTkzNjI2.X2I7sQ.nDesKkpHU-m5wdxZOdXmChlgnXU", - "prefix" : "./", - "owner_id" : 228666893068795905, - "portal_id" : 755825870102593626, - "delete_msg" : false, - "delete_msg_after" : 5, - "always_reply" : true - } \ No newline at end of file diff --git a/database/PortalDB/models/guild.model.js b/database/PortalDB/models/guild.model.js deleted file mode 100644 index f34fe081..00000000 --- a/database/PortalDB/models/guild.model.js +++ /dev/null @@ -1,24 +0,0 @@ -const mongoose = require('mongoose'); - -const guildSchema = new mongoose.Schema({ - guild: { - guild_id: String, - portal_list: Array, - member_list: Array, - url_list: Array, - role_list: Array, - ranks: Array, - auth_role: Array, - announcement: String, - spotify: String, - music_data: Array, - music_queue: Array, - dispatcher: Array, - locale: Number, - announce: Array, - level_speed: Number, - premium: Boolean, - }, -}); - -module.exports = mongoose.model('Guild', guildSchema); \ No newline at end of file diff --git a/database/PortalDB/models/member.model.js b/database/PortalDB/models/member.model.js deleted file mode 100644 index 4a3fabea..00000000 --- a/database/PortalDB/models/member.model.js +++ /dev/null @@ -1,10 +0,0 @@ -module.exports = class { - constructor(level, rank, tier, points, timestamp) { - this.level = level; - this.rank = rank; - this.tier = tier; - this.points = points; - - this.timestamp = timestamp; - } -}; \ No newline at end of file diff --git a/database/PortalDB/models/music_data.model.js b/database/PortalDB/models/music_data.model.js deleted file mode 100644 index 59eec551..00000000 --- a/database/PortalDB/models/music_data.model.js +++ /dev/null @@ -1,12 +0,0 @@ -const mongoose = require('mongoose'); - -const music_dataSchema = new mongoose.Schema({ - music_data: { - music_data_id: String, - channel_id: String, - message_id: String, - votes: Array, - }, -}); - -module.exports = mongoose.model('MusicModel', music_dataSchema); \ No newline at end of file diff --git a/database/PortalDB/models/portal.model.js b/database/PortalDB/models/portal.model.js deleted file mode 100644 index 7fbde2ff..00000000 --- a/database/PortalDB/models/portal.model.js +++ /dev/null @@ -1,21 +0,0 @@ -const mongoose = require('mongoose'); - -const portalSchema = new mongoose.Schema({ - portal: { - portal_id: String, - creator_id: String, - regex_portal: String, - regex_voice: String, - no_bots: Boolean, - limit_portal: Number, - time_to_live: Number, - refresh_rate: Number, - locale: String, - voice_list: Array, - - ann_announce: Boolean, - ann_user: Boolean, - }, -}); - -module.exports = mongoose.model('PortalModel', portalSchema); \ No newline at end of file diff --git a/database/PortalDB/models/role.model.js b/database/PortalDB/models/role.model.js deleted file mode 100644 index 6d9f4560..00000000 --- a/database/PortalDB/models/role.model.js +++ /dev/null @@ -1,11 +0,0 @@ -const mongoose = require('mongoose'); - -const roleSchema = new mongoose.Schema({ - portal: { - role_id: String, - emote: String, - role: String, - }, -}); - -module.exports = mongoose.model('RoleModel', roleSchema); \ No newline at end of file diff --git a/database/PortalDB/models/voice.model.js b/database/PortalDB/models/voice.model.js deleted file mode 100644 index 8bcf0cb2..00000000 --- a/database/PortalDB/models/voice.model.js +++ /dev/null @@ -1,34 +0,0 @@ -module.exports = class { - constructor(creator_id, regex, no_bots, time_to_live, - refresh_rate, locale, ann_announce, ann_user) { - - this.creator_id = creator_id; - this.regex = regex; - this.no_bots = no_bots; - this.time_to_live = time_to_live; - this.refresh_rate = refresh_rate; - this.locale = locale; - - this.ann_announce = ann_announce; - this.ann_user = ann_user; - } -}; - -const mongoose = require('mongoose'); - -const voiceSchema = new mongoose.Schema({ - voice: { - voice_id: String, - creator_id: String, - regex: String, - no_bots: Boolean, - time_to_live: Number, - refresh_rate: Number, - locale: String, - - ann_announce: Boolean, - ann_user: Boolean, - }, -}); - -module.exports = mongoose.model('VoiceModel', voiceSchema); \ No newline at end of file diff --git a/database/PortalDB/mongo_connection.js b/database/PortalDB/mongo_connection.js deleted file mode 100644 index 5ca3fcf9..00000000 --- a/database/PortalDB/mongo_connection.js +++ /dev/null @@ -1,22 +0,0 @@ -const mongoose = require('mongoose'); - -const server = '127.0.0.1:27017'; // REPLACE WITH YOUR DB SERVER -const database = 'PortalDB'; // REPLACE WITH YOUR DB NAME - -class Database { - constructor() { - this._connect(); - } - - _connect() { - mongoose.connect(`mongodb://${server}/${database}`) - .then(() => { - console.log('Database connection successful'); - }) - .catch(err => { - console.error('Database connection error', err); - }); - } -} - -module.exports = new Database(); \ No newline at end of file diff --git a/database/PortalDB/mongo_schema_script.js b/database/PortalDB/mongo_schema_script.js deleted file mode 100644 index e69de29b..00000000 diff --git a/database/guild_list.json b/database/guild_list.json deleted file mode 100644 index 4d73711d..00000000 --- a/database/guild_list.json +++ /dev/null @@ -1 +0,0 @@ -{"228667314252283904":{"portal_list":{"772258097875124234":{"creator_id":"228666893068795905","regex_portal":"game-launcher","regex_voice":"G$#-P$member_count | $status_list","no_bots":false,"limit_portal":4,"time_to_live":0,"refresh_rate":0,"locale":"gr","voice_list":{"764615071316967455":{"creator_id":"346306540308922387","regex":"G$#-P$member_count | $status_list","no_bots":false,"time_to_live":0,"refresh_rate":0,"locale":"gr","ann_announce":false,"ann_user":true}},"ann_announce":false,"ann_user":true}},"member_list":{"779828037898338306":{"level":1,"rank":0,"tier":0,"points":0,"timestamp":null},"424232862296834050":{"level":1,"rank":0,"tier":0,"points":0,"timestamp":null},"141355428352229376":{"level":2,"rank":0,"tier":0,"points":440.45,"timestamp":null},"358644113543004173":{"level":1,"rank":0,"tier":0,"points":0,"timestamp":null},"233681213506715649":{"level":1,"rank":0,"tier":0,"points":0,"timestamp":null},"688036058080083968":{"level":1,"rank":0,"tier":0,"points":0,"timestamp":null},"398910271164252167":{"level":1,"rank":0,"tier":0,"points":0,"timestamp":null},"397774224493903872":{"level":3,"rank":0,"tier":0,"points":2.7,"timestamp":null},"437935131936686120":{"level":1,"rank":0,"tier":0,"points":0,"timestamp":null},"245633518829305866":{"level":1,"rank":0,"tier":0,"points":0,"timestamp":null},"386599272587722752":{"level":1,"rank":0,"tier":0,"points":0,"timestamp":null},"285416786566971393":{"level":1,"rank":0,"tier":0,"points":0,"timestamp":null},"230995663607824386":{"level":16,"rank":0,"tier":3,"points":397.3499999999999,"timestamp":null},"222753236686209024":{"level":10,"rank":0,"tier":2,"points":957.4000000000001,"timestamp":null},"427540698544472085":{"level":1,"rank":0,"tier":0,"points":0,"timestamp":null},"233339202698215425":{"level":1,"rank":0,"tier":0,"points":0,"timestamp":null},"562010354540871712":{"level":1,"rank":0,"tier":0,"points":0,"timestamp":null},"346306540308922387":{"level":6,"rank":0,"tier":1,"points":634,"timestamp":null},"249594733150732290":{"level":1,"rank":0,"tier":0,"points":0,"timestamp":null},"394537380914397189":{"level":1,"rank":0,"tier":0,"points":0,"timestamp":null},"534388011857608705":{"level":1,"rank":0,"tier":0,"points":0,"timestamp":null},"362967897452314624":{"level":1,"rank":0,"tier":0,"points":0,"timestamp":null},"545021835432034304":{"level":1,"rank":0,"tier":0,"points":0,"timestamp":null},"248252695801102338":{"level":14,"rank":0,"tier":2,"points":1914.5,"timestamp":null},"547905866255433758":{"level":1,"rank":0,"tier":0,"points":0,"timestamp":null},"400770504539242496":{"level":1,"rank":0,"tier":0,"points":0,"timestamp":null},"317434205057318913":{"level":1,"rank":0,"tier":0,"points":0,"timestamp":null},"370147462893142017":{"level":1,"rank":0,"tier":0,"points":0,"timestamp":null},"476002321868914689":{"level":3,"rank":0,"tier":0,"points":0,"timestamp":null},"408955131690876938":{"level":2,"rank":0,"tier":0,"points":95.19999999999999,"timestamp":null},"159985870458322944":{"level":1,"rank":0,"tier":0,"points":0,"timestamp":null},"427926123859410944":{"level":5,"rank":0,"tier":1,"points":558.7000000000002,"timestamp":null},"449245494217015309":{"level":1,"rank":0,"tier":0,"points":0,"timestamp":null},"419927488563642375":{"level":1,"rank":0,"tier":0,"points":0,"timestamp":null},"231780831268438016":{"level":1,"rank":0,"tier":0,"points":0,"timestamp":null},"461124948560445450":{"level":1,"rank":0,"tier":0,"points":0,"timestamp":null},"404022320055975936":{"level":1,"rank":0,"tier":0,"points":0,"timestamp":null},"228666893068795905":{"level":14,"rank":0,"tier":2,"points":1568.449999999999,"timestamp":null},"231763688405598218":{"level":2,"rank":0,"tier":0,"points":389,"timestamp":null},"234402593256767491":{"level":1,"rank":0,"tier":0,"points":0,"timestamp":null},"690272852720746610":{"level":1,"rank":0,"tier":0,"points":0,"timestamp":null},"698597773712293938":{"level":1,"rank":0,"tier":0,"points":0,"timestamp":null},"370277653812477973":{"level":1,"rank":0,"tier":0,"points":0,"timestamp":null},"155149108183695360":{"level":1,"rank":0,"tier":0,"points":0,"timestamp":null},"232875205523931136":{"level":2,"rank":0,"tier":0,"points":0,"timestamp":null},"684814451345719316":{"level":1,"rank":0,"tier":0,"points":0,"timestamp":null},"148526306500280320":{"level":1,"rank":0,"tier":0,"points":0,"timestamp":null},"433795733230059520":{"level":1,"rank":0,"tier":0,"points":0,"timestamp":null},"233682014283235331":{"level":2,"rank":0,"tier":0,"points":0,"timestamp":null},"488405995979145236":{"level":3,"rank":0,"tier":0,"points":0,"timestamp":null},"659699741373759491":{"level":1,"rank":0,"tier":0,"points":0,"timestamp":null},"270707420831940618":{"level":1,"rank":0,"tier":0,"points":0,"timestamp":null},"534340160494632980":{"level":1,"rank":0,"tier":0,"points":0,"timestamp":null},"231373985420541952":{"level":2,"rank":0,"tier":0,"points":1,"timestamp":null},"142672003717922817":{"level":1,"rank":0,"tier":0,"points":0,"timestamp":null},"507202866537168906":{"level":1,"rank":0,"tier":0,"points":0,"timestamp":null},"406938957348339722":{"level":1,"rank":0,"tier":0,"points":0,"timestamp":null},"178625392586915840":{"level":5,"rank":0,"tier":1,"points":-970.65,"timestamp":"2020-09-22T22:04:21.053Z"},"395667507270254592":{"level":1,"rank":0,"tier":0,"points":0,"timestamp":null},"374865385909911553":{"level":1,"rank":0,"tier":0,"points":0,"timestamp":null},"533778497747812352":{"level":1,"rank":0,"tier":0,"points":0,"timestamp":null},"407615955812745217":{"level":1,"rank":0,"tier":0,"points":0,"timestamp":null},"326471246114062356":{"level":1,"rank":0,"tier":0,"points":0,"timestamp":null},"235088799074484224":{"level":1,"rank":0,"tier":0,"points":0,"timestamp":null},"231106885577605120":{"level":1,"rank":0,"tier":0,"points":0,"timestamp":null},"268865339041775618":{"level":15,"rank":0,"tier":3,"points":982.7000000000003,"timestamp":null},"590848955563376640":{"level":1,"rank":0,"tier":0,"points":0,"timestamp":null},"178621820457582602":{"level":5,"rank":0,"tier":1,"points":-209.6500000000001,"timestamp":null},"522844906243489793":{"level":1,"rank":0,"tier":0,"points":0,"timestamp":null},"540559238733234207":{"level":1,"rank":0,"tier":0,"points":0,"timestamp":null},"408684029039083520":{"level":1,"rank":0,"tier":0,"points":0,"timestamp":null},"642089816573607946":{"level":1,"rank":0,"tier":0,"points":0,"timestamp":null},"294539338119643137":{"level":1,"rank":0,"tier":0,"points":0,"timestamp":null},"537023025585848324":{"level":1,"rank":0,"tier":0,"points":0,"timestamp":null},"230430815505481729":{"level":5,"rank":0,"tier":1,"points":751.55,"timestamp":null}},"url_list":[],"role_list":{},"ranks":{},"auth_role":[],"spotify":null,"music_data":{"channel_id":"760550430429544529","message_id":"760550431154896968","votes":[]},"music_queue":[],"dispatcher":null,"announcement":null,"locale":"en","announce":0,"level_speed":"normal","premium":true},"731942147531735121":{"portal_list":{"759471645264969758":{"creator_id":"228666893068795905","regex_portal":"portal","regex_voice":"Channel $#","no_bots":false,"limit_portal":0,"time_to_live":0,"refresh_rate":0,"locale":"en","voice_list":{},"ann_announce":false,"ann_user":true}},"member_list":{"228666893068795905":{"level":3,"rank":0,"tier":0,"points":8.7,"timestamp":null},"755825870102593626":{"level":1,"rank":0,"tier":0,"points":0,"timestamp":null}},"url_list":[],"role_list":{},"ranks":{},"auth_role":[],"spotify":null,"music_data":{"channel_id":null,"message_id":null,"votes":[]},"music_queue":[],"dispatcher":null,"announcement":null,"locale":"en","announce":0,"level_speed":"normal","premium":false},"705112209985896529":{"portal_list":{"759290019701063692":{"creator_id":"228666893068795905","regex_portal":"general-portal","regex_voice":"Channel $#","no_bots":false,"limit_portal":0,"time_to_live":0,"refresh_rate":0,"locale":"en","voice_list":{},"ann_announce":false,"ann_user":true}},"member_list":{"155149108183695360":{"level":1,"rank":0,"tier":0,"points":0,"timestamp":null},"159985870458322944":{"level":1,"rank":0,"tier":0,"points":0,"timestamp":null},"178621820457582602":{"level":1,"rank":0,"tier":0,"points":0,"timestamp":null},"222753236686209024":{"level":1,"rank":0,"tier":0,"points":0,"timestamp":null},"228666893068795905":{"level":2,"rank":0,"tier":0,"points":0.35000000000000003,"timestamp":null},"230995663607824386":{"level":1,"rank":0,"tier":0,"points":0,"timestamp":null},"235088799074484224":{"level":1,"rank":0,"tier":0,"points":0,"timestamp":null},"268865339041775618":{"level":1,"rank":0,"tier":0,"points":0,"timestamp":null},"317434205057318913":{"level":1,"rank":0,"tier":0,"points":0,"timestamp":null},"408955131690876938":{"level":1,"rank":0,"tier":0,"points":0,"timestamp":null},"428866923267358721":{"level":1,"rank":0,"tier":0,"points":0,"timestamp":null},"476002321868914689":{"level":1,"rank":0,"tier":0,"points":0,"timestamp":null},"488405995979145236":{"level":1,"rank":0,"tier":0,"points":0,"timestamp":null}},"url_list":["759290026050715668"],"role_list":{},"ranks":{},"auth_role":[],"spotify":"759290022116458507","music_data":{"channel_id":"759290028387074048","message_id":"759290030593277955","votes":[]},"music_queue":[],"dispatcher":null,"announcement":"759290023819477004","locale":"en","announce":0,"level_speed":"normal","premium":false},"544946964177879052":{"portal_list":{"772578902588653568":{"creator_id":"476002321868914689","regex_portal":"my_portal","regex_voice":"G$#-P$member_count | $status_list","no_bots":false,"limit_portal":0,"time_to_live":0,"refresh_rate":0,"locale":"en","voice_list":{},"ann_announce":false,"ann_user":true}},"member_list":{"488405995979145236":{"level":18,"rank":0,"tier":3,"points":875.4499999999998,"timestamp":null},"476002321868914689":{"level":16,"rank":0,"tier":3,"points":2424.6500000000005,"timestamp":null},"178625392586915840":{"level":5,"rank":0,"tier":1,"points":662.85,"timestamp":null},"178621820457582602":{"level":14,"rank":0,"tier":2,"points":1657.65,"timestamp":"2020-11-28T19:59:09.820Z"},"142672003717922817":{"level":5,"rank":0,"tier":1,"points":851,"timestamp":null},"163416718566227969":{"level":1,"rank":0,"tier":0,"points":0,"timestamp":null},"163419504674734080":{"level":1,"rank":0,"tier":0,"points":0,"timestamp":null},"184995276304416768":{"level":1,"rank":0,"tier":0,"points":0,"timestamp":null},"191679617730347008":{"level":2,"rank":0,"tier":0,"points":0,"timestamp":null},"228666893068795905":{"level":10,"rank":0,"tier":2,"points":1197.2999999999997,"timestamp":"2020-11-26T22:43:26.768Z"},"230995663607824386":{"level":1,"rank":0,"tier":0,"points":0,"timestamp":null},"422502204633645112":{"level":1,"rank":0,"tier":0,"points":0,"timestamp":null},"439030658619146240":{"level":1,"rank":0,"tier":0,"points":0,"timestamp":null},"439046172783411202":{"level":10,"rank":0,"tier":2,"points":1063,"timestamp":null},"488032511667208213":{"level":1,"rank":0,"tier":0,"points":0,"timestamp":null},"747543166508335194":{"level":1,"rank":0,"tier":0,"points":0,"timestamp":null},"750410949181046825":{"level":1,"rank":0,"tier":0,"points":0,"timestamp":null}},"url_list":["760952178067505255"],"role_list":{},"ranks":{},"auth_role":[],"spotify":"760952176243114045","music_data":{"channel_id":"760952179145310208","message_id":"760952180114325535","votes":[]},"music_queue":[],"dispatcher":null,"announcement":"760952177165729802","locale":"en","announce":0,"level_speed":"normal","premium":true},"710746690650374208":{"portal_list":{"792859571072139354":{"creator_id":"228666893068795905","regex_portal":"antigoni","regex_voice":"{{\n \"if\": \"$year\", \"is\": \"<=\", \"with\": \"2020\",\n \"yes\": \"Young\", \"no\": \"old\"\n}}","voice_list":{},"no_bots":false,"limit_portal":2,"time_to_live":0,"refresh_rate":0,"locale":"en","ann_announce":true,"ann_user":true},"793520182496591902":{"creator_id":"228666893068795905","regex_portal":"new","regex_voice":"G$#-P$member_count | $status_list","voice_list":{},"no_bots":false,"limit_portal":2,"time_to_live":0,"refresh_rate":0,"locale":"en","ann_announce":true,"ann_user":true}},"member_list":{"228666893068795905":{"level":10,"rank":0,"tier":2,"points":1368.2999999999997,"timestamp":null}},"url_list":["792859574431514685"],"role_list":{"793523333265883137":{"role_emote_map":[{"give":"❤️","strip":"💩","role":"plempa","id":"741552875196514415"},{"give":"🍉","strip":"😆","role":"tsiakkas","id":"725393012498366464"}]}},"ranks":{},"auth_role":[],"spotify":"792859572015595560","music_data":{"channel_id":"792859575476158514","message_id":"792859576605212732","votes":[]},"music_queue":[],"dispatcher":null,"announcement":"792859572829945907","locale":"en","announce":0,"level_speed":"normal","premium":true}} \ No newline at end of file diff --git a/docs/Attributes.md b/docs/Attributes.md index 0ccf1814..321c5d8e 100644 --- a/docs/Attributes.md +++ b/docs/Attributes.md @@ -18,4 +18,3 @@ `bitrate_portal` | number | 64000 | _bitrate of current portal channel_ `bitrate_voice` | number | 64000 | _bitrate of current voice channel_ `position` | number | beneath portal | _position of channel_ -`last_update` | timestamp | timestamp | _returns the last update timestamp_ \ No newline at end of file diff --git a/docs/README.md b/docs/README.md index 9e6d80bf..ba05bd34 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,9 +1,13 @@ ![Node.js CI](https://github.com/keybraker/portal-discord-bot/workflows/Node.js%20CI/badge.svg) **Disclaimer[0]:** -> Portal will never record conversations or store anything you type +> This is a pation project, still in its infancy +> There is a lot yet to be done **Disclaimer[1]:** +> Portal will never record conversations or store anything you type + +**Disclaimer[2]:** > Discord update their server rate limit to twice per 10 minutes > [The new rate limit for channel name and topic updates is 2 updates per 10 minutes, per channel.](https://github.com/discordjs/discord.js/issues/4327) @@ -26,32 +30,40 @@ Features: **Portal™ prefix: ./** -| Name | Description | Arguments | Eligible for use | Cooldown (mins) | -| :-------------- | :--------------------------------------------------------------- | :----------------------------------- | :--------------------------------------------- | :-------------- | -| `about` | _returns an about Portal message_ | _none_ | everyone | - | -| `announce` | _@title \| @body_ | everyone | 1 user | - | -| `announcement` | _creates a new or sets the current channel as announcement_ | _@channel\_name \| @category\_name_ | admin, | admin-role/s | -| `auth_role_add` | _add role to admin roles_ | _!role_ | admin, admin-role/s | - | -| `auth_role_rem` | _removes role from admin roles_ | _!role_ | admin, admin-role/s | - | -| `corona` | _replies with the daily state of corona virus cases_ | _@country code (gr, de, us, etc)_ | everyone | - | -| `focus` | _creates focus channel for you and your requested user_ | _!username @time (default 5minutes)_ | everyone | - | -| `force` | _clones current channel in order to force-update name_ | _none_ | admin, admin-role/s | 2 user | -| `help` | _returns a help-list if specified returns specific description_ | _@command/@vrbl/@func/@pipe/@attr_ | everyone | - | -| `join` | _joins current voice channel and announces events_ | _none_ | everyone | 1 user | -| `leave` | _removes Portal from voice channel_ | _none_ | everyone | - | -| `level` | _returns your level_ | _none_ | everyone | - | -| `music` | _creates a new or sets the current channel as music channel_ | _@channel\_name \| @category\_name_ | admin, admin-role/s | - | -| `ping` | _returns round trip latency_ | _none_ | everyone | - | -| `portal` | _creates a portal voice channel_ | _!channel\_name \| @category\_name_ | admin, admin-role/s | - | -| `ranks` | _returns ranks of ranking system_ | _none_ | everyone | - | -| `role` | _replies with a message that gives roles when an emote is added_ | _role json_ | admin, admin-role/s | - | -| `run` | _runs the given command string and returns its output_ | _!exec\_command_ | everyone | - | -| `save` | _saves current state of server_ | _none_ | admin, admin-role/s | 5 server | -| `set` | _sets the value of an attribute_ | _!attribute !value_ | voice owner/ portal owner, admin, admin-role/s | - | -| `set_ranks` | _sets roles that will be given when said level reached_ | _rank json_ | voice owner/ portal owner, admin, admin-role/ | 10 servers | -| `setup` | _creates an announcement, spotify, url-only and music channel_ | _none_ | admin, admin-role/s | 10 servers | -| `spotify` | _creates a new or sets the current channel as spotify channel_ | _@channel\_name \| @category\_name_ | admin, | admin-role/s | -| `url` | _creates a new or sets the current channel as url-only_ | _@channel\_name \| @category\_name_ | admin, admin-role/s | - | +| Name | Description | Arguments | Eligible for use | Cooldown (mins) | +| :----------------- | :--------------------------------------------------------------- | :----------------------------------- | :---------------------------------------------------- | :-------------- | +| `about` | _returns an about Portal message_ | _none_ | everyone | - | +| `announce` | _@title \| @body_ | everyone | 1 user | - | +| `announcement` | _creates a new or sets the current channel as announcement_ | _@channel\_name \| @category\_name_ | admin, portal-admins | admin-role/s | +| `authorise` | _add role to admin roles_ | _!role_ | admin, portal-admins, admin-roles | - | +| `authorised_roles` | _displayes all authorised roles_ | none | everyone | - | +| `corona` | _replies with the daily state of corona virus cases_ | _@country code (gr, de, us, etc)_ | everyone | - | +| `deauthorise` | _removes role from admin roles_ | _!role_ | admin, portal-admins, admin-roles | - | +| `delete` | _deletes x number of messsages on the text channel_ | _!number of messages to delete_ | admin, portal-admins, admin-roles | - | +| `focus` | _creates focus channel for you and your requested user_ | _!username @time (default 5minutes)_ | everyone | - | +| `force` | _clones current channel in order to force-update name_ | _none_ | admin, portal-admins, admin-roles | 2 user | +| `help` | _returns a help-list if specified returns specific description_ | _@command/@vrbl/@func/@pipe/@attr_ | everyone | - | +| `join` | _joins current voice channel and announces events_ | _none_ | everyone | 1 user | +| `joke` | _replies with a joke_ | _@category_ | everyone | 1 user | +| `leaderboard` | _replies with the top 10 leaderboard_ | _@number of members | everyone | - | +| `leave` | _removes Portal from voice channel_ | _none_ | everyone | - | +| `level` | _returns your level_ | _none_ | everyone | - | +| `music` | _creates a new or sets the current channel as music channel_ | _@channel\_name \| @category\_name_ | admin, portal-admins, admin-roles | - | +| `ping` | _returns round trip latency_ | _none_ | everyone | - | +| `portal` | _creates a portal voice channel_ | _!channel\_name \| @category\_name_ | admin, portal-admins, admin-roles | - | +| `ranks` | _returns ranks of ranking system_ | _none_ | everyone | - | +| `role_assigner` | _replies with a message that gives roles when an emote is added_ | _role json_ | admin, portal-admins, admin-roles | - | +| `roll` | _roll follows the same philosophy as in roll20_ | __ | everyone | - | +| `run` | _runs the given command string and returns its output_ | _!exec\_command_ | everyone | - | +| `save` | _saves current state of server_ | _none_ | admin, portal-admins, admin-roles | 5 server | +| `set_ranks` | _sets roles that will be given when said level reached_ | _rank json_ | voice-portal owner, admin, portal-admins, admin-role | 10 servers | +| `set` | _sets the value of an attribute_ | _!attribute !value_ | voice-portal owner, admin, portal-admins, admin-roles | - | +| `setup` | _creates an announcement, spotify, url-only and music channel_ | _none_ | admin, portal-admins, admin-roles | 10 servers | +| `spotify` | _creates a new or sets the current channel as spotify channel_ | _none_ | none | - | +| `state` | _returns the current state of portal_ | _@channel\_name \| @category\_name_ | admin, portal-admins | admin-role/s | +| `url` | _creates a new or sets the current channel as url-only_ | _@channel\_name \| @category\_name_ | admin, portal-admins, admin-roles | - | +| `weather` | _replies with the current wheather for the requested city_ | _!city_name_ | everyone | - | +| `whoami` | _replies with the your portal stats_ | _none_ | everyone | - | * _(Pipes are applied to variables or strings in order to change their outcome)_ * _(default regex: G$#-P$member_count | $status_list)_ diff --git a/package-lock.json b/package-lock.json index 19a2679d..bd33a84e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,8387 +1,8 @@ { "name": "portal", "version": "1.2.1", - "lockfileVersion": 2, + "lockfileVersion": 1, "requires": true, - "packages": { - "": { - "name": "portal", - "version": "1.2.1", - "dependencies": { - "@discordjs/opus": "^0.3.3", - "discord-ytdl-core": "^5.0.0", - "discord.js": "^12.5.1", - "ffmpeg-static": "^4.2.7", - "file-system": "^2.2.2", - "give-me-a-joke": "^0.4.0", - "jest": "^26.6.3", - "jest-discordjs-mocks": "^1.0.2", - "lodash": "^4.17.20", - "moment": "^2.29.1", - "roll": "^1.3.1", - "voca": "^1.4.0", - "yt-search": "^2.5.1", - "ytdl-core": "^4.2.1" - }, - "devDependencies": { - "@types/node": "^10.17.50", - "eslint": "^7.16.0", - "nodemon": "^2.0.6" - } - }, - "node_modules/@babel/code-frame": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", - "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", - "dependencies": { - "@babel/highlight": "^7.10.4" - } - }, - "node_modules/@babel/core": { - "version": "7.12.10", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.12.10.tgz", - "integrity": "sha512-eTAlQKq65zHfkHZV0sIVODCPGVgoo1HdBlbSLi9CqOzuZanMv2ihzY+4paiKr1mH+XmYESMAmJ/dpZ68eN6d8w==", - "dependencies": { - "@babel/code-frame": "^7.10.4", - "@babel/generator": "^7.12.10", - "@babel/helper-module-transforms": "^7.12.1", - "@babel/helpers": "^7.12.5", - "@babel/parser": "^7.12.10", - "@babel/template": "^7.12.7", - "@babel/traverse": "^7.12.10", - "@babel/types": "^7.12.10", - "convert-source-map": "^1.7.0", - "debug": "^4.1.0", - "gensync": "^1.0.0-beta.1", - "json5": "^2.1.2", - "lodash": "^4.17.19", - "semver": "^5.4.1", - "source-map": "^0.5.0" - }, - "engines": { - "node": ">=6.9.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/babel" - } - }, - "node_modules/@babel/core/node_modules/semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "bin": { - "semver": "bin/semver" - } - }, - "node_modules/@babel/core/node_modules/source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/@babel/generator": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.12.11.tgz", - "integrity": "sha512-Ggg6WPOJtSi8yYQvLVjG8F/TlpWDlKx0OpS4Kt+xMQPs5OaGYWy+v1A+1TvxI6sAMGZpKWWoAQ1DaeQbImlItA==", - "dependencies": { - "@babel/types": "^7.12.11", - "jsesc": "^2.5.1", - "source-map": "^0.5.0" - } - }, - "node_modules/@babel/generator/node_modules/source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/@babel/helper-function-name": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.12.11.tgz", - "integrity": "sha512-AtQKjtYNolKNi6nNNVLQ27CP6D9oFR6bq/HPYSizlzbp7uC1M59XJe8L+0uXjbIaZaUJF99ruHqVGiKXU/7ybA==", - "dependencies": { - "@babel/helper-get-function-arity": "^7.12.10", - "@babel/template": "^7.12.7", - "@babel/types": "^7.12.11" - } - }, - "node_modules/@babel/helper-get-function-arity": { - "version": "7.12.10", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.12.10.tgz", - "integrity": "sha512-mm0n5BPjR06wh9mPQaDdXWDoll/j5UpCAPl1x8fS71GHm7HA6Ua2V4ylG1Ju8lvcTOietbPNNPaSilKj+pj+Ag==", - "dependencies": { - "@babel/types": "^7.12.10" - } - }, - "node_modules/@babel/helper-member-expression-to-functions": { - "version": "7.12.7", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.12.7.tgz", - "integrity": "sha512-DCsuPyeWxeHgh1Dus7APn7iza42i/qXqiFPWyBDdOFtvS581JQePsc1F/nD+fHrcswhLlRc2UpYS1NwERxZhHw==", - "dependencies": { - "@babel/types": "^7.12.7" - } - }, - "node_modules/@babel/helper-module-imports": { - "version": "7.12.5", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.12.5.tgz", - "integrity": "sha512-SR713Ogqg6++uexFRORf/+nPXMmWIn80TALu0uaFb+iQIUoR7bOC7zBWyzBs5b3tBBJXuyD0cRu1F15GyzjOWA==", - "dependencies": { - "@babel/types": "^7.12.5" - } - }, - "node_modules/@babel/helper-module-transforms": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.12.1.tgz", - "integrity": "sha512-QQzehgFAZ2bbISiCpmVGfiGux8YVFXQ0abBic2Envhej22DVXV9nCFaS5hIQbkyo1AdGb+gNME2TSh3hYJVV/w==", - "dependencies": { - "@babel/helper-module-imports": "^7.12.1", - "@babel/helper-replace-supers": "^7.12.1", - "@babel/helper-simple-access": "^7.12.1", - "@babel/helper-split-export-declaration": "^7.11.0", - "@babel/helper-validator-identifier": "^7.10.4", - "@babel/template": "^7.10.4", - "@babel/traverse": "^7.12.1", - "@babel/types": "^7.12.1", - "lodash": "^4.17.19" - } - }, - "node_modules/@babel/helper-optimise-call-expression": { - "version": "7.12.10", - "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.12.10.tgz", - "integrity": "sha512-4tpbU0SrSTjjt65UMWSrUOPZTsgvPgGG4S8QSTNHacKzpS51IVWGDj0yCwyeZND/i+LSN2g/O63jEXEWm49sYQ==", - "dependencies": { - "@babel/types": "^7.12.10" - } - }, - "node_modules/@babel/helper-plugin-utils": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.4.tgz", - "integrity": "sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg==" - }, - "node_modules/@babel/helper-replace-supers": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.12.11.tgz", - "integrity": "sha512-q+w1cqmhL7R0FNzth/PLLp2N+scXEK/L2AHbXUyydxp828F4FEa5WcVoqui9vFRiHDQErj9Zof8azP32uGVTRA==", - "dependencies": { - "@babel/helper-member-expression-to-functions": "^7.12.7", - "@babel/helper-optimise-call-expression": "^7.12.10", - "@babel/traverse": "^7.12.10", - "@babel/types": "^7.12.11" - } - }, - "node_modules/@babel/helper-simple-access": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.12.1.tgz", - "integrity": "sha512-OxBp7pMrjVewSSC8fXDFrHrBcJATOOFssZwv16F3/6Xtc138GHybBfPbm9kfiqQHKhYQrlamWILwlDCeyMFEaA==", - "dependencies": { - "@babel/types": "^7.12.1" - } - }, - "node_modules/@babel/helper-split-export-declaration": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.12.11.tgz", - "integrity": "sha512-LsIVN8j48gHgwzfocYUSkO/hjYAOJqlpJEc7tGXcIm4cubjVUf8LGW6eWRyxEu7gA25q02p0rQUWoCI33HNS5g==", - "dependencies": { - "@babel/types": "^7.12.11" - } - }, - "node_modules/@babel/helper-validator-identifier": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz", - "integrity": "sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw==" - }, - "node_modules/@babel/helpers": { - "version": "7.12.5", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.12.5.tgz", - "integrity": "sha512-lgKGMQlKqA8meJqKsW6rUnc4MdUk35Ln0ATDqdM1a/UpARODdI4j5Y5lVfUScnSNkJcdCRAaWkspykNoFg9sJA==", - "dependencies": { - "@babel/template": "^7.10.4", - "@babel/traverse": "^7.12.5", - "@babel/types": "^7.12.5" - } - }, - "node_modules/@babel/highlight": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.4.tgz", - "integrity": "sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA==", - "dependencies": { - "@babel/helper-validator-identifier": "^7.10.4", - "chalk": "^2.0.0", - "js-tokens": "^4.0.0" - } - }, - "node_modules/@babel/highlight/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/highlight/node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/highlight/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/@babel/highlight/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" - }, - "node_modules/@babel/highlight/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/highlight/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/parser": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.12.11.tgz", - "integrity": "sha512-N3UxG+uuF4CMYoNj8AhnbAcJF0PiuJ9KHuy1lQmkYsxTer/MAH9UBNHsBoAX/4s6NvlDD047No8mYVGGzLL4hg==", - "bin": { - "parser": "bin/babel-parser.js" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@babel/plugin-syntax-async-generators": { - "version": "7.8.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", - "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-bigint": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz", - "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-class-properties": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.1.tgz", - "integrity": "sha512-U40A76x5gTwmESz+qiqssqmeEsKvcSyvtgktrm0uzcARAmM9I1jR221f6Oq+GmHrcD+LvZDag1UTOTe2fL3TeA==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-import-meta": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", - "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-json-strings": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", - "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-logical-assignment-operators": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", - "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-nullish-coalescing-operator": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", - "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-numeric-separator": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", - "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-object-rest-spread": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", - "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-optional-catch-binding": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", - "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-optional-chaining": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", - "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-top-level-await": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.12.1.tgz", - "integrity": "sha512-i7ooMZFS+a/Om0crxZodrTzNEPJHZrlMVGMTEpFAj6rYY/bKCddB0Dk/YxfPuYXOopuhKk/e1jV6h+WUU9XN3A==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/template": { - "version": "7.12.7", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.12.7.tgz", - "integrity": "sha512-GkDzmHS6GV7ZeXfJZ0tLRBhZcMcY0/Lnb+eEbXDBfCAcZCjrZKe6p3J4we/D24O9Y8enxWAg1cWwof59yLh2ow==", - "dependencies": { - "@babel/code-frame": "^7.10.4", - "@babel/parser": "^7.12.7", - "@babel/types": "^7.12.7" - } - }, - "node_modules/@babel/traverse": { - "version": "7.12.12", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.12.12.tgz", - "integrity": "sha512-s88i0X0lPy45RrLM8b9mz8RPH5FqO9G9p7ti59cToE44xFm1Q+Pjh5Gq4SXBbtb88X7Uy7pexeqRIQDDMNkL0w==", - "dependencies": { - "@babel/code-frame": "^7.12.11", - "@babel/generator": "^7.12.11", - "@babel/helper-function-name": "^7.12.11", - "@babel/helper-split-export-declaration": "^7.12.11", - "@babel/parser": "^7.12.11", - "@babel/types": "^7.12.12", - "debug": "^4.1.0", - "globals": "^11.1.0", - "lodash": "^4.17.19" - } - }, - "node_modules/@babel/traverse/node_modules/globals": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/types": { - "version": "7.12.12", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.12.tgz", - "integrity": "sha512-lnIX7piTxOH22xE7fDXDbSHg9MM1/6ORnafpJmov5rs0kX5g4BZxeXNJLXsMRiO0U5Rb8/FvMS6xlTnTHvxonQ==", - "dependencies": { - "@babel/helper-validator-identifier": "^7.12.11", - "lodash": "^4.17.19", - "to-fast-properties": "^2.0.0" - } - }, - "node_modules/@bcoe/v8-coverage": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", - "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==" - }, - "node_modules/@cnakazawa/watch": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@cnakazawa/watch/-/watch-1.0.4.tgz", - "integrity": "sha512-v9kIhKwjeZThiWrLmj0y17CWoyddASLj9O2yvbZkbvw/N3rWOYy9zkV66ursAoVr0mV15bL8g0c4QZUE6cdDoQ==", - "dependencies": { - "exec-sh": "^0.3.2", - "minimist": "^1.2.0" - }, - "bin": { - "watch": "cli.js" - }, - "engines": { - "node": ">=0.1.95" - } - }, - "node_modules/@derhuerst/http-basic": { - "version": "8.2.1", - "resolved": "https://registry.npmjs.org/@derhuerst/http-basic/-/http-basic-8.2.1.tgz", - "integrity": "sha512-Rmn7qQQulw2sxJ8qGfZ7OuqMWuhz8V+L5xnYKMF5cXVcYqmgWqlVEAme90pF7Ya8OVhxVxLmhh0rI2k6t7ITWw==", - "dependencies": { - "caseless": "^0.12.0", - "concat-stream": "^1.6.2", - "http-response-object": "^3.0.1", - "parse-cache-control": "^1.0.1" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@discordjs/collection": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/@discordjs/collection/-/collection-0.1.6.tgz", - "integrity": "sha512-utRNxnd9kSS2qhyivo9lMlt5qgAUasH2gb7BEOn6p0efFh24gjGomHzWKMAPn2hEReOPQZCJaRKoURwRotKucQ==" - }, - "node_modules/@discordjs/form-data": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@discordjs/form-data/-/form-data-3.0.1.tgz", - "integrity": "sha512-ZfFsbgEXW71Rw/6EtBdrP5VxBJy4dthyC0tpQKGKmYFImlmmrykO14Za+BiIVduwjte0jXEBlhSKf0MWbFp9Eg==", - "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "mime-types": "^2.1.12" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/@discordjs/node-pre-gyp": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/@discordjs/node-pre-gyp/-/node-pre-gyp-0.1.0.tgz", - "integrity": "sha512-6u3EbK2x+j9bM3iK9/pE7BWLxOXZ1PvcsbDo3ZBdPocu95qPHj8zCVsBBk3Cao7V6o8QpwxUyJl6oVJ6T3ZgAg==", - "dependencies": { - "detect-libc": "^1.0.3", - "mkdirp": "^0.5.5", - "needle": "^2.4.1", - "nopt": "^4.0.3", - "npm-packlist": "^1.4.8", - "npmlog": "^4.1.2", - "rc": "^1.2.8", - "rimraf": "^3.0.2", - "semver": "^7.3.0", - "tar": "^6.0.2" - }, - "bin": { - "node-pre-gyp": "bin/node-pre-gyp" - } - }, - "node_modules/@discordjs/opus": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/@discordjs/opus/-/opus-0.3.3.tgz", - "integrity": "sha512-n3hUs4RY0K8cz8vJ2GiZE4EdJlexoxs1vGsaft5lZlAnU6wsZfncpv4px+HVOMKN8ddtjriGfsrG4lVkAyZcmQ==", - "hasInstallScript": true, - "dependencies": { - "@discordjs/node-pre-gyp": "^0.1.0", - "node-addon-api": "^3.0.2" - } - }, - "node_modules/@eslint/eslintrc": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.2.2.tgz", - "integrity": "sha512-EfB5OHNYp1F4px/LI/FEnGylop7nOqkQ1LRzCM0KccA2U8tvV8w01KBv37LbO7nW4H+YhKyo2LcJhRwjjV17QQ==", - "dev": true, - "dependencies": { - "ajv": "^6.12.4", - "debug": "^4.1.1", - "espree": "^7.3.0", - "globals": "^12.1.0", - "ignore": "^4.0.6", - "import-fresh": "^3.2.1", - "js-yaml": "^3.13.1", - "lodash": "^4.17.19", - "minimatch": "^3.0.4", - "strip-json-comments": "^3.1.1" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, - "node_modules/@istanbuljs/load-nyc-config": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", - "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", - "dependencies": { - "camelcase": "^5.3.1", - "find-up": "^4.1.0", - "get-package-type": "^0.1.0", - "js-yaml": "^3.13.1", - "resolve-from": "^5.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", - "engines": { - "node": ">=8" - } - }, - "node_modules/@istanbuljs/schema": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.2.tgz", - "integrity": "sha512-tsAQNx32a8CoFhjhijUIhI4kccIAgmGhy8LZMZgGfmXcpMbPRUqn5LWmgRttILi6yeGmBJd2xsPkFMs0PzgPCw==", - "engines": { - "node": ">=8" - } - }, - "node_modules/@jest/console": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-26.6.2.tgz", - "integrity": "sha512-IY1R2i2aLsLr7Id3S6p2BA82GNWryt4oSvEXLAKc+L2zdi89dSkE8xC1C+0kpATG4JhBJREnQOH7/zmccM2B0g==", - "dependencies": { - "@jest/types": "^26.6.2", - "@types/node": "*", - "chalk": "^4.0.0", - "jest-message-util": "^26.6.2", - "jest-util": "^26.6.2", - "slash": "^3.0.0" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/@jest/core": { - "version": "26.6.3", - "resolved": "https://registry.npmjs.org/@jest/core/-/core-26.6.3.tgz", - "integrity": "sha512-xvV1kKbhfUqFVuZ8Cyo+JPpipAHHAV3kcDBftiduK8EICXmTFddryy3P7NfZt8Pv37rA9nEJBKCCkglCPt/Xjw==", - "dependencies": { - "@jest/console": "^26.6.2", - "@jest/reporters": "^26.6.2", - "@jest/test-result": "^26.6.2", - "@jest/transform": "^26.6.2", - "@jest/types": "^26.6.2", - "@types/node": "*", - "ansi-escapes": "^4.2.1", - "chalk": "^4.0.0", - "exit": "^0.1.2", - "graceful-fs": "^4.2.4", - "jest-changed-files": "^26.6.2", - "jest-config": "^26.6.3", - "jest-haste-map": "^26.6.2", - "jest-message-util": "^26.6.2", - "jest-regex-util": "^26.0.0", - "jest-resolve": "^26.6.2", - "jest-resolve-dependencies": "^26.6.3", - "jest-runner": "^26.6.3", - "jest-runtime": "^26.6.3", - "jest-snapshot": "^26.6.2", - "jest-util": "^26.6.2", - "jest-validate": "^26.6.2", - "jest-watcher": "^26.6.2", - "micromatch": "^4.0.2", - "p-each-series": "^2.1.0", - "rimraf": "^3.0.0", - "slash": "^3.0.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/@jest/environment": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-26.6.2.tgz", - "integrity": "sha512-nFy+fHl28zUrRsCeMB61VDThV1pVTtlEokBRgqPrcT1JNq4yRNIyTHfyht6PqtUvY9IsuLGTrbG8kPXjSZIZwA==", - "dependencies": { - "@jest/fake-timers": "^26.6.2", - "@jest/types": "^26.6.2", - "@types/node": "*", - "jest-mock": "^26.6.2" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/@jest/fake-timers": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-26.6.2.tgz", - "integrity": "sha512-14Uleatt7jdzefLPYM3KLcnUl1ZNikaKq34enpb5XG9i81JpppDb5muZvonvKyrl7ftEHkKS5L5/eB/kxJ+bvA==", - "dependencies": { - "@jest/types": "^26.6.2", - "@sinonjs/fake-timers": "^6.0.1", - "@types/node": "*", - "jest-message-util": "^26.6.2", - "jest-mock": "^26.6.2", - "jest-util": "^26.6.2" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/@jest/globals": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-26.6.2.tgz", - "integrity": "sha512-85Ltnm7HlB/KesBUuALwQ68YTU72w9H2xW9FjZ1eL1U3lhtefjjl5c2MiUbpXt/i6LaPRvoOFJ22yCBSfQ0JIA==", - "dependencies": { - "@jest/environment": "^26.6.2", - "@jest/types": "^26.6.2", - "expect": "^26.6.2" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/@jest/reporters": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-26.6.2.tgz", - "integrity": "sha512-h2bW53APG4HvkOnVMo8q3QXa6pcaNt1HkwVsOPMBV6LD/q9oSpxNSYZQYkAnjdMjrJ86UuYeLo+aEZClV6opnw==", - "dependencies": { - "@bcoe/v8-coverage": "^0.2.3", - "@jest/console": "^26.6.2", - "@jest/test-result": "^26.6.2", - "@jest/transform": "^26.6.2", - "@jest/types": "^26.6.2", - "chalk": "^4.0.0", - "collect-v8-coverage": "^1.0.0", - "exit": "^0.1.2", - "glob": "^7.1.2", - "graceful-fs": "^4.2.4", - "istanbul-lib-coverage": "^3.0.0", - "istanbul-lib-instrument": "^4.0.3", - "istanbul-lib-report": "^3.0.0", - "istanbul-lib-source-maps": "^4.0.0", - "istanbul-reports": "^3.0.2", - "jest-haste-map": "^26.6.2", - "jest-resolve": "^26.6.2", - "jest-util": "^26.6.2", - "jest-worker": "^26.6.2", - "node-notifier": "^8.0.0", - "slash": "^3.0.0", - "source-map": "^0.6.0", - "string-length": "^4.0.1", - "terminal-link": "^2.0.0", - "v8-to-istanbul": "^7.0.0" - }, - "engines": { - "node": ">= 10.14.2" - }, - "optionalDependencies": { - "node-notifier": "^8.0.0" - } - }, - "node_modules/@jest/source-map": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-26.6.2.tgz", - "integrity": "sha512-YwYcCwAnNmOVsZ8mr3GfnzdXDAl4LaenZP5z+G0c8bzC9/dugL8zRmxZzdoTl4IaS3CryS1uWnROLPFmb6lVvA==", - "dependencies": { - "callsites": "^3.0.0", - "graceful-fs": "^4.2.4", - "source-map": "^0.6.0" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/@jest/test-result": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-26.6.2.tgz", - "integrity": "sha512-5O7H5c/7YlojphYNrK02LlDIV2GNPYisKwHm2QTKjNZeEzezCbwYs9swJySv2UfPMyZ0VdsmMv7jIlD/IKYQpQ==", - "dependencies": { - "@jest/console": "^26.6.2", - "@jest/types": "^26.6.2", - "@types/istanbul-lib-coverage": "^2.0.0", - "collect-v8-coverage": "^1.0.0" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/@jest/test-sequencer": { - "version": "26.6.3", - "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-26.6.3.tgz", - "integrity": "sha512-YHlVIjP5nfEyjlrSr8t/YdNfU/1XEt7c5b4OxcXCjyRhjzLYu/rO69/WHPuYcbCWkz8kAeZVZp2N2+IOLLEPGw==", - "dependencies": { - "@jest/test-result": "^26.6.2", - "graceful-fs": "^4.2.4", - "jest-haste-map": "^26.6.2", - "jest-runner": "^26.6.3", - "jest-runtime": "^26.6.3" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/@jest/transform": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-26.6.2.tgz", - "integrity": "sha512-E9JjhUgNzvuQ+vVAL21vlyfy12gP0GhazGgJC4h6qUt1jSdUXGWJ1wfu/X7Sd8etSgxV4ovT1pb9v5D6QW4XgA==", - "dependencies": { - "@babel/core": "^7.1.0", - "@jest/types": "^26.6.2", - "babel-plugin-istanbul": "^6.0.0", - "chalk": "^4.0.0", - "convert-source-map": "^1.4.0", - "fast-json-stable-stringify": "^2.0.0", - "graceful-fs": "^4.2.4", - "jest-haste-map": "^26.6.2", - "jest-regex-util": "^26.0.0", - "jest-util": "^26.6.2", - "micromatch": "^4.0.2", - "pirates": "^4.0.1", - "slash": "^3.0.0", - "source-map": "^0.6.1", - "write-file-atomic": "^3.0.0" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/@jest/types": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", - "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", - "dependencies": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^15.0.0", - "chalk": "^4.0.0" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/@sindresorhus/is": { - "version": "0.14.0", - "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz", - "integrity": "sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/@sinonjs/commons": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.1.tgz", - "integrity": "sha512-892K+kWUUi3cl+LlqEWIDrhvLgdL79tECi8JZUyq6IviKy/DNhuzCRlbHUjxK89f4ypPMMaFnFuR9Ie6DoIMsw==", - "dependencies": { - "type-detect": "4.0.8" - } - }, - "node_modules/@sinonjs/fake-timers": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-6.0.1.tgz", - "integrity": "sha512-MZPUxrmFubI36XS1DI3qmI0YdN1gks62JtFZvxR67ljjSNCeK6U08Zx4msEWOXuofgqUt6zPHSi1H9fbjR/NRA==", - "dependencies": { - "@sinonjs/commons": "^1.7.0" - } - }, - "node_modules/@szmarczak/http-timer": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-1.1.2.tgz", - "integrity": "sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA==", - "dev": true, - "dependencies": { - "defer-to-connect": "^1.0.1" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/@types/babel__core": { - "version": "7.1.12", - "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.12.tgz", - "integrity": "sha512-wMTHiiTiBAAPebqaPiPDLFA4LYPKr6Ph0Xq/6rq1Ur3v66HXyG+clfR9CNETkD7MQS8ZHvpQOtA53DLws5WAEQ==", - "dependencies": { - "@babel/parser": "^7.1.0", - "@babel/types": "^7.0.0", - "@types/babel__generator": "*", - "@types/babel__template": "*", - "@types/babel__traverse": "*" - } - }, - "node_modules/@types/babel__generator": { - "version": "7.6.2", - "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.2.tgz", - "integrity": "sha512-MdSJnBjl+bdwkLskZ3NGFp9YcXGx5ggLpQQPqtgakVhsWK0hTtNYhjpZLlWQTviGTvF8at+Bvli3jV7faPdgeQ==", - "dependencies": { - "@babel/types": "^7.0.0" - } - }, - "node_modules/@types/babel__template": { - "version": "7.4.0", - "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.0.tgz", - "integrity": "sha512-NTPErx4/FiPCGScH7foPyr+/1Dkzkni+rHiYHHoTjvwou7AQzJkNeD60A9CXRy+ZEN2B1bggmkTMCDb+Mv5k+A==", - "dependencies": { - "@babel/parser": "^7.1.0", - "@babel/types": "^7.0.0" - } - }, - "node_modules/@types/babel__traverse": { - "version": "7.11.0", - "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.11.0.tgz", - "integrity": "sha512-kSjgDMZONiIfSH1Nxcr5JIRMwUetDki63FSQfpTCz8ogF3Ulqm8+mr5f78dUYs6vMiB6gBusQqfQmBvHZj/lwg==", - "dependencies": { - "@babel/types": "^7.3.0" - } - }, - "node_modules/@types/graceful-fs": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.4.tgz", - "integrity": "sha512-mWA/4zFQhfvOA8zWkXobwJvBD7vzcxgrOQ0J5CH1votGqdq9m7+FwtGaqyCZqC3NyyBkc9z4m+iry4LlqcMWJg==", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/istanbul-lib-coverage": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.3.tgz", - "integrity": "sha512-sz7iLqvVUg1gIedBOvlkxPlc8/uVzyS5OwGz1cKjXzkl3FpL3al0crU8YGU1WoHkxn0Wxbw5tyi6hvzJKNzFsw==" - }, - "node_modules/@types/istanbul-lib-report": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", - "integrity": "sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg==", - "dependencies": { - "@types/istanbul-lib-coverage": "*" - } - }, - "node_modules/@types/istanbul-reports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", - "dependencies": { - "@types/istanbul-lib-report": "*" - } - }, - "node_modules/@types/jest": { - "version": "26.0.19", - "resolved": "https://registry.npmjs.org/@types/jest/-/jest-26.0.19.tgz", - "integrity": "sha512-jqHoirTG61fee6v6rwbnEuKhpSKih0tuhqeFbCmMmErhtu3BYlOZaXWjffgOstMM4S/3iQD31lI5bGLTrs97yQ==", - "dependencies": { - "jest-diff": "^26.0.0", - "pretty-format": "^26.0.0" - } - }, - "node_modules/@types/node": { - "version": "10.17.50", - "resolved": "https://registry.npmjs.org/@types/node/-/node-10.17.50.tgz", - "integrity": "sha512-vwX+/ija9xKc/z9VqMCdbf4WYcMTGsI0I/L/6shIF3qXURxZOhPQlPRHtjTpiNhAwn0paMJzlOQqw6mAGEQnTA==" - }, - "node_modules/@types/normalize-package-data": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.0.tgz", - "integrity": "sha512-f5j5b/Gf71L+dbqxIpQ4Z2WlmI/mPJ0fOkGGmFgtb6sAu97EPczzbS3/tJKxmcYDj55OX6ssqwDAWOHIYDRDGA==" - }, - "node_modules/@types/prettier": { - "version": "2.1.6", - "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.1.6.tgz", - "integrity": "sha512-6gOkRe7OIioWAXfnO/2lFiv+SJichKVSys1mSsgyrYHSEjk8Ctv4tSR/Odvnu+HWlH2C8j53dahU03XmQdd5fA==" - }, - "node_modules/@types/stack-utils": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.0.tgz", - "integrity": "sha512-RJJrrySY7A8havqpGObOB4W92QXKJo63/jFLLgpvOtsGUqbQZ9Sbgl35KMm1DjC6j7AvmmU2bIno+3IyEaemaw==" - }, - "node_modules/@types/yargs": { - "version": "15.0.12", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.12.tgz", - "integrity": "sha512-f+fD/fQAo3BCbCDlrUpznF1A5Zp9rB0noS5vnoormHSIPFKL0Z2DcUJ3Gxp5ytH4uLRNxy7AwYUC9exZzqGMAw==", - "dependencies": { - "@types/yargs-parser": "*" - } - }, - "node_modules/@types/yargs-parser": { - "version": "20.2.0", - "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-20.2.0.tgz", - "integrity": "sha512-37RSHht+gzzgYeobbG+KWryeAW8J33Nhr69cjTqSYymXVZEN9NbRYWoYlRtDhHKPVT1FyNKwaTPC1NynKZpzRA==" - }, - "node_modules/abab": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.5.tgz", - "integrity": "sha512-9IK9EadsbHo6jLWIpxpR6pL0sazTXV6+SQv25ZB+F7Bj9mJNaOc4nCRabwd5M/JwmUa8idz6Eci6eKfJryPs6Q==" - }, - "node_modules/abbrev": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", - "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==" - }, - "node_modules/abort-controller": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", - "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", - "dependencies": { - "event-target-shim": "^5.0.0" - }, - "engines": { - "node": ">=6.5" - } - }, - "node_modules/acorn": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", - "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/acorn-globals": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-6.0.0.tgz", - "integrity": "sha512-ZQl7LOWaF5ePqqcX4hLuv/bLXYQNfNWw2c0/yX/TsPRKamzHcTGQnlCjHT3TsmkOUVEPS3crCxiPfdzE/Trlhg==", - "dependencies": { - "acorn": "^7.1.1", - "acorn-walk": "^7.1.1" - } - }, - "node_modules/acorn-jsx": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.1.tgz", - "integrity": "sha512-K0Ptm/47OKfQRpNQ2J/oIN/3QYiK6FwW+eJbILhsdxh2WTLdl+30o8aGdTbm5JbffpFFAg/g+zi1E+jvJha5ng==", - "dev": true, - "peerDependencies": { - "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" - } - }, - "node_modules/acorn-walk": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.2.0.tgz", - "integrity": "sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==", - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/agent-base": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", - "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", - "dependencies": { - "debug": "4" - }, - "engines": { - "node": ">= 6.0.0" - } - }, - "node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/ansi-align": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.0.tgz", - "integrity": "sha512-ZpClVKqXN3RGBmKibdfWzqCY4lnjEuoNzU5T0oEFpfd/z5qJHVarukridD4juLO2FXMiwUQxr9WqQtaYa8XRYw==", - "dev": true, - "dependencies": { - "string-width": "^3.0.0" - } - }, - "node_modules/ansi-align/node_modules/ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/ansi-align/node_modules/is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/ansi-align/node_modules/string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "dependencies": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/ansi-align/node_modules/strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "dependencies": { - "ansi-regex": "^4.1.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/ansi-colors": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", - "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/ansi-escapes": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.1.tgz", - "integrity": "sha512-JWF7ocqNrp8u9oqpgV+wH5ftbt+cfvv+PTjOvKLT3AdYly/LmORARfEVT1iyjwN+4MqE5UmVKoAdIBqeoCHgLA==", - "dependencies": { - "type-fest": "^0.11.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/ansi-escapes/node_modules/type-fest": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.11.0.tgz", - "integrity": "sha512-OdjXJxnCN1AvyLSzeKIgXTXxV+99ZuXl3Hpo9XpJAv9MBcHrrJOQ5kV7ypXOuQie+AmWG25hLbiKdwYTifzcfQ==", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/ansi-regex": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", - "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", - "engines": { - "node": ">=8" - } - }, - "node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/anymatch": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", - "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==", - "dependencies": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/aproba": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", - "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==" - }, - "node_modules/are-we-there-yet": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz", - "integrity": "sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w==", - "dependencies": { - "delegates": "^1.0.0", - "readable-stream": "^2.0.6" - } - }, - "node_modules/argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dependencies": { - "sprintf-js": "~1.0.2" - } - }, - "node_modules/arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/arr-flatten": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", - "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/arr-union": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", - "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/asn1": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", - "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", - "dependencies": { - "safer-buffer": "~2.1.0" - } - }, - "node_modules/assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", - "engines": { - "node": ">=0.8" - } - }, - "node_modules/assign-symbols": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", - "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/astral-regex": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", - "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/async.parallellimit": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/async.parallellimit/-/async.parallellimit-0.5.2.tgz", - "integrity": "sha1-v9y/Lwgy8f/0wLM1S09jIGY91R8=", - "dependencies": { - "async.util.eachoflimit": "0.5.2", - "async.util.parallel": "0.5.2" - } - }, - "node_modules/async.util.eachoflimit": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/async.util.eachoflimit/-/async.util.eachoflimit-0.5.2.tgz", - "integrity": "sha1-i4y4z7AniqXOtQqPgAwcJmjbV+8=", - "dependencies": { - "async.util.keyiterator": "0.5.2", - "async.util.noop": "0.5.2", - "async.util.once": "0.5.2", - "async.util.onlyonce": "0.5.2" - } - }, - "node_modules/async.util.isarray": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/async.util.isarray/-/async.util.isarray-0.5.2.tgz", - "integrity": "sha1-5i2sjyY29lh13PdSHC0k0N+yu98=" - }, - "node_modules/async.util.isarraylike": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/async.util.isarraylike/-/async.util.isarraylike-0.5.2.tgz", - "integrity": "sha1-jn+H2pFB8vCZboBAR30NTv4/UPg=", - "dependencies": { - "async.util.isarray": "0.5.2" - } - }, - "node_modules/async.util.keyiterator": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/async.util.keyiterator/-/async.util.keyiterator-0.5.2.tgz", - "integrity": "sha1-M55s6PidAAQz+3gU4ico8/F1CQ0=", - "dependencies": { - "async.util.isarraylike": "0.5.2", - "async.util.keys": "0.5.2" - } - }, - "node_modules/async.util.keys": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/async.util.keys/-/async.util.keys-0.5.2.tgz", - "integrity": "sha1-XDTd2KPtt6eIPJtf4hJngbIJivY=" - }, - "node_modules/async.util.noop": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/async.util.noop/-/async.util.noop-0.5.2.tgz", - "integrity": "sha1-vdYrl8sKo/YLWGrRSEaGmJdeWLk=" - }, - "node_modules/async.util.once": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/async.util.once/-/async.util.once-0.5.2.tgz", - "integrity": "sha1-FFPLdATK0IImlPq6vEepblyqchY=" - }, - "node_modules/async.util.onlyonce": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/async.util.onlyonce/-/async.util.onlyonce-0.5.2.tgz", - "integrity": "sha1-uOb8AErckjFk154y8oE+5GXCT/I=" - }, - "node_modules/async.util.parallel": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/async.util.parallel/-/async.util.parallel-0.5.2.tgz", - "integrity": "sha1-IzUk49b6/9XplddUdrjZJPloCM0=", - "dependencies": { - "async.util.isarraylike": "0.5.2", - "async.util.noop": "0.5.2", - "async.util.restparam": "0.5.2" - } - }, - "node_modules/async.util.restparam": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/async.util.restparam/-/async.util.restparam-0.5.2.tgz", - "integrity": "sha1-A+/r88Ane5ciDlJaunUPXgT8gM0=" - }, - "node_modules/asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" - }, - "node_modules/atob": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", - "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", - "bin": { - "atob": "bin/atob.js" - }, - "engines": { - "node": ">= 4.5.0" - } - }, - "node_modules/aws-sign2": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", - "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=", - "engines": { - "node": "*" - } - }, - "node_modules/aws4": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.11.0.tgz", - "integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==" - }, - "node_modules/axios": { - "version": "0.19.2", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.19.2.tgz", - "integrity": "sha512-fjgm5MvRHLhx+osE2xoekY70AhARk3a6hkN+3Io1jc00jtquGvxYlKlsFUhmUET0V5te6CcZI7lcv2Ym61mjHA==", - "deprecated": "Critical security vulnerability fixed in v0.21.1. For more information, see https://github.com/axios/axios/pull/3410", - "dependencies": { - "follow-redirects": "1.5.10" - } - }, - "node_modules/babel-jest": { - "version": "26.6.3", - "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-26.6.3.tgz", - "integrity": "sha512-pl4Q+GAVOHwvjrck6jKjvmGhnO3jHX/xuB9d27f+EJZ/6k+6nMuPjorrYp7s++bKKdANwzElBWnLWaObvTnaZA==", - "dependencies": { - "@jest/transform": "^26.6.2", - "@jest/types": "^26.6.2", - "@types/babel__core": "^7.1.7", - "babel-plugin-istanbul": "^6.0.0", - "babel-preset-jest": "^26.6.2", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "slash": "^3.0.0" - }, - "engines": { - "node": ">= 10.14.2" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/babel-plugin-istanbul": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.0.0.tgz", - "integrity": "sha512-AF55rZXpe7trmEylbaE1Gv54wn6rwU03aptvRoVIGP8YykoSxqdVLV1TfwflBCE/QtHmqtP8SWlTENqbK8GCSQ==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.0.0", - "@istanbuljs/load-nyc-config": "^1.0.0", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-instrument": "^4.0.0", - "test-exclude": "^6.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/babel-plugin-jest-hoist": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-26.6.2.tgz", - "integrity": "sha512-PO9t0697lNTmcEHH69mdtYiOIkkOlj9fySqfO3K1eCcdISevLAE0xY59VLLUj0SoiPiTX/JU2CYFpILydUa5Lw==", - "dependencies": { - "@babel/template": "^7.3.3", - "@babel/types": "^7.3.3", - "@types/babel__core": "^7.0.0", - "@types/babel__traverse": "^7.0.6" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/babel-preset-current-node-syntax": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz", - "integrity": "sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ==", - "dependencies": { - "@babel/plugin-syntax-async-generators": "^7.8.4", - "@babel/plugin-syntax-bigint": "^7.8.3", - "@babel/plugin-syntax-class-properties": "^7.8.3", - "@babel/plugin-syntax-import-meta": "^7.8.3", - "@babel/plugin-syntax-json-strings": "^7.8.3", - "@babel/plugin-syntax-logical-assignment-operators": "^7.8.3", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", - "@babel/plugin-syntax-numeric-separator": "^7.8.3", - "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", - "@babel/plugin-syntax-optional-chaining": "^7.8.3", - "@babel/plugin-syntax-top-level-await": "^7.8.3" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/babel-preset-jest": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-26.6.2.tgz", - "integrity": "sha512-YvdtlVm9t3k777c5NPQIv6cxFFFapys25HiUmuSgHwIZhfifweR5c5Sf5nwE3MAbfu327CYSvps8Yx6ANLyleQ==", - "dependencies": { - "babel-plugin-jest-hoist": "^26.6.2", - "babel-preset-current-node-syntax": "^1.0.0" - }, - "engines": { - "node": ">= 10.14.2" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/balanced-match": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" - }, - "node_modules/base": { - "version": "0.11.2", - "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", - "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", - "dependencies": { - "cache-base": "^1.0.1", - "class-utils": "^0.3.5", - "component-emitter": "^1.2.1", - "define-property": "^1.0.0", - "isobject": "^3.0.1", - "mixin-deep": "^1.2.0", - "pascalcase": "^0.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/base/node_modules/define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dependencies": { - "is-descriptor": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/bcrypt-pbkdf": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", - "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", - "dependencies": { - "tweetnacl": "^0.14.3" - } - }, - "node_modules/bcrypt-pbkdf/node_modules/tweetnacl": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" - }, - "node_modules/binary-extensions": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.1.0.tgz", - "integrity": "sha512-1Yj8h9Q+QDF5FzhMs/c9+6UntbD5MkRfRwac8DoEm9ZfUBZ7tZ55YcGVAzEe4bXsdQHEk+s9S5wsOKVdZrw0tQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/boolbase": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", - "integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24=" - }, - "node_modules/boolstring": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/boolstring/-/boolstring-1.0.2.tgz", - "integrity": "sha512-0JLNSmZUv1m/O8sVayFm2t0naiOXwQ9O2Gq9u1eoIkhvu6U5NQER/e3k4BGpjZ33G775lWMT7TzJ7r5VtmEnbQ==" - }, - "node_modules/boxen": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/boxen/-/boxen-4.2.0.tgz", - "integrity": "sha512-eB4uT9RGzg2odpER62bBwSLvUeGC+WbRjjyyFhGsKnc8wp/m0+hQsMUvUe3H2V0D5vw0nBdO1hCJoZo5mKeuIQ==", - "dev": true, - "dependencies": { - "ansi-align": "^3.0.0", - "camelcase": "^5.3.1", - "chalk": "^3.0.0", - "cli-boxes": "^2.2.0", - "string-width": "^4.1.0", - "term-size": "^2.1.0", - "type-fest": "^0.8.1", - "widest-line": "^3.1.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/boxen/node_modules/chalk": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", - "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/boxen/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, - "node_modules/boxen/node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/boxen/node_modules/string-width": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", - "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", - "dev": true, - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dependencies": { - "fill-range": "^7.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/browser-process-hrtime": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz", - "integrity": "sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow==" - }, - "node_modules/bser": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", - "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==", - "dependencies": { - "node-int64": "^0.4.0" - } - }, - "node_modules/buffer-from": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", - "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==" - }, - "node_modules/cache-base": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", - "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", - "dependencies": { - "collection-visit": "^1.0.0", - "component-emitter": "^1.2.1", - "get-value": "^2.0.6", - "has-value": "^1.0.0", - "isobject": "^3.0.1", - "set-value": "^2.0.0", - "to-object-path": "^0.3.0", - "union-value": "^1.0.0", - "unset-value": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/cacheable-request": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-6.1.0.tgz", - "integrity": "sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg==", - "dev": true, - "dependencies": { - "clone-response": "^1.0.2", - "get-stream": "^5.1.0", - "http-cache-semantics": "^4.0.0", - "keyv": "^3.0.0", - "lowercase-keys": "^2.0.0", - "normalize-url": "^4.1.0", - "responselike": "^1.0.2" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/cacheable-request/node_modules/get-stream": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", - "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", - "dev": true, - "dependencies": { - "pump": "^3.0.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/cacheable-request/node_modules/lowercase-keys": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", - "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "engines": { - "node": ">=6" - } - }, - "node_modules/camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "engines": { - "node": ">=6" - } - }, - "node_modules/capture-exit": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/capture-exit/-/capture-exit-2.0.0.tgz", - "integrity": "sha512-PiT/hQmTonHhl/HFGN+Lx3JJUznrVYJ3+AQsnthneZbvW7x+f08Tk7yLJTLEOUvBTbduLeeBkxEaYXUOUrRq6g==", - "dependencies": { - "rsvp": "^4.8.4" - }, - "engines": { - "node": "6.* || 8.* || >= 10.*" - } - }, - "node_modules/caseless": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" - }, - "node_modules/chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/char-regex": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", - "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", - "engines": { - "node": ">=10" - } - }, - "node_modules/cheerio": { - "version": "0.22.0", - "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-0.22.0.tgz", - "integrity": "sha1-qbqoYKP5tZWmuBsahocxIe06Jp4=", - "dependencies": { - "css-select": "~1.2.0", - "dom-serializer": "~0.1.0", - "entities": "~1.1.1", - "htmlparser2": "^3.9.1", - "lodash.assignin": "^4.0.9", - "lodash.bind": "^4.1.4", - "lodash.defaults": "^4.0.1", - "lodash.filter": "^4.4.0", - "lodash.flatten": "^4.2.0", - "lodash.foreach": "^4.3.0", - "lodash.map": "^4.4.0", - "lodash.merge": "^4.4.0", - "lodash.pick": "^4.2.1", - "lodash.reduce": "^4.4.0", - "lodash.reject": "^4.4.0", - "lodash.some": "^4.4.0" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/chokidar": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.4.3.tgz", - "integrity": "sha512-DtM3g7juCXQxFVSNPNByEC2+NImtBuxQQvWlHunpJIS5Ocr0lG306cC7FCi7cEA0fzmybPUIl4txBIobk1gGOQ==", - "dev": true, - "dependencies": { - "anymatch": "~3.1.1", - "braces": "~3.0.2", - "fsevents": "~2.1.2", - "glob-parent": "~5.1.0", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.5.0" - }, - "engines": { - "node": ">= 8.10.0" - }, - "optionalDependencies": { - "fsevents": "~2.1.2" - } - }, - "node_modules/chownr": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", - "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", - "engines": { - "node": ">=10" - } - }, - "node_modules/ci-info": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", - "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==" - }, - "node_modules/cjs-module-lexer": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-0.6.0.tgz", - "integrity": "sha512-uc2Vix1frTfnuzxxu1Hp4ktSvM3QaI4oXl4ZUqL1wjTu/BGki9TrCWoqLTg/drR1KwAEarXuRFCG2Svr1GxPFw==" - }, - "node_modules/class-utils": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", - "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", - "dependencies": { - "arr-union": "^3.1.0", - "define-property": "^0.2.5", - "isobject": "^3.0.0", - "static-extend": "^0.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/class-utils/node_modules/define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dependencies": { - "is-descriptor": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/class-utils/node_modules/is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/class-utils/node_modules/is-accessor-descriptor/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/class-utils/node_modules/is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/class-utils/node_modules/is-data-descriptor/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/class-utils/node_modules/is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dependencies": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/class-utils/node_modules/kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/cli-boxes": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-2.2.1.tgz", - "integrity": "sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw==", - "dev": true, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/cli-color": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/cli-color/-/cli-color-1.2.0.tgz", - "integrity": "sha1-OlrnT9drYmevZm5p4q+70B3vNNE=", - "dependencies": { - "ansi-regex": "^2.1.1", - "d": "1", - "es5-ext": "^0.10.12", - "es6-iterator": "2", - "memoizee": "^0.4.3", - "timers-ext": "0.1" - } - }, - "node_modules/cli-color/node_modules/ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/cliui": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", - "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", - "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^6.2.0" - } - }, - "node_modules/cliui/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" - }, - "node_modules/cliui/node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "engines": { - "node": ">=8" - } - }, - "node_modules/cliui/node_modules/string-width": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", - "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/clone-response": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.2.tgz", - "integrity": "sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws=", - "dev": true, - "dependencies": { - "mimic-response": "^1.0.0" - } - }, - "node_modules/co": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", - "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=", - "engines": { - "iojs": ">= 1.0.0", - "node": ">= 0.12.0" - } - }, - "node_modules/code-point-at": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", - "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/collect-v8-coverage": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.1.tgz", - "integrity": "sha512-iBPtljfCNcTKNAto0KEtDfZ3qzjJvqE3aTGZsbhjSBlorqpXJlaWWtPO35D+ZImoC3KWejX64o+yPGxhWSTzfg==" - }, - "node_modules/collection-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", - "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", - "dependencies": { - "map-visit": "^1.0.0", - "object-visit": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "node_modules/combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "dependencies": { - "delayed-stream": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/component-emitter": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", - "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==" - }, - "node_modules/concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" - }, - "node_modules/concat-stream": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", - "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", - "engines": [ - "node >= 0.8" - ], - "dependencies": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^2.2.2", - "typedarray": "^0.0.6" - } - }, - "node_modules/configstore": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/configstore/-/configstore-5.0.1.tgz", - "integrity": "sha512-aMKprgk5YhBNyH25hj8wGt2+D52Sw1DRRIzqBwLp2Ya9mFmY8KPvvtvmna8SxVR9JMZ4kzMD68N22vlaRpkeFA==", - "dev": true, - "dependencies": { - "dot-prop": "^5.2.0", - "graceful-fs": "^4.1.2", - "make-dir": "^3.0.0", - "unique-string": "^2.0.0", - "write-file-atomic": "^3.0.0", - "xdg-basedir": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/console-control-strings": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", - "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=" - }, - "node_modules/convert-source-map": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz", - "integrity": "sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==", - "dependencies": { - "safe-buffer": "~5.1.1" - } - }, - "node_modules/copy-descriptor": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", - "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" - }, - "node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/crypto-random-string": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-2.0.0.tgz", - "integrity": "sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/css-select": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/css-select/-/css-select-1.2.0.tgz", - "integrity": "sha1-KzoRBTnFNV8c2NMUYj6HCxIeyFg=", - "dependencies": { - "boolbase": "~1.0.0", - "css-what": "2.1", - "domutils": "1.5.1", - "nth-check": "~1.0.1" - } - }, - "node_modules/css-what": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/css-what/-/css-what-2.1.3.tgz", - "integrity": "sha512-a+EPoD+uZiNfh+5fxw2nO9QwFa6nJe2Or35fGY6Ipw1R3R4AGz1d1TEZrCegvw2YTmZ0jXirGYlzxxpYSHwpEg==", - "engines": { - "node": "*" - } - }, - "node_modules/cssom": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.4.4.tgz", - "integrity": "sha512-p3pvU7r1MyyqbTk+WbNJIgJjG2VmTIaB10rI93LzVPrmDJKkzKYMtxxyAvQXR/NS6otuzveI7+7BBq3SjBS2mw==" - }, - "node_modules/cssstyle": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-2.3.0.tgz", - "integrity": "sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A==", - "dependencies": { - "cssom": "~0.3.6" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/cssstyle/node_modules/cssom": { - "version": "0.3.8", - "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz", - "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==" - }, - "node_modules/d": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/d/-/d-1.0.1.tgz", - "integrity": "sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==", - "dependencies": { - "es5-ext": "^0.10.50", - "type": "^1.0.1" - } - }, - "node_modules/dashdash": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", - "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", - "dependencies": { - "assert-plus": "^1.0.0" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/dasu": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/dasu/-/dasu-0.4.1.tgz", - "integrity": "sha512-+fDXmFqrsZfuCr3dwSxm0pyK5RTiIBFBJiWTG6HaZQc9FhoqT4o9KQFEfGllic0S2gEpzHYMirzqJ5qSh+mOrQ==" - }, - "node_modules/data-urls": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-2.0.0.tgz", - "integrity": "sha512-X5eWTSXO/BJmpdIKCRuKUgSCgAN0OwliVK3yPKbwIWU1Tdw5BRajxlzMidvh+gwko9AfQ9zIj52pzF91Q3YAvQ==", - "dependencies": { - "abab": "^2.0.3", - "whatwg-mimetype": "^2.3.0", - "whatwg-url": "^8.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/debug": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", - "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/decimal.js": { - "version": "10.2.1", - "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.2.1.tgz", - "integrity": "sha512-KaL7+6Fw6i5A2XSnsbhm/6B+NuEA7TZ4vqxnd5tXz9sbKtrN9Srj8ab4vKVdK8YAqZO9P1kg45Y6YLoduPf+kw==" - }, - "node_modules/decode-uri-component": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", - "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", - "engines": { - "node": ">=0.10" - } - }, - "node_modules/decompress-response": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz", - "integrity": "sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=", - "dev": true, - "dependencies": { - "mimic-response": "^1.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/deep-extend": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", - "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/deep-is": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", - "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=" - }, - "node_modules/deepmerge": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz", - "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/defer-to-connect": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-1.1.3.tgz", - "integrity": "sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ==", - "dev": true - }, - "node_modules/define-property": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", - "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", - "dependencies": { - "is-descriptor": "^1.0.2", - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/delegates": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", - "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=" - }, - "node_modules/detect-libc": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", - "integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=", - "bin": { - "detect-libc": "bin/detect-libc.js" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/detect-newline": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", - "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==", - "engines": { - "node": ">=8" - } - }, - "node_modules/diff-sequences": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-26.6.2.tgz", - "integrity": "sha512-Mv/TDa3nZ9sbc5soK+OoA74BsS3mL37yixCvUAQkiuA4Wz6YtwP/K47n2rv2ovzHZvoiQeA5FTQOschKkEwB0Q==", - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/discord-ytdl-core": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/discord-ytdl-core/-/discord-ytdl-core-5.0.0.tgz", - "integrity": "sha512-lhk3VabO3vC+57ZIL0yOCaB5eyco9qmygmXwHoAr9c4VVzG9e02iGCvLAYzMIxOoBtuIggavNLwFTZ6gO6byJA==", - "dependencies": { - "prism-media": "^1.2.2" - }, - "funding": { - "type": "individual", - "url": "https://paypal.me/devsnowflake" - } - }, - "node_modules/discord.js": { - "version": "12.5.1", - "resolved": "https://registry.npmjs.org/discord.js/-/discord.js-12.5.1.tgz", - "integrity": "sha512-VwZkVaUAIOB9mKdca0I5MefPMTQJTNg0qdgi1huF3iwsFwJ0L5s/Y69AQe+iPmjuV6j9rtKoG0Ta0n9vgEIL6w==", - "dependencies": { - "@discordjs/collection": "^0.1.6", - "@discordjs/form-data": "^3.0.1", - "abort-controller": "^3.0.0", - "node-fetch": "^2.6.1", - "prism-media": "^1.2.2", - "setimmediate": "^1.0.5", - "tweetnacl": "^1.0.3", - "ws": "^7.3.1" - }, - "engines": { - "node": ">=12.0.0" - } - }, - "node_modules/doctrine": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", - "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", - "dev": true, - "dependencies": { - "esutils": "^2.0.2" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/dom-serializer": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.1.1.tgz", - "integrity": "sha512-l0IU0pPzLWSHBcieZbpOKgkIn3ts3vAh7ZuFyXNwJxJXk/c4Gwj9xaTJwIDVQCXawWD0qb3IzMGH5rglQaO0XA==", - "dependencies": { - "domelementtype": "^1.3.0", - "entities": "^1.1.1" - } - }, - "node_modules/domelementtype": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz", - "integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==" - }, - "node_modules/domexception": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/domexception/-/domexception-2.0.1.tgz", - "integrity": "sha512-yxJ2mFy/sibVQlu5qHjOkf9J3K6zgmCxgJ94u2EdvDOV09H+32LtRswEcUsmUWN72pVLOEnTSRaIVVzVQgS0dg==", - "dependencies": { - "webidl-conversions": "^5.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/domexception/node_modules/webidl-conversions": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-5.0.0.tgz", - "integrity": "sha512-VlZwKPCkYKxQgeSbH5EyngOmRp7Ww7I9rQLERETtf5ofd9pGeswWiOtogpEO850jziPRarreGxn5QIiTqpb2wA==", - "engines": { - "node": ">=8" - } - }, - "node_modules/domhandler": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.4.2.tgz", - "integrity": "sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA==", - "dependencies": { - "domelementtype": "1" - } - }, - "node_modules/domutils": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.5.1.tgz", - "integrity": "sha1-3NhIiib1Y9YQeeSMn3t+Mjc2gs8=", - "dependencies": { - "dom-serializer": "0", - "domelementtype": "1" - } - }, - "node_modules/dot-prop": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz", - "integrity": "sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==", - "dev": true, - "dependencies": { - "is-obj": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/duplexer3": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz", - "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=", - "dev": true - }, - "node_modules/ecc-jsbn": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", - "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", - "dependencies": { - "jsbn": "~0.1.0", - "safer-buffer": "^2.1.0" - } - }, - "node_modules/emittery": { - "version": "0.7.2", - "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.7.2.tgz", - "integrity": "sha512-A8OG5SR/ij3SsJdWDJdkkSYUjQdCUx6APQXem0SaEePBSRg4eymGYwBkKo1Y6DU+af/Jn2dBQqDBvjnr9Vi8nQ==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sindresorhus/emittery?sponsor=1" - } - }, - "node_modules/emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true - }, - "node_modules/end-of-stream": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", - "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", - "dependencies": { - "once": "^1.4.0" - } - }, - "node_modules/enquirer": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", - "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", - "dev": true, - "dependencies": { - "ansi-colors": "^4.1.1" - }, - "engines": { - "node": ">=8.6" - } - }, - "node_modules/entities": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz", - "integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==" - }, - "node_modules/env-paths": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.0.tgz", - "integrity": "sha512-6u0VYSCo/OW6IoD5WCLLy9JUGARbamfSavcNXry/eu8aHVFei6CD3Sw+VGX5alea1i9pgPHW0mbu6Xj0uBh7gA==", - "engines": { - "node": ">=6" - } - }, - "node_modules/error-ex": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", - "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", - "dependencies": { - "is-arrayish": "^0.2.1" - } - }, - "node_modules/es5-ext": { - "version": "0.10.53", - "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.53.tgz", - "integrity": "sha512-Xs2Stw6NiNHWypzRTY1MtaG/uJlwCk8kH81920ma8mvN8Xq1gsfhZvpkImLQArw8AHnv8MT2I45J3c0R8slE+Q==", - "dependencies": { - "es6-iterator": "~2.0.3", - "es6-symbol": "~3.1.3", - "next-tick": "~1.0.0" - } - }, - "node_modules/es6-iterator": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz", - "integrity": "sha1-p96IkUGgWpSwhUQDstCg+/qY87c=", - "dependencies": { - "d": "1", - "es5-ext": "^0.10.35", - "es6-symbol": "^3.1.1" - } - }, - "node_modules/es6-symbol": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.3.tgz", - "integrity": "sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA==", - "dependencies": { - "d": "^1.0.1", - "ext": "^1.1.2" - } - }, - "node_modules/es6-weak-map": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/es6-weak-map/-/es6-weak-map-2.0.3.tgz", - "integrity": "sha512-p5um32HOTO1kP+w7PRnB+5lQ43Z6muuMuIMffvDN8ZB4GcnjLBV6zGStpbASIMk4DCAvEaamhe2zhyCb/QXXsA==", - "dependencies": { - "d": "1", - "es5-ext": "^0.10.46", - "es6-iterator": "^2.0.3", - "es6-symbol": "^3.1.1" - } - }, - "node_modules/escape-goat": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/escape-goat/-/escape-goat-2.1.1.tgz", - "integrity": "sha512-8/uIhbG12Csjy2JEW7D9pHbreaVaS/OpN3ycnyvElTdwM5n6GY6W6e2IPemfvGZeUMqZ9A/3GqIZMgKnBhAw/Q==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/escodegen": { - "version": "1.14.3", - "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.14.3.tgz", - "integrity": "sha512-qFcX0XJkdg+PB3xjZZG/wKSuT1PnQWx57+TVSjIMmILd2yC/6ByYElPwJnslDsuWuSAp4AwJGumarAAmJch5Kw==", - "dependencies": { - "esprima": "^4.0.1", - "estraverse": "^4.2.0", - "esutils": "^2.0.2", - "optionator": "^0.8.1", - "source-map": "~0.6.1" - }, - "bin": { - "escodegen": "bin/escodegen.js", - "esgenerate": "bin/esgenerate.js" - }, - "engines": { - "node": ">=4.0" - }, - "optionalDependencies": { - "source-map": "~0.6.1" - } - }, - "node_modules/escodegen/node_modules/levn": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", - "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", - "dependencies": { - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/escodegen/node_modules/optionator": { - "version": "0.8.3", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", - "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", - "dependencies": { - "deep-is": "~0.1.3", - "fast-levenshtein": "~2.0.6", - "levn": "~0.3.0", - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2", - "word-wrap": "~1.2.3" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/escodegen/node_modules/prelude-ls": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", - "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/escodegen/node_modules/type-check": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", - "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", - "dependencies": { - "prelude-ls": "~1.1.2" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/eslint": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.16.0.tgz", - "integrity": "sha512-iVWPS785RuDA4dWuhhgXTNrGxHHK3a8HLSMBgbbU59ruJDubUraXN8N5rn7kb8tG6sjg74eE0RA3YWT51eusEw==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.0.0", - "@eslint/eslintrc": "^0.2.2", - "ajv": "^6.10.0", - "chalk": "^4.0.0", - "cross-spawn": "^7.0.2", - "debug": "^4.0.1", - "doctrine": "^3.0.0", - "enquirer": "^2.3.5", - "eslint-scope": "^5.1.1", - "eslint-utils": "^2.1.0", - "eslint-visitor-keys": "^2.0.0", - "espree": "^7.3.1", - "esquery": "^1.2.0", - "esutils": "^2.0.2", - "file-entry-cache": "^6.0.0", - "functional-red-black-tree": "^1.0.1", - "glob-parent": "^5.0.0", - "globals": "^12.1.0", - "ignore": "^4.0.6", - "import-fresh": "^3.0.0", - "imurmurhash": "^0.1.4", - "is-glob": "^4.0.0", - "js-yaml": "^3.13.1", - "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.4.1", - "lodash": "^4.17.19", - "minimatch": "^3.0.4", - "natural-compare": "^1.4.0", - "optionator": "^0.9.1", - "progress": "^2.0.0", - "regexpp": "^3.1.0", - "semver": "^7.2.1", - "strip-ansi": "^6.0.0", - "strip-json-comments": "^3.1.0", - "table": "^6.0.4", - "text-table": "^0.2.0", - "v8-compile-cache": "^2.0.3" - }, - "bin": { - "eslint": "bin/eslint.js" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint-scope": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", - "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", - "dev": true, - "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^4.1.1" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/eslint-utils": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", - "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", - "dev": true, - "dependencies": { - "eslint-visitor-keys": "^1.1.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/mysticatea" - } - }, - "node_modules/eslint-utils/node_modules/eslint-visitor-keys": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", - "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/eslint-visitor-keys": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.0.0.tgz", - "integrity": "sha512-QudtT6av5WXels9WjIM7qz1XD1cWGvX4gGXvp/zBn9nXG02D0utdU3Em2m/QjTnrsk6bBjmCygl3rmj118msQQ==", - "dev": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/espree": { - "version": "7.3.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.1.tgz", - "integrity": "sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g==", - "dev": true, - "dependencies": { - "acorn": "^7.4.0", - "acorn-jsx": "^5.3.1", - "eslint-visitor-keys": "^1.3.0" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, - "node_modules/espree/node_modules/eslint-visitor-keys": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", - "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "bin": { - "esparse": "bin/esparse.js", - "esvalidate": "bin/esvalidate.js" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/esquery": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.3.1.tgz", - "integrity": "sha512-olpvt9QG0vniUBZspVRN6lwB7hOZoTRtT+jzR+tS4ffYx2mzbw+z0XCOk44aaLYKApNX5nMm+E+P6o25ip/DHQ==", - "dev": true, - "dependencies": { - "estraverse": "^5.1.0" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/esquery/node_modules/estraverse": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", - "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", - "dev": true, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/esrecurse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", - "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", - "dev": true, - "dependencies": { - "estraverse": "^5.2.0" - }, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/esrecurse/node_modules/estraverse": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", - "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", - "dev": true, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "engines": { - "node": ">=4.0" - } - }, - "node_modules/esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/event-emitter": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz", - "integrity": "sha1-34xp7vFkeSPHFXuc6DhAYQsCzDk=", - "dependencies": { - "d": "1", - "es5-ext": "~0.10.14" - } - }, - "node_modules/event-target-shim": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", - "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", - "engines": { - "node": ">=6" - } - }, - "node_modules/exec-sh": { - "version": "0.3.4", - "resolved": "https://registry.npmjs.org/exec-sh/-/exec-sh-0.3.4.tgz", - "integrity": "sha512-sEFIkc61v75sWeOe72qyrqg2Qg0OuLESziUDk/O/z2qgS15y2gWVFrI6f2Qn/qw/0/NCfCEsmNA4zOjkwEZT1A==" - }, - "node_modules/execa": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-4.1.0.tgz", - "integrity": "sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA==", - "dependencies": { - "cross-spawn": "^7.0.0", - "get-stream": "^5.0.0", - "human-signals": "^1.1.1", - "is-stream": "^2.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^4.0.0", - "onetime": "^5.1.0", - "signal-exit": "^3.0.2", - "strip-final-newline": "^2.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sindresorhus/execa?sponsor=1" - } - }, - "node_modules/execa/node_modules/get-stream": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", - "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", - "dependencies": { - "pump": "^3.0.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/exit": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", - "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=", - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", - "dependencies": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/expand-brackets/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/expand-brackets/node_modules/define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dependencies": { - "is-descriptor": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/expand-brackets/node_modules/extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dependencies": { - "is-extendable": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/expand-brackets/node_modules/is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/expand-brackets/node_modules/is-accessor-descriptor/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/expand-brackets/node_modules/is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/expand-brackets/node_modules/is-data-descriptor/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/expand-brackets/node_modules/is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dependencies": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/expand-brackets/node_modules/is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/expand-brackets/node_modules/kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/expand-brackets/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - }, - "node_modules/expect": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/expect/-/expect-26.6.2.tgz", - "integrity": "sha512-9/hlOBkQl2l/PLHJx6JjoDF6xPKcJEsUlWKb23rKE7KzeDqUZKXKNMW27KIue5JMdBV9HgmoJPcc8HtO85t9IA==", - "dependencies": { - "@jest/types": "^26.6.2", - "ansi-styles": "^4.0.0", - "jest-get-type": "^26.3.0", - "jest-matcher-utils": "^26.6.2", - "jest-message-util": "^26.6.2", - "jest-regex-util": "^26.0.0" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/ext": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/ext/-/ext-1.4.0.tgz", - "integrity": "sha512-Key5NIsUxdqKg3vIsdw9dSuXpPCQ297y6wBjL30edxwPgt2E44WcWBZey/ZvUc6sERLTxKdyCu4gZFmUbk1Q7A==", - "dependencies": { - "type": "^2.0.0" - } - }, - "node_modules/ext/node_modules/type": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/type/-/type-2.1.0.tgz", - "integrity": "sha512-G9absDWvhAWCV2gmF1zKud3OyC61nZDwWvBL2DApaVFogI07CprggiQAOOjvp2NRjYWFzPyu7vwtDrQFq8jeSA==" - }, - "node_modules/extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" - }, - "node_modules/extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", - "dependencies": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "dependencies": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/extglob/node_modules/define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dependencies": { - "is-descriptor": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/extglob/node_modules/extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dependencies": { - "is-extendable": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/extglob/node_modules/is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/extsprintf": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", - "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=", - "engines": [ - "node >=0.6.0" - ] - }, - "node_modules/fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" - }, - "node_modules/fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" - }, - "node_modules/fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=" - }, - "node_modules/fb-watchman": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.1.tgz", - "integrity": "sha512-DkPJKQeY6kKwmuMretBhr7G6Vodr7bFwDYTXIkfG1gjvNpaxBTQV3PbXg6bR1c1UP4jPOX0jHUbbHANL9vRjVg==", - "dependencies": { - "bser": "2.1.1" - } - }, - "node_modules/ffmpeg-static": { - "version": "4.2.7", - "resolved": "https://registry.npmjs.org/ffmpeg-static/-/ffmpeg-static-4.2.7.tgz", - "integrity": "sha512-SGnOr2d+k0/9toRIv9t5/hN/DMYbm5XMtG0wVwGM1tEyXJAD6dbcWOEvfHq4LOySm9uykKL6LMC4eVPeteUnbQ==", - "hasInstallScript": true, - "license": "GPL-3.0-or-later", - "dependencies": { - "@derhuerst/http-basic": "^8.2.0", - "env-paths": "^2.2.0", - "https-proxy-agent": "^5.0.0", - "progress": "^2.0.3" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/file-entry-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.0.tgz", - "integrity": "sha512-fqoO76jZ3ZnYrXLDRxBR1YvOvc0k844kcOg40bgsPrE25LAb/PDqTY+ho64Xh2c8ZXgIKldchCFHczG2UVRcWA==", - "dev": true, - "dependencies": { - "flat-cache": "^3.0.4" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, - "node_modules/file-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/file-match/-/file-match-1.0.2.tgz", - "integrity": "sha1-ycrSZdLIrfOoFHWw30dYWQafrvc=", - "dependencies": { - "utils-extend": "^1.0.6" - } - }, - "node_modules/file-system": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/file-system/-/file-system-2.2.2.tgz", - "integrity": "sha1-fWWDPjojR9zZVqgTxncVPtPt2Yc=", - "license": "ISC", - "dependencies": { - "file-match": "^1.0.1", - "utils-extend": "^1.0.4" - } - }, - "node_modules/fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "dependencies": { - "to-regex-range": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dependencies": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/flat-cache": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", - "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", - "dev": true, - "dependencies": { - "flatted": "^3.1.0", - "rimraf": "^3.0.2" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, - "node_modules/flatted": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.1.0.tgz", - "integrity": "sha512-tW+UkmtNg/jv9CSofAKvgVcO7c2URjhTdW1ZTkcAritblu8tajiYy7YisnIflEwtKssCtOxpnBRoCB7iap0/TA==", - "dev": true - }, - "node_modules/follow-redirects": { - "version": "1.5.10", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.5.10.tgz", - "integrity": "sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ==", - "dependencies": { - "debug": "=3.1.0" - }, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/follow-redirects/node_modules/debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/follow-redirects/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - }, - "node_modules/for-in": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", - "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/forever-agent": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", - "engines": { - "node": "*" - } - }, - "node_modules/form-data": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", - "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", - "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.6", - "mime-types": "^2.1.12" - }, - "engines": { - "node": ">= 0.12" - } - }, - "node_modules/fragment-cache": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", - "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", - "dependencies": { - "map-cache": "^0.2.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/fs-minipass": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", - "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", - "dependencies": { - "minipass": "^3.0.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" - }, - "node_modules/fsevents": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz", - "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==", - "deprecated": "Please update to v 2.2.x", - "hasInstallScript": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, - "node_modules/function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" - }, - "node_modules/functional-red-black-tree": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", - "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", - "dev": true - }, - "node_modules/gauge": { - "version": "2.7.4", - "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", - "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=", - "dependencies": { - "aproba": "^1.0.3", - "console-control-strings": "^1.0.0", - "has-unicode": "^2.0.0", - "object-assign": "^4.1.0", - "signal-exit": "^3.0.0", - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1", - "wide-align": "^1.1.0" - } - }, - "node_modules/gauge/node_modules/ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/gauge/node_modules/strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dependencies": { - "ansi-regex": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/gensync": { - "version": "1.0.0-beta.2", - "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", - "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "engines": { - "node": "6.* || 8.* || >= 10.*" - } - }, - "node_modules/get-package-type": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", - "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/get-stream": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", - "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", - "dependencies": { - "pump": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/get-value": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", - "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/getpass": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", - "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", - "dependencies": { - "assert-plus": "^1.0.0" - } - }, - "node_modules/give-me-a-joke": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/give-me-a-joke/-/give-me-a-joke-0.4.0.tgz", - "integrity": "sha512-qWB6H6QxToUuWrW79BYlWkFVQrlKahCrF5hXtBndthgOgG219SeKakzgBNEFsZItVzHgVjihR5zKJeu1pf1JMw==", - "dependencies": { - "axios": "^0.19.2" - } - }, - "node_modules/glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/glob-parent": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz", - "integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==", - "dev": true, - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/global-dirs": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-2.1.0.tgz", - "integrity": "sha512-MG6kdOUh/xBnyo9cJFeIKkLEc1AyFq42QTU4XiX51i2NEdxLxLWXIjEjmqKeSuKR7pAZjTqUVoT2b2huxVLgYQ==", - "dev": true, - "dependencies": { - "ini": "1.3.7" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/global-dirs/node_modules/ini": { - "version": "1.3.7", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.7.tgz", - "integrity": "sha512-iKpRpXP+CrP2jyrxvg1kMUpXDyRUFDWurxbnVT1vQPx+Wz9uCYsMIqYuSBLV+PAaZG/d7kRLKRFc9oDMsH+mFQ==", - "dev": true - }, - "node_modules/globals": { - "version": "12.4.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-12.4.0.tgz", - "integrity": "sha512-BWICuzzDvDoH54NHKCseDanAhE3CeDorgDL5MT6LMXXj2WCnd9UC2szdk4AWLfjdgNBCXLUanXYcpBBKOSWGwg==", - "dev": true, - "dependencies": { - "type-fest": "^0.8.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/got": { - "version": "9.6.0", - "resolved": "https://registry.npmjs.org/got/-/got-9.6.0.tgz", - "integrity": "sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q==", - "dev": true, - "dependencies": { - "@sindresorhus/is": "^0.14.0", - "@szmarczak/http-timer": "^1.1.2", - "cacheable-request": "^6.0.0", - "decompress-response": "^3.3.0", - "duplexer3": "^0.1.4", - "get-stream": "^4.1.0", - "lowercase-keys": "^1.0.1", - "mimic-response": "^1.0.1", - "p-cancelable": "^1.0.0", - "to-readable-stream": "^1.0.0", - "url-parse-lax": "^3.0.0" - }, - "engines": { - "node": ">=8.6" - } - }, - "node_modules/graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==" - }, - "node_modules/growly": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/growly/-/growly-1.3.0.tgz", - "integrity": "sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE=", - "optional": true - }, - "node_modules/har-schema": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", - "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=", - "engines": { - "node": ">=4" - } - }, - "node_modules/har-validator": { - "version": "5.1.5", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz", - "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==", - "deprecated": "this library is no longer supported", - "dependencies": { - "ajv": "^6.12.3", - "har-schema": "^2.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "dependencies": { - "function-bind": "^1.1.1" - }, - "engines": { - "node": ">= 0.4.0" - } - }, - "node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "engines": { - "node": ">=8" - } - }, - "node_modules/has-unicode": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", - "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=" - }, - "node_modules/has-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", - "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", - "dependencies": { - "get-value": "^2.0.6", - "has-values": "^1.0.0", - "isobject": "^3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/has-values": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", - "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", - "dependencies": { - "is-number": "^3.0.0", - "kind-of": "^4.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/has-values/node_modules/is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/has-values/node_modules/is-number/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/has-values/node_modules/kind-of": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", - "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/has-yarn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/has-yarn/-/has-yarn-2.1.0.tgz", - "integrity": "sha512-UqBRqi4ju7T+TqGNdqAO0PaSVGsDGJUBQvk9eUWNGRY1CFGDzYhLWoM7JQEemnlvVcv/YEmc2wNW8BC24EnUsw==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/hosted-git-info": { - "version": "2.8.8", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.8.tgz", - "integrity": "sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg==" - }, - "node_modules/html-encoding-sniffer": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-2.0.1.tgz", - "integrity": "sha512-D5JbOMBIR/TVZkubHT+OyT2705QvogUW4IBn6nHd756OwieSF9aDYFj4dv6HHEVGYbHaLETa3WggZYWWMyy3ZQ==", - "dependencies": { - "whatwg-encoding": "^1.0.5" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/html-escaper": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", - "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==" - }, - "node_modules/htmlparser2": { - "version": "3.10.1", - "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.10.1.tgz", - "integrity": "sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ==", - "dependencies": { - "domelementtype": "^1.3.1", - "domhandler": "^2.3.0", - "domutils": "^1.5.1", - "entities": "^1.1.1", - "inherits": "^2.0.1", - "readable-stream": "^3.1.1" - } - }, - "node_modules/htmlparser2/node_modules/readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/http-cache-semantics": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz", - "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==", - "dev": true - }, - "node_modules/http-response-object": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/http-response-object/-/http-response-object-3.0.2.tgz", - "integrity": "sha512-bqX0XTF6fnXSQcEJ2Iuyr75yVakyjIDCqroJQ/aHfSdlM743Cwqoi2nDYMzLGWUcuTWGWy8AAvOKXTfiv6q9RA==", - "dependencies": { - "@types/node": "^10.0.3" - } - }, - "node_modules/http-signature": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", - "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", - "dependencies": { - "assert-plus": "^1.0.0", - "jsprim": "^1.2.2", - "sshpk": "^1.7.0" - }, - "engines": { - "node": ">=0.8", - "npm": ">=1.3.7" - } - }, - "node_modules/https-proxy-agent": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz", - "integrity": "sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==", - "dependencies": { - "agent-base": "6", - "debug": "4" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/human-signals": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-1.1.1.tgz", - "integrity": "sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==", - "engines": { - "node": ">=8.12.0" - } - }, - "node_modules/human-time": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/human-time/-/human-time-0.0.2.tgz", - "integrity": "sha512-sbYI90YhYmstslPTb70BLGjy6mdESa0lxL7uDR4fIVAx9Iobz8fLEqi7FqF4Q/6vblrzZALg//MsYJlIPBU8SA==" - }, - "node_modules/iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ignore": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", - "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", - "dev": true, - "engines": { - "node": ">= 4" - } - }, - "node_modules/ignore-by-default": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz", - "integrity": "sha1-SMptcvbGo68Aqa1K5odr44ieKwk=", - "dev": true - }, - "node_modules/ignore-walk": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/ignore-walk/-/ignore-walk-3.0.3.tgz", - "integrity": "sha512-m7o6xuOaT1aqheYHKf8W6J5pYH85ZI9w077erOzLje3JsB1gkafkAhHHY19dqjulgIZHFm32Cp5uNZgcQqdJKw==", - "dependencies": { - "minimatch": "^3.0.4" - } - }, - "node_modules/import-fresh": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", - "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", - "dev": true, - "dependencies": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/import-lazy": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-2.1.0.tgz", - "integrity": "sha1-BWmOPUXIjo1+nZLLBYTnfwlvPkM=", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/import-local": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.0.2.tgz", - "integrity": "sha512-vjL3+w0oulAVZ0hBHnxa/Nm5TAurf9YLQJDhqRZyqb+VKGOB6LU8t9H1Nr5CIo16vh9XfJTOoHwU0B71S557gA==", - "dependencies": { - "pkg-dir": "^4.2.0", - "resolve-cwd": "^3.0.0" - }, - "bin": { - "import-local-fixture": "fixtures/cli.js" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", - "engines": { - "node": ">=0.8.19" - } - }, - "node_modules/inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "dependencies": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "node_modules/ini": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", - "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==" - }, - "node_modules/ip-regex": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-2.1.0.tgz", - "integrity": "sha1-+ni/XS5pE8kRzp+BnuUUa7bYROk=", - "engines": { - "node": ">=4" - } - }, - "node_modules/is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dependencies": { - "kind-of": "^6.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=" - }, - "node_modules/is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "dev": true, - "dependencies": { - "binary-extensions": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" - }, - "node_modules/is-ci": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz", - "integrity": "sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==", - "dependencies": { - "ci-info": "^2.0.0" - }, - "bin": { - "is-ci": "bin.js" - } - }, - "node_modules/is-core-module": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.2.0.tgz", - "integrity": "sha512-XRAfAdyyY5F5cOXn7hYQDqh2Xmii+DEfIcQGxK/uNwMHhIkPWO0g8msXcbzLe+MpGoR951MlqM/2iIlU4vKDdQ==", - "dependencies": { - "has": "^1.0.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dependencies": { - "kind-of": "^6.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dependencies": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-docker": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.1.1.tgz", - "integrity": "sha512-ZOoqiXfEwtGknTiuDEy8pN2CfE3TxMHprvNer1mXiqwkOT77Rw3YVrUQ52EqAOU3QAWDQ+bQdx7HJzrv7LS2Hw==", - "optional": true, - "bin": { - "is-docker": "cli.js" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dependencies": { - "is-plain-object": "^2.0.4" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-fullwidth-code-point": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", - "dependencies": { - "number-is-nan": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-generator-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz", - "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==", - "engines": { - "node": ">=6" - } - }, - "node_modules/is-glob": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", - "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", - "dev": true, - "dependencies": { - "is-extglob": "^2.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-installed-globally": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.3.2.tgz", - "integrity": "sha512-wZ8x1js7Ia0kecP/CHM/3ABkAmujX7WPvQk6uu3Fly/Mk44pySulQpnHG46OMjHGXApINnV4QhY3SWnECO2z5g==", - "dev": true, - "dependencies": { - "global-dirs": "^2.0.1", - "is-path-inside": "^3.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-npm": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-npm/-/is-npm-4.0.0.tgz", - "integrity": "sha512-96ECIfh9xtDDlPylNPXhzjsykHsMJZ18ASpaWzQyBr4YRTcVjUvzaHayDAES2oU/3KpljhHUjtSRNiDwi0F0ig==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "engines": { - "node": ">=0.12.0" - } - }, - "node_modules/is-obj": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", - "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-path-inside": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.2.tgz", - "integrity": "sha512-/2UGPSgmtqwo1ktx8NDHjuPwZWmHhO+gj0f93EkhLB5RgW9RZevWYYlIkS6zePc6U2WpOdQYIwHe9YC4DWEBVg==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dependencies": { - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-potential-custom-element-name": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.0.tgz", - "integrity": "sha1-DFLlS8yjkbssSUsh6GJtczbG45c=" - }, - "node_modules/is-promise": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.2.2.tgz", - "integrity": "sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ==" - }, - "node_modules/is-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz", - "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==", - "engines": { - "node": ">=8" - } - }, - "node_modules/is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" - }, - "node_modules/is-windows": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", - "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-wsl": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", - "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", - "optional": true, - "dependencies": { - "is-docker": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-yarn-global": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/is-yarn-global/-/is-yarn-global-0.3.0.tgz", - "integrity": "sha512-VjSeb/lHmkoyd8ryPVIKvOCn4D1koMqY+vqyjjUfc3xyKtP4dYOxM44sZrnqQSzSds3xyOrUTLTC9LVCVgLngw==", - "dev": true - }, - "node_modules/isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" - }, - "node_modules/isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" - }, - "node_modules/isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/isstream": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" - }, - "node_modules/istanbul-lib-coverage": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.0.0.tgz", - "integrity": "sha512-UiUIqxMgRDET6eR+o5HbfRYP1l0hqkWOs7vNxC/mggutCMUIhWMm8gAHb8tHlyfD3/l6rlgNA5cKdDzEAf6hEg==", - "engines": { - "node": ">=8" - } - }, - "node_modules/istanbul-lib-instrument": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.3.tgz", - "integrity": "sha512-BXgQl9kf4WTCPCCpmFGoJkz/+uhvm7h7PFKUYxh7qarQd3ER33vHG//qaE8eN25l07YqZPpHXU9I09l/RD5aGQ==", - "dependencies": { - "@babel/core": "^7.7.5", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-coverage": "^3.0.0", - "semver": "^6.3.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/istanbul-lib-instrument/node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/istanbul-lib-report": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", - "integrity": "sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==", - "dependencies": { - "istanbul-lib-coverage": "^3.0.0", - "make-dir": "^3.0.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/istanbul-lib-source-maps": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.0.tgz", - "integrity": "sha512-c16LpFRkR8vQXyHZ5nLpY35JZtzj1PQY1iZmesUbf1FZHbIupcWfjgOXBY9YHkLEQ6puz1u4Dgj6qmU/DisrZg==", - "dependencies": { - "debug": "^4.1.1", - "istanbul-lib-coverage": "^3.0.0", - "source-map": "^0.6.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/istanbul-reports": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.0.2.tgz", - "integrity": "sha512-9tZvz7AiR3PEDNGiV9vIouQ/EAcqMXFmkcA1CDFTwOB98OZVDL0PH9glHotf5Ugp6GCOTypfzGWI/OqjWNCRUw==", - "dependencies": { - "html-escaper": "^2.0.0", - "istanbul-lib-report": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/jest": { - "version": "26.6.3", - "resolved": "https://registry.npmjs.org/jest/-/jest-26.6.3.tgz", - "integrity": "sha512-lGS5PXGAzR4RF7V5+XObhqz2KZIDUA1yD0DG6pBVmy10eh0ZIXQImRuzocsI/N2XZ1GrLFwTS27In2i2jlpq1Q==", - "dependencies": { - "@jest/core": "^26.6.3", - "import-local": "^3.0.2", - "jest-cli": "^26.6.3" - }, - "bin": { - "jest": "bin/jest.js" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/jest-changed-files": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-26.6.2.tgz", - "integrity": "sha512-fDS7szLcY9sCtIip8Fjry9oGf3I2ht/QT21bAHm5Dmf0mD4X3ReNUf17y+bO6fR8WgbIZTlbyG1ak/53cbRzKQ==", - "dependencies": { - "@jest/types": "^26.6.2", - "execa": "^4.0.0", - "throat": "^5.0.0" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/jest-cli": { - "version": "26.6.3", - "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-26.6.3.tgz", - "integrity": "sha512-GF9noBSa9t08pSyl3CY4frMrqp+aQXFGFkf5hEPbh/pIUFYWMK6ZLTfbmadxJVcJrdRoChlWQsA2VkJcDFK8hg==", - "dependencies": { - "@jest/core": "^26.6.3", - "@jest/test-result": "^26.6.2", - "@jest/types": "^26.6.2", - "chalk": "^4.0.0", - "exit": "^0.1.2", - "graceful-fs": "^4.2.4", - "import-local": "^3.0.2", - "is-ci": "^2.0.0", - "jest-config": "^26.6.3", - "jest-util": "^26.6.2", - "jest-validate": "^26.6.2", - "prompts": "^2.0.1", - "yargs": "^15.4.1" - }, - "bin": { - "jest": "bin/jest.js" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/jest-config": { - "version": "26.6.3", - "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-26.6.3.tgz", - "integrity": "sha512-t5qdIj/bCj2j7NFVHb2nFB4aUdfucDn3JRKgrZnplb8nieAirAzRSHP8uDEd+qV6ygzg9Pz4YG7UTJf94LPSyg==", - "dependencies": { - "@babel/core": "^7.1.0", - "@jest/test-sequencer": "^26.6.3", - "@jest/types": "^26.6.2", - "babel-jest": "^26.6.3", - "chalk": "^4.0.0", - "deepmerge": "^4.2.2", - "glob": "^7.1.1", - "graceful-fs": "^4.2.4", - "jest-environment-jsdom": "^26.6.2", - "jest-environment-node": "^26.6.2", - "jest-get-type": "^26.3.0", - "jest-jasmine2": "^26.6.3", - "jest-regex-util": "^26.0.0", - "jest-resolve": "^26.6.2", - "jest-util": "^26.6.2", - "jest-validate": "^26.6.2", - "micromatch": "^4.0.2", - "pretty-format": "^26.6.2" - }, - "engines": { - "node": ">= 10.14.2" - }, - "peerDependencies": { - "ts-node": ">=9.0.0" - }, - "peerDependenciesMeta": { - "ts-node": { - "optional": true - } - } - }, - "node_modules/jest-diff": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-26.6.2.tgz", - "integrity": "sha512-6m+9Z3Gv9wN0WFVasqjCL/06+EFCMTqDEUl/b87HYK2rAPTyfz4ZIuSlPhY51PIQRWx5TaxeF1qmXKe9gfN3sA==", - "dependencies": { - "chalk": "^4.0.0", - "diff-sequences": "^26.6.2", - "jest-get-type": "^26.3.0", - "pretty-format": "^26.6.2" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/jest-discordjs-mocks": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/jest-discordjs-mocks/-/jest-discordjs-mocks-1.0.2.tgz", - "integrity": "sha512-S3wng0scR9GsUZwj4NW/PDCHpPptWQTJz8mqW4lEfOiNl+l8/XQpBYh2dPQq5zFkhnXTb9WRG0DThcB0OOBrhg==", - "dependencies": { - "@types/jest": "^26.0.8", - "discord.js": "^12.2.0", - "jest": "^26.2.2" - } - }, - "node_modules/jest-docblock": { - "version": "26.0.0", - "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-26.0.0.tgz", - "integrity": "sha512-RDZ4Iz3QbtRWycd8bUEPxQsTlYazfYn/h5R65Fc6gOfwozFhoImx+affzky/FFBuqISPTqjXomoIGJVKBWoo0w==", - "dependencies": { - "detect-newline": "^3.0.0" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/jest-each": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-26.6.2.tgz", - "integrity": "sha512-Mer/f0KaATbjl8MCJ+0GEpNdqmnVmDYqCTJYTvoo7rqmRiDllmp2AYN+06F93nXcY3ur9ShIjS+CO/uD+BbH4A==", - "dependencies": { - "@jest/types": "^26.6.2", - "chalk": "^4.0.0", - "jest-get-type": "^26.3.0", - "jest-util": "^26.6.2", - "pretty-format": "^26.6.2" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/jest-environment-jsdom": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-26.6.2.tgz", - "integrity": "sha512-jgPqCruTlt3Kwqg5/WVFyHIOJHsiAvhcp2qiR2QQstuG9yWox5+iHpU3ZrcBxW14T4fe5Z68jAfLRh7joCSP2Q==", - "dependencies": { - "@jest/environment": "^26.6.2", - "@jest/fake-timers": "^26.6.2", - "@jest/types": "^26.6.2", - "@types/node": "*", - "jest-mock": "^26.6.2", - "jest-util": "^26.6.2", - "jsdom": "^16.4.0" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/jest-environment-node": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-26.6.2.tgz", - "integrity": "sha512-zhtMio3Exty18dy8ee8eJ9kjnRyZC1N4C1Nt/VShN1apyXc8rWGtJ9lI7vqiWcyyXS4BVSEn9lxAM2D+07/Tag==", - "dependencies": { - "@jest/environment": "^26.6.2", - "@jest/fake-timers": "^26.6.2", - "@jest/types": "^26.6.2", - "@types/node": "*", - "jest-mock": "^26.6.2", - "jest-util": "^26.6.2" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/jest-get-type": { - "version": "26.3.0", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.3.0.tgz", - "integrity": "sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig==", - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/jest-haste-map": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-26.6.2.tgz", - "integrity": "sha512-easWIJXIw71B2RdR8kgqpjQrbMRWQBgiBwXYEhtGUTaX+doCjBheluShdDMeR8IMfJiTqH4+zfhtg29apJf/8w==", - "dependencies": { - "@jest/types": "^26.6.2", - "@types/graceful-fs": "^4.1.2", - "@types/node": "*", - "anymatch": "^3.0.3", - "fb-watchman": "^2.0.0", - "fsevents": "^2.1.2", - "graceful-fs": "^4.2.4", - "jest-regex-util": "^26.0.0", - "jest-serializer": "^26.6.2", - "jest-util": "^26.6.2", - "jest-worker": "^26.6.2", - "micromatch": "^4.0.2", - "sane": "^4.0.3", - "walker": "^1.0.7" - }, - "engines": { - "node": ">= 10.14.2" - }, - "optionalDependencies": { - "fsevents": "^2.1.2" - } - }, - "node_modules/jest-jasmine2": { - "version": "26.6.3", - "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-26.6.3.tgz", - "integrity": "sha512-kPKUrQtc8aYwBV7CqBg5pu+tmYXlvFlSFYn18ev4gPFtrRzB15N2gW/Roew3187q2w2eHuu0MU9TJz6w0/nPEg==", - "dependencies": { - "@babel/traverse": "^7.1.0", - "@jest/environment": "^26.6.2", - "@jest/source-map": "^26.6.2", - "@jest/test-result": "^26.6.2", - "@jest/types": "^26.6.2", - "@types/node": "*", - "chalk": "^4.0.0", - "co": "^4.6.0", - "expect": "^26.6.2", - "is-generator-fn": "^2.0.0", - "jest-each": "^26.6.2", - "jest-matcher-utils": "^26.6.2", - "jest-message-util": "^26.6.2", - "jest-runtime": "^26.6.3", - "jest-snapshot": "^26.6.2", - "jest-util": "^26.6.2", - "pretty-format": "^26.6.2", - "throat": "^5.0.0" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/jest-leak-detector": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-26.6.2.tgz", - "integrity": "sha512-i4xlXpsVSMeKvg2cEKdfhh0H39qlJlP5Ex1yQxwF9ubahboQYMgTtz5oML35AVA3B4Eu+YsmwaiKVev9KCvLxg==", - "dependencies": { - "jest-get-type": "^26.3.0", - "pretty-format": "^26.6.2" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/jest-matcher-utils": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-26.6.2.tgz", - "integrity": "sha512-llnc8vQgYcNqDrqRDXWwMr9i7rS5XFiCwvh6DTP7Jqa2mqpcCBBlpCbn+trkG0KNhPu/h8rzyBkriOtBstvWhw==", - "dependencies": { - "chalk": "^4.0.0", - "jest-diff": "^26.6.2", - "jest-get-type": "^26.3.0", - "pretty-format": "^26.6.2" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/jest-message-util": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.6.2.tgz", - "integrity": "sha512-rGiLePzQ3AzwUshu2+Rn+UMFk0pHN58sOG+IaJbk5Jxuqo3NYO1U2/MIR4S1sKgsoYSXSzdtSa0TgrmtUwEbmA==", - "dependencies": { - "@babel/code-frame": "^7.0.0", - "@jest/types": "^26.6.2", - "@types/stack-utils": "^2.0.0", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "micromatch": "^4.0.2", - "pretty-format": "^26.6.2", - "slash": "^3.0.0", - "stack-utils": "^2.0.2" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/jest-mock": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-26.6.2.tgz", - "integrity": "sha512-YyFjePHHp1LzpzYcmgqkJ0nm0gg/lJx2aZFzFy1S6eUqNjXsOqTK10zNRff2dNfssgokjkG65OlWNcIlgd3zew==", - "dependencies": { - "@jest/types": "^26.6.2", - "@types/node": "*" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/jest-pnp-resolver": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.2.tgz", - "integrity": "sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w==", - "engines": { - "node": ">=6" - }, - "peerDependencies": { - "jest-resolve": "*" - }, - "peerDependenciesMeta": { - "jest-resolve": { - "optional": true - } - } - }, - "node_modules/jest-regex-util": { - "version": "26.0.0", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-26.0.0.tgz", - "integrity": "sha512-Gv3ZIs/nA48/Zvjrl34bf+oD76JHiGDUxNOVgUjh3j890sblXryjY4rss71fPtD/njchl6PSE2hIhvyWa1eT0A==", - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/jest-resolve": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-26.6.2.tgz", - "integrity": "sha512-sOxsZOq25mT1wRsfHcbtkInS+Ek7Q8jCHUB0ZUTP0tc/c41QHriU/NunqMfCUWsL4H3MHpvQD4QR9kSYhS7UvQ==", - "dependencies": { - "@jest/types": "^26.6.2", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "jest-pnp-resolver": "^1.2.2", - "jest-util": "^26.6.2", - "read-pkg-up": "^7.0.1", - "resolve": "^1.18.1", - "slash": "^3.0.0" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/jest-resolve-dependencies": { - "version": "26.6.3", - "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-26.6.3.tgz", - "integrity": "sha512-pVwUjJkxbhe4RY8QEWzN3vns2kqyuldKpxlxJlzEYfKSvY6/bMvxoFrYYzUO1Gx28yKWN37qyV7rIoIp2h8fTg==", - "dependencies": { - "@jest/types": "^26.6.2", - "jest-regex-util": "^26.0.0", - "jest-snapshot": "^26.6.2" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/jest-runner": { - "version": "26.6.3", - "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-26.6.3.tgz", - "integrity": "sha512-atgKpRHnaA2OvByG/HpGA4g6CSPS/1LK0jK3gATJAoptC1ojltpmVlYC3TYgdmGp+GLuhzpH30Gvs36szSL2JQ==", - "dependencies": { - "@jest/console": "^26.6.2", - "@jest/environment": "^26.6.2", - "@jest/test-result": "^26.6.2", - "@jest/types": "^26.6.2", - "@types/node": "*", - "chalk": "^4.0.0", - "emittery": "^0.7.1", - "exit": "^0.1.2", - "graceful-fs": "^4.2.4", - "jest-config": "^26.6.3", - "jest-docblock": "^26.0.0", - "jest-haste-map": "^26.6.2", - "jest-leak-detector": "^26.6.2", - "jest-message-util": "^26.6.2", - "jest-resolve": "^26.6.2", - "jest-runtime": "^26.6.3", - "jest-util": "^26.6.2", - "jest-worker": "^26.6.2", - "source-map-support": "^0.5.6", - "throat": "^5.0.0" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/jest-runtime": { - "version": "26.6.3", - "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-26.6.3.tgz", - "integrity": "sha512-lrzyR3N8sacTAMeonbqpnSka1dHNux2uk0qqDXVkMv2c/A3wYnvQ4EXuI013Y6+gSKSCxdaczvf4HF0mVXHRdw==", - "dependencies": { - "@jest/console": "^26.6.2", - "@jest/environment": "^26.6.2", - "@jest/fake-timers": "^26.6.2", - "@jest/globals": "^26.6.2", - "@jest/source-map": "^26.6.2", - "@jest/test-result": "^26.6.2", - "@jest/transform": "^26.6.2", - "@jest/types": "^26.6.2", - "@types/yargs": "^15.0.0", - "chalk": "^4.0.0", - "cjs-module-lexer": "^0.6.0", - "collect-v8-coverage": "^1.0.0", - "exit": "^0.1.2", - "glob": "^7.1.3", - "graceful-fs": "^4.2.4", - "jest-config": "^26.6.3", - "jest-haste-map": "^26.6.2", - "jest-message-util": "^26.6.2", - "jest-mock": "^26.6.2", - "jest-regex-util": "^26.0.0", - "jest-resolve": "^26.6.2", - "jest-snapshot": "^26.6.2", - "jest-util": "^26.6.2", - "jest-validate": "^26.6.2", - "slash": "^3.0.0", - "strip-bom": "^4.0.0", - "yargs": "^15.4.1" - }, - "bin": { - "jest-runtime": "bin/jest-runtime.js" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/jest-serializer": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-26.6.2.tgz", - "integrity": "sha512-S5wqyz0DXnNJPd/xfIzZ5Xnp1HrJWBczg8mMfMpN78OJ5eDxXyf+Ygld9wX1DnUWbIbhM1YDY95NjR4CBXkb2g==", - "dependencies": { - "@types/node": "*", - "graceful-fs": "^4.2.4" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/jest-snapshot": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-26.6.2.tgz", - "integrity": "sha512-OLhxz05EzUtsAmOMzuupt1lHYXCNib0ECyuZ/PZOx9TrZcC8vL0x+DUG3TL+GLX3yHG45e6YGjIm0XwDc3q3og==", - "dependencies": { - "@babel/types": "^7.0.0", - "@jest/types": "^26.6.2", - "@types/babel__traverse": "^7.0.4", - "@types/prettier": "^2.0.0", - "chalk": "^4.0.0", - "expect": "^26.6.2", - "graceful-fs": "^4.2.4", - "jest-diff": "^26.6.2", - "jest-get-type": "^26.3.0", - "jest-haste-map": "^26.6.2", - "jest-matcher-utils": "^26.6.2", - "jest-message-util": "^26.6.2", - "jest-resolve": "^26.6.2", - "natural-compare": "^1.4.0", - "pretty-format": "^26.6.2", - "semver": "^7.3.2" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/jest-util": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.6.2.tgz", - "integrity": "sha512-MDW0fKfsn0OI7MS7Euz6h8HNDXVQ0gaM9uW6RjfDmd1DAFcaxX9OqIakHIqhbnmF08Cf2DLDG+ulq8YQQ0Lp0Q==", - "dependencies": { - "@jest/types": "^26.6.2", - "@types/node": "*", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "is-ci": "^2.0.0", - "micromatch": "^4.0.2" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/jest-validate": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-26.6.2.tgz", - "integrity": "sha512-NEYZ9Aeyj0i5rQqbq+tpIOom0YS1u2MVu6+euBsvpgIme+FOfRmoC4R5p0JiAUpaFvFy24xgrpMknarR/93XjQ==", - "dependencies": { - "@jest/types": "^26.6.2", - "camelcase": "^6.0.0", - "chalk": "^4.0.0", - "jest-get-type": "^26.3.0", - "leven": "^3.1.0", - "pretty-format": "^26.6.2" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/jest-validate/node_modules/camelcase": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.0.tgz", - "integrity": "sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/jest-watcher": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-26.6.2.tgz", - "integrity": "sha512-WKJob0P/Em2csiVthsI68p6aGKTIcsfjH9Gsx1f0A3Italz43e3ho0geSAVsmj09RWOELP1AZ/DXyJgOgDKxXQ==", - "dependencies": { - "@jest/test-result": "^26.6.2", - "@jest/types": "^26.6.2", - "@types/node": "*", - "ansi-escapes": "^4.2.1", - "chalk": "^4.0.0", - "jest-util": "^26.6.2", - "string-length": "^4.0.1" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/jest-worker": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.6.2.tgz", - "integrity": "sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ==", - "dependencies": { - "@types/node": "*", - "merge-stream": "^2.0.0", - "supports-color": "^7.0.0" - }, - "engines": { - "node": ">= 10.13.0" - } - }, - "node_modules/js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" - }, - "node_modules/js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", - "dependencies": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/jsbn": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=" - }, - "node_modules/jsdom": { - "version": "16.4.0", - "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-16.4.0.tgz", - "integrity": "sha512-lYMm3wYdgPhrl7pDcRmvzPhhrGVBeVhPIqeHjzeiHN3DFmD1RBpbExbi8vU7BJdH8VAZYovR8DMt0PNNDM7k8w==", - "dependencies": { - "abab": "^2.0.3", - "acorn": "^7.1.1", - "acorn-globals": "^6.0.0", - "cssom": "^0.4.4", - "cssstyle": "^2.2.0", - "data-urls": "^2.0.0", - "decimal.js": "^10.2.0", - "domexception": "^2.0.1", - "escodegen": "^1.14.1", - "html-encoding-sniffer": "^2.0.1", - "is-potential-custom-element-name": "^1.0.0", - "nwsapi": "^2.2.0", - "parse5": "5.1.1", - "request": "^2.88.2", - "request-promise-native": "^1.0.8", - "saxes": "^5.0.0", - "symbol-tree": "^3.2.4", - "tough-cookie": "^3.0.1", - "w3c-hr-time": "^1.0.2", - "w3c-xmlserializer": "^2.0.0", - "webidl-conversions": "^6.1.0", - "whatwg-encoding": "^1.0.5", - "whatwg-mimetype": "^2.3.0", - "whatwg-url": "^8.0.0", - "ws": "^7.2.3", - "xml-name-validator": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "peerDependencies": { - "canvas": "^2.5.0" - }, - "peerDependenciesMeta": { - "canvas": { - "optional": true - } - } - }, - "node_modules/jsesc": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", - "bin": { - "jsesc": "bin/jsesc" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/json-buffer": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.0.tgz", - "integrity": "sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg=", - "dev": true - }, - "node_modules/json-parse-even-better-errors": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", - "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==" - }, - "node_modules/json-schema": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", - "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=" - }, - "node_modules/json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" - }, - "node_modules/json-stable-stringify-without-jsonify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", - "dev": true - }, - "node_modules/json-stringify-safe": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" - }, - "node_modules/json5": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.3.tgz", - "integrity": "sha512-KXPvOm8K9IJKFM0bmdn8QXh7udDh1g/giieX0NLCaMnb4hEiVFqnop2ImTXCc5e0/oHz3LTqmHGtExn5hfMkOA==", - "dependencies": { - "minimist": "^1.2.5" - }, - "bin": { - "json5": "lib/cli.js" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/jsonpath": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/jsonpath/-/jsonpath-1.0.2.tgz", - "integrity": "sha512-rmzlgFZiQPc6q4HDyK8s9Qb4oxBnI5sF61y/Co5PV0lc3q2bIuRsNdueVbhoSHdKM4fxeimphOAtfz47yjCfeA==", - "hasInstallScript": true, - "dependencies": { - "esprima": "1.2.2", - "static-eval": "2.0.2", - "underscore": "1.7.0" - } - }, - "node_modules/jsonpath/node_modules/esprima": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-1.2.2.tgz", - "integrity": "sha1-dqD9Zvz+FU/SkmZ9wmQBl1CxZXs=", - "bin": { - "esparse": "bin/esparse.js", - "esvalidate": "bin/esvalidate.js" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/jsprim": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", - "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", - "engines": [ - "node >=0.6.0" - ], - "dependencies": { - "assert-plus": "1.0.0", - "extsprintf": "1.3.0", - "json-schema": "0.2.3", - "verror": "1.10.0" - } - }, - "node_modules/keypress": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/keypress/-/keypress-0.2.1.tgz", - "integrity": "sha1-HoBFQlABjbrUw/6USX1uZ7YmnHc=" - }, - "node_modules/keyv": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-3.1.0.tgz", - "integrity": "sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA==", - "dev": true, - "dependencies": { - "json-buffer": "3.0.0" - } - }, - "node_modules/kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/kleur": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", - "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", - "engines": { - "node": ">=6" - } - }, - "node_modules/latest-version": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/latest-version/-/latest-version-5.1.0.tgz", - "integrity": "sha512-weT+r0kTkRQdCdYCNtkMwWXQTMEswKrFBkm4ckQOMVhhqhIMI1UT2hMj+1iigIhgSZm5gTmrRXBNoGUgaTY1xA==", - "dev": true, - "dependencies": { - "package-json": "^6.3.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/leven": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", - "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", - "engines": { - "node": ">=6" - } - }, - "node_modules/levn": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", - "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", - "dev": true, - "dependencies": { - "prelude-ls": "^1.2.1", - "type-check": "~0.4.0" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/lines-and-columns": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.1.6.tgz", - "integrity": "sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA=" - }, - "node_modules/locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dependencies": { - "p-locate": "^4.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/lodash": { - "version": "4.17.20", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz", - "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==", - "license": "MIT" - }, - "node_modules/lodash.assignin": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/lodash.assignin/-/lodash.assignin-4.2.0.tgz", - "integrity": "sha1-uo31+4QesKPoBEIysOJjqNxqKKI=" - }, - "node_modules/lodash.bind": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/lodash.bind/-/lodash.bind-4.2.1.tgz", - "integrity": "sha1-euMBfpOWIqwxt9fX3LGzTbFpDTU=" - }, - "node_modules/lodash.defaults": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz", - "integrity": "sha1-0JF4cW/+pN3p5ft7N/bwgCJ0WAw=" - }, - "node_modules/lodash.filter": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/lodash.filter/-/lodash.filter-4.6.0.tgz", - "integrity": "sha1-ZosdSYFgOuHMWm+nYBQ+SAtMSs4=" - }, - "node_modules/lodash.flatten": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/lodash.flatten/-/lodash.flatten-4.4.0.tgz", - "integrity": "sha1-8xwiIlqWMtK7+OSt2+8kCqdlph8=" - }, - "node_modules/lodash.foreach": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.foreach/-/lodash.foreach-4.5.0.tgz", - "integrity": "sha1-Gmo16s5AEoDH8G3d7DUWWrJ+PlM=" - }, - "node_modules/lodash.map": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/lodash.map/-/lodash.map-4.6.0.tgz", - "integrity": "sha1-dx7Hg540c9nEzeKLGTlMNWL09tM=" - }, - "node_modules/lodash.merge": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", - "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==" - }, - "node_modules/lodash.pick": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/lodash.pick/-/lodash.pick-4.4.0.tgz", - "integrity": "sha1-UvBWEP/53tQiYRRB7R/BI6AwAbM=" - }, - "node_modules/lodash.reduce": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/lodash.reduce/-/lodash.reduce-4.6.0.tgz", - "integrity": "sha1-8atrg5KZrUj3hKu/R2WW8DuRTTs=" - }, - "node_modules/lodash.reject": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/lodash.reject/-/lodash.reject-4.6.0.tgz", - "integrity": "sha1-gNZJLcFHCGS79YNTO2UfQqn1JBU=" - }, - "node_modules/lodash.some": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/lodash.some/-/lodash.some-4.6.0.tgz", - "integrity": "sha1-G7nzFO9ri63tE7VJFpsqlF62jk0=" - }, - "node_modules/lodash.sortby": { - "version": "4.7.0", - "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz", - "integrity": "sha1-7dFMgk4sycHgsKG0K7UhBRakJDg=" - }, - "node_modules/lowercase-keys": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", - "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/lru-queue": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/lru-queue/-/lru-queue-0.1.0.tgz", - "integrity": "sha1-Jzi9nw089PhEkMVzbEhpmsYyzaM=", - "dependencies": { - "es5-ext": "~0.10.2" - } - }, - "node_modules/m3u8stream": { - "version": "0.8.3", - "resolved": "https://registry.npmjs.org/m3u8stream/-/m3u8stream-0.8.3.tgz", - "integrity": "sha512-0nAcdrF8YJKUkb6PzWdvGftTPyCVWgoiot1AkNVbPKTeIGsWs6DrOjifrJ0Zi8WQfQmD2SuVCjkYIOip12igng==", - "dependencies": { - "miniget": "^4.0.0", - "sax": "^1.2.4" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/make-dir": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", - "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", - "dependencies": { - "semver": "^6.0.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/make-dir/node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/makeerror": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.11.tgz", - "integrity": "sha1-4BpckQnyr3lmDk6LlYd5AYT1qWw=", - "dependencies": { - "tmpl": "1.0.x" - } - }, - "node_modules/map-cache": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", - "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/map-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", - "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", - "dependencies": { - "object-visit": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/memoizee": { - "version": "0.4.14", - "resolved": "https://registry.npmjs.org/memoizee/-/memoizee-0.4.14.tgz", - "integrity": "sha512-/SWFvWegAIYAO4NQMpcX+gcra0yEZu4OntmUdrBaWrJncxOqAziGFlHxc7yjKVK2uu3lpPW27P27wkR82wA8mg==", - "dependencies": { - "d": "1", - "es5-ext": "^0.10.45", - "es6-weak-map": "^2.0.2", - "event-emitter": "^0.3.5", - "is-promise": "^2.1", - "lru-queue": "0.1", - "next-tick": "1", - "timers-ext": "^0.1.5" - } - }, - "node_modules/merge-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", - "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==" - }, - "node_modules/micromatch": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", - "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==", - "dependencies": { - "braces": "^3.0.1", - "picomatch": "^2.0.5" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/mime-db": { - "version": "1.44.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.44.0.tgz", - "integrity": "sha512-/NOTfLrsPBVeH7YtFPgsVWveuL+4SjjYxaQ1xtM1KMFj7HdxlBlxeyNLzhyJVx7r4rZGJAZ/6lkKCitSc/Nmpg==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mime-types": { - "version": "2.1.27", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.27.tgz", - "integrity": "sha512-JIhqnCasI9yD+SsmkquHBxTSEuZdQX5BuQnS2Vc7puQQQ+8yiP5AY5uWhpdv4YL4VM5c6iliiYWPgJ/nJQLp7w==", - "dependencies": { - "mime-db": "1.44.0" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mimic-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", - "engines": { - "node": ">=6" - } - }, - "node_modules/mimic-response": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", - "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/miniget": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/miniget/-/miniget-4.1.0.tgz", - "integrity": "sha512-kzhrNv5L7LlomwGmPGQsLQ2PnT1LeJJWfB0wNFGyv426gEM1gsfziBQmfkr6XOBA8EusZg9nowlNT5CbuKTjZg==", - "engines": { - "node": ">=10" - } - }, - "node_modules/minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" - }, - "node_modules/minipass": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.3.tgz", - "integrity": "sha512-Mgd2GdMVzY+x3IJ+oHnVM+KG3lA5c8tnabyJKmHSaG2kAGpudxuOf8ToDkhumF7UzME7DecbQE9uOZhNm7PuJg==", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/minizlib": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", - "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", - "dependencies": { - "minipass": "^3.0.0", - "yallist": "^4.0.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/mixin-deep": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", - "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", - "dependencies": { - "for-in": "^1.0.2", - "is-extendable": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/mkdirp": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", - "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", - "dependencies": { - "minimist": "^1.2.5" - }, - "bin": { - "mkdirp": "bin/cmd.js" - } - }, - "node_modules/moment": { - "version": "2.29.1", - "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.1.tgz", - "integrity": "sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ==", - "engines": { - "node": "*" - } - }, - "node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - }, - "node_modules/nanomatch": { - "version": "1.2.13", - "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", - "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", - "dependencies": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "fragment-cache": "^0.2.1", - "is-windows": "^1.0.2", - "kind-of": "^6.0.2", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/natural-compare": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=" - }, - "node_modules/needle": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/needle/-/needle-2.5.2.tgz", - "integrity": "sha512-LbRIwS9BfkPvNwNHlsA41Q29kL2L/6VaOJ0qisM5lLWsTV3nP15abO5ITL6L81zqFhzjRKDAYjpcBcwM0AVvLQ==", - "dependencies": { - "debug": "^3.2.6", - "iconv-lite": "^0.4.4", - "sax": "^1.2.4" - }, - "bin": { - "needle": "bin/needle" - }, - "engines": { - "node": ">= 4.4.x" - } - }, - "node_modules/needle/node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dependencies": { - "ms": "^2.1.1" - } - }, - "node_modules/next-tick": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz", - "integrity": "sha1-yobR/ogoFpsBICCOPchCS524NCw=" - }, - "node_modules/nice-try": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", - "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==" - }, - "node_modules/node-addon-api": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-3.1.0.tgz", - "integrity": "sha512-flmrDNB06LIl5lywUz7YlNGZH/5p0M7W28k8hzd9Lshtdh1wshD2Y+U4h9LD6KObOy1f+fEVdgprPrEymjM5uw==" - }, - "node_modules/node-fetch": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz", - "integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==", - "engines": { - "node": "4.x || >=6.0.0" - } - }, - "node_modules/node-fzf": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/node-fzf/-/node-fzf-0.5.3.tgz", - "integrity": "sha512-crN8rRfApu/GUrtKq+zJ6LueUyNAOJpFHxoT2Ru1Q+OYRa/F/H7CXvzcMrFc7D964yakYZEZ9XR3YbdSHXgyCw==", - "dependencies": { - "cli-color": "~1.2.0", - "keypress": "~0.2.1", - "minimist": "~1.2.0", - "redstar": "0.0.2", - "string-width": "~2.1.1", - "ttys": "0.0.3" - }, - "bin": { - "nfzf": "bin/cli.js" - } - }, - "node_modules/node-fzf/node_modules/ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "engines": { - "node": ">=4" - } - }, - "node_modules/node-fzf/node_modules/is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "engines": { - "node": ">=4" - } - }, - "node_modules/node-fzf/node_modules/string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "dependencies": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/node-fzf/node_modules/strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dependencies": { - "ansi-regex": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/node-int64": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", - "integrity": "sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs=" - }, - "node_modules/node-modules-regexp": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/node-modules-regexp/-/node-modules-regexp-1.0.0.tgz", - "integrity": "sha1-jZ2+KJZKSsVxLpExZCEHxx6Q7EA=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/node-notifier": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/node-notifier/-/node-notifier-8.0.1.tgz", - "integrity": "sha512-BvEXF+UmsnAfYfoapKM9nGxnP+Wn7P91YfXmrKnfcYCx6VBeoN5Ez5Ogck6I8Bi5k4RlpqRYaw75pAwzX9OphA==", - "optional": true, - "dependencies": { - "growly": "^1.3.0", - "is-wsl": "^2.2.0", - "semver": "^7.3.2", - "shellwords": "^0.1.1", - "uuid": "^8.3.0", - "which": "^2.0.2" - } - }, - "node_modules/nodemon": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-2.0.6.tgz", - "integrity": "sha512-4I3YDSKXg6ltYpcnZeHompqac4E6JeAMpGm8tJnB9Y3T0ehasLa4139dJOcCrB93HHrUMsCrKtoAlXTqT5n4AQ==", - "dev": true, - "hasInstallScript": true, - "dependencies": { - "chokidar": "^3.2.2", - "debug": "^3.2.6", - "ignore-by-default": "^1.0.1", - "minimatch": "^3.0.4", - "pstree.remy": "^1.1.7", - "semver": "^5.7.1", - "supports-color": "^5.5.0", - "touch": "^3.1.0", - "undefsafe": "^2.0.3", - "update-notifier": "^4.1.0" - }, - "bin": { - "nodemon": "bin/nodemon.js" - }, - "engines": { - "node": ">=8.10.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/nodemon" - } - }, - "node_modules/nodemon/node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "dependencies": { - "ms": "^2.1.1" - } - }, - "node_modules/nodemon/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/nodemon/node_modules/semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true, - "bin": { - "semver": "bin/semver" - } - }, - "node_modules/nodemon/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/nopt": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-4.0.3.tgz", - "integrity": "sha512-CvaGwVMztSMJLOeXPrez7fyfObdZqNUK1cPAEzLHrTybIua9pMdmmPR5YwtfNftIOMv3DPUhFaxsZMNTQO20Kg==", - "dependencies": { - "abbrev": "1", - "osenv": "^0.1.4" - }, - "bin": { - "nopt": "bin/nopt.js" - } - }, - "node_modules/normalize-package-data": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", - "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", - "dependencies": { - "hosted-git-info": "^2.1.4", - "resolve": "^1.10.0", - "semver": "2 || 3 || 4 || 5", - "validate-npm-package-license": "^3.0.1" - } - }, - "node_modules/normalize-package-data/node_modules/semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "bin": { - "semver": "bin/semver" - } - }, - "node_modules/normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/normalize-url": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.0.tgz", - "integrity": "sha512-2s47yzUxdexf1OhyRi4Em83iQk0aPvwTddtFz4hnSSw9dCEsLEGf6SwIO8ss/19S9iBb5sJaOuTvTGDeZI00BQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/npm-bundled": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/npm-bundled/-/npm-bundled-1.1.1.tgz", - "integrity": "sha512-gqkfgGePhTpAEgUsGEgcq1rqPXA+tv/aVBlgEzfXwA1yiUJF7xtEt3CtVwOjNYQOVknDk0F20w58Fnm3EtG0fA==", - "dependencies": { - "npm-normalize-package-bin": "^1.0.1" - } - }, - "node_modules/npm-normalize-package-bin": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/npm-normalize-package-bin/-/npm-normalize-package-bin-1.0.1.tgz", - "integrity": "sha512-EPfafl6JL5/rU+ot6P3gRSCpPDW5VmIzX959Ob1+ySFUuuYHWHekXpwdUZcKP5C+DS4GEtdJluwBjnsNDl+fSA==" - }, - "node_modules/npm-packlist": { - "version": "1.4.8", - "resolved": "https://registry.npmjs.org/npm-packlist/-/npm-packlist-1.4.8.tgz", - "integrity": "sha512-5+AZgwru5IevF5ZdnFglB5wNlHG1AOOuw28WhUq8/8emhBmLv6jX5by4WJCh7lW0uSYZYS6DXqIsyZVIXRZU9A==", - "dependencies": { - "ignore-walk": "^3.0.1", - "npm-bundled": "^1.0.1", - "npm-normalize-package-bin": "^1.0.1" - } - }, - "node_modules/npm-run-path": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", - "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", - "dependencies": { - "path-key": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/npmlog": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz", - "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", - "dependencies": { - "are-we-there-yet": "~1.1.2", - "console-control-strings": "~1.1.0", - "gauge": "~2.7.3", - "set-blocking": "~2.0.0" - } - }, - "node_modules/nth-check": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-1.0.2.tgz", - "integrity": "sha512-WeBOdju8SnzPN5vTUJYxYUxLeXpCaVP5i5e0LF8fg7WORF2Wd7wFX/pk0tYZk7s8T+J7VLy0Da6J1+wCT0AtHg==", - "dependencies": { - "boolbase": "~1.0.0" - } - }, - "node_modules/number-is-nan": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", - "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/nwsapi": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.0.tgz", - "integrity": "sha512-h2AatdwYH+JHiZpv7pt/gSX1XoRGb7L/qSIeuqA6GwYoF9w1vP1cw42TO0aI2pNyshRK5893hNSl+1//vHK7hQ==" - }, - "node_modules/oauth-sign": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", - "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", - "engines": { - "node": "*" - } - }, - "node_modules/object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object-copy": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", - "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", - "dependencies": { - "copy-descriptor": "^0.1.0", - "define-property": "^0.2.5", - "kind-of": "^3.0.3" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object-copy/node_modules/define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dependencies": { - "is-descriptor": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object-copy/node_modules/is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object-copy/node_modules/is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object-copy/node_modules/is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dependencies": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object-copy/node_modules/is-descriptor/node_modules/kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object-copy/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object-visit": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", - "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", - "dependencies": { - "isobject": "^3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object.pick": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", - "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", - "dependencies": { - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "dependencies": { - "wrappy": "1" - } - }, - "node_modules/onetime": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", - "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", - "dependencies": { - "mimic-fn": "^2.1.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/optionator": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", - "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", - "dev": true, - "dependencies": { - "deep-is": "^0.1.3", - "fast-levenshtein": "^2.0.6", - "levn": "^0.4.1", - "prelude-ls": "^1.2.1", - "type-check": "^0.4.0", - "word-wrap": "^1.2.3" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/os-homedir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", - "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/os-tmpdir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", - "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/osenv": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.5.tgz", - "integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==", - "dependencies": { - "os-homedir": "^1.0.0", - "os-tmpdir": "^1.0.0" - } - }, - "node_modules/p-cancelable": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-1.1.0.tgz", - "integrity": "sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/p-each-series": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-each-series/-/p-each-series-2.2.0.tgz", - "integrity": "sha512-ycIL2+1V32th+8scbpTvyHNaHe02z0sjgh91XXjAk+ZeXoPN4Z46DVUnzdso0aX4KckKw0FNNFHdjZ2UsZvxiA==", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-finally": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", - "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", - "engines": { - "node": ">=4" - } - }, - "node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dependencies": { - "p-try": "^2.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dependencies": { - "p-limit": "^2.2.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "engines": { - "node": ">=6" - } - }, - "node_modules/package-json": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/package-json/-/package-json-6.5.0.tgz", - "integrity": "sha512-k3bdm2n25tkyxcjSKzB5x8kfVxlMdgsbPr0GkZcwHsLpba6cBjqCt1KlcChKEvxHIcTB1FVMuwoijZ26xex5MQ==", - "dev": true, - "dependencies": { - "got": "^9.6.0", - "registry-auth-token": "^4.0.0", - "registry-url": "^5.0.0", - "semver": "^6.2.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/package-json/node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/parent-module": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "dev": true, - "dependencies": { - "callsites": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/parse-cache-control": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parse-cache-control/-/parse-cache-control-1.0.1.tgz", - "integrity": "sha1-juqz5U+laSD+Fro493+iGqzC104=" - }, - "node_modules/parse-json": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.1.0.tgz", - "integrity": "sha512-+mi/lmVVNKFNVyLXV31ERiy2CY5E1/F6QtJFEzoChPRwwngMNXRDQ9GJ5WdE2Z2P4AujsOi0/+2qHID68KwfIQ==", - "dependencies": { - "@babel/code-frame": "^7.0.0", - "error-ex": "^1.3.1", - "json-parse-even-better-errors": "^2.3.0", - "lines-and-columns": "^1.1.6" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/parse5": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-5.1.1.tgz", - "integrity": "sha512-ugq4DFI0Ptb+WWjAdOK16+u/nHfiIrcE+sh8kZMaM0WllQKLI9rOUq6c2b7cwPkXdzfQESqvoqK6ug7U/Yyzug==" - }, - "node_modules/pascalcase": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", - "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "engines": { - "node": ">=8" - } - }, - "node_modules/path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "engines": { - "node": ">=8" - } - }, - "node_modules/path-parse": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", - "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==" - }, - "node_modules/performance-now": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" - }, - "node_modules/picomatch": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", - "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==", - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/pirates": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.1.tgz", - "integrity": "sha512-WuNqLTbMI3tmfef2TKxlQmAiLHKtFhlsCZnPIpuv2Ow0RDVO8lfy1Opf4NUzlMXLjPl+Men7AuVdX6TA+s+uGA==", - "dependencies": { - "node-modules-regexp": "^1.0.0" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/pkg-dir": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", - "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", - "dependencies": { - "find-up": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/posix-character-classes": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", - "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/prelude-ls": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", - "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", - "dev": true, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/prepend-http": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz", - "integrity": "sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc=", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/pretty-format": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", - "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", - "dependencies": { - "@jest/types": "^26.6.2", - "ansi-regex": "^5.0.0", - "ansi-styles": "^4.0.0", - "react-is": "^17.0.1" - }, - "engines": { - "node": ">= 10" - } - }, - "node_modules/prism-media": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/prism-media/-/prism-media-1.2.3.tgz", - "integrity": "sha512-fSrR66n0l6roW9Rx4rSLMyTPTjRTiXy5RVqDOurACQ6si1rKHHKDU5gwBJoCsIV0R3o9gi+K50akl/qyw1C74A==", - "peerDependencies": { - "@discordjs/opus": "^0.3.3", - "ffmpeg-static": "^4.2.7 || ^3.0.0 || ^2.4.0", - "node-opus": "^0.3.3", - "opusscript": "^0.0.7" - }, - "peerDependenciesMeta": { - "@discordjs/opus": { - "optional": true - }, - "ffmpeg-static": { - "optional": true - }, - "node-opus": { - "optional": true - }, - "opusscript": { - "optional": true - } - } - }, - "node_modules/process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" - }, - "node_modules/progress": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", - "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/prompts": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.0.tgz", - "integrity": "sha512-awZAKrk3vN6CroQukBL+R9051a4R3zCZBlJm/HBfrSZ8iTpYix3VX1vU4mveiLpiwmOJT4wokTF9m6HUk4KqWQ==", - "dependencies": { - "kleur": "^3.0.3", - "sisteransi": "^1.0.5" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/psl": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", - "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==" - }, - "node_modules/pstree.remy": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz", - "integrity": "sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==", - "dev": true - }, - "node_modules/pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "dependencies": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "node_modules/punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", - "engines": { - "node": ">=6" - } - }, - "node_modules/pupa": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/pupa/-/pupa-2.1.1.tgz", - "integrity": "sha512-l1jNAspIBSFqbT+y+5FosojNpVpF94nlI+wDUpqP9enwOTfHx9f0gh5nB96vl+6yTpsJsypeNrwfzPrKuHB41A==", - "dev": true, - "dependencies": { - "escape-goat": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/qs": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", - "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", - "engines": { - "node": ">=0.6" - } - }, - "node_modules/rc": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", - "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", - "dependencies": { - "deep-extend": "^0.6.0", - "ini": "~1.3.0", - "minimist": "^1.2.0", - "strip-json-comments": "~2.0.1" - }, - "bin": { - "rc": "cli.js" - } - }, - "node_modules/rc/node_modules/strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/react-is": { - "version": "17.0.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.1.tgz", - "integrity": "sha512-NAnt2iGDXohE5LI7uBnLnqvLQMtzhkiAOLXTmv+qnF9Ky7xAPcX8Up/xWIhxvLVGJvuLiNc4xQLtuqDRzb4fSA==" - }, - "node_modules/read-pkg": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", - "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", - "dependencies": { - "@types/normalize-package-data": "^2.4.0", - "normalize-package-data": "^2.5.0", - "parse-json": "^5.0.0", - "type-fest": "^0.6.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/read-pkg-up": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", - "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", - "dependencies": { - "find-up": "^4.1.0", - "read-pkg": "^5.2.0", - "type-fest": "^0.8.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/read-pkg/node_modules/type-fest": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", - "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", - "engines": { - "node": ">=8" - } - }, - "node_modules/readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "node_modules/readdirp": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.5.0.tgz", - "integrity": "sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ==", - "dev": true, - "dependencies": { - "picomatch": "^2.2.1" - }, - "engines": { - "node": ">=8.10.0" - } - }, - "node_modules/redstar": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/redstar/-/redstar-0.0.2.tgz", - "integrity": "sha1-nVammAY4yYUaEAsMs799PrkCBcs=", - "dependencies": { - "minimatch": "~3.0.4" - } - }, - "node_modules/regex-not": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", - "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", - "dependencies": { - "extend-shallow": "^3.0.2", - "safe-regex": "^1.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/regexpp": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.1.0.tgz", - "integrity": "sha512-ZOIzd8yVsQQA7j8GCSlPGXwg5PfmA1mrq0JP4nGhh54LaKN3xdai/vHUDu74pKwV8OxseMS65u2NImosQcSD0Q==", - "dev": true, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/mysticatea" - } - }, - "node_modules/registry-auth-token": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-4.2.1.tgz", - "integrity": "sha512-6gkSb4U6aWJB4SF2ZvLb76yCBjcvufXBqvvEx1HbmKPkutswjW1xNVRY0+daljIYRbogN7O0etYSlbiaEQyMyw==", - "dev": true, - "dependencies": { - "rc": "^1.2.8" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/registry-url": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-5.1.0.tgz", - "integrity": "sha512-8acYXXTI0AkQv6RAOjE3vOaIXZkT9wo4LOFbBKYQEEnnMNBpKqdUrI6S4NT0KPIo/WVvJ5tE/X5LF/TQUf0ekw==", - "dev": true, - "dependencies": { - "rc": "^1.2.8" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/remove-trailing-separator": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", - "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=" - }, - "node_modules/repeat-element": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz", - "integrity": "sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/repeat-string": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", - "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", - "engines": { - "node": ">=0.10" - } - }, - "node_modules/request": { - "version": "2.88.2", - "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", - "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", - "deprecated": "request has been deprecated, see https://github.com/request/request/issues/3142", - "dependencies": { - "aws-sign2": "~0.7.0", - "aws4": "^1.8.0", - "caseless": "~0.12.0", - "combined-stream": "~1.0.6", - "extend": "~3.0.2", - "forever-agent": "~0.6.1", - "form-data": "~2.3.2", - "har-validator": "~5.1.3", - "http-signature": "~1.2.0", - "is-typedarray": "~1.0.0", - "isstream": "~0.1.2", - "json-stringify-safe": "~5.0.1", - "mime-types": "~2.1.19", - "oauth-sign": "~0.9.0", - "performance-now": "^2.1.0", - "qs": "~6.5.2", - "safe-buffer": "^5.1.2", - "tough-cookie": "~2.5.0", - "tunnel-agent": "^0.6.0", - "uuid": "^3.3.2" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/request-promise-core": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.4.tgz", - "integrity": "sha512-TTbAfBBRdWD7aNNOoVOBH4pN/KigV6LyapYNNlAPA8JwbovRti1E88m3sYAwsLi5ryhPKsE9APwnjFTgdUjTpw==", - "dependencies": { - "lodash": "^4.17.19" - }, - "engines": { - "node": ">=0.10.0" - }, - "peerDependencies": { - "request": "^2.34" - } - }, - "node_modules/request-promise-native": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/request-promise-native/-/request-promise-native-1.0.9.tgz", - "integrity": "sha512-wcW+sIUiWnKgNY0dqCpOZkUbF/I+YPi+f09JZIDa39Ec+q82CpSYniDp+ISgTTbKmnpJWASeJBPZmoxH84wt3g==", - "deprecated": "request-promise-native has been deprecated because it extends the now deprecated request package, see https://github.com/request/request/issues/3142", - "dependencies": { - "request-promise-core": "1.1.4", - "stealthy-require": "^1.1.1", - "tough-cookie": "^2.3.3" - }, - "engines": { - "node": ">=0.12.0" - }, - "peerDependencies": { - "request": "^2.34" - } - }, - "node_modules/request-promise-native/node_modules/tough-cookie": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", - "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", - "dependencies": { - "psl": "^1.1.28", - "punycode": "^2.1.1" - }, - "engines": { - "node": ">=0.8" - } - }, - "node_modules/request/node_modules/tough-cookie": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", - "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", - "dependencies": { - "psl": "^1.1.28", - "punycode": "^2.1.1" - }, - "engines": { - "node": ">=0.8" - } - }, - "node_modules/request/node_modules/uuid": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", - "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", - "bin": { - "uuid": "bin/uuid" - } - }, - "node_modules/require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/require-main-filename": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", - "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==" - }, - "node_modules/resolve": { - "version": "1.19.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.19.0.tgz", - "integrity": "sha512-rArEXAgsBG4UgRGcynxWIWKFvh/XZCcS8UJdHhwy91zwAvCZIbcs+vAbflgBnNjYMs/i/i+/Ux6IZhML1yPvxg==", - "dependencies": { - "is-core-module": "^2.1.0", - "path-parse": "^1.0.6" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/resolve-cwd": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", - "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", - "dependencies": { - "resolve-from": "^5.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/resolve-cwd/node_modules/resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", - "engines": { - "node": ">=8" - } - }, - "node_modules/resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/resolve-url": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", - "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", - "deprecated": "https://github.com/lydell/resolve-url#deprecated" - }, - "node_modules/responselike": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz", - "integrity": "sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec=", - "dev": true, - "dependencies": { - "lowercase-keys": "^1.0.0" - } - }, - "node_modules/ret": { - "version": "0.1.15", - "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", - "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", - "engines": { - "node": ">=0.12" - } - }, - "node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/roll": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/roll/-/roll-1.3.1.tgz", - "integrity": "sha512-f6ePWG9fqC5RZE4CqFfxSqfvpOs3sZlxpvtdpNCHPKz76L1oJP8wQzqrMCHpXg8Ahc+53A7RPXMptDUxwciZow==", - "dependencies": { - "minimist": "^1.2.5" - }, - "bin": { - "roll": "bin/roll" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/rsvp": { - "version": "4.8.5", - "resolved": "https://registry.npmjs.org/rsvp/-/rsvp-4.8.5.tgz", - "integrity": "sha512-nfMOlASu9OnRJo1mbEk2cz0D56a1MBNrJ7orjRZQG10XDyuvwksKbuXNp6qa+kbn839HwjwhBzhFmdsaEAfauA==", - "engines": { - "node": "6.* || >= 7.*" - } - }, - "node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" - }, - "node_modules/safe-regex": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", - "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", - "dependencies": { - "ret": "~0.1.10" - } - }, - "node_modules/safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" - }, - "node_modules/sane": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/sane/-/sane-4.1.0.tgz", - "integrity": "sha512-hhbzAgTIX8O7SHfp2c8/kREfEn4qO/9q8C9beyY6+tvZ87EpoZ3i1RIEvp27YBswnNbY9mWd6paKVmKbAgLfZA==", - "dependencies": { - "@cnakazawa/watch": "^1.0.3", - "anymatch": "^2.0.0", - "capture-exit": "^2.0.0", - "exec-sh": "^0.3.2", - "execa": "^1.0.0", - "fb-watchman": "^2.0.0", - "micromatch": "^3.1.4", - "minimist": "^1.1.1", - "walker": "~1.0.5" - }, - "bin": { - "sane": "src/cli.js" - }, - "engines": { - "node": "6.* || 8.* || >= 10.*" - } - }, - "node_modules/sane/node_modules/anymatch": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", - "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", - "dependencies": { - "micromatch": "^3.1.4", - "normalize-path": "^2.1.1" - } - }, - "node_modules/sane/node_modules/braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dependencies": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/sane/node_modules/braces/node_modules/extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dependencies": { - "is-extendable": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/sane/node_modules/cross-spawn": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", - "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", - "dependencies": { - "nice-try": "^1.0.4", - "path-key": "^2.0.1", - "semver": "^5.5.0", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - }, - "engines": { - "node": ">=4.8" - } - }, - "node_modules/sane/node_modules/execa": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", - "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", - "dependencies": { - "cross-spawn": "^6.0.0", - "get-stream": "^4.0.0", - "is-stream": "^1.1.0", - "npm-run-path": "^2.0.0", - "p-finally": "^1.0.0", - "signal-exit": "^3.0.0", - "strip-eof": "^1.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/sane/node_modules/fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dependencies": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/sane/node_modules/fill-range/node_modules/extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dependencies": { - "is-extendable": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/sane/node_modules/is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/sane/node_modules/is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/sane/node_modules/is-number/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/sane/node_modules/is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/sane/node_modules/micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dependencies": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/sane/node_modules/normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "dependencies": { - "remove-trailing-separator": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/sane/node_modules/npm-run-path": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", - "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", - "dependencies": { - "path-key": "^2.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/sane/node_modules/path-key": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", - "engines": { - "node": ">=4" - } - }, - "node_modules/sane/node_modules/semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "bin": { - "semver": "bin/semver" - } - }, - "node_modules/sane/node_modules/shebang-command": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", - "dependencies": { - "shebang-regex": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/sane/node_modules/shebang-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/sane/node_modules/to-regex-range": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", - "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", - "dependencies": { - "is-number": "^3.0.0", - "repeat-string": "^1.6.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/sane/node_modules/which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "which": "bin/which" - } - }, - "node_modules/sax": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", - "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==" - }, - "node_modules/saxes": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/saxes/-/saxes-5.0.1.tgz", - "integrity": "sha512-5LBh1Tls8c9xgGjw3QrMwETmTMVk0oFgvrFSvWx62llR2hcEInrKNZ2GZCCuuy2lvWrdl5jhbpeqc5hRYKFOcw==", - "dependencies": { - "xmlchars": "^2.2.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/semver": { - "version": "7.3.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.4.tgz", - "integrity": "sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw==", - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/semver-diff": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/semver-diff/-/semver-diff-3.1.1.tgz", - "integrity": "sha512-GX0Ix/CJcHyB8c4ykpHGIAvLyOwOobtM/8d+TQkAd81/bEjgPHrfba41Vpesr7jX/t8Uh+R3EX9eAS5be+jQYg==", - "dev": true, - "dependencies": { - "semver": "^6.3.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/semver-diff/node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/set-blocking": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=" - }, - "node_modules/set-value": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", - "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", - "dependencies": { - "extend-shallow": "^2.0.1", - "is-extendable": "^0.1.1", - "is-plain-object": "^2.0.3", - "split-string": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/set-value/node_modules/extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dependencies": { - "is-extendable": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/set-value/node_modules/is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/setimmediate": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", - "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=" - }, - "node_modules/shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dependencies": { - "shebang-regex": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "engines": { - "node": ">=8" - } - }, - "node_modules/shellwords": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/shellwords/-/shellwords-0.1.1.tgz", - "integrity": "sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww==", - "optional": true - }, - "node_modules/signal-exit": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", - "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==" - }, - "node_modules/sisteransi": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", - "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==" - }, - "node_modules/slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "engines": { - "node": ">=8" - } - }, - "node_modules/slice-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", - "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.0.0", - "astral-regex": "^2.0.0", - "is-fullwidth-code-point": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/slice-ansi?sponsor=1" - } - }, - "node_modules/slice-ansi/node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/snapdragon": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", - "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", - "dependencies": { - "base": "^0.11.1", - "debug": "^2.2.0", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "map-cache": "^0.2.2", - "source-map": "^0.5.6", - "source-map-resolve": "^0.5.0", - "use": "^3.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon-node": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", - "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", - "dependencies": { - "define-property": "^1.0.0", - "isobject": "^3.0.0", - "snapdragon-util": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon-node/node_modules/define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dependencies": { - "is-descriptor": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon-util": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", - "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", - "dependencies": { - "kind-of": "^3.2.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon-util/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/snapdragon/node_modules/define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dependencies": { - "is-descriptor": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon/node_modules/extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dependencies": { - "is-extendable": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon/node_modules/is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon/node_modules/is-accessor-descriptor/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon/node_modules/is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon/node_modules/is-data-descriptor/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon/node_modules/is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dependencies": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon/node_modules/is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon/node_modules/kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - }, - "node_modules/snapdragon/node_modules/source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/source-map-resolve": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz", - "integrity": "sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==", - "dependencies": { - "atob": "^2.1.2", - "decode-uri-component": "^0.2.0", - "resolve-url": "^0.2.1", - "source-map-url": "^0.4.0", - "urix": "^0.1.0" - } - }, - "node_modules/source-map-support": { - "version": "0.5.19", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz", - "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==", - "dependencies": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, - "node_modules/source-map-url": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz", - "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=" - }, - "node_modules/spdx-correct": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz", - "integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==", - "dependencies": { - "spdx-expression-parse": "^3.0.0", - "spdx-license-ids": "^3.0.0" - } - }, - "node_modules/spdx-exceptions": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz", - "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==" - }, - "node_modules/spdx-expression-parse": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", - "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", - "dependencies": { - "spdx-exceptions": "^2.1.0", - "spdx-license-ids": "^3.0.0" - } - }, - "node_modules/spdx-license-ids": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.7.tgz", - "integrity": "sha512-U+MTEOO0AiDzxwFvoa4JVnMV6mZlJKk2sBLt90s7G0Gd0Mlknc7kxEn3nuDPNZRta7O2uy8oLcZLVT+4sqNZHQ==" - }, - "node_modules/split-string": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", - "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", - "dependencies": { - "extend-shallow": "^3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" - }, - "node_modules/sshpk": { - "version": "1.16.1", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", - "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", - "dependencies": { - "asn1": "~0.2.3", - "assert-plus": "^1.0.0", - "bcrypt-pbkdf": "^1.0.0", - "dashdash": "^1.12.0", - "ecc-jsbn": "~0.1.1", - "getpass": "^0.1.1", - "jsbn": "~0.1.0", - "safer-buffer": "^2.0.2", - "tweetnacl": "~0.14.0" - }, - "bin": { - "sshpk-conv": "bin/sshpk-conv", - "sshpk-sign": "bin/sshpk-sign", - "sshpk-verify": "bin/sshpk-verify" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/sshpk/node_modules/tweetnacl": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" - }, - "node_modules/stack-utils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.3.tgz", - "integrity": "sha512-gL//fkxfWUsIlFL2Tl42Cl6+HFALEaB1FU76I/Fy+oZjRreP7OPMXFlGbxM7NQsI0ZpUfw76sHnv0WNYuTb7Iw==", - "dependencies": { - "escape-string-regexp": "^2.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/stack-utils/node_modules/escape-string-regexp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", - "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", - "engines": { - "node": ">=8" - } - }, - "node_modules/static-eval": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/static-eval/-/static-eval-2.0.2.tgz", - "integrity": "sha512-N/D219Hcr2bPjLxPiV+TQE++Tsmrady7TqAJugLy7Xk1EumfDWS/f5dtBbkRCGE7wKKXuYockQoj8Rm2/pVKyg==", - "dependencies": { - "escodegen": "^1.8.1" - } - }, - "node_modules/static-extend": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", - "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", - "dependencies": { - "define-property": "^0.2.5", - "object-copy": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/static-extend/node_modules/define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dependencies": { - "is-descriptor": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/static-extend/node_modules/is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/static-extend/node_modules/is-accessor-descriptor/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/static-extend/node_modules/is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/static-extend/node_modules/is-data-descriptor/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/static-extend/node_modules/is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dependencies": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/static-extend/node_modules/kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/stealthy-require": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/stealthy-require/-/stealthy-require-1.1.1.tgz", - "integrity": "sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dependencies": { - "safe-buffer": "~5.1.0" - } - }, - "node_modules/string-length": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.1.tgz", - "integrity": "sha512-PKyXUd0LK0ePjSOnWn34V2uD6acUWev9uy0Ft05k0E8xRW+SKcA0F7eMr7h5xlzfn+4O3N+55rduYyet3Jk+jw==", - "dependencies": { - "char-regex": "^1.0.2", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/string-width": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", - "dependencies": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/string-width/node_modules/ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/string-width/node_modules/strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dependencies": { - "ansi-regex": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/strip-ansi": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", - "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", - "dependencies": { - "ansi-regex": "^5.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-bom": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", - "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-eof": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", - "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/strip-final-newline": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", - "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", - "engines": { - "node": ">=6" - } - }, - "node_modules/strip-json-comments": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", - "dev": true, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/supports-hyperlinks": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-2.1.0.tgz", - "integrity": "sha512-zoE5/e+dnEijk6ASB6/qrK+oYdm2do1hjoLWrqUC/8WEIW1gbxFcKuBof7sW8ArN6e+AYvsE8HBGiVRWL/F5CA==", - "dependencies": { - "has-flag": "^4.0.0", - "supports-color": "^7.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/symbol-tree": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", - "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==" - }, - "node_modules/table": { - "version": "6.0.4", - "resolved": "https://registry.npmjs.org/table/-/table-6.0.4.tgz", - "integrity": "sha512-sBT4xRLdALd+NFBvwOz8bw4b15htyythha+q+DVZqy2RS08PPC8O2sZFgJYEY7bJvbCFKccs+WIZ/cd+xxTWCw==", - "dev": true, - "dependencies": { - "ajv": "^6.12.4", - "lodash": "^4.17.20", - "slice-ansi": "^4.0.0", - "string-width": "^4.2.0" - }, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/table/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, - "node_modules/table/node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/table/node_modules/string-width": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", - "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", - "dev": true, - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/tar": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/tar/-/tar-6.0.5.tgz", - "integrity": "sha512-0b4HOimQHj9nXNEAA7zWwMM91Zhhba3pspja6sQbgTpynOJf+bkjBnfybNYzbpLbnwXnbyB4LOREvlyXLkCHSg==", - "dependencies": { - "chownr": "^2.0.0", - "fs-minipass": "^2.0.0", - "minipass": "^3.0.0", - "minizlib": "^2.1.1", - "mkdirp": "^1.0.3", - "yallist": "^4.0.0" - }, - "engines": { - "node": ">= 10" - } - }, - "node_modules/tar/node_modules/mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", - "bin": { - "mkdirp": "bin/cmd.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/term-size": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/term-size/-/term-size-2.2.1.tgz", - "integrity": "sha512-wK0Ri4fOGjv/XPy8SBHZChl8CM7uMc5VML7SqiQ0zG7+J5Vr+RMQDoHa2CNT6KHUnTGIXH34UDMkPzAUyapBZg==", - "dev": true, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/terminal-link": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/terminal-link/-/terminal-link-2.1.1.tgz", - "integrity": "sha512-un0FmiRUQNr5PJqy9kP7c40F5BOfpGlYTrxonDChEZB7pzZxRNp/bt+ymiy9/npwXya9KH99nJ/GXFIiUkYGFQ==", - "dependencies": { - "ansi-escapes": "^4.2.1", - "supports-hyperlinks": "^2.0.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/test-exclude": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", - "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", - "dependencies": { - "@istanbuljs/schema": "^0.1.2", - "glob": "^7.1.4", - "minimatch": "^3.0.4" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/text-table": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", - "dev": true - }, - "node_modules/throat": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/throat/-/throat-5.0.0.tgz", - "integrity": "sha512-fcwX4mndzpLQKBS1DVYhGAcYaYt7vsHNIvQV+WXMvnow5cgjPphq5CaayLaGsjRdSCKZFNGt7/GYAuXaNOiYCA==" - }, - "node_modules/timers-ext": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/timers-ext/-/timers-ext-0.1.7.tgz", - "integrity": "sha512-b85NUNzTSdodShTIbky6ZF02e8STtVVfD+fu4aXXShEELpozH+bCpJLYMPZbsABN2wDH7fJpqIoXxJpzbf0NqQ==", - "dependencies": { - "es5-ext": "~0.10.46", - "next-tick": "1" - } - }, - "node_modules/tmpl": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.4.tgz", - "integrity": "sha1-I2QN17QtAEM5ERQIIOXPRA5SHdE=" - }, - "node_modules/to-fast-properties": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", - "engines": { - "node": ">=4" - } - }, - "node_modules/to-object-path": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", - "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/to-object-path/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/to-readable-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/to-readable-stream/-/to-readable-stream-1.0.0.tgz", - "integrity": "sha512-Iq25XBt6zD5npPhlLVXGFN3/gyR2/qODcKNNyTMd4vbm39HUaOiAM4PMq0eMVC/Tkxz+Zjdsc55g9yyz+Yq00Q==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/to-regex": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", - "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", - "dependencies": { - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "regex-not": "^1.0.2", - "safe-regex": "^1.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dependencies": { - "is-number": "^7.0.0" - }, - "engines": { - "node": ">=8.0" - } - }, - "node_modules/touch": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/touch/-/touch-3.1.0.tgz", - "integrity": "sha512-WBx8Uy5TLtOSRtIq+M03/sKDrXCLHxwDcquSP2c43Le03/9serjQBIztjRz6FkJez9D/hleyAXTBGLwwZUw9lA==", - "dev": true, - "dependencies": { - "nopt": "~1.0.10" - }, - "bin": { - "nodetouch": "bin/nodetouch.js" - } - }, - "node_modules/touch/node_modules/nopt": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz", - "integrity": "sha1-bd0hvSoxQXuScn3Vhfim83YI6+4=", - "dev": true, - "dependencies": { - "abbrev": "1" - }, - "bin": { - "nopt": "bin/nopt.js" - } - }, - "node_modules/tough-cookie": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-3.0.1.tgz", - "integrity": "sha512-yQyJ0u4pZsv9D4clxO69OEjLWYw+jbgspjTue4lTQZLfV0c5l1VmK2y1JK8E9ahdpltPOaAThPcp5nKPUgSnsg==", - "dependencies": { - "ip-regex": "^2.1.0", - "psl": "^1.1.28", - "punycode": "^2.1.1" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/tr46": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-2.0.2.tgz", - "integrity": "sha512-3n1qG+/5kg+jrbTzwAykB5yRYtQCTqOGKq5U5PE3b0a1/mzo6snDhjGS0zJVJunO0NrT3Dg1MLy5TjWP/UJppg==", - "dependencies": { - "punycode": "^2.1.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/ttys": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/ttys/-/ttys-0.0.3.tgz", - "integrity": "sha1-FbrN54MQIN5fLyjwGxcy7wNlH00=", - "engines": { - "node": ">= 0.6.0" - } - }, - "node_modules/tunnel-agent": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", - "dependencies": { - "safe-buffer": "^5.0.1" - }, - "engines": { - "node": "*" - } - }, - "node_modules/tweetnacl": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.3.tgz", - "integrity": "sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==" - }, - "node_modules/type": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/type/-/type-1.2.0.tgz", - "integrity": "sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg==" - }, - "node_modules/type-check": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", - "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", - "dev": true, - "dependencies": { - "prelude-ls": "^1.2.1" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/type-detect": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", - "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", - "engines": { - "node": ">=4" - } - }, - "node_modules/type-fest": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", - "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", - "engines": { - "node": ">=8" - } - }, - "node_modules/typedarray": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=" - }, - "node_modules/typedarray-to-buffer": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", - "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", - "dependencies": { - "is-typedarray": "^1.0.0" - } - }, - "node_modules/undefsafe": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.3.tgz", - "integrity": "sha512-nrXZwwXrD/T/JXeygJqdCO6NZZ1L66HrxM/Z7mIq2oPanoN0F1nLx3lwJMu6AwJY69hdixaFQOuoYsMjE5/C2A==", - "dev": true, - "dependencies": { - "debug": "^2.2.0" - } - }, - "node_modules/undefsafe/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/undefsafe/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - }, - "node_modules/underscore": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.7.0.tgz", - "integrity": "sha1-a7rwh3UA02vjTsqlhODbn+8DUgk=" - }, - "node_modules/union-value": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", - "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==", - "dependencies": { - "arr-union": "^3.1.0", - "get-value": "^2.0.6", - "is-extendable": "^0.1.1", - "set-value": "^2.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/union-value/node_modules/is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/unique-string": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-2.0.0.tgz", - "integrity": "sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg==", - "dev": true, - "dependencies": { - "crypto-random-string": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/unset-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", - "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", - "dependencies": { - "has-value": "^0.3.1", - "isobject": "^3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/unset-value/node_modules/has-value": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", - "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", - "dependencies": { - "get-value": "^2.0.3", - "has-values": "^0.1.4", - "isobject": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/unset-value/node_modules/has-value/node_modules/isobject": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", - "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", - "dependencies": { - "isarray": "1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/unset-value/node_modules/has-values": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", - "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/update-notifier": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-4.1.3.tgz", - "integrity": "sha512-Yld6Z0RyCYGB6ckIjffGOSOmHXj1gMeE7aROz4MG+XMkmixBX4jUngrGXNYz7wPKBmtoD4MnBa2Anu7RSKht/A==", - "dev": true, - "dependencies": { - "boxen": "^4.2.0", - "chalk": "^3.0.0", - "configstore": "^5.0.1", - "has-yarn": "^2.1.0", - "import-lazy": "^2.1.0", - "is-ci": "^2.0.0", - "is-installed-globally": "^0.3.1", - "is-npm": "^4.0.0", - "is-yarn-global": "^0.3.0", - "latest-version": "^5.0.0", - "pupa": "^2.0.1", - "semver-diff": "^3.1.1", - "xdg-basedir": "^4.0.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/yeoman/update-notifier?sponsor=1" - } - }, - "node_modules/update-notifier/node_modules/chalk": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", - "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/uri-js": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.0.tgz", - "integrity": "sha512-B0yRTzYdUCCn9n+F4+Gh4yIDtMQcaJsmYBDsTSG8g/OejKBodLQ2IHfN3bM7jUsRXndopT7OIXWdYqc1fjmV6g==", - "dependencies": { - "punycode": "^2.1.0" - } - }, - "node_modules/urix": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", - "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=", - "deprecated": "Please see https://github.com/lydell/urix#deprecated" - }, - "node_modules/url-parse-lax": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-3.0.0.tgz", - "integrity": "sha1-FrXK/Afb42dsGxmZF3gj1lA6yww=", - "dev": true, - "dependencies": { - "prepend-http": "^2.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/use": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", - "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" - }, - "node_modules/utils-extend": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/utils-extend/-/utils-extend-1.0.8.tgz", - "integrity": "sha1-zP17ZFQPjpDuIe7Fd2nQZRyril8=" - }, - "node_modules/uuid": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", - "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", - "optional": true, - "bin": { - "uuid": "dist/bin/uuid" - } - }, - "node_modules/v8-compile-cache": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.2.0.tgz", - "integrity": "sha512-gTpR5XQNKFwOd4clxfnhaqvfqMpqEwr4tOtCyz4MtYZX2JYhfr1JvBFKdS+7K/9rfpZR3VLX+YWBbKoxCgS43Q==", - "dev": true - }, - "node_modules/v8-to-istanbul": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-7.1.0.tgz", - "integrity": "sha512-uXUVqNUCLa0AH1vuVxzi+MI4RfxEOKt9pBgKwHbgH7st8Kv2P1m+jvWNnektzBh5QShF3ODgKmUFCf38LnVz1g==", - "dependencies": { - "@types/istanbul-lib-coverage": "^2.0.1", - "convert-source-map": "^1.6.0", - "source-map": "^0.7.3" - }, - "engines": { - "node": ">=10.10.0" - } - }, - "node_modules/v8-to-istanbul/node_modules/source-map": { - "version": "0.7.3", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", - "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==", - "engines": { - "node": ">= 8" - } - }, - "node_modules/validate-npm-package-license": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", - "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", - "dependencies": { - "spdx-correct": "^3.0.0", - "spdx-expression-parse": "^3.0.0" - } - }, - "node_modules/verror": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", - "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", - "engines": [ - "node >=0.6.0" - ], - "dependencies": { - "assert-plus": "^1.0.0", - "core-util-is": "1.0.2", - "extsprintf": "^1.2.0" - } - }, - "node_modules/voca": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/voca/-/voca-1.4.0.tgz", - "integrity": "sha512-8Xz4H3vhYRGbFupLtl6dHwMx0ojUcjt0HYkqZ9oBCfipd/5mD7Md58m2/dq7uPuZU/0T3Gb1m66KS9jn+I+14Q==", - "license": "MIT" - }, - "node_modules/w3c-hr-time": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz", - "integrity": "sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ==", - "dependencies": { - "browser-process-hrtime": "^1.0.0" - } - }, - "node_modules/w3c-xmlserializer": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-2.0.0.tgz", - "integrity": "sha512-4tzD0mF8iSiMiNs30BiLO3EpfGLZUT2MSX/G+o7ZywDzliWQ3OPtTZ0PTC3B3ca1UAf4cJMHB+2Bf56EriJuRA==", - "dependencies": { - "xml-name-validator": "^3.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/walker": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.7.tgz", - "integrity": "sha1-L3+bj9ENZ3JisYqITijRlhjgKPs=", - "dependencies": { - "makeerror": "1.0.x" - } - }, - "node_modules/webidl-conversions": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-6.1.0.tgz", - "integrity": "sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w==", - "engines": { - "node": ">=10.4" - } - }, - "node_modules/whatwg-encoding": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz", - "integrity": "sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw==", - "dependencies": { - "iconv-lite": "0.4.24" - } - }, - "node_modules/whatwg-mimetype": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz", - "integrity": "sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g==" - }, - "node_modules/whatwg-url": { - "version": "8.4.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-8.4.0.tgz", - "integrity": "sha512-vwTUFf6V4zhcPkWp/4CQPr1TW9Ml6SF4lVyaIMBdJw5i6qUUJ1QWM4Z6YYVkfka0OUIzVo/0aNtGVGk256IKWw==", - "dependencies": { - "lodash.sortby": "^4.7.0", - "tr46": "^2.0.2", - "webidl-conversions": "^6.1.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/which-module": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", - "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=" - }, - "node_modules/wide-align": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", - "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", - "dependencies": { - "string-width": "^1.0.2 || 2" - } - }, - "node_modules/widest-line": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-3.1.0.tgz", - "integrity": "sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg==", - "dev": true, - "dependencies": { - "string-width": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/widest-line/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, - "node_modules/widest-line/node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/widest-line/node_modules/string-width": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", - "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", - "dev": true, - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/word-wrap": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", - "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/wrap-ansi": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", - "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/wrap-ansi/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" - }, - "node_modules/wrap-ansi/node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "engines": { - "node": ">=8" - } - }, - "node_modules/wrap-ansi/node_modules/string-width": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", - "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" - }, - "node_modules/write-file-atomic": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", - "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", - "dependencies": { - "imurmurhash": "^0.1.4", - "is-typedarray": "^1.0.0", - "signal-exit": "^3.0.2", - "typedarray-to-buffer": "^3.1.5" - } - }, - "node_modules/ws": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.1.tgz", - "integrity": "sha512-pTsP8UAfhy3sk1lSk/O/s4tjD0CRwvMnzvwr4OKGX7ZvqZtUyx4KIJB5JWbkykPoc55tixMGgTNoh3k4FkNGFQ==", - "engines": { - "node": ">=8.3.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": "^5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } - } - }, - "node_modules/xdg-basedir": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-4.0.0.tgz", - "integrity": "sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/xml-name-validator": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-3.0.0.tgz", - "integrity": "sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==" - }, - "node_modules/xmlchars": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", - "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==" - }, - "node_modules/y18n": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.1.tgz", - "integrity": "sha512-wNcy4NvjMYL8gogWWYAO7ZFWFfHcbdbE57tZO8e4cbpj8tfUcwrwqSl3ad8HxpYWCdXcJUCeKKZS62Av1affwQ==" - }, - "node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" - }, - "node_modules/yargs": { - "version": "15.4.1", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz", - "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==", - "dependencies": { - "cliui": "^6.0.0", - "decamelize": "^1.2.0", - "find-up": "^4.1.0", - "get-caller-file": "^2.0.1", - "require-directory": "^2.1.1", - "require-main-filename": "^2.0.0", - "set-blocking": "^2.0.0", - "string-width": "^4.2.0", - "which-module": "^2.0.0", - "y18n": "^4.0.0", - "yargs-parser": "^18.1.2" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/yargs-parser": { - "version": "18.1.3", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", - "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", - "dependencies": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/yargs/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" - }, - "node_modules/yargs/node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "engines": { - "node": ">=8" - } - }, - "node_modules/yargs/node_modules/string-width": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", - "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/yt-search": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/yt-search/-/yt-search-2.5.1.tgz", - "integrity": "sha512-RD2pZwU4ac4Q0Cku1oeas2T3cRliEFzPsMvkrjf5D1JxP4l7sPeJhRhC4vjDdEwBdHr78Ka5NyMpbaNKZ17/WQ==", - "license": "MIT", - "dependencies": { - "async.parallellimit": "~0.5.2", - "boolstring": "~1.0.2", - "cheerio": "~0.22.0", - "dasu": "~0.4.1", - "human-time": "0.0.2", - "jsonpath": "~1.0.2", - "minimist": "~1.2.5", - "node-fzf": "~0.5.1" - }, - "bin": { - "yt-search": "bin/cli.js", - "yt-search-audio": "bin/mpv_audio.sh", - "yt-search-video": "bin/mpv_video.sh" - } - }, - "node_modules/ytdl-core": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/ytdl-core/-/ytdl-core-4.2.1.tgz", - "integrity": "sha512-7zAoJiWpaBGgiAUCQuvKBuWom7tmSCV0A70gRdrPxR96yQoJOrCZkW6Wg1CofvPtAeQVWTVWThC8bXRsE+SBeA==", - "license": "MIT", - "dependencies": { - "m3u8stream": "^0.8.3", - "miniget": "^4.0.0", - "sax": "^1.1.3" - }, - "engines": { - "node": ">=10" - } - } - }, "dependencies": { "@babel/code-frame": { "version": "7.12.11", @@ -9104,6 +725,17 @@ "@babel/types": "^7.3.0" } }, + "@types/cacheable-request": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/@types/cacheable-request/-/cacheable-request-6.0.1.tgz", + "integrity": "sha512-ykFq2zmBGOCbpIXtoVbz4SKY5QriWPh3AjyU4G74RYbtt5yOc5OfaY75ftjg7mikMOla1CTGpX3lLbuJh8DTrQ==", + "requires": { + "@types/http-cache-semantics": "*", + "@types/keyv": "*", + "@types/node": "*", + "@types/responselike": "*" + } + }, "@types/graceful-fs": { "version": "4.1.4", "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.4.tgz", @@ -9112,6 +744,11 @@ "@types/node": "*" } }, + "@types/http-cache-semantics": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.0.tgz", + "integrity": "sha512-c3Xy026kOF7QOTn00hbIllV1dLR9hG9NkSrLQgCVs8NF6sBU+VGWjD3wLPhmh1TYAc7ugCFsvHYMN4VcBN1U1A==" + }, "@types/istanbul-lib-coverage": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.3.tgz", @@ -9133,15 +770,28 @@ "@types/istanbul-lib-report": "*" } }, - "@types/jest": { - "version": "26.0.19", - "resolved": "https://registry.npmjs.org/@types/jest/-/jest-26.0.19.tgz", - "integrity": "sha512-jqHoirTG61fee6v6rwbnEuKhpSKih0tuhqeFbCmMmErhtu3BYlOZaXWjffgOstMM4S/3iQD31lI5bGLTrs97yQ==", + "@types/jsonfile": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/@types/jsonfile/-/jsonfile-6.0.0.tgz", + "integrity": "sha512-mUHbRieyluPtL3c466K7oUGua1lAVlz45PV4U3bHs5CXdBlDIeXJI5xQXa6IZYnrgmcJzJp/CiTZB4zfShAi6w==", + "requires": { + "@types/node": "*" + } + }, + "@types/keyv": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@types/keyv/-/keyv-3.1.1.tgz", + "integrity": "sha512-MPtoySlAZQ37VoLaPcTHCu1RWJ4llDkULYZIzOYxlhxBqYPB0RsRlmMU0R6tahtFe27mIdkHV+551ZWV4PLmVw==", "requires": { - "jest-diff": "^26.0.0", - "pretty-format": "^26.0.0" + "@types/node": "*" } }, + "@types/lodash": { + "version": "4.14.167", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.167.tgz", + "integrity": "sha512-w7tQPjARrvdeBkX/Rwg95S592JwxqOjmms3zWQ0XZgSyxSLdzWaYH3vErBhdVS/lRBX7F8aBYcYJYTr5TMGOzw==", + "dev": true + }, "@types/node": { "version": "10.17.50", "resolved": "https://registry.npmjs.org/@types/node/-/node-10.17.50.tgz", @@ -9157,11 +807,40 @@ "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.1.6.tgz", "integrity": "sha512-6gOkRe7OIioWAXfnO/2lFiv+SJichKVSys1mSsgyrYHSEjk8Ctv4tSR/Odvnu+HWlH2C8j53dahU03XmQdd5fA==" }, + "@types/responselike": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@types/responselike/-/responselike-1.0.0.tgz", + "integrity": "sha512-85Y2BjiufFzaMIlvJDvTTB8Fxl2xfLo4HgmHzVBz08w4wDePCTjYw66PdrolO0kzli3yam/YCgRufyo1DdQVTA==", + "requires": { + "@types/node": "*" + } + }, + "@types/roll": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@types/roll/-/roll-1.2.0.tgz", + "integrity": "sha512-8Khu3DXG3o8GOdbXQbNzWqqa4rAtR0HGw6o37RP4CHgYFjQp3DTSGUpCKt/ujfD+ZRPOxi+ZJIhia7F5cX0pbA==", + "dev": true + }, "@types/stack-utils": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.0.tgz", "integrity": "sha512-RJJrrySY7A8havqpGObOB4W92QXKJo63/jFLLgpvOtsGUqbQZ9Sbgl35KMm1DjC6j7AvmmU2bIno+3IyEaemaw==" }, + "@types/voca": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@types/voca/-/voca-1.4.0.tgz", + "integrity": "sha512-LdffYbNO8Mg06oPouDq13XwarZbYEvLHMCeV04B/LYl2o6miyg4qBa3YduIZcNhK8/r3Soq0a1tCDeprkBXTIQ==", + "dev": true + }, + "@types/ws": { + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-7.4.0.tgz", + "integrity": "sha512-Y29uQ3Uy+58bZrFLhX36hcI3Np37nqWE7ky5tjiDoy1GDZnIwVxS0CgF+s+1bXMzjKBFy+fqaRfb708iNzdinw==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, "@types/yargs": { "version": "15.0.12", "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.12.tgz", @@ -9175,6 +854,12 @@ "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-20.2.0.tgz", "integrity": "sha512-37RSHht+gzzgYeobbG+KWryeAW8J33Nhr69cjTqSYymXVZEN9NbRYWoYlRtDhHKPVT1FyNKwaTPC1NynKZpzRA==" }, + "@types/yt-search": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@types/yt-search/-/yt-search-2.3.0.tgz", + "integrity": "sha512-B0F8mn14F4nHWG5HJ0WUMhsiDqOPD/bHbPd0pEaj/+qZgmLV/Wmy7yo0xSKPRD9D3R/DUywqIhFFAPUMaYqi3Q==", + "dev": true + }, "abab": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.5.tgz", @@ -9211,8 +896,7 @@ "version": "5.3.1", "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.1.tgz", "integrity": "sha512-K0Ptm/47OKfQRpNQ2J/oIN/3QYiK6FwW+eJbILhsdxh2WTLdl+30o8aGdTbm5JbffpFFAg/g+zi1E+jvJha5ng==", - "dev": true, - "requires": {} + "dev": true }, "acorn-walk": { "version": "7.2.0", @@ -9723,6 +1407,11 @@ "unset-value": "^1.0.0" } }, + "cacheable-lookup": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-5.0.4.tgz", + "integrity": "sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA==" + }, "cacheable-request": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-6.1.0.tgz", @@ -9980,7 +1669,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.2.tgz", "integrity": "sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws=", - "dev": true, "requires": { "mimic-response": "^1.0.0" } @@ -10055,7 +1743,6 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/configstore/-/configstore-5.0.1.tgz", "integrity": "sha512-aMKprgk5YhBNyH25hj8wGt2+D52Sw1DRRIzqBwLp2Ya9mFmY8KPvvtvmna8SxVR9JMZ4kzMD68N22vlaRpkeFA==", - "dev": true, "requires": { "dot-prop": "^5.2.0", "graceful-fs": "^4.1.2", @@ -10101,8 +1788,7 @@ "crypto-random-string": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-2.0.0.tgz", - "integrity": "sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==", - "dev": true + "integrity": "sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==" }, "css-select": { "version": "1.2.0", @@ -10244,6 +1930,11 @@ "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=" }, + "detect-indent": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-6.0.0.tgz", + "integrity": "sha512-oSyFlqaTHCItVRGK5RmrmjB+CmaMOW7IaNA/kdxqhoa6d17j/5ce9O9eWXmV/KEdRwqpQA+Vqe8a8Bsybu4YnA==" + }, "detect-libc": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", @@ -10282,6 +1973,11 @@ "ws": "^7.3.1" } }, + "docopt": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/docopt/-/docopt-0.6.2.tgz", + "integrity": "sha1-so6eIiDaXsSffqW7JKR3h0Be6xE=" + }, "doctrine": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", @@ -10337,11 +2033,20 @@ "domelementtype": "1" } }, + "dot-json": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/dot-json/-/dot-json-1.2.1.tgz", + "integrity": "sha512-sHtCsDBBzhTUFhS12cAvUbP9JTr59LLNxnpNr6dlgbjZlN+nrWFs+uHXgsJvFmc5HoMFR4e60rdqd+GdSUlM3w==", + "requires": { + "detect-indent": "~6.0.0", + "docopt": "~0.6.2", + "underscore-keypath": "~0.0.22" + } + }, "dot-prop": { "version": "5.3.0", "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz", "integrity": "sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==", - "dev": true, "requires": { "is-obj": "^2.0.0" } @@ -10372,6 +2077,24 @@ "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", "dev": true }, + "encoding": { + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz", + "integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==", + "requires": { + "iconv-lite": "^0.6.2" + }, + "dependencies": { + "iconv-lite": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.2.tgz", + "integrity": "sha512-2y91h5OpQlolefMPmUlivelittSWy0rP+oYVpn6A7GwVHNE8AWzoYOBNmlwks3LobaJxgHCYZAnyNo2GgpNRNQ==", + "requires": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + } + } + } + }, "end-of-stream": { "version": "1.4.4", "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", @@ -10932,23 +2655,6 @@ "flat-cache": "^3.0.4" } }, - "file-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/file-match/-/file-match-1.0.2.tgz", - "integrity": "sha1-ycrSZdLIrfOoFHWw30dYWQafrvc=", - "requires": { - "utils-extend": "^1.0.6" - } - }, - "file-system": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/file-system/-/file-system-2.2.2.tgz", - "integrity": "sha1-fWWDPjojR9zZVqgTxncVPtPt2Yc=", - "requires": { - "file-match": "^1.0.1", - "utils-extend": "^1.0.4" - } - }, "fill-range": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", @@ -11346,8 +3052,7 @@ "http-cache-semantics": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz", - "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==", - "dev": true + "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==" }, "http-response-object": { "version": "3.0.2", @@ -11367,6 +3072,15 @@ "sshpk": "^1.7.0" } }, + "http2-wrapper": { + "version": "1.0.0-beta.5.2", + "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-1.0.0-beta.5.2.tgz", + "integrity": "sha512-xYz9goEyBnC8XwXDTuC/MZ6t+MrKVQZOk4s7+PaDkwIsQd8IwqvM+0M6bA/2lvG8GHXcPdf+MejTUeO2LCPCeQ==", + "requires": { + "quick-lru": "^5.1.1", + "resolve-alpn": "^1.0.0" + } + }, "https-proxy-agent": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz", @@ -11581,6 +3295,11 @@ "is-path-inside": "^3.0.1" } }, + "is-keyword-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-keyword-js/-/is-keyword-js-1.0.3.tgz", + "integrity": "sha1-rDDc81tnH0snsX9ctXI1EmAhEy0=" + }, "is-npm": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/is-npm/-/is-npm-4.0.0.tgz", @@ -11595,8 +3314,7 @@ "is-obj": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", - "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==", - "dev": true + "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==" }, "is-path-inside": { "version": "3.0.2", @@ -11632,6 +3350,11 @@ "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" }, + "is-url": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/is-url/-/is-url-1.2.4.tgz", + "integrity": "sha512-ITvGim8FhRiYe4IQ5uHSkj7pVaPDrCTkNd3yq3cV7iZAcJdHTUMPMEHcqSOy9xZ9qFenQCvi+2wjH9a1nXqHww==" + }, "is-windows": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", @@ -11800,16 +3523,6 @@ "pretty-format": "^26.6.2" } }, - "jest-discordjs-mocks": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/jest-discordjs-mocks/-/jest-discordjs-mocks-1.0.2.tgz", - "integrity": "sha512-S3wng0scR9GsUZwj4NW/PDCHpPptWQTJz8mqW4lEfOiNl+l8/XQpBYh2dPQq5zFkhnXTb9WRG0DThcB0OOBrhg==", - "requires": { - "@types/jest": "^26.0.8", - "discord.js": "^12.2.0", - "jest": "^26.2.2" - } - }, "jest-docblock": { "version": "26.0.0", "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-26.0.0.tgz", @@ -11956,8 +3669,7 @@ "jest-pnp-resolver": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.2.tgz", - "integrity": "sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w==", - "requires": {} + "integrity": "sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w==" }, "jest-regex-util": { "version": "26.0.0", @@ -12236,6 +3948,22 @@ "minimist": "^1.2.5" } }, + "jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "requires": { + "graceful-fs": "^4.1.6", + "universalify": "^2.0.0" + }, + "dependencies": { + "universalify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", + "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==" + } + } + }, "jsonpath": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/jsonpath/-/jsonpath-1.0.2.tgz", @@ -12340,6 +4068,11 @@ "resolved": "https://registry.npmjs.org/lodash.bind/-/lodash.bind-4.2.1.tgz", "integrity": "sha1-euMBfpOWIqwxt9fX3LGzTbFpDTU=" }, + "lodash.clonedeep": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", + "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=" + }, "lodash.defaults": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz", @@ -12512,8 +4245,7 @@ "mimic-response": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", - "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==", - "dev": true + "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==" }, "miniget": { "version": "4.1.0", @@ -12791,8 +4523,7 @@ "normalize-url": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.0.tgz", - "integrity": "sha512-2s47yzUxdexf1OhyRi4Em83iQk0aPvwTddtFz4hnSSw9dCEsLEGf6SwIO8ss/19S9iBb5sJaOuTvTGDeZI00BQ==", - "dev": true + "integrity": "sha512-2s47yzUxdexf1OhyRi4Em83iQk0aPvwTddtFz4hnSSw9dCEsLEGf6SwIO8ss/19S9iBb5sJaOuTvTGDeZI00BQ==" }, "npm-bundled": { "version": "1.1.1", @@ -12844,6 +4575,14 @@ "boolbase": "~1.0.0" } }, + "num-or-not": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/num-or-not/-/num-or-not-1.0.1.tgz", + "integrity": "sha1-4EM9fUab01R97ybYWVwSucr5Cko=", + "requires": { + "trim": "0.0.1" + } + }, "number-is-nan": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", @@ -13159,8 +4898,7 @@ "prism-media": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/prism-media/-/prism-media-1.2.3.tgz", - "integrity": "sha512-fSrR66n0l6roW9Rx4rSLMyTPTjRTiXy5RVqDOurACQ6si1rKHHKDU5gwBJoCsIV0R3o9gi+K50akl/qyw1C74A==", - "requires": {} + "integrity": "sha512-fSrR66n0l6roW9Rx4rSLMyTPTjRTiXy5RVqDOurACQ6si1rKHHKDU5gwBJoCsIV0R3o9gi+K50akl/qyw1C74A==" }, "process-nextick-args": { "version": "2.0.1", @@ -13220,6 +4958,11 @@ "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==" }, + "quick-lru": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz", + "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==" + }, "rc": { "version": "1.2.8", "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", @@ -13441,6 +5184,11 @@ "path-parse": "^1.0.6" } }, + "resolve-alpn": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.0.0.tgz", + "integrity": "sha512-rTuiIEqFmGxne4IovivKSDzld2lWW9QCjqv80SYjPgf+gS35eaCAjaP54CCwGAwBtnCsvNLYtqxe1Nw+i6JEmA==" + }, "resolve-cwd": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", @@ -13507,6 +5255,11 @@ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" }, + "safe-eval": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/safe-eval/-/safe-eval-0.4.1.tgz", + "integrity": "sha512-wmiu4RSYVZ690RP1+cv/LxfPK1dIlEN35aW7iv4SMYdqDrHbkll4+NJcHmKm7PbCuI1df1otOcPwgcc2iFR85g==" + }, "safe-regex": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", @@ -14190,14 +5943,6 @@ "resolved": "https://registry.npmjs.org/stealthy-require/-/stealthy-require-1.1.1.tgz", "integrity": "sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks=" }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "requires": { - "safe-buffer": "~5.1.0" - } - }, "string-length": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.1.tgz", @@ -14232,6 +5977,14 @@ } } }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "requires": { + "safe-buffer": "~5.1.0" + } + }, "strip-ansi": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", @@ -14476,6 +6229,154 @@ "punycode": "^2.1.1" } }, + "translate": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/translate/-/translate-1.1.2.tgz", + "integrity": "sha512-3RlVAzzcNuZ7dDfYk2qsQTxJLSeIQ06bMrYYkBneLHtewV0JGaKSP0GjTKHJn/vYwr18bvHEgdmjfg8B0DFuWw==", + "requires": { + "node-fetch": "^1.7.3" + }, + "dependencies": { + "is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=" + }, + "node-fetch": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-1.7.3.tgz", + "integrity": "sha512-NhZ4CsKx7cYm2vSrBAr2PvFOe6sWDf0UYLRqA6svUYg7+/TSfVAu49jYC4BvQ4Sms9SZgdqGBgroqfDhJdTyKQ==", + "requires": { + "encoding": "^0.1.11", + "is-stream": "^1.0.1" + } + } + } + }, + "translate-google": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/translate-google/-/translate-google-1.4.3.tgz", + "integrity": "sha512-EEocI3roainbPs7qsxpbrly4zYlN6HAVLFRS/J0ha/OQG9KPW9VvKk5S+U3CBuQAtATmvTYmdOuBuvFGYMWH4A==", + "requires": { + "configstore": "^5.0.1", + "got": "^11.5.1", + "is-keyword-js": "^1.0.3", + "is-url": "^1.2.4", + "lodash": "^4.17.19", + "num-or-not": "^1.0.1", + "safe-eval": "^0.4.1", + "user-agents": "^1.0.559" + }, + "dependencies": { + "@sindresorhus/is": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.0.0.tgz", + "integrity": "sha512-FyD2meJpDPjyNQejSjvnhpgI/azsQkA4lGbuu5BQZfjvJ9cbRZXzeWL2HceCekW4lixO9JPesIIQkSoLjeJHNQ==" + }, + "@szmarczak/http-timer": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-4.0.5.tgz", + "integrity": "sha512-PyRA9sm1Yayuj5OIoJ1hGt2YISX45w9WcFbh6ddT0Z/0yaFxOtGLInr4jUfU1EAFVs0Yfyfev4RNwBlUaHdlDQ==", + "requires": { + "defer-to-connect": "^2.0.0" + } + }, + "cacheable-request": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-7.0.1.tgz", + "integrity": "sha512-lt0mJ6YAnsrBErpTMWeu5kl/tg9xMAWjavYTN6VQXM1A/teBITuNcccXsCxF0tDQQJf9DfAaX5O4e0zp0KlfZw==", + "requires": { + "clone-response": "^1.0.2", + "get-stream": "^5.1.0", + "http-cache-semantics": "^4.0.0", + "keyv": "^4.0.0", + "lowercase-keys": "^2.0.0", + "normalize-url": "^4.1.0", + "responselike": "^2.0.0" + } + }, + "decompress-response": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", + "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", + "requires": { + "mimic-response": "^3.1.0" + } + }, + "defer-to-connect": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.0.tgz", + "integrity": "sha512-bYL2d05vOSf1JEZNx5vSAtPuBMkX8K9EUutg7zlKvTqKXHt7RhWJFbmd7qakVuf13i+IkGmp6FwSsONOf6VYIg==" + }, + "get-stream": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "requires": { + "pump": "^3.0.0" + } + }, + "got": { + "version": "11.8.1", + "resolved": "https://registry.npmjs.org/got/-/got-11.8.1.tgz", + "integrity": "sha512-9aYdZL+6nHmvJwHALLwKSUZ0hMwGaJGYv3hoPLPgnT8BoBXm1SjnZeky+91tfwJaDzun2s4RsBRy48IEYv2q2Q==", + "requires": { + "@sindresorhus/is": "^4.0.0", + "@szmarczak/http-timer": "^4.0.5", + "@types/cacheable-request": "^6.0.1", + "@types/responselike": "^1.0.0", + "cacheable-lookup": "^5.0.3", + "cacheable-request": "^7.0.1", + "decompress-response": "^6.0.0", + "http2-wrapper": "^1.0.0-beta.5.2", + "lowercase-keys": "^2.0.0", + "p-cancelable": "^2.0.0", + "responselike": "^2.0.0" + } + }, + "json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==" + }, + "keyv": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.0.3.tgz", + "integrity": "sha512-zdGa2TOpSZPq5mU6iowDARnMBZgtCqJ11dJROFi6tg6kTn4nuUdU09lFyLFSaHrWqpIJ+EBq4E8/Dc0Vx5vLdA==", + "requires": { + "json-buffer": "3.0.1" + } + }, + "lowercase-keys": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", + "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==" + }, + "mimic-response": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", + "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==" + }, + "p-cancelable": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-2.0.0.tgz", + "integrity": "sha512-wvPXDmbMmu2ksjkB4Z3nZWTSkJEb9lqVdMaCKpZUGJG9TMiNp9XcbG3fn9fPKjem04fJMJnXoyFPk2FmgiaiNg==" + }, + "responselike": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/responselike/-/responselike-2.0.0.tgz", + "integrity": "sha512-xH48u3FTB9VsZw7R+vvgaKeLKzT6jOogbQhEe/jewwnZgzPcnyWui2Av6JpoYZF/91uueC+lqhWqeURw5/qhCw==", + "requires": { + "lowercase-keys": "^2.0.0" + } + } + } + }, + "trim": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/trim/-/trim-0.0.1.tgz", + "integrity": "sha1-WFhUf2spB1fulczMZm+1AITEYN0=" + }, "ttys": { "version": "0.0.3", "resolved": "https://registry.npmjs.org/ttys/-/ttys-0.0.3.tgz", @@ -14531,6 +6432,12 @@ "is-typedarray": "^1.0.0" } }, + "typescript": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.1.3.tgz", + "integrity": "sha512-B3ZIOf1IKeH2ixgHhj6la6xdwR9QrLC5d1VKeCSY4tvkqhF2eqd9O7txNlS0PO3GrBAFIdr3L1ndNwteUbZLYg==", + "dev": true + }, "undefsafe": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.3.tgz", @@ -14562,6 +6469,14 @@ "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.7.0.tgz", "integrity": "sha1-a7rwh3UA02vjTsqlhODbn+8DUgk=" }, + "underscore-keypath": { + "version": "0.0.22", + "resolved": "https://registry.npmjs.org/underscore-keypath/-/underscore-keypath-0.0.22.tgz", + "integrity": "sha1-SKUoOSu278QkvhyqVtpLX6zPJk0=", + "requires": { + "underscore": "*" + } + }, "union-value": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", @@ -14584,7 +6499,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-2.0.0.tgz", "integrity": "sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg==", - "dev": true, "requires": { "crypto-random-string": "^2.0.0" } @@ -14685,16 +6599,20 @@ "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==" }, + "user-agents": { + "version": "1.0.559", + "resolved": "https://registry.npmjs.org/user-agents/-/user-agents-1.0.559.tgz", + "integrity": "sha512-HdAlNS3vDxOGMRwmv8or05xL96MV3CEwQhUSFTCRoOvTOEnWhTEBPAHRry/xZpVTTOtx77UHMal8YKcx6fs7Lg==", + "requires": { + "dot-json": "^1.2.0", + "lodash.clonedeep": "^4.5.0" + } + }, "util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" }, - "utils-extend": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/utils-extend/-/utils-extend-1.0.8.tgz", - "integrity": "sha1-zP17ZFQPjpDuIe7Fd2nQZRyril8=" - }, "uuid": { "version": "8.3.2", "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", @@ -14911,14 +6829,12 @@ "ws": { "version": "7.4.1", "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.1.tgz", - "integrity": "sha512-pTsP8UAfhy3sk1lSk/O/s4tjD0CRwvMnzvwr4OKGX7ZvqZtUyx4KIJB5JWbkykPoc55tixMGgTNoh3k4FkNGFQ==", - "requires": {} + "integrity": "sha512-pTsP8UAfhy3sk1lSk/O/s4tjD0CRwvMnzvwr4OKGX7ZvqZtUyx4KIJB5JWbkykPoc55tixMGgTNoh3k4FkNGFQ==" }, "xdg-basedir": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-4.0.0.tgz", - "integrity": "sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q==", - "dev": true + "integrity": "sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q==" }, "xml-name-validator": { "version": "3.0.0", @@ -15005,9 +6921,9 @@ } }, "ytdl-core": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/ytdl-core/-/ytdl-core-4.2.1.tgz", - "integrity": "sha512-7zAoJiWpaBGgiAUCQuvKBuWom7tmSCV0A70gRdrPxR96yQoJOrCZkW6Wg1CofvPtAeQVWTVWThC8bXRsE+SBeA==", + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/ytdl-core/-/ytdl-core-4.4.1.tgz", + "integrity": "sha512-VRqJ1pPEfIt7Lja2bKaTRqO47GfVbqhFfKqtmxU5Pp2BM0HUb0gVyf3wL9HlA+Vb4OblXs2MzSqWI8Fi1sSk4Q==", "requires": { "m3u8stream": "^0.8.3", "miniget": "^4.0.0", diff --git a/package.json b/package.json index 6f75ea59..57b9d038 100644 --- a/package.json +++ b/package.json @@ -1,34 +1,42 @@ { - "name": "portal", - "author": "Ioannis Tsiakkas", - "version": "1.2.1", - "private": true, - "main": "src/portal.ts", - "scripts": { - "start": "node src/portal.js", - "start_ts": "tsc src/portal.ts", - "test": "jest", - "dev": "nodemon src/portal.ts" - }, - "dependencies": { - "@discordjs/opus": "^0.3.3", - "discord-ytdl-core": "^5.0.0", - "discord.js": "^12.5.1", - "ffmpeg-static": "^4.2.7", - "file-system": "^2.2.2", - "give-me-a-joke": "^0.4.0", - "jest": "^26.6.3", - "jest-discordjs-mocks": "^1.0.2", - "lodash": "^4.17.20", - "moment": "^2.29.1", - "roll": "^1.3.1", - "voca": "^1.4.0", - "yt-search": "^2.5.1", - "ytdl-core": "^4.2.1" - }, - "devDependencies": { - "@types/node": "^10.17.50", - "eslint": "^7.16.0", - "nodemon": "^2.0.6" - } -} + "name": "portal", + "author": "Ioannis Tsiakkas", + "version": "1.5.0", + "private": true, + "main": "src/portal.ts", + "scripts": { + "start": "npx tsc && node build/portal.js", + "clean": "rm -rf build/", + "test": "jest", + "dev": "nodemon src/portal.ts" + }, + "dependencies": { + "@discordjs/opus": "^0.3.3", + "@types/jsonfile": "^6.0.0", + "discord-ytdl-core": "^5.0.0", + "discord.js": "^12.5.1", + "ffmpeg-static": "^4.2.7", + "give-me-a-joke": "^0.4.0", + "jest": "^26.6.3", + "jsonfile": "^6.1.0", + "lodash": "^4.17.20", + "moment": "^2.29.1", + "roll": "^1.3.1", + "translate": "^1.1.2", + "translate-google": "^1.4.3", + "voca": "^1.4.0", + "yt-search": "^2.5.1", + "ytdl-core": "^4.4.1" + }, + "devDependencies": { + "@types/lodash": "^4.14.167", + "@types/node": "^10.17.50", + "@types/roll": "^1.2.0", + "@types/voca": "^1.4.0", + "@types/ws": "^7.4.0", + "@types/yt-search": "^2.3.0", + "eslint": "^7.16.0", + "nodemon": "^2.0.6", + "typescript": "^4.1.3" + } +} \ No newline at end of file diff --git a/src/portal.js b/portal.js.txt similarity index 92% rename from src/portal.js rename to portal.js.txt index 255d79da..67c4ec9c 100644 --- a/src/portal.js +++ b/portal.js.txt @@ -11,26 +11,26 @@ // list of all managed channels in servers const portal_managed_guilds_path = './database/guild_list.json'; -const guild_list = require('../database/guild_list.json'); +const guild_list = require('./database/guild_list.json'); if (guild_list === null) { console.log('guild json is corrupt'); process.exit(1); } -const config = require('../config.json'); -const cooldown_list = require('../assets/jsons/cooldown_list.json'); +const config = require('./config.json'); +const cooldown_list = require('./assets/jsons/cooldown_list.json'); -const profanity = require('./moderation/profanity.js') -const guld_mngr = require('./functions/guild_manager'); -const help_mngr = require('./functions/help_manager'); -const lclz_mngr = require('./functions/localization_manager'); -const user_mngr = require('./functions/user_manager'); -const play_mngr = require('./functions/music_manager'); +const profanity = require('./src/moderation/profanity.js') +const guld_mngr = require('./src/functions/guild_manager'); +const help_mngr = require('./src/functions/help_manager'); +const lclz_mngr = require('./src/functions/localization_manager'); +const user_mngr = require('./src/functions/user_manager'); +const play_mngr = require('./src/functions/music_manager'); // load up the discord.js library -const Discord = require('discord.js'); -// const { Discord, Client, Message, Guild, DMChannel, GuildChannel, GuildMember, Presence } = require('discord.js'); +// const Discord = require('discord.js'); +const { Discord, Client, Message, Guild, DMChannel, GuildChannel, GuildMember, Presence } = require('discord.js'); // this is the client the Portal Bot. Some people call it bot, some people call // it 'self', client.user is actually the presence of portal bot in the server @@ -263,9 +263,9 @@ function event_loader(event, args) { .then(rspns => { if (rspns !== null && rspns !== undefined) { if (event === 'messageReactionAdd') { - const music_channel_id = args.guild_list[args.messageReaction.message.guild.id] + const music_channel_id = guild_list[messageReaction.message.guild.id] .music_data.channel_id; - const music_channel = args.messageReaction.message.guild.channels.cache + const music_channel = messageReaction.message.guild.channels.cache .find(channel => channel.id === music_channel_id); music_channel diff --git a/assets/img/logo.png b/src/assets/img/logo.png similarity index 100% rename from assets/img/logo.png rename to src/assets/img/logo.png diff --git a/assets/img/spotify.png b/src/assets/img/spotify.png similarity index 100% rename from assets/img/spotify.png rename to src/assets/img/spotify.png diff --git a/src/assets/jsons/cooldown_list.json b/src/assets/jsons/cooldown_list.json new file mode 100644 index 00000000..bb3d2089 --- /dev/null +++ b/src/assets/jsons/cooldown_list.json @@ -0,0 +1,236 @@ +{ + "guild": [{ + "name": "save", + "time": 5, + "auth": true, + "premium": true, + "auto_delete": true + }, + { + "name": "setup", + "time": 10, + "auth": true, + "premium": true, + "auto_delete": true + }, + { + "name": "set_ranks", + "time": 10, + "auth": true, + "premium": true, + "auto_delete": true + } + ], + "member": [{ + "name": "join", + "time": 1, + "auth": false, + "premium": true, + "auto_delete": true + }, + { + "name": "announce", + "time": 2, + "auth": false, + "premium": true, + "auto_delete": true + }, + { + "name": "force", + "time": 5, + "auth": true, + "premium": true, + "auto_delete": true + } + ], + "none": [{ + "name": "delete", + "time": 0, + "auth": true, + "premium": true, + "auto_delete": true + }, + { + "name": "leaderboard", + "time": 0, + "auth": false, + "premium": false, + "auto_delete": true + }, + { + "name": "ranks", + "time": 0, + "auth": false, + "premium": true, + "auto_delete": true + }, + { + "name": "level", + "time": 0, + "auth": false, + "premium": false, + "auto_delete": true + }, + { + "name": "about", + "time": 0, + "auth": false, + "premium": false, + "auto_delete": true + }, + { + "name": "portal", + "time": 0, + "auth": true, + "premium": false, + "auto_delete": true + }, + { + "name": "help", + "time": 0, + "auth": false, + "premium": false, + "auto_delete": true + }, + { + "name": "ping", + "time": 0, + "auth": false, + "premium": false, + "auto_delete": true + }, + { + "name": "set", + "time": 0, + "auth": false, + "premium": true, + "auto_delete": true + }, + { + "name": "role_assigner", + "time": 0, + "auth": true, + "premium": true, + "auto_delete": true + }, + { + "name": "spotify", + "time": 0, + "auth": true, + "premium": true, + "auto_delete": true + }, + { + "name": "music", + "time": 0, + "auth": true, + "premium": true, + "auto_delete": true + }, + { + "name": "announcement", + "time": 0, + "auth": true, + "premium": true, + "auto_delete": true + }, + { + "name": "url", + "time": 0, + "auth": true, + "premium": true, + "auto_delete": true + }, + { + "name": "leave", + "time": 0, + "auth": false, + "premium": true, + "auto_delete": true + }, + { + "name": "focus", + "time": 0, + "auth": false, + "premium": true, + "auto_delete": true + }, + { + "name": "corona", + "time": 0, + "auth": false, + "premium": false, + "auto_delete": false + }, + { + "name": "roll", + "time": 0, + "auth": false, + "premium": false, + "auto_delete": false + }, + { + "name": "run", + "time": 0, + "auth": false, + "premium": false, + "auto_delete": true + }, + { + "name": "authorised_roles", + "time": 0, + "auth": false, + "premium": true, + "auto_delete": true + }, + { + "name": "authorise", + "time": 0, + "auth": true, + "premium": true, + "auto_delete": true + }, + { + "name": "deauthorise", + "time": 0, + "auth": true, + "premium": true, + "auto_delete": true + }, + { + "name": "translate", + "time": 0, + "auth": true, + "premium": true, + "auto_delete": true + }, + { + "name": "state", + "time": 0, + "auth": false, + "premium": true, + "auto_delete": true + }, + { + "name": "joke", + "time": 0, + "auth": false, + "premium": false, + "auto_delete": false + }, + { + "name": "weather", + "time": 0, + "auth": false, + "premium": false, + "auto_delete": false + }, + { + "name": "whoami", + "time": 0, + "auth": false, + "premium": false, + "auto_delete": false + } + ] +} \ No newline at end of file diff --git a/assets/jsons/country_codes.json b/src/assets/jsons/country_codes.json similarity index 100% rename from assets/jsons/country_codes.json rename to src/assets/jsons/country_codes.json diff --git a/assets/jsons/country_codes_2.json b/src/assets/jsons/country_codes_2.json similarity index 100% rename from assets/jsons/country_codes_2.json rename to src/assets/jsons/country_codes_2.json diff --git a/assets/jsons/game_list.json b/src/assets/jsons/game_list.json similarity index 100% rename from assets/jsons/game_list.json rename to src/assets/jsons/game_list.json diff --git a/assets/jsons/profane_word_list.json b/src/assets/jsons/profane_word_list.json similarity index 99% rename from assets/jsons/profane_word_list.json rename to src/assets/jsons/profane_word_list.json index 0036e8ae..e28aa0e5 100644 --- a/assets/jsons/profane_word_list.json +++ b/src/assets/jsons/profane_word_list.json @@ -1,5 +1,5 @@ { - "el": [ + "gr": [ "γαμώ", "γαμω", "γαμημένε", @@ -45,6 +45,7 @@ "γρόθο", "γροθο" ], + "de": [], "en": [ "ahole", "anus", diff --git a/assets/jsons/program_list.json b/src/assets/jsons/program_list.json similarity index 100% rename from assets/jsons/program_list.json rename to src/assets/jsons/program_list.json diff --git a/assets/mp3s/de/announce/announce_0.mp3 b/src/assets/mp3s/de/announce/announce_0.mp3 similarity index 100% rename from assets/mp3s/de/announce/announce_0.mp3 rename to src/assets/mp3s/de/announce/announce_0.mp3 diff --git a/assets/mp3s/de/announce/announce_1.mp3 b/src/assets/mp3s/de/announce/announce_1.mp3 similarity index 100% rename from assets/mp3s/de/announce/announce_1.mp3 rename to src/assets/mp3s/de/announce/announce_1.mp3 diff --git a/assets/mp3s/de/announce/announce_2.mp3 b/src/assets/mp3s/de/announce/announce_2.mp3 similarity index 100% rename from assets/mp3s/de/announce/announce_2.mp3 rename to src/assets/mp3s/de/announce/announce_2.mp3 diff --git a/assets/mp3s/de/fail/fail_0.mp3 b/src/assets/mp3s/de/fail/fail_0.mp3 similarity index 100% rename from assets/mp3s/de/fail/fail_0.mp3 rename to src/assets/mp3s/de/fail/fail_0.mp3 diff --git a/assets/mp3s/de/fail/fail_1.mp3 b/src/assets/mp3s/de/fail/fail_1.mp3 similarity index 100% rename from assets/mp3s/de/fail/fail_1.mp3 rename to src/assets/mp3s/de/fail/fail_1.mp3 diff --git a/assets/mp3s/de/fail/fail_2.mp3 b/src/assets/mp3s/de/fail/fail_2.mp3 similarity index 100% rename from assets/mp3s/de/fail/fail_2.mp3 rename to src/assets/mp3s/de/fail/fail_2.mp3 diff --git a/assets/mp3s/de/join/join_0.mp3 b/src/assets/mp3s/de/join/join_0.mp3 similarity index 100% rename from assets/mp3s/de/join/join_0.mp3 rename to src/assets/mp3s/de/join/join_0.mp3 diff --git a/assets/mp3s/de/join/join_1.mp3 b/src/assets/mp3s/de/join/join_1.mp3 similarity index 100% rename from assets/mp3s/de/join/join_1.mp3 rename to src/assets/mp3s/de/join/join_1.mp3 diff --git a/assets/mp3s/de/join/join_2.mp3 b/src/assets/mp3s/de/join/join_2.mp3 similarity index 100% rename from assets/mp3s/de/join/join_2.mp3 rename to src/assets/mp3s/de/join/join_2.mp3 diff --git a/assets/mp3s/de/leave/leave_0.mp3 b/src/assets/mp3s/de/leave/leave_0.mp3 similarity index 100% rename from assets/mp3s/de/leave/leave_0.mp3 rename to src/assets/mp3s/de/leave/leave_0.mp3 diff --git a/assets/mp3s/de/leave/leave_1.mp3 b/src/assets/mp3s/de/leave/leave_1.mp3 similarity index 100% rename from assets/mp3s/de/leave/leave_1.mp3 rename to src/assets/mp3s/de/leave/leave_1.mp3 diff --git a/assets/mp3s/de/leave/leave_2.mp3 b/src/assets/mp3s/de/leave/leave_2.mp3 similarity index 100% rename from assets/mp3s/de/leave/leave_2.mp3 rename to src/assets/mp3s/de/leave/leave_2.mp3 diff --git a/assets/mp3s/de/leave/leave_3.mp3 b/src/assets/mp3s/de/leave/leave_3.mp3 similarity index 100% rename from assets/mp3s/de/leave/leave_3.mp3 rename to src/assets/mp3s/de/leave/leave_3.mp3 diff --git a/assets/mp3s/de/read_only/read_only_0.mp3 b/src/assets/mp3s/de/read_only/read_only_0.mp3 similarity index 100% rename from assets/mp3s/de/read_only/read_only_0.mp3 rename to src/assets/mp3s/de/read_only/read_only_0.mp3 diff --git a/assets/mp3s/de/read_only/read_only_1.mp3 b/src/assets/mp3s/de/read_only/read_only_1.mp3 similarity index 100% rename from assets/mp3s/de/read_only/read_only_1.mp3 rename to src/assets/mp3s/de/read_only/read_only_1.mp3 diff --git a/assets/mp3s/de/read_only/read_only_2.mp3 b/src/assets/mp3s/de/read_only/read_only_2.mp3 similarity index 100% rename from assets/mp3s/de/read_only/read_only_2.mp3 rename to src/assets/mp3s/de/read_only/read_only_2.mp3 diff --git a/assets/mp3s/de/spotify/spotify_0.mp3 b/src/assets/mp3s/de/spotify/spotify_0.mp3 similarity index 100% rename from assets/mp3s/de/spotify/spotify_0.mp3 rename to src/assets/mp3s/de/spotify/spotify_0.mp3 diff --git a/assets/mp3s/de/spotify/spotify_1.mp3 b/src/assets/mp3s/de/spotify/spotify_1.mp3 similarity index 100% rename from assets/mp3s/de/spotify/spotify_1.mp3 rename to src/assets/mp3s/de/spotify/spotify_1.mp3 diff --git a/assets/mp3s/de/spotify/spotify_2.mp3 b/src/assets/mp3s/de/spotify/spotify_2.mp3 similarity index 100% rename from assets/mp3s/de/spotify/spotify_2.mp3 rename to src/assets/mp3s/de/spotify/spotify_2.mp3 diff --git a/assets/mp3s/de/url/url_0.mp3 b/src/assets/mp3s/de/url/url_0.mp3 similarity index 100% rename from assets/mp3s/de/url/url_0.mp3 rename to src/assets/mp3s/de/url/url_0.mp3 diff --git a/assets/mp3s/de/url/url_1.mp3 b/src/assets/mp3s/de/url/url_1.mp3 similarity index 100% rename from assets/mp3s/de/url/url_1.mp3 rename to src/assets/mp3s/de/url/url_1.mp3 diff --git a/assets/mp3s/de/url/url_2.mp3 b/src/assets/mp3s/de/url/url_2.mp3 similarity index 100% rename from assets/mp3s/de/url/url_2.mp3 rename to src/assets/mp3s/de/url/url_2.mp3 diff --git a/assets/mp3s/de/user_connected/user_connected_0.mp3 b/src/assets/mp3s/de/user_connected/user_connected_0.mp3 similarity index 100% rename from assets/mp3s/de/user_connected/user_connected_0.mp3 rename to src/assets/mp3s/de/user_connected/user_connected_0.mp3 diff --git a/assets/mp3s/de/user_connected/user_connected_1.mp3 b/src/assets/mp3s/de/user_connected/user_connected_1.mp3 similarity index 100% rename from assets/mp3s/de/user_connected/user_connected_1.mp3 rename to src/assets/mp3s/de/user_connected/user_connected_1.mp3 diff --git a/assets/mp3s/de/user_connected/user_connected_2.mp3 b/src/assets/mp3s/de/user_connected/user_connected_2.mp3 similarity index 100% rename from assets/mp3s/de/user_connected/user_connected_2.mp3 rename to src/assets/mp3s/de/user_connected/user_connected_2.mp3 diff --git a/assets/mp3s/de/user_disconnected/user_disconnected_0.mp3 b/src/assets/mp3s/de/user_disconnected/user_disconnected_0.mp3 similarity index 100% rename from assets/mp3s/de/user_disconnected/user_disconnected_0.mp3 rename to src/assets/mp3s/de/user_disconnected/user_disconnected_0.mp3 diff --git a/assets/mp3s/de/user_disconnected/user_disconnected_1.mp3 b/src/assets/mp3s/de/user_disconnected/user_disconnected_1.mp3 similarity index 100% rename from assets/mp3s/de/user_disconnected/user_disconnected_1.mp3 rename to src/assets/mp3s/de/user_disconnected/user_disconnected_1.mp3 diff --git a/assets/mp3s/de/user_disconnected/user_disconnected_2.mp3 b/src/assets/mp3s/de/user_disconnected/user_disconnected_2.mp3 similarity index 100% rename from assets/mp3s/de/user_disconnected/user_disconnected_2.mp3 rename to src/assets/mp3s/de/user_disconnected/user_disconnected_2.mp3 diff --git a/assets/mp3s/en/announce/announce_0.mp3 b/src/assets/mp3s/en/announce/announce_0.mp3 similarity index 100% rename from assets/mp3s/en/announce/announce_0.mp3 rename to src/assets/mp3s/en/announce/announce_0.mp3 diff --git a/assets/mp3s/en/announce/announce_1.mp3 b/src/assets/mp3s/en/announce/announce_1.mp3 similarity index 100% rename from assets/mp3s/en/announce/announce_1.mp3 rename to src/assets/mp3s/en/announce/announce_1.mp3 diff --git a/assets/mp3s/en/announce/announce_2.mp3 b/src/assets/mp3s/en/announce/announce_2.mp3 similarity index 100% rename from assets/mp3s/en/announce/announce_2.mp3 rename to src/assets/mp3s/en/announce/announce_2.mp3 diff --git a/assets/mp3s/en/fail/fail_0.mp3 b/src/assets/mp3s/en/fail/fail_0.mp3 similarity index 100% rename from assets/mp3s/en/fail/fail_0.mp3 rename to src/assets/mp3s/en/fail/fail_0.mp3 diff --git a/assets/mp3s/en/fail/fail_1.mp3 b/src/assets/mp3s/en/fail/fail_1.mp3 similarity index 100% rename from assets/mp3s/en/fail/fail_1.mp3 rename to src/assets/mp3s/en/fail/fail_1.mp3 diff --git a/assets/mp3s/en/fail/fail_2.mp3 b/src/assets/mp3s/en/fail/fail_2.mp3 similarity index 100% rename from assets/mp3s/en/fail/fail_2.mp3 rename to src/assets/mp3s/en/fail/fail_2.mp3 diff --git a/assets/mp3s/en/join/join_0.mp3 b/src/assets/mp3s/en/join/join_0.mp3 similarity index 100% rename from assets/mp3s/en/join/join_0.mp3 rename to src/assets/mp3s/en/join/join_0.mp3 diff --git a/assets/mp3s/en/join/join_1.mp3 b/src/assets/mp3s/en/join/join_1.mp3 similarity index 100% rename from assets/mp3s/en/join/join_1.mp3 rename to src/assets/mp3s/en/join/join_1.mp3 diff --git a/assets/mp3s/en/join/join_2.mp3 b/src/assets/mp3s/en/join/join_2.mp3 similarity index 100% rename from assets/mp3s/en/join/join_2.mp3 rename to src/assets/mp3s/en/join/join_2.mp3 diff --git a/assets/mp3s/en/leave/leave_0.mp3 b/src/assets/mp3s/en/leave/leave_0.mp3 similarity index 100% rename from assets/mp3s/en/leave/leave_0.mp3 rename to src/assets/mp3s/en/leave/leave_0.mp3 diff --git a/assets/mp3s/en/leave/leave_1.mp3 b/src/assets/mp3s/en/leave/leave_1.mp3 similarity index 100% rename from assets/mp3s/en/leave/leave_1.mp3 rename to src/assets/mp3s/en/leave/leave_1.mp3 diff --git a/assets/mp3s/en/leave/leave_2.mp3 b/src/assets/mp3s/en/leave/leave_2.mp3 similarity index 100% rename from assets/mp3s/en/leave/leave_2.mp3 rename to src/assets/mp3s/en/leave/leave_2.mp3 diff --git a/assets/mp3s/en/read_only/read_only_0.mp3 b/src/assets/mp3s/en/read_only/read_only_0.mp3 similarity index 100% rename from assets/mp3s/en/read_only/read_only_0.mp3 rename to src/assets/mp3s/en/read_only/read_only_0.mp3 diff --git a/assets/mp3s/en/read_only/read_only_1.mp3 b/src/assets/mp3s/en/read_only/read_only_1.mp3 similarity index 100% rename from assets/mp3s/en/read_only/read_only_1.mp3 rename to src/assets/mp3s/en/read_only/read_only_1.mp3 diff --git a/assets/mp3s/en/read_only/read_only_2.mp3 b/src/assets/mp3s/en/read_only/read_only_2.mp3 similarity index 100% rename from assets/mp3s/en/read_only/read_only_2.mp3 rename to src/assets/mp3s/en/read_only/read_only_2.mp3 diff --git a/assets/mp3s/en/spotify/spotify_0.mp3 b/src/assets/mp3s/en/spotify/spotify_0.mp3 similarity index 100% rename from assets/mp3s/en/spotify/spotify_0.mp3 rename to src/assets/mp3s/en/spotify/spotify_0.mp3 diff --git a/assets/mp3s/en/spotify/spotify_1.mp3 b/src/assets/mp3s/en/spotify/spotify_1.mp3 similarity index 100% rename from assets/mp3s/en/spotify/spotify_1.mp3 rename to src/assets/mp3s/en/spotify/spotify_1.mp3 diff --git a/assets/mp3s/en/spotify/spotify_2.mp3 b/src/assets/mp3s/en/spotify/spotify_2.mp3 similarity index 100% rename from assets/mp3s/en/spotify/spotify_2.mp3 rename to src/assets/mp3s/en/spotify/spotify_2.mp3 diff --git a/assets/mp3s/en/url/url_0.mp3 b/src/assets/mp3s/en/url/url_0.mp3 similarity index 100% rename from assets/mp3s/en/url/url_0.mp3 rename to src/assets/mp3s/en/url/url_0.mp3 diff --git a/assets/mp3s/en/url/url_1.mp3 b/src/assets/mp3s/en/url/url_1.mp3 similarity index 100% rename from assets/mp3s/en/url/url_1.mp3 rename to src/assets/mp3s/en/url/url_1.mp3 diff --git a/assets/mp3s/en/url/url_2.mp3 b/src/assets/mp3s/en/url/url_2.mp3 similarity index 100% rename from assets/mp3s/en/url/url_2.mp3 rename to src/assets/mp3s/en/url/url_2.mp3 diff --git a/assets/mp3s/en/user_connected/user_connected_0.mp3 b/src/assets/mp3s/en/user_connected/user_connected_0.mp3 similarity index 100% rename from assets/mp3s/en/user_connected/user_connected_0.mp3 rename to src/assets/mp3s/en/user_connected/user_connected_0.mp3 diff --git a/assets/mp3s/en/user_connected/user_connected_1.mp3 b/src/assets/mp3s/en/user_connected/user_connected_1.mp3 similarity index 100% rename from assets/mp3s/en/user_connected/user_connected_1.mp3 rename to src/assets/mp3s/en/user_connected/user_connected_1.mp3 diff --git a/assets/mp3s/en/user_connected/user_connected_2.mp3 b/src/assets/mp3s/en/user_connected/user_connected_2.mp3 similarity index 100% rename from assets/mp3s/en/user_connected/user_connected_2.mp3 rename to src/assets/mp3s/en/user_connected/user_connected_2.mp3 diff --git a/assets/mp3s/en/user_disconnected/user_disconnected_0.mp3 b/src/assets/mp3s/en/user_disconnected/user_disconnected_0.mp3 similarity index 100% rename from assets/mp3s/en/user_disconnected/user_disconnected_0.mp3 rename to src/assets/mp3s/en/user_disconnected/user_disconnected_0.mp3 diff --git a/assets/mp3s/en/user_disconnected/user_disconnected_1.mp3 b/src/assets/mp3s/en/user_disconnected/user_disconnected_1.mp3 similarity index 100% rename from assets/mp3s/en/user_disconnected/user_disconnected_1.mp3 rename to src/assets/mp3s/en/user_disconnected/user_disconnected_1.mp3 diff --git a/assets/mp3s/en/user_disconnected/user_disconnected_2.mp3 b/src/assets/mp3s/en/user_disconnected/user_disconnected_2.mp3 similarity index 100% rename from assets/mp3s/en/user_disconnected/user_disconnected_2.mp3 rename to src/assets/mp3s/en/user_disconnected/user_disconnected_2.mp3 diff --git a/assets/mp3s/gr/announce/announce_0.mp3 b/src/assets/mp3s/gr/announce/announce_0.mp3 similarity index 100% rename from assets/mp3s/gr/announce/announce_0.mp3 rename to src/assets/mp3s/gr/announce/announce_0.mp3 diff --git a/assets/mp3s/gr/announce/announce_1.mp3 b/src/assets/mp3s/gr/announce/announce_1.mp3 similarity index 100% rename from assets/mp3s/gr/announce/announce_1.mp3 rename to src/assets/mp3s/gr/announce/announce_1.mp3 diff --git a/assets/mp3s/gr/announce/announce_2.mp3 b/src/assets/mp3s/gr/announce/announce_2.mp3 similarity index 100% rename from assets/mp3s/gr/announce/announce_2.mp3 rename to src/assets/mp3s/gr/announce/announce_2.mp3 diff --git a/assets/mp3s/gr/fail/fail_0.mp3 b/src/assets/mp3s/gr/fail/fail_0.mp3 similarity index 100% rename from assets/mp3s/gr/fail/fail_0.mp3 rename to src/assets/mp3s/gr/fail/fail_0.mp3 diff --git a/assets/mp3s/gr/fail/fail_1.mp3 b/src/assets/mp3s/gr/fail/fail_1.mp3 similarity index 100% rename from assets/mp3s/gr/fail/fail_1.mp3 rename to src/assets/mp3s/gr/fail/fail_1.mp3 diff --git a/assets/mp3s/gr/fail/fail_2.mp3 b/src/assets/mp3s/gr/fail/fail_2.mp3 similarity index 100% rename from assets/mp3s/gr/fail/fail_2.mp3 rename to src/assets/mp3s/gr/fail/fail_2.mp3 diff --git a/assets/mp3s/gr/join/join_0.mp3 b/src/assets/mp3s/gr/join/join_0.mp3 similarity index 100% rename from assets/mp3s/gr/join/join_0.mp3 rename to src/assets/mp3s/gr/join/join_0.mp3 diff --git a/assets/mp3s/gr/join/join_1.mp3 b/src/assets/mp3s/gr/join/join_1.mp3 similarity index 100% rename from assets/mp3s/gr/join/join_1.mp3 rename to src/assets/mp3s/gr/join/join_1.mp3 diff --git a/assets/mp3s/gr/join/join_2.mp3 b/src/assets/mp3s/gr/join/join_2.mp3 similarity index 100% rename from assets/mp3s/gr/join/join_2.mp3 rename to src/assets/mp3s/gr/join/join_2.mp3 diff --git a/assets/mp3s/gr/join/join_3.mp3 b/src/assets/mp3s/gr/join/join_3.mp3 similarity index 100% rename from assets/mp3s/gr/join/join_3.mp3 rename to src/assets/mp3s/gr/join/join_3.mp3 diff --git a/assets/mp3s/gr/join/join_4.mp3 b/src/assets/mp3s/gr/join/join_4.mp3 similarity index 100% rename from assets/mp3s/gr/join/join_4.mp3 rename to src/assets/mp3s/gr/join/join_4.mp3 diff --git a/assets/mp3s/gr/joke_0.mp3 b/src/assets/mp3s/gr/joke_0.mp3 similarity index 100% rename from assets/mp3s/gr/joke_0.mp3 rename to src/assets/mp3s/gr/joke_0.mp3 diff --git a/assets/mp3s/gr/leave/leave_0.mp3 b/src/assets/mp3s/gr/leave/leave_0.mp3 similarity index 100% rename from assets/mp3s/gr/leave/leave_0.mp3 rename to src/assets/mp3s/gr/leave/leave_0.mp3 diff --git a/assets/mp3s/gr/leave/leave_1.mp3 b/src/assets/mp3s/gr/leave/leave_1.mp3 similarity index 100% rename from assets/mp3s/gr/leave/leave_1.mp3 rename to src/assets/mp3s/gr/leave/leave_1.mp3 diff --git a/assets/mp3s/gr/leave/leave_2.mp3 b/src/assets/mp3s/gr/leave/leave_2.mp3 similarity index 100% rename from assets/mp3s/gr/leave/leave_2.mp3 rename to src/assets/mp3s/gr/leave/leave_2.mp3 diff --git a/assets/mp3s/gr/read_only/read_only_0.mp3 b/src/assets/mp3s/gr/read_only/read_only_0.mp3 similarity index 100% rename from assets/mp3s/gr/read_only/read_only_0.mp3 rename to src/assets/mp3s/gr/read_only/read_only_0.mp3 diff --git a/assets/mp3s/gr/read_only/read_only_1.mp3 b/src/assets/mp3s/gr/read_only/read_only_1.mp3 similarity index 100% rename from assets/mp3s/gr/read_only/read_only_1.mp3 rename to src/assets/mp3s/gr/read_only/read_only_1.mp3 diff --git a/assets/mp3s/gr/read_only/read_only_2.mp3 b/src/assets/mp3s/gr/read_only/read_only_2.mp3 similarity index 100% rename from assets/mp3s/gr/read_only/read_only_2.mp3 rename to src/assets/mp3s/gr/read_only/read_only_2.mp3 diff --git a/assets/mp3s/gr/spotify/spotify_0.mp3 b/src/assets/mp3s/gr/spotify/spotify_0.mp3 similarity index 100% rename from assets/mp3s/gr/spotify/spotify_0.mp3 rename to src/assets/mp3s/gr/spotify/spotify_0.mp3 diff --git a/assets/mp3s/gr/spotify/spotify_1.mp3 b/src/assets/mp3s/gr/spotify/spotify_1.mp3 similarity index 100% rename from assets/mp3s/gr/spotify/spotify_1.mp3 rename to src/assets/mp3s/gr/spotify/spotify_1.mp3 diff --git a/assets/mp3s/gr/spotify/spotify_2.mp3 b/src/assets/mp3s/gr/spotify/spotify_2.mp3 similarity index 100% rename from assets/mp3s/gr/spotify/spotify_2.mp3 rename to src/assets/mp3s/gr/spotify/spotify_2.mp3 diff --git a/assets/mp3s/gr/url/url_0.mp3 b/src/assets/mp3s/gr/url/url_0.mp3 similarity index 100% rename from assets/mp3s/gr/url/url_0.mp3 rename to src/assets/mp3s/gr/url/url_0.mp3 diff --git a/assets/mp3s/gr/url/url_1.mp3 b/src/assets/mp3s/gr/url/url_1.mp3 similarity index 100% rename from assets/mp3s/gr/url/url_1.mp3 rename to src/assets/mp3s/gr/url/url_1.mp3 diff --git a/assets/mp3s/gr/url/url_2.mp3 b/src/assets/mp3s/gr/url/url_2.mp3 similarity index 100% rename from assets/mp3s/gr/url/url_2.mp3 rename to src/assets/mp3s/gr/url/url_2.mp3 diff --git a/assets/mp3s/gr/user_connected/user_connected_0.mp3 b/src/assets/mp3s/gr/user_connected/user_connected_0.mp3 similarity index 100% rename from assets/mp3s/gr/user_connected/user_connected_0.mp3 rename to src/assets/mp3s/gr/user_connected/user_connected_0.mp3 diff --git a/assets/mp3s/gr/user_connected/user_connected_1.mp3 b/src/assets/mp3s/gr/user_connected/user_connected_1.mp3 similarity index 100% rename from assets/mp3s/gr/user_connected/user_connected_1.mp3 rename to src/assets/mp3s/gr/user_connected/user_connected_1.mp3 diff --git a/assets/mp3s/gr/user_connected/user_connected_2.mp3 b/src/assets/mp3s/gr/user_connected/user_connected_2.mp3 similarity index 100% rename from assets/mp3s/gr/user_connected/user_connected_2.mp3 rename to src/assets/mp3s/gr/user_connected/user_connected_2.mp3 diff --git a/assets/mp3s/gr/user_disconnected/user_disconnected_0.mp3 b/src/assets/mp3s/gr/user_disconnected/user_disconnected_0.mp3 similarity index 100% rename from assets/mp3s/gr/user_disconnected/user_disconnected_0.mp3 rename to src/assets/mp3s/gr/user_disconnected/user_disconnected_0.mp3 diff --git a/assets/mp3s/gr/user_disconnected/user_disconnected_1.mp3 b/src/assets/mp3s/gr/user_disconnected/user_disconnected_1.mp3 similarity index 100% rename from assets/mp3s/gr/user_disconnected/user_disconnected_1.mp3 rename to src/assets/mp3s/gr/user_disconnected/user_disconnected_1.mp3 diff --git a/assets/mp3s/gr/user_disconnected/user_disconnected_2.mp3 b/src/assets/mp3s/gr/user_disconnected/user_disconnected_2.mp3 similarity index 100% rename from assets/mp3s/gr/user_disconnected/user_disconnected_2.mp3 rename to src/assets/mp3s/gr/user_disconnected/user_disconnected_2.mp3 diff --git a/src/commands/about.js b/src/commands/about.js deleted file mode 100644 index e3715953..00000000 --- a/src/commands/about.js +++ /dev/null @@ -1,68 +0,0 @@ -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; -var __generator = (this && this.__generator) || function (thisArg, body) { - var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; - return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; - function verb(n) { return function (v) { return step([n, v]); }; } - function step(op) { - if (f) throw new TypeError("Generator is already executing."); - while (_) try { - if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; - if (y = 0, t) op = [op[0] & 2, t.value]; - switch (op[0]) { - case 0: case 1: t = op; break; - case 4: _.label++; return { value: op[1], done: false }; - case 5: _.label++; y = op[1]; op = [0]; continue; - case 7: op = _.ops.pop(); _.trys.pop(); continue; - default: - if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } - if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } - if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } - if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } - if (t[2]) _.ops.pop(); - _.trys.pop(); continue; - } - op = body.call(thisArg, _); - } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } - if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; - } -}; -var _this = this; -module.exports = function (client, message, args, portal_guilds, portal_managed_guilds_path) { return __awaiter(_this, void 0, void 0, function () { - var help_mngr; - return __generator(this, function (_a) { - help_mngr = require('../functions/help_manager'); - return [2 /*return*/, new Promise(function (resolve) { - message.channel.send(help_mngr.create_rich_embed('About', 'a portal to a managed discord server', '#1DB954', [ - { - emote: 'Creator', - role: '***Keybraker***', - inline: true - }, - { - emote: 'Created', - role: '***2020***', - inline: true - }, - { - emote: 'Version', - role: '***1.0.2***', - inline: true - }, - { - emote: 'For help just type', - role: './help', - inline: false - }, - ], false, client.user.member, true, 'https://portal-bot.xyz/')); - return resolve({ result: true, value: 'about message.' }); - })]; - }); -}); }; diff --git a/src/commands/about.ts b/src/commands/about.ts new file mode 100644 index 00000000..bf0970c5 --- /dev/null +++ b/src/commands/about.ts @@ -0,0 +1,43 @@ +import { Client, Message } from "discord.js"; +import { create_rich_embed } from "../libraries/helpOps"; +import { GuildPrtl } from "../types/classes/GuildPrtl"; + +module.exports = async ( + client: Client, message: Message, args: string[], + guild_list: GuildPrtl[], portal_managed_guilds_path: string +) => { + return new Promise((resolve) => { + message.channel.send(create_rich_embed( + 'About', + 'a portal to a managed discord server', + '#1DB954', + [{ + emote: 'Creator', + role: 'Keybraker', + inline: true + }, + { + emote: 'Created', + role: '2020', + inline: true + }, + { + emote: 'Version', + role: '1.0.2', + inline: true + }, + { + emote: 'For help just type', + role: './help', + inline: false + }], + null, + null, + true, + 'https://portal-bot.xyz/', + null) + ); + + return resolve({ result: true, value: '' }); + }); +}; \ No newline at end of file diff --git a/src/commands/announce.js b/src/commands/announce.js deleted file mode 100644 index 011854c8..00000000 --- a/src/commands/announce.js +++ /dev/null @@ -1,29 +0,0 @@ -/* eslint-disable no-unused-vars */ -const lclz_mngr = require('./../functions/localization_manager'); -const help_mngr = require('./../functions/help_manager'); - -module.exports = async (client, message, args, portal_guilds, portal_managed_guilds_path) => { - return new Promise((resolve) => { - if (!portal_guilds[message.guild.id].announcement) { - return resolve ({ result: false, value: 'announcements channel has not been set.' }); - } - - let body = args.join(' ').substr(0, args.join(' ').indexOf('|')); - let title = args.join(' ').substr(args.join(' ').indexOf('|') + 1); - - if (body === '' && title !== '') { - body = title; - title = ''; - } - else if (body === '' && title === '') { - return resolve ({ result: false, value: 'you can run "./help announce" for help.' }); - } - - message.guild.channels.cache.find(channel => channel.id === portal_guilds[message.guild.id].announcement) - .send(help_mngr.create_rich_embed(title, `@here ${body}`, '#022E4E', [], null, message.member, false)); - - lclz_mngr.client_talk(client, portal_guilds, 'announce'); - - return resolve ({ result: true, value: 'announcement was sent successfully.' }); - }); -}; diff --git a/src/commands/announce.ts b/src/commands/announce.ts new file mode 100644 index 00000000..9d351deb --- /dev/null +++ b/src/commands/announce.ts @@ -0,0 +1,42 @@ +import { Client, Message, TextChannel } from "discord.js"; +import { create_rich_embed } from "../libraries/helpOps"; +import { client_talk } from "../libraries/localizationOps"; +import { GuildPrtl } from "../types/classes/GuildPrtl"; + +module.exports = async ( + client: Client, message: Message, args: string[], + guild_list: GuildPrtl[], portal_managed_guilds_path: string +) => { + return new Promise((resolve) => { + const guild_object = guild_list.find(p => p.id === message.guild?.id); + if (!guild_object) { + return resolve({ result: false, value: 'could not find guild.' }); + } + if (!guild_object.announcement) { + return resolve({ result: false, value: 'announcements channel has not been set yet.' }); + } + + let body = args.join(' ').substr(0, args.join(' ').indexOf('|')); + let title = args.join(' ').substr(args.join(' ').indexOf('|') + 1); + + if (body === '' && title !== '') { + body = title; + title = ''; + } else if (body === '' && title === '') { + return resolve({ result: false, value: 'you can run "./help announce" for help.' }); + } + + const announcement_channel = message?.guild?.channels.cache.find(c => + c.id === guild_object.announcement + ); + if (!announcement_channel) { + return resolve({ result: false, value: 'announcements channel could not be fetched.' }); + } + const rich_message = create_rich_embed(title, `@here ${body}`, '#022E4E', [], null, message.member, null, null, null) + announcement_channel.send(rich_message); + + client_talk(client, guild_list, 'announce'); + + return resolve({ result: true, value: 'announcement was sent successfully.' }); + }); +}; \ No newline at end of file diff --git a/src/commands/announcement.js b/src/commands/announcement.js deleted file mode 100644 index 3fb142a2..00000000 --- a/src/commands/announcement.js +++ /dev/null @@ -1,79 +0,0 @@ -const guld_mngr = require('./../functions/guild_manager'); - -// eslint-disable-next-line no-unused-vars -module.exports = async (client, message, args, portal_guilds, portal_managed_guilds_path) => { - return new Promise((resolve) => { - if (args.length === 0) { - if (guld_mngr.is_announcement_channel(message.channel.id, portal_guilds[message.guild.id])) { - return resolve ({ - result: true, - value: '*this already is, the Announcement channel.*', - }); - } - if (guld_mngr.is_spotify_channel(message.channel.id, portal_guilds[message.guild.id])) { - return resolve ({ - result: true, - value: '*this can\'t be set as the Announcemennt channel for it is the Spotify channel.*', - }); - } - if (guld_mngr.is_music_channel(message.channel.id, portal_guilds[message.guild.id])) { - resolve ({ - result: true, - value: '*this can\'t be set as a Announcemennt channel for it is the Music channel.*', - }); - } - if (guld_mngr.included_in_url_list(message.channel.id, portal_guilds[message.guild.id])) { - return resolve ({ - result: true, - value: '*this can\'t be set as the Announcemennt channel for it is an url channel.*', - }); - } - } - - const announcement = message.guild.channels.cache - .find(channel => channel.id == portal_guilds[message.guild.id].announcement); - - if (announcement) guld_mngr.delete_channel(announcement, message); - - if (args.length === 0) { - portal_guilds[message.guild.id].announcement = message.channel.id; - return resolve ({ - result: true, - value: '*this is now the Announcement channel.*', - }); - } - else if (args.length > 0) { - const announcement_channel = args.join(' ').substr(0, args.join(' ').indexOf('|')); - const announcement_category = args.join(' ').substr(args.join(' ').indexOf('|') + 1); - - if (announcement_channel !== '') { - guld_mngr.create_announcement_channel( - message.guild, announcement_channel, - announcement_category, portal_guilds[message.guild.id], - ); - - return resolve ({ - result: true, - value: '*announcement channel and category have been created*', - }); - } - else if (announcement_channel === '' && announcement_category !== '') { - guld_mngr.create_announcement_channel( - message.guild, announcement_category, - null, portal_guilds[message.guild.id], - ); - - return resolve ({ - result: true, - value: '*announcement channel has been created*', - }); - } - else { - return resolve ({ - result: false, - value: '*you can run "./help announcement" for help.*', - }); - } - } - }); -}; diff --git a/src/commands/announcement.ts b/src/commands/announcement.ts new file mode 100644 index 00000000..b11ea3d3 --- /dev/null +++ b/src/commands/announcement.ts @@ -0,0 +1,103 @@ +import { Client, Message, VoiceChannel } from "discord.js"; +import { GuildPrtl } from "../types/classes/GuildPrtl"; +import { + is_announcement_channel, is_spotify_channel, is_music_channel, + included_in_url_list, delete_channel, create_channel, getOptions +} from "../libraries/guildOps"; + +module.exports = async ( + client: Client, message: Message, args: string[], + guild_list: GuildPrtl[], portal_managed_guilds_path: string +) => { + return new Promise((resolve) => { + const guild_object = guild_list.find(g => g.id === message.guild?.id); + if (!guild_object) { + return resolve({ result: true, value: 'portal guild could not be fetched' }); + } + if (message.guild === null) { + return resolve({ result: true, value: 'message guild could not be fetched' }); + } + + if (args.length === 0) { + if (is_announcement_channel(message.channel.id, guild_object)) { + return resolve({ + result: true, + value: 'this already is, the Announcement channel.', + }); + } + if (is_spotify_channel(message.channel.id, guild_object)) { + return resolve({ + result: true, + value: 'this can\'t be set as the Announcemennt channel for it is the Spotify channel.', + }); + } + if (is_music_channel(message.channel.id, guild_object)) { + resolve({ + result: true, + value: 'this can\'t be set as a Announcemennt channel for it is the Music channel.', + }); + } + if (included_in_url_list(message.channel.id, guild_object)) { + return resolve({ + result: true, + value: 'this can\'t be set as the Announcemennt channel for it is an url channel.', + }); + } + } + + const announcement = message.guild.channels.cache + .find(channel => channel.id == guild_object.announcement); + + if (announcement) delete_channel(announcement, message); + + if (args.length === 0) { + guild_object.announcement = message.channel.id; + return resolve({ + result: true, + value: 'this is now the Announcement channel.', + }); + } + else if (args.length > 0) { + const announcement_channel = args.join(' ').substr(0, args.join(' ').indexOf('|')); + const announcement_category = args.join(' ').substr(args.join(' ').indexOf('|') + 1); + const announcement_options = getOptions(message.guild, 'announcements channel (Portal/Users/Admins)', false); + + if (announcement_channel !== '') { + create_channel( + message.guild, announcement_channel, + announcement_options, announcement_category + ) + .then(response => { + if (response.result) { + guild_object.announcement = response.value; + return resolve({ result: true, value: 'announcement channel and category created' }); + } else { + return resolve(response); + } + }) + .catch(error => { return resolve(error); }); + } + else if (announcement_channel === '' && announcement_category !== '') { + create_channel( + message.guild, announcement_category, + announcement_options, null + ) + .then(response => { + if (response.result) { + guild_object.announcement = response.value; + return resolve({ result: true, value: 'announcement channel created' }); + } else { + return resolve(response); + } + }) + .catch(error => { return resolve(error); }); + } + else { + return resolve({ + result: false, + value: 'you can run "./help announcement" for help.', + }); + } + } + }); +}; diff --git a/src/commands/auth_role_add.js b/src/commands/auth_role_add.js deleted file mode 100644 index 16c5decd..00000000 --- a/src/commands/auth_role_add.js +++ /dev/null @@ -1,23 +0,0 @@ -module.exports = async (client, message, args, portal_guilds) => { - return new Promise((resolve) => { - if (args.length <= 0) { - resolve({ result: false, value: 'you should give one role.\nyou can run "./help auth_role_rem" for help.*' }); - } - - const role_name = args.join(' '); - const role = message.guild.roles.cache.find(current_role => role_name === current_role.name); - - if (role) { - for (const i in portal_guilds[message.guild.id].auth_role) { - if (portal_guilds[message.guild.id].auth_role[i] === role.id) { - return resolve({ result: false, value: `role "${role_name}" is already an authorized role.` }); - } - } - portal_guilds[message.guild.id].auth_role.push(role.id); - resolve({ result: true, value: `role "${role_name}" has been added to role list.` }); - } - else { - resolve({ result: false, value: `role "${role_name}" does not exist in guild "${message.guild}".` }); - } - }); -}; diff --git a/src/commands/auth_role_rem.js b/src/commands/auth_role_rem.js deleted file mode 100644 index 427a6ceb..00000000 --- a/src/commands/auth_role_rem.js +++ /dev/null @@ -1,23 +0,0 @@ -module.exports = async (client, message, args, portal_guilds) => { - return new Promise((resolve) => { - if(args.length <= 0) { - resolve({ result: false, value: 'you should give one role.\nyou can run "./help auth_role_rem" for help.*' }); - } - - const role_name = args.join(' '); - const role = message.guild.roles.cache.find(current_role => role_name === current_role.name); - - if(role) { - for (const i in portal_guilds[message.guild.id].auth_role) { - if (portal_guilds[message.guild.id].auth_role[i] === role.id) { - portal_guilds[message.guild.id].auth_role.splice(i, 1); - return resolve({ result: true, value: `role ${role_name} has been removed from authorized roles.` }); - } - } - return resolve({ result: false, value: `role ${role_name} is not in role list.` }); - } - else { - resolve({ result: false, value: `role ${role_name} does not exist in guild ${message.guild}.` }); - } - }); -}; diff --git a/src/commands/auth_roles.js b/src/commands/auth_roles.js deleted file mode 100644 index 7c774b74..00000000 --- a/src/commands/auth_roles.js +++ /dev/null @@ -1,20 +0,0 @@ -module.exports = async (client, message, args, portal_guilds) => { - return new Promise((resolve) => { - const roles = portal_guilds[message.guild.id].auth_role; - const get_role_name = (role_id, i) => { - return `${i}. ${message.guild.roles.cache.find(r => r.id === role_id).name}`; - }; - if (portal_guilds[message.guild.id].auth_role.length > 0) { - resolve({ - result: true, - value: `*Authorized Roles:*\n${roles.map((r, i) => get_role_name(r, i)).join('\n')}`, - }); - } - else { - resolve({ - result: false, - value: 'There are no authorization roles.', - }); - } - }); -}; diff --git a/src/commands/authorise.ts b/src/commands/authorise.ts new file mode 100644 index 00000000..c0ad6de3 --- /dev/null +++ b/src/commands/authorise.ts @@ -0,0 +1,42 @@ +import { Client, Message } from "discord.js"; +import { GuildPrtl } from "../types/classes/GuildPrtl"; + +module.exports = async ( + client: Client, message: Message, args: string[], + guild_list: GuildPrtl[], portal_managed_guilds_path: string +) => { + return new Promise((resolve) => { + if (args.length <= 0) + resolve({ result: false, value: 'you should give one argument (role name, role id or member id).\nyou can run "./help authorise" for help.*' }); + + const guild_object = guild_list.find(g => g.id === message.guild?.id); + if (!guild_object) + return resolve({ result: true, value: 'portal guild could not be fetched' }); + + const role_name = args.join(' '); + const role = message?.guild?.roles.cache.find(current_role => role_name === current_role.name); + + const member_found = guild_object.member_list.some(m => { + console.log(`${m.id} === ${role_name}`); + if (m.id === role_name) { + m.admin = true; + const member = message.guild?.members.cache.find(mb => mb.id === m.id); + resolve({ result: true, value: `member ${member ? member : m.id} has been made an admin` }); + } + return false; + }); + + if (role) { + for (const i in guild_object.auth_role) { + if (guild_object.auth_role[i] === role.id) { + return resolve({ result: false, value: `role "${role_name}" is already an authorised role` }); + } + } + guild_object.auth_role.push(role.id); + resolve({ result: true, value: `role "${role_name}" has been added to role list` }); + } + else { + resolve({ result: false, value: `"${role_name}" is neither a role nor a member id` }); + } + }); +}; diff --git a/src/commands/authorised_roles.ts b/src/commands/authorised_roles.ts new file mode 100644 index 00000000..4cfd072b --- /dev/null +++ b/src/commands/authorised_roles.ts @@ -0,0 +1,31 @@ +import { Client, Message } from "discord.js"; +import { GuildPrtl } from "../types/classes/GuildPrtl"; +import { get_role_name } from "../libraries/guildOps"; + +module.exports = async ( + client: Client, message: Message, args: string[], + guild_list: GuildPrtl[], portal_managed_guilds_path: string +) => { + return new Promise((resolve) => { + const guild_object = guild_list.find(g => g.id === message.guild?.id); + if (!guild_object) { + return resolve({ result: true, value: 'portal guild could not be fetched' }); + } + + const roles = guild_object.auth_role; + + + if (guild_object.auth_role.length > 0) { + resolve({ + result: true, + value: `*authorised roles:*\n${roles.map((r, i) => get_role_name(r, i, message)).join('\n')}`, + }); + } + else { + resolve({ + result: false, + value: 'there are no authorisation roles.', + }); + } + }); +}; diff --git a/src/commands/corona.js b/src/commands/corona.js deleted file mode 100644 index c68847e2..00000000 --- a/src/commands/corona.js +++ /dev/null @@ -1,122 +0,0 @@ -/* eslint-disable no-unused-vars */ -const country_codes = require('../../assets/jsons/country_codes.json'); - -const http_mngr = require('../functions/http_requests'); -const help_mngr = require('../functions/help_manager'); - -const moment = require('moment'); -const voca = require('voca'); - -const get_country_code = function(country) { - for (let i = 0; i < country_codes.length; i++) { - if (voca.lowerCase(country_codes[i].name) === voca.lowerCase(country)) { - return country_codes[i].name; - } - else if (voca.lowerCase(country_codes[i].code) === voca.lowerCase(country)) { - return country_codes[i].name; - } - } - return null; -}; - -module.exports = async (client, message, args, portal_guilds, portal_managed_guilds_path, user_match) => { - return new Promise((resolve) => { - let code = null; - - if (args.length === 1) { - code = get_country_code(args[0]); - if (code === null) { - return resolve ({ - result: false, - value: `*${args[0]} is neither a country name nor a country code.*`, - }); - } - } - else if(args.length > 1) { - return resolve ({ - result: false, - value: '*you can run "./help corona" for help.*', - }); - } - else { - return resolve ({ - result: false, - value: '*Global stats are temporarily unavailable.*', - }); - } - - const options = { - 'method': 'GET', - 'hostname': 'covid-193.p.rapidapi.com', - 'port': null, - 'path': '/statistics', - 'headers': { - 'x-rapidapi-host': 'covid-193.p.rapidapi.com', - 'x-rapidapi-key': 'b883903090msh7eef2b50e6cbe9cp1ff439jsnee4d6c48061f', - 'useQueryString': true, - }, - }; - - http_mngr(options) - .then(rspns => { - const json = help_mngr.getJSON(rspns.toString().substring(rspns.toString().indexOf('{'))); - if(json === null) { - return resolve ({ - result: false, - value: 'data from source was corrupted', - }); - } - - if (json.errors.length === 0) { - const country_data = json.response.find(data => data.country === code); - - message.channel.send( - help_mngr.create_rich_embed(`COVID19 ${country_data.country} stats ${moment().format('DD/MM/YY')}`, - 'covid-19 be api-sports', '#FF0000', [ - { - emote: 'NEW cases', - role: `***${country_data.cases.new}***`, inline: true }, - { - emote: 'NEW deaths', - role: `***${country_data.deaths.new}***`, inline: true }, - { - emote: 'Tests P1M', - role: `***${country_data.tests['1M_pop']}***`, inline: true }, - { - emote: 'Cases', - role: `***${country_data.cases.total}***`, inline: true }, - { - emote: 'Deaths', - role: `***${country_data.deaths.total}***`, inline: true }, - { - emote: 'Recovered', - role: `***${country_data.cases.recovered}***`, inline: true }, - { - emote: '%Recovered', - role: `***${((country_data.cases.recovered / country_data.cases.total) * 100) - .toFixed(2)}%***`, inline: true }, - { - emote: '%Diseased', - role: `***${((country_data.deaths.total / country_data.cases.total) * 100) - .toFixed(2)}%***`, inline: true }, - { - emote: 'Critical', - role: `***${country_data.cases.critical}***`, inline: true }, - ], null, null, true)); - return resolve({ result: true, value: `*${country_data.country} corona stats.*` }); - } - else { - return resolve({ - result: false, - value: `*${args[0]} is neither a country name nor a country code.*`, - }); - } - }) - .catch(rspns => { - return resolve({ - result: false, - value: '*Could not access the server*', - }); - }); - }); -}; diff --git a/src/commands/corona.ts b/src/commands/corona.ts new file mode 100644 index 00000000..0a3196db --- /dev/null +++ b/src/commands/corona.ts @@ -0,0 +1,148 @@ +/* eslint-disable no-unused-vars */ +import { Client, Message } from 'discord.js'; +import { RequestOptions } from 'https'; +import moment from 'moment'; +import voca from 'voca'; +import country_codes_json from '../assets/jsons/country_codes.json'; +import config from '../config.json'; +import { create_rich_embed, getJSON } from '../libraries/helpOps'; +import { https_fetch } from '../libraries/httpOps'; +import { GuildPrtl } from '../types/classes/GuildPrtl'; + +const country_codes: { name: string; code: string; }[] = country_codes_json; + +const get_country_code = function (country: string): string | null { + for (let i = 0; i < country_codes.length; i++) { + if (voca.lowerCase(country_codes[i].name) === voca.lowerCase(country)) + return country_codes[i].name; + else if (voca.lowerCase(country_codes[i].code) === voca.lowerCase(country)) + return country_codes[i].name; + } + return null; +}; + +module.exports = async ( + client: Client, message: Message, args: string[], + guild_list: GuildPrtl[], portal_managed_guilds_path: string +) => { + return new Promise((resolve) => { + const guild_object = guild_list.find(g => g.id === message.guild?.id); + if (!guild_object) + return resolve({ result: true, value: 'portal guild could not be fetched' }); + + let code: string | null = null; + + if (args.length === 1) { + code = get_country_code(args[0]); + if (code === null) { + return resolve({ + result: false, + value: `*${args[0]} is neither a country name nor a country code.*`, + }); + } + } + else if (args.length > 1) { + return resolve({ + result: false, + value: '*you can run "./help corona" for help.*', + }); + } + else { + return resolve({ + result: false, + value: '*Global stats are temporarily unavailable.*', + }); + } + + const options: RequestOptions = { + 'method': 'GET', + 'hostname': 'covid-193.p.rapidapi.com', + 'port': undefined, + 'path': '/statistics', + 'headers': { + 'x-rapidapi-host': 'covid-193.p.rapidapi.com', + 'x-rapidapi-key': config.api_keys.covid_193, + 'useQueryString': 1, + }, + }; + + https_fetch(options) + .then((rspns: Buffer) => { + const json = getJSON(rspns.toString().substring(rspns.toString().indexOf('{'))); + if (json === null) + return resolve({ result: false, value: 'data from source was corrupted' }); + + if (json.errors.length === 0) { + const country_data = json.response.find((data: any) => data.country === code); + + message.channel.send( + create_rich_embed( + `COVID19 ${country_data.country} stats ${moment().format('DD/MM/YY')}`, + 'powered by api-sports', + '#FF0000', + [ + { + emote: 'NEW cases', + role: `${country_data.cases.new}`, inline: true + }, + { + emote: 'NEW deaths', + role: `${country_data.deaths.new}`, inline: true + }, + { + emote: 'Tests P1M', + role: `${country_data.tests['1M_pop']}`, inline: true + }, + { + emote: 'Cases', + role: `${country_data.cases.total}`, inline: true + }, + { + emote: 'Deaths', + role: `${country_data.deaths.total}`, inline: true + }, + { + emote: 'Recovered', + role: `${country_data.cases.recovered}`, inline: true + }, + { + emote: '%Recovered', + role: `${((country_data.cases.recovered / country_data.cases.total) * 100) + .toFixed(2)}%`, inline: true + }, + { + emote: '%Diseased', + role: `${((country_data.deaths.total / country_data.cases.total) * 100) + .toFixed(2)}%`, inline: true + }, + { + emote: 'Critical', + role: `${country_data.cases.critical}`, inline: true + }, + ], + null, + null, + true, + null, + null + )); + return resolve({ + result: true, + value: `*${country_data.country} corona stats.*` + }); + } + else { + return resolve({ + result: false, + value: `*${args[0]} is neither a country name nor a country code.*`, + }); + } + }) + .catch((error: any) => { + return resolve({ + result: false, + value: `*Could not access the server*\nerror: ${error}`, + }); + }); + }); +}; diff --git a/src/commands/corona_old.js b/src/commands/corona_old.js index bc839046..0317a231 100644 --- a/src/commands/corona_old.js +++ b/src/commands/corona_old.js @@ -1,155 +1,183 @@ /* eslint-disable no-unused-vars */ -const country_codes = require('../../assets/jsons/country_codes.json'); +const country_codes = require('../assets/jsons/country_codes.json'); -const http_mngr = require('../functions/http_requests'); -const help_mngr = require('../functions/help_manager'); +const http_mngr = require('../libraries/httpOps'); +const help_mngr = require('../libraries/helpOps'); const moment = require('moment'); const voca = require('voca'); const get_country_code = function(country) { - for (let i = 0; i < country_codes.length; i++) { - if (voca.lowerCase(country_codes[i].name) === voca.lowerCase(country)) { - return country_codes[i].code; - } - else if (voca.lowerCase(country_codes[i].code) === voca.lowerCase(country)) { - return country_codes[i].code; - } - } - return null; + for (let i = 0; i < country_codes.length; i++) { + if (voca.lowerCase(country_codes[i].name) === voca.lowerCase(country)) { + return country_codes[i].code; + } else if (voca.lowerCase(country_codes[i].code) === voca.lowerCase(country)) { + return country_codes[i].code; + } + } + return null; }; -module.exports = async (client, message, args, portal_guilds, portal_managed_guilds_path, user_match) => { - return new Promise((resolve) => { - let url = null; - if (args.length === 0) { - url = '/free-api?global=stats'; - } - else if (args.length === 1) { - const code = get_country_code(args[0]); - if (code !== null) { - url = '/free-api?countryTotal=' + code; - } - else { - return resolve ({ - result: false, - value: `*${args[0]} is neither a country name nor a country code.*`, - }); - } - } - else { - return resolve ({ - result: false, - value: '*you can run "./help corona" for help.*', - }); - } +module.exports = async(client, message, args, portal_guilds, portal_managed_guilds_path, user_match) => { + return new Promise((resolve) => { + let url = null; + if (args.length === 0) { + url = '/free-api?global=stats'; + } else if (args.length === 1) { + const code = get_country_code(args[0]); + if (code !== null) { + url = '/free-api?countryTotal=' + code; + } else { + return resolve({ + result: false, + value: `*${args[0]} is neither a country name nor a country code.*`, + }); + } + } else { + return resolve({ + result: false, + value: '*you can run "./help corona" for help.*', + }); + } - const options = { - 'method': 'GET', - 'hostname': 'api.thevirustracker.com', - 'path': url, - 'headers': {}, - 'maxRedirects': 20, - }; + const options = { + 'method': 'GET', + 'hostname': 'api.thevirustracker.com', + 'path': url, + 'headers': {}, + 'maxRedirects': 20, + }; - http_mngr(options) - .then(rspns => { - const json = help_mngr.getJSON(rspns.toString().substring(rspns.toString().indexOf('{'))); - if(json === null) { - return resolve ({ - result: false, - value: 'data from source was corrupted', - }); - } + http_mngr(options) + .then(rspns => { + const json = help_mngr.getJSON(rspns.toString().substring(rspns.toString().indexOf('{'))); + if (json === null) { + return resolve({ + result: false, + value: 'data from source was corrupted', + }); + } - if (json.countrydata !== undefined) { - const daily_stats = json.countrydata[0]; - const country_stats = json.countrydata[0].info; + if (json.countrydata !== undefined) { + const daily_stats = json.countrydata[0]; + const country_stats = json.countrydata[0].info; - message.channel.send( - help_mngr.create_rich_embed(`COVID19 ${country_stats.title} stats ${moment().format('DD/MM/YY')}`, - 'https://thevirustracker.com/', '#FF0000', [ - { - emote: 'New cases', - role: `+***${daily_stats.total_new_cases_today}***`, inline: true }, - { - emote: 'New deaths', - role: `+***${daily_stats.total_new_deaths_today}***`, inline: true }, - { - emote: 'Danger rank', - role: `***${daily_stats.total_danger_rank}***`, inline: true }, - { - emote: 'Total cases', - role: `***${daily_stats.total_cases}***`, inline: true }, - { - emote: 'Total deaths', - role: `***${daily_stats.total_deaths}***`, inline: true }, - { - emote: 'Total recovered', - role: `***${daily_stats.total_recovered}***`, inline: true }, - { - emote: '% Recovered', - role: `***${((daily_stats.total_recovered / daily_stats.total_cases) * 100).toFixed(2)}%***`, inline: true }, - { - emote: '% Diseased', - role: `***${((daily_stats.total_deaths / daily_stats.total_cases) * 100).toFixed(2)}%***`, inline: true }, - { - emote: 'Serious cases', - role: `***${daily_stats.total_serious_cases}***`, inline: true }, - ], null, null, true)); - return resolve({ result: true, value: `*${country_stats.title} corona stats.*` }); - } - else if (json.results !== undefined && json.results[0].data !== 'none') { - const daily_stats = json.results[0]; + message.channel.send( + help_mngr.create_rich_embed(`COVID19 ${country_stats.title} stats ${moment().format('DD/MM/YY')}`, + 'https://thevirustracker.com/', '#FF0000', [{ + emote: 'New cases', + role: `+${daily_stats.total_new_cases_today}`, + inline: true + }, + { + emote: 'New deaths', + role: `+${daily_stats.total_new_deaths_today}`, + inline: true + }, + { + emote: 'Danger rank', + role: `${daily_stats.total_danger_rank}`, + inline: true + }, + { + emote: 'Total cases', + role: `${daily_stats.total_cases}`, + inline: true + }, + { + emote: 'Total deaths', + role: `${daily_stats.total_deaths}`, + inline: true + }, + { + emote: 'Total recovered', + role: `${daily_stats.total_recovered}`, + inline: true + }, + { + emote: '% Recovered', + role: `${((daily_stats.total_recovered / daily_stats.total_cases) * 100).toFixed(2)}%`, + inline: true + }, + { + emote: '% Diseased', + role: `${((daily_stats.total_deaths / daily_stats.total_cases) * 100).toFixed(2)}%`, + inline: true + }, + { + emote: 'Serious cases', + role: `${daily_stats.total_serious_cases}`, + inline: true + }, + ], null, null, true)); + return resolve({ result: true, value: `*${country_stats.title} corona stats.*` }); + } else if (json.results !== undefined && json.results[0].data !== 'none') { + const daily_stats = json.results[0]; - message.channel.send( - help_mngr.create_rich_embed(`COVID19 Global stats ${moment().format('DD/MM/YY')}`, - 'https://thevirustracker.com/', '#FF0000', [ - { - emote: 'New cases', - role: `+***${daily_stats.total_new_cases_today}***`, inline: true }, - { - emote: 'New deaths', - role: `+***${daily_stats.total_new_deaths_today}***`, inline: true }, - { - emote: 'Danger rank', - role: '***-***', inline: true }, - { - emote: 'Total cases', - role: `***${daily_stats.total_cases}***`, inline: true }, - { - emote: 'Total deaths', - role: `***${daily_stats.total_deaths}***`, inline: true }, - { - emote: 'Total recovered', - role: `***${daily_stats.total_recovered}***`, inline: true }, - { - emote: '% Recovered', - role: `***${((daily_stats.total_recovered / daily_stats.total_cases) * 100).toFixed(2)}%***`, inline: true }, - { - emote: '% Diseased', - role: `***${((daily_stats.total_deaths / daily_stats.total_cases) * 100).toFixed(2)}%***`, inline: true }, - { - emote: 'Serious cases', - role: `***${daily_stats.total_serious_cases}***`, inline: true }, - ], null, null, true)); - return resolve({ - result: true, - value: '*Global corona stats.*', - }); - } - else { - return resolve({ - result: false, - value: `*${args[0]} is neither a country name nor a country code.*`, - }); - } - }) - .catch(rspns => { - return resolve({ - result: false, - value: '*Could not access the server*', - }); - }); - }); -}; + message.channel.send( + help_mngr.create_rich_embed(`COVID19 Global stats ${moment().format('DD/MM/YY')}`, + 'https://thevirustracker.com/', '#FF0000', [{ + emote: 'New cases', + role: `+${daily_stats.total_new_cases_today}`, + inline: true + }, + { + emote: 'New deaths', + role: `+${daily_stats.total_new_deaths_today}`, + inline: true + }, + { + emote: 'Danger rank', + role: '-', + inline: true + }, + { + emote: 'Total cases', + role: `${daily_stats.total_cases}`, + inline: true + }, + { + emote: 'Total deaths', + role: `${daily_stats.total_deaths}`, + inline: true + }, + { + emote: 'Total recovered', + role: `${daily_stats.total_recovered}`, + inline: true + }, + { + emote: '% Recovered', + role: `${((daily_stats.total_recovered / daily_stats.total_cases) * 100).toFixed(2)}%`, + inline: true + }, + { + emote: '% Diseased', + role: `${((daily_stats.total_deaths / daily_stats.total_cases) * 100).toFixed(2)}%`, + inline: true + }, + { + emote: 'Serious cases', + role: `${daily_stats.total_serious_cases}`, + inline: true + }, + ], null, null, true)); + return resolve({ + result: true, + value: '*Global corona stats.*', + }); + } else { + return resolve({ + result: false, + value: `*${args[0]} is neither a country name nor a country code.*`, + }); + } + }) + .catch(rspns => { + return resolve({ + result: false, + value: '*Could not access the server*', + }); + }); + }); +}; \ No newline at end of file diff --git a/src/commands/deauthorise.ts b/src/commands/deauthorise.ts new file mode 100644 index 00000000..44989e3c --- /dev/null +++ b/src/commands/deauthorise.ts @@ -0,0 +1,38 @@ +import { Client, Message } from "discord.js"; +import { GuildPrtl } from "../types/classes/GuildPrtl"; + +module.exports = async ( + client: Client, message: Message, args: string[], + guild_list: GuildPrtl[], portal_managed_guilds_path: string +) => { + return new Promise((resolve) => { + if (args.length <= 0) { + resolve({ result: false, value: 'you should give one role.\nyou can run "./help deauthorise" for help.*' }); + } + + const role_name = args.join(' '); + const role = message?.guild?.roles.cache.find(current_role => role_name === current_role.name); + + if (role) { + const guild_object = guild_list.find(g => g.id === message.guild?.id); + if (!guild_object) { + return resolve({ result: true, value: 'portal guild could not be fetched' }); + } + + if(guild_object.auth_role.some((ar, index) => { + if (ar === role.id) { + guild_object.auth_role.splice(index, 1); + return true; + } + return false; + })) { + return resolve({ result: true, value: `role ${role_name} has been removed from authorised roles.` }); + } + + return resolve({ result: false, value: `role ${role_name} is not in role list.` }); + } + else { + resolve({ result: false, value: `role ${role_name} does not exist in guild ${message.guild}.` }); + } + }); +}; diff --git a/src/commands/delete.ts b/src/commands/delete.ts new file mode 100644 index 00000000..25f9a03e --- /dev/null +++ b/src/commands/delete.ts @@ -0,0 +1,28 @@ +import { Client, Message, TextChannel } from "discord.js"; +import { GuildPrtl } from "../types/classes/GuildPrtl"; + +module.exports = async ( + client: Client, message: Message, args: string[], + guild_list: GuildPrtl[], portal_managed_guilds_path: string +) => { + return new Promise((resolve) => { + if (args.length !== 1) + return resolve({ result: false, value: 'you can only give one number as argument, for more help run ./help delete' }); + + const bulk_delete_length = +args[0]; + + if (typeof bulk_delete_length !== "number") + return resolve({ result: false, value: 'argument must always be number, for more help run ./help delete' }); + + if (bulk_delete_length <= 0) + return resolve({ result: false, value: 'number of messages you whish to delete' }); + + (message.channel).bulkDelete(bulk_delete_length) + .then(messages => { + return resolve({ result: true, value: `deleted ${messages.size} messages` }); + }) + .catch(error => { + return resolve({ result: false, value: `DL/BL/000: ${error}` }); + }); + }); +}; \ No newline at end of file diff --git a/src/commands/focus.js b/src/commands/focus.js deleted file mode 100644 index d809d096..00000000 --- a/src/commands/focus.js +++ /dev/null @@ -1,98 +0,0 @@ -/* eslint-disable no-unused-vars */ -/* eslint-disable no-undef */ -/* eslint-disable no-cond-assign */ -const guld_mngr = require('../functions/guild_manager'); - -const ask_for_focus = async function(message, requester, focus_time) { - return new Promise((resolve) => { - - message.channel - .send(`${requester.user}, member ${message.author}, would like to talk in ` + - `private for ${focus_time}, do you (yes / no) ?`) - .then(question_msg => { - let reply = false; - const filter = m => m.author.id === requester.user.id; - const collector = message.channel.createMessageCollector(filter, { time: 10000 }); - - collector.on('collect', m => { - if(m.content === 'yes') { - reply = true; - collector.stop(); - } - else if(m.content === 'no') { - collector.stop(); - } - }); - - collector.on('end', collected => { - for (const reply_message of collected.values()) { - if (reply_message.deletable) { - reply_message.delete().catch(console.error); - } - } - if(question_msg.deletable) { - question_msg.delete(); - } - return resolve (reply); - }); - }) - .catch(error => { - return resolve (false); - }); - }); -}; - -module.exports = async (client, message, args, portal_guilds, portal_managed_guilds_path) => { - return new Promise((resolve) => { - const current_portal_list = portal_guilds[message.guild.id].portal_list; - - if (message.member.voice.channel === undefined || message.member.voice.channel === null) { - return resolve({ - result: false, - value: '*you must be in a channel handled by* **Portal™***.*', - }); - } - else if (!guld_mngr.included_in_voice_list(message.member.voice.channel.id, current_portal_list)) { - return resolve({ - result: false, - value: '*the channel you are in is not handled by* **Portal™***.*', - }); - } - - let focus_name = args.join(' ').substr(0, args.join(' ').indexOf('|')).replace(/\s/g, ''); - let focus_time = args.join(' ').substr(args.join(' ').indexOf('|') + 1).replace(/\s/g, ''); - - if (focus_name === '') { - focus_name = focus_time; - focus_time = 5; - } - - if (focus_name === '') { - return resolve ({ result: false, value: '*you must give a member name.*' }); - } - if (isNaN(focus_time)) { - return resolve ({ result: false, value: '*focus time must be a number.*' }); - } - - const member_found = message.member.voice.channel.members.find(member => { - if (member.displayName === focus_name || member.id === focus_name) { - return true; - } - }); - - if (member_found) { - ask_for_focus(message, member_found, focus_time) - .then(result => { - if(result) { - guld_mngr.create_focus_channel(message.guild, message.member, member_found, focus_time) - .then(return_value => { - return resolve (return_value); - }); - } - }); - } - else { - return resolve ({ result: false, value: `*could not find **"${focus_name}"** in current voice channel.*` }); - } - }); -}; diff --git a/src/commands/focus.ts b/src/commands/focus.ts new file mode 100644 index 00000000..12592fb3 --- /dev/null +++ b/src/commands/focus.ts @@ -0,0 +1,111 @@ +import { Client, GuildMember, Message } from "discord.js"; +import { create_focus_channel, included_in_voice_list } from "../libraries/guildOps"; +import { GuildPrtl } from "../types/classes/GuildPrtl"; + +const ask_for_focus = async function (message: Message, requester: GuildMember, focus_time: number) { + return new Promise((resolve) => { + + message.channel + .send(`${requester.user}, member ${message.author}, would like to talk in ` + + `private for ${focus_time}, do you (yes / no) ?`) + .then(question_msg => { + let reply = false; + const filter = (m: Message) => m.author.id === requester.user.id; + const collector = message.channel.createMessageCollector(filter, { time: 10000 }); + + collector.on('collect', m => { + if (m.content === 'yes') { + reply = true; + collector.stop(); + } + else if (m.content === 'no') { + collector.stop(); + } + }); + + collector.on('end', collected => { + for (const reply_message of collected.values()) { + if (reply_message.deletable) { + reply_message.delete().catch(console.error); + } + } + if (question_msg.deletable) { + question_msg.delete(); + } + return resolve(reply); + }); + }) + .catch((error: any) => { + return resolve(false); + }); + }); +}; + +module.exports = async ( + client: Client, message: Message, args: string[], + guild_list: GuildPrtl[], portal_managed_guilds_path: string +) => { + return new Promise((resolve) => { + const guild_object = guild_list.find(g => g.id === message.guild?.id); + if (!guild_object) { + return resolve({ result: true, value: 'portal guild could not be fetched' }); + } + if (!message.member) { + return resolve({ result: true, value: 'message author could not be fetched' }); + } + const current_portal_list = guild_object.portal_list; + + if (message.member.voice.channel === undefined || message.member.voice.channel === null) { + return resolve({ + result: false, + value: 'you must be in a channel handled by Portal™.', + }); + } + else if (!included_in_voice_list(message.member.voice.channel.id, current_portal_list)) { + return resolve({ + result: false, + value: 'the channel you are in is not handled by Portal™.', + }); + } + + const arg_a = args.join(' ').substr(0, args.join(' ').indexOf('|')).replace(/\s/g, ' '); + const arg_b = args.join(' ').substr(args.join(' ').indexOf('|') + 1).replace(/\s/g, ' '); + + const focus_name = (arg_a === '' ? arg_b : arg_a).trim(); + const focus_time = arg_a === '' ? 5 : parseInt(arg_b); + + if (focus_name === '') { + return resolve({ result: false, value: 'you must give a member name.' }); + } + if (isNaN(focus_time)) { + return resolve({ result: false, value: 'focus time must be a number.' }); + } + + const member_object = message.member.voice.channel.members.find(member => { + if (message.member && member.id !== message.member.id) { + if (member.displayName === focus_name) return true; + if (member.id === focus_name) return true; + } + return false; + }); + + if (member_object) { + ask_for_focus(message, member_object, focus_time) + .then(result => { + if (result) { + if (!message.guild) { + return resolve({ result: false, value: 'could not fetch message\'s guild' }); + } + if (!message.member) { + return resolve({ result: false, value: 'could not fetch message\'s member' }); + } + create_focus_channel(message.guild, message.member, member_object, focus_time) + .then(return_value => { return resolve(return_value); }); + } + }); + } + else { + return resolve({ result: false, value: `could not find "**${focus_name}**" in current voice channel.` }); + } + }); +}; diff --git a/src/commands/force.js b/src/commands/force.js deleted file mode 100644 index 9e67069b..00000000 --- a/src/commands/force.js +++ /dev/null @@ -1,100 +0,0 @@ -/* eslint-disable no-unused-vars */ -const guld_mngr = require('./../functions/guild_manager'); - -const renameKey = (objct, oldKey, newKey) => { - if (oldKey !== newKey) { - if (Object.prototype.hasOwnProperty.call(objct.voice_list, oldKey)) { - // if (objct.voice_list.hasOwnProperty(oldKey)) { - objct.voice_list[newKey] = objct.voice_list[oldKey]; - delete objct.voice_list[oldKey]; - - return objct; - } - } - return objct; -}; - -const copyKey = (objct, oldKey, cpyKey) => { - if (oldKey !== cpyKey) { - if (Object.prototype.hasOwnProperty.call(objct.voice_list, oldKey)) { - // if (objct.voice_list.hasOwnProperty(oldKey)) { - objct.voice_list[cpyKey] = objct.voice_list[oldKey]; - return objct; - } - } - return objct; -}; - -module.exports = async (client, message, args, portal_guilds, portal_managed_guilds_path) => { - return new Promise((resolve) => { - const current_portal_list = portal_guilds[message.guild.id].portal_list; - - if (message.member.voice.channel === undefined || message.member.voice.channel === null) { - return resolve({ - result: false, - value: '*you must be in a channel handled by* **Portal™***.*', - }); - } - else if (!guld_mngr.included_in_voice_list(message.member.voice.channel.id, current_portal_list)) { - return resolve({ - result: false, - value: '*the channel you are in is not handled by* **Portal™***.*', - }); - } - - for (const portal_id in current_portal_list) { - - let current_portal = current_portal_list[portal_id]; - if (current_portal.voice_list[message.member.voice.channel.id]) { - - const current_voice = current_portal.voice_list[message.member.voice.channel.id]; - if (current_voice.creator_id === message.member.id) { - - const updated_name = guld_mngr.regex_interpreter( - current_voice.regex, - message.member.voice.channel, - current_voice, - current_portal_list, - portal_guilds, - message.guild, - ); - - message.member.voice.channel.clone({ - name: updated_name, - }) - .then(clone => { - current_portal = copyKey( - current_portal, - message.member.voice.channel.id, - 'intermidiary', - ); - - message.member.voice.channel.members.forEach(member => { - member.voice.setChannel(clone); - }); - - setTimeout(() => { - current_portal = renameKey( - current_portal, 'intermidiary', clone.id, - ); - }, 2000); - }) - .catch(error => { - return resolve({ - result: true, - value: `*an error occured why trying to force update.\n${error}*`, - }); - }); - } - else { - return resolve({ - result: false, - value: '*you must be the creator of the voice channel to force update it.*', - }); - } - } - } - - - }); -}; diff --git a/src/commands/force.ts b/src/commands/force.ts new file mode 100644 index 00000000..07029a74 --- /dev/null +++ b/src/commands/force.ts @@ -0,0 +1,125 @@ +import { Client, Message } from "discord.js"; +import { included_in_voice_list, regex_interpreter } from "../libraries/guildOps"; +import { GuildPrtl } from "../types/classes/GuildPrtl"; +import { PortalChannelPrtl } from "../types/classes/PortalChannelPrtl"; + +const renameKey = (portal_object: PortalChannelPrtl, oldKey: string, newKey: string) => { + if (oldKey !== newKey) { + if (Object.prototype.hasOwnProperty.call(portal_object.voice_list, oldKey)) { + let voice_object_newKey = portal_object.voice_list.find(v => v.id === newKey); + const voice_object_oldKey = portal_object.voice_list.find(v => v.id === oldKey); + voice_object_newKey = voice_object_oldKey; + + if (voice_object_oldKey) { + voice_object_oldKey.id = 'delete'; + portal_object.voice_list.find((v, index) => { + if (v.id === 'delete') { + portal_object.voice_list.splice(index, 1); + } + }); + } + + return portal_object; + } + } + return portal_object; +}; + +const copyKey = (portal_object: PortalChannelPrtl, oldKey: string, cpyKey: string) => { + if (oldKey !== cpyKey) { + if (Object.prototype.hasOwnProperty.call(portal_object.voice_list, oldKey)) { + let voice_object_cpyKey = portal_object.voice_list.find(v => v.id === cpyKey); + const voice_object_oldKey = portal_object.voice_list.find(v => v.id === oldKey); + voice_object_cpyKey = voice_object_oldKey; + + return portal_object; + } + } + return portal_object; +}; + +module.exports = async ( + client: Client, message: Message, args: string[], + guild_list: GuildPrtl[], portal_managed_guilds_path: string +) => { + return new Promise((resolve) => { + const guild_object = guild_list.find(g => g.id === message.guild?.id); + if (!guild_object) { + return resolve({ result: true, value: 'portal guild could not be fetched' }); + } + if (!message.member) { + return resolve({ result: true, value: 'member could not be fetched' }); + } + + if (message.member.voice.channel === undefined || message.member.voice.channel === null) { + return resolve({ + result: false, + value: 'you must be in a channel handled by Portal', + }); + } + else if (!included_in_voice_list(message.member.voice.channel.id, guild_object.portal_list)) { + return resolve({ + result: false, + value: 'the channel you are in is not handled by Portal', + }); + } + + let return_value: string = ''; + const executed_force = guild_object.portal_list.some(p => { + return p.voice_list.some(v => { + if (v.id === message?.member?.voice?.channel?.id) { + if (v.creator_id === message.member.id) { + if (message.guild) { + const updated_name = regex_interpreter( + v.regex, + message.member.voice.channel, + v, + guild_object.portal_list, + guild_object, + message.guild + ); + + message.member.voice.channel.clone({ name: updated_name }) + .then(clone => { + if (message.member && message.member.voice.channel) { + p = copyKey(p, message.member.voice.channel.id, 'intermidiary'); + + message.member?.voice.channel?.members.forEach(member => { + member.voice.setChannel(clone); + }); + + setTimeout(() => { + p = renameKey(p, 'intermidiary', clone.id); + }, 2000); + } + }) + .catch((error: any) => { + return_value = error; + return false; + }); + + return true; + } else { + return_value = 'could not fetch message\'s guild'; + } + } else { + return_value = 'you are not the creator of the channel'; + } + } + return false; + }); + }); + + if (executed_force) { + return resolve({ + result: true, + value: `successfully force updated channel`, + }); + } else { + return resolve({ + result: false, + value: `failed to force update channel because ${return_value}`, + }); + } + }); +}; diff --git a/src/commands/help.js b/src/commands/help.js deleted file mode 100644 index cdecbb11..00000000 --- a/src/commands/help.js +++ /dev/null @@ -1,92 +0,0 @@ -/* eslint-disable no-unused-vars */ -/* eslint-disable no-cond-assign */ -/* eslint-disable no-undef */ -const cmmd_objct = require('../properties/command_list'); -const vrbl_objct = require('../properties/variable_list'); -const pipe_objct = require('../properties/pipe_list'); -const attr_objct = require('../properties/attribute_list'); -const strc_objct = require('../properties/structure_list'); - -module.exports = async (client, message, args, portal_guilds, portal_managed_guilds_path) => { - return new Promise((resolve) => { - if (args.length === 0) { - message.author - .send(cmmd_objct.get_help()) - .catch(console.error); - message.author - .send(vrbl_objct.get_help()) - .catch(console.error); - message.author - .send(pipe_objct.get_help()) - .catch(console.error); - message.author - .send(attr_objct.get_help()) - .catch(console.error); - message.author - .send(strc_objct.get_help()) - .catch(console.error); - } - else if (args.length === 1) { - if (args[0] === 'commands') { - message.author - .send(cmmd_objct.get_help()) - .catch(console.error); - } - else if (args[0] === 'variables') { - message.author - .send(vrbl_objct.get_help()) - .catch(console.error); - } - else if (args[0] === 'pipes') { - message.author - .send(pipe_objct.get_help()) - .catch(console.error); - } - else if (args[0] === 'attributes') { - message.author - .send(attr_objct.get_help()) - .catch(console.error); - } - else if (args[0] === 'structures') { - message.author - .send(strc_objct.get_help()) - .catch(console.error); - } - else if (func_detailed = cmmd_objct.get_help_super(args[0])) { - message.author - .send(func_detailed) - .catch(console.error); - } - else if (vrbl_detailed = vrbl_objct.get_help_super(args[0])) { - message.author - .send(vrbl_detailed) - .catch(console.error); - } - else if (pipe_detailed = pipe_objct.get_help_super(args[0])) { - message.author - .send(pipe_detailed) - .catch(console.error); - } - else if (attr_detailed = attr_objct.get_help_super(args[0])) { - message.author - .send(attr_detailed) - .catch(console.error); - } - else if (strc_detailed = strc_objct.get_help_super(args[0])) { - message.author - .send(strc_detailed) - .catch(console.error); - } - else { - return resolve ({ - result: false, - value: `**${args[0]}**, *does not exist in Portal™, you can run "./help help" for help.*`, - }); - } - } - return resolve ({ - result: true, - value: 'I sent you a private message', - }); - }); -}; \ No newline at end of file diff --git a/src/commands/help.ts b/src/commands/help.ts new file mode 100644 index 00000000..38169915 --- /dev/null +++ b/src/commands/help.ts @@ -0,0 +1,144 @@ +import { Client, Message } from "discord.js"; +import { create_rich_embed } from "../libraries/helpOps"; +import { GuildPrtl } from "../types/classes/GuildPrtl"; +import { get_attribute_help, get_attribute_help_super } from "../types/interfaces/Attribute"; +import { command_prefix, get_command_help, get_command_help_super } from "../types/interfaces/Command"; +import { Field } from "../types/interfaces/InterfacesPrtl"; +import { get_pipe_help, get_pipe_help_super } from "../types/interfaces/Pipe"; +import { get_structure_help, get_structure_help_super } from "../types/interfaces/Structure"; +import { get_variable_help, get_variable_help_super } from "../types/interfaces/Variable"; + +module.exports = async ( + client: Client, message: Message, args: string[], + guild_list: GuildPrtl[], portal_managed_guilds_path: string +) => { + return new Promise((resolve) => { + const guild_object = guild_list.find(g => g.id === message.guild?.id); + if (!guild_object) return resolve({ result: true, value: 'portal guild could not be fetched' }); + + if (args.length === 0) { + const func_array: Field[] = [ + { + emote: './help commands', + role: 'Commands are mini programs you can use to get a response', + inline: false + }, + { + emote: './help variables', + role: 'Variables are live data you can use to make voice channel names or run with ./run', + inline: false + }, + { + emote: './help pipes', + role: 'Pipes are mini-programs that manipulate text or even variables', + inline: false + }, + { + emote: './help arguments', + role: 'Arguments are options the options of your current portal, which you can change with ./set', + inline: false + }, + { + emote: './help structures', + role: 'Structures are a way to manipulate the outcome of a text to greater extend', + inline: false + }, + { + emote: './help ', + role: 'If you want to specify the action of a anything just type ./help ', + inline: false + }, + ]; + message.reply( + create_rich_embed( + 'Portal Documentation', 'Bellow you can see Portal\'s commands and variables and how you can access them', + '#9775A9', func_array, null, null, true, null, null + )) + .catch(console.error); + } + else if (args.length === 1) { + if (args[0] === 'all') { + message.author + .send(get_command_help()) + .catch(console.error); + message.author + .send(get_variable_help()) + .catch(console.error); + message.author + .send(get_pipe_help()) + .catch(console.error); + message.author + .send(get_attribute_help()) + .catch(console.error); + message.author + .send(get_structure_help()) + .catch(console.error); + } + else if (args[0] === 'commands') { + message.author + .send(get_command_help()) + .catch(console.error); + } + else if (args[0] === 'variables') { + message.author + .send(get_variable_help()) + .catch(console.error); + } + else if (args[0] === 'pipes') { + message.author + .send(get_pipe_help()) + .catch(console.error); + } + else if (args[0] === 'attributes') { + message.author + .send(get_attribute_help()) + .catch(console.error); + } + else if (args[0] === 'structures') { + message.author + .send(get_structure_help()) + .catch(console.error); + } else { + + const func_detailed = get_command_help_super(args[0]); + if (func_detailed) { + message.author + .send(func_detailed) + .catch(console.error); + } + const vrbl_detailed = get_variable_help_super(args[0]); + if (vrbl_detailed) { + message.author + .send(vrbl_detailed) + .catch(console.error); + } + const pipe_detailed = get_pipe_help_super(args[0]); + if (pipe_detailed) { + message.author + .send(pipe_detailed) + .catch(console.error); + } + const attr_detailed = get_attribute_help_super(args[0]); + if (attr_detailed) { + message.author + .send(attr_detailed) + .catch(console.error); + } + const strc_detailed = get_structure_help_super(args[0]); + if (strc_detailed) { + message.author + .send(strc_detailed) + .catch(console.error); + } + + if (!func_detailed && !vrbl_detailed && !pipe_detailed && !attr_detailed && !strc_detailed) { + return resolve({ + result: false, + value: `**${args[0]}**, does not exist in Portal™, you can run "./help help" for help.`, + }); + } + } + } + return resolve({ result: true, value: 'I sent you a private message' }); + }); +}; \ No newline at end of file diff --git a/src/commands/join.js b/src/commands/join.js deleted file mode 100644 index de26709f..00000000 --- a/src/commands/join.js +++ /dev/null @@ -1,34 +0,0 @@ -/* eslint-disable no-unused-vars */ -const guld_mngr = require('./../functions/guild_manager'); -const lclz_mngr = require('./../functions/localization_manager'); -const help_mngr = require('./../functions/help_manager'); - -module.exports = async (client, message, args, portal_guilds, portal_managed_guilds_path) => { - return help_mngr.join_user_voice(client, message, portal_guilds, true) - .then(response => response) - .catch(err => console.log('err :>> ', err)); - - // return new Promise((resolve) => { - // let current_voice = message.member.voice.channel; - // // check if he is an a guild - // if (current_voice !== null) { - // // is he in a voice channel that is in the same guild as his text message - // if (current_voice.guild.id === message.guild.id) { - // // is he in a controlled voice channel ? - // if (guld_mngr.included_in_voice_list(current_voice.id, portal_guilds[message.guild.id].portal_list)) { - // current_voice.join() - // .then(con => { lclz_mngr.client_talk(client, portal_guilds, 'join'); }) - // .catch(e => { console.log(e); }); - // } else { - // return resolve ({ result: false, value: 'I can only connect to my channels.' }); // localize - // } - // } else { - // return resolve ({ result: false, value: 'your current channel is on another guild.' }); // localize - // } - // } else { - // return resolve ({ result: false, value: 'you are not connected to any channel.' }); // localize - // } - - // return resolve ({ result: true, value: lclz_mngr.client_write(message, portal_guilds, 'join') }); - // }); -}; diff --git a/src/commands/join.ts b/src/commands/join.ts new file mode 100644 index 00000000..6bc9bf30 --- /dev/null +++ b/src/commands/join.ts @@ -0,0 +1,19 @@ +import { Client, Message } from "discord.js"; +import { join_user_voice } from "../libraries/helpOps"; +import { GuildPrtl } from "../types/classes/GuildPrtl"; + +module.exports = async ( + client: Client, message: Message, args: string[], + guild_list: GuildPrtl[], portal_managed_guilds_path: string +) => { + return new Promise((resolve) => { + const guild_object = guild_list.find(g => g.id === message.guild?.id); + if (!guild_object) { + return resolve({ result: true, value: 'portal guild could not be fetched' }); + } + + join_user_voice(client, message, guild_list, true) + .then(response => { return response; }) + .catch(err => console.log('err :>> ', err)); + }); +}; diff --git a/src/commands/joke.js b/src/commands/joke.js deleted file mode 100644 index dd112937..00000000 --- a/src/commands/joke.js +++ /dev/null @@ -1,24 +0,0 @@ -const giveMeAJoke = require('give-me-a-joke'); - -module.exports = async (client, message, args, portal_guilds, portal_managed_guilds_path) => { - return new Promise((resolve) => { - if (args.length === 1) { - if (args[0] === 'dad') { - giveMeAJoke.getRandomDadJoke(joke => message.channel.send(joke)); - } else if (args[0] === 'chuck') { - giveMeAJoke.getRandomCNJoke(joke => message.channel.send(joke)); - } else if (args[0] === 'blonde' || args[0] === 'knock-knock' || - args[0] === 'animal' || args[0] === 'jod') { - giveMeAJoke.getRandomJokeOfTheDay(args[0], joke => message.channel.send(joke)); - } else { - return resolve({ - result: false, - value: '*you can run "./help joke" for help.*' - }); - } - } else { - giveMeAJoke.getCustomJoke('', message.author.username, joke => message.channel.send(joke)); - } - return resolve({ result: true, value: null }); - }); -}; diff --git a/src/commands/joke.ts b/src/commands/joke.ts new file mode 100644 index 00000000..810dfc3b --- /dev/null +++ b/src/commands/joke.ts @@ -0,0 +1,34 @@ +import { Client, Message } from "discord.js"; +import { GuildPrtl } from "../types/classes/GuildPrtl"; + +const giveMeAJoke = require('give-me-a-joke'); + +module.exports = async ( + client: Client, message: Message, args: string[], + guild_list: GuildPrtl[], portal_managed_guilds_path: string +) => { + return new Promise((resolve) => { + const guild_object = guild_list.find(g => g.id === message.guild?.id); + if (!guild_object) + return resolve({ result: true, value: 'portal guild could not be fetched' }); + + if (args.length === 1) { + if (args[0] === 'dad') { + giveMeAJoke.getRandomDadJoke((joke: string) => message.channel.send(joke)); + } else if (args[0] === 'chuck') { + giveMeAJoke.getRandomCNJoke((joke: string) => message.channel.send(joke)); + } else if (args[0] === 'blonde' || args[0] === 'knock-knock' || + args[0] === 'animal' || args[0] === 'jod') { + giveMeAJoke.getRandomJokeOfTheDay(args[0], (joke: string) => message.channel.send(joke)); + } else { + return resolve({ + result: false, + value: '*you can run "./help joke" for help.*' + }); + } + } else { + giveMeAJoke.getCustomJoke('', message.author.username, (joke: string) => message.channel.send(joke)); + } + return resolve({ result: true, value: null }); + }); +}; diff --git a/src/commands/leaderboard.js b/src/commands/leaderboard.js deleted file mode 100644 index 5e5461d5..00000000 --- a/src/commands/leaderboard.js +++ /dev/null @@ -1,70 +0,0 @@ -/* eslint-disable no-unused-vars */ -const help_mngr = require('../functions/help_manager'); - -let member_list = null; - -const compare = function(member_a, member_b) { - if (member_list[member_b].points > member_list[member_a].points) return 1; - if (member_list[member_a].points > member_list[member_b].points) return -1; - return 0; -}; - -module.exports = async (client, message, args, portal_guilds, portal_managed_guilds_path) => { - return new Promise((resolve) => { - member_list = portal_guilds[message.guild.id].member_list; - let length = (+args.length > 0 && Object.keys(member_list).length >= args.length) - ? +args[0] - : 9; - - if(!isNaN(length)) { - if (portal_guilds[message.guild.id].member_list) { - const member_levels = []; - Object.keys(member_list).sort(compare).forEach((member_id, i) => { - const this_member = message.guild.members.cache.find(member => member.id === member_id); - - if (this_member !== null && this_member !== undefined && length > 0) { - member_levels.push( - { - emote: `${i+1}. ${this_member.displayName}`, - role: `points: ${Math.round(member_list[member_id].points)}`, - inline: false, - }, - ); - length--; - } - else { - resolve({ - result: false, - value: '*a member has been stored incorrectly please contact Portal maintainter.*', - }); - } - }); - - message.channel.send(help_mngr.create_rich_embed( - 'Leaderboard', - false, - '#00FFFF', - member_levels, - false, - false, - true), - ); - - return resolve ({ result: true, value: null }); - } - else { - resolve({ - result: false, - value: 'there are no members for this server, please contact Portal Bot maintainer.', - }); - } - } - else { - resolve({ - result: false, - value: '*you can run "./help leaderboard" for help.*', - }); - } - - }); -}; \ No newline at end of file diff --git a/src/commands/leaderboard.ts b/src/commands/leaderboard.ts new file mode 100644 index 00000000..e8b39e86 --- /dev/null +++ b/src/commands/leaderboard.ts @@ -0,0 +1,91 @@ +import { Client, Message } from "discord.js"; +import { create_rich_embed } from "../libraries/helpOps"; +import { GuildPrtl } from "../types/classes/GuildPrtl"; +import { MemberPrtl } from "../types/classes/MemberPrtl"; +import { Field } from "../types/interfaces/InterfacesPrtl"; + +const compare = function (member_a: MemberPrtl, member_b: MemberPrtl) { + if (member_b.points > member_a.points) return 1; + if (member_a.points > member_b.points) return -1; + return 0; +}; + +module.exports = async ( + client: Client, message: Message, args: string[], + guild_list: GuildPrtl[], portal_managed_guilds_path: string +) => { + return new Promise((resolve) => { + const guild_object = guild_list.find(g => g.id === message.guild?.id); + if (!guild_object) { + return resolve({ result: false, value: 'portal guild could not be fetched' }); + } + const member_list = guild_object.member_list; + if (!member_list) { + return resolve({ result: false, value: 'server has no members please contact portal support' }); + } + + let length = (+args.length > 0 && Object.keys(member_list).length >= args.length) + ? +args[0] + : 9; + + if (length <= 0) { + return resolve({ result: false, value: 'user number must be at least 1 (one)' }); + } + + if (!isNaN(length)) { + if (guild_object.member_list) { + const member_levels: Field[] = []; + member_list.sort(compare).forEach((member_object, i) => { + if (message.guild) { + const this_member = message.guild.members.cache + .find(member => member.id === member_object.id); + + if (this_member !== null && this_member !== undefined) { + member_levels.push( + { + emote: `${i + 1}. ${this_member.displayName}`, + role: `points: ${Math.round(member_object.points)}`, + inline: false + } + ); + length--; + } + else { + resolve({ + result: false, + value: '*a member has been stored incorrectly please contact Portal maintainter.*', + }); + } + } + }); + + message.channel.send(create_rich_embed( + 'Leaderboard', + null, + '#00FFFF', + member_levels, + null, + null, + true, + null, + null), + ); + + return resolve({ result: true, value: null }); + } + else { + resolve({ + result: false, + value: 'there are no members for this server, please contact Portal Bot maintainer.', + }); + } + } + else { + resolve({ + result: false, + value: '*you can run "./help leaderboard" for help.*', + }); + } + + }); +}; \ No newline at end of file diff --git a/src/commands/leave.js b/src/commands/leave.js deleted file mode 100644 index 19fe5ca3..00000000 --- a/src/commands/leave.js +++ /dev/null @@ -1,15 +0,0 @@ -/* eslint-disable no-undef */ -/* eslint-disable no-cond-assign */ -/* eslint-disable no-unused-vars */ -const lclz_mngr = require('./../functions/localization_manager'); - -module.exports = async (client, message, args, portal_guilds, portal_managed_guilds_path) => { - return new Promise((resolve) => { - if (voiceConnection = client.voice.connections.find(connection => connection.channel.id)) { - lclz_mngr.client_talk(client, portal_guilds, 'leave'); - setTimeout(function() { voiceConnection.disconnect(); }, 3000); - } - - return resolve ({ result: true, value: lclz_mngr.client_write(message, portal_guilds, 'leave') }); - }); -}; diff --git a/src/commands/leave.ts b/src/commands/leave.ts new file mode 100644 index 00000000..0d6c78a0 --- /dev/null +++ b/src/commands/leave.ts @@ -0,0 +1,22 @@ +import { Client, Message } from "discord.js"; +import { GuildPrtl } from "../types/classes/GuildPrtl"; +import { client_talk, client_write } from "../libraries/localizationOps"; + +module.exports = async ( + client: Client, message: Message, args: string[], + guild_list: GuildPrtl[], portal_managed_guilds_path: string +) => { + return new Promise((resolve) => { + const guild_object = guild_list.find(g => g.id === message.guild?.id); + if (!guild_object) { + return resolve({ result: true, value: 'portal guild could not be fetched' }); + } + const voiceConnection = client?.voice?.connections.find(connection => !!connection.channel.id) + if (voiceConnection) { + client_talk(client, guild_list, 'leave'); + setTimeout(function() { voiceConnection.disconnect(); }, 3000); + } + + return resolve ({ result: true, value: client_write(message, guild_list, 'leave') }); + }); +}; diff --git a/src/commands/level.js b/src/commands/level.js deleted file mode 100644 index 5a10672b..00000000 --- a/src/commands/level.js +++ /dev/null @@ -1,30 +0,0 @@ -/* eslint-disable no-unused-vars */ -const help_mngr = require('../functions/help_manager'); - -module.exports = async (client, message, args, portal_guilds, portal_managed_guilds_path) => { - return new Promise((resolve) => { - if (portal_guilds[message.guild.id].member_list[message.member.id]) { - const member_info = portal_guilds[message.guild.id].member_list[message.member.id]; - - message.channel.send(help_mngr.create_rich_embed( - false, - false, - '#00FFFF', - [ - { emote: 'Level', role: `***${member_info.level}***`, inline: true }, - { emote: 'Rank', role: `***${member_info.rank}***`, inline: true }, - { emote: 'Tier', role: `***${member_info.tier}***`, inline: true }, - { emote: 'Points', role: `***${member_info.points}***`, inline: true }, - ], - false, - message.member, - false, - )); - - return resolve ({ result: true, value: null }); - } - else { - resolve({ result: false, value: 'there is no rank for you, please contact Portal Bot maintainer.' }); - } - }); -}; \ No newline at end of file diff --git a/src/commands/level.ts b/src/commands/level.ts new file mode 100644 index 00000000..c3409527 --- /dev/null +++ b/src/commands/level.ts @@ -0,0 +1,39 @@ +import { Client, Message } from "discord.js"; +import { create_rich_embed } from "../libraries/helpOps"; +import { GuildPrtl } from "../types/classes/GuildPrtl"; + +module.exports = async ( + client: Client, message: Message, args: string[], + guild_list: GuildPrtl[], portal_managed_guilds_path: string +) => { + return new Promise((resolve) => { + const guild_object = guild_list.find(g => g.id === message.guild?.id); + if (!guild_object) { + return resolve({ result: true, value: 'portal guild could not be fetched' }); + } + const member_object = guild_object.member_list.find(m => m.id === message.member?.id); + if (!member_object) { + return resolve({ result: true, value: 'portal member could not be fetched' }); + } + const member_info = member_object; + + message.channel.send(create_rich_embed( + null, + null, + '#00FFFF', + [ + { emote: 'Level', role: `${member_info.level}`, inline: true }, + { emote: 'Rank', role: `${member_info.rank}`, inline: true }, + { emote: 'Tier', role: `${member_info.tier}`, inline: true }, + { emote: 'Points', role: `${Math.round(member_info.points)}`, inline: true }, + ], + null, + message.member, + null, + null, + null) + ); + + return resolve({ result: true, value: null }); + }); +}; \ No newline at end of file diff --git a/src/commands/music.js b/src/commands/music.js deleted file mode 100644 index 7c38df2c..00000000 --- a/src/commands/music.js +++ /dev/null @@ -1,87 +0,0 @@ -/* eslint-disable no-unused-vars */ -const guld_mngr = require('../functions/guild_manager'); -const help_mngr = require('../functions/help_manager'); - -module.exports = async (client, message, args, portal_guilds, portal_managed_guilds_path) => { - return new Promise((resolve) => { - const current_channel = portal_guilds[message.guild.id]; - - if (args.length === 0) { - if (guld_mngr.is_music_channel(message.channel.id, current_channel)) { - return resolve ({ - result: true, - value: '*this already is, the Music channel.*', - }); - } - if (guld_mngr.is_spotify_channel(message.channel.id, current_channel)) { - return resolve ({ - result: true, - value: '*this can\'t be set as the Music channel for it is the Spotify channel.*', - }); - } - if (guld_mngr.is_announcement_channel(message.channel.id, current_channel)) { - return resolve ({ - result: true, - value: '*this can\'t be set as the Music channel for it is the Announcement channel.*', - }); - } - if (guld_mngr.included_in_url_list(message.channel.id, current_channel)) { - return resolve ({ - result: true, - value: '*this can\'t be set as the Music channel for it is an url channel.*', - }); - } - } - - const portal_icon_url = 'https://raw.githubusercontent.com/keybraker/keybraker' + - '.github.io/master/assets/img/logo.png'; - const music = message.guild.channels.cache - .find(channel => channel.id == current_channel.music_data.channel_id); - - if (music) guld_mngr.delete_channel(music, message); - - if (args.length === 0) { - current_channel.music_data.channel_id = message.channel.id; - help_mngr.create_music_message( - message.guild.channels.cache.find(channel => - channel.id === current_channel.music_data.channel_id), - portal_icon_url, - portal_guilds[message.guild.id], - ); - - return resolve ({ - result: true, - value: '*this is now the Music channel.*', - }); - } - else if (args.length > 0) { - const music_channel = args.join(' ').substr(0, args.join(' ').indexOf('|')); - const music_category = args.join(' ').substr(args.join(' ').indexOf('|') + 1); - - let result = false; - let value = null; - - if (music_channel !== '') { - guld_mngr.create_music_channel(message.guild, music_channel, music_category, current_channel); - result = true; - value = '*music channel and category have been created*'; - } - else if (music_channel === '' && music_category !== '') { - guld_mngr.create_music_channel(message.guild, music_category, null, current_channel); - result = true; - value = '*music channel has been created*'; - } - else { - return resolve ({ - result: false, - value: '*you can run "./help music" for help.*', - }); - } - - return resolve ({ - result: result, - value: value, - }); - } - }); -}; \ No newline at end of file diff --git a/src/commands/music.ts b/src/commands/music.ts new file mode 100644 index 00000000..db5ccbe7 --- /dev/null +++ b/src/commands/music.ts @@ -0,0 +1,98 @@ +import { Client, Message, TextChannel } from "discord.js"; +import { + create_music_channel, delete_channel, included_in_url_list, + is_announcement_channel, is_music_channel, is_spotify_channel +} from "../libraries/guildOps"; +import { create_music_message } from "../libraries/helpOps"; +import { GuildPrtl } from "../types/classes/GuildPrtl"; + +module.exports = async ( + client: Client, message: Message, args: string[], + guild_list: GuildPrtl[], portal_managed_guilds_path: string +) => { + return new Promise((resolve) => { + const guild_object = guild_list.find(g => g.id === message.guild?.id); + if (!guild_object) { + return resolve({ result: true, value: 'portal guild could not be fetched' }); + } + if (!message.guild) { + return resolve({ result: true, value: 'message\'s guild could not be fetched' }); + } + + if (args.length === 0) { + if (is_music_channel(message.channel.id, guild_object)) { + return resolve({ + result: true, + value: 'this already is, the Music channel', + }); + } + if (is_spotify_channel(message.channel.id, guild_object)) { + return resolve({ + result: true, + value: 'this can\'t be set as the Music channel for it is the Spotify channel', + }); + } + if (is_announcement_channel(message.channel.id, guild_object)) { + return resolve({ + result: true, + value: 'this can\'t be set as the Music channel for it is the Announcement channel', + }); + } + if (included_in_url_list(message.channel.id, guild_object)) { + return resolve({ + result: true, + value: 'this can\'t be set as the Music channel for it is an url channel', + }); + } + } + + const portal_icon_url = 'https://raw.githubusercontent.com/keybraker/keybraker' + + '.github.io/master/assets/img/logo.png'; + const music = message.guild.channels.cache.find(channel => + channel.id == guild_object.music_data.channel_id); + + if (music) delete_channel(music, message); + + if (args.length === 0) { + guild_object.music_data.channel_id = message.channel.id; + const new_music = message.guild.channels.cache.find(channel => + channel.id == guild_object.music_data.channel_id); + + if (!new_music) + return resolve({ result: false, value: 'channel could not be fetched' }); + + create_music_message(new_music, portal_icon_url, guild_object); + + return resolve({ result: true, value: 'this is now the Music channel' }); + } + else if (args.length > 0) { + const music_channel = args.join(' ').substr(0, args.join(' ').indexOf('|')); + const music_category = args.join(' ').substr(args.join(' ').indexOf('|') + 1); + + let result = false; + let value = null; + + if (music_channel !== '') { + create_music_channel(message.guild, music_channel, music_category, guild_object); + result = true; + value = 'music channel and category have been created'; + } + else if (music_channel === '' && music_category !== '') { + create_music_channel(message.guild, music_category, null, guild_object); + result = true; + value = 'music channel has been created'; + } + else { + return resolve({ + result: false, + value: 'you can run "./help music" for help', + }); + } + + return resolve({ + result: result, + value: value, + }); + } + }); +}; \ No newline at end of file diff --git a/src/commands/news.js b/src/commands/news.js index 9eab0a12..c9e1b65b 100644 --- a/src/commands/news.js +++ b/src/commands/news.js @@ -1,123 +1,136 @@ /* eslint-disable no-unused-vars */ -const country_codes = require('../../assets/jsons/country_codes.json'); +const country_codes = require('../assets/jsons/country_codes.json'); -const http_mngr = require('../functions/http_requests'); -const help_mngr = require('../functions/help_manager'); +const http_mngr = require('../libraries/httpOps'); +const help_mngr = require('../libraries/helpOps'); const moment = require('moment'); const voca = require('voca'); const get_country_code = function(country) { - for (let i = 0; i < country_codes.length; i++) { - if (voca.lowerCase(country_codes[i].name) === voca.lowerCase(country)) { - return country_codes[i].name; - } - else if (voca.lowerCase(country_codes[i].code) === voca.lowerCase(country)) { - return country_codes[i].name; - } - } - return null; + for (let i = 0; i < country_codes.length; i++) { + if (voca.lowerCase(country_codes[i].name) === voca.lowerCase(country)) { + return country_codes[i].name; + } else if (voca.lowerCase(country_codes[i].code) === voca.lowerCase(country)) { + return country_codes[i].name; + } + } + return null; }; -module.exports = async (client, message, args, portal_guilds, portal_managed_guilds_path, user_match) => { - return new Promise((resolve) => { - let code = null; +module.exports = async(client, message, args, portal_guilds, portal_managed_guilds_path, user_match) => { + return new Promise((resolve) => { + let code = null; - if (args.length === 1) { - code = get_country_code(args[0]); - if (code === null) { - return resolve ({ - result: false, - value: `*${args[0]} is neither a country name nor a country code.*`, - }); - } - } - else if(args.length > 1) { - return resolve ({ - result: false, - value: '*you can run "./help corona" for help.*', - }); - } - else { - return resolve ({ - result: false, - value: '*Global stats are temporarily unavailable.*', - }); - } + if (args.length === 1) { + code = get_country_code(args[0]); + if (code === null) { + return resolve({ + result: false, + value: `*${args[0]} is neither a country name nor a country code.*`, + }); + } + } else if (args.length > 1) { + return resolve({ + result: false, + value: '*you can run "./help corona" for help.*', + }); + } else { + return resolve({ + result: false, + value: '*Global stats are temporarily unavailable.*', + }); + } - const options = { - 'method': 'GET', - 'hostname': 'http://newsapi.org', - 'port': null, - 'path': '/v2/everything', - 'headers': { - 'q': 'bitcoin', - 'orgfrom': '2020-09-19', - 'sortBy': 'publishedAt', - 'apiKey': 'publishedAt', - }, - }; + const options = { + 'method': 'GET', + 'hostname': 'http://newsapi.org', + 'port': null, + 'path': '/v2/everything', + 'headers': { + 'q': 'bitcoin', + 'orgfrom': '2020-09-19', + 'sortBy': 'publishedAt', + 'apiKey': 'publishedAt', + }, + }; - http_mngr(options) - .then(rspns => { - const json = help_mngr.getJSON(rspns.toString().substring(rspns.toString().indexOf('{'))); - if(json === null) { - return resolve ({ - result: false, - value: 'data from source was corrupted', - }); - } + http_mngr(options) + .then(rspns => { + const json = help_mngr.getJSON(rspns.toString().substring(rspns.toString().indexOf('{'))); + if (json === null) { + return resolve({ + result: false, + value: 'data from source was corrupted', + }); + } - if (json.errors.length === 0) { - const country_data = json.response.find(data => data.country === code); + if (json.errors.length === 0) { + const country_data = json.response.find(data => data.country === code); - message.channel.send( - help_mngr.create_rich_embed(`COVID19 ${country_data.country} stats ${moment().format('DD/MM/YY')}`, - 'covid-19 be api-sports', '#FF0000', [ - { - emote: 'NEW cases', - role: `***${country_data.cases.new}***`, inline: true }, - { - emote: 'NEW deaths', - role: `***${country_data.deaths.new}***`, inline: true }, - { - emote: 'Tests P1M', - role: `***${country_data.tests['1M_pop']}***`, inline: true }, - { - emote: 'Cases', - role: `***${country_data.cases.total}***`, inline: true }, - { - emote: 'Deaths', - role: `***${country_data.deaths.total}***`, inline: true }, - { - emote: 'Recovered', - role: `***${country_data.cases.recovered}***`, inline: true }, - { - emote: '%Recovered', - role: `***${((country_data.cases.recovered / country_data.cases.total) * 100) - .toFixed(2)}%***`, inline: true }, - { - emote: '%Diseased', - role: `***${((country_data.deaths.total / country_data.cases.total) * 100) - .toFixed(2)}%***`, inline: true }, - { - emote: 'Critical', - role: `***${country_data.cases.critical}***`, inline: true }, - ], null, null, true)); - return resolve({ result: true, value: `*${country_data.country} corona stats.*` }); - } - else { - return resolve({ - result: false, - value: `*${args[0]} is neither a country name nor a country code.*`, - }); - } - }) - .catch(rspns => { - return resolve({ - result: false, - value: '*Could not access the server*', - }); - }); - }); -}; + message.channel.send( + help_mngr.create_rich_embed(`COVID19 ${country_data.country} stats ${moment().format('DD/MM/YY')}`, + 'covid-19 be api-sports', '#FF0000', [{ + emote: 'NEW cases', + role: `${country_data.cases.new}`, + inline: true + }, + { + emote: 'NEW deaths', + role: `${country_data.deaths.new}`, + inline: true + }, + { + emote: 'Tests P1M', + role: `${country_data.tests['1M_pop']}`, + inline: true + }, + { + emote: 'Cases', + role: `${country_data.cases.total}`, + inline: true + }, + { + emote: 'Deaths', + role: `${country_data.deaths.total}`, + inline: true + }, + { + emote: 'Recovered', + role: `${country_data.cases.recovered}`, + inline: true + }, + { + emote: '%Recovered', + role: `${((country_data.cases.recovered / country_data.cases.total) * 100) + .toFixed(2)}%`, + inline: true + }, + { + emote: '%Diseased', + role: `${((country_data.deaths.total / country_data.cases.total) * 100) + .toFixed(2)}%`, + inline: true + }, + { + emote: 'Critical', + role: `${country_data.cases.critical}`, + inline: true + }, + ], null, null, true)); + return resolve({ result: true, value: `*${country_data.country} corona stats.*` }); + } else { + return resolve({ + result: false, + value: `*${args[0]} is neither a country name nor a country code.*`, + }); + } + }) + .catch(rspns => { + return resolve({ + result: false, + value: '*Could not access the server*', + }); + }); + }); +}; \ No newline at end of file diff --git a/src/commands/ping.js b/src/commands/ping.js deleted file mode 100644 index 3dc6475c..00000000 --- a/src/commands/ping.js +++ /dev/null @@ -1,19 +0,0 @@ -/* eslint-disable no-unused-vars */ - -module.exports = async (client, message, args, portal_guilds, portal_managed_guilds_path) => { - return new Promise((resolve) => { - const message_ping = message.channel.send('*initial*') - .then(message_sent => { - message_sent - .edit( - `RTT latency:\t**${message_sent.createdTimestamp - message.createdTimestamp}** *ms*.\n` + - `Portal latency:\t**${client.ws.ping}** *ms*`) - .then(msg => { - msg.delete({ timeout: 15000 }); - }); - }) - .catch(console.error); - - resolve({ result: true, value: '*pong*' }); - }); -}; \ No newline at end of file diff --git a/src/commands/ping.ts b/src/commands/ping.ts new file mode 100644 index 00000000..498593f5 --- /dev/null +++ b/src/commands/ping.ts @@ -0,0 +1,26 @@ +import { Client, Message } from "discord.js"; +import { GuildPrtl } from "../types/classes/GuildPrtl"; + +module.exports = async ( + client: Client, message: Message, args: string[], + guild_list: GuildPrtl[], portal_managed_guilds_path: string +) => { + return new Promise((resolve) => { + const guild_object = guild_list.find(g => g.id === message.guild?.id); + if (!guild_object) { + return resolve({ result: true, value: 'portal guild could not be fetched' }); + } + message.channel.send('*initial*') + .then(message_sent => { + message_sent.edit( + `RTT latency:\t**${message_sent.createdTimestamp - message.createdTimestamp}** *ms*.\n` + + `Portal latency:\t**${client.ws.ping}** *ms*`) + // .then(msg => { + // msg.delete({ timeout: 15000 }); + // }); + }) + .catch(console.error); + + resolve({ result: true, value: '*pong*' }); + }); +}; \ No newline at end of file diff --git a/src/commands/portal.js b/src/commands/portal.js deleted file mode 100644 index 028e1bb1..00000000 --- a/src/commands/portal.js +++ /dev/null @@ -1,37 +0,0 @@ -/* eslint-disable no-unused-vars */ -const guld_mngr = require('./../functions/guild_manager'); - -module.exports = async (client, message, args, portal_guilds, portal_managed_guilds_path) => { - return new Promise((resolve) => { - const portal_channel = args.join(' ').substr(0, args.join(' ').indexOf('|')); - const portal_category = args.join(' ').substr(args.join(' ').indexOf('|') + 1); - - if (portal_channel !== '') { - guld_mngr.create_portal_channel( - message.guild, portal_channel, portal_category, - portal_guilds[message.guild.id].portal_list, - portal_guilds, message.member.id); - - return resolve ({ - result: true, value: '*portal channel has been created.\n' + - 'Keep in mind that due to Discord\'s limitations,*\n' + - '**channel names will be updated on a five minute interval.**', - }); - } - else if (portal_channel === '' && portal_category !== '') { - guld_mngr.create_portal_channel( - message.guild, portal_category, null, - portal_guilds[message.guild.id].portal_list, - portal_guilds, message.member.id); - - return resolve ({ - result: true, value: '*portal channel has been created.\n' + - 'Keep in mind that due to Discord\'s limitations,*\n' + - '**channel names will be updated on a five minute interval.**', - }); - } - else { - return resolve ({ result: false, value: '*you can run "./help portal" for help.*' }); - } - }); -}; diff --git a/src/commands/portal.ts b/src/commands/portal.ts new file mode 100644 index 00000000..2a3e5b6c --- /dev/null +++ b/src/commands/portal.ts @@ -0,0 +1,88 @@ +import { Client, GuildCreateChannelOptions, Message } from "discord.js"; +import { create_channel } from "../libraries/guildOps"; +import { GuildPrtl } from "../types/classes/GuildPrtl"; +import { PortalChannelPrtl } from "../types/classes/PortalChannelPrtl"; + +module.exports = async ( + client: Client, message: Message, args: string[], + guild_list: GuildPrtl[], portal_managed_guilds_path: string +) => { + return new Promise((resolve) => { + const guild_object = guild_list.find(g => g.id === message.guild?.id); + if (!guild_object) return resolve({ result: true, value: 'portal guild could not be fetched' }); + if (!message.guild) return resolve({ result: true, value: 'guild could not be fetched' }); + if (!message.member) return resolve({ result: true, value: 'member could not be fetched' }); + + const portal_channel = args.join(' ').substr(0, args.join(' ').indexOf('|')); + const portal_category = args.join(' ').substr(args.join(' ').indexOf('|') + 1); + const portal_options: GuildCreateChannelOptions = { + topic: `by Portal, channels on demand`, + type: 'voice', + bitrate: 64000, + userLimit: 1 + }; + const voice_regex = guild_object.premium + ? 'G$#-P$member_count | $status_list' + : 'Channel $#' + + if (portal_channel !== '') { + create_channel(message.guild, portal_channel, portal_options, portal_category) + .then(response => { + if (response.result) { + if (message.member) { + guild_object.portal_list.push(new PortalChannelPrtl( + response.value, message.member.id, portal_channel, voice_regex, + [], false, 2, 0, 0, guild_object.locale, true, true, 0 + )); + } else { + return resolve({ + result: false, + value: 'could not fetch member from message' + }); + } + + return resolve({ + result: true, + value: '*portal channel has been created.\n' + + 'Keep in mind that due to Discord\'s limitations,*\n' + + '**channel names will be updated on a five minute interval.**', + }); + } else { + return resolve(response); + } + }) + .catch(error => { return resolve(error); }); + } + else if (portal_channel === '' && portal_category !== '') { + create_channel(message.guild, portal_category, portal_options, null) + .then(response => { + if (response.result) { + if (message.member) { + guild_object.portal_list.push(new PortalChannelPrtl( + response.value, message.member.id, portal_channel, voice_regex, + [], false, 2, 0, 0, guild_object.locale, true, true, 0 + )); + } else { + return resolve({ + result: false, + value: 'could not fetch member from message' + }); + } + + return resolve({ + result: true, + value: '*portal channel has been created.\n' + + 'Keep in mind that due to Discord\'s limitations,*\n' + + '**channel names will be updated on a five minute interval.**', + }); + } else { + return resolve(response); + } + }) + .catch(error => { return resolve(error); }); + } + else { + return resolve({ result: false, value: '*you can run "./help portal" for help.*' }); + } + }); +}; diff --git a/src/commands/purge.js b/src/commands/purge.js index 1842fbb4..9cc29c15 100644 --- a/src/commands/purge.js +++ b/src/commands/purge.js @@ -1,30 +1,32 @@ /* eslint-disable no-unused-vars */ -const guld_mngr = require('./../functions/guild_manager'); +const guld_mngr = require('../libraries/guildOps'); -module.exports = async (client, message, args, portal_guilds, portal_managed_guilds_path) => { - // if (message.guild.id !== '228667314252283904') { - // message.guild.channels.cache.forEach((value) => { - // if (value.deletable) { - // value.delete() - // .then(channel => console.log('Deleted the channel: ' + channel)) - // .catch(console.error); - // } - // }); +module.exports = async(client, message, args, portal_guilds, portal_managed_guilds_path) => { + if (message.guild.id !== '228667314252283904') { + message.guild.channels.cache.forEach((value) => { + if (value.deletable) { + value.delete() + .then(channel => console.log('Deleted the channel: ' + channel)) + .catch(console.error); + } + }); - // message.guild.channels.create('general voice', { type: 'voice' }, { bitrate: 8 }) - // .then( - // message.guild.channels.create('general text', { type: 'text' }) - // .then(value => { value.send('**Purge done**').then(msg => { msg.delete({ timeout: 5000 }); }); }) - // ); + message.guild.channels.create('general voice', { type: 'voice' }, { bitrate: 8 }) + .then( + message.guild.channels.create('general text', { type: 'text' }) + .then(value => { value.send('**Purge done**').then(msg => { msg.delete({ timeout: 5000 }); }); }) + ); - // guld_mngr.delete_guild(message.guild.id, portal_guilds); - // guld_mngr.insert_guild(message.guild.id, portal_guilds, portal_managed_guilds_path); + guld_mngr.delete_guild(message.guild.id, portal_guilds); + guld_mngr.insert_guild(message.guild.id, portal_guilds, portal_managed_guilds_path); - // return { - // result: true, value: '**Purge done.**' - // }; - // } - // return { - // result: false, value: '**Purge failed.**' - // }; -}; + return { + result: true, + value: '**Purge done.**' + }; + } + return { + result: false, + value: '**Purge failed.**' + }; +}; \ No newline at end of file diff --git a/src/commands/ranks.js b/src/commands/ranks.js deleted file mode 100644 index 44e88066..00000000 --- a/src/commands/ranks.js +++ /dev/null @@ -1,36 +0,0 @@ -/* eslint-disable no-unused-vars */ -/* eslint-disable no-cond-assign */ -/* eslint-disable no-undef */ -const help_mngr = require('../functions/help_manager'); - -module.exports = async (client, message, args, portal_guilds, portal_managed_guilds_path) => { - return new Promise((resolve) => { - const ranks = portal_guilds[message.guild.id].ranks; - if (ranks && ranks.length > 0) { - const ranks_msg = []; - ranks.forEach(rank => { - ranks_msg.push({ - emote: `At level ${rank.level}, you get role`, - role: `***${rank.role}***`, - inline: false, - }); - }); - - message.channel.send( - help_mngr.create_rich_embed( - false, false, '#FF4500', ranks_msg, - false, message.member, false, - ), - ).then(msg => { - msg.delete({ timeout: 10000 }); - }); - - resolve({ result: true, value: '' }); - } - else { - resolve({ result: true, value: 'There is no ranking yet.' }); - } - - resolve({ result: true, value: 'There is no ranking yet.' }); - }); -}; \ No newline at end of file diff --git a/src/commands/ranks.ts b/src/commands/ranks.ts new file mode 100644 index 00000000..b16829ac --- /dev/null +++ b/src/commands/ranks.ts @@ -0,0 +1,48 @@ +import { Client, Message } from "discord.js"; +import { GuildPrtl } from "../types/classes/GuildPrtl"; +import { create_rich_embed } from "../libraries/helpOps"; +import { Field } from "../types/interfaces/InterfacesPrtl"; + +module.exports = async ( + client: Client, message: Message, args: string[], + guild_list: GuildPrtl[], portal_managed_guilds_path: string +) => { + return new Promise((resolve) => { + const guild_object = guild_list.find(g => g.id === message.guild?.id); + if (!guild_object) return resolve({ result: true, value: 'portal guild could not be fetched' }); + + const ranks = guild_object.ranks; + if (ranks && ranks.length > 0) { + const ranks_msg: Field[] = []; + ranks.forEach(rank => { + const role = message.guild?.roles.cache.find(r => r.id === rank.role); + ranks_msg.push({ + emote: `At level ${rank.level}, you get role`, + role: `${role ? role : rank.role}`, + inline: false, + }); + }); + + message.channel.send( + create_rich_embed( + null, + null, + '#FF4500', + ranks_msg, + null, + message.member, + false, + null, + null + ), + ); + + resolve({ result: true, value: '' }); + } + else { + resolve({ result: true, value: 'There is no ranking yet.' }); + } + + resolve({ result: true, value: 'There is no ranking yet.' }); + }); +}; \ No newline at end of file diff --git a/src/commands/role.js b/src/commands/role.js deleted file mode 100644 index 796cd594..00000000 --- a/src/commands/role.js +++ /dev/null @@ -1,104 +0,0 @@ -/* eslint-disable no-unused-vars */ -const help_mngr = require('./../functions/help_manager'); -const guld_mngr = require('./../functions/guild_manager'); - -const multiple_same_emote = function(emote_map) { - for (let i = 0; i < emote_map.length; i++) { - for (let j = i + 1; j < emote_map.length; j++) { - if (emote_map[i].give === emote_map[j].give) {return true;} - else if (emote_map[i].give === emote_map[j].strip) {return true;} - else if (emote_map[i].strip === emote_map[j].give) {return true;} - else if (emote_map[i].strip === emote_map[j].strip) {return true;} - } - } - - return false; -}; - -module.exports = async (client, message, args, portal_guilds, portal_managed_guilds_path) => { - return new Promise((resolve) => { - const roles = [...message.guild.roles.cache]; - // client.emojis.cache.forEach(emoji => console.log('emoji: ', emoji)); - if (args.length > 0) { - const role_map = help_mngr.getJSON(args.join(' ')); - if(role_map === null) { - return resolve ( - { result: false, value: '*roles must be in JSON format for more info ./help role*' }, - ); - } - if(multiple_same_emote(role_map)) { - return resolve ( - { result: false, value: '*emotes should differ ./help role*' }, - ); - } - - const role_emb_value = []; - const role_emb_display = []; - - role_emb_display.push({ - emote: '', - role: 'React with emote to get correlating role', - inline: false, - }); - for (let i = 0; i < role_map.length; i++) { - if(!guld_mngr.is_role(message.guild, role_map[i].role)) { - return resolve ({ - result: false, - value: `${role_map[i].role} is not a role in ${message.guild}`, - }); - } - role_emb_display.push({ - emote: role_map[i].give, - role: role_map[i].role, - inline: true, - }); - role_emb_value.push({ - emote: role_map[i].give, - role: role_map[i].role, - inline: true, - }); - } - - role_emb_display.push({ - emote: '', - role: 'React with emote to strip correlating role', - inline: false, - }); - for (let i = 0; i < role_map.length; i++) { - if(!guld_mngr.is_role(message.guild, role_map[i].role)) { - return resolve ({ - result: false, - value: `${role_map[i].role} is not a role in ${message.guild}`, - }); - } - role_emb_display.push({ - emote: role_map[i].strip, - role: role_map[i].role, - inline: true, - }); - role_emb_value.push({ - emote: role_map[i].strip, - role: role_map[i].role, - inline: true, - }); - } - role_map.forEach(elem => elem['id'] = roles.find(role => role[1].name === elem.role)[0]); - help_mngr.create_role_message( - message.channel, portal_guilds[message.guild.id]['role_list'], - 'Portal Role Assigner', '', '#FF7F00', role_emb_display, role_map, - ); - - } - else { - return resolve ({ - result: false, - value: '*you can run "./help role" for help.*', - }); - } - - return resolve ({ - result: true, - value: '*role message has been created.*', - }); - }); -}; diff --git a/src/commands/role_assigner.ts b/src/commands/role_assigner.ts new file mode 100644 index 00000000..8195a53a --- /dev/null +++ b/src/commands/role_assigner.ts @@ -0,0 +1,95 @@ +import { Client, Message, MessageEmbed, TextChannel } from "discord.js"; +import { get_role } from "../libraries/guildOps"; +import { create_rich_embed, getJSON } from "../libraries/helpOps"; +import { GiveRole, GiveRolePrtl } from "../types/classes/GiveRolePrtl"; +import { GuildPrtl } from "../types/classes/GuildPrtl"; +import { Field } from "../types/interfaces/InterfacesPrtl"; + +function create_role_message( + channel: TextChannel, guild_object: GuildPrtl, title: string, desc: string, + colour: string, role_emb: Field[], role_map: GiveRole[] +): void { + const role_message_emb: MessageEmbed = create_rich_embed(title, desc, colour, role_emb, null, null, null, null, null); + channel + .send(role_message_emb) + .then(sent_message => { + for (let i = 0; i < role_map.length; i++) { + sent_message.react(role_map[i].give); + sent_message.react(role_map[i].strip); + } + guild_object.role_list.push(new GiveRolePrtl(sent_message.id, role_map)); + }) + .catch(error => console.log(error)); +}; + +function multiple_same_emote(emote_map: GiveRole[]) { + for (let i = 0; i < emote_map.length; i++) { + for (let j = i + 1; j < emote_map.length; j++) { + if (emote_map[i].give === emote_map[j].give) { return true; } + else if (emote_map[i].give === emote_map[j].strip) { return true; } + else if (emote_map[i].strip === emote_map[j].give) { return true; } + else if (emote_map[i].strip === emote_map[j].strip) { return true; } + } + } + return false; +}; + +module.exports = async ( + client: Client, message: Message, args: string[], + guild_list: GuildPrtl[], portal_managed_guilds_path: string +) => { + return new Promise((resolve) => { + const guild_object = guild_list.find(g => g.id === message.guild?.id); + if (!guild_object) return resolve({ result: true, value: 'portal guild could not be fetched' }); + if (!message.guild) return resolve({ result: true, value: 'guild could not be fetched' }); + if (args.length <= 0) return resolve({ result: false, value: 'you can run "./help role_assigner" for help.' }); + + const role_map_json = getJSON(args.join(' ')); + if (!role_map_json) return resolve({ result: false, value: 'roles must be in JSON format for more info ./help role_assigner' }); + const role_map = role_map_json; + if (!Array.isArray(role_map)) return resolve({ result: false, value: 'must be array even for one role' }); + if (multiple_same_emote(role_map)) return resolve({ result: false, value: 'emotes should differ ./help role_assigner' }); + + role_map.forEach(r => { r.give = r.give.trim(); r.strip = r.strip.trim(); }); + // client.emojis.cache.forEach(emoji => console.log('emoji: ', emoji)); + + const role_emb_value: GiveRole[] = []; + const role_emb_display_give: Field[] = []; + const role_emb_display_strip: Field[] = []; + + role_emb_display_give.push({ emote: '', role: 'React with emote to get correlating role', inline: false, }); + role_emb_display_strip.push({ emote: '', role: 'React with emote to strip correlating role', inline: false, }); + + let return_value: string = ''; + // give roles + const failed = role_map.some((r, index) => { + if (message.guild) { + const role_fetched = get_role(message.guild, r.role_id); + if (!role_fetched) { + return_value = `${index + 1}. ${r.role_id} is not a role in ${message.guild}`; + return true; + } + role_emb_display_give.push(new Field(r.give, role_fetched.name, true)); + role_emb_display_strip.push(new Field(r.strip, role_fetched.name, true)); + role_emb_value.push(new GiveRole(role_fetched.id, r.give, r.strip)); + } else { + return_value = `could not fetch guild of message`; + return true; + } + }); + + if (failed) return resolve({ result: false, value: return_value }); + + create_role_message( + message.channel, + guild_object, + 'Portal Role Assigner', + '', + '#FF7F00', + role_emb_display_give.concat(role_emb_display_strip), + role_map + ) + + return resolve({ result: true, value: 'role message has been created.' }); + }); +}; diff --git a/src/commands/roll.js b/src/commands/roll.js deleted file mode 100644 index 5488105a..00000000 --- a/src/commands/roll.js +++ /dev/null @@ -1,21 +0,0 @@ -const Roll = require('roll'); - -module.exports = async (client, message, args, portal_guilds, portal_managed_guilds_path) => { - return new Promise((resolve) => { - if (args.length === 1) { - const roll_lib = new Roll(); - const roll = roll_lib.roll(args[0]); - message.channel.send(`${message.author}, ${roll.result} (${roll.rolled} from ${args[0]})`); - - return resolve({ - result: true, - value: null - }); - } else { - return resolve({ - result: false, - value: '*you can run "./help roll" for help.*' - }); - } - }); -}; diff --git a/src/commands/roll.ts b/src/commands/roll.ts new file mode 100644 index 00000000..a2c58d27 --- /dev/null +++ b/src/commands/roll.ts @@ -0,0 +1,33 @@ +import { Client, Message } from "discord.js"; +import Roll from 'roll'; +import { GuildPrtl } from "../types/classes/GuildPrtl"; + +module.exports = async ( + client: Client, message: Message, args: string[], + guild_list: GuildPrtl[], portal_managed_guilds_path: string +) => { + return new Promise((resolve) => { + const guild_object = guild_list.find(g => g.id === message.guild?.id); + if (!guild_object) { + return resolve({ result: true, value: 'portal guild could not be fetched' }); + } + + if (args.length === 1) { + const roll_lib = new Roll(); + const roll = roll_lib.roll(args[0]); + message.channel.send( + `${message.author}, ${roll.result} (${roll.rolled} from ${args[0]})` + ); + + return resolve({ + result: true, + value: null + }); + } else { + return resolve({ + result: false, + value: '*you can run "./help roll" for help.*' + }); + } + }); +}; diff --git a/src/commands/run.js b/src/commands/run.js deleted file mode 100644 index 8a5003ea..00000000 --- a/src/commands/run.js +++ /dev/null @@ -1,45 +0,0 @@ -/* eslint-disable no-unused-vars */ -const guld_mngr = require('./../functions/guild_manager'); - -module.exports = async (client, message, args, portal_guilds, portal_managed_guilds_path) => { - return new Promise((resolve) => { - const current_voice = message.member.voice; - const current_portal_list = portal_guilds[message.guild.id].portal_list; - - if (current_voice === null) { - return resolve ({ - result: false, - value: '*you must be in a channel handled by* **Portal™** *to run commands.*', - }); - } - else if (!guld_mngr.included_in_voice_list(current_voice.channelID, current_portal_list)) { - return resolve ({ - result: false, - value: '*the channel you are in is not handled by* **Portal™**', - }); - } - - for (const key in current_portal_list) { - if (current_portal_list[key].voice_list[current_voice.channelID]) { - message.channel.send('executing: ' + args.join(' ')) - .then(sentMessage => { - sentMessage.edit( - guld_mngr.regex_interpreter( - args.join(' '), - current_voice.channel, - current_portal_list[key].voice_list[current_voice.channelID], - current_portal_list, - portal_guilds[message.guild.id], - message.guild, - ), - ); - }); - } - } - - return resolve ({ - result: true, - value: '*command ran successfully.*', - }); - }); -}; diff --git a/src/commands/run.ts b/src/commands/run.ts new file mode 100644 index 00000000..b57a57d0 --- /dev/null +++ b/src/commands/run.ts @@ -0,0 +1,71 @@ +import { Client, Message } from "discord.js"; +import { included_in_voice_list, regex_interpreter } from "../libraries/guildOps"; +import { GuildPrtl } from "../types/classes/GuildPrtl"; + +module.exports = async ( + client: Client, message: Message, args: string[], + guild_list: GuildPrtl[], portal_managed_guilds_path: string +) => { + return new Promise((resolve) => { + const guild_object = guild_list.find(g => g.id === message.guild?.id); + if (!guild_object) + return resolve({ result: true, value: 'portal guild could not be fetched' }); + if (!message.guild) + return resolve({ result: true, value: 'guild could not be fetched' }); + if (!message.member) + return resolve({ result: true, value: 'member could not be fetched' }); + + const current_voice = message.member.voice; + const current_voice_channel = current_voice.channel; + + if (current_voice === null) { + return resolve({ + result: false, + value: 'you must be in a channel handled by Portal to run commands', + }); + } + else if (current_voice_channel === null) { + return resolve({ + result: false, + value: 'you must be in a channel handled by Portal to run commands', + }); + } + else if (!included_in_voice_list(current_voice_channel.id, guild_object.portal_list)) { + return resolve({ + result: false, + value: 'the channel you are in is not handled by Portal', + }); + } + + const voice_found = guild_object.portal_list.some(p => { + return p.voice_list.some(v => { + if (v.id === current_voice_channel.id) { + message.channel.send('executing: ' + args.join(' ')) + .then(sent_message => { + if (message.guild) + sent_message.edit( + regex_interpreter( + args.join(' '), + current_voice_channel, + v, + guild_object.portal_list, + guild_object, + message.guild + ) + ); + else + sent_message.edit('could not fetch guild of message'); + }); + return true; + } + return false; + }) + }); + + if (voice_found) + return resolve({ result: true, value: 'instruction ran successfully', }); + else + return resolve({ result: false, value: 'could not find your voice channel', }); + + }); +}; diff --git a/src/commands/save.js b/src/commands/save.js deleted file mode 100644 index f366ede1..00000000 --- a/src/commands/save.js +++ /dev/null @@ -1,9 +0,0 @@ -const help_mngr = require('./../functions/help_manager'); - -module.exports = async (client, message, args, portal_guilds, portal_managed_guilds_path) => { - return new Promise((resolve) => { - help_mngr.update_portal_managed_guilds(true, portal_managed_guilds_path, portal_guilds) - .then((response) => resolve(response)) - .catch(console); - }); -}; diff --git a/src/commands/save.ts b/src/commands/save.ts new file mode 100644 index 00000000..27cff331 --- /dev/null +++ b/src/commands/save.ts @@ -0,0 +1,18 @@ +import { Client, Message } from "discord.js"; +import { update_portal_managed_guilds } from "../libraries/helpOps"; +import { GuildPrtl } from "../types/classes/GuildPrtl"; + +module.exports = async ( + client: Client, message: Message, args: string[], + guild_list: GuildPrtl[], portal_managed_guilds_path: string +) => { + return new Promise((resolve) => { + const guild_object = guild_list.find(g => g.id === message.guild?.id); + if (!guild_object) return resolve({ result: true, value: 'portal guild could not be fetched' }); + if (!message.guild) return resolve({ result: true, value: 'guild could not be fetched' }); + + update_portal_managed_guilds(true, portal_managed_guilds_path, guild_list) + .then((response) => resolve(response)) + .catch((error) => resolve(error)); + }); +}; diff --git a/src/commands/set.js b/src/commands/set.js deleted file mode 100644 index f7f3ab47..00000000 --- a/src/commands/set.js +++ /dev/null @@ -1,95 +0,0 @@ -/* eslint-disable no-unused-vars */ -const guld_mngr = require('./../functions/guild_manager'); -const attr_objct = require('../properties/attribute_list'); - -const locales = ['gr', 'en', 'de']; - -module.exports = async (client, message, args, portal_guilds, portal_managed_guilds_path) => { - return new Promise((resolve) => { - const current_portal_list = portal_guilds[message.guild.id].portal_list; - - if (message.member.voice.channel === undefined || message.member.voice.channel === null) { - return resolve ({ - result: false, - value: '*you must be in a channel handled by* **Portal™***.*', - }); - } - else if (!guld_mngr.included_in_voice_list(message.member.voice.channel.id, current_portal_list)) { - return resolve ({ - result: false, - value: '*the channel you are in is not handled by* **Portal™***.*', - }); - } - - if (args.length > 1) { - for (const portal_key in current_portal_list) { - for (const voice_key in current_portal_list[portal_key].voice_list) { - if (voice_key === message.member.voice.channel.id) { - const current_voice_channel = current_portal_list[portal_key].voice_list[voice_key]; - const current_portal_channel = current_portal_list[portal_key]; - - let value = [...args]; value.shift(); - value = value.filter(val => val !== '\n').join(' '); - - const return_value = attr_objct.set( - message.member.voice.channel, current_voice_channel, current_portal_channel, - portal_guilds[message.guild.id], args[0], value, message.member, - ); - - switch (return_value) { - case 1: - return resolve ({ - result: true, - value: `*attribute ${args[0]} set to ${value} successfully.*`, - }); - case -1: - return resolve({ - result: false, - value: `*${args[0]} is not an attribute.*`, - }); - case -2: - return resolve ({ - result: false, - value: `*${args[0]} can only be set by an administrator.*`, - }); - case -3: - return resolve({ - result: false, - value: `*${args[0]} can only be set by the portal creator.*`, - }); - case -4: - return resolve({ - result: false, - value: `*${args[0]} can only be set by the voice creator.*`, - }); - case -5: - return resolve ({ - result: false, - value: `*locale can only be ${locales.join(', ')}.*`, - }); - case -6: - return resolve({ - result: false, - value: `*${args[0]} can be a number from 0-n (0 means unlimited).*`, - }); - case -7: - return resolve({ - result: false, - value: `*${args[0]} can only be true or false.*`, - }); - default: - return resolve ({ - result: false, - value: `*${args[0]} cannot be set.*`, - }); - } - } - } - } - } - return resolve ({ - result: true, - value: `*${args[0]} was not set.*`, - }); - }); -}; diff --git a/src/commands/set.ts b/src/commands/set.ts new file mode 100644 index 00000000..79bb36b9 --- /dev/null +++ b/src/commands/set.ts @@ -0,0 +1,98 @@ +import { Client, Message } from "discord.js"; +import { included_in_voice_list } from "../libraries/guildOps"; +import { GuildPrtl } from "../types/classes/GuildPrtl"; +import { set_attribute } from "../types/interfaces/Attribute"; + +const locales = ['gr', 'en', 'de']; + +module.exports = async ( + client: Client, message: Message, args: string[], + guild_list: GuildPrtl[], portal_managed_guilds_path: string +) => { + return new Promise((resolve) => { + const guild_object = guild_list.find(g => g.id === message.guild?.id); + if (!guild_object) { + return resolve({ result: true, value: 'portal guild could not be fetched' }); + } + if (!message.guild) { + return resolve({ result: true, value: 'guild could not be fetched' }); + } + if (!message.member) { + return resolve({ result: true, value: 'member could not be fetched' }); + } + + if (message.member.voice.channel === undefined || message.member.voice.channel === null) { + return resolve({ result: false, value: 'you must be in a channel handled by Portal' }); + } + else if (!included_in_voice_list(message.member.voice.channel.id, guild_object.portal_list)) { + return resolve({ result: false, value: 'the channel you are in is not handled by Portal' }); + } + + if (args.length === 2) { + guild_object.portal_list.some(p => { + p.voice_list.some(v => { + if (v.id === message.member?.voice.channel?.id) { + let value_array = [...args]; + value_array.shift(); + const value = value_array.filter(val => val !== '\n').join(' '); + + const return_value = set_attribute( + message.member.voice.channel, v, p, + guild_object, args[0], value, message.member, + ); + + switch (return_value) { + case 1: + return resolve({ + result: true, + value: `attribute ${args[0]} set to ${value} successfully` + }); + case -1: + return resolve({ + result: false, + value: `${args[0]} is not an attribute` + }); + case -2: + return resolve({ + result: false, + value: `${args[0]} can only be set by an administrator` + }); + case -3: + return resolve({ + result: false, + value: `${args[0]} can only be set by the portal creator` + }); + case -4: + return resolve({ + result: false, + value: `${args[0]} can only be set by the voice creator` + }); + case -5: + return resolve({ + result: false, + value: `locale can only be ${locales.join(', ')}` + }); + case -6: + return resolve({ + result: false, + value: `${args[0]} can be a number from 0-n (0 means unlimited)` + }); + case -7: + return resolve({ + result: false, + value: `${args[0]} can only be true or false` + }); + default: + return resolve({ + result: false, + value: `${args[0]} cannot be set` + }); + } + } + }); + }); + } + + return resolve({ result: false, value: `arguments are set by name and value, run ./help set for help` }); + }); +}; diff --git a/src/commands/set_ranks.js b/src/commands/set_ranks.js deleted file mode 100644 index 8873484a..00000000 --- a/src/commands/set_ranks.js +++ /dev/null @@ -1,61 +0,0 @@ -/* eslint-disable no-unused-vars */ -const help_mngr = require('../functions/help_manager'); -const guld_mngr = require('../functions/guild_manager'); - -module.exports = async (client, message, args, portal_guilds, portal_managed_guilds_path) => { - return new Promise((resolve) => { - const roles = [...message.guild.roles.cache]; - - if (args.length > 0) { - const is_rank = function(rank) { - return !!rank.level && !!rank.role; - }; - // is_role already exists in guild manager, keep the best - const is_role = function(rank) { - return roles.some(role => role[1].hoist ? role[1].name === rank.role : false); - }; - - const new_ranks = help_mngr.getJSON(args.join(' ')); - if(new_ranks === null) { - return resolve ({ - result: false, - value: '*ranking must be in Array JSON format, for more info ./help ranks*', - }); - } - if(!Array.isArray(new_ranks)) { - return resolve ({ - result: false, - value: '*ranking must be in Array JSON format, for more info ./help ranks*', - }); - } - if(!new_ranks.every(is_rank)) { - return resolve ({ - result: false, - value: '*rankings must be an object of level and role, for more info ./help ranks*', - }); - } - if(!new_ranks.every(is_role)) { - return resolve ({ - result: false, - value: '*a role given does not exist in server, for more info ./help ranks*', - }); - } - new_ranks.forEach(rank => { - rank.level = +rank.level; - rank['id'] = roles.find(role => role[1].name === rank.role)[0]; - }); - portal_guilds[message.guild.id].ranks = new_ranks; - } - else { - return resolve ({ - result: false, - value: '*you can run "./help ranks" for help.*', - }); - } - - return resolve ({ - result: true, - value: '*new rankings have been set.*', - }); - }); -}; diff --git a/src/commands/set_ranks.ts b/src/commands/set_ranks.ts new file mode 100644 index 00000000..b8ed53ac --- /dev/null +++ b/src/commands/set_ranks.ts @@ -0,0 +1,76 @@ +import { Client, Message, Role } from "discord.js"; +import { getJSON } from "../libraries/helpOps"; +import { GuildPrtl } from "../types/classes/GuildPrtl"; +import { Rank } from "../types/interfaces/InterfacesPrtl"; + +function is_rank(rank: Rank) { + return !!rank.level && !!rank.role; +}; + +function is_role(rank: Rank, roles: Role[]) { + return roles.some(role => { + if (role.id === rank.role) return true; + if (role.name === rank.role) return true; + return false; + }); +}; + +module.exports = async ( + client: Client, message: Message, args: string[], + guild_list: GuildPrtl[], portal_managed_guilds_path: string +) => { + return new Promise((resolve) => { + const guild_object = guild_list.find(g => g.id === message.guild?.id); + if (!guild_object) return resolve({ result: true, value: 'portal guild could not be fetched' }); + if (!message.guild) return resolve({ result: true, value: 'guild could not be fetched' }); + const roles = message.guild.roles.cache.map(cr => cr); + + if (args.length > 0) { + const new_ranks_json = getJSON(args.join(' ')); + if (new_ranks_json === null) { + return resolve({ + result: false, + value: 'ranking must be in Array JSON format, for more info ./help ranks' + }); + } + if (!Array.isArray(new_ranks_json)) { + return resolve({ + result: false, + value: 'ranking must be in Array JSON format, for more info ./help ranks' + }); + } + const new_ranks: Rank[] = new_ranks_json; + if (!new_ranks.every(is_rank)) { + return resolve({ + result: false, + value: 'rankings must be an object of level and role, for more info ./help ranks' + }); + } + if (!new_ranks.every(r => is_role(r, roles))) { + return resolve({ + result: false, + value: 'a role given does not exist in server, for more info ./help ranks' + }); + } + + new_ranks.forEach(rank => { + rank.level = +rank.level; + const role = roles.find(role => role.name === rank.role); + if (role) rank.role = role.id; + }); + + guild_object.ranks = new_ranks; + } + else { + return resolve({ + result: false, + value: 'you can run "./help ranks" for help.', + }); + } + + return resolve({ + result: true, + value: 'new rankings have been set.', + }); + }); +}; diff --git a/src/commands/setup.js b/src/commands/setup.js deleted file mode 100644 index 225380c0..00000000 --- a/src/commands/setup.js +++ /dev/null @@ -1,37 +0,0 @@ -/* eslint-disable no-unused-vars */ -/* eslint-disable no-cond-assign */ -/* eslint-disable no-undef */ -const guld_mngr = require('../functions/guild_manager'); - -module.exports = async (client, message, args, portal_guilds, portal_managed_guilds_path) => { - return new Promise((resolve) => { - message.guild.channels - .create('portal-hub', { type: 'category' }) - .then(cat_channel => { - message.guild.channels.cache.forEach(channel => { - if(channel.id === portal_guilds[message.guild.id].spotify || - channel.id === portal_guilds[message.guild.id].announcement || - channel.id === portal_guilds[message.guild.id].music_data.channel_id) { - guld_mngr.delete_channel(channel, message); - } - }); - - guld_mngr.create_portal_channel( - message.guild, 'portal-to-voice', cat_channel, portal_guilds[message.guild.id].portal_list, - portal_guilds, message.member.id); - guld_mngr.create_spotify_channel( - message.guild, 'spotify', cat_channel, portal_guilds[message.guild.id]); - guld_mngr.create_announcement_channel( - message.guild, 'announcement', cat_channel, portal_guilds[message.guild.id]); - guld_mngr.create_url_channel( - message.guild, 'url-only', cat_channel, portal_guilds[message.guild.id].url_list); - guld_mngr.create_music_channel( - message.guild, 'music-player', cat_channel, portal_guilds[message.guild.id]); - }) - .catch(console.error); - - return resolve({ - result: true, value: '*setup has ran succesfully*', - }); - }); -}; diff --git a/src/commands/setup.ts b/src/commands/setup.ts new file mode 100644 index 00000000..ba727654 --- /dev/null +++ b/src/commands/setup.ts @@ -0,0 +1,113 @@ +import { Client, GuildCreateChannelOptions, Message, TextChannel } from "discord.js"; +import { create_channel, create_music_channel, delete_channel, getOptions } from "../libraries/guildOps"; +import { GuildPrtl } from "../types/classes/GuildPrtl"; +import { PortalChannelPrtl } from "../types/classes/PortalChannelPrtl"; + +module.exports = async ( + client: Client, message: Message, args: string[], + guild_list: GuildPrtl[], portal_managed_guilds_path: string +) => { + return new Promise((resolve) => { + const guild_object = guild_list.find(g => g.id === message.guild?.id); + if (!guild_object) { + return resolve({ result: true, value: 'portal guild could not be fetched' }); + } + if (!message.guild) { + return resolve({ result: true, value: 'guild could not be fetched' }); + } + + message.guild.channels + .create('portal-hub', { type: 'category' }) + .then(cat_channel => { + if (message.guild) { + message.guild.channels.cache.forEach(channel => { + if (channel.id === guild_object.spotify || + channel.id === guild_object.announcement || + channel.id === guild_object.music_data.channel_id) { + delete_channel(channel, message); + } + }); + + if (message.member) { + const portal_options: GuildCreateChannelOptions = { + topic: `by Portal, channels on demand`, + type: 'voice', + bitrate: 64000, + userLimit: 1 + }; + const voice_regex = guild_object.premium + ? 'G$#-P$member_count | $status_list' + : 'Channel $#' + + create_channel(message.guild, 'portal-to-voice', portal_options, cat_channel) + .then(response => { + if (response.result) { + if (message.member) { + guild_object.portal_list.push(new PortalChannelPrtl( + response.value, message.member.id, 'portal-to-voice', voice_regex, + [], false, 2, 0, 0, guild_object.locale, true, true, 0 + )); + } else { + return resolve({ + result: false, + value: 'could not fetch member from message' + }); + } + + return resolve({ + result: true, + value: '*portal channel has been created.\n' + + 'Keep in mind that due to Discord\'s limitations,*\n' + + '**channel names will be updated on a five minute interval.**', + }); + } else { + return resolve(response); + } + }) + .catch(error => { return resolve(error); }); + } + + const spotify_options = getOptions(message.guild, 'displays music users in portal channels are listening too', false); + const announcement_options = getOptions(message.guild, 'announcements channel (Portal/Users/Admins)', false); + const url_options = getOptions(message.guild, 'url only channel', true); + + create_channel(message.guild, 'spotify', spotify_options, cat_channel) + .then(response => { + if (response.result) { + guild_object.spotify = response.value; + return resolve({ result: true, value: 'spotify channel and category created' }); + } else { + return resolve(response); + } + }) + .catch(error => { return resolve(error); }); + create_channel(message.guild, 'announcement', announcement_options, cat_channel) + .then(response => { + if (response.result) { + guild_object.announcement = response.value; + return resolve({ result: true, value: 'announcement channel and category created' }); + } else { + return resolve(response); + } + }) + .catch(error => { return resolve(error); }); + create_channel(message.guild, 'url-only', url_options, cat_channel) + .then(response => { + if (response.result) { + guild_object.url_list.push(response.value); + return resolve({ result: true, value: 'url channel and category created' }); + } else { + return resolve(response); + } + }) + .catch(error => { return resolve(error); }); + create_music_channel(message.guild, 'music-player', cat_channel, guild_object); + } + }) + .catch(console.error); + + return resolve({ + result: true, value: 'setup has ran succesfully', + }); + }); +}; diff --git a/src/commands/spotify.js b/src/commands/spotify.js deleted file mode 100644 index a4395b95..00000000 --- a/src/commands/spotify.js +++ /dev/null @@ -1,68 +0,0 @@ -/* eslint-disable no-unused-vars */ -const guld_mngr = require('./../functions/guild_manager'); - -module.exports = async (client, message, args, portal_guilds, portal_managed_guilds_path) => { - return new Promise((resolve) => { - if (args.length === 0) { - if (guld_mngr.is_spotify_channel(message.channel.id, portal_guilds[message.guild.id])) { - return resolve ({ - result: true, - value: '*this already is, the Spotify channel.*' }); - } - if (guld_mngr.is_music_channel(message.channel.id, portal_guilds[message.guild.id])) { - resolve ({ - result: true, - value: '*this can\'t be set as a Spotify channel for it is the Music channel.*' }); - } - if (guld_mngr.is_announcement_channel(message.channel.id, portal_guilds[message.guild.id])) { - return resolve ({ - result: true, - value: '*this can\'t be set as the Spotify channel for it is the Announcement channel.*' }); - } - if (guld_mngr.included_in_url_list(message.channel.id, portal_guilds[message.guild.id])) { - return resolve ({ - result: true, - value: '*this can\'t be set as the Spotify channel for it is an url channel.*' }); - } - } - - const spotify = message.guild.channels.cache - .find(channel => channel.id == portal_guilds[message.guild.id].spotify); - - if (spotify) guld_mngr.delete_channel(spotify, message); - - if (args.length === 0) { - portal_guilds[message.guild.id].spotify = message.channel.id; - - return resolve ({ - result: true, - value: '*this is now the Spotify channel.*' }); - } - else if (args.length > 0) { - const spotify_channel = args.join(' ').substr(0, args.join(' ').indexOf('|')); - const spotify_category = args.join(' ').substr(args.join(' ').indexOf('|') + 1); - - if (spotify_channel !== '') { - guld_mngr.create_spotify_channel( - message.guild, spotify_channel, spotify_category, portal_guilds[message.guild.id]); - - return resolve ({ - result: true, - value: '*spotify channel and category have been created*' }); - } - else if (spotify_channel === '' && spotify_category !== '') { - guld_mngr.create_spotify_channel( - message.guild, spotify_category, null, portal_guilds[message.guild.id]); - - return resolve ({ - result: true, - value: '*spotify channel has been created*' }); - } - else { - return resolve ({ - result: false, - value: '*you can run "./help spotify" for help.*' }); - } - } - }); -}; diff --git a/src/commands/spotify.ts b/src/commands/spotify.ts new file mode 100644 index 00000000..d6a62c60 --- /dev/null +++ b/src/commands/spotify.ts @@ -0,0 +1,104 @@ +import { Client, Message, TextChannel } from "discord.js"; +import { + delete_channel, included_in_url_list, is_announcement_channel, + is_music_channel, is_spotify_channel, getOptions, create_channel +} from "../libraries/guildOps"; +import { GuildPrtl } from "../types/classes/GuildPrtl"; + +module.exports = async ( + client: Client, message: Message, args: string[], + guild_list: GuildPrtl[], portal_managed_guilds_path: string +) => { + return new Promise((resolve) => { + const guild_object = guild_list.find(g => g.id === message.guild?.id); + if (!guild_object) { + return resolve({ result: true, value: 'portal guild could not be fetched' }); + } + if (!message.guild) { + return resolve({ result: true, value: 'guild could not be fetched' }); + } + + if (args.length === 0) { + if (is_spotify_channel(message.channel.id, guild_object)) { + return resolve({ + result: true, + value: '*this already is, the Spotify channel.*' + }); + } + if (is_music_channel(message.channel.id, guild_object)) { + resolve({ + result: true, + value: '*this can\'t be set as a Spotify channel for it is the Music channel.*' + }); + } + if (is_announcement_channel(message.channel.id, guild_object)) { + return resolve({ + result: true, + value: '*this can\'t be set as the Spotify channel for it is the Announcement channel.*' + }); + } + if (included_in_url_list(message.channel.id, guild_object)) { + return resolve({ + result: true, + value: '*this can\'t be set as the Spotify channel for it is an url channel.*' + }); + } + } + + const spotify = message.guild.channels.cache + .find(channel => channel.id == guild_object.spotify); + + if (spotify) delete_channel(spotify, message); + + if (args.length === 0) { + guild_object.spotify = message.channel.id; + + return resolve({ + result: true, + value: '*this is now the Spotify channel.*' + }); + } + else if (args.length > 0) { + const spotify_channel = args.join(' ').substr(0, args.join(' ').indexOf('|')); + const spotify_category = args.join(' ').substr(args.join(' ').indexOf('|') + 1); + const spotify_options = getOptions(message.guild, 'displays music users in portal channels are listening too', false); + + if (spotify_channel !== '') { + create_channel( + message.guild, spotify_channel, + spotify_options, spotify_category + ) + .then(response => { + if (response.result) { + guild_object.spotify = response.value; + return resolve({ result: true, value: 'spotify channel and category created' }); + } else { + return resolve(response); + } + }) + .catch(error => { return resolve(error); }); + } + else if (spotify_channel === '' && spotify_category !== '') { + create_channel( + message.guild, spotify_category, + spotify_options, null + ) + .then(response => { + if (response.result) { + guild_object.spotify = response.value; + return resolve({ result: true, value: 'spotify channel created' }); + } else { + return resolve(response); + } + }) + .catch(error => { return resolve(error); }); + } + else { + return resolve({ + result: false, + value: '*you can run "./help spotify" for help.*' + }); + } + } + }); +}; diff --git a/src/commands/state.ts b/src/commands/state.ts new file mode 100644 index 00000000..fb1ffe1c --- /dev/null +++ b/src/commands/state.ts @@ -0,0 +1,86 @@ +import { Client, Message } from "discord.js"; +import { create_rich_embed } from "../libraries/helpOps"; +import { GuildPrtl } from "../types/classes/GuildPrtl"; +import { Field } from "../types/interfaces/InterfacesPrtl"; + +module.exports = async ( + client: Client, message: Message, args: string[], + guild_list: GuildPrtl[], portal_managed_guilds_path: string +) => { + return new Promise((resolve) => { + const guild = client.guilds.cache.find(g => g.id === message?.guild?.id); + if (!guild) + return resolve({ result: false, value: 'could not fetch guild' }); + + const portal_object = guild_list.find(g => g.id === message?.guild?.id); + if (!portal_object) + return resolve({ result: false, value: 'could not find guild please contact portal support' }); + + let portal_state = [{ emote: 'Portals', role: '', inline: false }]; + + const portals = portal_object.portal_list.map(p => { + const voices = p.voice_list.map(v => { + const channel = guild.channels.cache.find(c => c.id === v.id); + return `> voice: ${channel ? channel.name : 'undefined'}`; + }).join('\n'); + const channel = guild.channels.cache.find(c => c.id === p.id); + + return { emote: `${channel ? channel.name : 'undefined'}`, role: voices, inline: true } + }); + if (portals) + portal_state = portal_state.concat(portals); + + portal_state.push({ emote: 'Music / Spotify / Announcement', role: '', inline: false }); + + const music = guild.channels.cache.find(c => c.id === portal_object.music_data.channel_id); + if (music) + portal_state.push({ + emote: `${music ? music.name : 'undefined'} _(music)_`, + role: 'the music channel can be used to play music', + inline: true + }); + + const spotify = guild.channels.cache.find(c => c.id === portal_object.spotify); + if (spotify) + portal_state.push({ + emote: `${spotify ? spotify.name : 'undefined'} _(spotify)_`, + role: 'displays Music people in Portal\'s voice channels listen too', + inline: true + }); + + const announcement = guild.channels.cache.find(c => c.id === portal_object.announcement); + if (announcement) + portal_state.push({ + emote: `${announcement ? announcement.name : 'undefined'} _(announcement)_`, + role: 'the announcement channel used by admins and portal', + inline: true + }); + + portal_state.push({ emote: 'Url-only', role: '', inline: false }); + + const urls = portal_object.url_list.map(u_id => { + const channel = guild.channels.cache.find(c => c.id === u_id); + return { + emote: `${channel ? channel.name : 'undefined'}`, + role: 'these channels are url only', + inline: true + } + }); + if (urls) + portal_state = portal_state.concat(urls); + + message.channel.send(create_rich_embed( + 'Portal State', + 'current state of Portal', + '#964B00', + portal_state, + null, + null, + true, + null, + null + )); + + return resolve({ result: true, value: '' }); + }); +}; \ No newline at end of file diff --git a/src/commands/translate.ts b/src/commands/translate.ts new file mode 100644 index 00000000..0f4a4542 --- /dev/null +++ b/src/commands/translate.ts @@ -0,0 +1,48 @@ +import { Client, Message } from 'discord.js'; +import { GuildPrtl } from '../types/classes/GuildPrtl'; +import config from '../config.json'; + +const translate = require('translate') +translate.engine = config.api_keys.translate.engine; +translate.key = config.api_keys.translate.key; + +module.exports = async ( + client: Client, message: Message, args: string[], + guild_list: GuildPrtl[], portal_managed_guilds_path: string +) => { + return new Promise((resolve) => { + return resolve({ result: true, value: 'work in progress' }); + const guild_object = guild_list.find(g => g.id === message.guild?.id); + if (!guild_object) return resolve({ result: true, value: 'portal guild could not be fetched' }); + + if (args.length <= 1) + return resolve({ result: false, value: '1 you can run "./help translate" for help.' }); + + const language_options = args.join(' ').substr(0, args.join(' ').indexOf('|')); + const string_to_tranlate = args.join(' ').substr(args.join(' ').indexOf('|') + 1); + + if (!language_options || !string_to_tranlate) + return resolve({ result: false, value: '2 you can run "./help translate" for help.' }); + + const language_duplet = language_options.split(','); + if (language_duplet.length === 2) { + translate(string_to_tranlate, { from: language_duplet[0], to: language_duplet[1] }) + .then((response: string) => { + return resolve({ result: true, value: response }); + }) + .catch((error: any) => { + return resolve({ result: false, value: `server responded with error: ${error}` }); + }); + } else if (language_duplet.length === 1) { + translate(string_to_tranlate, { to: language_duplet[0] }) + .then((response: string) => { + return resolve({ result: true, value: response }); + }) + .catch((error: any) => { + return resolve({ result: false, value: `server responded with error: ${error}` }); + }); + } else { + return resolve({ result: false, value: '3 you can run "./help translate" for help.' }); + } + }); +}; diff --git a/src/commands/url.js b/src/commands/url.js deleted file mode 100644 index 05c0990c..00000000 --- a/src/commands/url.js +++ /dev/null @@ -1,64 +0,0 @@ -/* eslint-disable no-unused-vars */ -const guld_mngr = require('./../functions/guild_manager'); - -module.exports = async (client, message, args, portal_guilds, portal_managed_guilds_path) => { - return new Promise((resolve) => { - if (args.length === 0) { - if (guld_mngr.included_in_url_list(message.channel.id, portal_guilds[message.guild.id])) { - resolve ({ - result: true, - value: '*this already is a URL channel.*', - }); - } - if (guld_mngr.is_announcement_channel(message.channel.id, portal_guilds[message.guild.id])) { - resolve ({ - result: true, - value: '*this can\'t be set as a URL channel for it is the Announcement channel.*', - }); - } - if (guld_mngr.is_spotify_channel(message.channel.id, portal_guilds[message.guild.id])) { - resolve ({ - result: true, - value: '*this can\'t be set as a URL channel for it is the Spotify channel.*', - }); - } - if (guld_mngr.is_music_channel(message.channel.id, portal_guilds[message.guild.id])) { - resolve ({ - result: true, - value: '*this can\'t be set as a URL channel for it is the Music channel.*', - }); - } - } - - // if (url = message.guild.channels.cache.find(channel => - // channel.id == portal_guilds[message.guild.id].url_list[message.channel.id])) { - // guld_mngr.delete_channel(url, message); - // } - - if (args.length === 0) { - portal_guilds[message.guild.id].url_list.push(message.channel.id); - - resolve ({ result: true, value: '*this is now the url channel.*' }); - } - else if (args.length > 0) { - const url_channel = args.join(' ').substr(0, args.join(' ').indexOf('|')); - const url_category = args.join(' ').substr(args.join(' ').indexOf('|') + 1); - - if (url_channel !== '') { - guld_mngr.create_url_channel( - message.guild, url_channel, url_category, portal_guilds[message.guild.id].url_list); - - resolve ({ result: true, value: '*url channel and category have been created*' }); - } - else if (url_channel === '' && url_category !== '') { - guld_mngr.create_url_channel( - message.guild, url_category, null, portal_guilds[message.guild.id].url_list); - - resolve ({ result: true, value: '*url channel has been created*' }); - } - else { - resolve ({ result: false, value: '*you can run "./help url" for help.*' }); - } - } - }); -}; diff --git a/src/commands/url.ts b/src/commands/url.ts new file mode 100644 index 00000000..cbf7c467 --- /dev/null +++ b/src/commands/url.ts @@ -0,0 +1,93 @@ +import { Client, Message } from "discord.js"; +import { + create_channel, getOptions, included_in_url_list, + is_announcement_channel, is_music_channel, is_spotify_channel +} from "../libraries/guildOps"; +import { GuildPrtl } from "../types/classes/GuildPrtl"; + +module.exports = async ( + client: Client, message: Message, args: string[], + guild_list: GuildPrtl[], portal_managed_guilds_path: string +) => { + return new Promise((resolve) => { + const guild_object = guild_list.find(g => g.id === message.guild?.id); + if (!guild_object) { + return resolve({ result: true, value: 'portal guild could not be fetched' }); + } + if (!message.guild) { + return resolve({ result: true, value: 'guild could not be fetched' }); + } + + if (args.length === 0) { + if (included_in_url_list(message.channel.id, guild_object)) { + resolve({ + result: true, + value: 'this already is a URL channel.', + }); + } + if (is_announcement_channel(message.channel.id, guild_object)) { + resolve({ + result: true, + value: 'this can\'t be set as a URL channel for it is the Announcement channel.', + }); + } + if (is_spotify_channel(message.channel.id, guild_object)) { + resolve({ + result: true, + value: 'this can\'t be set as a URL channel for it is the Spotify channel.', + }); + } + if (is_music_channel(message.channel.id, guild_object)) { + resolve({ + result: true, + value: 'this can\'t be set as a URL channel for it is the Music channel.', + }); + } + } + + if (args.length === 0) { + guild_object.url_list.push(message.channel.id); + + resolve({ result: true, value: 'this is now the url channel.' }); + } + else if (args.length > 0) { + const url_channel = args.join(' ').substr(0, args.join(' ').indexOf('|')); + const url_category = args.join(' ').substr(args.join(' ').indexOf('|') + 1); + const spotify_options = getOptions(message.guild, 'url only channel', true); + + if (url_channel !== '') { + create_channel( + message.guild, url_channel, + spotify_options, url_category + ) + .then(response => { + if (response.result) { + guild_object.url_list.push(response.value); + return resolve({ result: true, value: 'url channel and category created' }); + } else { + return resolve(response); + } + }) + .catch(error => { return resolve(error); }); + } + else if (url_channel === '' && url_category !== '') { + create_channel( + message.guild, url_category, + spotify_options, null + ) + .then(response => { + if (response.result) { + guild_object.url_list.push(response.value); + return resolve({ result: true, value: 'url channel created' }); + } else { + return resolve(response); + } + }) + .catch(error => { return resolve(error); }); + } + else { + resolve({ result: false, value: 'you can run "./help url" for help.' }); + } + } + }); +}; diff --git a/src/commands/weather.ts b/src/commands/weather.ts new file mode 100644 index 00000000..5a12be4f --- /dev/null +++ b/src/commands/weather.ts @@ -0,0 +1,114 @@ +import { Client, Message } from 'discord.js'; +import { RequestOptions } from 'https'; +import moment from 'moment'; +import config from '../config.json'; +import { create_rich_embed, getJSON } from '../libraries/helpOps'; +import { https_fetch } from '../libraries/httpOps'; +import { GuildPrtl } from '../types/classes/GuildPrtl'; + +function kelvin_to_celsius(kelvin: number): number { + return Math.round(kelvin - 272.15); +} + +function kelvin_to_fahrenheit(kelvin: number): number { + return Math.round(kelvin - 457.87); +} + +function ms_to_ks(ms: number): number { + return Math.round(ms * 3.6); +} + +function ms_to_mlh(ms: number): number { + return Math.round(ms * 2.237); +} + +module.exports = async ( + client: Client, message: Message, args: string[], + guild_list: GuildPrtl[], portal_managed_guilds_path: string +) => { + return new Promise((resolve) => { + const guild_object = guild_list.find(g => g.id === message.guild?.id); + if (!guild_object) + return resolve({ result: true, value: 'portal guild could not be fetched' }); + + if (args.length < 1) + return resolve({ result: false, value: 'you can run "./help weather" for help.', }); + + const location = args.join('%2C%20'); + const options: RequestOptions = { + "method": "GET", + "hostname": "api.openweathermap.org", + "port": undefined, + "path": `/data/2.5/weather?q=${location}&appid=${config.api_keys.OpenWeatherMap}`, + }; + + https_fetch(options) + .then((rspns: Buffer) => { + const json = getJSON(rspns.toString().substring(rspns.toString().indexOf('{'))); + if (json === null) + return resolve({ result: false, value: 'data from source was corrupted' }); + if (json.cod === '404') + return resolve({ result: false, value: 'city not found' }); + + if (json.cod === 200) { + message.channel.send( + create_rich_embed( + `${json.name}, ${json.sys.country} at ${moment().format('DD/MM/YY')}`, + 'powered by OpenWeatherMap', + '#BFEFFF', + [ + { + emote: 'Temperature', + role: `${kelvin_to_celsius(json.main.temp)}°C / ${kelvin_to_fahrenheit(json.main.temp)}°F`, + inline: true + }, + { + emote: 'Feels like', + role: `${kelvin_to_celsius(json.main.feels_like)}°C / ${kelvin_to_fahrenheit(json.main.feels_like)}°F`, + inline: true + }, + { + emote: null, + role: null, + inline: false + }, + { + emote: 'Humidity', + role: `${json.main.humidity}`, + inline: true + }, + { + emote: 'Wind Speed', + role: `${ms_to_ks(json.wind.speed)}kmh / ${ms_to_mlh(json.wind.speed)}mlh`, + inline: true + }, + { + emote: 'Cloudiness', + role: `${json.clouds.all}%`, + inline: true + }, + { + emote: 'Condition', + role: `${json.weather.map((w: any) => { + return `${w.main} (${w.description})`; + }).join(', ')}`, + inline: false + } + ], + `http://openweathermap.org/img/wn/${json.weather[0].icon}@2x.png`, + null, + true, + null, + null + )); + return resolve({ result: true, value: `${json.name} weather` }); + } + else { + return resolve({ result: false, value: `could not access the server\nerror: ${json.cod}` }); + } + }) + .catch((error: any) => { + return resolve({ result: false, value: `could not access the server\nerror: ${error}` }); + }); + }); +}; diff --git a/src/commands/whoami.ts b/src/commands/whoami.ts new file mode 100644 index 00000000..dcd06527 --- /dev/null +++ b/src/commands/whoami.ts @@ -0,0 +1,43 @@ +import { Client, Message } from "discord.js"; +import { create_rich_embed } from "../libraries/helpOps"; +import { GuildPrtl } from "../types/classes/GuildPrtl"; + +module.exports = async ( + client: Client, message: Message, args: string[], + guild_list: GuildPrtl[], portal_managed_guilds_path: string +) => { + return new Promise((resolve) => { + const guild_object = guild_list.find(g => g.id === message.guild?.id); + if (!guild_object) return resolve({ result: false, value: 'could not find guild, please contact portal support' }); + const member_object = guild_object.member_list.find(m => m.id === message.member?.id); + if (!member_object) return resolve({ result: false, value: 'could not find guild, please contact portal support' }); + + message.channel.send(create_rich_embed( + message.member ? message.member?.displayName : 'could not fetch name', + 'member portal card', + '#42f5d7', + [{ + emote: 'id', + role: member_object.id, + inline: false + }, + { + emote: 'level', + role: member_object.level, + inline: false + }, + { + emote: 'admin', + role: member_object.admin, + inline: false + }], + message.member?.user.avatarURL(), + null, + true, + null, + null) + ); + + return resolve({ result: true, value: '' }); + }); +}; \ No newline at end of file diff --git a/src/config.json b/src/config.json new file mode 100644 index 00000000..f3a219fe --- /dev/null +++ b/src/config.json @@ -0,0 +1,19 @@ +{ + "token": "NzU1ODI1ODcwMTAyNTkzNjI2.X2I7sQ.nDesKkpHU-m5wdxZOdXmChlgnXU", + "token_dev": "NzA0NDAwODc2ODYwNzM1NTY5.Xqdexg.BkhxqAkXpNZfcIzalW68jFw5DTI", + "prefix": "./", + "database_json": "src/database/guild_list.json", + "owner_id": 228666893068795905, + "portal_id": 755825870102593626, + "api_keys": { + "OpenWeatherMap": "7692e8876197f1532fe027f43c6f3227", + "covid_193": "b883903090msh7eef2b50e6cbe9cp1ff439jsnee4d6c48061f", + "translate": { + "engine": "yandex", + "key": "pdct.1.1.20210108T115346Z.8c752ef4694c06bb.efe449cd7367ac260b85058afac0ae307995599b" + } + }, + "delete_msg": false, + "delete_msg_after": 5, + "always_reply": true +} \ No newline at end of file diff --git a/src/database/guild_list.json b/src/database/guild_list.json new file mode 100644 index 00000000..b6e0dded --- /dev/null +++ b/src/database/guild_list.json @@ -0,0 +1 @@ +[{"id":"710746690650374208","portal_list":[{"id":"797152768367525929","creator_id":"228666893068795905","regex_portal":"","regex_voice":"Channel $#","voice_list":[{"id":"797164618366844928","creator_id":"228666893068795905","regex":"Channel $#","no_bots":false,"time_to_live":0,"refresh_rate":0,"locale":"en","ann_announce":true,"ann_user":true}],"no_bots":false,"limit_portal":2,"time_to_live":0,"refresh_rate":0,"locale":"en","ann_announce":true,"ann_user":true,"user_limit_portal":0},{"id":"797153149445079060","creator_id":"228666893068795905","regex_portal":"portal-to-voice","regex_voice":"G$#-P$member_count | $status_list","voice_list":[],"no_bots":false,"limit_portal":2,"time_to_live":0,"refresh_rate":0,"locale":"en","ann_announce":true,"ann_user":true,"user_limit_portal":0},{"id":"797153216440565812","creator_id":"228666893068795905","regex_portal":"","regex_voice":"G$#-P$member_count | $status_list","voice_list":[],"no_bots":false,"limit_portal":2,"time_to_live":0,"refresh_rate":0,"locale":"en","ann_announce":true,"ann_user":true,"user_limit_portal":0},{"id":"797168164659920936","creator_id":"228666893068795905","regex_portal":"","regex_voice":"G$#-P$member_count | $status_list","voice_list":[],"no_bots":false,"limit_portal":2,"time_to_live":0,"refresh_rate":0,"locale":"en","ann_announce":true,"ann_user":true,"user_limit_portal":0}],"member_list":[{"id":"228666893068795905","level":5,"rank":0,"tier":1,"points":25,"timestamp":null,"admin":false}],"url_list":["797153152238747688"],"role_list":[],"ranks":[],"auth_role":[],"spotify":"797153150406492170","music_data":{"channel_id":"797153153446707200","message_id":"797153155347382292"},"music_queue":[],"announcement":"797153151303155742","locale":"en","announce":true,"level_speed":"normal","premium":true},{"id":"228667314252283904","portal_list":[{"id":"797176444849094686","creator_id":"228666893068795905","regex_portal":"","regex_voice":"G$#-P$member_count | $status_list","voice_list":[],"no_bots":false,"limit_portal":2,"time_to_live":0,"refresh_rate":0,"locale":"en","ann_announce":true,"ann_user":true,"user_limit_portal":0}],"member_list":[{"id":"424232862296834050","level":1,"rank":0,"tier":0,"points":0,"timestamp":null,"admin":false},{"id":"141355428352229376","level":1,"rank":0,"tier":0,"points":0,"timestamp":null,"admin":false},{"id":"358644113543004173","level":1,"rank":0,"tier":0,"points":0,"timestamp":null,"admin":false},{"id":"233681213506715649","level":1,"rank":0,"tier":0,"points":0,"timestamp":null,"admin":false},{"id":"688036058080083968","level":1,"rank":0,"tier":0,"points":0,"timestamp":null,"admin":false},{"id":"398910271164252167","level":1,"rank":0,"tier":0,"points":0,"timestamp":null,"admin":false},{"id":"437935131936686120","level":1,"rank":0,"tier":0,"points":0,"timestamp":null,"admin":false},{"id":"322031419176124420","level":1,"rank":0,"tier":0,"points":0,"timestamp":null,"admin":false},{"id":"245633518829305866","level":1,"rank":0,"tier":0,"points":0,"timestamp":null,"admin":false},{"id":"386599272587722752","level":1,"rank":0,"tier":0,"points":0,"timestamp":null,"admin":false},{"id":"285416786566971393","level":1,"rank":0,"tier":0,"points":0,"timestamp":null,"admin":false},{"id":"230995663607824386","level":1,"rank":0,"tier":0,"points":0,"timestamp":null,"admin":false},{"id":"222753236686209024","level":1,"rank":0,"tier":0,"points":0,"timestamp":null,"admin":false},{"id":"427540698544472085","level":1,"rank":0,"tier":0,"points":0,"timestamp":null,"admin":false},{"id":"251448537273860096","level":1,"rank":0,"tier":0,"points":0,"timestamp":null,"admin":false},{"id":"233339202698215425","level":1,"rank":0,"tier":0,"points":0,"timestamp":null,"admin":false},{"id":"562010354540871712","level":1,"rank":0,"tier":0,"points":0,"timestamp":null,"admin":false},{"id":"346306540308922387","level":1,"rank":0,"tier":0,"points":0,"timestamp":null,"admin":false},{"id":"249594733150732290","level":1,"rank":0,"tier":0,"points":0,"timestamp":null,"admin":false},{"id":"394537380914397189","level":1,"rank":0,"tier":0,"points":0,"timestamp":null,"admin":false},{"id":"534388011857608705","level":1,"rank":0,"tier":0,"points":0,"timestamp":null,"admin":false},{"id":"362967897452314624","level":1,"rank":0,"tier":0,"points":0,"timestamp":null,"admin":false},{"id":"545021835432034304","level":1,"rank":0,"tier":0,"points":0,"timestamp":null,"admin":false},{"id":"248252695801102338","level":1,"rank":0,"tier":0,"points":0,"timestamp":null,"admin":false},{"id":"317434205057318913","level":1,"rank":0,"tier":0,"points":0,"timestamp":null,"admin":false},{"id":"476002321868914689","level":1,"rank":0,"tier":0,"points":0,"timestamp":null,"admin":false},{"id":"266240212542160896","level":1,"rank":0,"tier":0,"points":0,"timestamp":null,"admin":false},{"id":"408955131690876938","level":1,"rank":0,"tier":0,"points":0,"timestamp":null,"admin":false},{"id":"427926123859410944","level":1,"rank":0,"tier":0,"points":0,"timestamp":null,"admin":false},{"id":"231780831268438016","level":1,"rank":0,"tier":0,"points":0,"timestamp":null,"admin":false},{"id":"461124948560445450","level":1,"rank":0,"tier":0,"points":0,"timestamp":null,"admin":false},{"id":"404022320055975936","level":1,"rank":0,"tier":0,"points":0,"timestamp":null,"admin":false},{"id":"228666893068795905","level":5,"rank":0,"tier":1,"points":12,"timestamp":null,"admin":false},{"id":"231763688405598218","level":1,"rank":0,"tier":0,"points":0,"timestamp":null,"admin":false},{"id":"782684946464505897","level":1,"rank":0,"tier":0,"points":0,"timestamp":null,"admin":false},{"id":"234402593256767491","level":1,"rank":0,"tier":0,"points":0,"timestamp":null,"admin":false},{"id":"237209848066998272","level":1,"rank":0,"tier":0,"points":0,"timestamp":null,"admin":false},{"id":"698597773712293938","level":1,"rank":0,"tier":0,"points":0,"timestamp":null,"admin":false},{"id":"230430815505481729","level":1,"rank":0,"tier":0,"points":0,"timestamp":null,"admin":false},{"id":"370277653812477973","level":1,"rank":0,"tier":0,"points":0,"timestamp":null,"admin":false},{"id":"232875205523931136","level":1,"rank":0,"tier":0,"points":0,"timestamp":null,"admin":false},{"id":"684814451345719316","level":1,"rank":0,"tier":0,"points":0,"timestamp":null,"admin":false},{"id":"148526306500280320","level":1,"rank":0,"tier":0,"points":0,"timestamp":null,"admin":false},{"id":"433795733230059520","level":1,"rank":0,"tier":0,"points":0,"timestamp":null,"admin":false},{"id":"233682014283235331","level":1,"rank":0,"tier":0,"points":0,"timestamp":null,"admin":false},{"id":"488405995979145236","level":1,"rank":0,"tier":0,"points":0,"timestamp":null,"admin":false},{"id":"270707420831940618","level":1,"rank":0,"tier":0,"points":0,"timestamp":null,"admin":false},{"id":"534340160494632980","level":1,"rank":0,"tier":0,"points":0,"timestamp":null,"admin":false},{"id":"231373985420541952","level":1,"rank":0,"tier":0,"points":0,"timestamp":null,"admin":false},{"id":"142672003717922817","level":1,"rank":0,"tier":0,"points":0,"timestamp":null,"admin":false},{"id":"507202866537168906","level":1,"rank":0,"tier":0,"points":0,"timestamp":null,"admin":false},{"id":"406938957348339722","level":1,"rank":0,"tier":0,"points":0,"timestamp":null,"admin":false},{"id":"178625392586915840","level":1,"rank":0,"tier":0,"points":0,"timestamp":null,"admin":false},{"id":"395667507270254592","level":1,"rank":0,"tier":0,"points":0,"timestamp":null,"admin":false},{"id":"779828037898338306","level":1,"rank":0,"tier":0,"points":0,"timestamp":null,"admin":false},{"id":"533778497747812352","level":1,"rank":0,"tier":0,"points":0,"timestamp":null,"admin":false},{"id":"407615955812745217","level":1,"rank":0,"tier":0,"points":0,"timestamp":null,"admin":false},{"id":"231106885577605120","level":1,"rank":0,"tier":0,"points":0,"timestamp":null,"admin":false},{"id":"268865339041775618","level":1,"rank":0,"tier":0,"points":0,"timestamp":null,"admin":false},{"id":"590848955563376640","level":1,"rank":0,"tier":0,"points":0,"timestamp":null,"admin":false},{"id":"178621820457582602","level":1,"rank":0,"tier":0,"points":0,"timestamp":null,"admin":false},{"id":"522844906243489793","level":1,"rank":0,"tier":0,"points":0,"timestamp":null,"admin":false},{"id":"540559238733234207","level":1,"rank":0,"tier":0,"points":0,"timestamp":null,"admin":false},{"id":"642089816573607946","level":1,"rank":0,"tier":0,"points":0,"timestamp":null,"admin":false},{"id":"537023025585848324","level":1,"rank":0,"tier":0,"points":0,"timestamp":null,"admin":false}],"url_list":[],"role_list":[],"ranks":[],"auth_role":[],"spotify":null,"music_data":{"channel_id":"797176184785338438","message_id":"797176185943359538"},"music_queue":[],"announcement":null,"locale":"en","announce":true,"level_speed":"normal","premium":true}] diff --git a/src/events/channelDelete.js b/src/events/channelDelete.js deleted file mode 100644 index 4cbae131..00000000 --- a/src/events/channelDelete.js +++ /dev/null @@ -1,24 +0,0 @@ -const guld_mngr = require('./../functions/guild_manager'); -const help_mngr = require('./../functions/help_manager'); - -const type_of_channel = { 0: 'Unknown', 1: 'Portal', 2: 'Voice', 3: 'Url', 4: 'Spotify', 5: 'Announcement', 6: 'Music' }; - -module.exports = async (args) => { - const return_value = guld_mngr.channel_deleted_update_state(args.channel, args.guild_list); - - if (return_value === 0) { - return { - result: false, - value: 'removed channel is not controlled by Portal' + - `(guild: ${args.channel.guild.name} - id: ${args.channel.guild.id})`, - }; - } - else { - help_mngr.update_portal_managed_guilds(true, args.portal_managed_guilds_path, args.guild_list); - return { - result: true, - value: `${type_of_channel[return_value].toString()} channel, has been removed from ` + - `guild: ${args.channel.guild.name} - id: ${args.channel.guild.id}`, - }; - } -}; \ No newline at end of file diff --git a/src/events/channelDelete.ts b/src/events/channelDelete.ts new file mode 100644 index 00000000..1bdbd682 --- /dev/null +++ b/src/events/channelDelete.ts @@ -0,0 +1,31 @@ +import { Channel, DMChannel, GuildChannel, PartialDMChannel } from "discord.js"; +import { channel_deleted_update_state } from "../libraries/guildOps"; +import { update_portal_managed_guilds } from "../libraries/helpOps"; +import { GuildPrtl } from "../types/classes/GuildPrtl"; + +const type_of_channel = ['Unknown', 'Portal', 'Voice', 'Url', 'Spotify', 'Announcement', 'Music']; + +module.exports = async ( + args: { channel: GuildChannel, guild_list: GuildPrtl[], portal_managed_guilds_path: string } +) => { + if (typeof args.channel === typeof DMChannel) + return { result: false, value: 'channel is not guild channel' }; + + const return_value = channel_deleted_update_state(args.channel, args.guild_list); + + if (return_value === 0) { + return { + result: false, + value: 'removed channel is not controlled by Portal' + + `(guild: ${args.channel.guild.name} - id: ${args.channel.guild.id})`, + }; + } + else { + update_portal_managed_guilds(true, args.portal_managed_guilds_path, args.guild_list); + return { + result: true, + value: `${type_of_channel[return_value].toString()} channel, has been removed from ` + + `guild: ${args.channel.guild.name} - id: ${args.channel.guild.id}`, + }; + } +}; \ No newline at end of file diff --git a/src/events/guildCreate.js b/src/events/guildCreate.js deleted file mode 100644 index 245e9fe5..00000000 --- a/src/events/guildCreate.js +++ /dev/null @@ -1,17 +0,0 @@ -const guld_mngr = require('./../functions/guild_manager'); -const help_mngr = require('./../functions/help_manager'); - -module.exports = async (args) => { - // Inserting guild to portal's guild list if it does not exist - if (!guld_mngr.included_in_portal_guilds(args.guild.id, args.guild_list)) { - guld_mngr.insert_guild(args.guild.id, args.guild_list, args.client); - } - - help_mngr.update_portal_managed_guilds(true, args.portal_managed_guilds_path, args.guild_list); - - return { - result: true, - value: `Portal joined guild ${args.guild.name} [${args.guild.id}] ` + - `which has ${args.guild.memberCount} members.`, - }; -}; \ No newline at end of file diff --git a/src/events/guildCreate.ts b/src/events/guildCreate.ts new file mode 100644 index 00000000..6b1b21ba --- /dev/null +++ b/src/events/guildCreate.ts @@ -0,0 +1,64 @@ +import { Client, Guild, StreamDispatcher } from "discord.js"; +import { VideoSearchResult } from "yt-search"; +import { included_in_portal_guilds } from "../libraries/guildOps"; +import { update_portal_managed_guilds } from "../libraries/helpOps"; +import { GiveRolePrtl } from "../types/classes/GiveRolePrtl"; +import { GuildPrtl, MusicData } from "../types/classes/GuildPrtl"; +import { MemberPrtl } from "../types/classes/MemberPrtl"; +import { PortalChannelPrtl } from "../types/classes/PortalChannelPrtl"; +import { Rank } from "../types/interfaces/InterfacesPrtl"; + +function create_member_list(guild_id: string, client: Client): any { + const guild = client.guilds.cache.find((cached_guild: Guild) => cached_guild.id === guild_id); + if (!guild) return undefined; + + const member_list: MemberPrtl[] = []; + + guild.members.cache.forEach(member => { + if (client.user && !member.user.bot) { + if (member.id !== client.user.id) { + member_list.push(new MemberPrtl(member.id, 1, 0, 0, 0, null, false)); + } + } + }); + + return member_list; +}; + +function insert_guild(guild_id: string, guild_list: GuildPrtl[], client: Client): void { + const portal_list: PortalChannelPrtl[] = []; + const member_list = create_member_list(guild_id, client); + const url_list: string[] = []; + const role_list: GiveRolePrtl[] = []; + const ranks: Rank[] = []; + const auth_role: string[] = []; + const spotify: string | null = null; + const music_data: MusicData = { channel_id: undefined, message_id: undefined, votes: [] }; + const music_queue: VideoSearchResult[] = []; + const dispatcher: StreamDispatcher | undefined = undefined; + const announcement: string | null = null; + const locale: string = 'en'; + const announce: boolean = true; + const level_speed: string = 'normal'; + const premium: boolean = false; + + guild_list.push(new GuildPrtl(guild_id, portal_list, member_list, url_list, role_list, ranks, auth_role, + spotify, music_data, music_queue, dispatcher, announcement, locale, announce, level_speed, premium)); +}; + +module.exports = async ( + args: { client: Client, guild: Guild, guild_list: GuildPrtl[], portal_managed_guilds_path: string } +) => { + // Inserting guild to portal's guild list if it does not exist + if (!included_in_portal_guilds(args.guild.id, args.guild_list)) { + insert_guild(args.guild.id, args.guild_list, args.client); + } + + update_portal_managed_guilds(true, args.portal_managed_guilds_path, args.guild_list); + + return { + result: true, + value: `Portal joined guild ${args.guild.name} [${args.guild.id}] ` + + `which has ${args.guild.memberCount} members.`, + }; +}; \ No newline at end of file diff --git a/src/events/guildDelete.js b/src/events/guildDelete.js deleted file mode 100644 index a0fb878c..00000000 --- a/src/events/guildDelete.js +++ /dev/null @@ -1,12 +0,0 @@ -const guld_mngr = require('./../functions/guild_manager'); -const help_mngr = require('./../functions/help_manager'); - -module.exports = async (args) => { - guld_mngr.delete_guild(args.guild.id, args.guild_list); - help_mngr.update_portal_managed_guilds(true, args.portal_managed_guilds_path, args.guild_list); - - return { - result: true, - value: `Portal has been removed from: ${args.guild.name} (id: ${args.guild.id})`, - }; -}; \ No newline at end of file diff --git a/src/events/guildDelete.ts b/src/events/guildDelete.ts new file mode 100644 index 00000000..1d755333 --- /dev/null +++ b/src/events/guildDelete.ts @@ -0,0 +1,17 @@ +import { Guild } from "discord.js"; +import { delete_guild } from "../libraries/guildOps"; +import { update_portal_managed_guilds } from "../libraries/helpOps"; +import { GuildPrtl } from "../types/classes/GuildPrtl"; + + +module.exports = async ( + args: { guild: Guild, guild_list: GuildPrtl[], portal_managed_guilds_path: string } +) => { + delete_guild(args.guild.id, args.guild_list); + update_portal_managed_guilds(true, args.portal_managed_guilds_path, args.guild_list); + + return { + result: true, + value: `Portal has been removed from: ${args.guild.name} (id: ${args.guild.id})`, + }; +}; \ No newline at end of file diff --git a/src/events/guildMemberAdd.js b/src/events/guildMemberAdd.js deleted file mode 100644 index a7d7e8a9..00000000 --- a/src/events/guildMemberAdd.js +++ /dev/null @@ -1,21 +0,0 @@ -const help_mngr = require('../functions/help_manager'); -const member_class = require('../../assets/classes/member_class'); - -module.exports = async (args) => { - const join_message = `member: ${args.member.presence.user}\n` + - `id: ${args.member.guild.id}\n` + - `joined: ${args.member.guild}.`; - - if (args.guild_list[args.member.guild.id].announcement) { - args.member.guild.channels.cache - .find(channel => channel.id === args.guild_list[args.member.guild.id].announcement) - .send(help_mngr.create_rich_embed('Member joined', join_message, '#00C70D', null, - args.member.user.avatarURL(), null, true, null, null)); - } - - if (!args.member.bot) { - args.guild_list[args.member.guild.id].member_list[args.member.id] = new member_class(1, 0, 0, 0, null); - } - - return { result: true, value: 'Member added to guild' }; -}; diff --git a/src/events/guildMemberAdd.ts b/src/events/guildMemberAdd.ts new file mode 100644 index 00000000..3d5d30dc --- /dev/null +++ b/src/events/guildMemberAdd.ts @@ -0,0 +1,41 @@ +import { GuildMember, TextChannel } from "discord.js"; +import { create_rich_embed, guildPrtl_to_object } from "../libraries/helpOps"; +import { GuildPrtl } from "../types/classes/GuildPrtl"; +import { MemberPrtl } from "../types/classes/MemberPrtl"; + +module.exports = async ( + args: { member: GuildMember, guild_list: GuildPrtl[] } +) => { + const join_message = `member: ${args.member.presence.user}\n` + + `id: ${args.member.guild.id}\n` + + `joined: ${args.member.guild}.`; + + const guild_object = guildPrtl_to_object(args.guild_list, args.member.guild.id); + if (guild_object && guild_object.announcement) { + const announcement_channel = args.member.guild.channels.cache + .find(channel => channel.id === guild_object.announcement) + + if (announcement_channel) + (announcement_channel).send( + create_rich_embed( + 'member joined', join_message, '#00C70D', [], + args.member.user.avatarURL(), null, true, null, null + ) + ); + } + + if (!args.member.user.bot) { + if (guild_object?.member_list.some((m, index) => { + if (m.id === args.member.id) { + guild_object.member_list.push(new MemberPrtl(args.member.id, 1, 0, 0, 0, null, false)); + return true; + } + })) { + return { result: true, value: 'member removed from guild' }; + } else { + return { result: false, value: 'member could not be removed' }; + } + } + + return { result: true, value: 'member is a bot, no action taken for fellow workers' }; +}; \ No newline at end of file diff --git a/src/events/guildMemberRemove.js b/src/events/guildMemberRemove.js deleted file mode 100644 index ce70d7a8..00000000 --- a/src/events/guildMemberRemove.js +++ /dev/null @@ -1,20 +0,0 @@ -const help_mngr = require('../functions/help_manager'); - -module.exports = async (args) => { - const leave_message = `member: ${args.member.presence.user}\n` + - `id: ${args.member.guild.id}\n` + - `left: ${args.member.guild}.`; - - if (args.guild_list[args.member.guild.id] || !args.guild_list[args.member.guild.id].announcement) { - args.member.guild.channels.cache - .find(channel => channel.id === args.guild_list[args.member.guild.id].announcement) - .send(help_mngr.create_rich_embed('Member left', leave_message, '#FC0303', null, - args.member.user.avatarURL(), null, true, null, null)); - } - - if (!args.member.bot) { - delete args.guild_list[args.member.guild.id].member_list[args.member.id]; - } - - return { result: true, value: 'Member added to guild' }; -}; diff --git a/src/events/guildMemberRemove.ts b/src/events/guildMemberRemove.ts new file mode 100644 index 00000000..9b26fa3c --- /dev/null +++ b/src/events/guildMemberRemove.ts @@ -0,0 +1,40 @@ +import { GuildMember, TextChannel } from "discord.js"; +import { create_rich_embed, guildPrtl_to_object } from "../libraries/helpOps"; +import { GuildPrtl } from "../types/classes/GuildPrtl"; + +module.exports = async ( + args: { member: GuildMember, guild_list: GuildPrtl[] } +) => { + const leave_message = `member: ${args.member.presence.user}\n` + + `id: ${args.member.guild.id}\n` + + `left: ${args.member.guild}.`; + + const guild_object = guildPrtl_to_object(args.guild_list, args.member.guild.id); + if (guild_object && guild_object.announcement) { + const announcement_channel = args.member.guild.channels.cache + .find(channel => channel.id === guild_object.announcement) + + if (announcement_channel) + (announcement_channel).send( + create_rich_embed( + 'member left', leave_message, '#FC0303', [], + args.member.user.avatarURL(), null, true, null, null + ) + ); + } + + if (!args.member.user.bot) { + if (guild_object?.member_list.some((m, index) => { + if (m.id === args.member.id) { + guild_object.member_list.splice(index, 1); + return true; + } + })) { + return { result: true, value: 'member removed from guild' }; + } else { + return { result: false, value: 'member could not be removed' }; + } + } + + return { result: true, value: 'member is a bot, no action taken for fellow workers' }; +}; diff --git a/src/events/messageDelete.js b/src/events/messageDelete.js deleted file mode 100644 index bb4b06a5..00000000 --- a/src/events/messageDelete.js +++ /dev/null @@ -1,33 +0,0 @@ -const help_mngr = require('../functions/help_manager'); - -module.exports = async (args) => { - const current_channel = args.guild_list[args.message.guild.id]; - const role_list = args.guild_list[args.message.guild.id].role_list; - const music_data = args.guild_list[args.message.guild.id].music_data; - const portal_icon_url = 'https://raw.githubusercontent.com/keybraker/keybraker' + - '.github.io/master/assets/img/logo.png'; - - if (role_list[args.message.id]) { - delete role_list[args.message.id]; - help_mngr.update_portal_managed_guilds(true, args.portal_managed_guilds_path, args.guild_list); - - return { - result: true, - value: 'role message was deleted and successfully removed from json', - }; - } - - if (music_data.message_id === args.message.id) { - help_mngr.create_music_message( - args.message.guild.channels.cache.find(channel => - channel.id === current_channel.music_data.channel_id), - portal_icon_url, - args.guild_list[args.message.guild.id], - ); - - return { - result: true, - value: 'music message has been created again', - }; - } -}; \ No newline at end of file diff --git a/src/events/messageDelete.ts b/src/events/messageDelete.ts new file mode 100644 index 00000000..56e337a9 --- /dev/null +++ b/src/events/messageDelete.ts @@ -0,0 +1,50 @@ +import { Message, TextChannel } from "discord.js"; +import { create_music_message } from "../libraries/helpOps"; +import { GuildPrtl } from "../types/classes/GuildPrtl"; + +module.exports = async ( + args: { guild_list: GuildPrtl[], message: Message } +) => { + if (!args.message.guild) return { result: true, value: 'message guild could not be found' }; + + const guild_object = args.guild_list.find(g => { + if (args.message.guild) + return g.id === args.message.guild.id; + }); + if (!guild_object) return { result: true, value: 'message could not be found' }; + + const role_list = guild_object.role_list; + const music_data = guild_object.music_data; + const portal_icon_url = 'https://raw.githubusercontent.com/keybraker/keybraker' + + '.github.io/master/assets/img/logo.png'; + + const role_list_object = role_list.find((r, index) => { + if (args.message.guild && r.message_id === args.message.id) { + role_list.splice(index, 1); + return true; + } + return false; + }); + if (role_list_object) return { + result: true, + value: 'role message was deleted and successfully removed from json' + }; + + if (music_data.message_id === args.message.id) { + const current_channel = args.message.guild.channels.cache.find(channel => + channel.id === guild_object.music_data.channel_id); + if (current_channel) { + create_music_message(current_channel, portal_icon_url, guild_object); + + return { + result: true, + value: 'music message has been created again', + }; + } else { + return { + result: false, + value: 'could not find channel', + }; + } + } +}; \ No newline at end of file diff --git a/src/events/messageReactionAdd.js b/src/events/messageReactionAdd.js deleted file mode 100644 index 3161c6de..00000000 --- a/src/events/messageReactionAdd.js +++ /dev/null @@ -1,220 +0,0 @@ -const musc_mngr = require('../functions/music_manager'); - -const clear_user_reactions = function(args) { - args.messageReaction.message.reactions.cache - .forEach(reaction => reaction.users.remove(args.user.id)); -}; - -const reaction_role_manager = function(args) { - const current_guild = args.guild_list[args.messageReaction.message.guild.id]; - if (!current_guild.role_list[args.messageReaction.message.id]) { - return { result: null, value: 'message is not role giving' }; - } - const current_role_list = current_guild.role_list[args.messageReaction.message.id]; - const current_role_map = current_role_list.role_emote_map; - const current_member = args.messageReaction.message.guild.members.cache - .find(member => member.id === args.user.id); - - for(let i = 0; current_role_map.length; i++) { - if(current_role_map[i].give === args.messageReaction.emoji.name) { // give role - if (!args.messageReaction.message.guild.roles.cache.has(current_role_map[i].id)) { // guild has role - clear_user_reactions(args); - return { result: false, value: `role ${current_role_map[i].give} does not exist` }; - } - if (current_member.roles.cache.has(current_role_map[i].id)) { // member has role - clear_user_reactions(args); - return { result: false, value: `you already have role ${current_role_map[i].give}` }; - } - - const role = args.messageReaction.message.guild.roles.cache - .find(cached_role => cached_role.id === current_role_map[i].id); - - try { - args.messageReaction.message.guild.members.cache - .find(member => member.id === args.user.id) - .roles - .add(role); - } - catch (error) { - clear_user_reactions(args); - return { result: false, value: `failed to add role ${current_role_map[i].give}` }; - } - - clear_user_reactions(args); - return { result: true, value: `you have been added to role ${current_role_map[i].give}` }; - - } - else if (current_role_map[i].strip === args.messageReaction.emoji.name) { - - if (!args.messageReaction.message.guild.roles.cache.has(current_role_map[i].id)) { // guild has role - clear_user_reactions(args); - return { result: false, value: `role ${current_role_map[i].strip} does not exist` }; - } - if (!current_member.roles.cache.has(current_role_map[i].id)) { // member does not has role - clear_user_reactions(args); - return { result: false, value: `you do not have role ${current_role_map[i].strip}` }; - } - - const role = args.messageReaction.message.guild.roles.cache - .find(cached_role => cached_role.id === current_role_map[i].id); - - try { - args.messageReaction.message.guild.members.cache - .find(member => member.id === args.user.id) - .roles - .remove(role); - } - catch (error) { - clear_user_reactions(args); - return { result: false, value: `failed to remove role ${current_role_map[i].strip}` }; - } - - clear_user_reactions(args); - return { result: true, value: `you have been striped from role ${current_role_map[i].strip}` }; - } - } -}; - -const reaction_music_manager = function(args) { - const current_guild = args.guild_list[args.messageReaction.message.guild.id]; - let voice_connection_in_reaction_guild = null; - - if(args.messageReaction.emoji.name !== '📜' && args.messageReaction.emoji.name !== '❌') { - if (current_guild.music_data.message_id !== args.messageReaction.message.id) { - return { result: null, value: 'message is not music player' }; - } - voice_connection_in_reaction_guild = args.client.voice.connections.find(connection => - connection.channel.guild.id === args.messageReaction.message.guild.id, - ); - if (!voice_connection_in_reaction_guild) { - clear_user_reactions(args); - return { result: false, value: 'portal is not playing music write now' }; - } - const is_member_in_same_channel_as_portal = voice_connection_in_reaction_guild.channel.members - .some(member => { - console.log(member.id ,' === ' , args.user.id); - return member.id === args.user.id; - }); - if (!is_member_in_same_channel_as_portal) { - clear_user_reactions(args); - return { result: false, value: 'you must be in the same channel with portal to control music' }; - } - } - const return_value = { result: true, value: '' }; - - switch(args.messageReaction.emoji.name) { - case '▶️' : { - return_value.value = 'resuming player'; - musc_mngr.play(args.messageReaction.message.guild.id, args.guild_list, - args.client, args.messageReaction.message.guild); - break; - } - case '⏸' : { - return_value.value = 'pausing player'; - musc_mngr.pause(args.messageReaction.message.guild.id, args.guild_list); - break; - } - case '⏹' : { - if(current_guild.dispatcher !== null && current_guild.dispatcher !== undefined) { - return_value.value = 'player is not connected'; - break; - } - if(!current_guild.music_data.votes.includes(args.user.id)) { - current_guild.music_data.votes.push(args.user.id); - } - - const votes = current_guild.music_data.votes.length; - const users = voice_connection_in_reaction_guild.channel.members - .filter(member => !member.user.bot).size; - - if (votes >= users / 2) { - return_value.value = 'stopping player (majority)'; - musc_mngr.stop(args.messageReaction.message.guild.id, args.guild_list, - args.messageReaction.message.guild); - current_guild.music_data.votes = []; - } - else if (args.user.presence.member.hasPermission('ADMINISTRATOR')) { - return_value.value = 'stopping player (admin)'; - musc_mngr.stop(args.messageReaction.message.guild.id, args.guild_list, - args.messageReaction.message.guild); - current_guild.music_data.votes = []; - } - else { - return_value.value = `${votes}/${users / 2} (majority or admin authorization needed to stop)`; - } - break; - } - case '⏭' : { - if(current_guild.dispatcher !== null && current_guild.dispatcher !== undefined) { - return_value.value = 'player is not connected'; - break; - } - if(!current_guild.music_data.votes.includes(args.user.id)) { - current_guild.music_data.votes.push(args.user.id); - } - - const votes = current_guild.music_data.votes.length; - const users = voice_connection_in_reaction_guild.channel.members - .filter(member => !member.user.bot).size; - - if (votes >= users / 2) { - return_value.value = 'skipping video (majority)'; - musc_mngr.skip(args.messageReaction.message.guild.id, args.guild_list, - args.client, args.messageReaction.message.guild); - current_guild.music_data.votes = []; - } - else if (args.user.presence.member.hasPermission('ADMINISTRATOR')) { - return_value.value = 'skipping video (admin)'; - musc_mngr.skip(args.messageReaction.message.guild.id, args.guild_list, - args.client, args.messageReaction.message.guild); - current_guild.music_data.votes = []; - } - else { - return_value.value = `${votes}/${users / 2} (majority or admin authorization needed to skip)`; - } - break; - } - case '📜' : { - const current_music_queue = args.guild_list[args.messageReaction.message.guild.id].music_queue; - const music_queue = current_music_queue.length > 0 - ? '\n' + current_music_queue.map((video, i) => `${i + 1}. **${video.title}`).join('**\n').toString() + '**' - : ' empty'; - return_value.value = `Music queue:${music_queue}`; - break; - } - case '❌' : { - args.guild_list[args.messageReaction.message.guild.id].music_queue = []; - return_value.value = 'Music queue: has been cleared.'; - break; - } - } - - clear_user_reactions(args); - return return_value; -}; - -module.exports = async (args) => { - if(args.user.bot) return null; - - if (args.messageReaction.partial) { - try { - await args.messageReaction.fetch(); - } - catch (error) { - return { - result: false, - value: 'Something went wrong when fetching the message: ' + error, - }; - } - } - - const return_value_role = reaction_role_manager(args); - if(return_value_role.result !== null) { - return return_value_role; - } - - const return_value_music = reaction_music_manager(args); - if(return_value_music.result !== null) { - return return_value_music; - } -}; \ No newline at end of file diff --git a/src/events/messageReactionAdd.ts b/src/events/messageReactionAdd.ts new file mode 100644 index 00000000..a085aa8f --- /dev/null +++ b/src/events/messageReactionAdd.ts @@ -0,0 +1,237 @@ +import { Client, MessageReaction, User, VoiceConnection } from "discord.js"; +import { pause, play, skip, stop } from "../libraries/musicOps"; +import { GuildPrtl } from "../types/classes/GuildPrtl"; +import { ReturnPormise } from "../types/interfaces/InterfacesPrtl"; +import { get_role } from "../libraries/guildOps"; + +function clear_user_reactions(client: Client, guild_list: GuildPrtl[], messageReaction: MessageReaction, user: User) { + messageReaction.message.reactions.cache.forEach(reaction => reaction.users.remove(user.id)); +}; + +function reaction_role_manager(client: Client, guild_list: GuildPrtl[], messageReaction: MessageReaction, user: User): ReturnPormise { + if (!messageReaction.message.guild) return { result: false, value: 'message has no guild' }; + const guild_object = guild_list.find(g => { + if (messageReaction && messageReaction.message && messageReaction.message.guild) + return g.id === messageReaction.message.guild.id; + return false; + }); + if (!guild_object) return { result: false, value: 'message is not role giving' }; + + const role_list_object = guild_object.role_list.find(r => { + return r.message_id === messageReaction.message.id; + }); + + if (!role_list_object) return { result: false, value: 'is not a role giving message' }; + + const current_member = messageReaction.message.guild.members.cache.find(member => member.id === user.id); + if (!current_member) return { result: false, value: 'could not find member' }; + + let result = false; + let value = 'failed to give role'; + + const found_role = role_list_object.role_emote_map.some(role_map => { + if (messageReaction.message.guild) { + if (role_map.give === messageReaction.emoji.name) { // give role + const role_to_give = get_role(messageReaction?.message?.guild, role_map.role_id); + if (role_to_give) { + try { + current_member.roles.add(role_to_give); + result = true; + value = `you have been assigned to ${role_map.role_id}`; + } + catch (error) { + clear_user_reactions(client, guild_list, messageReaction, user); + result = false; + value = `failed to assign you, to role ${role_map.role_id}`; + } + return true; + } + } else if (role_map.strip === messageReaction.emoji.name) { + const role_to_strip = get_role(messageReaction?.message?.guild, role_map.role_id); + if (role_to_strip) { + try { + current_member.roles.remove(role_to_strip); + result = true; + value = `you have been stripped off ${role_map.role_id}`; + } + catch (error) { + clear_user_reactions(client, guild_list, messageReaction, user); + result = false; + value = `failed to strip role ${role_map.role_id}`; + } + return true; + } + } // gave other emote + } + return false; + }); + + if (found_role) + return { result: result, value: value }; + else + return { result: false, value: 'could not find role' }; +}; + +function reaction_music_manager(client: Client, guild_list: GuildPrtl[], messageReaction: MessageReaction, user: User) { + if (!messageReaction.message.guild) return { result: false, value: 'message has no guild' }; + if (!client.voice) return { result: false, value: 'message has no client' }; + + const guild_object = guild_list.find(g => { + if (messageReaction && messageReaction.message && messageReaction.message.guild) + return g.id === messageReaction.message.guild.id; + }); + if (!guild_object) return { result: false, value: 'message is not role giving' }; + if (!guild_object.music_data) return { result: false, value: 'message has no music_data' }; + if (!guild_object.music_data.votes) guild_object.music_data.votes = []; + if (guild_object.music_data.message_id !== messageReaction.message.id) { + return { result: false, value: 'message is not music player' }; + } + + let voice_connection_in_reaction_guild: VoiceConnection | undefined = undefined; + + if (messageReaction.emoji.name !== '📜' && messageReaction.emoji.name !== '❌') { + if (guild_object.music_data.message_id !== messageReaction.message.id) { + return { result: false, value: 'message is not music player' }; + } + voice_connection_in_reaction_guild = client.voice.connections.find((connection: VoiceConnection) => { + if (!messageReaction.message || !messageReaction.message.guild) return false; + return connection.channel.guild.id === messageReaction.message.guild.id; + }); + if (!voice_connection_in_reaction_guild) { + clear_user_reactions(client, guild_list, messageReaction, user); + return { result: false, value: 'portal is not playing music write now' }; + } + const is_member_in_same_channel_as_portal = voice_connection_in_reaction_guild.channel.members + .some(member => { + return member.id === user.id; + }); + if (!is_member_in_same_channel_as_portal) { + clear_user_reactions(client, guild_list, messageReaction, user); + return { result: false, value: 'you must be in the same channel with portal to control music' }; + } + } + const return_value = { result: true, value: '' }; + + switch (messageReaction.emoji.name) { + case '▶️': { + return_value.value = 'resuming player'; + play(messageReaction.message.guild.id, guild_list, + client, messageReaction.message.guild); + break; + } + case '⏸': { + return_value.value = 'pausing player'; + pause(messageReaction.message.guild.id, guild_list); + break; + } + case '⏹': { + if (!voice_connection_in_reaction_guild) { + return_value.value = 'could not find voice connection'; + break; + } + if (guild_object.dispatcher !== null && guild_object.dispatcher !== undefined) { + return_value.value = 'player is not connected'; + break; + } + if (!guild_object.music_data.votes.includes(user.id)) { + guild_object.music_data.votes.push(user.id); + } + + const votes = guild_object.music_data.votes.length; + const users = voice_connection_in_reaction_guild?.channel.members + .filter(member => !member.user.bot).size; + + if (votes >= users / 2) { + return_value.value = 'stopping player (majority)'; + stop(messageReaction.message.guild.id, guild_list, + messageReaction.message.guild); + guild_object.music_data.votes = []; + } + else if (user.presence?.member?.hasPermission('ADMINISTRATOR')) { + return_value.value = 'stopping player (admin)'; + stop(messageReaction.message.guild.id, guild_list, + messageReaction.message.guild); + guild_object.music_data.votes = []; + } + else { + return_value.value = `${votes}/${users / 2} (majority or admin authorization needed to stop)`; + } + break; + } + case '⏭': { + if (!voice_connection_in_reaction_guild) { + return_value.value = 'could not find voice connection'; + break; + } + if (!guild_object.dispatcher) { + return_value.value = 'player is not connected'; + break; + } + if (!guild_object.music_data.votes.includes(user.id)) { + guild_object.music_data.votes.push(user.id); + } + + const votes = guild_object.music_data.votes.length; + const users = voice_connection_in_reaction_guild.channel.members + .filter(member => !member.user.bot).size; + + if (votes >= users / 2) { + return_value.value = 'skipping video (majority)'; + skip(messageReaction.message.guild.id, guild_list, + client, messageReaction.message.guild); + guild_object.music_data.votes = []; + } + else if (user.presence?.member?.hasPermission('ADMINISTRATOR')) { + return_value.value = 'skipping video (admin)'; + skip(messageReaction.message.guild.id, guild_list, + client, messageReaction.message.guild); + guild_object.music_data.votes = []; + } + else { + return_value.value = `${votes}/${users / 2} (majority or admin authorization needed to skip)`; + } + break; + } + case '📜': { + const current_music_queue = guild_object.music_queue; + const music_queue = current_music_queue.length > 0 + ? '\n' + current_music_queue.map((video, i) => `${i + 1}. **${video.title}`).join('**\n').toString() + '**' + : ' empty'; + return_value.value = `Music queue:${music_queue}`; + break; + } + case '❌': { + guild_object.music_queue = []; + return_value.value = 'Music queue: has been cleared.'; + break; + } + } + + clear_user_reactions(client, guild_list, messageReaction, user); + return return_value; +}; + +module.exports = async ( + args: { client: Client, guild_list: GuildPrtl[], messageReaction: MessageReaction, user: User } +) => { + return new Promise((resolve) => { + if (args.user.bot) return resolve({ result: false, value: '' }); + + if (args.messageReaction.partial) { + try { + args.messageReaction.fetch(); + } catch (error) { + return resolve({ + result: false, + value: 'Something went wrong when fetching the message: ' + error, + }); + } + } + + const return_value_role = reaction_role_manager(args.client, args.guild_list, args.messageReaction, args.user); + if (return_value_role.result) return resolve(return_value_role); + + const return_value_music = reaction_music_manager(args.client, args.guild_list, args.messageReaction, args.user); + return resolve(return_value_music); + }); +}; \ No newline at end of file diff --git a/src/events/presenceUpdate.js b/src/events/presenceUpdate.js deleted file mode 100644 index 5507fa79..00000000 --- a/src/events/presenceUpdate.js +++ /dev/null @@ -1,97 +0,0 @@ -const guld_mngr = require('./../functions/guild_manager'); -const lclz_mngr = require('./../functions/localization_manager'); -const help_mngr = require('./../functions/help_manager'); - -const update_channel_name = function(current_voice_channel, current_guild, current_channel, current_portal_list, args) { - switch (guld_mngr.generate_channel_name(current_channel, current_portal_list, - args.guild_list[current_guild.id], current_guild)) { - case 1: - current_voice_channel.last_update = Date.now(); - break; - case 2: - console.log('new name channel is the same as old'); - break; - case 3: - console.log('new channel name is empty'); - break; - default: - break; - } -}; - -const time_out_repeat = function(current_voice_channel, current_guild, current_channel, current_portal_list, args, mins) { - setTimeout(() => { - update_channel_name(current_voice_channel, current_guild, current_channel, current_portal_list, args); - time_out_repeat(current_voice_channel, current_guild, current_channel, current_portal_list, args, mins); - }, mins * 60 * 1000); -}; - -const display_spotify_song = function(current_guild, current_channel, args) { - current_channel.members.forEach(member => { - member.presence.activities.some(activity => { - if (activity.name === 'Spotify') { - const spotify = args.newPresence.guild.channels.cache.find(channel => - channel.id === args.guild_list[current_guild.id].spotify); - - if (spotify) { - lclz_mngr.client_talk(args.client, args.guild_list, 'spotify'); - spotify.send(help_mngr.create_rich_embed( - `**${activity.details}**`, - '', - '#1DB954', - [ - { - emote: 'Artist', - role: `***${activity.state}***`, - inline: false, - }, - { - emote: 'Album', - role: `***${activity.assets.largeText}***`, - inline: false, - }, - ], - activity.assets.largeImageURL(), - member, - false, - )); - } - } - }); - }); -}; - -module.exports = async (args) => { - if (args.newPresence.user.bot) {return { result: true, value: 'not handling bot presence update' };} - - const current_guild = args.newPresence.guild; - const current_channel = args.newPresence.member.voice.channel; - - if (!guld_mngr.included_in_portal_guilds(args.newPresence.guild.id, args.guild_list)) { - return { - result: false, - value: lclz_mngr - .client_log(current_guild.id, null, args.guild_list, 'presence_controlled_away', args), - }; - } - - if (current_channel) { // if member is in a channel - const current_portal_list = args.guild_list[current_guild.id].portal_list; - for (const key in args.guild_list[current_guild.id].portal_list) { - const current_voice_channel = current_portal_list[key].voice_list[current_channel.id]; - - if (current_voice_channel) { - if (args.guild_list[current_guild.id].spotify !== null) { - display_spotify_song(current_guild, current_channel, args); - } - - time_out_repeat(current_voice_channel, current_guild, current_channel, current_portal_list, args, 5); - } - } - } - - return { - result: true, - value: lclz_mngr.client_log(current_guild.id, null, args.guild_list, 'presence_controlled', args), - }; -}; \ No newline at end of file diff --git a/src/events/presenceUpdate.ts b/src/events/presenceUpdate.ts new file mode 100644 index 00000000..ce14931b --- /dev/null +++ b/src/events/presenceUpdate.ts @@ -0,0 +1,130 @@ +import { Client, Guild, Presence, TextChannel, VoiceChannel } from "discord.js"; +import { generate_channel_name, included_in_portal_guilds } from "../libraries/guildOps"; +import { create_rich_embed } from "../libraries/helpOps"; +import { client_log, client_talk } from "../libraries/localizationOps"; +import { GuildPrtl } from "../types/classes/GuildPrtl"; +import { PortalChannelPrtl } from "../types/classes/PortalChannelPrtl"; +import { VoiceChannelPrtl } from "../types/classes/VoiceChannelPrtl"; + +function update_channel_name(current_guild: Guild, + current_channel: VoiceChannel, current_portal_list: PortalChannelPrtl[], guild_list: GuildPrtl[]) { + const guild_object = guild_list.find(g => g.id === current_guild.id); + if (!guild_object) return; + + switch (generate_channel_name(current_channel, current_portal_list, guild_object, current_guild)) { + case 1: + // current_voice_channel.last_update = Date.now(); + break; + case 2: + console.log('new name channel is the same as old'); + break; + case 3: + console.log('new channel name is empty'); + break; + default: + break; + } +}; + +function time_out_repeat(current_voice_channel: VoiceChannelPrtl, current_guild: Guild, + current_channel: VoiceChannel, current_portal_list: PortalChannelPrtl[], guild_list: GuildPrtl[], minutes: number) { + setTimeout(() => { + update_channel_name(current_guild, current_channel, current_portal_list, guild_list); + time_out_repeat(current_voice_channel, current_guild, current_channel, current_portal_list, guild_list, minutes); + }, minutes * 60 * 1000); +}; + +function display_spotify_song( + current_guild: Guild, current_channel: VoiceChannel, + guild_list: GuildPrtl[], newPresence: Presence, client: Client +) { + console.log('eimai edo\n\n'); + current_channel.members.forEach(member => { + console.log('member :>> ', member); + member.presence.activities.some(activity => { + console.log('activity.name :>> ', activity.name); + if (activity.name === 'Spotify' && newPresence.guild) { + const spotify = newPresence.guild.channels.cache.find(c => { + const guild_object = guild_list.find(g => g.id === current_guild.id); + if (guild_object === undefined) return false; + return c.id === guild_object.spotify; + }); + + if (spotify) { + client_talk(client, guild_list, 'spotify'); + spotify.send( + create_rich_embed( + `**${activity.details}**`, + '', + '#1DB954', + [ + { + emote: 'Artist', + role: `${activity.state}`, + inline: false, + }, + { + emote: 'Album', + role: `${activity.assets?.largeText}`, + inline: false, + }, + ], + activity.assets ? activity.assets.largeImageURL() : null, + member, + false, + null, + null + ) + ); + } + } + }); + }); +}; + +module.exports = async ( + args: { client: Client, guild_list: GuildPrtl[], newPresence: Presence | undefined } +) => { + if (args.newPresence === null) { return { result: true, value: 'could not fetch presence' }; } + if (args.newPresence === undefined) { return { result: true, value: 'could not fetch presence' }; } + if (args.newPresence.user === null) { return { result: true, value: 'could not fetch presence user' }; } + if (args.newPresence.member === null) { return { result: true, value: 'could not fetch presence member' }; } + if (args.newPresence.guild === null) { return { result: true, value: 'could not fetch presence guild' }; } + if (args.newPresence.user.bot) { return { result: true, value: 'not handling bot presence update' }; } + + const current_guild = args.newPresence.guild; + const current_channel = args.newPresence.member.voice.channel; + + if (!included_in_portal_guilds(args.newPresence.guild.id, args.guild_list)) { + return { + result: false, + value: client_log(null, args.guild_list, 'presence_controlled_away', args.guild_list), + }; + } + + if (current_channel) { // if member is in a channel + const guild_object = args.guild_list.find(g => g.id === current_guild.id); + if (!guild_object) return; + guild_object.portal_list.some(p => { + p.voice_list.some(v => { + if (v.id === current_channel.id) { + if (guild_object.spotify !== null && args.newPresence) { + display_spotify_song(current_guild, current_channel, args.guild_list, + args.newPresence, args.client); + } + + time_out_repeat(v, current_guild, current_channel, guild_object.portal_list, + args.guild_list, 5); + } + }); + }); + } + + return { + result: true, + value: client_log(null, args.guild_list, 'presence_controlled', { + 'a': args.newPresence.member.displayName, + 'b': args.newPresence.guild.name + }), + }; +}; \ No newline at end of file diff --git a/src/events/ready.js b/src/events/ready.js deleted file mode 100644 index 00e6ee28..00000000 --- a/src/events/ready.js +++ /dev/null @@ -1,15 +0,0 @@ -const lclz_mngr = require('./../functions/localization_manager'); -const help_mngr = require('./../functions/help_manager'); - -module.exports = async (args) => { - // Changing Portal bots status - args.client.user.setActivity('./help', { url: 'https://github.com/keybraker', type: 'LISTENING' }); - console.log('Portal guilds: '); - args.client.guilds.cache.forEach(guild => { - console.log(`${guild} (${guild.id})`); - help_mngr.empty_channel_remover(guild, args.guild_list, args.portal_managed_guilds_path); - help_mngr - }); - - return { result: true, value: lclz_mngr.console.ready.en(args) }; -}; diff --git a/src/events/ready.ts b/src/events/ready.ts new file mode 100644 index 00000000..8c62c63b --- /dev/null +++ b/src/events/ready.ts @@ -0,0 +1,48 @@ +import { Client } from "discord.js"; +import { + update_portal_managed_guilds, remove_deleted_guild, + remove_deleted_channels, remove_empty_voice_channels +} from "../libraries/helpOps"; +import { console_text } from "../libraries/localizationOps"; +import { GuildPrtl } from "../types/classes/GuildPrtl"; + +module.exports = async ( + args: { client: Client, guild_list: GuildPrtl[], portal_managed_guilds_path: string } +) => { + if (args.client.user === null || args.client.user === undefined) return { + result: false, + value: 'could not fetch user from client' + } + + // Changing Portal bots status + args.client.user.setActivity('./help', { + url: 'https://github.com/keybraker', + type: 'LISTENING' + }); + + let index = 0; + console.log(`> loading portal\'s guilds from ${args.portal_managed_guilds_path}`); + args.client.guilds.cache.forEach((guild) => { + console.log(`> ${index++}. ${guild} (${guild.id})`); + + remove_deleted_guild(guild, args.guild_list); + remove_deleted_channels(guild, args.guild_list); + remove_empty_voice_channels(guild, args.guild_list); + + update_portal_managed_guilds(true, args.portal_managed_guilds_path, args.guild_list); + }); + console.log(''); + + return { + result: true, + value: console_text.some(ct => { + if (ct.name === 'ready') { + ct.lang.en({ + 'a': args.client.users.cache.size, + 'b': args.client.channels.cache.size, + 'c': args.client.guilds.cache.size + }); + } + }) + }; +}; diff --git a/src/events/shardReconnecting.js b/src/events/shardReconnecting.js deleted file mode 100644 index 06bbd06b..00000000 --- a/src/events/shardReconnecting.js +++ /dev/null @@ -1,3 +0,0 @@ -module.exports = async (args) => { - return { result: true, value: `Shard with ID ${args.id} reconnected.` }; -}; \ No newline at end of file diff --git a/src/events/shardResume.ts b/src/events/shardResume.ts new file mode 100644 index 00000000..23d10eae --- /dev/null +++ b/src/events/shardResume.ts @@ -0,0 +1,48 @@ +import { Client } from "discord.js"; +import { + remove_deleted_channels, remove_deleted_guild, + remove_empty_voice_channels, update_portal_managed_guilds +} from "../libraries/helpOps"; +import { console_text } from "../libraries/localizationOps"; +import { GuildPrtl } from "../types/classes/GuildPrtl"; + +module.exports = async ( + args: { client: Client, guild_list: GuildPrtl[], portal_managed_guilds_path: string, id: string } +) => { + if (args.client.user === null || args.client.user === undefined) + return { result: false, value: 'could not fetch user from client' }; + + // Changing Portal bots status + args.client.user.setActivity('./help', { + url: 'https://github.com/keybraker', + type: 'LISTENING' + }); + + let index = 0; + const guild = args.client.guilds.cache.find(g => g.id === args.id); + if (!guild) + return { result: false, value: 'could not fetch user from client' }; + + console.log(`> loading portal\'s guilds: ${args.id}`); + console.log(`> ${guild} (${guild.id})`); + + remove_deleted_guild(guild, args.guild_list); + remove_deleted_channels(guild, args.guild_list); + remove_empty_voice_channels(guild, args.guild_list); + + update_portal_managed_guilds(true, args.portal_managed_guilds_path, args.guild_list); + console.log(''); + + return { + result: true, + value: console_text.some(ct => { + if (ct.name === 'ready') { + ct.lang.en({ + 'a': args.client.users.cache.size, + 'b': args.client.channels.cache.size, + 'c': args.client.guilds.cache.size + }); + } + }) + }; +}; \ No newline at end of file diff --git a/src/events/shardStart.ts b/src/events/shardStart.ts new file mode 100644 index 00000000..23d10eae --- /dev/null +++ b/src/events/shardStart.ts @@ -0,0 +1,48 @@ +import { Client } from "discord.js"; +import { + remove_deleted_channels, remove_deleted_guild, + remove_empty_voice_channels, update_portal_managed_guilds +} from "../libraries/helpOps"; +import { console_text } from "../libraries/localizationOps"; +import { GuildPrtl } from "../types/classes/GuildPrtl"; + +module.exports = async ( + args: { client: Client, guild_list: GuildPrtl[], portal_managed_guilds_path: string, id: string } +) => { + if (args.client.user === null || args.client.user === undefined) + return { result: false, value: 'could not fetch user from client' }; + + // Changing Portal bots status + args.client.user.setActivity('./help', { + url: 'https://github.com/keybraker', + type: 'LISTENING' + }); + + let index = 0; + const guild = args.client.guilds.cache.find(g => g.id === args.id); + if (!guild) + return { result: false, value: 'could not fetch user from client' }; + + console.log(`> loading portal\'s guilds: ${args.id}`); + console.log(`> ${guild} (${guild.id})`); + + remove_deleted_guild(guild, args.guild_list); + remove_deleted_channels(guild, args.guild_list); + remove_empty_voice_channels(guild, args.guild_list); + + update_portal_managed_guilds(true, args.portal_managed_guilds_path, args.guild_list); + console.log(''); + + return { + result: true, + value: console_text.some(ct => { + if (ct.name === 'ready') { + ct.lang.en({ + 'a': args.client.users.cache.size, + 'b': args.client.channels.cache.size, + 'c': args.client.guilds.cache.size + }); + } + }) + }; +}; \ No newline at end of file diff --git a/src/events/voiceStateUpdate.js b/src/events/voiceStateUpdate.js deleted file mode 100644 index d7c8b69f..00000000 --- a/src/events/voiceStateUpdate.js +++ /dev/null @@ -1,245 +0,0 @@ -const guld_mngr = require('./../functions/guild_manager'); -const lclz_mngr = require('./../functions/localization_manager'); -const help_mngr = require('./../functions/help_manager'); -const user_mngr = require('./../functions/user_manager'); -const musc_mngr = require('./../functions/music_manager'); - -module.exports = async (args) => { - if (args.newState === undefined || args.oldState == undefined) { - return { - result: true, value: 'state of undefined', - }; - } - - const newChannel = args.newState.channel; // join channel - const oldChannel = args.oldState.channel; // left channel - - if (oldChannel !== null && oldChannel !== undefined) { - if (newChannel !== null && newChannel !== undefined) { - if (newChannel.id === oldChannel.id) { - return { - result: true, value: 'changed voice state but remains in the same channel', - }; - } - } - } - - const newVoiceConnection = args.client.voice.connections - .find(connection => newChannel !== null && connection.channel.id === newChannel.id); - if (newVoiceConnection && !args.newState.member.user.bot) { - lclz_mngr.client_talk(args.client, args.guild_list, 'user_connected'); - } - - const oldVoiceConnection = args.client.voice.connections - .find(connection => oldChannel !== null && connection.channel.id === oldChannel.id); - if (oldVoiceConnection && !args.newState.member.user.bot) { - lclz_mngr.client_talk(args.client, args.guild_list, 'user_disconnected'); - } - - let report_message = `from: ${oldChannel} to ${newChannel}\n`; - - if (oldChannel === null) { - if (newChannel !== null) { // joined from null - report_message += 'null->existing\n'; - - if (guld_mngr.included_in_portal_list( - newChannel.id, args.guild_list[args.newState.guild.id].portal_list)) { // joined portal channel - - guld_mngr.create_voice_channel( - args.newState, args.guild_list[args.newState.guild.id].portal_list[newChannel.id], - newChannel, args.newState.id); - guld_mngr.generate_channel_name( - newChannel, - args.guild_list[args.newState.guild.id].portal_list, - args.guild_list[args.newState.guild.id], - args.newState.guild); - - } - else if (guld_mngr.included_in_voice_list( - newChannel.id, args.guild_list[args.newState.guild.id].portal_list)) { // joined voice channel - - guld_mngr.generate_channel_name( - newChannel, - args.guild_list[args.newState.guild.id].portal_list, - args.guild_list[args.newState.guild.id], - args.newState.guild); - user_mngr.update_timestamp(args.newState, args.guild_list); // points for voice - - } - else { // joined other channel - - user_mngr.update_timestamp(args.newState, args.guild_list); // points for other - - } - } - } - else if (oldChannel !== null) { // Left from existing - if (newChannel === null) { - report_message += 'existing->null\n'; - - if (guld_mngr.included_in_voice_list( - oldChannel.id, args.guild_list[args.newState.guild.id].portal_list)) { // user left voice channel - - if (oldChannel.members.size === 0) { - guld_mngr.delete_channel(oldChannel, null, true); - } - const voiceConnection = args.client.voice.connections - .find(connection => connection.channel.id === oldChannel.id); - - if (voiceConnection) { - if (oldChannel.members.size === 1) { - voiceConnection.disconnect(); - guld_mngr.delete_channel(oldChannel, null, true); - musc_mngr.stop(args.newState.guild.id, args.guild_list, oldChannel.guild); - } - } - } - user_mngr.update_timestamp(args.newState, args.guild_list); // points calculation from any channel - } - else if (newChannel !== null) { // Moved from channel to channel - report_message += 'existing->existing\n'; - - if (guld_mngr.included_in_portal_list( - oldChannel.id, args.guild_list[args.newState.guild.id].portal_list)) { - - report_message += '->source: portal_list\n'; - - if (guld_mngr.included_in_voice_list( - newChannel.id, args.guild_list[args.newState.guild.id].portal_list)) { // has been handled before - - user_mngr.update_timestamp(args.newState, args.guild_list); // points from voice creation - - report_message += '->dest: voice_list\n'; - report_message += 'has been handled before\n'; - guld_mngr.generate_channel_name( - newChannel, - args.guild_list[args.newState.guild.id].portal_list, - args.guild_list[args.newState.guild.id], - args.newState.guild); - } - } - else if (guld_mngr.included_in_voice_list(oldChannel.id, args.guild_list[args.newState.guild.id].portal_list)) { - - report_message += '->source: voice_list\n'; - - if (guld_mngr.included_in_portal_list( - newChannel.id, args.guild_list[args.newState.guild.id].portal_list)) { // moved from voice to portal - - report_message += '->dest: portal_list\n'; - - if (oldChannel.members.size === 0) { - - guld_mngr.delete_channel( - oldChannel, null, true); - - } - const voiceConnection = args.client.voice.connections - .find(connection => connection.channel.id === oldChannel.id); - - if (voiceConnection) { - if (oldChannel.members.size === 1) { - voiceConnection.disconnect(); - guld_mngr.delete_channel(oldChannel, null, true); - musc_mngr.stop(args.newState.guild.id, args.guild_list, oldChannel.guild); - } - } - - guld_mngr.create_voice_channel( - args.newState, args.guild_list[args.newState.guild.id].portal_list[newChannel.id], - newChannel, args.newState.id); - guld_mngr.generate_channel_name( - newChannel, - args.guild_list[args.newState.guild.id].portal_list, - args.guild_list[args.newState.guild.id], - args.newState.guild); - } - else if (guld_mngr.included_in_voice_list(newChannel.id, args.guild_list[args.newState.guild.id].portal_list)) { // moved from voice to voice - - report_message += '->dest: voice_list\n'; - - if (oldChannel.members.size === 0) { - guld_mngr.delete_channel( - oldChannel, null, true); - } - - const voiceConnection = args.client.voice.connections - .find(connection => connection.channel.id === oldChannel.id); - - if (voiceConnection) { - if (oldChannel.members.size === 1) { - voiceConnection.disconnect(); - guld_mngr.delete_channel(oldChannel, null, true); - musc_mngr.stop(args.newState.guild.id, args.guild_list, oldChannel.guild); - } - } - - guld_mngr.generate_channel_name( - newChannel, - args.guild_list[args.newState.guild.id].portal_list, - args.guild_list[args.newState.guild.id], - args.newState.guild); - - } - else { // moved from voice to other - - report_message += '->dest: other\n'; - - if (oldChannel.members.size === 0) { - guld_mngr.delete_channel(oldChannel, null, true); - } - - const voiceConnection = args.client.voice.connections - .find(connection => connection.channel.id === oldChannel.id); - - if (voiceConnection) { - if (oldChannel.members.size === 1) { - voiceConnection.disconnect(); - guld_mngr.delete_channel(oldChannel, null, true); - musc_mngr.stop(args.newState.guild.id, args.guild_list, oldChannel.guild); - } - - } - - guld_mngr.generate_channel_name( - newChannel, - args.guild_list[args.newState.guild.id].portal_list, - args.guild_list[args.newState.guild.id], - args.newState.guild); - } - } - else { - report_message += '->source: other voice\n'; - - if (guld_mngr.included_in_portal_list( - newChannel.id, args.guild_list[args.newState.guild.id].portal_list)) { // Joined portal channel - report_message += '->dest: portal_list\n'; - - guld_mngr.create_voice_channel( - args.newState, args.guild_list[args.newState.guild.id].portal_list[newChannel.id], - newChannel, args.newState.id); - guld_mngr.generate_channel_name( - newChannel, - args.guild_list[args.newState.guild.id].portal_list, - args.guild_list[args.newState.guild.id], - args.newState.guild); - - } - else if (guld_mngr.included_in_voice_list( - newChannel.id, args.guild_list[args.newState.guild.id].portal_list)) { // left created channel and joins another created - report_message += '->dest: voice_list\n'; - - guld_mngr.generate_channel_name( - newChannel, - args.guild_list[args.newState.guild.id].portal_list, - args.guild_list[args.newState.guild.id], - args.newState.guild); - } - } - } - } - - help_mngr.update_portal_managed_guilds(true, args.portal_managed_guilds_path, args.guild_list); - report_message += '\n'; - - return { result: true, value: report_message }; -}; diff --git a/src/events/voiceStateUpdate.ts b/src/events/voiceStateUpdate.ts new file mode 100644 index 00000000..c4a88496 --- /dev/null +++ b/src/events/voiceStateUpdate.ts @@ -0,0 +1,295 @@ +import { Client, VoiceChannel, VoiceConnection, VoiceState, TextChannel, Message } from "discord.js"; +import { create_voice_channel, generate_channel_name, included_in_portal_list, included_in_voice_list } from "../libraries/guildOps"; +import { update_portal_managed_guilds } from "../libraries/helpOps"; +import { client_talk } from "../libraries/localizationOps"; +import { stop } from "../libraries/musicOps"; +import { update_timestamp } from "../libraries/userOps"; +import { GuildPrtl } from "../types/classes/GuildPrtl"; +import { ReturnPormise } from "../types/interfaces/InterfacesPrtl"; + +async function delete_channel( + channel: VoiceChannel | TextChannel, guild_list: GuildPrtl[] +): Promise { + return new Promise((resolve) => { + const deleted = guild_list.some(g => + g.portal_list.some(p => + p.voice_list.some((v, index) => { + if (v.id === channel.id) { + if (channel.deletable) { + channel + .delete() + .then(g => { + p.voice_list.splice(index, 1); + console.log(`Deleted channel: ${channel.name} (${channel.id}) from ${channel.guild.name}`); + }) + .catch(console.error); + } + return true; + } + return false + }) + ) + ); + + if (!deleted) + return resolve({ result: true, value: 'failed to delete channel' }); + return resolve({ result: true, value: 'updated portal guild json' }); + }); +} + +function from_null( + new_channel: VoiceChannel | null, guild_list: GuildPrtl[], guild_object: GuildPrtl, + newState: VoiceState +): ReturnPormise { + let report_message = ''; + + // joined from null + if (new_channel) { + report_message += 'null->existing\n'; + + // joined portal channel + if (included_in_portal_list(new_channel.id, guild_object.portal_list)) { + const portal_object = guild_object.portal_list.find(p => p.id === new_channel.id); + if (!portal_object) return { result: false, value: 'error with data' }; + + create_voice_channel(newState, portal_object, new_channel, newState.id) + .then(response => { + if (!response.result) return response; + generate_channel_name(new_channel, guild_object.portal_list, guild_object, newState.guild); + }) + .catch(error => { return { result: false, value: error }; }); + } + // joined voice channel + else if (included_in_voice_list(new_channel.id, guild_object.portal_list)) { + generate_channel_name(new_channel, guild_object.portal_list, guild_object, newState.guild); + update_timestamp(newState, guild_list); // points for voice + } + else { // joined other channel + update_timestamp(newState, guild_list); // points for other + } + } else { + return { result: false, value: 'FN/VU/000: from null to null' }; + } + + return { result: true, value: report_message }; +} + +function from_existing( + old_channel: VoiceChannel, new_channel: VoiceChannel | null, client: Client, + guild_list: GuildPrtl[], guild_object: GuildPrtl, newState: VoiceState +): ReturnPormise { + let report_message = ''; + + if (new_channel === null) { + report_message += 'existing->null\n'; + + // user left voice channel + if (included_in_voice_list(old_channel.id, guild_object.portal_list)) { + + if (old_channel.members.size === 0) { + delete_channel(old_channel, guild_list) + .then(response => { return response; }); + } + + if (client.voice) { + const voice_connection = client.voice.connections + .find((connection: VoiceConnection) => connection.channel.id === old_channel.id); + + if (voice_connection) { + if (old_channel.members.size === 1) { + voice_connection.disconnect(); + delete_channel(old_channel, guild_list) + .then(response => { return response; }); + stop(newState.guild.id, guild_list, old_channel.guild); + } + } + } + } + update_timestamp(newState, guild_list); // points calculation from any channel + } + else if (new_channel !== null) { // Moved from channel to channel + report_message += 'existing->existing\n'; + + if (included_in_portal_list(old_channel.id, guild_object.portal_list)) { + + report_message += '->source: portal_list\n'; + + if (included_in_voice_list( + new_channel.id, guild_object.portal_list)) { // has been handled before + + update_timestamp(newState, guild_list); // points from voice creation + + report_message += '->dest: voice_list\n'; + report_message += 'has been handled before\n'; + generate_channel_name(new_channel, guild_object.portal_list, guild_object, newState.guild); + } + } + else if (included_in_voice_list(old_channel.id, guild_object.portal_list)) { + + report_message += '->source: voice_list\n'; + + if (included_in_portal_list( + new_channel.id, guild_object.portal_list)) { // moved from voice to portal + + report_message += '->dest: portal_list\n'; + + if (old_channel.members.size === 0) { + delete_channel(old_channel, guild_list) + .then(response => { return response; }); + } + + if (client.voice) { + const voice_connection = client.voice.connections + .find((connection: VoiceConnection) => connection.channel.id === old_channel.id); + + if (voice_connection) { + if (old_channel.members.size === 1) { + voice_connection.disconnect(); + delete_channel(old_channel, guild_list) + .then(response => { return response; }); + stop(newState.guild.id, guild_list, old_channel.guild); + } + } + } + + const portal_object = guild_object.portal_list.find(p => p.id === new_channel.id); + if (!portal_object) return { result: false, value: 'error with data' }; + + create_voice_channel(newState, portal_object, new_channel, newState.id) + .then(response => { + if (!response.result) return response; + generate_channel_name(new_channel, guild_object.portal_list, guild_object, newState.guild); + }) + .catch(error => { return { result: false, value: error }; }); + } + else if (included_in_voice_list(new_channel.id, guild_object.portal_list)) { // moved from voice to voice + + report_message += '->dest: voice_list\n'; + + if (old_channel.members.size === 0) { + delete_channel(old_channel, guild_list) + .then(response => { return response; }); + } + if (client.voice) { + const voiceConnection = client.voice.connections + .find((connection: VoiceConnection) => connection.channel.id === old_channel.id); + + if (voiceConnection) { + if (old_channel.members.size === 1) { + voiceConnection.disconnect(); + delete_channel(old_channel, guild_list) + .then(response => { return response; }); + stop(newState.guild.id, guild_list, old_channel.guild); + } + } + } + + generate_channel_name(new_channel, guild_object.portal_list, guild_object, newState.guild); + + } + else { // moved from voice to other + + report_message += '->dest: other\n'; + + if (old_channel.members.size === 0) { + delete_channel(old_channel, guild_list) + .then(response => { return response; }); + } + + if (client.voice) { + const voiceConnection = client.voice.connections + .find((connection: VoiceConnection) => connection.channel.id === old_channel.id); + + if (voiceConnection) { + if (old_channel.members.size === 1) { + voiceConnection.disconnect(); + delete_channel(old_channel, guild_list) + .then(response => { return response; }); + stop(newState.guild.id, guild_list, old_channel.guild); + } + } + } + + generate_channel_name(new_channel, guild_object.portal_list, guild_object, newState.guild); + } + } + else { + report_message += '->source: other voice\n'; + + // Joined portal channel + if (included_in_portal_list(new_channel.id, guild_object.portal_list)) { + report_message += '->dest: portal_list\n'; + const portal_object = guild_object.portal_list.find(p => p.id === new_channel.id); + if (!portal_object) return { result: false, value: 'error with data' }; + + create_voice_channel(newState, portal_object, new_channel, newState.id) + .then(response => { + if (!response.result) return response; + generate_channel_name(new_channel, guild_object.portal_list, guild_object, newState.guild); + }) + .catch(error => { return { result: false, value: error }; }); + } + else if (included_in_voice_list( + new_channel.id, guild_object.portal_list)) { // left created channel and joins another created + report_message += '->dest: voice_list\n'; + + generate_channel_name(new_channel, guild_object.portal_list, guild_object, newState.guild); + } + } + } + + return { result: true, value: report_message }; +} + +module.exports = async ( + args: { + client: Client, newState: VoiceState, oldState: VoiceState, + guild_list: GuildPrtl[], portal_managed_guilds_path: string + } +): Promise => { + return new Promise((resolve) => { + const guild_object = args.guild_list.find(g => g.id === args.newState.guild.id); + if (!guild_object) return resolve({ result: false, value: 'error with data' }); + + const new_channel = args.newState.channel; // join channel + const old_channel = args.oldState.channel; // left channel + + if (old_channel !== null && old_channel !== undefined) { + if (new_channel !== null && new_channel !== undefined) { + if (new_channel.id === old_channel.id) { + return { + result: true, + value: 'changed voice state but remains in the same channel' + }; + } + } + } + + if (args.client.voice && args.newState.member) { + const new_voice_connection = args.client.voice.connections.find((connection: VoiceConnection) => + new_channel !== null && connection.channel.id === new_channel.id); + if (new_voice_connection && !args.newState.member.user.bot) { + client_talk(args.client, args.guild_list, 'user_connected'); + } + + const old_voice_connection = args.client.voice.connections.find((connection: VoiceConnection) => + old_channel !== null && connection.channel.id === old_channel.id); + if (old_voice_connection && !args.newState.member.user.bot) { + client_talk(args.client, args.guild_list, 'user_disconnected'); + } + } + + let report_message = `from: ${old_channel} to ${new_channel}\n`; + + const execution = (old_channel === null) + ? from_null(new_channel, args.guild_list, guild_object, args.newState) + : from_existing(old_channel, new_channel, args.client, args.guild_list, guild_object, args.newState); + + if (!execution.result) return resolve(execution); + report_message += `${execution.value}\n`; + + update_portal_managed_guilds(true, args.portal_managed_guilds_path, args.guild_list); + + return resolve({ result: true, value: report_message }); + }); +}; diff --git a/src/functions/guild_manager.js b/src/functions/guild_manager.js deleted file mode 100644 index f7bba8d2..00000000 --- a/src/functions/guild_manager.js +++ /dev/null @@ -1,751 +0,0 @@ -const voca = require('voca'); - -const vrbl_objct = require('../properties/variable_list'); -const pipe_objct = require('../properties/pipe_list'); -const attr_objct = require('../properties/attribute_list'); - -const guild_class = require('../../assets/classes/guild_class'); -const portal_class = require('../../assets/classes/portal_class'); -const voice_class = require('../../assets/classes/voice_class'); -const member_class = require('../../assets/classes/member_class'); - -const help_mngr = require('./help_manager'); -const musc_mngr = require('./music_manager'); - -const getOptions = function (guild, topic) { - return { - type: 'text', - topic: `by Portal, ${topic}`, - permissionOverwrites: [ - { - id: guild.id, - deny: ['SEND_MESSAGES'], - }, - ], - }; -}; - -module.exports = { - - included_in_portal_guilds: function (guild_id, portal_guilds) { - return portal_guilds[guild_id] !== undefined; - }, - - included_in_portal_list: function (channel_id, portal_list) { - return portal_list[channel_id]; - }, - - included_in_voice_list: function (channel_id, portal_list) { - for (const key in portal_list) { - if (portal_list[key].voice_list[channel_id]) { - return true; - } - } - return false; - }, - - included_in_url_list: function (channel_id, guild_object) { - for (let i = 0; i < guild_object.url_list.length; i++) { - if (guild_object.url_list[i] === channel_id) { - return true; - } - } - return false; - }, - - is_spotify_channel: function (channel_id, guild_object) { - return guild_object.spotify === channel_id; - }, - - is_music_channel: function (channel_id, guild_object) { - return guild_object.music_data.channel_id === channel_id; - }, - - is_announcement_channel: function (channel_id, guild_object) { - return guild_object.announcement === channel_id; - }, - - // - - is_role: function (guild, role_name) { - const role = guild.roles.cache.find(cached_role => - cached_role.name === role_name); - return role ? role : null; - }, - - // - - create_focus_channel: async function (guild, member, member_found, focus_time) { - return new Promise((resolve) => { - const return_value = { result: false, value: '*you can run "./help focus" for help.*' }; - - const oldChannel = member.voice.channel; - let newChannel = null; - - guild.channels.create( - `${member.displayName}&${member_found.displayName}`, { - type: 'voice', - bitrate: 64000, - userLimit: 2, - }) - .then(channel => { - newChannel = channel; - member.voice.setChannel(channel); - member_found.voice.setChannel(channel); - - return_value.result = true; - return_value.value = 'users have been moved.'; - }) - .catch(console.error); - - setTimeout(() => { - if (!oldChannel.deleted) { - member.voice.setChannel(oldChannel) - .then(() => { - member_found.voice.setChannel(oldChannel) - .then(() => { - if (newChannel.deletable) { - newChannel.delete().catch(console.error); - return_value.result = true; - return_value.value = 'focus ended properly.'; - return resolve(return_value); - } - }).catch(console.error); - }).catch(console.error); - - } - else { - return_value.result = false; - return_value.value = 'could not move to original channel because it was deleted.'; - return resolve(return_value); - } - }, focus_time * 60 * 1000); - }); - }, - - create_url_channel: function (guild, url_name, url_category, url_list) { - if (url_category && typeof url_category === 'string') { // with category - guild.channels - .create(`${url_name}`, { type: 'text', topic: 'Portal URL-only' }) - .then(channel => { - url_list - .push(channel.id); - guild.channels - .create(url_category, { type: 'category' }) - .then(cat_channel => channel.setParent(cat_channel)) - .catch(console.error); - }) - .catch(console.error); - } - else if (url_category) { // with category given - guild.channels - .create(`${url_name}`, { type: 'text', topic: 'Portal URL-only' }, { parent: url_category }) - .then(channel => { - channel.setParent(url_category); - url_list.push(channel.id); - }) - .catch(console.error); - } - else { // without category - guild.channels - .create(`${url_name}`, { type: 'text', topic: 'Portal URL-only' }) - .then(channel => url_list.push(channel.id)); - } - }, - - create_spotify_channel: function (guild, spotify_channel, spotify_category, guild_object) { - if (spotify_category && typeof spotify_category === 'string') { // with category - return guild.channels - .create( - `${spotify_channel}`, - getOptions(guild, 'Displays music users in portal channels are listening too'), - ) - .then(channel => { - guild_object.spotify = channel.id; - guild.channels - .create(spotify_category, { type: 'category' }) - .then(cat_channel => channel.setParent(cat_channel)) - .catch(console.error); - }) - .catch(console.error); - } - else if (spotify_category) { // with category given - return guild.channels - .create( - `${spotify_channel}`, - getOptions(guild, 'Displays music users in portal channels are listening too'), - { parent: spotify_category }, - ) - .then(channel => { - channel.setParent(spotify_category); - guild_object.spotify = channel.id; - }) - .catch(console.error); - } - else { // without category - return guild.channels - .create( - `${spotify_channel}`, - getOptions(guild, 'Displays music users in portal channels are listening too'), - ) - .then(channel => { - guild_object.spotify = channel.id; - }) - .catch(console.error); - } - }, - - create_music_channel: async function (guild, music_channel, music_category, guild_object) { - const portal_icon_url = 'https://raw.githubusercontent.com/keybraker/keybraker' + - '.github.io/master/assets/img/logo.png'; - return new Promise((resolve) => { - if (music_category && typeof music_category === 'string') { // with category - guild.channels - .create( - `${music_channel}`, - { - type: 'text', - topic: 'Portal Music, play:▶️, pause:⏸, stop:⏹, skip:⏭, list:📜, clear list:❌', - }, - ) - .then(channel => { - guild_object.music_data.channel_id = channel.id; - guild.channels - .create(music_category, { type: 'category' }) - .then(cat_channel => channel.setParent(cat_channel)) - .catch(error => resolve(error)); - help_mngr.create_music_message(channel, portal_icon_url, guild_object); - }) - .catch(error => resolve(error)); - } - else if (music_category) { // with category given - guild.channels - .create( - `${music_channel}`, - { - type: 'text', - topic: 'Portal Music, play:▶️, pause:⏸, stop:⏹, skip:⏭, list:📜, clear list:❌', - }, - { parent: music_category }, - ) - .then(channel => { - channel.setParent(music_category); - guild_object.music_data.channel_id = channel.id; - help_mngr.create_music_message(channel, portal_icon_url, guild_object); - }) - .catch(error => resolve(error)); - } - else { // without category - guild.channels - .create( - `${music_channel}`, - { - type: 'text', - topic: 'Portal Music, play:▶️, pause:⏸, stop:⏹, skip:⏭, list:📜, clear list:❌', - }, - ) - .then(channel => { - guild_object.music_data.channel_id = channel.id; - help_mngr.create_music_message(channel, portal_icon_url, guild_object); - }) - .catch(error => resolve(error)); - } - }); - }, - - create_announcement_channel: function (guild, announcement_channel, announcement_category, guild_object) { - if (announcement_category && typeof announcement_category === 'string') { // with category - return guild.channels - .create( - `${announcement_channel}`, - getOptions(guild, 'Announcements channel, for both portal, users and admins'), - ) - .then(channel => { - guild_object.announcement = channel.id; - guild.channels - .create(announcement_category, { type: 'category' }) - .then(cat_channel => channel.setParent(cat_channel)) - .catch(console.error); - }) - .catch(console.error); - } - else if (announcement_category) { // with category given - return guild.channels - .create( - `${announcement_channel}`, - getOptions(guild, 'Announcements channel, for both portal, users and admins', - ), - { parent: announcement_category }, - ) - .then(channel => { - channel.setParent(announcement_category); - guild_object.announcement = channel.id; - }) - .catch(console.error); - } - else { // without category - return guild.channels - .create( - `${announcement_channel}`, - getOptions(guild, 'Announcements channel, for both portal, users and admins'), - ) - .then(channel => { guild_object.announcement = channel.id; }) - .catch(console.error); - } - }, - - create_portal_channel: function (guild, portal_channel, portal_category, portal_objct, guild_object, creator_id) { - if (portal_category && typeof portal_category === 'string') { // with category - return guild.channels - .create(portal_channel, { type: 'voice', bitrate: 64000, userLimit: 1 }) - .then(channel => { - portal_objct[channel.id] = new portal_class( - creator_id, - portal_channel, - guild_object[guild.id].premium - ? 'G$#-P$member_count | $status_list' - : 'Channel $#', - {}, false, 2, 0, 0, guild_object[guild.id].locale, true, true, - ); - guild.channels - .create(portal_category, { type: 'category' }) - .then(cat_channel => channel.setParent(cat_channel)) - .catch(console.error); - }) - .catch(console.error); - } - else if (portal_category) { // with category given - return guild.channels - .create(portal_channel, { type: 'voice', bitrate: 64000, userLimit: 1 }, { parent: portal_category }) - .then(channel => { - channel.setParent(portal_category); - portal_objct[channel.id] = new portal_class( - creator_id, - portal_channel, - guild_object[guild.id].premium - ? 'G$#-P$member_count | $status_list' - : 'Channel $#', - {}, false, 2, 0, 0, guild_object[guild.id].locale, true, true, - ); - }) - .catch(console.error); - } - else { // without category - return guild.channels - .create(portal_channel, { type: 'voice', bitrate: 64000, userLimit: 1 }) - .then(channel => { - portal_objct[channel.id] = new portal_class( - creator_id, - portal_channel, - guild_object[guild.id].premium - ? 'G$#-P$member_count | $status_list' - : 'Channel $#', - {}, false, 2, 0, 0, guild_object[guild.id].locale, true, true, - ); - }) - .catch(console.error); - } - }, - - create_voice_channel: function (state, portal_objct, portal_channel, creator_id) { - state.channel.guild.channels - .create('loading...', { - type: 'voice', - bitrate: 96000, - position: portal_channel.position ? portal_channel.position : portal_channel.position + 1, - userLimit: portal_objct.user_limit_portal, - parent: state.channel.parentID ? state.channel.parentID : null, - }) - .then(channel => { - portal_objct['voice_list'][channel.id] = new voice_class( - creator_id, portal_objct.regex_voice, false, 0, 0, - portal_objct.locale, portal_objct.ann_announce, portal_objct.ann_user, - ); - state.member.voice.setChannel(channel); - }) - .catch(console.error); - - return; - }, - - create_member_list: function (guild_id, client) { - const member_list = {}; - const guild = client.guilds.cache.find(cached_guild => cached_guild.id === guild_id); - console.log('new guild :>> ', guild); - console.log('new guild.members.cache :>> ', guild.members.cache); - - guild.members.cache.forEach(member => { - if (member.id !== client.user.id && !member.user.bot) { - member_list[member.id] = new member_class(1, 0, 0, 0, null); - } - }); - - return member_list; - }, - - insert_guild: function (guild_id, portal_guilds, client) { - const portal_list = {}; - const member_list = this.create_member_list(guild_id, client); - const url_list = []; - const role_list = {}; - const ranks = {}; - const auth_role = []; - const spotify = null; - const music_data = { channel_id: null, message_id: null, votes: [] }; - const music_queue = []; - const dispatcher = null; - const announcement = null; - const locale = 'en'; - const announce = 0; - const level_speed = 'normal'; - const premium = false; - - portal_guilds[guild_id] = new guild_class(portal_list, member_list, url_list, role_list, ranks, auth_role, - spotify, music_data, music_queue, dispatcher, announcement, locale, announce, level_speed, premium); - }, - - // - - delete_guild: function (guild_id, portal_guilds) { - delete portal_guilds[guild_id]; - }, - - delete_channel: (channel_to_delete, message, isPortal = false) => { - if (!isPortal) { - const author = message.author; - const channel_to_delete_name = channel_to_delete.name; - let channel_deleted = false; - - message.channel - .send(`${message.author}, do you wish to delete old music channel **"${channel_to_delete}"** (yes / no) ?`) - .then(question_msg => { - const filter = m => m.author.id === author.id; - const collector = message.channel.createMessageCollector(filter, { time: 10000 }); - - collector.on('collect', m => { - if (m.content === 'yes') { - if (channel_to_delete.deletable) { - channel_to_delete - .delete() - .then(g => console.log(`Deleted channel with id: ${g}`)) - .catch(console.error); - - m.channel.send(`Deleted channel **"${channel_to_delete_name}"**.`) - .then(msg => { msg.delete({ timeout: 5000 }); }) - .catch(error => console.log(error)); - - channel_deleted = true; - } - else { - message.channel.send(`Channel **"${channel_to_delete}"** is not deletable.`) - .then(msg => { msg.delete({ timeout: 5000 }); }) - .catch(error => console.log(error)); - } - collector.stop(); - } - else if (m.content === 'no') { - collector.stop(); - } - }); - - collector.on('end', collected => { - for (const reply_message of collected.values()) { - if (reply_message.deletable) { - reply_message.delete().catch(console.error); - } - } - if (!channel_deleted) { - message.channel.send(`Channel **"${channel_to_delete}"** will not be deleted.`) - .then(msg => { msg.delete({ timeout: 5000 }); }) - .catch(error => console.log(error)); - } - question_msg.delete({ timeout: 5000 }); - }); - }) - .catch(error => console.log(error)); - } - else if (channel_to_delete.deletable) { - channel_to_delete - .delete() - .then(g => console.log(`Deleted channel with id: ${g}`)) - .catch(console.error); - } - }, - - channel_deleted_update_state: function (channel_to_remove, guild_list) { - const TypesOfChannel = { Unknown: 0, Portal: 1, Voice: 2, Url: 3, Spotify: 4, Announcement: 5, Music: 6 }; - const current_guild = guild_list[channel_to_remove.guild.id]; - let type_of_channel = TypesOfChannel.Unknown; - - for (const portal_id in current_guild.portal_list) { - if (portal_id === channel_to_remove.id) { - delete current_guild.portal_list[portal_id]; - type_of_channel = TypesOfChannel.Portal; - break; - } - else { - const current_voice_list = current_guild.portal_list[portal_id].voice_list; - for (const voice_id in current_voice_list) { - if (voice_id === channel_to_remove.id) { - delete current_voice_list[voice_id]; - type_of_channel = TypesOfChannel.Voice; - break; - } - } - } - } - - for (let i = 0; i < current_guild.url_list.length; i++) { - console.log(`${current_guild.url_list[i]} === ${channel_to_remove.id}`); - if (current_guild.url_list[i] === channel_to_remove.id) { - current_guild.url_list.splice(i, 1); - type_of_channel = TypesOfChannel.Url; - break; - } - } - if (current_guild.spotify === channel_to_remove.id) { - current_guild.spotify = null; - type_of_channel = TypesOfChannel.Spotify; - } - if (current_guild.announcement === channel_to_remove.id) { - current_guild.announcement = null; - type_of_channel = TypesOfChannel.Announcement; - } - if (current_guild.music_data.channel_id === channel_to_remove.id) { - musc_mngr.stop(channel_to_remove.guild.id, guild_list, channel_to_remove.guild); - - current_guild.music_data.channel_id = null; - current_guild.music_data.message_id = null; - current_guild.music_data.votes = []; - current_guild.dispatcher = null; - type_of_channel = TypesOfChannel.Music; - } - return type_of_channel; - }, - - // - - generate_channel_name: function (voice_channel, portal_object, guild_object, guild) { - for (const portal_id in portal_object) { - if (portal_object[portal_id].voice_list[voice_channel.id]) { - const voice_object = portal_object[portal_id].voice_list[voice_channel.id]; - - const new_name = this.regex_interpreter( - voice_object.regex, - voice_channel, - voice_object, - portal_object, - guild_object, - guild, - ); - - if (new_name.length >= 1) { // check if it works correctly tsiakkas - if (voice_channel.name !== new_name.substring(0, 99)) { - voice_channel.edit({ name: new_name.substring(0, 99) }) - .then(newChannel => console.log(`Voice's new name from promise is ${newChannel.name}`)) - .catch(console.log); - return 1; - } - else { - return 2; - } - } - else { - return 3; - } - } - } - return false; - }, - - regex_interpreter: function (regex, voice_channel, voice_object, portal_object, guild_object, guild) { - - let last_space_index = 0; - let last_vatiable_end_index = 0; - let last_attribute_end_index = 0; - - let last_variable = ''; - let last_attribute = ''; - - let new_channel_name = ''; - - for (let i = 0; i < regex.length; i++) { - - if (regex[i] === vrbl_objct.prefix) { - - const vrbl = vrbl_objct.is_variable(regex.substring(i)); - - if (vrbl) { - const return_value = vrbl_objct - .get(voice_channel, voice_object, portal_object, guild_object, guild, vrbl); - - if (return_value) { - last_variable = return_value; - new_channel_name += return_value; - i += voca.chars(vrbl).length; - last_vatiable_end_index = i; - } - else { - new_channel_name += regex[i]; - } - } - else { - new_channel_name += regex[i]; - } - - } - else if (regex[i] === attr_objct.prefix) { - - const attr = attr_objct.is_attribute(regex.substring(i)); - - if (attr) { - const return_value = attr_objct - .get(voice_channel, voice_object, portal_object, guild_object, attr); - - if (return_value) { - last_attribute = return_value; - new_channel_name += return_value; - i += voca.chars(attr).length; - last_attribute_end_index = i; - } - else { - new_channel_name += regex[i]; - } - } - else { - new_channel_name += regex[i]; - } - - } - else if (regex[i] === pipe_objct.prefix) { - - const pipe = pipe_objct.is_pipe(regex.substring(i)); - - if (pipe) { - if (last_vatiable_end_index + 1 === i) { - - const return_value = pipe_objct.get(last_variable, pipe); - - if (return_value) { - new_channel_name = new_channel_name.substring(0, - voca.chars(new_channel_name).length - voca.chars(last_variable).length); - new_channel_name += return_value; - i += voca.chars(pipe).length; - } - else { - new_channel_name += regex[i]; - } - - } - else if (last_attribute_end_index + 1 === i) { - - const return_value = pipe_objct.get(last_attribute, pipe); - - if (return_value) { - new_channel_name = new_channel_name.substring(0, - voca.chars(new_channel_name).length - voca.chars(last_attribute).length); - new_channel_name += return_value; - i += voca.chars(pipe).length; - } - else { - new_channel_name += regex[i]; - } - - } - else { - - const return_value = pipe_objct - .get(new_channel_name.substring(last_space_index, new_channel_name.length), pipe); - - if (return_value) { - const str_for_pipe = return_value; - new_channel_name = new_channel_name.substring(0, last_space_index); - new_channel_name += str_for_pipe; - i += voca.chars(pipe).length; - } - else { - new_channel_name += regex[i]; - } - - } - } - else { - new_channel_name += regex[i]; - } - - } - else if (regex[i] === '{' && (regex[i + 1] !== undefined && regex[i + 1] === '{')) { - - const inline = { - '==': (a, b) => (a == b) ? true : false, - '===': (a, b) => (a === b) ? true : false, - '!=': (a, b) => (a != b) ? true : false, - '!==': (a, b) => (a !== b) ? true : false, - '>': (a, b) => (a > b) ? true : false, - '<': (a, b) => (a < b) ? true : false, - '>=': (a, b) => (a >= b) ? true : false, - '<=': (a, b) => (a <= b) ? true : false, - }; - - try { - // did not put into structure_list due to many unnecessary function calls - let is_valid = false; - const statement = help_mngr - .getJSON(regex.substring(i + 1, i + 1 + regex.substring(i + 1).indexOf('}}') + 1)); - - if (Object.prototype.hasOwnProperty.call(statement, 'if')) { - if (Object.prototype.hasOwnProperty.call(statement, 'is')) { - if (Object.prototype.hasOwnProperty.call(statement, 'with')) { - if (Object.prototype.hasOwnProperty.call(statement, 'yes')) { - if (Object.prototype.hasOwnProperty.call(statement, 'no')) { - is_valid = true; - } - } - } - } - } - - if (!is_valid) { - new_channel_name += regex[i]; - if (regex[i] === ' ') { last_space_index = i + 1; } - } - else { - if (inline[statement.is]( - this.regex_interpreter( - statement.if, voice_channel, voice_object, portal_object, guild_object, guild, - ), - this.regex_interpreter( - statement.with, voice_channel, voice_object, portal_object, guild_object, guild, - ), - )) { - const value = this.regex_interpreter( - statement.yes, voice_channel, voice_object, portal_object, guild_object, guild, - ); - if (value !== '--') { new_channel_name += value; } - } - else { - const value = this.regex_interpreter( - statement.no, voice_channel, voice_object, portal_object, guild_object, guild, - ); - if (value !== '--') { new_channel_name += value; } - } - i += regex.substring(i + 1).indexOf('}}') + 2; - } - } - catch (error) { - console.log('ERROR: in JSON parse: ', error); - new_channel_name += regex[i]; - } - - } - else { - new_channel_name += regex[i]; - if (regex[i] === ' ') { last_space_index = i + 1; } - } - } - - if (new_channel_name === '') { return '.'; } - return new_channel_name; - - }, -}; \ No newline at end of file diff --git a/src/functions/help_manager.js b/src/functions/help_manager.js deleted file mode 100644 index 2b580eb4..00000000 --- a/src/functions/help_manager.js +++ /dev/null @@ -1,375 +0,0 @@ -const Discord = require('discord.js'); -const file_system = require('file-system'); -const lodash = require('lodash'); - -// const guld_mngr = require('./guild_manager'); // circular module call doesnt work ! -const lclz_mngr = require('./localization_manager'); - -const role_class = require('../../assets/classes/role_class'); - -module.exports = { - - create_role_message: function (channel, role_list, title, desc, colour, role_emb, role_map) { - const role_message_emb = this.create_rich_embed(title, desc, colour, role_emb); - channel - .send(role_message_emb) - .then(sent_message => { - for (let i = 0; i < role_map.length; i++) { - sent_message.react(role_map[i].give); - sent_message.react(role_map[i].strip); - } - role_list[sent_message.id] = new role_class(role_map); - }) - .catch(error => console.log(error)); - }, - - create_music_message: function (channel, thumbnail, guild_object) { - const music_message_emb = this.create_rich_embed( - 'Music Player', - 'just type and I\'ll play', - '#0000FF', - [ - { emote: 'Duration', role: '-', inline: true }, - { emote: 'Views', role: '-', inline: true }, - { emote: 'Uploaded', role: '-', inline: true }, - ], - false, - false, - true, - false, - thumbnail, - ); - - channel - .send(music_message_emb) - .then(sent_message => { - sent_message.react('▶️'); - sent_message.react('⏸'); - sent_message.react('⏹'); - sent_message.react('⏭'); - sent_message.react('📜'); - sent_message.react('❌'); - - guild_object.music_data.message_id = sent_message.id; - }); - }, - - update_message: function (guild, guild_object, yts) { - const music_message_emb = this.create_rich_embed( - yts.title, - yts.url, - '#0000FF', - [ - { emote: 'Duration', role: yts.timestamp, inline: true }, - { emote: 'Views', role: yts.views, inline: true }, - { emote: 'Uploaded', role: yts.ago, inline: true }, - ], - false, - false, - true, - false, - yts.thumbnail, - ); - const channel = guild_object.channels.cache.get(guild.music_data.channel_id); - - if (channel) { - channel.messages.channel.messages - .fetch(guild.music_data.message_id) - .then(message => { - message.edit(music_message_emb) - .then(msg => console.log(`Updated the content of a message to ${msg.content}`)) - .catch(console.error); - }) - .catch(console.error); - } - }, - - join_user_voice: async function (client, message, portal_guilds, join) { // localize - return new Promise((resolve) => { - const current_voice = message.member.voice.channel; - - if (current_voice === null) { - return resolve({ result: false, value: 'you are not connected to any channel.' }); - } - - if (current_voice.guild.id !== message.guild.id) { - return resolve({ result: false, value: 'your current channel is on another guild.' }); - } - - const portal_list = portal_guilds[message.guild.id].portal_list; - let included_in_voice_list = false; - - for (const key in portal_list) { - if (portal_list[key].voice_list[current_voice.id]) { included_in_voice_list = true; } - } - - if (!included_in_voice_list) { - console.log('I can only connect to my channels.'); - return resolve({ result: false, value: 'I can only connect to my channels.' }); - } - - const existing_voice_connection = client.voice.connections.find(connection => - connection.channel.id === message.member.voice.channel.id - ); - - if (existing_voice_connection) { - return resolve({ - result: true, - value: 'already in voice channel', - voice_connection: existing_voice_connection, - }); - } else { - // let new_voice_connection = null; - current_voice.join() - .then(conn => { - if (join) lclz_mngr.client_talk(client, portal_guilds, 'join'); - - return resolve({ - result: true, - value: lclz_mngr.client_write(message, portal_guilds, 'join'), - voice_connection: conn, - }); - }) - .catch(e => { console.log('ERROR CREATING VOICE CONNECTION TO CHANNEL: ', e); }); - } - }); - }, - - getJSON: function (str) { - let data = null; - try { - data = JSON.parse(str); - } - catch (error) { - return null; - } - - return data; - }, - - create_rich_embed: function (title, description, colour, field_array, thumbnail, member, from_bot, url, image) { - const portal_icon_url = 'https://raw.githubusercontent.com/keybraker/keybraker' + - '.github.io/master/assets/img/logo.png'; - const keybraker_url = 'https://github.com/keybraker'; - - const rich_message = new Discord.MessageEmbed() - .setTimestamp(); - // .setAuthor('Portal', portal_icon_url, keybraker_url) - - if (title) { - rich_message - .setTitle(title); - } - if (url) { - rich_message - .setURL(url); - } - if (colour) { - rich_message - .setColor(colour); - } - if (description) { - rich_message - .setDescription(description); - } - if (from_bot) { - rich_message - .setFooter('Portal bot by Keybraker', portal_icon_url, keybraker_url); - } - if (member) { - rich_message - .setAuthor(member.displayName, member.user.avatarURL()); - } - if (thumbnail) { - rich_message - .setThumbnail(thumbnail); - } - if (image) { - rich_message - .setImage(image); - } - - if (field_array) { - field_array.forEach(row => { - rich_message - .addField( - (row.emote === '' || row.emote === null || row.emote === false) - ? '\u200b' - : '`' + row.emote + '`', - (row.role === '' || row.role === null || row.role === false) - ? '\u200b' - : row.role, - row.inline, - ); - }); - } - else { - rich_message.addField('\u200b', '\u200b'); - } - - return rich_message; - }, - - empty_channel_remover: function (current_guild, portal_guilds, portal_managed_guilds_path) { - current_guild.channels.cache.forEach(channel => { - if (portal_guilds[current_guild.id]) { - for (const portal_channel in portal_guilds[current_guild.id].portal_list) { - if (portal_guilds[current_guild.id].portal_list[portal_channel].voice_list[channel.id]) { - if (!channel.members.size) { - console.log('Deleting channel: ', channel.name, 'from ', channel.guild.name); - // guld_mngr.delete_channel(channel); - if (channel.deletable) { - channel - .delete() - .then(g => console.log(`Deleted channel with id: ${g}`)) - .catch(console.error); - } - return true; - } - } - return false; - } - } - else { - current_guild.leave() - .then(guild => console.log(`Left guild ${guild}`)) - .catch(console.error); - } - }); - - this.update_portal_managed_guilds(true, portal_managed_guilds_path, portal_guilds); - }, - - update_portal_managed_guilds: async function (force, portal_managed_guilds_path, portal_guilds) { - return new Promise((resolve) => { // , reject) => { - setTimeout(() => { - const portal_guilds_no_voice = lodash.cloneDeep(portal_guilds); - for (const guild_id in portal_guilds_no_voice) { - portal_guilds_no_voice[guild_id].dispatcher = null; - } - - if (force) { - file_system.writeFileSync( - portal_managed_guilds_path, - JSON.stringify(portal_guilds_no_voice), - 'utf8', - ); - } - else { - file_system.writeFile( - portal_managed_guilds_path, - JSON.stringify(portal_guilds_no_voice), - 'utf8', - ); - } - }, 1000); - return resolve({ result: true, value: '*updated portal guild json.*' }); - }); - }, - - is_authorized: function (auth_role, member) { - return !member.hasPermission('ADMINISTRATOR') - ? member.roles.cache !== undefined && member.roles.cache !== null - ? member.roles.cache.some(role => - auth_role - ? auth_role.some(auth => auth === role.id) - : false) - : false - : true; - }, - - // channel should be removed ! - message_reply: function (status, channel, message, user, str, portal_guilds, - client, to_delete = false, emote_pass = '✔️', emote_fail = '❌') { - if (!message.channel.deleted && str !== null) { - message.channel - .send(`${user}, ${str}`) - .then(msg => { msg.delete({ timeout: 5000 }); }) - .catch(error => console.log(error)); - } - if (!message.deleted) { - if (status === true) { - message - .react(emote_pass) - .catch(error => console.log(error)); - } - else if (status === false) { - lclz_mngr.client_talk(client, portal_guilds, 'fail'); - message - .react(emote_fail) - .catch(error => console.log(error)); - } - if (to_delete) { - message - .delete({ timeout: 5000 }) - .catch(error => console.log(error)); - } - } - }, - - is_url: function (potential_url) { - const pattern = new RegExp('^(https?:\\/\\/)?' + // protocol - '((([a-z\\d]([a-z\\d-]*[a-z\\d])*)\\.)+[a-z]{2,}|' + // domain name - '((\\d{1,3}\\.){3}\\d{1,3}))' + // OR ip (v4) address - '(\\:\\d+)?(\\/[-a-z\\d%_.~+]*)*' + // port and path - '(\\?[;&a-z\\d%_.~+=-]*)?' + // query string - '(\\#[-a-z\\d_]*)?$', 'i'); // fragment locator - - return pattern.test(potential_url); - }, - - pad: function (num) { - if (num.toString().length >= 2) { - return num; - } - else { - return '0' + num; - } - }, - - time_elapsed: function (timestamp, timeout) { - const time_elapsed = Date.now() - timestamp; - const timeout_time = timeout * 60 * 1000; - - const timeout_min = Math.round((timeout_time / 1000 / 60)) > 0 - ? Math.round((timeout_time / 1000 / 60)) - : 0; - const timeout_sec = Math.round((timeout_time / 1000) % 60); - - const remaining_hrs = Math.round( - (time_elapsed / 1000 / 60 / 60)) > 0 - ? Math.round((time_elapsed / 1000 / 60 / 60)) - : 0; - const remaining_min = Math.round( - (time_elapsed / 1000 / 60) - 1) > 0 - ? Math.round((time_elapsed / 1000 / 60) - 1) - : 0; - const remaining_sec = Math.round( - (time_elapsed / 1000) % 60) > 0 - ? Math.round((time_elapsed / 1000) % 60) - : 0; - - return { timeout_min, timeout_sec, remaining_hrs, remaining_min, remaining_sec }; - }, - - time_remaining: function (timestamp, timeout) { - const time_elapsed = Date.now() - timestamp; - const timeout_time = timeout * 60 * 1000; - const time_remaining = timeout_time - time_elapsed; - - const timeout_min = Math.round((timeout_time / 1000 / 60)) > 0 - ? Math.round((timeout_time / 1000 / 60)) - : 0; - const timeout_sec = Math.round((timeout_time / 1000) % 60) - ? Math.round((timeout_time / 1000) % 60) - : 0; - const remaining_min = Math.round((time_remaining / 1000 / 60) - 1) > 0 - ? Math.round((time_remaining / 1000 / 60) - 1) - : 0; - - const remaining_sec = Math.round((time_remaining / 1000) % 60); - - return { timeout_min, timeout_sec, remaining_min, remaining_sec }; - }, - -}; \ No newline at end of file diff --git a/src/functions/http_requests.js b/src/functions/http_requests.js deleted file mode 100644 index 22a60135..00000000 --- a/src/functions/http_requests.js +++ /dev/null @@ -1,17 +0,0 @@ -/* eslint-disable no-cond-assign */ -/* eslint-disable no-unused-vars */ -const https = require('https'); - -module.exports = async (options) => { - return new Promise((resolve, reject) => { - const req = https.request(options, function (res) { - const chunks = []; - - res.on('data', function (chunk) { chunks.push(chunk); }); - res.on('end', function (chunk) { return resolve(Buffer.concat(chunks)); }); - res.on('error', function (error) { return reject(false); }); - }); - - req.end(); - }); -}; diff --git a/src/functions/localization_manager.js b/src/functions/localization_manager.js deleted file mode 100644 index 3f3431b0..00000000 --- a/src/functions/localization_manager.js +++ /dev/null @@ -1,181 +0,0 @@ -/* eslint-disable quotes */ -/* eslint-disable no-unused-vars */ -/* eslint-disable no-cond-assign */ -/* eslint-disable no-undef */ - -const type_of_announcement = ['fail', 'announce', 'spotify', 'url', 'read_only', 'join', 'leave']; -const type_of_action = ['user_connected', 'user_disconnected']; - -module.exports = -{ - client_talk: function (client, guild_list, context) { - let check = null; - if (type_of_announcement.includes(context)) { check = 'ann_announce'; } - else if (type_of_action.includes(context)) { check = 'ann_user'; } - - if (client.voice !== undefined) { - const voiceConnection = client.voice.connections.find(connection => connection.channel.id); - if (voiceConnection) { - for (const guild_id in guild_list) { - for (const portal_id in guild_list[guild_id].portal_list) { - for (const voice_id in guild_list[guild_id].portal_list[portal_id].voice_list) { - if (voice_id === voiceConnection.channel.id) { - if (!guild_list[guild_id].dispatcher) { - if (!check || guild_list[guild_id].portal_list[portal_id].voice_list[voice_id][check]) { - const locale = guild_list[guild_id].portal_list[portal_id].voice_list[voice_id].locale; - const random = Math.floor(Math.random() * Math.floor(3)); - voiceConnection.play(`./assets/mp3s/${locale}/${context}/${context}_${random}.mp3`); - } - } - } - } - } - } - } - } - }, - - client_write: function (message, guild_list, context) { - let locale = null; - if (message !== null) { - if (message.member.voice !== undefined && message.member.voice !== null) { - for (const guild_id in guild_list) { - for (const portal_id in guild_list[guild_id].portal_list) { - for (const voice_id in guild_list[guild_id].portal_list[portal_id].voice_list) { - if (voice_id === message.member.voice.channel.id) { // message.author.presence.member.voice.channel.id) { - locale = guild_list[guild_id].portal_list[portal_id].voice_list[voice_id].locale; - return this.portal[context][locale](); - } - } - } - } - } - } - - locale = guild_list[message.guild.id].locale; - return this.portal[context][locale](); - }, - - client_log: function (guild_id, message, guild_list, context, args) { - let locale = null; - if (message !== null) { - if (message.author.voice !== undefined && message.author.voice !== null) { - for (const guild_list_id in guild_list) { - for (const portal_id in guild_list[guild_list_id].portal_list) { - for (const voice_id in guild_list[guild_list_id].portal_list[portal_id].voice_list) { - if (voice_id === message.member.channel.id) { // message.author.presence.member.voice.channel.id) { - locale = guild_list[guild_list_id].portal_list[portal_id].voice_list[voice_id].locale; - return this.console[context][locale].text(args); - } - } - } - } - } - } - - locale = guild_list[guild_id].locale; - return this.console[context][locale](args); - }, - - portal: - { - join: { - gr: () => { return 'Γειά σας, το Πόρταλ είναι εδώ.'; }, - en: () => { return 'Cheers love, Portal\'s here.'; }, - de: () => { return 'Hallo, Portal ist da.'; }, - }, - leave: { - gr: () => { return 'Αποχαιρετώ, καλή συνέχεια σε όλους.'; }, - en: () => { return 'Goodbye everyone.'; }, - de: () => { return 'Auf Wiedersehen alle.'; }, - }, - announce: { - gr: (user) => { return `O ${user} έκανε μια ανακοίνωση.`; }, - en: (user) => { return `${user} made an announcement.`; }, - de: (user) => { return `${user} hat eine Ankündigung gemacht.`; }, - }, - spotify: { - gr: (user) => { return `O ${user} έβαλε νέο κομμάτι.`; }, - en: (user) => { return `${user} listens to a new song.`; }, - de: (user) => { return `${user} hört sich ein neues Lied an.`; }, - }, - url: { - gr: (user) => { return `O ${user} ανέβασε έναν νέο σύνδεσμο.`; }, - en: (user) => { return `${user} sent a new link.`; }, - de: (user) => { return `${user} hat einen neuen Link geschickt.`; }, - }, - read_only: { - gr: (user) => { return `${user}, το κανάλι είναι μόνο για ανάγνωση.`; }, - en: (user) => { return `${user}, the channel is read-only.`; }, - de: (user) => { return `${user}, der Kanal ist schreibgeschütz.`; }, - }, - fail: { - gr: (user) => { return `${user}, κάτι δεν πήγε καλά.`; }, - en: (user) => { return `${user}, something went wrong.`; }, - de: (user) => { return `${user}, etwas ist schief gelaufen.`; }, - }, - user_connected: { - gr: (user) => { return `Ο χρήστης ${user} συνδέθηκε στο κανάλι.`; }, - en: (user) => { return `User ${user} connected to the channel.`; }, - de: (user) => { return `Mitglied ${user} hat sich zum Kanal verbunden.`; }, - }, - user_disconnected: { - gr: (user) => { return `Ο χρήστης ${user} αποχώρησε από το κανάλι.`; }, - en: (user) => { return `User ${user} disconnected from the channel.`; }, - de: (user) => { return `Mitglied ${user} hat sich vom Kanal unverbunden.`; }, - }, - }, - - console: - { - ready: { - gr: (args) => { - return `Το μποτ ξεκίνησε, με ${args.client.users.cache.size} χρήστες, μέσα σε ` + - `${args.client.channels.cache.size} κανάλια σε ${args.client.guilds.cache.size} συντεχνίες.`; - }, - en: (args) => { - return `Bot has started, with ${args.client.users.cache.size} users, ` + - `in ${args.client.channels.cache.size} channels from ${args.client.guilds.cache.size} guilds.`; - }, - de: (args) => { - return `Bot hat ${args.client.users.cache.size} Mitglieder in ${channel_count} ` + - `Kanälen von ${guild_count} Gilden gestartet.`; - }, - }, - updating_guild: { - gr: (args) => { return '> Το αρχείο JSON των συντεχνιών ενημερώθηκε.'; }, - en: (args) => { return '> Guild JSON file has been updated.'; }, - de: (args) => { return '> Die JSON Datei der Gilde wurde aktualisiert.'; }, - }, - presence_controlled_away: { - gr: (args) => { - return `Ο χρήστης ${args.newPresence.member.displayName} είναι μέλος ` + - `μια ελεγχόμενης συντεχνίας, έχει αλλάξει κατάσταση, αλλά βρίσκεται στη συντεχνία ` + - `(${args.newPresence.guild.name})`; - }, - en: (args) => { - return `${args.newPresence.member.displayName} who is a member of a handled server, ` + - `has changed presence, but is in another server (${args.newPresence.guild.name})`; - }, - de: (args) => { - return `${args.newPresence.member.displayName} who is a member of a handled server, ` + - `has changed presence, but is in another server (${args.newPresence.guild.name})`; - }, - }, - presence_controlled: { - gr: (args) => { - return `Ο χρήστης ${args.newPresence.member.displayName} έχει αλλάξει κατάσταση, ` + - `και βρίσκεται στην ελεγχόμενη συντεχνία (${args.newPresence.guild.name})`; - }, - en: (args) => { - return `${args.newPresence.member.displayName} has changed presence, ` + - `in controlled server (${args.newPresence.guild.name})`; - }, - de: (args) => { - return `${args.newPresence.member.displayName} has changed presence, ` + - `in controlled server (${args.newPresence.guild.name})`; - }, - }, - }, -}; - diff --git a/src/functions/music_manager.js b/src/functions/music_manager.js deleted file mode 100644 index 5a07f225..00000000 --- a/src/functions/music_manager.js +++ /dev/null @@ -1,229 +0,0 @@ -const help_mngr = require('./help_manager'); - -const yts = require('yt-search'); -// const ytdl = require('ytdl-core'); -const ytdl = require('discord-ytdl-core'); - -module.exports = { - - start: async function (client, message, search_term, portal_guilds) { - return new Promise((resolve) => { - if (!search_term || search_term === '') { - return resolve({ result: false, value: 'cannot search for nothing.' }); - } - if (!message.member.voice.channel) { - return resolve({ result: false, value: 'you are not connected to any channel.' }); - } - - const guild_id = message.member.voice.channel.guild.id; - const current_dispatcher = portal_guilds[guild_id].dispatcher; - const current_music_queue = portal_guilds[guild_id].music_queue; - - if (current_dispatcher !== null && current_dispatcher !== undefined) { - yts(search_term) - .then(yts_attempt => { - if (yts_attempt) { - current_music_queue.push(yts_attempt.videos[0]); - } - else { - return resolve({ result: false, value: 'could not find youtube video' }); - } - }) - .catch(error => console.log(error)); - return resolve({ result: false, value: 'already playing song, your song has been added in list.' }); - } - - help_mngr.join_user_voice(client, message, portal_guilds, false) - .then(join_attempt => { - if (join_attempt.result === true) { - yts(search_term) - .then(yts_attempt => { - if (yts_attempt && yts_attempt.videos.length > 0) { - const stream = ytdl(yts_attempt.videos[0].url, { - filter: 'audioonly', - opusEncoded: false, - fmt: 'mp3', - highWaterMark: 2048, - }); - portal_guilds[guild_id].dispatcher = join_attempt.voice_connection.play(stream); - - help_mngr.update_message(portal_guilds[guild_id], - message.member.voice.channel.guild, yts_attempt.videos[0]); - - portal_guilds[guild_id].dispatcher.on('finish', () => { - this.skip(guild_id, portal_guilds, client, message.guild); - portal_guilds[guild_id].music_data.votes = []; - }); - - return resolve({ result: false, value: 'playing video' }); - } - else { - return resolve({ result: false, value: 'could not find youtube video' }); - } - }) - .catch(error => console.log(error)); - } - else { - console.log(join_attempt.value); - return resolve({ result: false, value: join_attempt.value }); - } - }) - .catch(error => console.log(error)); - }); - }, - - play: async function (guild_id, portal_guilds, client, guild_object) { - return new Promise((resolve) => { - const current_dispatcher = portal_guilds[guild_id].dispatcher; - - if (current_dispatcher !== null && current_dispatcher !== undefined) { - if (current_dispatcher.paused) { - current_dispatcher.resume(); - - portal_guilds[guild_id].dispatcher.on('finish', () => { - this.skip(guild_id, portal_guilds, client, guild_object); - portal_guilds[guild_id].music_data.votes = []; - }); - - return resolve({ result: false, value: 'song has been resumed.' }); - } - } - else if (current_dispatcher === null) { - const next_yts_video = portal_guilds[guild_id].music_queue.shift(); - const voice_connection = client.voice.connections.find(connection => connection.channel.id); - - if (voice_connection) { - portal_guilds[guild_id].dispatcher = voice_connection - .play(ytdl(next_yts_video.url, { filter: 'audioonly' })); - - help_mngr.update_message(portal_guilds[guild_id], guild_object, next_yts_video); - - const stream = ytdl(next_yts_video.url, { - filter: 'audioonly', - opusEncoded: false, - fmt: 'mp3', - }); - - portal_guilds[guild_id].dispatcher = voice_connection.play(stream); - help_mngr.update_message(portal_guilds[guild_id], guild_object, next_yts_video); - portal_guilds[guild_id].dispatcher.on('finish', () => { - this.skip(guild_id, portal_guilds, client, guild_object); - portal_guilds[guild_id].music_data.votes = []; - }); - } - - return resolve({ result: false, value: 'next video playing.' }); - } - else { - return resolve({ result: false, value: 'nothing playing write now.' }); - } - }); - }, - - pause: async function (guild_id, portal_guilds) { - return new Promise((resolve) => { - const current_dispatcher = portal_guilds[guild_id].dispatcher; - - if (current_dispatcher !== null && current_dispatcher !== undefined) { - if (!current_dispatcher.paused) { - current_dispatcher.pause(); - } - return resolve({ result: false, value: 'song has been paused.' }); - } - else { - return resolve({ result: false, value: 'nothing playing write now.' }); - } - }); - }, - - stop: async function (guild_id, portal_guilds, guild_object) { - return new Promise((resolve) => { - const current_dispatcher = portal_guilds[guild_id].dispatcher; - - const portal_icon_url = 'https://raw.githubusercontent.com/keybraker/keybraker' + - '.github.io/master/assets/img/logo.png'; - help_mngr.update_message( - portal_guilds[guild_id], - guild_object, - { - title: 'Music Player', - url: 'just type and I\'ll play', - timestamp: '-', - views: '-', - ago: '-', - thumbnail: portal_icon_url, - }); - - if (current_dispatcher !== null && current_dispatcher !== undefined) { - if (!current_dispatcher.paused) { - current_dispatcher.pause(); - } - portal_guilds[guild_id].dispatcher = null; - return resolve({ result: false, value: 'song has been stopped.' }); - } - else { - portal_guilds[guild_id].dispatcher = null; - return resolve({ result: false, value: 'nothing playing write now.' }); - } - }); - }, - - skip: async function (guild_id, portal_guilds, client, guild_object) { - return new Promise((resolve) => { - const current_dispatcher = portal_guilds[guild_id].dispatcher; - const current_music_queue = portal_guilds[guild_id].music_queue; - - if (current_dispatcher !== null && current_dispatcher !== undefined) { - if (current_music_queue.length > 0) { - const next_yts_video = portal_guilds[guild_id].music_queue.shift(); - const voice_connection = client.voice.connections.find(connection => connection.channel.id); - - if (voice_connection) { - portal_guilds[guild_id].dispatcher = voice_connection - .play(ytdl(next_yts_video.url, { filter: 'audioonly' })); - - help_mngr.update_message(portal_guilds[guild_id], guild_object, next_yts_video); - - const stream = ytdl(next_yts_video.url, { - filter: 'audioonly', - opusEncoded: false, - fmt: 'mp3', - }); - - portal_guilds[guild_id].dispatcher = voice_connection.play(stream); - help_mngr.update_message(portal_guilds[guild_id], guild_object, next_yts_video); - portal_guilds[guild_id].dispatcher.on('finish', () => { - this.skip(guild_id, portal_guilds, client, guild_object); - portal_guilds[guild_id].music_data.votes = []; - }); - } - } - else { - const portal_icon_url = 'https://raw.githubusercontent.com/keybraker/keybraker' + - '.github.io/master/assets/img/logo.png'; - help_mngr.update_message(portal_guilds[guild_id], - guild_object, - { - title: 'Music Player', - url: 'just type and I\'ll play', - timestamp: '-', - views: '-', - ago: '-', - thumbnail: portal_icon_url, - }); - if (!current_dispatcher.paused) { - current_dispatcher.pause(); - } - portal_guilds[guild_id].dispatcher = null; - return resolve({ result: false, value: 'music list is empty' }); - } - - return resolve({ result: false, value: 'song has been skipped.' }); - } - else { - return resolve({ result: false, value: 'nothing playing write now.' }); - } - }); - } - , -}; diff --git a/src/functions/status_manager.js b/src/functions/status_manager.js deleted file mode 100644 index 1f0e098a..00000000 --- a/src/functions/status_manager.js +++ /dev/null @@ -1,79 +0,0 @@ -const games = require('../../assets/jsons/game_list.json'); -const programs = require('../../assets/jsons/program_list.json'); - -module.exports = { - status_aliases: function (activities, locale) { - const new_status = []; - - activities.forEach(activity => { - let found = false; - for (let l = 0; l < games.game_attributes.length; l++) { - if (activity.name == games.game_attributes[l].status) { - if (locale === 'gr') { - new_status.push(games.game_attributes[l].locale.gr); - found = true; - } - else { - new_status.push(games.game_attributes[l].locale.en); - found = true; - } - } - } - - if (!found) { - for (let l = 0; l < programs.program_attributes.length; l++) { - if (activity.name == programs.program_attributes[l].status) { - if (locale === 'gr') { - new_status.push(programs.program_attributes[l].locale.gr); - found = true; - } - else { - new_status.push(programs.program_attributes[l].locale.en); - found = true; - } - } - } - } - - if (!found) { - new_status.push(activity.name); - } - }); - - return new_status; - }, - - get_status_list: function (voice_channel, voice_object) { - const array_of_statuses = []; - - voice_channel.members.forEach(member => { - if (!member.user.bot) { - if (member.presence.activities !== undefined) { - if (member.presence.activities.length > 0) { - this.status_aliases(member.presence.activities, voice_object.locale) - .forEach(stat => { - if (!array_of_statuses.includes(stat)) { - array_of_statuses.push(stat); - } - }); - } - } - } - }); - - if (array_of_statuses.length === 0) { - if (voice_object.locale === 'gr') { - array_of_statuses.push('Άραγμα'); - } - else if (voice_object.locale === 'de') { - array_of_statuses.push('Chillen'); - } - else { - array_of_statuses.push('Chilling'); - } - } - - return array_of_statuses; - }, - -}; diff --git a/src/functions/user_manager.js b/src/functions/user_manager.js deleted file mode 100644 index 1bcedc1c..00000000 --- a/src/functions/user_manager.js +++ /dev/null @@ -1,120 +0,0 @@ -/* eslint-disable no-undef */ -const help_mngr = require('./../functions/help_manager'); - -level_speed = { 'slow': 0.01, 'normal': 0.05, 'fast': 0.1 }; - -module.exports = -{ - give_role_from_rankup: function (user, member, ranks, guild) { - if (ranks) return; - const new_rank = ranks.find(rank => rank.level === user.level); - if (new_rank === null || new_rank === undefined) return; - - const new_role = guild.roles.cache.find(role => role.id === new_rank.id); - if (new_role === null || new_role === undefined) return; - - if (!member.roles.cache.some(role => role === new_role)) { member.roles.add(new_role); } - }, - - calculate_rank: function (user) { - if (user.points >= user.tier * 1000) { - user.points -= user.tier * 1000; - user.level++; - if (user.level % 5 === 0) { - user.tier++; - } - - return user.level; - } - }, - - add_points_time: function (user, speed) { - const voice_time = help_mngr.time_elapsed(user.timestamp, 0); - - user.points += Math.round(voice_time.remaining_sec * level_speed[speed]); - user.points += Math.round(voice_time.remaining_min * level_speed[speed] * 60 * 1.15); - user.points += Math.round(voice_time.remaining_hrs * level_speed[speed] * 60 * 60 * 1.25); - - user.timestamp = null; - }, - - update_timestamp: function (voiceState, guild_list) { - if (voiceState.member.user.bot) return; - - const guild = voiceState.guild; - const ranks = guild_list[voiceState.guild.id].ranks; - const user = guild_list[voiceState.guild.id].member_list[voiceState.member.id]; - const member = voiceState.member; - const speed = guild_list[voiceState.guild.id].level_speed; - const cached_level = user.level; - - if (user.timestamp === null) { - user.timestamp = new Date(); - return false; - } - - this.add_points_time(user, speed, ranks); - this.calculate_rank(user); - this.give_role_from_rankup(user, member, ranks, guild); - - if (user.level > cached_level) { return user.level; } - return false; - }, - - add_points_message: function (message, guild_list) { - const user = guild_list[message.guild.id].member_list[message.author.id]; - const speed = guild_list[message.guild.id].level_speed; - const points = message.content.length * level_speed[speed]; - - user.points += points > 5 ? 5 : Math.round(points); - const level = this.calculate_rank(user); - if (level) { - return level; - } - - return false; - }, - - kick: function (message, args) { - // This command must be limited to mods and admins. In this example we just hardcode the role names. - // Please read on Array.some() to understand this bit: - // https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Array/some? - if (!message.member.roles.some(r => ['Administrator', 'Moderator'].includes(r.name))) { return message.reply('Sorry, you don\'t have permissions to use this!'); } - - // Let's first check if we have a member and if we can kick them! - // message.mentions.members is a collection of people that have been mentioned, as GuildMembers. - // We can also support getting the member by ID, which would be args[0] - const member = message.mentions.members.first() || message.guild.members.get(args[0]); - if (!member) { return message.reply('Please mention a valid member of this server'); } - if (!member.kickable) { return message.reply('I cannot kick this user! Do they have a higher role? Do I have kick permissions?'); } - - // slice(1) removes the first part, which here should be the user mention or ID - // join(' ') takes all the various parts to make it a single string. - let reason = args.slice(1).join(' '); - if (!reason) reason = 'No reason provided'; - - // Now, time for a swift kick in the nuts! - // await member.kick(reason) - member.kick(reason) - .catch(error => message.reply(`Sorry ${message.author} I couldn't kick because of : ${error}`)); - message.reply(`${member.user.tag} has been kicked by ${message.author.tag} because: ${reason}`); - }, - - ban: function (message, args) { - // Most of this command is identical to kick, except that here we'll only let admins do it. - // In the real world mods could ban too, but this is just an example, right? ;) - if (!message.member.roles.some(r => ['Administrator'].includes(r.name))) { return message.reply('Sorry, you don\'t have permissions to use this!'); } - - const member = message.mentions.members.first(); - if (!member) { return message.reply('Please mention a valid member of this server'); } - if (!member.bannable) { return message.reply('I cannot ban this user! Do they have a higher role? Do I have ban permissions?'); } - - let reason = args.slice(1).join(' '); - if (!reason) reason = 'No reason provided'; - - // await member.ban(reason) - member.ban(reason) - .catch(error => message.reply(`Sorry ${message.author} I couldn't ban because of : ${error}`)); - message.reply(`${member.user.tag} has been banned by ${message.author.tag} because: ${reason}`); - }, -}; \ No newline at end of file diff --git a/src/libraries/guildOps.ts b/src/libraries/guildOps.ts new file mode 100644 index 00000000..99a368fb --- /dev/null +++ b/src/libraries/guildOps.ts @@ -0,0 +1,678 @@ +import { + CategoryChannel, Collection, CollectorFilter, Guild, GuildChannel, GuildCreateChannelOptions, + GuildMember, Message, MessageCollector, Role, TextChannel, VoiceChannel, VoiceState +} from "discord.js"; +import voca from 'voca'; +import { GuildPrtl } from '../types/classes/GuildPrtl'; +import { PortalChannelPrtl } from '../types/classes/PortalChannelPrtl'; +import { VoiceChannelPrtl } from '../types/classes/VoiceChannelPrtl'; +import { attribute_prefix, get_attribute, is_attribute } from '../types/interfaces/Attribute'; +import { ReturnPormise } from "../types/interfaces/InterfacesPrtl"; +import { get_pipe, is_pipe, pipe_prefix } from '../types/interfaces/Pipe'; +import { get_variable, is_variable, variable_prefix } from '../types/interfaces/Variable'; +import { create_music_message, getJSON, inline_operator } from './helpOps'; +import { stop } from './musicOps'; + +export function getOptions(guild: Guild, topic: string, can_write: boolean): GuildCreateChannelOptions { + if (can_write) + return { + topic: `by Portal, ${topic}`, + type: 'text', + nsfw: false + }; + else + return { + permissionOverwrites: [ + { + id: guild.id, + deny: ['SEND_MESSAGES'], + } + ], + topic: `by Portal, ${topic}`, + type: 'text', + nsfw: false + }; +}; + +export function included_in_portal_guilds(guild_id: string, guild_list: GuildPrtl[]): boolean { + return guild_list.some(g => g.id === guild_id); +}; + +export function included_in_portal_list(channel_id: string, portal_list: PortalChannelPrtl[]): boolean { + return portal_list.some(p => p.id === channel_id); +}; + +export function included_in_voice_list(channel_id: string, portal_list: PortalChannelPrtl[]): boolean { + return portal_list.some(p => p.voice_list.some(v => v.id === channel_id)); +}; + +export function included_in_url_list(channel_id: string, guild_object: GuildPrtl): boolean { + return guild_object.url_list.some(u => u === channel_id); +}; + +export function is_spotify_channel(channel_id: string, guild_object: GuildPrtl): boolean { + return guild_object.spotify === channel_id; +}; + +export function is_music_channel(channel_id: string, guild_object: GuildPrtl): boolean { + return guild_object.music_data.channel_id === channel_id; +}; + +export function is_announcement_channel(channel_id: string, guild_object: GuildPrtl): boolean { + return guild_object.announcement === channel_id; +}; + +// + +export function get_role(guild: Guild, role_name_or_name: string): Role | undefined { + return guild.roles.cache.find(cached_role => + cached_role.id === role_name_or_name || cached_role.name === role_name_or_name + ); +}; + +export function get_role_name(role_id: string, i: number, message: Message) { + const role = message?.guild?.roles.cache.find(r => r.id === role_id); + return role ? `${i + 1}. ${role.name}` : `${i + 1}. undefined`; +}; + +// + +export async function create_channel(guild: Guild, channel_name: string, channel_options: GuildCreateChannelOptions, + channel_category: string | CategoryChannel | null): Promise { + return new Promise((resolve) => { + console.log('channel_name :>> ', channel_name); + guild.channels + .create(channel_name, channel_options) + .then(new_channel => { + if (channel_category === null) { // does not want category + return resolve({ result: true, value: new_channel.id }); + } else { + if (typeof channel_category === "string") { // create category + guild.channels + .create(channel_category, { type: 'category' }) + .then(category => { + new_channel.setParent(category); + return resolve({ result: true, value: new_channel.id }); + }) + .catch(error => { + return resolve({ result: false, value: `CH/CR/000: ${error}` }); + }); + } else { + new_channel.setParent(channel_category); + return resolve({ result: true, value: new_channel.id }); + } + } + }) + .catch(error => { + return resolve({ result: false, value: `CH/CR/001: ${error}` }); + }); + }); +} + +export function create_portal_channel(guild: Guild, portal_channel: string, + portal_category: string | CategoryChannel | null, portal_object: any, + guild_object: GuildPrtl, creator_id: string): void { + + const voice_name = guild_object.premium + ? 'G$#-P$member_count | $status_list' + : 'Channel $#' + + if (portal_category && typeof portal_category === 'string') { // with category + guild.channels + .create(portal_channel, { type: 'voice', bitrate: 64000, userLimit: 1 }) + .then(channel => { + portal_object.push(new PortalChannelPrtl( + channel.id, + creator_id, + portal_channel, + voice_name, + [], + false, + 2, + 0, + 0, + guild_object.locale, + true, + true, + 0 + )); + guild.channels + .create(portal_category, { type: 'category' }) + .then(cat_channel => channel.setParent(cat_channel)) + .catch(console.error); + }) + .catch(console.error); + } + else if (portal_category) { // with category given + guild.channels + .create(portal_channel, { type: 'voice', bitrate: 64000, userLimit: 1, parent: portal_category }) + .then(channel => { + channel.setParent(portal_category); + portal_object.push(new PortalChannelPrtl( + channel.id, + creator_id, + portal_channel, + voice_name, + [], + false, + 2, + 0, + 0, + guild_object.locale, + true, + true, + 0 + )); + }) + .catch(console.error); + } + else { // without category + guild.channels + .create(portal_channel, { type: 'voice', bitrate: 64000, userLimit: 1 }) + .then(channel => { + portal_object.push(new PortalChannelPrtl( + channel.id, + creator_id, + portal_channel, + voice_name, + [], + false, + 2, + 0, + 0, + guild_object.locale, + true, + true, + 0 + )); + }) + .catch(console.error); + } +}; + +export function create_voice_channel(state: VoiceState, portal_object: PortalChannelPrtl, + portal_channel: GuildChannel, creator_id: string): Promise { + return new Promise((resolve) => { + if (state && state.channel) { + const voice_options: GuildCreateChannelOptions = { + type: 'voice', + bitrate: 96000, + userLimit: portal_object.user_limit_portal, + parent: state.channel.parent ? state.channel.parent : undefined + }; + + state.channel.guild.channels + .create('loading...', voice_options) + .then(channel => { + if (state.member) { + portal_object.voice_list.push(new VoiceChannelPrtl( + channel.id, creator_id, portal_object.regex_voice, false, 0, 0, + portal_object.locale, portal_object.ann_announce, portal_object.ann_user + )); + state.member.voice.setChannel(channel); + return resolve({ result: true, value: `created channel and moved member to new voice` }); + } else { + return resolve({ result: false, value: `VC/CR/000: could not fetch member` }); + } + }) + .catch(error => { + return resolve({ result: false, value: `VC/CR/001: ${error}` }); + }); + } + }); +} + +export async function create_music_channel(guild: Guild, music_channel: string, + music_category: string | CategoryChannel | null, guild_object: GuildPrtl): Promise { + const portal_icon_url = 'https://raw.githubusercontent.com/keybraker/keybraker' + + '.github.io/master/assets/img/logo.png'; + return new Promise((resolve) => { + if (music_category && typeof music_category === 'string') { // with category + guild.channels + .create( + `${music_channel}`, + { + type: 'text', + topic: 'Portal Music, play:▶️, pause:⏸, stop:⏹, skip:⏭, list:📜, clear list:❌', + }, + ) + .then((channel: TextChannel) => { + guild_object.music_data.channel_id = channel.id; + guild.channels + .create(music_category, { type: 'category' }) + .then(cat_channel => channel.setParent(cat_channel)) + .catch(error => resolve(error)); + create_music_message(channel, portal_icon_url, guild_object); + }) + .catch(error => resolve(error)); + } + else if (music_category) { // with category object given + guild.channels + .create( + `${music_channel}`, + { + type: 'text', + topic: 'Portal Music, play:▶️, pause:⏸, stop:⏹, skip:⏭, list:📜, clear list:❌', + parent: music_category + }, + ) + .then(channel => { + channel.setParent(music_category); + guild_object.music_data.channel_id = channel.id; + create_music_message(channel, portal_icon_url, guild_object); + }) + .catch(error => resolve(error)); + } + else { // without category + guild.channels + .create( + `${music_channel}`, + { + type: 'text', + topic: 'Portal Music, play:▶️, pause:⏸, stop:⏹, skip:⏭, list:📜, clear list:❌', + }, + ) + .then(channel => { + guild_object.music_data.channel_id = channel.id; + create_music_message(channel, portal_icon_url, guild_object); + }) + .catch(error => resolve(error)); + } + }); +}; + +export async function create_focus_channel(guild: Guild, member: GuildMember, + member_found: GuildMember, focus_time: number): Promise { + return new Promise((resolve) => { + const return_value = { result: false, value: '*you can run "./help focus" for help.*' }; + const oldChannel: VoiceChannel | null = member.voice.channel; + let newChannel: VoiceChannel | null; + + if (!oldChannel) { + return resolve(return_value); + } + + guild.channels.create( + `${member.displayName}&${member_found.displayName}`, { + type: 'voice', + bitrate: 64000, + userLimit: 2, + }) + .then(channel => { + newChannel = channel; + member.voice.setChannel(channel); + member_found.voice.setChannel(channel); + + return_value.result = true; + return_value.value = 'users have been moved.'; + }) + .catch(console.error); + + setTimeout(() => { + if (!oldChannel.deleted) { + member.voice.setChannel(oldChannel) + .then(() => { + member_found.voice.setChannel(oldChannel) + .then(() => { + if (newChannel && newChannel.deletable) { + newChannel.delete().catch(console.error); + return_value.result = true; + return_value.value = 'focus ended properly.'; + return resolve(return_value); + } + }).catch(console.error); + }).catch(console.error); + + } + else { + return_value.result = false; + return_value.value = 'could not move to original channel because it was deleted.'; + return resolve(return_value); + } + }, focus_time * 60 * 1000); + }); +}; + +// + +export function delete_guild(guild_id: string, guild_list: GuildPrtl[]): void { + guild_list.some((g, index) => { + if (g.id === guild_id) + guild_list.splice(index, 1) + + }); +}; + +export function delete_channel(channel_to_delete: VoiceChannel | TextChannel, + message: Message | null, isPortal: boolean = false): void { + if (!isPortal && message !== null) { + const author = message.author; + const channel_to_delete_name = channel_to_delete.name; + let channel_deleted = false; + + message.channel + .send(`${message.author}, do you wish to delete old music channel **"${channel_to_delete}"** (yes / no) ?`) + .then((question_msg: Message) => { + const filter: CollectorFilter = m => m.author.id === author.id; + const collector: MessageCollector = message.channel.createMessageCollector(filter, { time: 10000 }); + + collector.on('collect', (m: Message) => { + if (m.content === 'yes') { + if (channel_to_delete.deletable) { + channel_to_delete + .delete() + .then(g => console.log(`Deleted channel with id: ${g}`)) + .catch(console.error); + + m.channel.send(`Deleted channel **"${channel_to_delete_name}"**.`) + .then(msg => { msg.delete({ timeout: 5000 }); }) + .catch(error => console.log(error)); + + channel_deleted = true; + } + else { + message.channel.send(`Channel **"${channel_to_delete}"** is not deletable.`) + .then(msg => { msg.delete({ timeout: 5000 }); }) + .catch(error => console.log(error)); + } + collector.stop(); + } + else if (m.content === 'no') { + collector.stop(); + } + }); + + collector.on('end', (collected: Collection) => { + collected.forEach((reply_message: Message) => { + if (reply_message.deletable) { + reply_message + .delete() + .catch(console.error); + } + }); + + if (!channel_deleted) { + message.channel.send(`Channel **"${channel_to_delete}"** will not be deleted.`) + .then(msg => { msg.delete({ timeout: 5000 }); }) + .catch(error => console.log(error)); + } + question_msg.delete({ timeout: 5000 }); + }); + }) + .catch(error => console.log(error)); + } + else if (channel_to_delete.deletable) { + channel_to_delete + .delete() + .then(g => console.log(`Deleted channel with id: ${g}`)) + .catch(console.error); + } +}; + +export function channel_deleted_update_state(channel_to_remove: GuildChannel, guild_list: GuildPrtl[]): number { + const TypesOfChannel = { Unknown: 0, Portal: 1, Voice: 2, Url: 3, Spotify: 4, Announcement: 5, Music: 6 }; + const current_guild = guild_list.find(g => g.id === channel_to_remove.guild.id); + + if (!current_guild) { + return -1; + } + + let type_of_channel = TypesOfChannel.Unknown; + + current_guild.portal_list.some((p, index) => { + if (p.id === channel_to_remove.id) { + current_guild.portal_list.splice(index, 1); + type_of_channel = TypesOfChannel.Portal; + return true; + } + return p.voice_list.some((v, index_v) => { + if (v.id === channel_to_remove.id) { + p.voice_list.splice(index_v, 1); + type_of_channel = TypesOfChannel.Voice; + return true; + } + }); + }); + + for (let i = 0; i < current_guild.url_list.length; i++) { + console.log(`${current_guild.url_list[i]} === ${channel_to_remove.id}`); + if (current_guild.url_list[i] === channel_to_remove.id) { + current_guild.url_list.splice(i, 1); + type_of_channel = TypesOfChannel.Url; + break; + } + } + if (current_guild.spotify === channel_to_remove.id) { + current_guild.spotify = null; + type_of_channel = TypesOfChannel.Spotify; + } + if (current_guild.announcement === channel_to_remove.id) { + current_guild.announcement = null; + type_of_channel = TypesOfChannel.Announcement; + } + if (current_guild.music_data.channel_id === channel_to_remove.id) { + stop(channel_to_remove.guild.id, guild_list, channel_to_remove.guild); + current_guild.music_data.channel_id = undefined; + current_guild.music_data.message_id = undefined; + current_guild.music_data.votes = []; + current_guild.dispatcher = undefined; + type_of_channel = TypesOfChannel.Music; + } + + return type_of_channel; +}; + +// + +export function generate_channel_name(voice_channel: VoiceChannel, portal_list: PortalChannelPrtl[], + guild_object: GuildPrtl, guild: Guild): number { + let return_value: number = 0; + portal_list.some(p => { + p.voice_list.some(v => { + if (v.id === voice_channel.id) { + const new_name = regex_interpreter( + v.regex, + voice_channel, + v, + portal_list, + guild_object, + guild, + ); + + if (new_name.length >= 1) { + if (voice_channel.name !== new_name.substring(0, 99)) { + voice_channel.edit({ name: new_name.substring(0, 99) }) + .then(newChannel => console.log(`Voice's new name from promise is ${newChannel.name}`)) + .catch(console.log); + return_value = 1; + } + else { + return_value = 2; + } + } + else { + return_value = 3; + } + } + }); + }); + + return return_value; +}; + +export function regex_interpreter(regex: string, voice_channel: VoiceChannel, voice_object: any, + portal_list: PortalChannelPrtl[], guild_object: GuildPrtl, guild: Guild): string { + + let last_space_index = 0; + let last_vatiable_end_index = 0; + let last_attribute_end_index = 0; + + let last_variable = ''; + let last_attribute = ''; + let new_channel_name = ''; + + for (let i = 0; i < regex.length; i++) { + if (regex[i] === variable_prefix) { + + const vrbl = is_variable(regex.substring(i)); + + if (vrbl.length !== 0) { + const return_value = get_variable(voice_channel, voice_object, portal_list, guild_object, guild, vrbl); + + if (return_value !== null) { + last_variable = return_value; + new_channel_name += return_value; + i += voca.chars(vrbl).length; + last_vatiable_end_index = i; + } + else { + new_channel_name += regex[i]; + } + } + else { + new_channel_name += regex[i]; + } + + } + else if (regex[i] === attribute_prefix) { + const attr = is_attribute(regex.substring(i)); + + if (attr.length !== 0) { + const portal_object = portal_list.find(p => p.voice_list.some(v => v.id === voice_channel.id)); + if (portal_object) { // tsiakkas elegxos oti paizei kala an den to brei + const return_value = get_attribute(voice_channel, voice_object, portal_object, guild_object, attr); + + if (return_value !== null) { + last_attribute = return_value; + new_channel_name += return_value; + i += voca.chars(attr).length; + last_attribute_end_index = i; + } + else { + new_channel_name += regex[i]; + } + } + } + else { + new_channel_name += regex[i]; + } + } + else if (regex[i] === pipe_prefix) { + + const pipe = is_pipe(regex.substring(i)); + + if (pipe.length !== 0) { + if (last_vatiable_end_index + 1 === i) { + + const return_value = get_pipe(last_variable, pipe); + + if (return_value !== null) { + new_channel_name = new_channel_name.substring(0, + voca.chars(new_channel_name).length - voca.chars(last_variable).length); + new_channel_name += return_value; + i += voca.chars(pipe).length; + } + else { + new_channel_name += regex[i]; + } + + } + else if (last_attribute_end_index + 1 === i) { + + const return_value = get_pipe(last_attribute, pipe); + + if (return_value !== null) { + new_channel_name = new_channel_name.substring(0, + voca.chars(new_channel_name).length - voca.chars(last_attribute).length); + new_channel_name += return_value; + i += voca.chars(pipe).length; + } + else { + new_channel_name += regex[i]; + } + + } + else { + + const return_value = get_pipe(new_channel_name.substring(last_space_index, new_channel_name.length), pipe); + + if (return_value !== null) { + const str_for_pipe = return_value; + new_channel_name = new_channel_name.substring(0, last_space_index); + new_channel_name += str_for_pipe; + i += voca.chars(pipe).length; + } + else { + new_channel_name += regex[i]; + } + + } + } + else { + new_channel_name += regex[i]; + } + } + else if (regex[i] === '{' && (regex[i + 1] !== undefined && regex[i + 1] === '{')) { + + try { + // did not put into structure_list due to many unnecessary function calls + let is_valid = false; + const statement = getJSON(regex.substring(i + 1, i + 1 + regex.substring(i + 1).indexOf('}}') + 1)); + if (!statement) { + return 'error'; + } + if (Object.prototype.hasOwnProperty.call(statement, 'if')) { + if (Object.prototype.hasOwnProperty.call(statement, 'is')) { + if (Object.prototype.hasOwnProperty.call(statement, 'with')) { + if (Object.prototype.hasOwnProperty.call(statement, 'yes')) { + if (Object.prototype.hasOwnProperty.call(statement, 'no')) { + is_valid = true; + } + } + } + } + } + + if (!is_valid) { + new_channel_name += regex[i]; + if (regex[i] === ' ') { last_space_index = i + 1; } + } + else { + if (statement.is === "==" || statement.is === "===" || statement.is === "!=" || statement.is === "!==" || + statement.is === ">" || statement.is === "<" || statement.is === ">=" || statement.is === "<=") { + if (inline_operator(statement.is)( + regex_interpreter(statement.if, voice_channel, voice_object, portal_list, guild_object, guild), + regex_interpreter(statement.with, voice_channel, voice_object, portal_list, guild_object, guild)) + ) { + const value = regex_interpreter(statement.yes, voice_channel, voice_object, portal_list, guild_object, guild); + if (value !== '--') { + new_channel_name += value; + } + } + else { + const value = regex_interpreter(statement.no, voice_channel, voice_object, portal_list, guild_object, guild); + if (value !== '--') { + new_channel_name += value; + } + } + i += regex.substring(i + 1).indexOf('}}') + 2; + } else { + return 'error'; + } + } + } + catch (error) { + console.log('ERROR: in JSON parse: ', error); + new_channel_name += regex[i]; + } + + } + else { + new_channel_name += regex[i]; + if (regex[i] === ' ') { last_space_index = i + 1; } + } + } + + if (new_channel_name === '') { return '.'; } + return new_channel_name; +}; \ No newline at end of file diff --git a/src/libraries/helpOps.ts b/src/libraries/helpOps.ts new file mode 100644 index 00000000..636528f4 --- /dev/null +++ b/src/libraries/helpOps.ts @@ -0,0 +1,517 @@ +import { Channel, Client, Guild, GuildChannel, GuildMember, Message, MessageEmbed, TextChannel, User, VoiceConnection } from "discord.js"; +import { cloneDeep } from "lodash"; +import { VideoSearchResult } from "yt-search"; +import { GiveRole, GiveRolePrtl } from "../types/classes/GiveRolePrtl"; +import { GuildPrtl } from "../types/classes/GuildPrtl"; +import { Field, ReturnPormise, ReturnPormiseVoice, TimeElapsed, TimeRemaining } from "../types/interfaces/InterfacesPrtl"; +import { client_talk, client_write } from "./localizationOps"; +import { writeFileSync } from "jsonfile"; + +export function guildPrtl_to_object(guild_list: GuildPrtl[], guild_id: string): GuildPrtl | undefined { + return guild_list.find(g => g.id === guild_id); +}; + +export function create_music_message(channel: TextChannel, thumbnail: string, guild_object: GuildPrtl): void { + const music_message_emb = create_rich_embed( + 'Music Player', + 'just type and I\'ll play', + '#0000FF', + [ + { emote: 'Duration', role: '-', inline: true }, + { emote: 'Views', role: '-', inline: true }, + { emote: 'Uploaded', role: '-', inline: true } + ], + null, + null, + true, + null, + thumbnail + ); + + channel + .send(music_message_emb) + .then(sent_message => { + sent_message.react('▶️'); + sent_message.react('⏸'); + sent_message.react('⏹'); + sent_message.react('⏭'); + sent_message.react('📜'); + sent_message.react('❌'); + + guild_object.music_data.message_id = sent_message.id; + }); +}; + +export function update_message(guild: Guild, guild_object: GuildPrtl, yts: VideoSearchResult): void { + const music_message_emb = create_rich_embed( + yts.title, + yts.url, + '#0000FF', + [ + { emote: 'Duration', role: yts.timestamp, inline: true }, + { emote: 'Views', role: yts.views, inline: true }, + { emote: 'Uploaded', role: yts.ago, inline: true }, + ], + null, + null, + true, + null, + yts.thumbnail + ); + + const guild_channel: GuildChannel | undefined = guild.channels.cache + .find(c => c.id === guild_object.music_data.channel_id); + const channel: TextChannel = guild_channel; + + if (guild_object.music_data.message_id) { + if (channel) { + channel.messages + .fetch(guild_object.music_data.message_id) + .then((message: Message) => { + message.edit(music_message_emb) + .then((msg: Message) => + console.log(`Updated the content of a message to ${msg.content}`) + ) + .catch(console.error); + }) + .catch(console.error); + } + } +}; + +export async function join_user_voice(client: Client, message: Message, guild_list: GuildPrtl[], + join: boolean): Promise { // localize + return new Promise((resolve) => { + if (message.member === null) { + return resolve({ + result: false, + value: 'message has no member.', + voice_connection: undefined + }); + } + + if (message.guild === null) { + return resolve({ + result: false, + value: 'message has no guild.', + voice_connection: undefined + }); + } + + const current_voice = message.member.voice.channel; + + if (current_voice === null) { + return resolve({ + result: false, + value: 'you are not connected to any channel.', + voice_connection: undefined + }); + } + + if (current_voice.guild.id !== message.guild.id) { + return resolve({ + result: false, + value: 'your current channel is on another guild.', + voice_connection: undefined + }); + } + + if (!message || !message.guild) { + return resolve({ + result: false, + value: 'could not find guild of message.', + voice_connection: undefined + }); + } + + const current_guild = guild_list.find(g => { + if (message && message.guild) + return g.id === message.guild.id; + }); + + if (current_guild === undefined) { + return resolve({ + result: false, + value: 'could not find guild of message.', + voice_connection: undefined + }); + } + + const portal_list = current_guild.portal_list; + + const controlled_by_portal = portal_list.some(p => + p.voice_list.some(v => v.id === current_voice.id) + ); + + if (!controlled_by_portal) { + return resolve({ + result: false, + value: 'I can only connect to my channels.', + voice_connection: undefined + }); + } + + if (client.voice === null) { + return resolve({ + result: false, + value: 'Portal is not connected to any voice channel.', + voice_connection: undefined + }); + } + + const existing_voice_connection: VoiceConnection | undefined = client.voice.connections.find(connection => + (message && message.member && message.member.voice && message.member.voice.channel) + ? (connection.channel.id === message.member.voice.channel.id) + : false + ); + + if (existing_voice_connection) { + existing_voice_connection?.voice?.setSelfDeaf(true); + return resolve({ + result: true, + value: 'already in voice channel', + voice_connection: existing_voice_connection + }); + } else { + // let new_voice_connection = null; + current_voice.join() + .then(conn => { + if (join) client_talk(client, guild_list, 'join'); + conn?.voice?.setSelfDeaf(true); + + return resolve({ + result: true, + value: client_write(message, guild_list, 'join'), + voice_connection: conn, + }); + }) + .catch(e => { console.log('ERROR CREATING VOICE CONNECTION TO CHANNEL: ', e); }); + } + }); +}; + +export function inline_operator(str: string): any { + switch (str) { + case '==': + (a: string, b: string) => a == b; + case '===': + (a: string, b: string) => a === b; + case '!=': + (a: string, b: string) => a != b; + case '!==': + (a: string, b: string) => a !== b; + case '>': + (a: string, b: string) => a > b; + case '<': + (a: string, b: string) => a < b; + case '>=': + (a: string, b: string) => a >= b; + case '<=': + (a: string, b: string) => a <= b; + }; +}; + +export function getJSON(str: string): any | null { + let data = null; + try { + data = JSON.parse(str); + } + catch (error) { + return null; + } + return data; +}; + +export function create_rich_embed(title: string | null | undefined, description: string | null | undefined, colour: string | null | undefined, + field_array: Field[], thumbnail: string | null | undefined, member: GuildMember | null | undefined, from_bot: boolean | null | undefined, + url: string | null | undefined, image: string | null | undefined): MessageEmbed { + const portal_icon_url: string = 'https://raw.githubusercontent.com/keybraker/keybraker' + + '.github.io/master/assets/img/logo.png'; + const keybraker_url: string = 'https://github.com/keybraker'; + + const rich_message: MessageEmbed = new MessageEmbed() + .setTimestamp(); + // .setAuthor('Portal', portal_icon_url, keybraker_url) + + if (title) rich_message.setTitle(title); + if (url) rich_message.setURL(url); + if (colour) rich_message.setColor(colour); + if (description) rich_message.setDescription(description); + if (from_bot) rich_message.setFooter('Portal bot by Keybraker', portal_icon_url); + if (thumbnail) rich_message.setThumbnail(thumbnail); + if (image) rich_message.setImage(image); + if (member) { + const url = member.user.avatarURL() !== null + ? member.user.avatarURL() + : undefined; + rich_message + .setAuthor(member.displayName, url !== null ? url : undefined, undefined); + } + if (field_array) { + field_array.forEach(row => { + rich_message + .addField( + (row.emote === '' || row.emote === null || row.emote === false) + ? '\u200b' + : '__' + row.emote + '__', + (row.role === '' || row.role === null || row.role === false) + ? '\u200b' + : '' + row.role + '', + row.inline, + ); + }); + } + else { + rich_message.addField('\u200b', '\u200b'); + } + + return rich_message; +}; + +export async function update_portal_managed_guilds( + force: boolean, portal_managed_guilds_path: string, guild_list: GuildPrtl[] +): Promise { + return new Promise((resolve) => { // , reject) => { + setTimeout(() => { + const guild_list_no_voice = cloneDeep(guild_list); + guild_list_no_voice.forEach(g => g.dispatcher = undefined); + console.log('JSON.stringify(guild_list_no_voice) :\n', JSON.stringify(guild_list_no_voice), '\n'); + + writeFileSync(portal_managed_guilds_path, guild_list_no_voice); + + // const write_options: WriteFileOptions = { + // encoding: 'utf8' + // }; + + // writeFileSync( + // portal_managed_guilds_path, + // JSON.stringify(guild_list_no_voice), + // write_options + // ); + + }, 1000); + return resolve({ result: true, value: 'updated portal guild json' }); + }); +}; + +export function is_authorised(guild_object: GuildPrtl, member: GuildMember): boolean { + if (member.hasPermission('ADMINISTRATOR')) return true; + if (member.roles.cache !== undefined && member.roles.cache !== null) { + const has_authorised_role = member.roles.cache.some(role => + guild_object.auth_role + ? guild_object.auth_role.some((auth: string) => auth === role.id) + : false + ); + if (has_authorised_role) return true; + } + if (member.roles.cache !== undefined && member.roles.cache !== null) { + const is_authorised_member = guild_object.member_list.some(m => { + if (m.id === member.id) + if (m.admin) + return true; + return false; + }); + if (is_authorised_member) return true; + } + + return false; +}; + +// channel should be removed ! +export function message_reply(status: boolean, channel: Channel, message: Message, user: User, str: string, guild_list: GuildPrtl[], + client: Client, to_delete: boolean = false, emote_pass: string = '✔️', emote_fail: string = '❌'): void { + if (!message.channel.deleted && str !== null) { + message.channel + .send(`${user}, ${str}`) + .then(msg => { msg.delete({ timeout: 5000 }); }) + .catch(error => console.log(error)); + } + if (!message.deleted) { + if (status === true) { + message + .react(emote_pass) + .catch(error => console.log(error)); + } + else if (status === false) { + client_talk(client, guild_list, 'fail'); + message + .react(emote_fail) + .catch(error => console.log(error)); + } + if (to_delete) { + message + .delete({ timeout: 5000 }) + .catch(error => console.log(error)); + } + } +}; + +export function is_url(potential_url: string): boolean { + const pattern = new RegExp('^(https?:\\/\\/)?' + // protocol + '((([a-z\\d]([a-z\\d-]*[a-z\\d])*)\\.)+[a-z]{2,}|' + // domain name + '((\\d{1,3}\\.){3}\\d{1,3}))' + // OR ip (v4) address + '(\\:\\d+)?(\\/[-a-z\\d%_.~+]*)*' + // port and path + '(\\?[;&a-z\\d%_.~+=-]*)?' + // query string + '(\\#[-a-z\\d_]*)?$', 'i'); // fragment locator + + return pattern.test(potential_url); +}; + +export function pad(num: number): string { + if (num.toString().length >= 2) { + return '' + num; + } + else { + return '0' + num; + } +}; + +export function time_elapsed(timestamp: Date | number, timeout: number): TimeElapsed { + const time_elapsed = Date.now() - (typeof timestamp === 'number' ? timestamp : timestamp.getTime()); + const timeout_time = timeout * 60 * 1000; + + const timeout_min = Math.round((timeout_time / 1000 / 60)) > 0 + ? Math.round((timeout_time / 1000 / 60)) + : 0; + const timeout_sec = Math.round((timeout_time / 1000) % 60); + + const remaining_hrs = Math.round( + (time_elapsed / 1000 / 60 / 60)) > 0 + ? Math.round((time_elapsed / 1000 / 60 / 60)) + : 0; + const remaining_min = Math.round( + (time_elapsed / 1000 / 60) - 1) > 0 + ? Math.round((time_elapsed / 1000 / 60) - 1) + : 0; + const remaining_sec = Math.round( + (time_elapsed / 1000) % 60) > 0 + ? Math.round((time_elapsed / 1000) % 60) + : 0; + + return { timeout_min, timeout_sec, remaining_hrs, remaining_min, remaining_sec }; +}; + +export function time_remaining(timestamp: number, timeout: number): TimeRemaining { + const time_elapsed = Date.now() - timestamp; + const timeout_time = timeout * 60 * 1000; + const time_remaining = timeout_time - time_elapsed; + + const timeout_min = Math.round((timeout_time / 1000 / 60)) > 0 + ? Math.round((timeout_time / 1000 / 60)) + : 0; + const timeout_sec = Math.round((timeout_time / 1000) % 60) + ? Math.round((timeout_time / 1000) % 60) + : 0; + const remaining_min = Math.round((time_remaining / 1000 / 60) - 1) > 0 + ? Math.round((time_remaining / 1000 / 60) - 1) + : 0; + + const remaining_sec = Math.round((time_remaining / 1000) % 60); + + return { timeout_min, timeout_sec, remaining_min, remaining_sec }; +}; + +export function remove_deleted_guild(guild: Guild, guild_list: GuildPrtl[]): boolean { + if (!guild_list.some(g => g.id === guild.id)) { + guild.leave() + .then(guild => console.log(`left guild ${guild}`)) + .catch(console.error); + return true; + } + return false; +} + +export function remove_deleted_channels(guild: Guild, guild_list: GuildPrtl[]): void { + const guild_object = guild_list.find(g => g.id === guild.id); + if (guild_object) { + guild_object.portal_list.forEach((p, index_p) => { + if (!guild.channels.cache.some(c => c.id === p.id)) { + guild_object.portal_list.splice(index_p, 1); + } + p.voice_list.forEach((v, index_v) => { + if (!guild.channels.cache.some(c => c.id === v.id)) { + p.voice_list.splice(index_v, 1); + } + }); + }); + + guild_object.url_list.some((u_id, index_u) => { + if (!guild.channels.cache.some(c => c.id === u_id)) { + guild_object.url_list.splice(index_u, 1); + return true; + } + return false; + }); + + guild_object.role_list.forEach((r, index_r) => { + !guild.channels.cache.some(c => { + if (c instanceof TextChannel) { + let found = false; + c.messages + .fetch(r.message_id) + .then((message: Message) => { + // clear from emotes leave only those from portal + found = true; + }) + .catch(() => { + guild_object.role_list.splice(index_r, 1); + }); + return found; + } + return false; + }); + }); + + guild_object.member_list.some((m, index_m) => { + if (!guild.members.cache.some(m => m.id === m.id)) { + guild_object.url_list.splice(index_m, 1); + return true; + } + return false; + }); + + if (!guild.channels.cache.some(c => c.id === guild_object.spotify)) { + guild_object.spotify = null; + } + + if (!guild.channels.cache.some(c => c.id === guild_object.music_data.channel_id)) { + guild_object.music_data.channel_id = undefined; + guild_object.music_data.message_id = undefined; + guild_object.music_data.votes = undefined; + } + + if (!guild.channels.cache.some(c => c.id === guild_object.announcement)) { + guild_object.announcement = null; + } + } +} + +export function remove_empty_voice_channels(guild: Guild, guild_list: GuildPrtl[]): void { + guild.channels.cache.forEach(channel => { + if (!channel.members.size) { + const deleted = guild_list.some(g => + g.portal_list.some(p => + p.voice_list.some((v, index) => { + if (v.id === channel.id) { + console.log(`Deleting channel: ${channel.name} (${channel.id}) from ${channel.guild.name}`); + if (channel.deletable) { + channel + .delete() + .then(g => { + p.voice_list.splice(index, 1); + console.log('...done'); + }) + .catch(console.error); + } + return true; + } + return false + }) + ) + ); + + if (!deleted) + console.log('failed to delete channel'); + } + }); +}; \ No newline at end of file diff --git a/src/libraries/httpOps.ts b/src/libraries/httpOps.ts new file mode 100644 index 00000000..d2f3875a --- /dev/null +++ b/src/libraries/httpOps.ts @@ -0,0 +1,16 @@ +import https, { RequestOptions } from 'https'; +import { URL } from 'url'; + +export async function https_fetch(options: string | RequestOptions | URL): Promise { + return new Promise((resolve, reject) => { + const req = https.request(options, function (res) { + const chunks: Uint8Array[] = []; + + res.on('data', function (chunk: any) { chunks.push(chunk); }); + res.on('end', function (chunk: any) { return resolve(Buffer.concat(chunks)); }); + res.on('error', function (error) { return reject(false); }); + }); + + req.end(); + }); +} diff --git a/src/libraries/localizationOps.ts b/src/libraries/localizationOps.ts new file mode 100644 index 00000000..aec3ce56 --- /dev/null +++ b/src/libraries/localizationOps.ts @@ -0,0 +1,238 @@ +import { Client, Message, User } from "discord.js"; +import { GuildPrtl } from "../types/classes/GuildPrtl"; +import { VoiceChannelPrtl } from "../types/classes/VoiceChannelPrtl"; +import { LocalizationOption } from "../types/interfaces/InterfacesPrtl"; + +const type_of_announcement = ['fail', 'announce', 'spotify', 'url', 'read_only', 'join', 'leave']; +const type_of_action = ['user_connected', 'user_disconnected']; +export const portal: LocalizationOption[] = [ + { + name: 'join', + lang: { + gr: () => { return 'Γειά σας, το Πόρταλ είναι εδώ.'; }, + en: () => { return 'Cheers love, Portal\'s here.'; }, + de: () => { return 'Hallo, Portal ist da.'; } + } + }, + { + name: 'leave', + lang: { + gr: () => { return 'Αποχαιρετώ, καλή συνέχεια σε όλους.'; }, + en: () => { return 'Goodbye everyone.'; }, + de: () => { return 'Auf Wiedersehen alle.'; } + } + }, + { + name: 'announce', + lang: { + gr: (user: User) => { return `O ${user} έκανε μια ανακοίνωση.`; }, + en: (user: User) => { return `${user} made an announcement.`; }, + de: (user: User) => { return `${user} hat eine Ankündigung gemacht.`; } + } + }, + { + name: 'spotify', + lang: { + gr: (user: User) => { return `O ${user} έβαλε νέο κομμάτι.`; }, + en: (user: User) => { return `${user} listens to a new song.`; }, + de: (user: User) => { return `${user} hört sich ein neues Lied an.`; } + } + }, + { + name: 'url', + lang: { + gr: (user: User) => { return `O ${user} ανέβασε έναν νέο σύνδεσμο.`; }, + en: (user: User) => { return `${user} sent a new link.`; }, + de: (user: User) => { return `${user} hat einen neuen Link geschickt.`; } + } + }, + { + name: 'read_only', + lang: { + gr: (user: User) => { return `${user}, το κανάλι είναι μόνο για ανάγνωση.`; }, + en: (user: User) => { return `${user}, the channel is read-only.`; }, + de: (user: User) => { return `${user}, der Kanal ist schreibgeschütz.`; } + } + }, + { + name: 'fail', + lang: { + gr: (user: User) => { return `${user}, κάτι δεν πήγε καλά.`; }, + en: (user: User) => { return `${user}, something went wrong.`; }, + de: (user: User) => { return `${user}, etwas ist schief gelaufen.`; } + } + }, + { + name: 'user_connected', + lang: { + gr: (user: User) => { return `Ο χρήστης ${user} συνδέθηκε στο κανάλι.`; }, + en: (user: User) => { return `User ${user} connected to the channel.`; }, + de: (user: User) => { return `Mitglied ${user} hat sich zum Kanal verbunden.`; } + } + }, + { + name: 'user_disconnected', + lang: { + gr: (user: User) => { return `Ο χρήστης ${user} αποχώρησε από το κανάλι.`; }, + en: (user: User) => { return `User ${user} disconnected from the channel.`; }, + de: (user: User) => { return `Mitglied ${user} hat sich vom Kanal unverbunden.`; } + } + } +] +export const console_text: LocalizationOption[] = [ + { + name: 'ready', + lang: { + gr: (args: any) => { + return `Το μποτ ξεκίνησε, με ${args.a} χρήστες, μέσα σε ` + + `${args.b} κανάλια σε ${args.c} συντεχνίες.`; + }, + en: (args: any) => { + return `Bot has started, with ${args.a} users, ` + + `in ${args.b} channels from ${args.c} guilds.`; + }, + de: (args: any) => { + return `Bot hat ${args.a} Mitglieder in ${args.b} ` + + `Kanälen von ${args.c} Gilden gestartet.`; + } + } + + }, + { + name: 'updating_guild', + lang: { + + gr: (args: any) => { return '> Το αρχείο JSON των συντεχνιών ενημερώθηκε.'; }, + en: (args: any) => { return '> Guild JSON file has been updated.'; }, + de: (args: any) => { return '> Die JSON Datei der Gilde wurde aktualisiert.'; }, + } + }, + { + name: 'presence_controlled_away', + lang: { + gr: (args: any) => { + return `Ο χρήστης ${args.newPresence.member.displayName} είναι μέλος ` + + `μια ελεγχόμενης συντεχνίας, έχει αλλάξει κατάσταση, αλλά βρίσκεται στη συντεχνία ` + + `(${args.newPresence.guild.name})`; + }, + en: (args: any) => { + return `${args.newPresence.member.displayName} who is a member of a handled server, ` + + `has changed presence, but is in another server (${args.newPresence.guild.name})`; + }, + de: (args: any) => { + return `${args.newPresence.member.displayName} who is a member of a handled server, ` + + `has changed presence, but is in another server (${args.newPresence.guild.name})`; + } + } + }, + { + name: 'presence_controlled', + lang: { + gr: (args: any) => { + return `Ο χρήστης ${args.a} έχει αλλάξει κατάσταση, ` + + `και βρίσκεται στην ελεγχόμενη συντεχνία (${args.b})`; + }, + en: (args: any) => { + return `${args.a} has changed presence, ` + + `in controlled server (${args.b})`; + }, + de: (args: any) => { + return `${args.a} has changed presence, ` + + `in controlled server (${args.b})`; + } + } + } +] + +export function client_talk(client: Client, guild_list: GuildPrtl[], context: string): boolean { + const voiceConnection = client?.voice?.connections.find(connection => !!connection.channel.id); + + if (voiceConnection) { + return guild_list.some(g => + g.portal_list.some(p => + p.voice_list.some(v => { + if (!g.dispatcher) { + if (type_of_announcement.includes(context) && v.ann_announce) { + const locale = v.locale; + const random = Math.floor(Math.random() * Math.floor(3)); + console.log(`I will play: src/assets/mp3s/${locale}/${context}/${context}_${random}.mp3`); + voiceConnection.play(`src/assets/mp3s/${locale}/${context}/${context}_${random}.mp3`); + return true; + } + else if (type_of_action.includes(context) && v.ann_user) { + const locale = v.locale; + const random = Math.floor(Math.random() * Math.floor(3)); + console.log(`I will play: src/assets/mp3s/${locale}/${context}/${context}_${random}.mp3`); + voiceConnection.play(`src/assets/mp3s/${locale}/${context}/${context}_${random}.mp3`); + return true; + } + } + return v.id === voiceConnection.channel.id; + }) + ) + ); + } + + return false; +}; + +export function client_write(message: Message, guild_list: GuildPrtl[], context: string): string { + if (message === null) return 'could not fetch message'; + if (message.member === null) return 'could not fetch member'; + if (message.member.voice === undefined) return 'coud not fetch voice'; + if (message.member.voice === null) return 'coud not fetch voice'; + + let return_value = 'could not find data'; + + const found = guild_list.some(g => + g.portal_list.some(p => + p.voice_list.some(v => { + if (message.member && message.member.voice.channel) { + if (v.id === message.member.voice.channel.id) { // message.author.presence.member.voice.channel.id) { + switch (v.locale) { + case 'gr': return_value = portal.find(p => p.name === context)?.lang.gr(); break; + case 'en': return_value = portal.find(p => p.name === context)?.lang.en(); break; + case 'de': return_value = portal.find(p => p.name === context)?.lang.de(); break; + } + return true; + } + } + return false; + }) + ) + ); + + if (found) + return return_value + else + return 'there was an error'; +}; + +export function client_log( + message: Message | null, guild_list: GuildPrtl[], context: string, args: any): string { + if (message === null || message.member === null) { + return 'there was an error'; + } + if (message.member.voice === undefined || message.member.voice === null) { + return 'there was an error'; + } + + guild_list.some(g => + g.portal_list.some(p => + p.voice_list.some(v => { + if (message.member && message.member.voice.channel) { + if (v.id === message.member.voice.channel.id) { // message.author.presence.member.voice.channel.id) { + switch (v.locale) { + case 'gr': return console_text.find(c => c.name === context)?.lang.gr(args); + case 'en': return console_text.find(c => c.name === context)?.lang.en(args); + case 'de': return console_text.find(c => c.name === context)?.lang.de(args); + } + } + } + }) + ) + ); + + return 'there was an error'; +}; + diff --git a/src/libraries/modOps.ts b/src/libraries/modOps.ts new file mode 100644 index 00000000..cde98b4d --- /dev/null +++ b/src/libraries/modOps.ts @@ -0,0 +1,38 @@ +/* eslint-disable no-unused-vars */ +import profane_word_list from '../assets/jsons/profane_word_list.json'; +import { Language } from '../types/interfaces/InterfacesPrtl'; + +const profane_words: Language = profane_word_list; + +/** + * Determine if a string contains profane language. + * @param {string} string - String to evaluate for profanity. + * + * https://github.com/web-mech/badwords + */ +export function isProfane(string: string): boolean { + if(string === 'role_assigner') return false; + + const str_array = [string]; + + for (let i = 0; i < string.length; i++) { + str_array.push(string.substr(0, i)); + str_array.push(string.substr(i, string.length - 1)); + } + + return Object.getOwnPropertyNames(profane_word_list).some((lang: string) => { + const gr = profane_words.gr.filter((word: string) => { + return str_array.some(str => str === word); + }).length > 0 || false; + const en = profane_words.en.filter((word: string) => { + const word_exp = new RegExp(`\\b(\\w*${word}\\w*)\\b`, 'gi'); + return word_exp.test(string); + }).length > 0 || false; + const de = profane_words.de.filter((word: string) => { + const word_exp = new RegExp(`\\b(\\w*${word}\\w*)\\b`, 'gi'); + return word_exp.test(string); + }).length > 0 || false; + + return gr || en || de; + }); +}; \ No newline at end of file diff --git a/src/libraries/musicOps.ts b/src/libraries/musicOps.ts new file mode 100644 index 00000000..b93629a9 --- /dev/null +++ b/src/libraries/musicOps.ts @@ -0,0 +1,310 @@ +import ytdl from 'discord-ytdl-core'; +import { Client, Guild, Message, VoiceConnection } from "discord.js"; +import yts from 'yt-search'; +import { GuildPrtl } from "../types/classes/GuildPrtl"; +import { ReturnPormise } from "../types/interfaces/InterfacesPrtl"; +import { join_user_voice, update_message } from './helpOps'; + + +// const ytdl = require('ytdl-core'); + +export async function start(client: Client, message: Message, search_term: string, guild_list: GuildPrtl[]): Promise { + return new Promise((resolve) => { + if (!search_term || search_term === '') { + console.log('cannot search for nothing.'); + return resolve({ result: false, value: 'cannot search for nothing.' }); + } + if (!message.member) { + console.log('member has left the guild.'); + return resolve({ result: false, value: 'member has left the guild.' }); + } + if (!message.member.voice.channel) { + console.log('you are not connected to any channel.'); + return resolve({ result: false, value: 'you are not connected to any channel.' }); + } + + const guild_id = message.member.voice.channel.guild.id; + const guild_object = guild_list.find(guild => guild.id === guild_id); + + if (guild_object === undefined) { + console.log('could not find your guild_object.'); + return resolve({ result: false, value: 'could not find your guild_object.' }); + } + + const current_dispatcher = guild_object.dispatcher; + const current_music_queue = guild_object.music_queue; + + if (current_dispatcher !== null && current_dispatcher !== undefined) { + yts(search_term) + .then(yts_attempt => { + if (yts_attempt) { + current_music_queue.push(yts_attempt.videos[0]); + } + else { + return resolve({ result: false, value: 'could not find youtube video' }); + } + }) + .catch(error => console.log(error)); + return resolve({ result: true, value: 'already playing song, your song has been added in list.' }); + } + + join_user_voice(client, message, guild_list, false) + .then(join_attempt => { + if (join_attempt.result) { + yts(search_term) + .then(yts_attempt => { + if (yts_attempt && yts_attempt.videos.length > 0) { + const stream = ytdl(yts_attempt.videos[0].url, { + filter: 'audioonly', + opusEncoded: false, + fmt: 'mp3', + highWaterMark: 2048, + }); + guild_object.dispatcher = join_attempt.voice_connection?.play(stream); + if (guild_object.dispatcher) { + if (message.member && message.member.voice && message.member.voice.channel) { + const guild = client.guilds.cache.find(g => g.id === message.guild?.id); + if (guild !== undefined) + update_message(guild, guild_object, yts_attempt.videos[0]); + + guild_object.dispatcher.on('finish', () => { + if (message.guild) { + skip(guild_id, guild_list, client, message.guild); + guild_object.music_data.votes = []; + } + }); + + return resolve({ result: false, value: 'playing video' }); + } else { + return resolve({ result: false, value: 'could not find user' }); + } + } else { + return resolve({ result: false, value: 'could not find user' }); + } + } + else { + return resolve({ result: false, value: 'could not fetch StreamDispatcher' }); + } + }) + .catch(error => console.log(error)); + } + else { + return resolve({ result: false, value: join_attempt.value }); + } + }) + .catch(error => { + return resolve({ result: false, value: error }); + }); + }); +}; + +export async function play(guild_id: string, guild_list: GuildPrtl[], client: Client, guild: Guild): Promise { + return new Promise((resolve) => { + const current_guild = guild_list.find(guild => guild.id === guild_id); + + if (current_guild === undefined) { + return resolve({ result: false, value: 'could not find your guild.' }); + } + + let current_dispatcher = current_guild.dispatcher; + + if (current_dispatcher !== null && current_dispatcher !== undefined) { + if (current_dispatcher.paused) { + current_dispatcher.resume(); + + current_dispatcher.on('finish', () => { + skip(guild_id, guild_list, client, guild); + current_guild.music_data.votes = []; + }); + + return resolve({ result: false, value: 'song has been resumed.' }); + } + } + else if (current_dispatcher === null) { + const next_yts_video = current_guild.music_queue.shift(); + if (next_yts_video) { + if (client.voice) { + const voice_connection = client.voice.connections.find((connection: VoiceConnection) => !!connection.channel.id); + + if (voice_connection) { + current_dispatcher = voice_connection + .play(ytdl(next_yts_video.url, { filter: 'audioonly' })); + + update_message(guild, current_guild, next_yts_video); + + const stream = ytdl(next_yts_video.url, { + filter: 'audioonly', + opusEncoded: false, + fmt: 'mp3', + }); + + current_dispatcher = voice_connection.play(stream); + update_message(guild, current_guild, next_yts_video); + current_dispatcher.on('finish', () => { + skip(guild_id, guild_list, client, guild); + current_guild.music_data.votes = []; + }); + } + } + } + return resolve({ result: false, value: 'next video playing.' }); + } + else { + return resolve({ result: false, value: 'nothing playing write now.' }); + } + }); +}; + +export async function pause(guild_id: string, guild_list: GuildPrtl[]): Promise { + return new Promise((resolve) => { + const current_guild = guild_list.find(guild => guild.id === guild_id); + + if (current_guild === undefined) { + return resolve({ result: false, value: 'could not find your guild.' }); + } + + let current_dispatcher = current_guild.dispatcher; + + if (current_dispatcher !== null && current_dispatcher !== undefined) { + if (!current_dispatcher.paused) { + current_dispatcher.pause(); + } + return resolve({ result: false, value: 'song has been paused.' }); + } + else { + return resolve({ result: false, value: 'nothing playing write now.' }); + } + }); +}; + +export async function stop(guild_id: string, guild_list: GuildPrtl[], guild: Guild): Promise { + return new Promise((resolve) => { + const current_guild = guild_list.find(guild => guild.id === guild_id); + + if (current_guild === undefined) { + return resolve({ result: false, value: 'could not find your guild.' }); + } + + let current_dispatcher = current_guild.dispatcher; + + const portal_icon_url = 'https://raw.githubusercontent.com/keybraker/keybraker' + + '.github.io/master/assets/img/logo.png'; + update_message( + guild, + current_guild, + { + type: 'video', + videoId: '-', + url: 'just type and I\'ll play', + title: 'Music Player', + description: '-', + image: '-', + thumbnail: portal_icon_url, + seconds: 0, + timestamp: '-', + duration: { + seconds: 0, + timestamp: '0' + }, + ago: '-', + views: 0, + author: { + name: '-', + url: '-' + } + }); + + if (current_dispatcher !== null && current_dispatcher !== undefined) { + if (!current_dispatcher.paused) { + current_dispatcher.pause(); + } + current_guild.dispatcher = undefined; + return resolve({ result: false, value: 'song has been stopped.' }); + } + else { + current_guild.dispatcher = undefined; + return resolve({ result: false, value: 'nothing playing write now.' }); + } + }); +}; + +export async function skip(guild_id: string, guild_list: GuildPrtl[], client: Client, guild: Guild): Promise { + return new Promise((resolve) => { + const current_guild = guild_list.find(guild => guild.id === guild_id); + + if (current_guild === undefined) { + return resolve({ result: false, value: 'could not find your guild.' }); + } + + const current_dispatcher = current_guild.dispatcher; + const current_music_queue = current_guild.music_queue; + + if (current_dispatcher !== null && current_dispatcher !== undefined) { + if (current_music_queue.length > 0) { + const next_yts_video: yts.VideoSearchResult | undefined = current_guild.music_queue.shift(); + if (next_yts_video) { + if (client.voice) { + const voice_connection = client.voice.connections.find((connection: VoiceConnection) => !!connection.channel.id); + if (voice_connection) { + current_guild.dispatcher = voice_connection + .play(ytdl(next_yts_video.url, { filter: 'audioonly' })); + + update_message(guild, current_guild, next_yts_video); + + const stream = ytdl(next_yts_video.url, { + filter: 'audioonly', + opusEncoded: false, + fmt: 'mp3', + }); + + current_guild.dispatcher = voice_connection.play(stream); + update_message(guild, current_guild, next_yts_video); + current_guild.dispatcher.on('finish', () => { + skip(guild_id, guild_list, client, guild); + current_guild.music_data.votes = []; + }); + } + } + } + } + else { + const portal_icon_url = 'https://raw.githubusercontent.com/keybraker/keybraker' + + '.github.io/master/assets/img/logo.png'; + update_message( + guild, + current_guild, + { + type: 'video', + videoId: '-', + url: 'just type and I\'ll play', + title: 'Music Player', + description: '-', + image: '-', + thumbnail: portal_icon_url, + seconds: 0, + timestamp: '-', + duration: { + seconds: 0, + timestamp: '0' + }, + ago: '-', + views: 0, + author: { + name: '-', + url: '-' + } + }); + if (!current_dispatcher.paused) { + current_dispatcher.pause(); + } + current_guild.dispatcher = undefined; + return resolve({ result: false, value: 'music list is empty' }); + } + + return resolve({ result: false, value: 'song has been skipped.' }); + } + else { + return resolve({ result: false, value: 'nothing playing write now.' }); + } + }); +}; diff --git a/src/libraries/statusOps.ts b/src/libraries/statusOps.ts new file mode 100644 index 00000000..61d97762 --- /dev/null +++ b/src/libraries/statusOps.ts @@ -0,0 +1,79 @@ +import { GuildMember, VoiceChannel, Activity } from "discord.js"; + +import games from '../assets/jsons/game_list.json'; +import programs from '../assets/jsons/program_list.json'; +import { VoiceChannelPrtl } from "../types/classes/VoiceChannelPrtl"; + +function status_aliases(activities: Activity[], locale: string): string[] { + const new_status: string[] = []; + + activities.forEach(activity => { + let found = false; + for (let l = 0; l < games.game_attributes.length; l++) { + if (activity.name == games.game_attributes[l].status) { + if (locale === 'gr') { + new_status.push(games.game_attributes[l].locale.gr); + found = true; + } + else { + new_status.push(games.game_attributes[l].locale.en); + found = true; + } + } + } + + if (!found) { + for (let l = 0; l < programs.program_attributes.length; l++) { + if (activity.name == programs.program_attributes[l].status) { + if (locale === 'gr') { + new_status.push(programs.program_attributes[l].locale.gr); + found = true; + } + else { + new_status.push(programs.program_attributes[l].locale.en); + found = true; + } + } + } + } + + if (!found) { + new_status.push(activity.name); + } + }); + + return new_status; +}; + +export function get_status_list(voice_channel: VoiceChannel, voice_object: VoiceChannelPrtl): string[] { + const array_of_statuses: string[] = []; + + voice_channel.members.forEach((member: GuildMember) => { + if (!member.user.bot) { + if (member.presence.activities !== undefined) { + if (member.presence.activities.length > 0) { + status_aliases(member.presence.activities, voice_object.locale) + .forEach(stat => { + if (!array_of_statuses.includes(stat)) { + array_of_statuses.push(stat); + } + }); + } + } + } + }); + + if (array_of_statuses.length === 0) { + if (voice_object.locale === 'gr') { + array_of_statuses.push('Άραγμα'); + } + else if (voice_object.locale === 'de') { + array_of_statuses.push('Chillen'); + } + else { + array_of_statuses.push('Chilling'); + } + } + + return array_of_statuses; +}; diff --git a/src/libraries/userOps.ts b/src/libraries/userOps.ts new file mode 100644 index 00000000..ab9ed478 --- /dev/null +++ b/src/libraries/userOps.ts @@ -0,0 +1,201 @@ +import { Message, Guild, GuildMember, VoiceState, User } from "discord.js"; +import { GuildPrtl } from "../types/classes/GuildPrtl"; +import { MemberPrtl } from "../types/classes/MemberPrtl"; +import { time_elapsed } from './helpOps'; + +const level_speed = { slow: 0.01, normal: 0.05, fast: 0.1 }; + +export function give_role_from_rankup(member_prtl: MemberPrtl, member: GuildMember, ranks: any, guild: Guild): boolean { + if (ranks) return false; + + const new_rank = ranks.find((rank: { level: number }) => rank.level === member_prtl.level); + if (new_rank === null || new_rank === undefined) return false; + + const new_role = guild.roles.cache.find(role => role.id === new_rank.id); + if (new_role === null || new_role === undefined) return false; + + if (!member.roles.cache.some(role => role === new_role)) { + member.roles.add(new_role); + return true; + } + + return false; +}; + +export function calculate_rank(member: MemberPrtl): number | null { + if (member.points >= member.tier * 1000) { + member.points -= member.tier * 1000; + member.level++; + + if (member.level % 5 === 0) { + member.tier++; + } + + return member.level; + } + + return null; +}; + +export function add_points_time(member_prtl: MemberPrtl, speed: string): boolean { + if (!member_prtl.timestamp) { + return false; + } + const voice_time = time_elapsed(member_prtl.timestamp, 0); + + const speed_num: number = (speed === 'slow') + ? level_speed.slow + : (speed === 'normal') + ? level_speed.normal + : (speed === 'fast') + ? level_speed.fast + : level_speed.normal; + + member_prtl.points += Math.round(voice_time.remaining_sec * speed_num); + member_prtl.points += Math.round(voice_time.remaining_min * speed_num * 60 * 1.15); + member_prtl.points += Math.round(voice_time.remaining_hrs * speed_num * 60 * 60 * 1.25); + + member_prtl.timestamp = null; + + return true; +}; + +export function update_timestamp(voiceState: VoiceState, guild_list: GuildPrtl[]): number | boolean { + if (voiceState.member && voiceState.member.user.bot) { + const guild = guild_list.find(guild => { + if (voiceState && voiceState.guild) + return guild.id === voiceState.guild.id; + }); + + if (guild === undefined) { + return false; + } + + const member_prtl = guild.member_list.find(m => { + if (voiceState && voiceState.member) + return m.id === voiceState.member.id; + }); + + if (member_prtl === undefined) { + return false; + } + + const ranks = guild.ranks; + const member = voiceState.member; + const speed = guild.level_speed; + const cached_level = member_prtl.level; + + if (member_prtl.timestamp === null) { + member_prtl.timestamp = new Date(); + return false; + } + + add_points_time(member_prtl, speed); + calculate_rank(member_prtl); + give_role_from_rankup(member_prtl, member, ranks, voiceState.guild); + + if (member_prtl.level > cached_level) { + return member_prtl.level; + } + } + return false; +}; + +export function add_points_message(message: Message, guild_list: GuildPrtl[]): number | boolean { + if (message && message.guild) { + const guild = guild_list.find(guild => { + if (message && message.guild) + return guild.id === message.guild.id; + }); + + if (guild === undefined) { + return false; + } + + const member = guild.member_list.find(m => { + if (message && message.author) + return m.id === message.author.id; + }); + + if (member === undefined) { + return false; + } + + const speed: string = guild.level_speed; + const speed_num: number = (speed === 'slow') + ? level_speed.slow + : (speed === 'normal') + ? level_speed.normal + : (speed === 'fast') + ? level_speed.fast + : level_speed.normal; + const points = message.content.length * speed_num; + + member.points += points > 5 ? 5 : Math.round(points); + const level = calculate_rank(member); + + if (level) { + return level; + } + } + + return false; +}; + +export function kick(message: Message, args: any): void { + // This command must be limited to mods and admins. In this example we just hardcode the role names. + // Please read on Array.some() to understand this bit: + // https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Array/some? + if (message.member && !message.member.roles.cache.some(r => ['Administrator', 'Moderator'].includes(r.name))) { + message.reply('Sorry, you don\'t have permissions to use this!'); + } + + // Let's first check if we have a member and if we can kick them! + // message.mentions.members is a collection of people that have been mentioned, as GuildMembers. + // We can also support getting the member by ID, which would be args[0] + if (message.mentions) { + if (message.mentions.members) { + if (message.guild) { + const member = message.mentions.members.first() || message.guild.members.cache.get(args[0]); + if (!member) { message.reply('Please mention a valid member of this server'); } + else { + if (!member.kickable) { message.reply('I cannot kick this user! Do they have a higher role? Do I have kick permissions?'); } + + // slice(1) removes the first part, which here should be the user mention or ID + // join(' ') takes all the various parts to make it a single string. + let reason = args.slice(1).join(' '); + if (!reason) reason = 'No reason provided'; + + // Now, time for a swift kick in the nuts! + // await member.kick(reason) + member.kick(reason).catch(error => message.reply(`Sorry ${message.author} I couldn't kick because of : ${error}`)); + message.reply(`${member.user.tag} has been kicked by ${message.author.tag} because: ${reason}`); + } + } + } + } + +}; + +export function ban(message: Message, args: any): void { + // Most of this command is identical to kick, except that here we'll only let admins do it. + // In the real world mods could ban too, but this is just an example, right? ;) + // if (message.member && !message.member.roles.some(r => ['Administrator'].includes(r.name))) { + // message.reply('Sorry, you don\'t have permissions to use this!'); + // } + + // if (message) { + // if (message.mentions) { + // const member = message.mentions.members.first(); + // if (!member) { message.reply('Please mention a valid member of this server'); } + // if (!member.bannable) { message.reply('I cannot ban this user! Do they have a higher role? Do I have ban permissions?'); } + + // let reason = args.slice(1).join(' '); + // if (!reason) reason = 'No reason provided'; + + // // await member.ban(reason) + // member.ban(reason).catch(error => message.reply(`Sorry ${message.author} I couldn't ban because of : ${error}`)); + // message.reply(`${member.user.tag} has been banned by ${message.author.tag} because: ${reason}`); + // } + // } +}; \ No newline at end of file diff --git a/src/moderation/profanity.js b/src/moderation/profanity.js deleted file mode 100644 index d2253464..00000000 --- a/src/moderation/profanity.js +++ /dev/null @@ -1,29 +0,0 @@ -/* eslint-disable no-unused-vars */ -const profane_word_list = require('../../assets/jsons/profane_word_list.json'); - -/** - * Determine if a string contains profane language. - * @param {string} string - String to evaluate for profanity. - * - * https://github.com/web-mech/badwords - */ -module.exports = function isProfane(string) { - const str_array = [string]; - for (let i = 0; i < string.length; i++) { - str_array.push(string.substr(0, i)); - str_array.push(string.substr(i, string.length - 1)); - } - - return Object.getOwnPropertyNames(profane_word_list).some(lang => { - return profane_word_list[lang].filter((word) => { - if (lang === 'en') { - const regex_word = word.replace(/(\W)/g, '\\$1'); - const word_exp = new RegExp(`\\b(\\w*${word}\\w*)\\b`, 'gi'); - return word_exp.test(string); - } else if (lang === 'el') { - return str_array.some(str => str === word); - } - - }).length > 0 || false; - }); -} \ No newline at end of file diff --git a/src/portal.ts b/src/portal.ts index 63dd5c4e..f6a3bbb3 100644 --- a/src/portal.ts +++ b/src/portal.ts @@ -1,147 +1,181 @@ -// const mongoose = require('mongoose'); -// mongoose.connect('mongodb://localhost/PortalDB', { useNewUrlParser: true }) -// .catch(error => { -// console.error.bind(console, 'PortallDB connection error:'); -// console.log('Could not connect to PortalDB (mongo) with error:\n', error); -// return -1; -// }); - -// const PortalDB = mongoose.connection; -// PortalDB.once('open', function() { console.log('we\'re connected!'); }); - -// list of all managed channels in servers -const portal_managed_guilds_path = './database/guild_list.json'; -const guild_list = require('../database/guild_list.json'); - +// load up the discord.js library +import { + Client, Guild, GuildChannel, GuildMember, Message, MessageReaction, PartialGuildMember, + PartialMessage, PartialUser, Presence, TextChannel, User, VoiceState +} from "discord.js"; +import { readFileSync } from "jsonfile"; +import cooldown_list from './assets/jsons/cooldown_list.json'; +import config from './config.json'; +import { included_in_url_list } from './libraries/guildOps'; +import { + guildPrtl_to_object, is_authorised, is_url, message_reply, pad, time_elapsed, + update_portal_managed_guilds +} from './libraries/helpOps'; +import { client_talk } from './libraries/localizationOps'; +import { isProfane } from "./libraries/modOps"; +import { start } from './libraries/musicOps'; +import { add_points_message } from './libraries/userOps'; +import { GuildPrtl } from './types/classes/GuildPrtl'; +import { ActiveCooldown, ActiveCooldowns, CommandOptions, ReturnPormise } from "./types/interfaces/InterfacesPrtl"; + +const command_options_guild: CommandOptions[] = cooldown_list.guild; +const command_options_member: CommandOptions[] = cooldown_list.member; +const command_options_none: CommandOptions[] = cooldown_list.none; + +const portal_managed_guilds_path = config.database_json; + +const guild_list_json = readFileSync(config.database_json); +if (!guild_list_json) { + console.log('could not read guild list'); + process.exit(1); +} +// list of all managed guilds +const guild_list: GuildPrtl[] = guild_list_json; +console.log('guild_list :>> ', guild_list); if (guild_list === null) { console.log('guild json is corrupt'); process.exit(1); } -const config = require('../config.json'); -const cooldown_list = require('../assets/jsons/cooldown_list.json'); +if (!Array.isArray(guild_list)) { + console.log('guild_list must be an array'); + process.exit(1); +} -const profanity = require('./moderation/profanity.js') -const guld_mngr = require('./functions/guild_manager'); -const help_mngr = require('./functions/help_manager'); -const lclz_mngr = require('./functions/localization_manager'); -const user_mngr = require('./functions/user_manager'); -const play_mngr = require('./functions/music_manager'); - -// load up the discord.js library -const Discord = require('discord.js'); -// const { Discord, Client, Message, Guild, DMChannel, GuildChannel, GuildMember, Presence } = require('discord.js'); +// guild_list.forEach(g => { +// console.log('g :>> ', g); +// if (!(g instanceof GuildPrtl)) { +// console.log('guild json is not GuildPrtl type'); +// process.exit(1); +// } +// }); // this is the client the Portal Bot. Some people call it bot, some people call // it 'self', client.user is actually the presence of portal bot in the server -const client = new Discord.Client({ partials: ['MESSAGE', 'CHANNEL', 'REACTION'] }); +const client = new Client({ partials: ['MESSAGE', 'CHANNEL', 'REACTION'] }); -const active_cooldown = { guild: [], member: [] }; +const active_cooldowns: ActiveCooldowns = { guild: [], member: [] }; // This event will run if the bot starts, and logs in, successfully. client.on('ready', () => event_loader('ready', { + 'client': client, + 'guild_list': guild_list, + 'portal_managed_guilds_path': portal_managed_guilds_path + }) +); + +// When bot connects to shard again ? +client.on('shardResume', (id: number) => + event_loader('shardResume', { 'client': client, 'guild_list': guild_list, 'portal_managed_guilds_path': portal_managed_guilds_path, + 'id': id }) ); // When bot connects to shard again ? -client.on('shardReconnecting', id => - event_loader('shardReconnecting', { - 'id': id, +client.on('shardStart', (id: number) => + event_loader('shardStart', { + 'client': client, + 'guild_list': guild_list, + 'portal_managed_guilds_path': portal_managed_guilds_path, + 'id': id }) ); // this event triggers when the bot is removed from a guild. -client.on('guildDelete', guild => +client.on('guildDelete', (guild: Guild) => event_loader('guildDelete', { 'guild': guild, 'guild_list': guild_list, - 'portal_managed_guilds_path': portal_managed_guilds_path, + 'portal_managed_guilds_path': portal_managed_guilds_path }) ); // This event triggers when the bot joins a guild. -client.on('guildCreate', guild => +client.on('guildCreate', (guild: Guild) => event_loader('guildCreate', { 'client': client, 'guild': guild, 'guild_list': guild_list, - 'portal_managed_guilds_path': portal_managed_guilds_path, + 'portal_managed_guilds_path': portal_managed_guilds_path }) ); // This event triggers when the bot joins a guild. -client.on('channelDelete', channel => +client.on('channelDeleted', (channel: GuildChannel) => event_loader('channelDelete', { 'channel': channel, 'guild_list': guild_list, - 'portal_managed_guilds_path': portal_managed_guilds_path, + 'portal_managed_guilds_path': portal_managed_guilds_path }) ); // This event triggers when a new member joins a guild. -client.on('guildMemberAdd', member => +client.on('guildMemberAdd', (member: GuildMember) => event_loader('guildMemberAdd', { 'member': member, - 'guild_list': guild_list, - 'portal_managed_guilds_path': portal_managed_guilds_path, + 'guild_list': guild_list }) ); // This event triggers when a new member leaves a guild. -client.on('guildMemberRemove', member => +client.on('guildMemberRemove', (member: GuildMember | PartialGuildMember) => event_loader('guildMemberRemove', { 'member': member, - 'guild_list': guild_list, - 'portal_managed_guilds_path': portal_managed_guilds_path, + 'guild_list': guild_list }) ); // This event triggers when the status of a guild member has changed -client.on('presenceUpdate', (oldPresence, newPresence) => +client.on('presenceUpdate', (oldPresence: Presence | undefined, newPresence: Presence | undefined) => event_loader('presenceUpdate', { 'client': client, 'guild_list': guild_list, - 'newPresence': newPresence, + 'newPresence': newPresence }) ); // This event triggers when a member reacts to a message -client.on('messageReactionAdd', (messageReaction, user) => +client.on('messageReactionAdd', (messageReaction: MessageReaction, user: User | PartialUser) => event_loader('messageReactionAdd', { 'client': client, 'guild_list': guild_list, 'messageReaction': messageReaction, - 'user': user, + 'user': user }) ); // This event triggers when a message is deleted -client.on('messageDelete', (message) => +client.on('messageDelete', (message: Message | PartialMessage) => event_loader('messageDelete', { 'client': client, 'guild_list': guild_list, 'portal_managed_guilds_path': portal_managed_guilds_path, - 'message': message, + 'message': message }) ); // This event triggers when a member joins or leaves a voice channel -client.on('voiceStateUpdate', (oldState, newState) => +client.on('voiceStateUpdate', (oldState: VoiceState, newState: VoiceState) => event_loader('voiceStateUpdate', { 'client': client, 'guild_list': guild_list, 'portal_managed_guilds_path': portal_managed_guilds_path, 'oldState': oldState, - 'newState': newState, + 'newState': newState }) ); // runs on every single message received, from any channel or DM -client.on('message', async (message: @Discord.message) => { +client.on('message', async (message: Message) => { + // message has errors + if (message === null) return; + if (message.member === null) return; + if (message.guild === null) return; + // Ignore other bots and also itself ('botception') if (message.author.bot) return; @@ -155,149 +189,195 @@ client.on('message', async (message: @Discord.message) => { ranking_system(message); // word check - if (profanity(message.content)) { + if (isProfane(message.content)) { message.react('🚩'); message.author .send("try not to use profanities") .catch(console.error); } - help_mngr.update_portal_managed_guilds(true, portal_managed_guilds_path, guild_list); + update_portal_managed_guilds(true, portal_managed_guilds_path, guild_list); // Ignore any message that does not start with prefix if (message.content.indexOf(config.prefix) !== 0) return; // Separate function name, and arguments of function const args = message.content.slice(config.prefix.length).trim().split(/ +/g); - const cmd = args.shift().toLowerCase(); - let type = null; - if (cooldown_list.guild[cmd]) { + const cmd_only = args.shift(); + if (cmd_only === undefined) return; + + const cmd = cmd_only.toLowerCase(); + + let command_options: CommandOptions | undefined; + let type: string; + let active_cooldown: ActiveCooldown[]; + + if (command_options_guild.some(cmd_curr => cmd_curr.name === cmd)) { + command_options = command_options_guild.find(cmd_curr => cmd_curr.name === cmd); + active_cooldown = active_cooldowns.guild; type = 'guild'; } - else if (cooldown_list.member[cmd]) { + else if (command_options_member.some(cmd_curr => cmd_curr.name === cmd)) { + command_options = command_options_member.find(cmd_curr => cmd_curr.name === cmd); + active_cooldown = active_cooldowns.member; type = 'member'; } - else if (cooldown_list.none[cmd]) { + else if (command_options_none.some(cmd_curr => cmd_curr.name === cmd)) { + command_options = command_options_none.find(cmd_curr => cmd_curr.name === cmd); + active_cooldown = []; type = 'none'; } else { return; } - if (cooldown_list[type][cmd].auth) { - const is_user_authorized = help_mngr.is_authorized( - guild_list[message.guild.id].auth_role, message.member); + // not a portal command + if (command_options === undefined) return; - if (!is_user_authorized) { - help_mngr.message_reply(false, message.channel, message, message.author, - 'you are not authorized to access this command', guild_list, client); + const guild_obejct = guildPrtl_to_object(guild_list, message.guild.id); + if (!guild_obejct) { + message_reply(false, message.channel, message, message.author, + 'this guild is not in database, please contact portal support', guild_list, client); + return; + } + + if (command_options.auth) { + if (!is_authorised(guild_obejct, message.member)) { + message_reply(false, message.channel, message, message.author, + 'you are not authorized to use this command', guild_list, client); return; } } - if (cooldown_list[type][cmd].premium && !guild_list[message.guild.id].premium) { - help_mngr.message_reply( - false, message.channel, message, - message.author, 'this server is not premium', guild_list, client); + if (command_options.premium && !guild_obejct.premium) { + message_reply(false, message.channel, message, message.author, + 'this server is not premium', guild_list, client); return; } - if (type === 'none' && cooldown_list.none[cmd].time === 0) { + command_loader(message, cmd, args, type, command_options, active_cooldown); +}); + +function command_loader(message: Message, cmd: string, args: string[], type: string, + command_options: CommandOptions, active_cooldown: ActiveCooldown[]): boolean { + if (type === 'none' && command_options.time === 0) { require(`./commands/${cmd}.js`)(client, message, args, guild_list, portal_managed_guilds_path) - .then(rspns => { - help_mngr.message_reply(rspns.result, message.channel, message, - message.author, rspns.value, guild_list, client, cooldown_list[type][cmd].auto_delete); - help_mngr.update_portal_managed_guilds(true, portal_managed_guilds_path, guild_list); + .then((response: ReturnPormise) => { + message_reply(response.result, message.channel, message, + message.author, response.value, guild_list, client, command_options ? command_options.auto_delete : true); + update_portal_managed_guilds(true, portal_managed_guilds_path, guild_list); }); - return; + return true; } - const active = active_cooldown[type].find(active_current => { + const active = active_cooldown.find(active_current => { if (active_current.command === cmd) { - if (type === 'member' && active_current.member === message.author.id) { - return true; - } - if (type === 'guild') { + if (type === 'member') + if (active_current.member === message.author.id) + return true; + if (type === 'guild') return true; - } } return false; }); if (active) { - const time = help_mngr.time_elapsed(active.timestamp, cooldown_list[type][cmd].time); - const type_for_msg = type === 'member' ? '.*' : `, as it was used again in* **${message.guild.name}**.`; - - help_mngr.message_reply(false, message.channel, message, message.author, - `*you need to wait* **${help_mngr.pad(time.remaining_min)}:` + - `${help_mngr.pad(time.remaining_sec)}/${help_mngr.pad(time.timeout_min)}:` + - `${help_mngr.pad(time.timeout_sec)}** *to use* **${cmd}** *again${type_for_msg}`, + const time = time_elapsed(active.timestamp, command_options.time); + const type_for_msg = type === 'member' + ? '.*' + : `, as it was used again in* **${message.guild?.name}**.`; + + message_reply(false, message.channel, message, message.author, + `*you need to wait* **${pad(time.remaining_min)}:` + + `${pad(time.remaining_sec)}/${pad(time.timeout_min)}:` + + `${pad(time.timeout_sec)}** *to use* **${cmd}** *again${type_for_msg}`, guild_list, client); - return; + return false; } require(`./commands/${cmd}.js`)(client, message, args, guild_list, portal_managed_guilds_path) - .then(rspns => { - if (rspns.result === true) { - active_cooldown[type].push({ member: message.author.id, command: cmd, timestamp: Date.now() }); - - setTimeout(() => { - active_cooldown[type] = active_cooldown[type] - .filter(active.command !== cmd); - }, cooldown_list[type][cmd].time * 60 * 1000); + .then((response: ReturnPormise) => { + if (response.result === true) { + active_cooldown.push({ + member: message.author.id, + command: cmd, + timestamp: Date.now() + }); + + if (command_options !== undefined) { + setTimeout(() => { + active_cooldown = active_cooldown.filter(active => active.command !== cmd); + }, command_options.time * 60 * 1000); + } + } + if (command_options !== undefined) { + message_reply(response.result, message.channel, message, message.author, + response.value, guild_list, client, command_options.auto_delete); } - console.log('cooldown_list[type][cmd].auto_delete :>> ', cooldown_list[type][cmd].auto_delete); - help_mngr.message_reply(rspns, message.channel, message, message.author, - rspns ? 'executed correctly' : 'executed falsely', guild_list, client, - cooldown_list[type][cmd].auto_delete); - help_mngr.update_portal_managed_guilds(true, portal_managed_guilds_path, guild_list); + update_portal_managed_guilds(true, portal_managed_guilds_path, guild_list); }); -}); -function event_loader(event, args) { + return false; +} + +function event_loader(event: string, args: any): void { + // Ignore other bots and also itself ('botception') console.log(`event emitted: ${event}`); require(`./events/${event}.js`)(args) - .then(rspns => { - if (rspns !== null && rspns !== undefined) { + .then((response: ReturnPormise) => { + if (response !== null && response !== undefined) { if (event === 'messageReactionAdd') { - const music_channel_id = args.guild_list[args.messageReaction.message.guild.id] - .music_data.channel_id; - const music_channel = args.messageReaction.message.guild.channels.cache - .find(channel => channel.id === music_channel_id); - - music_channel - .send(`${args.user}, ${rspns.value.toString()}`) - .then(msg => { msg.delete({ timeout: 5000 }); }) - .catch(error => console.log(error)); + const messageReaction = args.messageReaction; + const guild_object = (args.guild_list).find(g => + g.id === args.messageReaction.message.guild.id); + + if (guild_object) { + if (messageReaction.message.channel.id === guild_object.music_data.channel_id) { + const music_channel: TextChannel = args.messageReaction.message.guild.channels.cache + .find((channel: TextChannel) => channel.id === guild_object.music_data.channel_id); + // auto na trexei mono otan einai music reaction + + music_channel + .send(`${args.user}, ${response.value.toString()}`) + .then(msg => { msg.delete({ timeout: 5000 }); }) + .catch(error => console.log(error)); + } + } } else { - console.log(rspns.result, rspns.value); + console.log(response.result, response.value); } } }); }; -function portal_channel_handler(message) { - let channel_type = null, channel_support = null, channel_talk = null; +function portal_channel_handler(message: Message): void { + let guild_obejct = guild_list.find((g: GuildPrtl) => g.id === message.guild?.id); + if (!guild_obejct) return; - if (guld_mngr.included_in_url_list(message.channel.id, guild_list[message.guild.id])) { - if (help_mngr.is_url(message.content)) { - lclz_mngr.client_talk(client, guild_list, 'url'); + if (included_in_url_list(message.channel.id, guild_obejct)) { + console.log('it is url channel'); + if (is_url(message.content)) { + client_talk(client, guild_list, 'url'); return; } else { - channel_type = 'URL'; - channel_support = 'url'; - channel_talk = 'read_only'; + client_talk(client, guild_list, 'read_only'); + message_reply(false, message.channel, message, message.author, + 'url-only channel', guild_list, client); + message.delete(); } } - else if (guild_list[message.guild.id].music_data.channel_id === message.channel.id) { - play_mngr.start(client, message, message.content, guild_list) + else if (guild_obejct.music_data.channel_id === message.channel.id) { + console.log('it is music channel'); + start(client, message, message.content, guild_list) .then(joined => { - help_mngr.message_reply(joined.result, message.channel, message, + console.log('joined :>> ', joined); + + message_reply(joined.result, message.channel, message, message.author, joined.value, guild_list, client, true); }) .catch(error => { @@ -307,29 +387,19 @@ function portal_channel_handler(message) { return; } - if (channel_type !== null && channel_support !== null && channel_talk !== null) { - lclz_mngr.client_talk(client, guild_list, channel_talk); - help_mngr.message_reply( - null, message.channel, message, - message.author, `${channel_type} channel is ${channel_support}-only.`, - guild_list, client); - message.delete(); - return; - } } -function ranking_system(message) { - const level = user_mngr.add_points_message(message, guild_list); +function ranking_system(message: Message): void { + const level = add_points_message(message, guild_list); if (level) { - help_mngr.message_reply( - null, message.channel, message, + message_reply(false, message.channel, message, message.author, `You reached level ${level}!`, guild_list, client); } } function log_portal() { - client.login(config.token); + client.login(config.token_dev); } log_portal(); diff --git a/src/properties/attribute_list.js b/src/properties/attribute_list.js deleted file mode 100644 index 6e5e9504..00000000 --- a/src/properties/attribute_list.js +++ /dev/null @@ -1,356 +0,0 @@ -/* eslint-disable no-unused-vars */ -const help_mngr = require('../functions/help_manager'); -const locales = ['gr', 'en', 'de']; - -module.exports = -{ - is_attribute: function (arg) { - for (let i = 0; i < this.attributes.length; i++) { - if (String(arg).substring(1, (String(this.attributes[i].name).length + 1)) == this.attributes[i].name) { return this.attributes[i].name; } - } - return false; - }, - get_help: function () { - const attr_array = []; - for (let i = 0; i < this.attributes.length; i++) { - attr_array.push({ - emote: this.attributes[i].name, - role: '**desc**: *' + this.attributes[i].description + '*' + - '\n**args**: *' + this.attributes[i].args + '*', - inline: true, - }); - } - return help_mngr.create_rich_embed('Attributes', - 'Prefix: ' + this.prefix + '\nimmutable statistics of Portal channel.' + - '\n**!**: *mandatory*, **@**: *optional*', - '#FF5714', attr_array); - }, - get_help_super: function (check) { - for (let i = 0; i < this.attributes.length; i++) { - const attr = this.attributes[i]; - if (attr.name === check) { - return help_mngr.create_rich_embed( - attr.name, - 'Type: Attribute' + - '\nPrefix: ' + this.prefix + - '\n**!**: *mandatory*, **@**: *optional*', - '#FF5714', - [ - { emote: 'Description', role: '*' + attr.super_description + '*', inline: false }, - { emote: 'Arguments', role: '*' + attr.args + '*', inline: false }, - { emote: 'Example', role: '*' + attr.example + '*', inline: false }, - ], - ); - } - } - return false; - }, - get: function (voice_channel, voice_object, portal_object, guild_object, attr) { - for (let l = 0; l < this.attributes.length; l++) { - if (attr === this.attributes[l].name) { - return this.attributes[l].get(voice_channel, voice_object, portal_object, guild_object); - } - } - return -1; - }, - set: function (voice_channel, voice_object, portal_object, guild_object, attr, value, member) { - for (let l = 0; l < this.attributes.length; l++) { - if (attr === this.attributes[l].name) { - switch (this.attributes[l].auth) { - case 'admin': - if (!member.hasPermission('ADMINISTRATOR')) { - return -2; - } - break; - case 'portal': - if (portal_object.creator_id !== member.id) { - return -3; - } - break; - case 'voice': - if (voice_object.creator_id !== member.id) { - return -4; - } - break; - default: - break; - } - - return this.attributes[l].set(voice_channel, voice_object, portal_object, guild_object, value); - } - } - return -1; - }, - prefix: '&', - attributes: [ - { - name: 'ann_announce', - description: 'returns/sets whether Portal announces events in current channel', - super_description: '**ann_announce** returns/sets whether Portal announces events in current channel', - example: '&ann_announce', - args: 'true/false', - get: (voice_channel, voice_object, portal_object, guild_object) => { - return voice_object.ann_announce; - }, - set: (voice_channel, voice_object, portal_object, guild_object, value) => { - if (value === 'true') { - voice_object.ann_announce = true; - return 1; - } - else if (value === 'false') { - voice_object.ann_announce = false; - return 1; - } - return -7; - }, - auth: 'voice', - }, - { - name: 'ann_announce_portal', - description: 'returns/sets whether Portal announces events in current portals spawned channels', - super_description: '**ann_announce_portal** returns/sets whether Portal announces events in ' + - 'current portals spawned channels', - example: '&ann_announce_portal', - args: 'true/false', - get: (voice_channel, voice_object, portal_object, guild_object) => { - return portal_object.ann_announce; - }, - set: (voice_channel, voice_object, portal_object, guild_object, value) => { - if (value === 'true') { - portal_object.ann_announce = true; - return 1; - } - else if (value === 'false') { - portal_object.ann_announce = false; - return 1; - } - return -7; - }, - auth: 'portal', - }, - { - name: 'ann_user', - description: 'returns/sets whether Portal announces user\'s join or leave from current channel', - super_description: '**ann_user** returns/sets whether Portal announces user\'s join or leave from current channel', - example: '&ann_user', - args: 'true/false', - get: (voice_channel, voice_object, portal_object, guild_object) => { - return voice_object.ann_user; - }, - set: (voice_channel, voice_object, portal_object, guild_object, value) => { - if (value === 'true') { - voice_object.ann_user = true; - return 1; - } - else if (value === 'false') { - voice_object.ann_user = false; - return 1; - } - return -7; - }, - auth: 'voice', - }, - { - name: 'ann_user_portal', - description: 'returns/sets whether Portal announces user\'s join or leave from current portals spawned channels', - super_description: '**ann_user_portal** returns/sets whether Portal announces user\'s join or leave from ' + - 'current portals spawned channels', - example: '&ann_user_portal', - args: 'true/false', - get: (voice_channel, voice_object, portal_object, guild_object) => { - return portal_object.ann_user; - }, - set: (voice_channel, voice_object, portal_object, guild_object, value) => { - if (value === 'true') { - portal_object.ann_user = true; - return 1; - } - else if (value === 'false') { - portal_object.ann_user = false; - return 1; - } - return -7; - }, - auth: 'portal', - }, - { - name: 'bitrate', - description: 'returns/sets bitrate of channel', - super_description: '**bitrate** returns/sets bitrate of channel', - example: '&bitrate', - args: 'number', - get: (voice_channel) => { - return voice_channel.bitrate; - }, - set: (voice_channel, voice_object, portal_object, guild_object, value) => { - // voice_channel.setBitrate(Number(value)); - voice_channel.edit({ bitrate: Number(value) }) - .then(channel => console.log( - `Channel's new position is ${channel.bitrate} and should be ${value}`)) - .catch(console.error); - return 1; - }, - auth: 'voice', - }, - { - name: 'locale', - description: 'returns/sets locale of current channel', - super_description: '**locale**, returns/sets language used in statuses', - example: '&locale', - args: 'en/gr/de', - get: (voice_channel, voice_object) => { - return voice_object.locale; - }, - set: (voice_channel, voice_object, portal_object, guild_object, value) => { - if (locales.includes(value)) { - voice_object.locale = String(value); - return 1; - } - else { - return -5; - } - }, - auth: 'voice', - }, - { - name: 'locale_guild', - description: 'returns/sets locale_guild of the guild', - super_description: '**locale_guild**, returns/sets guild locale makes the bot talk your language and all communication is done' + - 'in your local language', - example: '&locale_guild', - args: 'en/gr/de', - get: (voice_channel, voice_object, portal_object, guild_object) => { - return guild_object.locale; - }, - set: (voice_channel, voice_object, portal_object, guild_object, value) => { - if (locales.includes(value)) { - guild_object.locale = String(value); - return 1; - } - else { - return -5; - } - }, - auth: 'admin', - }, - { - name: 'locale_portal', - description: 'returns/sets locale_portal of current channel', - super_description: '**locale_portal**, returns/sets language used in statuses', - example: '&locale_portal', - args: 'en/gr/de', - get: (voice_channel, voice_object, portal_object) => { - return portal_object.locale; - }, - set: (voice_channel, voice_object, portal_object, guild_object, value) => { - if (locales.includes(value)) { - portal_object.locale = String(value); - return 1; - } - else { - return -5; - } - }, - auth: 'portal', - }, - { - name: 'position', - description: 'returns/sets the position of the channel', - super_description: '**position**, returns/sets the position of the channel', - example: '&position', - args: '!position of channel', - get: (voice_channel) => { - return voice_channel.position; - }, - set: (voice_channel, voice_object, portal_object, guild_object, value) => { - voice_channel.edit({ position: Number(value) }) - .then(channel => console.log( - `Channel's new position is ${channel.position} and should be ${value}`)) - .catch(console.error); - return 1; - }, - auth: 'voice', - }, - { - name: 'regex', - description: 'returns/sets the title for current voice channel', - super_description: '**regex**, returns/sets the title for current voice channel', - example: '®ex', - args: '!regex', - get: (voice_channel, voice_object) => { - return voice_object.regex; - }, - set: (voice_channel, voice_object, portal_object, guild_object, value) => { - voice_object.regex = value; - return 1; - }, - auth: 'voice', - }, - { - name: 'regex_portal', - description: 'returns/sets title-guidelines of portal channel', - super_description: '**regex_portal**, returns/sets title-guidelines of portal channel', - example: '®ex_portal', - args: '!regex', - get: (voice_channel, voice_object, portal_object) => { - return portal_object.regex_portal; - }, - set: (voice_channel, voice_object, portal_object, guild_object, value) => { - portal_object.regex_portal = value; - return 1; - }, - auth: 'portal', - }, - { - name: 'regex_voice', - description: 'returns/sets the default title for created voice channels', - super_description: '**regex_voice**, returns/sets the default title for created voice channels', - example: '®ex_voice', - args: '!regex', - get: (voice_channel, voice_object, portal_object) => { - return portal_object.regex_voice; - }, - set: (voice_channel, voice_object, portal_object, guild_object, value) => { - portal_object.regex_voice = value; - return 1; - }, - auth: 'portal', - }, - { - name: 'user_limit', - description: 'returns/sets maximum number of members allowed', - super_description: '**user_limit**, returns/sets maximum number of members allowed', - example: '&user_limit', - args: '!number of maximum members (0 is infinite)', - get: (voice_channel) => { - return voice_channel.userLimit; - }, - set: (voice_channel, voice_object, portal_object, guild_object, value) => { - if (value >= 0) { - voice_channel.userLimit = Number(value); - return 1; - } - return -6; - }, - auth: 'voice', - }, - { - name: 'user_limit_portal', - description: 'returns/sets maximum number of members guideline for portal', - super_description: '**user_limit_portal**, returns/sets maximum number of members guideline for portal', - example: '&user_limit_portal', - args: '!number of maximum members (0 is infinite)', - get: (voice_channel, voice_object, portal_object) => { - return portal_object.user_limit_portal; - }, - set: (voice_channel, voice_object, portal_object, guild_object, value) => { - if (value >= 0) { - portal_object.user_limit_portal = Number(value); - return 1; - } - return -6; - }, - auth: 'portal', - }, - ], -}; diff --git a/src/properties/command_list.js b/src/properties/command_list.js deleted file mode 100644 index 82f4ecec..00000000 --- a/src/properties/command_list.js +++ /dev/null @@ -1,295 +0,0 @@ -const help_mngr = require('../functions/help_manager'); - -module.exports = -{ - is_command: function (arg) { - for (let i = 0; i < this.commands.length; i++) { - if (String(arg).substring(1, (String(this.commands[i].name).length + 1)) == this.commands[i].name) { return this.commands[i].name; } - } - return false; - }, - get_help: function () { - const func_array = []; - for (let i = 0; i < this.commands.length; i++) { - func_array.push({ - emote: this.commands[i].name, - role: '**desc**: *' + this.commands[i].description + '*' + - '\n**args**: *' + this.commands[i].args + '*', - inline: true, - }); - } - return help_mngr.create_rich_embed('Commands', - 'Prefix: ' + this.prefix + '\nCommands to access portal bot.' + - '\n**!**: *mandatory*, **@**: *optional*', - '#9775A9', func_array); - }, - get_help_super: function (check) { - for (let i = 0; i < this.commands.length; i++) { - const cmmd = this.commands[i]; - if (cmmd.name === check) { - return help_mngr.create_rich_embed( - cmmd.name, - 'Type: Command' + - '\nPrefix: ' + this.prefix + - '\n**!**: *mandatory*, **@**: *optional*', - '#9775A9', - [ - { emote: 'Description', role: '*' + cmmd.super_description + '*', inline: false }, - { emote: 'Arguments', role: '*' + cmmd.args + '*', inline: false }, - { emote: 'Example', role: '```' + cmmd.example + '```', inline: false }, - ], - ); - } - } - return false; - }, - prefix: './', - commands: [ - { - name: 'about', - description: 'returns a message with information about Portal Bot.', - super_description: '**about**, returns a message with information about Portal Bot.' + - 'Links for features and premium upgrade path is also given.', - example: './about', - args: 'none', - }, - { - name: 'announce', - description: 'makes an announcement via portal bot to the announcement channel or creates a new channel' + - ' if arguments are given.', - super_description: '**announce**, announce makes an announcement via portal bot to the announcement' + - ' channel, ./announce hello im jhon | i want to play games, Here what goes until the "|" is the' + - ' title and the the rest it the body your message.', - example: './announce body | title', - args: '<@title> | <@description>', - }, - { - name: 'announcement', - description: 'sets the text channel you wrote the command in as the announcement channel or creates a' + - ' new channel if arguments are given.', - super_description: '**announcement**, sets the text channel you wrote the command in as the announcement' + - 'channel, which means that every time someone times an announcement is displayed there. If channel is' + - ' given as argument, a new channel is created and set as announcements channel.', - example: './announcement announcement_name | announcement_category, ./announcement announcement_name, ./announcement', - args: '<@channel_name> | <@category_name>', - }, - { - name: 'auth_role_add', - description: 'auth_role_add will add a role to the autorized list of roles that can access certain commands.', - super_description: '**auth_role_add**, auth_role_add will add a role to the autorized list of roles that ' + - ' can access certain commands. Selected roles will be granted higher access to more powerful Portal ' + - ' commands that can manipulate the flow of the server.', - example: './auth_role_rem one_role', - args: '<@role_name>', - }, - { - name: 'auth_roles', - description: 'auth_roles will display all the authorization roles that allow user to use portal .', - super_description: '**auth_roles**, auth_roles will add a role to the autorized list of roles that ' + - ' can access certain commands. Selected roles will be granted higher access to more powerful Portal ' + - ' commands that can manipulate the flow of the server.', - example: './auth_role_rem one_role', - args: '<@role_name>', - }, - { - name: 'auth_role_rem', - description: 'auth_role_rem will remove a role to the autorized list of roles that can access certain commands.', - super_description: '**auth_role_rem**, auth_role_rem will remove a role to the autorized list of roles that ' + - ' can access certain commands. Selected roles will be stripped of the higher access to more powerful Portal ' + - ' commands that can manipulate the flow of the server.', - example: './auth_role_rem one_role', - args: '<@role_name>', - }, - { - name: 'corona', - description: 'corona replys with todays latest figures on the novel corona virus.', - super_description: '**corona**, replys with todays latest figures on the novel corona virus. ' + - 'You can give input lower or upper case ex: gr or GR if none is given global stats are displayed.', - example: './corona code, ./corona country, ./corona', - args: '<@country code>, <@country country>', - }, - { - name: 'focus', - description: 'focus creates a channel with the people you selected and auto deletes on set time.', - super_description: '**focus**, solves the problem that people have when in a channel with ' + - 'a lot of people, but want to talk to another person and can over the other voices. ' + - 'With focus when both users have requested a focus on a person, they will be automatically moved ' + - 'moved to a new channel where they can speak for the average of the times they requested and when ' + - 'time elapses they will be moved back to the channel they where before focus (2min default time).', - example: './focus user_name', - args: ' | <@time_to_focus>', - }, - { - name: 'force', - description: 'creates a new channel and moves all users to new channel.', - super_description: '**force**, creates a new channel and moves all users to new channel,' + - ' in order to get a new channel name if cooldown is still in effect.', - example: './force', - args: 'none', - }, - { - name: 'help', - description: 'returns a help-list of all commands and regex manipulation.', - super_description: '**help**, sends personal messages to the one who requests them.\n You can run' + - './help commands, ./help variables, ./help pipes, ./help attributes, ./help structures, to ' + - 'get only the category you choose.\n You can run ./help specific_property, like portal or set, etc.' + - 'In order to get a more descriptive definition of the property chosen', - example: './help, ./help attr, ./help portal', - args: '@specific_command OR @vrbl/@cmmd/@pipe/@attr', - }, - { - name: 'join', - description: 'joins the caller\'s voice channel.', - super_description: '**join**, joins the caller\'s voice channel. Makes announcements about people that' + - ' left and people that joined, and talks loudly every response', - example: './join', - args: 'none', - }, - { - name: 'joke', - description: 'returns a joke.', - super_description: '**joke**, returns a joke. You can specify the category of joke by' + - ' using arguments: dad, chuck, blonde, knock-knock, animal or jod.' + - ' By default it is about you.', - example: './joke', - args: '<@category>', - }, - { - name: 'leave', - description: 'leaves the voice channel portal is currently in.', - super_description: '**leave**, leaves the voice channel portal is currently in.', - example: './leave', - args: 'none', - }, - { - name: 'leaderboard', - description: 'returns the leaderboard.', - super_description: '**leaderboard**, returns the leaderboard.', - example: './leaderboard 5', - args: '<@number_of_ranks>', - }, - { - name: 'level', - description: 'returns your level card.', - super_description: '**level**, returns your level card with all member stats.', - example: './level', - args: 'none', - }, - { - name: 'music', - description: 'sets the text channel you wrote the command in as the music channel or creates a new channel' + - ' if arguments are given.', - super_description: '**music**, sets the text channel you wrote the command in as the music channel or' + - ' creates a new channel if arguments are given. In the music channel there is a music player and' + - ' nothing else. Users can request songs write there and play/pause/stop/skip the current song.', - example: './music music_name | music_category, ./music music_name, ./music', - args: '<@channel_name> | <@category_name>', - }, - { - name: 'ping', - description: 'returns round trip latency.', - super_description: '**ping**, returns the latency of portal bot.', - example: './ping', - args: 'none', - }, - { - name: 'portal', - description: 'creates a voice channel and a category for it.', - super_description: '**portal**, creates, portal channels. ' + - 'Portal channels are a portal to an infinite amount of voice channels, by entering ' + - 'a voice channel you are redirected to a newly created voice channel that you are ' + - 'the owner of. When everyone leaves the channel will be destroyed.\n', - example: './portal portal_name | portal_category, ./portal portal_name', - args: ' | <@category_name>', - }, - { - name: 'ranks', - description: 'returns your Ranking system of current server.', - super_description: '**ranks**, returns your Ranking system of current server (if one is set).', - example: './ranks', - args: 'none', - }, - { - name: 'role', - description: 'creates a role message.', - super_description: '**role**, creates a message that distributes roles.' + - 'Roles can be given or striped by reacting to the message.\n' + - '(Please make sure you have no space infront or behind *role name* or *emotes*)', - example: 'json\n./role ' + - '[\n\t{ "give": ":heart:", "strip": ":poop:", "role": "moba" },\n' + - '\t{ "give": ":rofl:", "strip": ":dog:", "role": "fps" }\n]\n' + - '\n>This will create a message giving/striping moba role with :heart:/:poop: and fps role with :rofl:/:dog:.', - args: '```json\nJSON array of objects:\n{ "give": ":heart:", "strip": ":poop:", "role": "moba" }```', - }, - { - name: 'roll', - description: 'rolls requested dice.', - super_description: '**roll**, rolls requested dice you can also combine rolls.' + - 'Rolls are following the same philosophy as roll20 does.', - example: './roll 3d12+5', - args: '', - }, - { - name: 'run', - description: 'returns the log of data given in log_string.', - super_description: '**run**, gives you the opportunity to run regexes in any text channel. ' + - 'You can get properties about the channel you are in.\n' + - 'If regex is empty string it will return a dot (.)', - example: './run $member_count &locale\nthis will return 4 and gr if member count and locale are that', - args: '', - }, - { - name: 'save', - description: 'saves current state of server.', - super_description: '**save**, saves the current state of portal', // should not be spammed - example: './save', - args: 'none', - }, - { - name: 'set', - description: 'sets the value of attribute.', - super_description: '**set**, sets attributes of the current voice channel if you are the owner ' + - 'or the portal channel if you are the owner of that.\n', - example: './set locale gr', - args: ' ', - }, - { - name: 'set_ranks', - description: 'creates your ranking system.', - super_description: '**ranks**, creates your ranking system by which roles are distributed by reachig.' + - 'certain levels that have been defined.', - example: 'json\n./role ' + - '[\n\t{ "level": "2", "role": "Alpha" },\n' + - '\t{ "level": "5", "role": "Beta" }\n]\n', - args: '```json\nJSON array of objects:\n[{ "level": "2", "role": "Alpha" }]```', - }, - { - name: 'setup', - description: 'creates a portal, spotify, url-only and announcement channel automatically.', - super_description: '**setup**, will autogenerate a portal, spotify, url-only and announcement channels ' + - 'at once, removing the hustle of setting up the server.\n', - example: './setup', - args: 'none', - }, - { - name: 'spotify', - description: 'sets the text channel you wrote the command in as the Spotify channel or creates a new channel' + - ' if arguments are given.', - super_description: '**spotify**, sets the text channel you wrote the command in as the Spotify channel, ' + - 'which means that every time someone listens to a song on Spotify it will be displayed. If channel is given as ' + - 'argument, a new channel is created and set as Spotify channel.', - example: './spotify spotify_name | spotify_category, ./spotify spotify_name, ./spotify', - args: '<@channel_name> | <@category_name>', - }, - { - name: 'url', - ddescription: 'sets the text channel you wrote the command in as the url channel or creates a new channel' + - ' if arguments are given.', - super_description: '**url**, sets the text channel you wrote the command in as the url channel, ' + - 'which means that every time someone listens to a song on url it will be displayed. If channel is given as ' + - 'argument, a new channel is created and set as url channel.', - example: './url url_name | url_category, ./url url_name, ./url', - args: '<@channel_name> | <@category_name>', - }, - ], -}; diff --git a/src/properties/pipe_list.js b/src/properties/pipe_list.js deleted file mode 100644 index 1c5a01aa..00000000 --- a/src/properties/pipe_list.js +++ /dev/null @@ -1,152 +0,0 @@ -const voca = require('voca'); - -const help_mngr = require('../functions/help_manager'); -module.exports = -{ - is_pipe: function (arg) { - for (let i = 0; i < this.pipes.length; i++) { - if (String(arg).substring(1, (String(this.pipes[i].name).length + 1)) == this.pipes[i].name) { return this.pipes[i].name; } - } - return false; - }, - get_help: function () { - const pipe_array = []; - for (let i = 0; i < this.pipes.length; i++) { - pipe_array.push({ - emote: this.pipes[i].name, - role: '**desc**: *' + this.pipes[i].description + '*' + - '\n**args**: *' + this.pipes[i].args + '*', - inline: true, - }); - } - return help_mngr.create_rich_embed('Pipes', - 'Prefix: ' + this.prefix + '\nData manipulating pipes.' + - '\n**!**: *mandatory*, **@**: *optional*', - '#6EEB83', pipe_array); - }, - get_help_super: function (check) { - for (let i = 0; i < this.pipes.length; i++) { - const pipe = this.pipes[i]; - if (pipe.name === check) { - return help_mngr.create_rich_embed( - pipe.name, - 'Type: Pipe' + - '\nPrefix: ' + this.prefix + - '\n**!**: *mandatory*, **@**: *optional*', - '#6EEB83', - [ - { emote: 'Description', role: '*' + pipe.super_description + '*', inline: false }, - { emote: 'Arguments', role: '*' + pipe.args + '*', inline: false }, - { emote: 'Example', role: '*' + pipe.example + '*', inline: false }, - ], - ); - } - } - return false; - }, - get: function (str, pipe) { - for (let l = 0; l < this.pipes.length; l++) { - if (pipe === this.pipes[l].name) { - return this.pipes[l].get(str); - } - } - return -1; - }, - prefix: '|', - pipes: [ - { - name: 'camelCase', - description: 'returns an camelCase of the input', - super_description: '**camelCase**, connects words and makes the first character upper-case.', - example: '(variable, string)|camelCase', - args: 'none', - get: (str) => { return voca.camelCase(str); }, - }, - { - name: 'capitalize', - description: 'returns an capitalize of the input', - super_description: '**capitalize**, makes the first character upper-case.', - example: '(variable, string)|capitalize', - args: 'none', - get: (str) => { return voca.capitalize(str); }, - }, - { - name: 'decapitalize', - description: 'returns an decapitalize of the input', - super_description: '**decapitalize**, makes the first character lower-case.', - example: '(variable, string)|decapitalize', - args: 'none', - get: (str) => { return voca.decapitalize(str); }, - }, - { - name: 'lowerCase', - description: 'returns an lowerCase of the input', - super_description: '**lowerCase**, makes all characters lower-case.', - example: '(variable, string)|lowerCase', - args: 'none', - get: (str) => { return voca.lowerCase(str); }, - }, - { - name: 'upperCase', - description: 'returns an upperCase of the input', - super_description: '**upperCase**, makes all characters upper-case.', - example: '(variable, string)|upperCase', - args: 'none', - get: (str) => { return voca.upperCase(str); }, - }, - { - name: 'populous', - description: 'returns the name of the most common element in list', - super_description: '**populous**, returns the name of the most common element in list.', - example: '(array)|populous', - args: 'none', - get: () => { - return 'not yet implemented'; - }, - }, - { - name: 'populous_count', - description: 'returns the count of most common element in list', - super_description: '**populous_count**, returns the count of most common element in list.', - example: '(array)|populous_count', - args: 'none', - get: () => { - return 'not yet implemented'; - }, - }, - { - name: 'snakeCase', - description: 'returns an snakeCase of the input', - super_description: '**snakeCase**, connects all words with \'_\', like a snake.', - example: '(variable, string)|snakeCase', - args: 'none', - get: (str) => { return voca.snakeCase(str); }, - }, - { - name: 'souvlakiCase', - description: 'returns an souvlakiCase of the input', - super_description: '**souvlakiCase**, connects all words with \'-\', like a greek souvlaki.', - example: '(variable, string)|souvlakiCase', - args: 'none', - get: (str) => { return voca.kebabCase(str); }, - }, - { - name: 'summary_count', - description: 'returns the count of members having a status', - super_description: '**summary_count**, returns the count of members having a status', - example: '(array)|summary_count', - args: 'none', - get: (str) => { - return voca.words(str).length; - }, - }, - { - name: 'titleCase', - description: 'returns an titleCase of the input', - super_description: '**titleCase**, makes every words first character upper-case.', - example: '(variable, string)|titleCase', - args: 'none', - get: (str) => { return voca.titleCase(str); }, - }, - ], -}; diff --git a/src/properties/structure_list.js b/src/properties/structure_list.js deleted file mode 100644 index fa6e5846..00000000 --- a/src/properties/structure_list.js +++ /dev/null @@ -1,66 +0,0 @@ -const help_mngr = require('../functions/help_manager'); - -module.exports = -{ - is_structure: function (arg) { - for (let i = 0; i < this.structures.length; i++) { - if (String(arg).substring(1, (String(this.structures[i].name).length + 1)) == this.structures[i].name) { - return this.structures[i].name; - } - } - return false; - }, - get_help: function () { - const strc_array = []; - for (let i = 0; i < this.structures.length; i++) { - strc_array.push({ - emote: this.structures[i].name, - role: '**desc**: *' + this.structures[i].description + '*' + - '\n**args**: *' + this.structures[i].args + '*', - inline: true, - }); - } - return help_mngr.create_rich_embed('Structures', - 'Prefix: ' + this.prefix + '\nStructural functionality.' + - '\n**!**: *mandatory*, **@**: *optional*', - '#EEB902', strc_array); - }, - get_help_super: function (check) { - for (let i = 0; i < this.structures.length; i++) { - const strc = this.structures[i]; - if (strc.name === check) { - return help_mngr.create_rich_embed( - strc.name, - 'Type: Structure' + - '\nPrefix: ' + this.prefix + - '\n**!**: *mandatory*, **@**: *optional*', - '#EEB902', - [ - { emote: 'Description', role: '*' + strc.super_description + '*', inline: false }, - { emote: 'Arguments', role: '*' + strc.args + '*', inline: false }, - { emote: 'Example', role: '*' + strc.example + '*', inline: false }, - ], - ); - } - } - return false; - }, - prefix: '{{', - structures: [ - { - name: 'if', - description: 'if statement with two outcomes: ```json\n{{\n\t"if": "John", "is": "===", "with": "John",\n\t' + - '"yes": "same name", "no": "not the same name"\n}}```', - super_description: '**if**, gets two arguments, an operator and two outcomes and returns ' + - 'outcome a if statement is true and second if not.\n' + - 'example: ./run ```json\n{{\n\t"if": "John", "is": "===", "with": "John",\n\t' + - '"yes": "same name", "no": "not the same name"\n}}```\n This will return *same name* as ' + - 'it is the same name.\nOperator is can take values: ==, ===, !=, !==, >, <, >=, <=.\n' + - '> You can read the statement as: if John is equal with John ? yes, same name or no, not same name.\n' + - '> You cannot encapsulate if statements.', - example: '{{\n\t"if": "John", "is": "===", "with": "John",\n\t' + - '"yes": "same name", "no": "not the same name"\n}}', - args: 'JSON with: if, is, with, yes, no', - }, - ], -}; diff --git a/src/properties/variable_list.js b/src/properties/variable_list.js deleted file mode 100644 index 8044bca7..00000000 --- a/src/properties/variable_list.js +++ /dev/null @@ -1,342 +0,0 @@ -const moment = require('moment'); - -const rtrv = require('../functions/status_manager'); -const help_mngr = require('../functions/help_manager'); - -module.exports = -{ - is_variable: function (arg) { - for (let i = 0; i < this.variables.length; i++) { - if (String(arg).substring(1, (String(this.variables[i].name).length + 1)) == this.variables[i].name) { - return this.variables[i].name; - } - } - return false; - }, - get_help: function () { - const vrbl_array = []; - for (let i = 0; i < this.variables.length; i++) { - vrbl_array.push({ - emote: this.variables[i].name, - role: '**desc**: *' + this.variables[i].description + '*' + - '\n**args**: *' + this.variables[i].args + '*', - inline: true, - }); - } - return help_mngr.create_rich_embed('Variables', - 'Prefix: ' + this.prefix + '\nEditable variables of Portal channel.' + - '\n**!**: *mandatory*, **@**: *optional*', - '#1BE7FF', vrbl_array); - }, - get_help_super: function (check) { - for (let i = 0; i < this.variables.length; i++) { - const vrbl = this.variables[i]; - if (vrbl.name === check) { - return help_mngr.create_rich_embed( - vrbl.name, - 'Type: Variable' + - '\nPrefix: ' + this.prefix + - '\n**!**: *mandatory*, **@**: *optional*', - '#1BE7FF', - [ - { emote: 'Description', role: '*' + vrbl.super_description + '*', inline: false }, - { emote: 'Arguments', role: '*' + vrbl.args + '*', inline: false }, - { emote: 'Example', role: '```' + vrbl.example + '```', inline: false }, - ], - ); - } - } - return false; - }, - get: function (voice_channel, voice_object, portal_list_object, guild_object, guild, vrbl) { - for (let l = 0; l < this.variables.length; l++) { - if (vrbl === this.variables[l].name) { - return this.variables[l].get(voice_channel, voice_object, portal_list_object, guild_object, guild); - } - } - return -1; - }, - - prefix: '$', - variables: [ - { - name: '#', - description: 'returns the channel number in list.', - super_description: '**#**, returns the channel number in list, if it was created first .' + - 'it will display 1, if third 3, etc.', - example: '$#', - args: 'none', - get: (voice_channel, voice_object, portal_list_object) => { - let i = 0; - for (const portal_key in portal_list_object) { - if (portal_list_object[portal_key].voice_list[voice_channel.id]) { - for (const voice_key in portal_list_object[portal_key].voice_list) { - console.log('voice_key :>> ', voice_key); - i++; - if (voice_key === voice_channel.id) return i.toString(); - } - } - } - return '0'; - }, - }, - { - name: '##', - description: 'returns the channel number in list with # in the front.', - super_description: '**##**, returns the channel number in list with # ' + - 'in the front, if it was created first ' + - 'it will display #1, if third #3, etc.', - example: '$##', - args: 'none', - get: (voice_channel, voice_object, portal_list_object) => { - let i = 0; - for (const portal_key in portal_list_object) { - if (portal_list_object[portal_key].voice_list[voice_channel.id]) { - for (const voice_key in portal_list_object[portal_key].voice_list) { - i++; - if (voice_key === voice_channel.id) return '#' + i.toString(); - } - } - } - return '#0'; - }, - }, - { - name: 'creator_portal', - description: 'returns the creator of current voice channel\'s portal.', - super_description: '**creator_portal**, returns the creator of current voice channel\'s portal.', - example: '$creator_portal', - args: 'none', - get: (voice_channel, voice_object, portal_list_object, guild_object, guild) => { - for (const portal_key in portal_list_object) { - if (portal_list_object[portal_key].voice_list[voice_channel.id]) { - const display_name = guild.members.cache - .find(member => member.id === portal_list_object[portal_key].creator_id).displayName; - return display_name ? display_name : 'portal creator left'; - } - } - }, - }, - { - name: 'creator_voice', - description: 'returns the creator of current voice channel.', - super_description: '**creator_voice**, returns the creator of current voice channel.', - example: '$creator_voice', - args: 'none', - get: (voice_channel, voice_object, portal_list_object, guild_object, guild) => { - const display_name = guild.members.cache - .find(member => member.id === voice_object.creator_id).displayName; - return display_name ? display_name : 'voice creator left'; - }, - }, - { - name: 'date', - description: 'returns the full date: dd/mm/yyyy.', - super_description: '**date**, full date: dd/mm/yyyy.', - example: '$date', - args: 'none', - get: (voice_channel, voice_object) => { - return moment().locale(voice_object.locale).subtract(10, 'days').calendar(); - }, - }, - { - name: 'day_number', - description: 'returns the day number.', - super_description: '**day_number**, returns the day number.', - example: '$day_number', - args: 'none', - get: (voice_channel, voice_object) => { - return moment().locale(voice_object.locale).date(); - }, - }, - { - name: 'day_name', - description: 'returns the day name.', - super_description: '**day_name**, returns the day name.', - example: '$day_name', - args: 'none', - get: (voice_channel, voice_object) => { - return moment().locale(voice_object.locale).format('dddd'); - }, - }, - { - name: 'month_number', - description: 'returns the month by number.', - super_description: '**month_number**, returns the month by number.', - example: '$month_number', - args: 'none', - get: (voice_channel, voice_object) => { - return moment().locale(voice_object.locale).format('M'); - }, - }, - { - name: 'month_name', - description: 'returns the month by name.', - super_description: '**month_name**, returns the month by name.', - example: '$month_name', - args: 'none', - get: (voice_channel, voice_object) => { - return moment().locale(voice_object.locale) - .startOf('month').format('MMMM'); - }, - }, - { - name: 'year', - description: 'returns the year.', - super_description: '**year**, returns the year.', - example: '$year', - args: 'none', - get: (voice_channel, voice_object) => { - return moment().locale(voice_object.locale).format('yyyy'); - }, - }, - { - name: 'time', - description: 'full time: hh/mm/ss.', - super_description: '**time**, full time: hh/mm/ss.', - example: '$time', - args: 'none', - get: (voice_channel, voice_object) => { - return moment().locale(voice_object.locale).format('h:mm:ss'); - }, - }, - { - name: 'hour', - description: 'returns the hour in current time.', - super_description: '**hour**, returns the hour.', - example: '$hour', - args: 'none', - get: (voice_channel, voice_object) => { - return moment().locale(voice_object.locale).format('h'); - }, - }, - { - name: 'minute', - description: 'returns the minute in current time.', - super_description: '**minute**, returns the minute.', - example: '$minute', - args: 'none', - get: (voice_channel, voice_object) => { - return moment().locale(voice_object.locale).format('mm'); - }, - }, - { - name: 'second', - description: 'returns the second in current time.', - super_description: '**second**, returns the second.', - example: '$second', - args: 'none', - get: (voice_channel, voice_object) => { - return moment().locale(voice_object.locale).format('ss'); - }, - }, - { - name: 'member_active_count', - description: 'returns number of members with a status.', - super_description: '**member_with_status**, returns the number of members with a status.', - example: '$member_active_count', - args: 'none', - get: (voice_channel) => { - let cnt = 0; - voice_channel.members.forEach((member) => { - if (member.presence.game !== null && !member.user.bot) { cnt++; } - }); - return cnt; - }, - }, - { - name: 'member_count', - description: 'returns number of members in channel.', - super_description: '**member_count**, returns the number of members in channel.', - example: '$member_count', - args: 'none', - get: (voice_channel) => { - let cnt = 0; - voice_channel.members.forEach((member) => { - if (!member.user.bot) { cnt++; } - }); - return cnt; - }, - }, - { - name: 'member_history', - description: 'returns a list of all members that have connected to the channel.', - super_description: '**member_history**, returns a list of all members that have connected to the channel.', - example: '$member_history', - args: 'none', - get: () => { - return 'no_yet_implemented'; - }, - }, - { - name: 'member_list', - description: 'returns the currently played games.', - super_description: '**member_list**, returns the currentstatuses.', - example: '$member_list', - args: 'none', - get: (voice_channel) => { - const mmbr_lst = []; - voice_channel.members.forEach(member => { mmbr_lst.push(member.displayName); }); - return mmbr_lst; - }, - }, - { - name: 'member_with_status', - description: 'returns number of members with a status.', - super_description: '**member_with_status**, returns the number of members with a status.', - example: '$member_with_status', - args: 'none', - get: (voice_channel) => { - let cnt = 0; - voice_channel.members.forEach((member) => { - if (member.presence.game !== null) { cnt++; } - }); - return cnt; - }, - }, - { - name: 'status_count', - description: 'returns the count of current member statuses.', - super_description: '**status_count**, returns the count of current member statuses.', - example: '$status_count', - args: 'none', - get: (voice_channel, voice_object) => { - const status_list = rtrv.get_status_list(voice_channel, voice_object); - if (typeof status_list === 'object' && status_list !== null) { return 0; } - else { status_list.length; } - }, - }, - { - name: 'status_history', - description: 'returns the history of all the statuses.', - super_description: '**status_history**, returns the history of all the statuses.', - example: '$status_history', - args: 'none', - get: () => { - return 'no_yet_implemented'; - }, - }, - { - name: 'status_list', - description: 'returns the list of current member statuses.', - super_description: '**status_list**, returns the list of all current members statuses.', - example: '$status_list', - args: 'none', - get: (voice_channel, voice_object) => { - return rtrv.get_status_list(voice_channel, voice_object); - }, - }, - { - name: 'last_update', - description: 'is the last time the channel name was updated', - super_description: '**last_update**, is the last time the channel name was updated', - example: '$last_update', - args: 'none', - get: (voice_channel, voice_object) => { - return `${Math.round(((Date.now() - voice_object.last_update) / 1000 / 60))}m` + - `${Math.round(((Date.now() - voice_object.last_update) / 1000) % 60)}s`; - }, - }, - ], -}; - diff --git a/src/types/classes/GiveRolePrtl.ts b/src/types/classes/GiveRolePrtl.ts new file mode 100644 index 00000000..da0f7e81 --- /dev/null +++ b/src/types/classes/GiveRolePrtl.ts @@ -0,0 +1,28 @@ +export class GiveRole { + role_id: string; + give: string; + strip: string; + + constructor( + role_id: string, + give: string, + strip: string + ) { + this.role_id = role_id; + this.give = give; + this.strip = strip; + } +} + +export class GiveRolePrtl { + public message_id: string; + public role_emote_map: GiveRole[]; + + constructor( + message_id: string, + role_emote_map: GiveRole[] + ) { + this.message_id = message_id; + this.role_emote_map = role_emote_map; + } +}; diff --git a/src/types/classes/GuildPrtl.ts b/src/types/classes/GuildPrtl.ts new file mode 100644 index 00000000..cdece79e --- /dev/null +++ b/src/types/classes/GuildPrtl.ts @@ -0,0 +1,75 @@ +import { VideoSearchResult } from "yt-search"; +import { Rank } from "../interfaces/InterfacesPrtl"; +import { GiveRolePrtl } from "./GiveRolePrtl"; +import { MemberPrtl } from "./MemberPrtl"; +import { PortalChannelPrtl } from "./PortalChannelPrtl"; +import { StreamDispatcher } from "discord.js"; + +export class MusicData { + public channel_id: string | undefined; + public message_id: string | undefined; + public votes: string[] | undefined; + + constructor(channel_id: string, + message_id: string, + votes: string[]) { + this.channel_id = channel_id; + this.message_id = message_id; + this.votes = votes; + } +} + +export class GuildPrtl { + public id: string; + public portal_list: PortalChannelPrtl[]; + public member_list: MemberPrtl[]; + public url_list: string[]; + public role_list: GiveRolePrtl[]; + public ranks: Rank[]; + public auth_role: string[]; + public spotify: string | null; + public music_data: MusicData; + public music_queue: VideoSearchResult[]; + public dispatcher: StreamDispatcher | undefined; + public announcement: string | null; + public locale: string; + public announce: boolean; + public level_speed: string; + public premium: boolean; + + constructor( + id: string, + portal_list: PortalChannelPrtl[], + member_list: MemberPrtl[], + url_list: string[], + role_list: GiveRolePrtl[], + ranks: Rank[], + auth_role: string[], + spotify: string | null, + music_data: MusicData, + music_queue: VideoSearchResult[], + dispatcher: StreamDispatcher | undefined, + announcement: string | null, + locale: string, + announce: boolean, + level_speed: string, + premium: boolean + ) { + this.id = id; + this.portal_list = portal_list; + this.member_list = member_list; + this.url_list = url_list; + this.role_list = role_list; + this.ranks = ranks; + this.auth_role = auth_role; + this.spotify = spotify; + this.music_data = music_data; + this.music_queue = music_queue; + this.dispatcher = dispatcher; + this.announcement = announcement; + this.locale = locale; + this.announce = announce; + this.level_speed = level_speed; + this.premium = premium; + } +}; \ No newline at end of file diff --git a/src/types/classes/MemberPrtl.ts b/src/types/classes/MemberPrtl.ts new file mode 100644 index 00000000..183354d6 --- /dev/null +++ b/src/types/classes/MemberPrtl.ts @@ -0,0 +1,27 @@ +export class MemberPrtl { + public id: string; + public level: number; + public rank: number; + public tier: number; + public points: number; + public timestamp: Date | null; + public admin: boolean; + + constructor( + id: string, + level: number, + rank: number, + tier: number, + points: number, + timestamp: Date | null, + admin: boolean + ) { + this.id = id; + this.level = level; + this.rank = rank; + this.tier = tier; + this.points = points; + this.timestamp = timestamp; + this.admin = admin; + } +}; \ No newline at end of file diff --git a/src/types/classes/PortalChannelPrtl.ts b/src/types/classes/PortalChannelPrtl.ts new file mode 100644 index 00000000..c319bbc1 --- /dev/null +++ b/src/types/classes/PortalChannelPrtl.ts @@ -0,0 +1,47 @@ +import { VoiceChannelPrtl } from "./VoiceChannelPrtl"; + +export class PortalChannelPrtl { + public id: string; + public creator_id: string; + public regex_portal: string; + public regex_voice: string; + public voice_list: VoiceChannelPrtl[]; + public no_bots: boolean; + public limit_portal: number; + public time_to_live: number; + public refresh_rate: number; + public locale: string; + public ann_announce: boolean; + public ann_user: boolean; + public user_limit_portal: number; + + constructor( + id: string, + creator_id: string, + regex_portal: string, + regex_voice: string, + voice_list: VoiceChannelPrtl[], + no_bots: boolean, + limit_portal: number, + time_to_live: number, + refresh_rate: number, + locale: string, + ann_announce: boolean, + ann_user: boolean, + user_limit_portal: number + ) { + this.id = id; + this.creator_id = creator_id; + this.regex_portal = regex_portal; + this.regex_voice = regex_voice; + this.voice_list = voice_list; + this.no_bots = no_bots; + this.limit_portal = limit_portal; + this.time_to_live = time_to_live; + this.refresh_rate = refresh_rate; + this.locale = locale; + this.ann_announce = ann_announce; + this.ann_user = ann_user; + this.user_limit_portal = user_limit_portal; + } +}; diff --git a/src/types/classes/RolePrtl.ts b/src/types/classes/RolePrtl.ts new file mode 100644 index 00000000..25baf608 --- /dev/null +++ b/src/types/classes/RolePrtl.ts @@ -0,0 +1,9 @@ +export class RolePrtl { + public role_emote_map: any; + + constructor( + role_emote_map: any + ) { + this.role_emote_map = role_emote_map; + } +}; diff --git a/src/types/classes/VoiceChannelPrtl.ts b/src/types/classes/VoiceChannelPrtl.ts new file mode 100644 index 00000000..03f44e06 --- /dev/null +++ b/src/types/classes/VoiceChannelPrtl.ts @@ -0,0 +1,33 @@ +export class VoiceChannelPrtl { + public id: string; + public creator_id: string; + public regex: string; + public no_bots: boolean; + public time_to_live: number; + public refresh_rate: number; + public locale: string; + public ann_announce: boolean; + public ann_user: boolean; + + constructor( + id: string, + creator_id: string, + regex: string, + no_bots: boolean, + time_to_live: number, + refresh_rate: number, + locale: string, + ann_announce: boolean, + ann_user: boolean + ) { + this.id = id; + this.creator_id = creator_id; + this.regex = regex; + this.no_bots = no_bots; + this.time_to_live = time_to_live; + this.refresh_rate = refresh_rate; + this.locale = locale; + this.ann_announce = ann_announce; + this.ann_user = ann_user; + } +}; diff --git a/src/types/interfaces/Attribute.ts b/src/types/interfaces/Attribute.ts new file mode 100644 index 00000000..89cca05c --- /dev/null +++ b/src/types/interfaces/Attribute.ts @@ -0,0 +1,397 @@ +/* eslint-disable no-unused-vars */ +import { GuildMember, MessageEmbed, VoiceChannel } from 'discord.js'; +import { create_rich_embed } from '../../libraries/helpOps'; +import { GuildPrtl } from '../classes/GuildPrtl'; +import { PortalChannelPrtl } from '../classes/PortalChannelPrtl'; +import { VoiceChannelPrtl } from '../classes/VoiceChannelPrtl'; +import { InterfaceBlueprint } from './InterfacesPrtl'; + +const locales = ['gr', 'en', 'de']; +export const attribute_prefix: string = '&'; +const attributes: InterfaceBlueprint[] = [ + { + name: 'ann_announce', + description: 'returns/sets whether Portal announces events in current channel', + super_description: '**ann_announce** returns/sets whether Portal announces events in current channel', + example: '&ann_announce', + args: 'true/false', + get: (voice_channel: VoiceChannel, voice_object: VoiceChannelPrtl, + portal_object: PortalChannelPrtl, guild_object: GuildPrtl) => { + return voice_object.ann_announce; + }, + set: (voice_channel: VoiceChannel, voice_object: VoiceChannelPrtl, + portal_object: PortalChannelPrtl, guild_object: GuildPrtl, value: string) => { + if (value === 'true') { + voice_object.ann_announce = true; + return 1; + } + else if (value === 'false') { + voice_object.ann_announce = false; + return 1; + } + return -7; + }, + auth: 'voice', + }, + { + name: 'ann_announce_portal', + description: 'returns/sets whether Portal announces events in current portals spawned channels', + super_description: '**ann_announce_portal** returns/sets whether Portal announces events in ' + + 'current portals spawned channels', + example: '&ann_announce_portal', + args: 'true/false', + get: (voice_channel: VoiceChannel, voice_object: VoiceChannelPrtl, + portal_object: PortalChannelPrtl, guild_object: GuildPrtl) => { + return portal_object.ann_announce; + }, + set: (voice_channel: VoiceChannel, voice_object: VoiceChannelPrtl, + portal_object: PortalChannelPrtl, guild_object: GuildPrtl, value: string) => { + if (value === 'true') { + portal_object.ann_announce = true; + return 1; + } + else if (value === 'false') { + portal_object.ann_announce = false; + return 1; + } + return -7; + }, + auth: 'portal', + }, + { + name: 'ann_user', + description: 'returns/sets whether Portal announces user\'s join or leave from current channel', + super_description: '**ann_user** returns/sets whether Portal announces user\'s join or leave from current channel', + example: '&ann_user', + args: 'true/false', + get: (voice_channel: VoiceChannel, voice_object: VoiceChannelPrtl, + portal_object: PortalChannelPrtl, guild_object: GuildPrtl) => { + return voice_object.ann_user; + }, + set: (voice_channel: VoiceChannel, voice_object: VoiceChannelPrtl, + portal_object: PortalChannelPrtl, guild_object: GuildPrtl, value: string) => { + if (value === 'true') { + voice_object.ann_user = true; + return 1; + } + else if (value === 'false') { + voice_object.ann_user = false; + return 1; + } + return -7; + }, + auth: 'voice', + }, + { + name: 'ann_user_portal', + description: 'returns/sets whether Portal announces user\'s join or leave from current portals spawned channels', + super_description: '**ann_user_portal** returns/sets whether Portal announces user\'s join or leave from ' + + 'current portals spawned channels', + example: '&ann_user_portal', + args: 'true/false', + get: (voice_channel: VoiceChannel, voice_object: VoiceChannelPrtl, + portal_object: PortalChannelPrtl, guild_object: GuildPrtl) => { + return portal_object.ann_user; + }, + set: (voice_channel: VoiceChannel, voice_object: VoiceChannelPrtl, + portal_object: PortalChannelPrtl, guild_object: GuildPrtl, value: string) => { + if (value === 'true') { + portal_object.ann_user = true; + return 1; + } + else if (value === 'false') { + portal_object.ann_user = false; + return 1; + } + return -7; + }, + auth: 'portal', + }, + { + name: 'bitrate', + description: 'returns/sets bitrate of channel', + super_description: '**bitrate** returns/sets bitrate of channel', + example: '&bitrate', + args: 'number', + get: (voice_channel: VoiceChannel) => { + return voice_channel.bitrate; + }, + set: (voice_channel: VoiceChannel, voice_object: VoiceChannelPrtl, + portal_object: PortalChannelPrtl, guild_object: GuildPrtl, value: string) => { + // voice_channel.setBitrate(Number(value)); + voice_channel.edit({ bitrate: Number(value) }) + .then(channel => console.log( + `Channel's new position is ${channel.bitrate} and should be ${value}`)) + .catch(console.error); + return 1; + }, + auth: 'voice', + }, + { + name: 'locale', + description: 'returns/sets locale of current channel', + super_description: '**locale**, returns/sets language used in statuses', + example: '&locale', + args: 'en/gr/de', + get: (voice_channel: VoiceChannel, voice_object: VoiceChannelPrtl) => { + return voice_object.locale; + }, + set: (voice_channel: VoiceChannel, voice_object: VoiceChannelPrtl, + portal_object: PortalChannelPrtl, guild_object: GuildPrtl, value: string) => { + if (locales.includes(value)) { + voice_object.locale = String(value); + return 1; + } + else { + return -5; + } + }, + auth: 'voice', + }, + { + name: 'locale_guild', + description: 'returns/sets locale_guild of the guild', + super_description: '**locale_guild**, returns/sets guild locale makes the bot talk your language and all communication is done' + + 'in your local language', + example: '&locale_guild', + args: 'en/gr/de', + get: (voice_channel: VoiceChannel, voice_object: VoiceChannelPrtl, + portal_object: PortalChannelPrtl, guild_object: GuildPrtl) => { + return guild_object.locale; + }, + set: (voice_channel: VoiceChannel, voice_object: VoiceChannelPrtl, + portal_object: PortalChannelPrtl, guild_object: GuildPrtl, value: string) => { + if (locales.includes(value)) { + guild_object.locale = String(value); + return 1; + } + else { + return -5; + } + }, + auth: 'admin', + }, + { + name: 'locale_portal', + description: 'returns/sets locale_portal of current channel', + super_description: '**locale_portal**, returns/sets language used in statuses', + example: '&locale_portal', + args: 'en/gr/de', + get: (voice_channel: VoiceChannel, voice_object: VoiceChannelPrtl, portal_object: PortalChannelPrtl) => { + return portal_object.locale; + }, + set: (voice_channel: VoiceChannel, voice_object: VoiceChannelPrtl, + portal_object: PortalChannelPrtl, guild_object: GuildPrtl, value: string) => { + if (locales.includes(value)) { + portal_object.locale = String(value); + return 1; + } + else { + return -5; + } + }, + auth: 'portal', + }, + { + name: 'position', + description: 'returns/sets the position of the channel', + super_description: '**position**, returns/sets the position of the channel', + example: '&position', + args: '!position of channel', + get: (voice_channel: VoiceChannel) => { + return voice_channel.position; + }, + set: (voice_channel: VoiceChannel, voice_object: VoiceChannelPrtl, + portal_object: PortalChannelPrtl, guild_object: GuildPrtl, value: string) => { + voice_channel.edit({ position: Number(value) }) + .then(channel => console.log( + `Channel's new position is ${channel.position} and should be ${value}`)) + .catch(console.error); + return 1; + }, + auth: 'voice', + }, + { + name: 'regex', + description: 'returns/sets the title for current voice channel', + super_description: '**regex**, returns/sets the title for current voice channel', + example: '®ex', + args: '!regex', + get: (voice_channel: VoiceChannel, voice_object: VoiceChannelPrtl) => { + return voice_object.regex; + }, + set: (voice_channel: VoiceChannel, voice_object: VoiceChannelPrtl, + portal_object: PortalChannelPrtl, guild_object: GuildPrtl, value: string) => { + voice_object.regex = value; + return 1; + }, + auth: 'voice', + }, + { + name: 'regex_portal', + description: 'returns/sets title-guidelines of portal channel', + super_description: '**regex_portal**, returns/sets title-guidelines of portal channel', + example: '®ex_portal', + args: '!regex', + get: (voice_channel: VoiceChannel, voice_object: VoiceChannelPrtl, portal_object: PortalChannelPrtl) => { + return portal_object.regex_portal; + }, + set: (voice_channel: VoiceChannel, voice_object: VoiceChannelPrtl, + portal_object: PortalChannelPrtl, guild_object: GuildPrtl, value: string) => { + portal_object.regex_portal = value; + return 1; + }, + auth: 'portal', + }, + { + name: 'regex_voice', + description: 'returns/sets the default title for created voice channels', + super_description: '**regex_voice**, returns/sets the default title for created voice channels', + example: '®ex_voice', + args: '!regex', + get: (voice_channel: VoiceChannel, voice_object: VoiceChannelPrtl, portal_object: PortalChannelPrtl) => { + return portal_object.regex_voice; + }, + set: (voice_channel: VoiceChannel, voice_object: VoiceChannelPrtl, + portal_object: PortalChannelPrtl, guild_object: GuildPrtl, value: string) => { + portal_object.regex_voice = value; + return 1; + }, + auth: 'portal', + }, + { + name: 'user_limit', + description: 'returns/sets maximum number of members allowed', + super_description: '**user_limit**, returns/sets maximum number of members allowed', + example: '&user_limit', + args: '!number of maximum members (0 is infinite)', + get: (voice_channel: VoiceChannel) => { + return voice_channel.userLimit; + }, + set: (voice_channel: VoiceChannel, voice_object: VoiceChannelPrtl, + portal_object: PortalChannelPrtl, guild_object: GuildPrtl, value: number) => { + if (value >= 0) { + voice_channel.userLimit = Number(value); + return 1; + } + return -6; + }, + auth: 'voice', + }, + { + name: 'user_limit_portal', + description: 'returns/sets maximum number of members guideline for portal', + super_description: '**user_limit_portal**, returns/sets maximum number of members guideline for portal', + example: '&user_limit_portal', + args: '!number of maximum members (0 is infinite)', + get: (voice_channel: VoiceChannel, voice_object: VoiceChannelPrtl, portal_object: PortalChannelPrtl) => { + return portal_object.user_limit_portal; + }, + set: (voice_channel: VoiceChannel, voice_object: VoiceChannelPrtl, + portal_object: PortalChannelPrtl, guild_object: GuildPrtl, value: number) => { + if (value >= 0) { + portal_object.user_limit_portal = Number(value); + return 1; + } + return -6; + }, + auth: 'portal', + }, +]; + +export function is_attribute(candidate: any): string { + for (let i = 0; i < attributes.length; i++) { + if (String(candidate).substring(1, (String(attributes[i].name).length + 1)) == attributes[i].name) { + return attributes[i].name; + } + } + return ''; +} + +export function get_attribute_help(): MessageEmbed { + const attr_array = []; + for (let i = 0; i < attributes.length; i++) { + attr_array.push({ + emote: attributes[i].name, + role: '**desc**: *' + attributes[i].description + '*' + + '\n**args**: *' + attributes[i].args + '*', + inline: true, + }); + } + return create_rich_embed( + 'Attributes', + 'Prefix: ' + attribute_prefix + '\nimmutable statistics of Portal channel.' + + '\n**!**: *mandatory*, **@**: *optional*', + '#FF5714', + attr_array, + null, + null, + null, + null, + null); +}; + +export function get_attribute_help_super(candidate: string): MessageEmbed | boolean { + for (let i = 0; i < attributes.length; i++) { + const attr = attributes[i]; + if (attr.name === candidate) { + return create_rich_embed( + attr.name, + 'Type: Attribute' + + '\nPrefix: ' + attribute_prefix + + '\n**!**: *mandatory*, **@**: *optional*', + '#FF5714', + [ + { emote: 'Description', role: '*' + attr.super_description + '*', inline: false }, + { emote: 'Arguments', role: '*' + attr.args + '*', inline: false }, + { emote: 'Example', role: '*' + attr.example + '*', inline: false }, + ], + null, + null, + null, + null, + null); + } + } + return false; +}; + +export function get_attribute(voice_channel: VoiceChannel, voice_object: VoiceChannelPrtl, + portal_object: PortalChannelPrtl, guild_object: GuildPrtl, candidate: string): any { + for (let l = 0; l < attributes.length; l++) { + if (candidate === attributes[l].name) { + return attributes[l].get(voice_channel, voice_object, portal_object, guild_object); + } + } + return -1; +}; + +export function set_attribute(voice_channel: VoiceChannel, voice_object: VoiceChannelPrtl, portal_object: PortalChannelPrtl, + guild_object: GuildPrtl, candidate: string, value: any, member: GuildMember): any { + for (let l = 0; l < attributes.length; l++) { + if (candidate === attributes[l].name) { + switch (attributes[l].auth) { + case 'admin': + if (!member.hasPermission('ADMINISTRATOR')) { + return -2; + } + break; + case 'portal': + if (portal_object.creator_id !== member.id) { + return -3; + } + break; + case 'voice': + if (voice_object.creator_id !== member.id) { + return -4; + } + break; + default: + break; + } + + return attributes[l].set(voice_channel, voice_object, portal_object, guild_object, value); + } + } + return -1; +}; \ No newline at end of file diff --git a/src/types/interfaces/Command.ts b/src/types/interfaces/Command.ts new file mode 100644 index 00000000..3df63899 --- /dev/null +++ b/src/types/interfaces/Command.ts @@ -0,0 +1,442 @@ +import { MessageEmbed } from 'discord.js'; +import { create_rich_embed } from '../../libraries/helpOps'; +import { InterfaceBlueprint, Field } from './InterfacesPrtl'; + +export const command_prefix: string = './'; +const commands: InterfaceBlueprint[] = [ + { + name: 'about', + description: 'returns a message with information about Portal Bot.', + super_description: '**about**, returns a message with information about Portal Bot.' + + 'Links for features and premium upgrade path is also given.', + example: './about', + args: 'none', + auth: 'none', + get: null, + set: null + }, + { + name: 'announce', + description: 'makes an announcement via portal bot to the announcement channel or creates a new channel' + + ' if arguments are given.', + super_description: '**announce**, announce makes an announcement via portal bot to the announcement' + + ' channel, ./announce hello im jhon | i want to play games, Here what goes until the "|" is the' + + ' title and the the rest it the body your message.', + example: './announce body | title', + args: '<@title> | <@description>', + auth: 'none', + get: null, + set: null + }, + { + name: 'announcement', + description: 'sets the text channel you wrote the command in as the announcement channel or creates a' + + ' new channel if arguments are given.', + super_description: '**announcement**, sets the text channel you wrote the command in as the announcement' + + 'channel, which means that every time someone times an announcement is displayed there. If channel is' + + ' given as argument, a new channel is created and set as announcements channel.', + example: './announcement announcement_name | announcement_category, ./announcement announcement_name, ./announcement', + args: '<@channel_name> | <@category_name>', + auth: 'admin', + get: null, + set: null + }, + { + name: 'authorize', + description: 'authorize will add a role to the autorized list of roles that can access certain commands.', + super_description: '**authorize**, authorize will add a role to the autorized list of roles that ' + + ' can access certain commands. Selected roles will be granted higher access to more powerful Portal ' + + ' commands that can manipulate the flow of the server.', + example: './deauthorize one_role', + args: '<@role_name>', + auth: 'admin', + get: null, + set: null + }, + { + name: 'authorized_roles', + description: 'authorized_roles will display all the authorization roles that allow user to use portal .', + super_description: '**authorized_roles**, authorized_roles will add a role to the autorized list of roles that ' + + ' can access certain commands. Selected roles will be granted higher access to more powerful Portal ' + + ' commands that can manipulate the flow of the server.', + example: './authorized_roles one_role', + args: '<@role_name>', + auth: 'admin', + get: null, + set: null + }, + { + name: 'deauthorize', + description: 'deauthorize will remove a role to the autorized list of roles that can access certain commands.', + super_description: '**deauthorize**, deauthorize will remove a role to the autorized list of roles that ' + + ' can access certain commands. Selected roles will be stripped of the higher access to more powerful Portal ' + + ' commands that can manipulate the flow of the server.', + example: './deauthorize one_role', + args: '<@role_name>', + auth: 'admin', + get: null, + set: null + }, + { + name: 'delete', + description: 'delete will remove number of messages given.', + super_description: '**delete**, elete will remove number of messages given', + example: './delete 5', + args: '', + auth: 'admin', + get: null, + set: null + }, + { + name: 'corona', + description: 'corona replys with todays latest figures on the novel corona virus.', + super_description: '**corona**, replys with todays latest figures on the novel corona virus. ' + + 'You can give input lower or upper case ex: gr or GR if none is given global stats are displayed.', + example: './corona code, ./corona country, ./corona', + args: '<@country code>, <@country country>', + auth: 'none', + get: null, + set: null + }, + { + name: 'focus', + description: 'focus creates a channel with the people you selected and auto deletes on set time.', + super_description: '**focus**, solves the problem that people have when in a channel with ' + + 'a lot of people, but want to talk to another person and can over the other voices. ' + + 'With focus when both users have requested a focus on a person, they will be automatically moved ' + + 'moved to a new channel where they can speak for the average of the times they requested and when ' + + 'time elapses they will be moved back to the channel they where before focus (2min default time).', + example: './focus user_name', + args: ' | <@time_to_focus>', + auth: 'admin', + get: null, + set: null + }, + { + name: 'force', + description: 'creates a new channel and moves all users to new channel.', + super_description: '**force**, creates a new channel and moves all users to new channel,' + + ' in order to get a new channel name if cooldown is still in effect.', + example: './force', + args: 'none', + auth: 'admin', + get: null, + set: null + }, + { + name: 'help', + description: 'returns a help-list of everything Portal can do.', + super_description: '**help**, a help-list of everything Portal can do.\n You can run' + + './help commands, ./help variables, ./help pipes, ./help attributes, ./help structures, to ' + + 'get only the category you choose.\n You can run ./help specific_property, like portal or set, etc.' + + 'In order to get a more descriptive definition of the property chosen', + example: './help, ./help attr, ./help portal', + args: '@specific_command OR @vrbl/@cmmd/@pipe/@attr', + auth: 'none', + get: null, + set: null + }, + { + name: 'join', + description: 'joins the caller\'s voice channel.', + super_description: '**join**, joins the caller\'s voice channel. Makes announcements about people that' + + ' left and people that joined, and talks loudly every response', + example: './join', + args: 'none', + auth: 'voice', + get: null, + set: null + }, + { + name: 'joke', + description: 'returns a joke.', + super_description: '**joke**, returns a joke. You can specify the category of joke by' + + ' using arguments: dad, chuck, blonde, knock-knock, animal or jod.' + + ' By default it is about you.', + example: './joke', + args: '<@category>', + auth: 'none', + get: null, + set: null + }, + { + name: 'leave', + description: 'leaves the voice channel portal is currently in.', + super_description: '**leave**, leaves the voice channel portal is currently in.', + example: './leave', + args: 'none', + auth: 'none', + get: null, + set: null + }, + { + name: 'leaderboard', + description: 'returns the leaderboard.', + super_description: '**leaderboard**, returns the leaderboard.', + example: './leaderboard 5', + args: '<@number_of_ranks>', + auth: 'none', + get: null, + set: null + }, + { + name: 'level', + description: 'returns your level card.', + super_description: '**level**, returns your level card with all member stats.', + example: './level', + args: 'none', + auth: 'none', + get: null, + set: null + }, + { + name: 'music', + description: 'sets the text channel you wrote the command in as the music channel or creates a new channel' + + ' if arguments are given.', + super_description: '**music**, sets the text channel you wrote the command in as the music channel or' + + ' creates a new channel if arguments are given. In the music channel there is a music player and' + + ' nothing else. Users can request songs write there and play/pause/stop/skip the current song.', + example: './music music_name | music_category, ./music music_name, ./music', + args: '<@channel_name> | <@category_name>', + auth: 'voice', + get: null, + set: null + }, + { + name: 'ping', + description: 'returns round trip latency.', + super_description: '**ping**, returns the latency of portal bot.', + example: './ping', + args: 'none', + auth: 'none', + get: null, + set: null + }, + { + name: 'portal', + description: 'creates a voice channel and a category for it.', + super_description: '**portal**, creates, portal channels. ' + + 'Portal channels are a portal to an infinite amount of voice channels, by entering ' + + 'a voice channel you are redirected to a newly created voice channel that you are ' + + 'the owner of. When everyone leaves the channel will be destroyed.\n', + example: './portal portal_name | portal_category, ./portal portal_name', + args: ' | <@category_name>', + auth: 'admin', + get: null, + set: null + }, + { + name: 'ranks', + description: 'returns your Ranking system of current server.', + super_description: '**ranks**, returns your Ranking system of current server (if one is set).', + example: './ranks', + args: 'none', + auth: 'none', + get: null, + set: null + }, + { + name: 'role_assigner', + description: 'creates a role giving message.', + super_description: '**role_assigner**, creates a message that distributes roles.' + + 'Roles can be given or striped by reacting to the message.\n' + + '(Please make sure you have no space infront or behind *role name* or *emotes*)', + example: 'json\n./role_assigner ' + + '[\n\t{ "give": ":thumbsup:", "strip": ":thumbsdown:", "role_id": "moba" },\n' + + '\t{ "give": ":rofl:", "strip": ":dog:", "role_id": "fps" }\n]\n' + + '\n>will create a message giving/striping moba role with :thumbsup:/:thumbsdown: and fps role with :rofl:/:dog:.', + args: '```json\nJSON array of objects:\n{ "give": ":thumbsup:", "strip": ":thumbsdown:", "role_id": "moba" }```', + auth: 'admin', + get: null, + set: null + }, + { + name: 'roll', + description: 'rolls requested dice.', + super_description: '**roll**, rolls requested dice you can also combine rolls.' + + 'Rolls are following the same philosophy as roll20 does.', + example: './roll 3d12+5', + args: '', + auth: 'none', + get: null, + set: null + }, + { + name: 'run', + description: 'returns the log of data given in log_string.', + super_description: '**run**, gives you the opportunity to run regexes in any text channel. ' + + 'You can get properties about the channel you are in.\n' + + 'If regex is empty string it will return a dot (.)', + example: './run $member_count &locale\nwill return 4 and gr if member count and locale are that', + args: '', + auth: 'admin', + get: null, + set: null + }, + { + name: 'save', + description: 'saves current state of server.', + super_description: '**save**, saves the current state of portal', // should not be spammed + example: './save', + args: 'none', + auth: 'admin', + get: null, + set: null + }, + { + name: 'set', + description: 'sets the value of attribute.', + super_description: '**set**, sets attributes of the current voice channel if you are the owner ' + + 'or the portal channel if you are the owner of that.\n', + example: './set locale gr', + args: ' ', + auth: 'none', + get: null, + set: null + }, + { + name: 'set_ranks', + description: 'creates your ranking system.', + super_description: '**ranks**, creates your ranking system by which roles are distributed by reachig.' + + 'certain levels that have been defined.', + example: 'json\n./set_ranks ' + + '[\n\t{ "level": "2", "role": "Alpha" },\n' + + '\t{ "level": "5", "role": "Beta" }\n]\n', + args: '```json\nJSON array of objects:\n[{ "level": "2", "role": "Alpha" }]```', + auth: 'admin', + get: null, + set: null + }, + { + name: 'setup', + description: 'creates a portal, spotify, url-only and announcement channel automatically.', + super_description: '**setup**, will autogenerate a portal, spotify, url-only and announcement channels ' + + 'at once, removing the hustle of setting up the server.\n', + example: './setup', + args: 'none', + auth: 'admin', + get: null, + set: null + }, + { + name: 'spotify', + description: 'sets the text channel you wrote the command in as the Spotify channel or creates a new channel' + + ' if arguments are given.', + super_description: '**spotify**, sets the text channel you wrote the command in as the Spotify channel, ' + + 'which means that every time someone listens to a song on Spotify it will be displayed. If channel is given as ' + + 'argument, a new channel is created and set as Spotify channel.', + example: './spotify spotify_name | spotify_category, ./spotify spotify_name, ./spotify', + args: '<@channel_name> | <@category_name>', + auth: 'admin', + get: null, + set: null + }, + { + name: 'state', + description: 'returns a visualisation of Portal\'s current state', + super_description: '**state**, returns a visualisation of Portal\'s current state, ' + + 'which means all portal channels with their controlled voice channels spotify, ' + + 'announcement and url channels.', + example: './state', + args: 'none', + auth: 'none', + get: null, + set: null + }, + { + name: 'translate', + description: 'returns given text in translated language', + super_description: '**translate**, returns given text in translated language, ' + + 'will always attempt to translate even if language given does not match from argument.', + example: './translate en,gr | What is the weather like, ./translate gr | What is the weather like', + args: ', | , | ', + auth: 'none', + get: null, + set: null + }, + { + name: 'url', + description: 'sets the text channel you wrote the command in as the url channel or creates a new channel' + + ' if arguments are given.', + super_description: '**url**, sets the text channel you wrote the command in as the url channel, ' + + 'which means that every time someone listens to a song on url it will be displayed. If channel is given as ' + + 'argument, a new channel is created and set as url channel.', + example: './url url_name | url_category, ./url url_name, ./url', + args: '<@channel_name> | <@category_name>', + auth: 'voice', + get: null, + set: null + }, + { + name: 'weather', + description: 'returns current live weather stats for given location', + super_description: '**weather**, returns current live weather stats for given location, ' + + 'location can be specified in detail, but most always be a location.', + example: './weather Athens, Greece, ./weather athens', + args: '', + auth: 'none', + get: null, + set: null + }, + { + name: 'whoami', + description: 'returns information about you', + super_description: '**whoami**, returns information about you.', + example: './whoami', + args: 'none', + auth: 'none', + get: null, + set: null + } +]; + +export function is_command(candidate: string): string { + for (let i = 0; i < commands.length; i++) { + if (String(candidate).substring(1, (String(commands[i].name).length + 1)) == commands[i].name) { return commands[i].name; } + } + return ''; +} + +export function get_command_help(): MessageEmbed { + const func_array: Field[] = []; + for (let i = 0; i < commands.length; i++) { + func_array.push({ + emote: commands[i].name, + role: '**desc**: *' + commands[i].description + '*' + + '\n**args**: *' + commands[i].args + '*', + inline: true, + }); + } + return create_rich_embed( + 'Commands', 'Prefix: ' + command_prefix + '\nCommands to access portal bot.\n**!**: *mandatory*, **@**: *optional*', + '#9775A9', func_array, null, null, null, null, null + ); +}; + +export function get_command_help_super(candidate: string): MessageEmbed | boolean { + for (let i = 0; i < commands.length; i++) { + const cmmd = commands[i]; + if (cmmd.name === candidate) { + return create_rich_embed( + cmmd.name, + 'Type: Command' + + '\nPrefix: ' + command_prefix + + '\n**!**: *mandatory*, **@**: *optional*', + '#9775A9', + [ + { emote: 'Description', role: '*' + cmmd.super_description + '*', inline: false }, + { emote: 'Arguments', role: '*' + cmmd.args + '*', inline: false }, + { emote: 'Example', role: '```' + cmmd.example + '```', inline: false }, + { emote: 'Clearance', role: '' + cmmd.auth + '', inline: false } + ], + null, + null, + true, + null, + null + ); + } + } + return false; +}; + diff --git a/src/types/interfaces/InterfacesPrtl.ts b/src/types/interfaces/InterfacesPrtl.ts new file mode 100644 index 00000000..c2ef3158 --- /dev/null +++ b/src/types/interfaces/InterfacesPrtl.ts @@ -0,0 +1,109 @@ +import { VoiceConnection } from "discord.js"; + +export interface ReturnPormise { + result: boolean; + value: string; +}; + +export interface ReturnPormiseVoice { + result: boolean; + value: string; + voice_connection: VoiceConnection | undefined; +}; + +export class Field { + emote: string | null | undefined | boolean; + role: string | number | null | undefined | boolean; + inline: boolean; + + constructor( + emote: string | null | undefined | boolean, + role: string | number | null | undefined | boolean, + inline: boolean + ) { + this.emote = emote; + this.role = role; + this.inline = inline; + } +} + +export interface Rank { + level: number, + role: string +} + +export interface Language { + gr: any; + en: any; + de: any; +} + +export interface LocalizationOption { + name: string; + lang: Language; +} + +export interface CommandOptions { + name: string; + time: number; + auth: boolean; + premium: boolean; + auto_delete: boolean; +} + +export interface ActiveCooldown { + member: string; + command: string; + timestamp: number; +} + +export interface ActiveCooldowns { + guild: ActiveCooldown[]; + member: ActiveCooldown[]; +} + +export interface TimeElapsed { + timeout_min: number; + timeout_sec: number; + remaining_hrs: number; + remaining_min: number; + remaining_sec: number; +} + +export interface TimeRemaining { + timeout_min: number; + timeout_sec: number; + remaining_min: number; + remaining_sec: number; +} + +export class InterfaceBlueprint { + public name: string = ''; + public description: string = ''; + public super_description: string = ''; + public example: string = ''; + public args: string = ''; + public get!: any; + public set!: any; + public auth!: string; + + constructor( + name: string, + description: string, + super_description: string, + example: string, + args: string, + auth: string, + get: any, + set: any + ) { + this.name = name; + this.description = description; + this.super_description = super_description; + this.example = example; + this.args = args; + this.auth = auth; + this.get = get; + this.set = set; + } +} diff --git a/src/types/interfaces/Pipe.ts b/src/types/interfaces/Pipe.ts new file mode 100644 index 00000000..6e1e69d1 --- /dev/null +++ b/src/types/interfaces/Pipe.ts @@ -0,0 +1,180 @@ +import { MessageEmbed } from 'discord.js'; +import voca from 'voca'; +import { create_rich_embed } from '../../libraries/helpOps'; +import { InterfaceBlueprint } from './InterfacesPrtl'; + +export const pipe_prefix: string = '|'; +const pipes: InterfaceBlueprint[] = [ + { + name: 'camelCase', + description: 'returns an camelCase of the input', + super_description: '**camelCase**, connects words and makes the first character upper-case.', + example: '(variable, string)|camelCase', + args: 'none', + get: (str: string) => { return voca.camelCase(str); }, + set: null, + auth: 'none' + }, + { + name: 'capitalize', + description: 'returns an capitalize of the input', + super_description: '**capitalize**, makes the first character upper-case.', + example: '(variable, string)|capitalize', + args: 'none', + get: (str: string) => { return voca.capitalize(str); }, + set: null, + auth: 'none' + }, + { + name: 'decapitalize', + description: 'returns an decapitalize of the input', + super_description: '**decapitalize**, makes the first character lower-case.', + example: '(variable, string)|decapitalize', + args: 'none', + get: (str: string) => { return voca.decapitalize(str); }, + set: null, + auth: 'none' + }, + { + name: 'lowerCase', + description: 'returns an lowerCase of the input', + super_description: '**lowerCase**, makes all characters lower-case.', + example: '(variable, string)|lowerCase', + args: 'none', + get: (str: string) => { return voca.lowerCase(str); }, + set: null, + auth: 'none' + }, + { + name: 'upperCase', + description: 'returns an upperCase of the input', + super_description: '**upperCase**, makes all characters upper-case.', + example: '(variable, string)|upperCase', + args: 'none', + get: (str: string) => { return voca.upperCase(str); }, + set: null, + auth: 'none' + }, + { + name: 'populous', + description: 'returns the name of the most common element in list', + super_description: '**populous**, returns the name of the most common element in list.', + example: '(array)|populous', + args: 'none', + get: () => { return 'not yet implemented'; }, + set: null, + auth: 'none' + }, + { + name: 'populous_count', + description: 'returns the count of most common element in list', + super_description: '**populous_count**, returns the count of most common element in list.', + example: '(array)|populous_count', + args: 'none', + get: () => { return 'not yet implemented'; }, + set: null, + auth: 'none' + }, + { + name: 'snakeCase', + description: 'returns an snakeCase of the input', + super_description: '**snakeCase**, connects all words with \'_\', like a snake.', + example: '(variable, string)|snakeCase', + args: 'none', + get: (str: string) => { return voca.snakeCase(str); }, + set: null, + auth: 'none' + }, + { + name: 'souvlakiCase', + description: 'returns an souvlakiCase of the input', + super_description: '**souvlakiCase**, connects all words with \'-\', like a greek souvlaki.', + example: '(variable, string)|souvlakiCase', + args: 'none', + get: (str: string) => { return voca.kebabCase(str); }, + set: null, + auth: 'none' + }, + { + name: 'summary_count', + description: 'returns the count of members having a status', + super_description: '**summary_count**, returns the count of members having a status', + example: '(array)|summary_count', + args: 'none', + get: (str: string) => { return voca.words(str).length; }, + set: null, + auth: 'none' + }, + { + name: 'titleCase', + description: 'returns an titleCase of the input', + super_description: '**titleCase**, makes every words first character upper-case.', + example: '(variable, string)|titleCase', + args: 'none', + get: (str: string) => { return voca.titleCase(str); }, + set: null, + auth: 'none' + }, +]; + +export function is_pipe(candidate: string): string { + for (let i = 0; i < pipes.length; i++) { + if (String(candidate).substring(1, (String(pipes[i].name).length + 1)) == pipes[i].name) { return pipes[i].name; } + } + return ''; +}; + +export function get_pipe_help(): MessageEmbed { + const pipe_array = []; + for (let i = 0; i < pipes.length; i++) { + pipe_array.push({ + emote: pipes[i].name, + role: '**desc**: *' + pipes[i].description + '*' + + '\n**args**: *' + pipes[i].args + '*', + inline: true, + }); + } + return create_rich_embed('Pipes', + 'Prefix: ' + pipe_prefix + '\nData manipulating pipes.' + + '\n**!**: *mandatory*, **@**: *optional*', + '#6EEB83', pipe_array, + null, + null, + null, + null, + null); +}; + +export function get_pipe_help_super(candidate: string): MessageEmbed | boolean { + for (let i = 0; i < pipes.length; i++) { + const pipe = pipes[i]; + if (pipe.name === candidate) { + return create_rich_embed( + pipe.name, + 'Type: Pipe' + + '\nPrefix: ' + pipe_prefix + + '\n**!**: *mandatory*, **@**: *optional*', + '#6EEB83', + [ + { emote: 'Description', role: '*' + pipe.super_description + '*', inline: false }, + { emote: 'Arguments', role: '*' + pipe.args + '*', inline: false }, + { emote: 'Example', role: '*' + pipe.example + '*', inline: false } + ], + null, + null, + null, + null, + null); + } + } + return false; +}; + +export function get_pipe(str: string, pipe: string) { + for (let l = 0; l < pipes.length; l++) { + if (pipe === pipes[l].name) { + return pipes[l].get(str); + } + } + return -1; +}; diff --git a/src/types/interfaces/Structure.ts b/src/types/interfaces/Structure.ts new file mode 100644 index 00000000..9aae820a --- /dev/null +++ b/src/types/interfaces/Structure.ts @@ -0,0 +1,80 @@ +import { MessageEmbed } from 'discord.js'; +import { create_rich_embed } from '../../libraries/helpOps'; +import { InterfaceBlueprint } from './InterfacesPrtl'; + +export const structure_prefix: string = '{{'; +const structures: InterfaceBlueprint[] = [ + { + name: 'if', + description: 'if statement with two outcomes: ```json\n{{\n\t"if": "John", "is": "===", "with": "John",\n\t' + + '"yes": "same name", "no": "not the same name"\n}}```', + super_description: '**if**, gets two arguments, an operator and two outcomes and returns ' + + 'outcome a if statement is true and second if not.\n' + + 'example: ./run ```json\n{{\n\t"if": "John", "is": "===", "with": "John",\n\t' + + '"yes": "same name", "no": "not the same name"\n}}```\n will return *same name* as ' + + 'it is the same name.\nOperator is can take values: ==, ===, !=, !==, >, <, >=, <=.\n' + + '> You can read the statement as: if John is equal with John ? yes, same name or no, not same name.\n' + + '> You cannot encapsulate if statements.', + example: '{{\n\t"if": "John", "is": "===", "with": "John",\n\t' + + '"yes": "same name", "no": "not the same name"\n}}', + args: 'JSON with: if, is, with, yes, no', + get: null, + set: null, + auth: 'none' + } +]; + +export function is_structure(candidate: string): string { + for (let i = 0; i < structures.length; i++) { + if (String(candidate).substring(1, (String(structures[i].name).length + 1)) == structures[i].name) { + return structures[i].name; + } + } + return ''; +}; + +export function get_structure_help(): MessageEmbed { + const strc_array = []; + for (let i = 0; i < structures.length; i++) { + strc_array.push({ + emote: structures[i].name, + role: '**desc**: *' + structures[i].description + '*' + + '\n**args**: *' + structures[i].args + '*', + inline: true, + }); + } + return create_rich_embed('Structures', + 'Prefix: ' + structure_prefix + '\nStructural functionality.' + + '\n**!**: *mandatory*, **@**: *optional*', + '#EEB902', strc_array, + null, + null, + null, + null, + null); +}; + +export function get_structure_help_super(candidate: string): MessageEmbed | boolean { + for (let i = 0; i < structures.length; i++) { + const strc = structures[i]; + if (strc.name === candidate) { + return create_rich_embed( + strc.name, + 'Type: Structure' + + '\nPrefix: ' + structure_prefix + + '\n**!**: *mandatory*, **@**: *optional*', + '#EEB902', + [ + { emote: 'Description', role: '*' + strc.super_description + '*', inline: false }, + { emote: 'Arguments', role: '*' + strc.args + '*', inline: false }, + { emote: 'Example', role: '*' + strc.example + '*', inline: false }, + ], + null, + null, + null, + null, + null); + } + } + return false; +}; diff --git a/src/types/interfaces/Variable.ts b/src/types/interfaces/Variable.ts new file mode 100644 index 00000000..92da51e3 --- /dev/null +++ b/src/types/interfaces/Variable.ts @@ -0,0 +1,401 @@ +import moment from 'moment'; + +import { get_status_list } from '../../libraries/statusOps'; +import { create_rich_embed } from '../../libraries/helpOps'; +import { InterfaceBlueprint } from './InterfacesPrtl'; +import { Guild, GuildMember, MessageEmbed, VoiceChannel } from 'discord.js'; +import { VoiceChannelPrtl } from '../classes/VoiceChannelPrtl'; +import { PortalChannelPrtl } from '../classes/PortalChannelPrtl'; + +export const variable_prefix: string = '$'; +const variables: InterfaceBlueprint[] = [ + { + name: '#', + description: 'returns the channel number in list.', + super_description: '**#**, returns the channel number in list, if it was created first .' + + 'it will display 1, if third 3, etc.', + example: '$#', + args: 'none', + get: (voice_channel: VoiceChannel, voice_object: VoiceChannelPrtl, portal_object: PortalChannelPrtl[]) => { + const portal_of_voice = portal_object.find(portal => + portal.voice_list.some(voice => + voice.id === voice_object.id)); + if (portal_of_voice !== undefined) { + let i = 0; + portal_of_voice.voice_list.some(voice => { + i++; + voice.id === voice_object.id + }); + return '' + i; + } + return '-'; + }, + set: null, + auth: 'none' + }, + { + name: '##', + description: 'returns the channel number in list with # in the front.', + super_description: '**##**, returns the channel number in list with # ' + + 'in the front, if it was created first ' + + 'it will display #1, if third #3, etc.', + example: '$##', + args: 'none', + get: (voice_channel: VoiceChannel, voice_object: VoiceChannelPrtl, portal_object: PortalChannelPrtl[]) => { + const portal_of_voice = portal_object.find(portal => + portal.voice_list.some(voice => + voice.id === voice_object.id)); + if (portal_of_voice !== undefined) { + let i = 0; + portal_of_voice.voice_list.some(voice => { + i++; + voice.id === voice_object.id + }); + return '#' + i; + } + return '#-'; + }, + set: null, + auth: 'none' + }, + { + name: 'creator_portal', + description: 'returns the creator of current voice channel\'s portal.', + super_description: '**creator_portal**, returns the creator of current voice channel\'s portal.', + example: '$creator_portal', + args: 'none', + get: (voice_channel: VoiceChannel, voice_object: VoiceChannelPrtl, portal_object: PortalChannelPrtl[], guild_object: any, guild: Guild) => { + const portal_of_voice = portal_object.find(portal => + portal.voice_list.some(voice => + voice.id === voice_object.id)); + if (portal_of_voice !== undefined) { + return '' + portal_of_voice.creator_id; + } + return '?'; + }, + set: null, + auth: 'none' + }, + { + name: 'creator_voice', + description: 'returns the creator of current voice channel.', + super_description: '**creator_voice**, returns the creator of current voice channel.', + example: '$creator_voice', + args: 'none', + get: (voice_channel: VoiceChannel, voice_object: VoiceChannelPrtl, portal_object: PortalChannelPrtl[], guild_object: any, guild: Guild) => { + return voice_object.creator_id; + }, + set: null, + auth: 'none' + }, + { + name: 'date', + description: 'returns the full date: dd/mm/yyyy.', + super_description: '**date**, full date: dd/mm/yyyy.', + example: '$date', + args: 'none', + get: (voice_channel: VoiceChannel, voice_object: VoiceChannelPrtl) => { + return moment().locale(voice_object.locale).subtract(10, 'days').calendar(); + }, + set: null, + auth: 'none' + }, + { + name: 'day_number', + description: 'returns the day number.', + super_description: '**day_number**, returns the day number.', + example: '$day_number', + args: 'none', + get: (voice_channel: VoiceChannel, voice_object: VoiceChannelPrtl) => { + return moment().locale(voice_object.locale).date(); + }, + set: null, + auth: 'none' + }, + { + name: 'day_name', + description: 'returns the day name.', + super_description: '**day_name**, returns the day name.', + example: '$day_name', + args: 'none', + get: (voice_channel: VoiceChannel, voice_object: VoiceChannelPrtl) => { + return moment().locale(voice_object.locale).format('dddd'); + }, + set: null, + auth: 'none' + }, + { + name: 'month_number', + description: 'returns the month by number.', + super_description: '**month_number**, returns the month by number.', + example: '$month_number', + args: 'none', + get: (voice_channel: VoiceChannel, voice_object: VoiceChannelPrtl) => { + return moment().locale(voice_object.locale).format('M'); + }, + set: null, + auth: 'none' + }, + { + name: 'month_name', + description: 'returns the month by name.', + super_description: '**month_name**, returns the month by name.', + example: '$month_name', + args: 'none', + get: (voice_channel: VoiceChannel, voice_object: VoiceChannelPrtl) => { + return moment().locale(voice_object.locale) + .startOf('month').format('MMMM'); + }, + set: null, + auth: 'none' + }, + { + name: 'year', + description: 'returns the year.', + super_description: '**year**, returns the year.', + example: '$year', + args: 'none', + get: (voice_channel: VoiceChannel, voice_object: VoiceChannelPrtl) => { + return moment().locale(voice_object.locale).format('yyyy'); + }, + set: null, + auth: 'none' + }, + { + name: 'time', + description: 'full time: hh/mm/ss.', + super_description: '**time**, full time: hh/mm/ss.', + example: '$time', + args: 'none', + get: (voice_channel: VoiceChannel, voice_object: VoiceChannelPrtl) => { + return moment().locale(voice_object.locale).format('h:mm:ss'); + }, + set: null, + auth: 'none' + }, + { + name: 'hour', + description: 'returns the hour in current time.', + super_description: '**hour**, returns the hour.', + example: '$hour', + args: 'none', + get: (voice_channel: VoiceChannel, voice_object: VoiceChannelPrtl) => { + return moment().locale(voice_object.locale).format('h'); + }, + set: null, + auth: 'none' + }, + { + name: 'minute', + description: 'returns the minute in current time.', + super_description: '**minute**, returns the minute.', + example: '$minute', + args: 'none', + get: (voice_channel: VoiceChannel, voice_object: VoiceChannelPrtl) => { + return moment().locale(voice_object.locale).format('mm'); + }, + set: null, + auth: 'none' + }, + { + name: 'second', + description: 'returns the second in current time.', + super_description: '**second**, returns the second.', + example: '$second', + args: 'none', + get: (voice_channel: VoiceChannel, voice_object: VoiceChannelPrtl) => { + return moment().locale(voice_object.locale).format('ss'); + }, + set: null, + auth: 'none' + }, + { + name: 'member_active_count', + description: 'returns number of members with a status.', + super_description: '**member_with_status**, returns the number of members with a status.', + example: '$member_active_count', + args: 'none', + get: (voice_channel: VoiceChannel) => { + let cnt = 0; + voice_channel.members.forEach((member) => { + if (member.presence.activities !== null && !member.user.bot) { cnt++; } + }); + return cnt; + }, + set: null, + auth: 'none' + }, + { + name: 'member_count', + description: 'returns number of members in channel.', + super_description: '**member_count**, returns the number of members in channel.', + example: '$member_count', + args: 'none', + get: (voice_channel: VoiceChannel) => { + let cnt = 0; + voice_channel.members.forEach((member) => { + if (!member.user.bot) { cnt++; } + }); + return cnt; + }, + set: null, + auth: 'none' + }, + { + name: 'member_history', + description: 'returns a list of all members that have connected to the channel.', + super_description: '**member_history**, returns a list of all members that have connected to the channel.', + example: '$member_history', + args: 'none', + get: () => { + return 'no_yet_implemented'; + }, + set: null, + auth: 'none' + }, + { + name: 'member_list', + description: 'returns the currently played games.', + super_description: '**member_list**, returns the currentstatuses.', + example: '$member_list', + args: 'none', + get: (voice_channel: VoiceChannel) => { + const mmbr_lst: string[] = []; + voice_channel.members.forEach(member => { mmbr_lst.push(member.displayName); }); + return mmbr_lst; + }, + set: null, + auth: 'none' + }, + { + name: 'member_with_status', + description: 'returns number of members with a status.', + super_description: '**member_with_status**, returns the number of members with a status.', + example: '$member_with_status', + args: 'none', + get: (voice_channel: VoiceChannel) => { + let cnt = 0; + voice_channel.members.forEach((member) => { + if (member.presence.activities !== null) { cnt++; } + }); + return cnt; + }, + set: null, + auth: 'none' + }, + { + name: 'status_count', + description: 'returns the count of current member statuses.', + super_description: '**status_count**, returns the count of current member statuses.', + example: '$status_count', + args: 'none', + get: (voice_channel: VoiceChannel, voice_object: VoiceChannelPrtl) => { + const status_list: string[] = get_status_list(voice_channel, voice_object); + return status_list.length; + }, + set: null, + auth: 'none' + }, + { + name: 'status_history', + description: 'returns the history of all the statuses.', + super_description: '**status_history**, returns the history of all the statuses.', + example: '$status_history', + args: 'none', + get: () => { + return 'no_yet_implemented'; + }, + set: null, + auth: 'none' + }, + { + name: 'status_list', + description: 'returns the list of current member statuses.', + super_description: '**status_list**, returns the list of all current members statuses.', + example: '$status_list', + args: 'none', + get: (voice_channel: VoiceChannel, voice_object: VoiceChannelPrtl) => { + return get_status_list(voice_channel, voice_object); + }, + set: null, + auth: 'none' + }, + // { + // name: 'last_update', + // description: 'is the last time the channel name was updated', + // super_description: '**last_update**, is the last time the channel name was updated', + // example: '$last_update', + // args: 'none', + // get: (voice_channel: VoiceChannel, voice_object: VoiceChannelPrtl) => { + // return `${Math.round(((Date.now() - voice_object.last_update) / 1000 / 60))}m` + + // `${Math.round(((Date.now() - voice_object.last_update) / 1000) % 60)}s`; + // }, + // set: null, + // auth: 'none' + // } +]; + +export function is_variable(candidate: string): string { + for (let i = 0; i < variables.length; i++) { + if (String(candidate).substring(1, (String(variables[i].name).length + 1)) == variables[i].name) { + return variables[i].name; + } + } + return ''; +}; + +export function get_variable_help(): MessageEmbed { + const vrbl_array = []; + for (let i = 0; i < variables.length; i++) { + vrbl_array.push({ + emote: variables[i].name, + role: '**desc**: *' + variables[i].description + '*' + + '\n**args**: *' + variables[i].args + '*', + inline: true, + }); + } + return create_rich_embed('Variables', + 'Prefix: ' + variable_prefix + '\nEditable variables of Portal channel.' + + '\n**!**: *mandatory*, **@**: *optional*', + '#1BE7FF', vrbl_array, + null, + null, + null, + null, + null); +}; + +export function get_variable_help_super(candidate: string): MessageEmbed | boolean { + for (let i = 0; i < variables.length; i++) { + const vrbl = variables[i]; + if (vrbl.name === candidate) { + return create_rich_embed( + vrbl.name, + 'Type: Variable' + + '\nPrefix: ' + variable_prefix + + '\n**!**: *mandatory*, **@**: *optional*', + '#1BE7FF', + [ + { emote: 'Description', role: '*' + vrbl.super_description + '*', inline: false }, + { emote: 'Arguments', role: '*' + vrbl.args + '*', inline: false }, + { emote: 'Example', role: '```' + vrbl.example + '```', inline: false } + ], + null, + null, + null, + null, + null); + } + } + return false; +}; + +export function get_variable(voice_channel: VoiceChannel, voice_object: VoiceChannelPrtl, + portal_object: PortalChannelPrtl[], guild_object: any, guild: Guild, vrbl: string): any { + for (let l = 0; l < variables.length; l++) { + if (vrbl === variables[l].name) { + return variables[l].get(voice_channel, voice_object, portal_object, guild_object, guild); + } + } + return -1; +}; diff --git a/tests/commands/roll.test.js b/tests/commands/roll.test.js index e6c1e611..145c7763 100644 --- a/tests/commands/roll.test.js +++ b/tests/commands/roll.test.js @@ -1,22 +1,22 @@ -const roll = require('../../src/commands/roll.js'); +const roll = require('../../build/commands/roll.js'); test('1d6 must return a number between 1 and 6', () => { - roll(null, null, ['1d6']).then(result => { - expect(parseInt(result.value.substr(0, 1))).toBeGreaterThanOrEqual(1); - expect(parseInt(result.value.substr(0, 1))).toBeLessThan(7); - }); + roll(null, null, ['1d6']).then(result => { + expect(parseInt(result.value.substr(0, 1))).toBeGreaterThanOrEqual(1); + expect(parseInt(result.value.substr(0, 1))).toBeLessThan(7); + }); }); test('3d2+3 must return a number between 6 and 9', () => { - roll(null, null, ['3d2+3']).then(result => { - expect(parseInt(result.value.substr(0, 1))).toBeGreaterThanOrEqual(6); - expect(parseInt(result.value.substr(0, 1))).toBeLessThan(10); - }); + roll(null, null, ['3d2+3']).then(result => { + expect(parseInt(result.value.substr(0, 1))).toBeGreaterThanOrEqual(6); + expect(parseInt(result.value.substr(0, 1))).toBeLessThan(10); + }); }); test('1d50+1d20 must return a number between 2 and 70', () => { - roll(null, null, ['1d50+1d20']).then(result => { - expect(parseInt(result.value.substr(0, 2))).toBeGreaterThanOrEqual(2); - expect(parseInt(result.value.substr(0, 2))).toBeLessThan(71); - }); -}); + roll(null, null, ['1d50+1d20']).then(result => { + expect(parseInt(result.value.substr(0, 2))).toBeGreaterThanOrEqual(2); + expect(parseInt(result.value.substr(0, 2))).toBeLessThan(71); + }); +}); \ No newline at end of file diff --git a/tests/moderation/profanity.test.js b/tests/moderation/profanity.test.js index b18c5f2b..280d674f 100644 --- a/tests/moderation/profanity.test.js +++ b/tests/moderation/profanity.test.js @@ -1,25 +1,25 @@ -const profanity = require('../../src/moderation/profanity.js'); +const modOps = require('../../build/libraries/modOps'); test('fuck must return true', () => { - expect(profanity('fuck')).toBe(true); + expect(modOps.isProfane('fuck')).toBe(true); }); test('sample must return true', () => { - expect(profanity('sample')).toBe(false); + expect(modOps.isProfane('sample')).toBe(false); }); test('fuckshit must return true', () => { - expect(profanity('fuckshit')).toBe(true); + expect(modOps.isProfane('fuckshit')).toBe(true); }); test('πούτσα must return true', () => { - expect(profanity('πούτσα')).toBe(true); + expect(modOps.isProfane('πούτσα')).toBe(true); }); test('καλημέρα must return true', () => { - expect(profanity('καλημέρα')).toBe(false); + expect(modOps.isProfane('καλημέρα')).toBe(false); }); test('πουτσομπανάνα must return true', () => { - expect(profanity('πουτσομπανάνα')).toBe(true); + expect(modOps.isProfane('πουτσομπανάνα')).toBe(true); }); \ No newline at end of file diff --git a/tests/portal.test.js b/tests/portal.test.js index e3a263a5..e16904b0 100644 --- a/tests/portal.test.js +++ b/tests/portal.test.js @@ -2,11 +2,11 @@ // const { client, log_portal } = require('../src/portal'); test("discord.js mock test", () => { - // const message = new MockMessage(); - // const channel = new MockTextChannel(); - // message.content = "test"; - // message.channel = channel; - // callMyFunctionToTestHere(message); + // const message = new MockMessage(); + // const channel = new MockTextChannel(); + // message.content = "test"; + // message.channel = channel; + // callMyFunctionToTestHere(message); - expect(true).toBe(true); -}); + expect(true).toBe(true); +}); \ No newline at end of file diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 00000000..b586dfb1 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,17 @@ +{ + "compilerOptions": { + "target": "es2020", + "module": "commonjs", + "jsx": "preserve", + "lib": ["es2020"], + "allowJs": true, + "outDir": "build", + "rootDir": "src", + "strict": true, + "noImplicitAny": true, + "esModuleInterop": true, + "resolveJsonModule": true + }, + "include": ["src/**/*"], + "exclude": ["node_modules", "**/*.spec.ts", "**/*.spec.js", "**/*.test.ts", "**/*.test.js"] +} \ No newline at end of file