squacker.js 1.0.4
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of squacker.js might be problematic. Click here for more details.
- package/activityTypes.js +10 -0
- package/events.js +7 -0
- package/index.js +31 -0
- package/package.js +320 -0
- package/package.json +16 -0
- package/readme.md +159 -0
package/activityTypes.js
ADDED
package/events.js
ADDED
package/index.js
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
const client = require('./package.js'); // or require('squacker.js')
|
2
|
+
|
3
|
+
|
4
|
+
client.on('READY', ()=>{
|
5
|
+
console.log('Bot is online!')
|
6
|
+
})
|
7
|
+
|
8
|
+
client.on('INTERACTION_CREATE', (interaction)=>{
|
9
|
+
// console.log('Interaction!^2')
|
10
|
+
if(interaction.data.name == 'help'){
|
11
|
+
new client.INTERACTION(interaction).repy('Help Message!', [], [])
|
12
|
+
}else if(interaction.data.name == 't'){
|
13
|
+
new client.INTERACTION(interaction).repy('oohh yeah! you said.. ' + interaction.data.options[0].value, [], [])
|
14
|
+
}
|
15
|
+
})
|
16
|
+
|
17
|
+
|
18
|
+
client.on('MESSAGE_CREATE', (msg)=>{
|
19
|
+
if(msg.content == 'ping'){
|
20
|
+
let ping = new client.MESSAGE(msg)
|
21
|
+
ping.reply('pong')
|
22
|
+
ping.channel.send('pong')
|
23
|
+
console.log('pong')
|
24
|
+
}
|
25
|
+
})
|
26
|
+
|
27
|
+
|
28
|
+
client.login('TOKEN', 513, {
|
29
|
+
name: "Froggy",
|
30
|
+
type: client.activityTypes["Playing"],
|
31
|
+
});
|
package/package.js
ADDED
@@ -0,0 +1,320 @@
|
|
1
|
+
// require('dotenv').config()
|
2
|
+
const WebSocket = require('ws');
|
3
|
+
const ws = new WebSocket('wss://gateway.discord.gg/?v=9&encoding=json')
|
4
|
+
// const fetch = require('node-fetch')
|
5
|
+
const fetchPromise = import('node-fetch').then(mod => mod.default)
|
6
|
+
const fetch = (...args) => fetchPromise.then(fetch => fetch(...args))
|
7
|
+
let interval = 0;
|
8
|
+
|
9
|
+
|
10
|
+
|
11
|
+
ws.addEventListener('message', function(event) {
|
12
|
+
const payload = event.data
|
13
|
+
// console.log(JSON.parse(payload.toString()))
|
14
|
+
})
|
15
|
+
|
16
|
+
ws.on('message', function incoming(data) {
|
17
|
+
let payload = JSON.parse(data)
|
18
|
+
const { t, event, op, d } = payload;
|
19
|
+
|
20
|
+
switch (op) {
|
21
|
+
case 10:
|
22
|
+
const { heartbeat_interval } = d;
|
23
|
+
interval = heartbeat(heartbeat_interval)
|
24
|
+
break;
|
25
|
+
}
|
26
|
+
// console.log(t)
|
27
|
+
|
28
|
+
if(t == "ready"){
|
29
|
+
pkg.READY()
|
30
|
+
}else if(t == "MESSAGE_CREATE"){
|
31
|
+
pkg.MESSAGE_CREATE(d)
|
32
|
+
}else if( t == "INTERACTION_CREATE"){
|
33
|
+
// https://discord.com/api/v9/interactions/${d.id}/${d.token}/callback
|
34
|
+
let URL = `https://discord.com/api/v9/interactions/${d.id}/${d.token}/callback`;
|
35
|
+
pkg["INTERACTION_CREATE"](d)
|
36
|
+
}else if(typeof(t) == "string"){
|
37
|
+
pkg[t](d)
|
38
|
+
}
|
39
|
+
|
40
|
+
|
41
|
+
|
42
|
+
})
|
43
|
+
|
44
|
+
const heartbeat = (ms) => {
|
45
|
+
return setInterval(() => {
|
46
|
+
ws.send(JSON.stringify({op: 2, d: null}))
|
47
|
+
}, ms)
|
48
|
+
}
|
49
|
+
|
50
|
+
let pkg = {
|
51
|
+
login: (token, intents, activity)=>{ ws.on('open', function open(data) {
|
52
|
+
pkg.token = token
|
53
|
+
ws.send(JSON.stringify({
|
54
|
+
op: 2,
|
55
|
+
d: {
|
56
|
+
token: token,
|
57
|
+
intents: intents,
|
58
|
+
properties: {
|
59
|
+
$os: 'win',
|
60
|
+
$browser: 'squacker',
|
61
|
+
$device: 'squacker'
|
62
|
+
},
|
63
|
+
presence: {
|
64
|
+
activities: [activity],
|
65
|
+
status: "online",
|
66
|
+
since: 0,
|
67
|
+
afk: false
|
68
|
+
},
|
69
|
+
}
|
70
|
+
}))
|
71
|
+
})
|
72
|
+
},
|
73
|
+
["INTERACTION_CREATE"]: (d)=>{
|
74
|
+
console.log('INTERACTION_CREATE')
|
75
|
+
},
|
76
|
+
["MESSAGE_CREATE"]: (d)=>{
|
77
|
+
console.log('MESSAGE_CREATE')
|
78
|
+
},
|
79
|
+
["READY"]: (d)=>{
|
80
|
+
console.log('READY')
|
81
|
+
},
|
82
|
+
['CHANNEL_CREATE']: (d)=>{
|
83
|
+
console.log('CHANNEL_CREATE')
|
84
|
+
},
|
85
|
+
['CHANNEL_UPDATE']: (d)=>{
|
86
|
+
console.log('CHANNEL_UPDATE')
|
87
|
+
},
|
88
|
+
['CHANNEL_DELETE']: (d)=>{
|
89
|
+
console.log('CHANNEL_DELETE')
|
90
|
+
},
|
91
|
+
['CHANNEL_PINS_UPDATE']: (d)=>{
|
92
|
+
console.log('CHANNEL_PINS_UPDATE')
|
93
|
+
},
|
94
|
+
["GUILD_CREATE"]: (d)=>{
|
95
|
+
console.log('GUILD_CREATE')
|
96
|
+
},
|
97
|
+
["GUILD_MEMBER_ADD"]: (d)=>{
|
98
|
+
console.log('GUILD_MEMBER_ADD')
|
99
|
+
},
|
100
|
+
["GUILD_MEMBER_REMOVE"]: (d)=>{
|
101
|
+
console.log('GUILD_MEMBER_REMOVE')
|
102
|
+
},
|
103
|
+
["GUILD_MEMBER_UPDATE"]: (d)=>{
|
104
|
+
console.log('GUILD_MEMBER_UPDATE')
|
105
|
+
},
|
106
|
+
["GUILD_MEMBERS_CHUNK"]: (d)=>{
|
107
|
+
console.log('GUILD_MEMBERS_CHUNK')
|
108
|
+
},
|
109
|
+
["GUILD_UPDATE"]: (d)=>{
|
110
|
+
console.log('GUILD_UPDATE')
|
111
|
+
},
|
112
|
+
["GUILD_DELETE"]: (d)=>{
|
113
|
+
console.log('GUILD_DELETE')
|
114
|
+
},
|
115
|
+
["GUILD_BAN_ADD"]: (d)=>{
|
116
|
+
console.log('GUILD_BAN_ADD')
|
117
|
+
},
|
118
|
+
["GUILD_BAN_REMOVE"]: (d)=>{
|
119
|
+
console.log('GUILD_BAN_REMOVE')
|
120
|
+
},
|
121
|
+
["GUILD_EMOJIS_UPDATE"]: (d)=>{
|
122
|
+
console.log('GUILD_EMOJIS_UPDATE')
|
123
|
+
},
|
124
|
+
["GUILD_INTEGRATIONS_UPDATE"]: (d)=>{
|
125
|
+
console.log('GUILD_INTEGRATIONS_UPDATE')
|
126
|
+
},
|
127
|
+
["GUILD_ROLE_CREATE"]: (d)=>{
|
128
|
+
console.log('GUILD_ROLE_CREATE')
|
129
|
+
},
|
130
|
+
["GUILD_ROLE_UPDATE"]: (d)=>{
|
131
|
+
console.log('GUILD_ROLE_UPDATE')
|
132
|
+
},
|
133
|
+
["GUILD_ROLE_DELETE"]: (d)=>{
|
134
|
+
console.log('GUILD_ROLE_DELETE')
|
135
|
+
},
|
136
|
+
["GUILD_SYNC"]: (d)=>{
|
137
|
+
console.log('GUILD_SYNC')
|
138
|
+
},
|
139
|
+
["GUILD_MEMBERS_CHUNK"]: (d)=>{
|
140
|
+
console.log('GUILD_MEMBERS_CHUNK')
|
141
|
+
},
|
142
|
+
["GUILD_MESSAGE_DELETE"]: (d)=>{
|
143
|
+
console.log('GUILD_MESSAGE_DELETE')
|
144
|
+
},
|
145
|
+
["GUILD_MESSAGE_BULK_DELETE"]: (d)=>{
|
146
|
+
console.log('GUILD_MESSAGE_BULK_DELETE')
|
147
|
+
},
|
148
|
+
["GUILD_MESSAGE_UPDATE"]: (d)=>{
|
149
|
+
console.log('GUILD_MESSAGE_UPDATE')
|
150
|
+
},
|
151
|
+
["GUILD_MESSAGE_DELETE_BULK"]: (d)=>{
|
152
|
+
console.log('GUILD_MESSAGE_DELETE_BULK')
|
153
|
+
},
|
154
|
+
["GUILD_MESSAGE_REACTION_ADD"]: (d)=>{
|
155
|
+
console.log('GUILD_MESSAGE_REACTION_ADD')
|
156
|
+
},
|
157
|
+
["GUILD_MESSAGE_REACTION_REMOVE"]: (d)=>{
|
158
|
+
console.log('GUILD_MESSAGE_REACTION_REMOVE')
|
159
|
+
},
|
160
|
+
["GUILD_MESSAGE_REACTION_REMOVE_ALL"]: (d)=>{
|
161
|
+
console.log('GUILD_MESSAGE_REACTION_REMOVE_ALL')
|
162
|
+
},
|
163
|
+
["GUILD_MESSAGE_REACTION_REMOVE_EMOJI"]: (d)=>{
|
164
|
+
console.log('GUILD_MESSAGE_REACTION_REMOVE_EMOJI')
|
165
|
+
},
|
166
|
+
["GUILD_INTEGRATIONS_UPDATE"]: (d)=>{
|
167
|
+
console.log('GUILD_INTEGRATIONS_UPDATE')
|
168
|
+
},
|
169
|
+
["GUILD_WEBHOOKS_UPDATE"]: (d)=>{
|
170
|
+
console.log('GUILD_WEBHOOKS_UPDATE')
|
171
|
+
},
|
172
|
+
["GUILD_INVITE_CREATE"]: (d)=>{
|
173
|
+
console.log('GUILD_INVITE_CREATE')
|
174
|
+
},
|
175
|
+
["GUILD_INVITE_DELETE"]: (d)=>{
|
176
|
+
console.log('GUILD_INVITE_DELETE')
|
177
|
+
},
|
178
|
+
["GUILD_BAN_ADD"]: (d)=>{
|
179
|
+
console.log('GUILD_BAN_ADD')
|
180
|
+
},
|
181
|
+
["GUILD_BAN_REMOVE"]: (d)=>{
|
182
|
+
console.log('GUILD_BAN_REMOVE')
|
183
|
+
},
|
184
|
+
["GUILD_EMOJIS_UPDATE"]: (d)=>{
|
185
|
+
console.log('GUILD_EMOJIS_UPDATE')
|
186
|
+
},
|
187
|
+
INTERACTION: class {
|
188
|
+
constructor(d) {
|
189
|
+
this.data = d
|
190
|
+
}
|
191
|
+
repy(reply, embeds, components) {
|
192
|
+
// https://discord.com/api/v9/interactions/${this.data.id}/${this.data.token}/callback
|
193
|
+
const fetch_arguments = {
|
194
|
+
method: "POST",
|
195
|
+
headers: {
|
196
|
+
"Content-Type": "application/json",
|
197
|
+
"Authorization": `Bot ${pkg.token}`,
|
198
|
+
},
|
199
|
+
body: JSON.stringify({
|
200
|
+
type: 4,
|
201
|
+
data: {
|
202
|
+
"content": reply,
|
203
|
+
"embeds": embeds,
|
204
|
+
"components": components,
|
205
|
+
}
|
206
|
+
})
|
207
|
+
}
|
208
|
+
// console.log(this)
|
209
|
+
fetch(`https://discord.com/api/v9/interactions/${this.data.id}/${this.data.token}/callback`, fetch_arguments).catch(err => console.log(err))
|
210
|
+
}},
|
211
|
+
token: null,
|
212
|
+
MESSAGE: class {
|
213
|
+
constructor(d) {
|
214
|
+
this.data = d
|
215
|
+
this.channel = {
|
216
|
+
id: d.channel_id,
|
217
|
+
send: (reply, embeds, components)=>{
|
218
|
+
// https://discord.com/api/v10/channels/${channel.id}/messages
|
219
|
+
const fetch_arguments = {
|
220
|
+
method: "POST",
|
221
|
+
headers: {
|
222
|
+
"Content-Type": "application/json",
|
223
|
+
"Authorization": `Bot ${pkg.token}`,
|
224
|
+
},
|
225
|
+
body: JSON.stringify({
|
226
|
+
"content": reply,
|
227
|
+
"embeds": embeds,
|
228
|
+
"components": components,
|
229
|
+
})
|
230
|
+
}
|
231
|
+
fetch(`https://discord.com/api/v10/channels/${this.data.channel_id}/messages`, fetch_arguments).catch(err => console.log(err))
|
232
|
+
}
|
233
|
+
}
|
234
|
+
}
|
235
|
+
reply(reply, embeds, components) {
|
236
|
+
// POST https://discord.com/api/v10/channels/${channel.id}/messages
|
237
|
+
const fetch_arguments = {
|
238
|
+
method: "POST",
|
239
|
+
headers: {
|
240
|
+
"Content-Type": "application/json",
|
241
|
+
"Authorization": `Bot ${pkg.token}`,
|
242
|
+
},
|
243
|
+
body: JSON.stringify({
|
244
|
+
"content": `<@${this.data.author.id}>, ${reply}`,
|
245
|
+
"embeds": embeds,
|
246
|
+
"components": components,
|
247
|
+
})
|
248
|
+
}
|
249
|
+
// console.log(this.data)
|
250
|
+
fetch(`https://discord.com/api/v10/channels/${this.data.channel_id}/messages`, fetch_arguments).catch(err => console.log(err))
|
251
|
+
}
|
252
|
+
|
253
|
+
|
254
|
+
},
|
255
|
+
|
256
|
+
command: class {
|
257
|
+
constructor(name, type, description, APP_ID,options) {
|
258
|
+
this.name = name
|
259
|
+
this.type = type
|
260
|
+
this.description = description
|
261
|
+
this.options = options
|
262
|
+
|
263
|
+
let headers = {
|
264
|
+
"Content-Type": "application/json",
|
265
|
+
"Authorization": `Bot ${pkg.token}`,
|
266
|
+
}
|
267
|
+
let uuri = `https://discord.com/api/v10/applications/${APP_ID}/commands`
|
268
|
+
let optionscmd = {
|
269
|
+
method: 'POST',
|
270
|
+
headers: headers,
|
271
|
+
body: JSON.stringify({
|
272
|
+
"name": name,
|
273
|
+
"type": type,
|
274
|
+
"description": description,
|
275
|
+
"options": options,
|
276
|
+
})
|
277
|
+
}
|
278
|
+
fetch(uuri, optionscmd).catch(err => console.log(err))
|
279
|
+
}
|
280
|
+
},
|
281
|
+
guild_command: class {
|
282
|
+
constructor(name, type, description, APP_ID, GUILD_ID, options) {
|
283
|
+
this.name = name
|
284
|
+
this.type = type
|
285
|
+
this.description = description
|
286
|
+
this.options = options
|
287
|
+
|
288
|
+
let headers = {
|
289
|
+
"Content-Type": "application/json",
|
290
|
+
"Authorization": `Bot ${pkg.token}`,
|
291
|
+
}
|
292
|
+
let uuri = `https://discord.com/api/v10/applications/${APP_ID}/guilds/${GUILD_ID}/commands`
|
293
|
+
let optionsguild = {
|
294
|
+
method: 'POST',
|
295
|
+
headers: headers,
|
296
|
+
body: JSON.stringify({
|
297
|
+
"name": name,
|
298
|
+
"type": type,
|
299
|
+
"description": description,
|
300
|
+
"options": options,
|
301
|
+
})
|
302
|
+
}
|
303
|
+
fetch(uuri, optionsguild).catch(err => console.log(err))
|
304
|
+
}
|
305
|
+
},
|
306
|
+
on: function(event, callback) {
|
307
|
+
const events = require('./events.js')
|
308
|
+
pkg[event] = callback
|
309
|
+
},
|
310
|
+
activityTypes: {
|
311
|
+
"Playing": 0,
|
312
|
+
"Streaming": 1,
|
313
|
+
"Listening": 2,
|
314
|
+
"Watching": 3,
|
315
|
+
"Custom": 4,
|
316
|
+
"Competing": 5,
|
317
|
+
},
|
318
|
+
}
|
319
|
+
|
320
|
+
module.exports = pkg
|
package/package.json
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
{
|
2
|
+
"name": "squacker.js",
|
3
|
+
"version": "1.0.4",
|
4
|
+
"description": "",
|
5
|
+
"main": "index.js",
|
6
|
+
"scripts": {
|
7
|
+
"test": "echo \"Error: no test specified\" && exit 1"
|
8
|
+
},
|
9
|
+
"author": "amukh1",
|
10
|
+
"license": "ISC",
|
11
|
+
"dependencies": {
|
12
|
+
"node-fetch": "^3.2.9",
|
13
|
+
"request": "^2.88.2",
|
14
|
+
"ws": "^8.8.1"
|
15
|
+
}
|
16
|
+
}
|
package/readme.md
ADDED
@@ -0,0 +1,159 @@
|
|
1
|
+
[![npm version](https://badge.fury.io/js/squacker.js.svg)](https://www.npmjs.com/package/squacker.js)
|
2
|
+
|
3
|
+
# squacker.js
|
4
|
+
|
5
|
+
> A small library for making discord bots, using the gateway *unlike* discord-easy-slash *(my last library)*
|
6
|
+
|
7
|
+
## Prerequisites
|
8
|
+
|
9
|
+
This project requires NodeJS (version 8 or later) and NPM.
|
10
|
+
[Node](http://nodejs.org/) and [NPM](https://npmjs.org/) are really easy to install.
|
11
|
+
To make sure you have them available on your machine,
|
12
|
+
try running the following command.
|
13
|
+
|
14
|
+
```sh
|
15
|
+
$ npm -v && node -v
|
16
|
+
6.4.1
|
17
|
+
v8.16.0
|
18
|
+
```
|
19
|
+
|
20
|
+
## Getting Started
|
21
|
+
|
22
|
+
|
23
|
+
## Installation
|
24
|
+
<br>
|
25
|
+
|
26
|
+
**BEFORE YOU INSTALL:** please read the [prerequisites](#prerequisites)
|
27
|
+
|
28
|
+
<br>
|
29
|
+
|
30
|
+
To install and set up the library, run:
|
31
|
+
|
32
|
+
```sh
|
33
|
+
$ npm install squacker.js
|
34
|
+
```
|
35
|
+
|
36
|
+
Or if you prefer using Yarn:
|
37
|
+
|
38
|
+
```sh
|
39
|
+
$ yarn add --dev squacker.js
|
40
|
+
```
|
41
|
+
|
42
|
+
## Usage
|
43
|
+
|
44
|
+
### First, Start by importing the library
|
45
|
+
|
46
|
+
```js
|
47
|
+
var client = require('squacker.js');
|
48
|
+
```
|
49
|
+
<br>
|
50
|
+
### Then, log in with your token, intents, and presence.
|
51
|
+
|
52
|
+
```js
|
53
|
+
client.login('TOKEN', 513, {
|
54
|
+
name: "Froggy",
|
55
|
+
type: client.activityTypes["Playing"],
|
56
|
+
});
|
57
|
+
```
|
58
|
+
<br>
|
59
|
+
|
60
|
+
### Making a command:
|
61
|
+
|
62
|
+
```js
|
63
|
+
new client.command('help', 1, 'help command?', <APP_ID> ,null) // GLOBAL COMMAND
|
64
|
+
new client.guild_command('help', 1, 'help command?', <APP_ID> , <GUILD_ID>, null) // GUILD COMMAND
|
65
|
+
```
|
66
|
+
|
67
|
+
The *command* class takes 5 arguments, *Name* (Of the command), *Type* (Of the command), *Description* (Of the command), the *APP_ID* (Of the bot), and *Options* (any options that the command takes).
|
68
|
+
|
69
|
+
The *guild_command* class takes 6 arguments, *Name* (Of the command), *Type* (Of the command), *Description* (Of the command), the *APP_ID* (Of the bot), the *GUILD_ID* (Of the guild), and *Options* (any options that the command takes).
|
70
|
+
|
71
|
+
### For types:
|
72
|
+
![](./command_types.png)
|
73
|
+
or look at this [page](https://discord.com/developers/docs/interactions/application-commands#application-command-object-application-command-types) by discord.
|
74
|
+
|
75
|
+
### For options:
|
76
|
+
They look like this:
|
77
|
+
```js
|
78
|
+
[ { "name": "nameofoption", "description": "descriptionofoption", "type": 4, "required": true, } ]
|
79
|
+
```
|
80
|
+
It takes an array, with all the options for the command. Because of this, you can have multiple options for a single command.
|
81
|
+
|
82
|
+
For types of objects:
|
83
|
+
![](./option_types.png)
|
84
|
+
or look at this [page](https://discord.com/developers/docs/interactions/application-commands#application-command-object-application-command-option-type) by discord.
|
85
|
+
|
86
|
+
### Main Event Listener:
|
87
|
+
|
88
|
+
```js
|
89
|
+
client.on('INTERACTION_CREATE', (interaction)=>{
|
90
|
+
// do stuff
|
91
|
+
const message = new client.MESSAGE(msg)
|
92
|
+
message.reply(`Oh, nice message!`)
|
93
|
+
})
|
94
|
+
|
95
|
+
client.on('MESSAGE_CREATE', (msg)=>{
|
96
|
+
// do stuff
|
97
|
+
const interact = new client.INTERACTION(msg)
|
98
|
+
interact.reply(`Oh, nice interaction!`)
|
99
|
+
})
|
100
|
+
|
101
|
+
// and so on...
|
102
|
+
```
|
103
|
+
|
104
|
+
[List of all events](https://discord.com/developers/docs/topics/gateway#commands-and-events)
|
105
|
+
|
106
|
+
<br>
|
107
|
+
|
108
|
+
client.reply takes 3 arguments, *message*, which is the message to send, *embeds*, which is an array of embeds for the command to send, and *components*, which is an array of components for the command to send.
|
109
|
+
|
110
|
+
```js
|
111
|
+
client.reply(message, embeds, components)
|
112
|
+
```
|
113
|
+
|
114
|
+
### For embeds:
|
115
|
+
|
116
|
+
```js
|
117
|
+
[ { "title": "title", "description": "description", "color": "color", "fields": [ { "name": "name", "value": "value", "inline": true }, { "name": "name", "value": "value", "inline": true } ] } ]
|
118
|
+
```
|
119
|
+
|
120
|
+
### Making our bot search for interactions/logging-in/turning it on:
|
121
|
+
|
122
|
+
```js
|
123
|
+
client.login('TOKEN', 513, {
|
124
|
+
name: "Froggy",
|
125
|
+
type: client.activityTypes["Playing"],
|
126
|
+
});
|
127
|
+
```
|
128
|
+
|
129
|
+
|
130
|
+
### Serving the app
|
131
|
+
|
132
|
+
```sh
|
133
|
+
$ npm start
|
134
|
+
```
|
135
|
+
|
136
|
+
## Contributing
|
137
|
+
|
138
|
+
You can contribute to the project by making a pull request on [GitHub](https://github.com).
|
139
|
+
|
140
|
+
## Credits
|
141
|
+
|
142
|
+
# Amukh1.
|
143
|
+
|
144
|
+
## Built With
|
145
|
+
|
146
|
+
* [Node](https://nodejs.org/)
|
147
|
+
* [Express + Cors](https://expressjs.com)
|
148
|
+
* [Discord](https://discord.com/developers/docs/intro)
|
149
|
+
* [Love](https://amukh1.dev)
|
150
|
+
|
151
|
+
## Authors
|
152
|
+
|
153
|
+
* **Amukh1** - [Github](https://github.com/amukh1)
|
154
|
+
|
155
|
+
See also the list of [contributors](https://github.com/amukh1/squacker.js/contributors) who participated in this project.
|
156
|
+
|
157
|
+
## License
|
158
|
+
|
159
|
+
[MIT License](https://andreasonny.mit-license.org/2022) © Amukh1
|