@20syldev/api 3.4.5 → 3.4.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/FUNDING.yml +1 -1
- package/LICENSE +27 -27
- package/README.md +110 -110
- package/app.js +850 -842
- package/modules/v3/algorithms.js +217 -217
- package/modules/v3/captcha.js +54 -54
- package/modules/v3/chat.js +108 -108
- package/modules/v3/color.js +40 -40
- package/modules/v3/convert.js +38 -38
- package/modules/v3/domain.js +38 -38
- package/modules/v3/hash.js +15 -15
- package/modules/v3/hyperplanning.js +54 -50
- package/modules/v3/levenshtein.js +45 -45
- package/modules/v3/personal.js +126 -126
- package/modules/v3/qrcode.js +19 -19
- package/modules/v3/tic_tac_toe.js +235 -235
- package/modules/v3/time.js +86 -86
- package/modules/v3/token.js +47 -47
- package/modules/v3/username.js +31 -31
- package/modules/v3/utils.js +76 -65
- package/modules/v3.js +14 -14
- package/package.json +56 -53
- package/robots.txt +73 -73
- package/.github/workflows/publish.yml +0 -27
package/modules/v3/algorithms.js
CHANGED
|
@@ -1,218 +1,218 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Check if two strings are anagrams of each other
|
|
3
|
-
*
|
|
4
|
-
* @param {string} value - First string to compare
|
|
5
|
-
* @param {string} value2 - Second string to compare
|
|
6
|
-
* @returns {boolean} - True if strings are anagrams, false otherwise
|
|
7
|
-
* @throws {Error} - If inputs are invalid
|
|
8
|
-
*/
|
|
9
|
-
export function anagram(value, value2) {
|
|
10
|
-
if (!value) throw new Error('First value is required');
|
|
11
|
-
if (!value2) throw new Error('Second value is required');
|
|
12
|
-
|
|
13
|
-
if (typeof value !== 'string') throw new Error('First value must be a string');
|
|
14
|
-
if (typeof value2 !== 'string') throw new Error('Second value must be a string');
|
|
15
|
-
|
|
16
|
-
if (value.length < 2) throw new Error('First value must be at least two characters long');
|
|
17
|
-
if (value.length > 1000) throw new Error('First value must be less than 1000 characters long');
|
|
18
|
-
|
|
19
|
-
if (value2.length < 2) throw new Error('Second value must be at least two characters long');
|
|
20
|
-
if (value2.length > 1000) throw new Error('Second value must be less than 1000 characters long');
|
|
21
|
-
|
|
22
|
-
return value.split('').sort().join('') === value2.split('').sort().join('');
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
/**
|
|
26
|
-
* Sort an array using bubble sort algorithm
|
|
27
|
-
*
|
|
28
|
-
* @param {string} value - Comma-separated list of numbers
|
|
29
|
-
* @returns {number[]} - Sorted array of numbers
|
|
30
|
-
* @throws {Error} - If input is invalid
|
|
31
|
-
*/
|
|
32
|
-
export function bubblesort(value) {
|
|
33
|
-
if (!value) throw new Error('A value is required');
|
|
34
|
-
|
|
35
|
-
if (typeof value !== 'string') throw new Error('Value must be a string');
|
|
36
|
-
|
|
37
|
-
const arr = value.split(',').map(Number);
|
|
38
|
-
|
|
39
|
-
if (arr.some(isNaN)) throw new Error('Array must contain only numbers');
|
|
40
|
-
if (arr.length < 2) throw new Error('Array must contain at least two numbers');
|
|
41
|
-
if (arr.length > 1000) throw new Error('Array must contain less than 1000 numbers');
|
|
42
|
-
|
|
43
|
-
for (let i = 0; i < arr.length - 1; i++) {
|
|
44
|
-
for (let j = 0; j < arr.length - i - 1; j++) {
|
|
45
|
-
if (arr[j] > arr[j + 1]) [arr[j], arr[j + 1]] = [arr[j + 1], arr[j]];
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
return arr;
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
/**
|
|
53
|
-
* Calculate the factorial of a number
|
|
54
|
-
*
|
|
55
|
-
* @param {number} value - Number to calculate factorial for
|
|
56
|
-
* @returns {number} - Factorial result
|
|
57
|
-
* @throws {Error} - If input is invalid or out of range
|
|
58
|
-
*/
|
|
59
|
-
export function factorial(value) {
|
|
60
|
-
if (isNaN(value)) throw new Error('Value must be a number');
|
|
61
|
-
if (value < 0) throw new Error('Number must be positive');
|
|
62
|
-
if (value > 170) throw new Error('Number must be between 0 and 170');
|
|
63
|
-
|
|
64
|
-
return value <= 1 ? 1 : value * factorial(value - 1);
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
/**
|
|
68
|
-
* Generate a Fibonacci sequence up to the specified length
|
|
69
|
-
*
|
|
70
|
-
* @param {number} value - Length of Fibonacci sequence to generate
|
|
71
|
-
* @returns {number[]} - Array of Fibonacci numbers
|
|
72
|
-
* @throws {Error} - If input is invalid or out of range
|
|
73
|
-
*/
|
|
74
|
-
export function fibonacci(value) {
|
|
75
|
-
if (isNaN(value)) throw new Error('Value must be a number');
|
|
76
|
-
if (value < 0) throw new Error('Number must be positive');
|
|
77
|
-
if (value > 1000) throw new Error('Number must be between 0 and 1000');
|
|
78
|
-
|
|
79
|
-
let fib = [0, 1];
|
|
80
|
-
|
|
81
|
-
for (let i = 2; i < parseInt(value); i++) {
|
|
82
|
-
fib.push(fib[i - 1] + fib[i - 2]);
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
return fib.slice(0, parseInt(value));
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
/**
|
|
89
|
-
* Calculate the greatest common divisor (GCD) of two numbers
|
|
90
|
-
*
|
|
91
|
-
* @param {number} value - First number
|
|
92
|
-
* @param {number} value2 - Second number
|
|
93
|
-
* @returns {number} - Greatest common divisor
|
|
94
|
-
* @throws {Error} - If inputs are invalid or out of range
|
|
95
|
-
*/
|
|
96
|
-
export function gcd(value, value2) {
|
|
97
|
-
if (isNaN(value)) throw new Error('First value must be a number');
|
|
98
|
-
if (isNaN(value2)) throw new Error('Second value must be a number');
|
|
99
|
-
|
|
100
|
-
if (value <= 0) throw new Error('First number must be strictly positive');
|
|
101
|
-
if (value2 <= 0) throw new Error('Second number must be strictly positive');
|
|
102
|
-
|
|
103
|
-
if (value > 100000) throw new Error('First number must be between 0 and 100000');
|
|
104
|
-
if (value2 > 100000) throw new Error('Second number must be between 0 and 100000');
|
|
105
|
-
|
|
106
|
-
value = Math.abs(value);
|
|
107
|
-
value2 = Math.abs(value2);
|
|
108
|
-
|
|
109
|
-
while (value2) [value, value2] = [value2, value % value2];
|
|
110
|
-
|
|
111
|
-
return value;
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
/**
|
|
115
|
-
* Check if a number is prime
|
|
116
|
-
*
|
|
117
|
-
* @param {number} value - Number to check
|
|
118
|
-
* @returns {boolean} - True if the number is prime, false otherwise
|
|
119
|
-
* @throws {Error} - If input is invalid or out of range
|
|
120
|
-
*/
|
|
121
|
-
export function isprime(value) {
|
|
122
|
-
if (isNaN(value)) throw new Error('Value must be a number');
|
|
123
|
-
if (value < 1) throw new Error('Number must be positive');
|
|
124
|
-
if (value > 100000) throw new Error('Number must be between 1 and 100000');
|
|
125
|
-
|
|
126
|
-
for (let i = 2; i <= Math.sqrt(value); i++) {
|
|
127
|
-
if (value % i === 0) return false;
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
return true;
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
/**
|
|
134
|
-
* Check if a string is a palindrome
|
|
135
|
-
*
|
|
136
|
-
* @param {string} value - String to check
|
|
137
|
-
* @returns {boolean} - True if the string is a palindrome, false otherwise
|
|
138
|
-
* @throws {Error} - If input is invalid
|
|
139
|
-
*/
|
|
140
|
-
export function palindrome(value) {
|
|
141
|
-
if (!value) throw new Error('A value is required');
|
|
142
|
-
|
|
143
|
-
if (typeof value !== 'string') throw new Error('Value must be a string');
|
|
144
|
-
|
|
145
|
-
if (value.length < 2) throw new Error('Value must be at least two characters long');
|
|
146
|
-
if (value.length > 1000) throw new Error('Value must be less than 1000 characters long');
|
|
147
|
-
|
|
148
|
-
return value === value.split('').reverse().join('');
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
/**
|
|
152
|
-
* Find all prime factors of a number
|
|
153
|
-
*
|
|
154
|
-
* @param {number} value - Number to factorize
|
|
155
|
-
* @returns {number[]} - Array of prime factors
|
|
156
|
-
* @throws {Error} - If input is invalid or out of range
|
|
157
|
-
*/
|
|
158
|
-
export function primefactors(value) {
|
|
159
|
-
if (isNaN(value)) throw new Error('Value must be a number');
|
|
160
|
-
if (value < 2) throw new Error('Number must be positive and greater than 1');
|
|
161
|
-
if (value > 100000) throw new Error('Number must be between 2 and 100000');
|
|
162
|
-
|
|
163
|
-
const factors = [];
|
|
164
|
-
|
|
165
|
-
for (let i = 2; i <= value; i++) {
|
|
166
|
-
while (value % i === 0) {
|
|
167
|
-
factors.push(i);
|
|
168
|
-
value /= i;
|
|
169
|
-
}
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
return factors;
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
/**
|
|
176
|
-
* Generate a list of all prime numbers up to the specified limit
|
|
177
|
-
*
|
|
178
|
-
* @param {number} value - Upper limit to check for primes
|
|
179
|
-
* @returns {number[]} - Array of prime numbers
|
|
180
|
-
* @throws {Error} - If input is invalid or out of range
|
|
181
|
-
*/
|
|
182
|
-
export function primelist(value) {
|
|
183
|
-
if (isNaN(value)) throw new Error('Value must be a number');
|
|
184
|
-
if (value < 2) throw new Error('Number must be positive and greater than 1');
|
|
185
|
-
if (value > 10000) throw new Error('Number must be between 2 and 10000');
|
|
186
|
-
|
|
187
|
-
const primes = [];
|
|
188
|
-
|
|
189
|
-
for (let i = 2; i <= value; i++) {
|
|
190
|
-
let isPrime = true;
|
|
191
|
-
|
|
192
|
-
for (let j = 2; j <= Math.sqrt(i); j++) {
|
|
193
|
-
if (i % j === 0) {
|
|
194
|
-
isPrime = false;
|
|
195
|
-
break;
|
|
196
|
-
}
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
if (isPrime) primes.push(i);
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
return primes;
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
/**
|
|
206
|
-
* Reverse a string
|
|
207
|
-
*
|
|
208
|
-
* @param {string} value - String to reverse
|
|
209
|
-
* @returns {string} - Reversed string
|
|
210
|
-
* @throws {Error} - If input is invalid
|
|
211
|
-
*/
|
|
212
|
-
export function reverse(value) {
|
|
213
|
-
if (!value) throw new Error('A value is required');
|
|
214
|
-
|
|
215
|
-
if (typeof value !== 'string') throw new Error('Value must be a string');
|
|
216
|
-
|
|
217
|
-
return value.split('').reverse().join('');
|
|
1
|
+
/**
|
|
2
|
+
* Check if two strings are anagrams of each other
|
|
3
|
+
*
|
|
4
|
+
* @param {string} value - First string to compare
|
|
5
|
+
* @param {string} value2 - Second string to compare
|
|
6
|
+
* @returns {boolean} - True if strings are anagrams, false otherwise
|
|
7
|
+
* @throws {Error} - If inputs are invalid
|
|
8
|
+
*/
|
|
9
|
+
export function anagram(value, value2) {
|
|
10
|
+
if (!value) throw new Error('First value is required');
|
|
11
|
+
if (!value2) throw new Error('Second value is required');
|
|
12
|
+
|
|
13
|
+
if (typeof value !== 'string') throw new Error('First value must be a string');
|
|
14
|
+
if (typeof value2 !== 'string') throw new Error('Second value must be a string');
|
|
15
|
+
|
|
16
|
+
if (value.length < 2) throw new Error('First value must be at least two characters long');
|
|
17
|
+
if (value.length > 1000) throw new Error('First value must be less than 1000 characters long');
|
|
18
|
+
|
|
19
|
+
if (value2.length < 2) throw new Error('Second value must be at least two characters long');
|
|
20
|
+
if (value2.length > 1000) throw new Error('Second value must be less than 1000 characters long');
|
|
21
|
+
|
|
22
|
+
return value.split('').sort().join('') === value2.split('').sort().join('');
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Sort an array using bubble sort algorithm
|
|
27
|
+
*
|
|
28
|
+
* @param {string} value - Comma-separated list of numbers
|
|
29
|
+
* @returns {number[]} - Sorted array of numbers
|
|
30
|
+
* @throws {Error} - If input is invalid
|
|
31
|
+
*/
|
|
32
|
+
export function bubblesort(value) {
|
|
33
|
+
if (!value) throw new Error('A value is required');
|
|
34
|
+
|
|
35
|
+
if (typeof value !== 'string') throw new Error('Value must be a string');
|
|
36
|
+
|
|
37
|
+
const arr = value.split(',').map(Number);
|
|
38
|
+
|
|
39
|
+
if (arr.some(isNaN)) throw new Error('Array must contain only numbers');
|
|
40
|
+
if (arr.length < 2) throw new Error('Array must contain at least two numbers');
|
|
41
|
+
if (arr.length > 1000) throw new Error('Array must contain less than 1000 numbers');
|
|
42
|
+
|
|
43
|
+
for (let i = 0; i < arr.length - 1; i++) {
|
|
44
|
+
for (let j = 0; j < arr.length - i - 1; j++) {
|
|
45
|
+
if (arr[j] > arr[j + 1]) [arr[j], arr[j + 1]] = [arr[j + 1], arr[j]];
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
return arr;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Calculate the factorial of a number
|
|
54
|
+
*
|
|
55
|
+
* @param {number} value - Number to calculate factorial for
|
|
56
|
+
* @returns {number} - Factorial result
|
|
57
|
+
* @throws {Error} - If input is invalid or out of range
|
|
58
|
+
*/
|
|
59
|
+
export function factorial(value) {
|
|
60
|
+
if (isNaN(value)) throw new Error('Value must be a number');
|
|
61
|
+
if (value < 0) throw new Error('Number must be positive');
|
|
62
|
+
if (value > 170) throw new Error('Number must be between 0 and 170');
|
|
63
|
+
|
|
64
|
+
return value <= 1 ? 1 : value * factorial(value - 1);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Generate a Fibonacci sequence up to the specified length
|
|
69
|
+
*
|
|
70
|
+
* @param {number} value - Length of Fibonacci sequence to generate
|
|
71
|
+
* @returns {number[]} - Array of Fibonacci numbers
|
|
72
|
+
* @throws {Error} - If input is invalid or out of range
|
|
73
|
+
*/
|
|
74
|
+
export function fibonacci(value) {
|
|
75
|
+
if (isNaN(value)) throw new Error('Value must be a number');
|
|
76
|
+
if (value < 0) throw new Error('Number must be positive');
|
|
77
|
+
if (value > 1000) throw new Error('Number must be between 0 and 1000');
|
|
78
|
+
|
|
79
|
+
let fib = [0, 1];
|
|
80
|
+
|
|
81
|
+
for (let i = 2; i < parseInt(value); i++) {
|
|
82
|
+
fib.push(fib[i - 1] + fib[i - 2]);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
return fib.slice(0, parseInt(value));
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Calculate the greatest common divisor (GCD) of two numbers
|
|
90
|
+
*
|
|
91
|
+
* @param {number} value - First number
|
|
92
|
+
* @param {number} value2 - Second number
|
|
93
|
+
* @returns {number} - Greatest common divisor
|
|
94
|
+
* @throws {Error} - If inputs are invalid or out of range
|
|
95
|
+
*/
|
|
96
|
+
export function gcd(value, value2) {
|
|
97
|
+
if (isNaN(value)) throw new Error('First value must be a number');
|
|
98
|
+
if (isNaN(value2)) throw new Error('Second value must be a number');
|
|
99
|
+
|
|
100
|
+
if (value <= 0) throw new Error('First number must be strictly positive');
|
|
101
|
+
if (value2 <= 0) throw new Error('Second number must be strictly positive');
|
|
102
|
+
|
|
103
|
+
if (value > 100000) throw new Error('First number must be between 0 and 100000');
|
|
104
|
+
if (value2 > 100000) throw new Error('Second number must be between 0 and 100000');
|
|
105
|
+
|
|
106
|
+
value = Math.abs(value);
|
|
107
|
+
value2 = Math.abs(value2);
|
|
108
|
+
|
|
109
|
+
while (value2) [value, value2] = [value2, value % value2];
|
|
110
|
+
|
|
111
|
+
return value;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Check if a number is prime
|
|
116
|
+
*
|
|
117
|
+
* @param {number} value - Number to check
|
|
118
|
+
* @returns {boolean} - True if the number is prime, false otherwise
|
|
119
|
+
* @throws {Error} - If input is invalid or out of range
|
|
120
|
+
*/
|
|
121
|
+
export function isprime(value) {
|
|
122
|
+
if (isNaN(value)) throw new Error('Value must be a number');
|
|
123
|
+
if (value < 1) throw new Error('Number must be positive');
|
|
124
|
+
if (value > 100000) throw new Error('Number must be between 1 and 100000');
|
|
125
|
+
|
|
126
|
+
for (let i = 2; i <= Math.sqrt(value); i++) {
|
|
127
|
+
if (value % i === 0) return false;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
return true;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* Check if a string is a palindrome
|
|
135
|
+
*
|
|
136
|
+
* @param {string} value - String to check
|
|
137
|
+
* @returns {boolean} - True if the string is a palindrome, false otherwise
|
|
138
|
+
* @throws {Error} - If input is invalid
|
|
139
|
+
*/
|
|
140
|
+
export function palindrome(value) {
|
|
141
|
+
if (!value) throw new Error('A value is required');
|
|
142
|
+
|
|
143
|
+
if (typeof value !== 'string') throw new Error('Value must be a string');
|
|
144
|
+
|
|
145
|
+
if (value.length < 2) throw new Error('Value must be at least two characters long');
|
|
146
|
+
if (value.length > 1000) throw new Error('Value must be less than 1000 characters long');
|
|
147
|
+
|
|
148
|
+
return value === value.split('').reverse().join('');
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* Find all prime factors of a number
|
|
153
|
+
*
|
|
154
|
+
* @param {number} value - Number to factorize
|
|
155
|
+
* @returns {number[]} - Array of prime factors
|
|
156
|
+
* @throws {Error} - If input is invalid or out of range
|
|
157
|
+
*/
|
|
158
|
+
export function primefactors(value) {
|
|
159
|
+
if (isNaN(value)) throw new Error('Value must be a number');
|
|
160
|
+
if (value < 2) throw new Error('Number must be positive and greater than 1');
|
|
161
|
+
if (value > 100000) throw new Error('Number must be between 2 and 100000');
|
|
162
|
+
|
|
163
|
+
const factors = [];
|
|
164
|
+
|
|
165
|
+
for (let i = 2; i <= value; i++) {
|
|
166
|
+
while (value % i === 0) {
|
|
167
|
+
factors.push(i);
|
|
168
|
+
value /= i;
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
return factors;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
/**
|
|
176
|
+
* Generate a list of all prime numbers up to the specified limit
|
|
177
|
+
*
|
|
178
|
+
* @param {number} value - Upper limit to check for primes
|
|
179
|
+
* @returns {number[]} - Array of prime numbers
|
|
180
|
+
* @throws {Error} - If input is invalid or out of range
|
|
181
|
+
*/
|
|
182
|
+
export function primelist(value) {
|
|
183
|
+
if (isNaN(value)) throw new Error('Value must be a number');
|
|
184
|
+
if (value < 2) throw new Error('Number must be positive and greater than 1');
|
|
185
|
+
if (value > 10000) throw new Error('Number must be between 2 and 10000');
|
|
186
|
+
|
|
187
|
+
const primes = [];
|
|
188
|
+
|
|
189
|
+
for (let i = 2; i <= value; i++) {
|
|
190
|
+
let isPrime = true;
|
|
191
|
+
|
|
192
|
+
for (let j = 2; j <= Math.sqrt(i); j++) {
|
|
193
|
+
if (i % j === 0) {
|
|
194
|
+
isPrime = false;
|
|
195
|
+
break;
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
if (isPrime) primes.push(i);
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
return primes;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
/**
|
|
206
|
+
* Reverse a string
|
|
207
|
+
*
|
|
208
|
+
* @param {string} value - String to reverse
|
|
209
|
+
* @returns {string} - Reversed string
|
|
210
|
+
* @throws {Error} - If input is invalid
|
|
211
|
+
*/
|
|
212
|
+
export function reverse(value) {
|
|
213
|
+
if (!value) throw new Error('A value is required');
|
|
214
|
+
|
|
215
|
+
if (typeof value !== 'string') throw new Error('Value must be a string');
|
|
216
|
+
|
|
217
|
+
return value.split('').reverse().join('');
|
|
218
218
|
}
|
package/modules/v3/captcha.js
CHANGED
|
@@ -1,55 +1,55 @@
|
|
|
1
|
-
import { createCanvas } from 'canvas';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Generate a captcha image from the provided text
|
|
5
|
-
*
|
|
6
|
-
* @param {string} text - Text to render in the captcha image
|
|
7
|
-
* @returns {Buffer} - PNG image buffer of the rendered captcha
|
|
8
|
-
* @throws {Error} - If text is not provided
|
|
9
|
-
*/
|
|
10
|
-
export default function captcha(text) {
|
|
11
|
-
if (!text) throw new Error('Text is required to generate a captcha.');
|
|
12
|
-
|
|
13
|
-
const size = 60, font = '60px Comic Sans Ms', width = text.length * size, height = 120;
|
|
14
|
-
const canvas = createCanvas(width, height), ctx = canvas.getContext('2d');
|
|
15
|
-
|
|
16
|
-
// Set white background
|
|
17
|
-
ctx.fillStyle = 'white';
|
|
18
|
-
ctx.fillRect(0, 0, width, height);
|
|
19
|
-
|
|
20
|
-
// Add random lines for noise
|
|
21
|
-
for (let i = 0; i < 20; i++) {
|
|
22
|
-
ctx.strokeStyle = 'rgba(0, 0, 0, 0.3)';
|
|
23
|
-
ctx.beginPath();
|
|
24
|
-
ctx.moveTo(Math.random() * width, Math.random() * height);
|
|
25
|
-
ctx.lineTo(Math.random() * width, Math.random() * height);
|
|
26
|
-
ctx.lineWidth = Math.random() * 2;
|
|
27
|
-
ctx.stroke();
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
let x = (canvas.width + 20 - width) / 2;
|
|
31
|
-
|
|
32
|
-
// Draw each character with random rotation and color
|
|
33
|
-
for (let i = 0; i < text.length; i++) {
|
|
34
|
-
const offsetX = Math.cos(i * 0.3) * 10, y = height / 2.5 + Math.floor(Math.random() * (height / 2));
|
|
35
|
-
|
|
36
|
-
ctx.font = font;
|
|
37
|
-
ctx.fillStyle = `rgb(${Math.floor(Math.random() * 192)}, ${Math.floor(Math.random() * 192)}, ${Math.floor(Math.random() * 192)})`;
|
|
38
|
-
|
|
39
|
-
ctx.save();
|
|
40
|
-
ctx.translate(x + size / 2, y);
|
|
41
|
-
ctx.rotate((Math.random() - 0.5) * 0.5);
|
|
42
|
-
ctx.fillText(text[i], -size / 2 + offsetX, 0);
|
|
43
|
-
ctx.restore();
|
|
44
|
-
|
|
45
|
-
x += size;
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
// Add noise dots
|
|
49
|
-
for (let i = 0; i < 200; i++) {
|
|
50
|
-
ctx.fillStyle = 'black';
|
|
51
|
-
ctx.fillRect(Math.floor(Math.random() * width), Math.floor(Math.random() * height), 1.2, 1.2);
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
return canvas.toBuffer('image/png');
|
|
1
|
+
import { createCanvas } from 'canvas';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Generate a captcha image from the provided text
|
|
5
|
+
*
|
|
6
|
+
* @param {string} text - Text to render in the captcha image
|
|
7
|
+
* @returns {Buffer} - PNG image buffer of the rendered captcha
|
|
8
|
+
* @throws {Error} - If text is not provided
|
|
9
|
+
*/
|
|
10
|
+
export default function captcha(text) {
|
|
11
|
+
if (!text) throw new Error('Text is required to generate a captcha.');
|
|
12
|
+
|
|
13
|
+
const size = 60, font = '60px Comic Sans Ms', width = text.length * size, height = 120;
|
|
14
|
+
const canvas = createCanvas(width, height), ctx = canvas.getContext('2d');
|
|
15
|
+
|
|
16
|
+
// Set white background
|
|
17
|
+
ctx.fillStyle = 'white';
|
|
18
|
+
ctx.fillRect(0, 0, width, height);
|
|
19
|
+
|
|
20
|
+
// Add random lines for noise
|
|
21
|
+
for (let i = 0; i < 20; i++) {
|
|
22
|
+
ctx.strokeStyle = 'rgba(0, 0, 0, 0.3)';
|
|
23
|
+
ctx.beginPath();
|
|
24
|
+
ctx.moveTo(Math.random() * width, Math.random() * height);
|
|
25
|
+
ctx.lineTo(Math.random() * width, Math.random() * height);
|
|
26
|
+
ctx.lineWidth = Math.random() * 2;
|
|
27
|
+
ctx.stroke();
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
let x = (canvas.width + 20 - width) / 2;
|
|
31
|
+
|
|
32
|
+
// Draw each character with random rotation and color
|
|
33
|
+
for (let i = 0; i < text.length; i++) {
|
|
34
|
+
const offsetX = Math.cos(i * 0.3) * 10, y = height / 2.5 + Math.floor(Math.random() * (height / 2));
|
|
35
|
+
|
|
36
|
+
ctx.font = font;
|
|
37
|
+
ctx.fillStyle = `rgb(${Math.floor(Math.random() * 192)}, ${Math.floor(Math.random() * 192)}, ${Math.floor(Math.random() * 192)})`;
|
|
38
|
+
|
|
39
|
+
ctx.save();
|
|
40
|
+
ctx.translate(x + size / 2, y);
|
|
41
|
+
ctx.rotate((Math.random() - 0.5) * 0.5);
|
|
42
|
+
ctx.fillText(text[i], -size / 2 + offsetX, 0);
|
|
43
|
+
ctx.restore();
|
|
44
|
+
|
|
45
|
+
x += size;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// Add noise dots
|
|
49
|
+
for (let i = 0; i < 200; i++) {
|
|
50
|
+
ctx.fillStyle = 'black';
|
|
51
|
+
ctx.fillRect(Math.floor(Math.random() * width), Math.floor(Math.random() * height), 1.2, 1.2);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
return canvas.toBuffer('image/png');
|
|
55
55
|
}
|