strc 2.0.0 → 2.0.2

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/dist/jssc.cjs ADDED
@@ -0,0 +1,1615 @@
1
+ /*
2
+
3
+ MIT License
4
+
5
+ Copyright (c) 2025-2026 JustDeveloper <https://justdeveloper.is-a.dev/>
6
+
7
+ Permission is hereby granted, free of charge, to any person obtaining a copy
8
+ of this software and associated documentation files (the "Software"), to deal
9
+ in the Software without restriction, including without limitation the rights
10
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11
+ copies of the Software, and to permit persons to whom the Software is
12
+ furnished to do so, subject to the following conditions:
13
+
14
+ The above copyright notice and this permission notice shall be included in all
15
+ copies or substantial portions of the Software.
16
+
17
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23
+ SOFTWARE.
24
+
25
+ */
26
+
27
+ /*
28
+ __ _______________ __
29
+ \ \ __ / / __/ __/ ___/ / /
30
+ > > / // /\ \_\ \/ /__ < <
31
+ /_/ \___/___/___/\___/ \_\
32
+
33
+ JavaScript String Compressor
34
+ https://jssc.js.org/
35
+
36
+ npm i strc
37
+
38
+ */
39
+
40
+ 'use strict';
41
+
42
+ Object.defineProperty(exports, '__esModule', { value: true });
43
+
44
+ const JUSTC = require('justc');
45
+
46
+ const name__ = 'JSSC';
47
+ const prefix = name__+': ';
48
+ if ((String.fromCharCode(65536).charCodeAt(0) === 65536) || !(String.fromCharCode(256).charCodeAt(0) === 256)) {
49
+ throw new Error(prefix+'Supported UTF-16 only!')
50
+ }
51
+
52
+ function stringCodes(str) {
53
+ let output = [];
54
+ let max = 0;
55
+ let maxCharCode = 0;
56
+ let min = Infinity;
57
+ String(str).split('').forEach(char => {
58
+ const code = char.charCodeAt();
59
+ output.push(code);
60
+ max = Math.max(max, code.toString().length);
61
+ maxCharCode = Math.max(maxCharCode, code);
62
+ min = Math.min(min, code.toString().length);
63
+ });
64
+ return {max, output, maxCharCode, min};
65
+ }
66
+
67
+ function charCode(num) {
68
+ return String.fromCharCode(num + 32);
69
+ }
70
+ function checkChar(cde) {
71
+ return cde % 65535 === cde
72
+ }
73
+
74
+ function stringChunks(str, num) {
75
+ const output = [];
76
+ for (let i = 0; i < str.length; i += num) {
77
+ output.push(str.slice(i, i + num));
78
+ }
79
+ return output
80
+ }
81
+ function chunkArray(array, num) {
82
+ const result = [];
83
+ for (let i = 0; i < array.length; i += num) {
84
+ result.push(array.slice(i, i + num));
85
+ }
86
+ return result;
87
+ }
88
+
89
+ function decToBin(num, wnum) {
90
+ return num.toString(2).padStart(wnum, '0');
91
+ }
92
+ function binToDec(str) {
93
+ return parseInt(str, 2);
94
+ }
95
+
96
+ function charsBase() {
97
+ const charsBase = {};
98
+ function addChar(i) {
99
+ charsBase[i] = String.fromCharCode(i);
100
+ }
101
+ for (let i = 0; i < 65; i++) addChar(i); /* ASCII 00 - 40 */
102
+ for (let i = 91; i < 97; i++) addChar(i); /* ASCII 5B - 60 */
103
+ for (let i = 123; i < 128; i++) addChar(i); /* ASCII 7B - 7F */
104
+ return charsBase;
105
+ }
106
+ function charsLatin() {
107
+ const charsLatin = {};
108
+ for (let i = 0; i < 128; i++) {
109
+ charsLatin[i] = String.fromCharCode(i); /* ASCII 00 - 7F */
110
+ }
111
+ return charsLatin;
112
+ }
113
+
114
+ const _JSSC = {};
115
+ _JSSC._char = (cde) => String.fromCharCode(cde);
116
+ _JSSC._IDs = {
117
+ 'BASE': 0,
118
+ 'RU': 1,
119
+ 'ENRU': 2,
120
+ 'ENKK': 3,
121
+ 'HI': 4,
122
+ 'ENHI': 5,
123
+ 'BN': 6,
124
+ 'ENBN': 7,
125
+ 'HIBN': 8,
126
+ 'JA': 9,
127
+ 'Telu': 10,
128
+ 'MR': 11,
129
+ 'B': 12,
130
+ 'E': 13,
131
+ 'AR': 14
132
+ };
133
+ _JSSC.BASE = function() { /* Base */
134
+ const chrsBase = charsBase();
135
+ const addCBase = [
136
+ 215, 247, 8722, 11800,
137
+ 174, 169, 171, 10003,
138
+ 182, 9834, 183, 10005,
139
+ 177, 181, 8960, 8211,
140
+ 8212, 8228, 8229, 8230,
141
+ 8240, 8241, 8249, 8250,
142
+ 8252, 8253, 8263, 8264,
143
+ 8267, 8270, 8274, 8451,
144
+ 8457, 8470, 8471, 8482,
145
+
146
+ 402, 1423, 1547, 65020,
147
+ 2547, 2553, 2555, 2801,
148
+ 3065, 3647, 6107, 8499,
149
+ 2546,
150
+
151
+ 8304, 185, 178, 179,
152
+ 8585, 8319, 8305,
153
+
154
+ 8709, 8730, 8734,
155
+ ];
156
+ for (let i = 161; i < 168; i++) {
157
+ addCBase.push(i);
158
+ }
159
+ for (let i = 187; i < 192; i++) {
160
+ addCBase.push(i);
161
+ }
162
+ for (let i = 8308; i < 8317; i++) {
163
+ addCBase.push(i);
164
+ }
165
+ for (let i = 8528; i < 8576; i++) {
166
+ addCBase.push(i);
167
+ }
168
+ for (let i = 8352; i < 8385; i++) {
169
+ addCBase.push(i);
170
+ }
171
+ for (let i = 8320; i < 8333; i++) {
172
+ addCBase.push(i);
173
+ }
174
+ for (let i = 8712; i < 8718; i++) {
175
+ addCBase.push(i);
176
+ }
177
+ let i = 65;
178
+ for (const cde of addCBase) {
179
+ chrsBase[i++] = _JSSC._char(cde);
180
+ if (i === 91) {
181
+ i = 97;
182
+ } else if (i === 123) {
183
+ i = 128;
184
+ }
185
+ }
186
+ return chrsBase
187
+ };
188
+ _JSSC._BASE = [
189
+ 167, 8722, 8451, 169, 8211, 215, 247,
190
+ 8457, 174, 8470, 8482, 8471, 8249,
191
+ 8250, 171, 187, 8242, 8245, 8216,
192
+ 8217, 8218, 8219, 8243, 8246, 8220,
193
+ 8221, 8222, 8223, 8226, 182, 8267,
194
+ 8270, 8240, 8241, 9834, 183, 8228,
195
+ 8229, 8230, 161, 191, 8252, 8264
196
+ ];
197
+ _JSSC._MATH = [
198
+ 8544, 8547, 8550, 8553, 8556, 8572,
199
+ 8545, 8548, 8551, 8554, 8557, 8573,
200
+ 8546, 8549, 8552, 8555, 8558, 8574,
201
+ 8560, 8563, 8566, 8569, 8559, 8575,
202
+ 8561, 8564, 8567, 8570, 8562, 8565,
203
+ 8568, 8571, 8712, 8715, 8713, 8716,
204
+ 8730, 8721, 8734, 8804, 8805
205
+ ];
206
+ _JSSC._CURR = [
207
+ 165, 3647, 8363, 8361, 1423, 8364,
208
+ 8377, 8362, 8378, 8353, 8358, 163,
209
+ 8381, 8354, 8369, 2547, 8370, 8366,
210
+ 8376, 8382, 8357, 6107, 8360, 8372,
211
+ 8373, 8365, 1547, 2801, 162, 65020,
212
+ 8355, 8383, 8380, 3065, 164, 8384,
213
+ 8379, 402, 8359, 2546, 8371, 8367,
214
+ 8356, 8375, 2553, 8368, 8352, 8499,
215
+ 8374, 2555
216
+ ];
217
+ /*
218
+ ASCII (charsLatin) // English, Spanish, Portuguese, French, German
219
+ */
220
+ _JSSC._RU = function(baseOrLatin) {
221
+ const chrsBase = baseOrLatin();
222
+ let maxI = 0;
223
+ for (let i = 1040; i < 1104; i++) {
224
+ const curI = i - 912;
225
+ chrsBase[curI] = _JSSC._char(i); /* Unicode 0410 - 044F */
226
+ maxI = Math.max(maxI, curI);
227
+ }
228
+ chrsBase[maxI + 1] = _JSSC._char(1025); /* Unicode 0401 ( Ё ) */
229
+ chrsBase[maxI + 2] = _JSSC._char(1105); /* Unicode 0451 ( ё ) */
230
+ return chrsBase;
231
+ };
232
+ _JSSC.RU = function() { /* Russian, Ukrainian, Belarusian, Kazakh */
233
+ const chrsBase = _JSSC._RU(charsBase);
234
+ let i = 65;
235
+ for (const char of _JSSC._BASE.concat(_JSSC._MATH, [
236
+ 105, 239, 1028, 1030, 1031, 1108, 1110, 1111,
237
+ 1118, 1038,
238
+ 1241, 1181, 1171, 1199, 1201, 1179, 1257, 1211, 1240, 1186, 1170, 1198, 1200, 1178, 1256, 1210,
239
+ 8381, 8364, 165, 8376, 8372
240
+ ])) {
241
+ chrsBase[i++] = _JSSC._char(char);
242
+ if (i === 91) {
243
+ i = 97;
244
+ } else if (i === 123) {
245
+ i = 193;
246
+ }
247
+ }
248
+ chrsBase[110] = 'i';
249
+ chrsBase[111] = 'I';
250
+
251
+ return chrsBase;
252
+ };
253
+ _JSSC.ENRU = function() { /* English, Russian, Ukrainian, Belarusian */
254
+ const chrsBase = _JSSC._RU(charsLatin);
255
+ let i = 194;
256
+ for (const char of _JSSC._BASE.concat([
257
+ 105, 239, 1028, 1030, 1031, 1108, 1110, 1111,
258
+ 1118, 1038,
259
+ 8381, 8364, 165, 8376, 8372, 163, 8380
260
+ ], [
261
+ 215, 247
262
+ ])) {
263
+ chrsBase[i++] = _JSSC._char(char);
264
+ }
265
+ return chrsBase;
266
+ };
267
+ _JSSC.ENKK = function() { /* English, Russian, Kazakh */
268
+ const chrsBase = _JSSC._RU(charsLatin);
269
+ let i = 194;
270
+ for (const char of _JSSC._BASE.concat([
271
+ 1241, 1181, 1171, 1199, 1201, 1179, 1257, 1211, 1240, 1186, 1170, 1198, 1200, 1178, 1256, 1210,
272
+ 8381, 163, 8376
273
+ ])) {
274
+ chrsBase[i++] = _JSSC._char(char);
275
+ }
276
+ return chrsBase;
277
+ };
278
+ _JSSC._HI = function(baseOrLatin) {
279
+ const chrsBase = baseOrLatin();
280
+ for (let i = 2304; i < 2432; i++) {
281
+ chrsBase[i - 2176] = _JSSC._char(i); /* Unicode 0900 - 097F */
282
+ }
283
+ return chrsBase;
284
+ };
285
+ _JSSC._Ind = [
286
+ 8377, 8360, 78, 2547,
287
+ 2404,
288
+ 215, 247,
289
+ ];
290
+ _JSSC.HI = function() { /* Hindi */
291
+ const chrsBase = _JSSC._HI(charsBase);
292
+ let i = 65;
293
+ for (const char of _JSSC._BASE.concat(_JSSC._Ind)) {
294
+ chrsBase[i++] = _JSSC._char(char);
295
+ if (i === 91) {
296
+ i = 97;
297
+ }
298
+ }
299
+ return chrsBase
300
+ };
301
+ _JSSC.ENHI = function() { /* English, Hindi */
302
+ return _JSSC._HI(charsLatin);
303
+ };
304
+ _JSSC._BN = function(baseOrLatin) {
305
+ const chrsBase = baseOrLatin();
306
+ for (let i = 2432; i < 2559; i++) {
307
+ chrsBase[i - 2304] = _JSSC._char(i); /* Unicode 0980 - 09FF */
308
+ }
309
+ chrsBase[255] = _JSSC._char(2404);
310
+ return chrsBase;
311
+ };
312
+ _JSSC.BN = function() { /* Bengali */
313
+ const chrsBase = _JSSC._BN(charsBase);
314
+ let i = 65;
315
+ for (const char of _JSSC._BASE.concat(_JSSC._Ind)) {
316
+ chrsBase[i++] = _JSSC._char(char);
317
+ if (i === 91) {
318
+ i = 97;
319
+ }
320
+ }
321
+ return chrsBase;
322
+ };
323
+ _JSSC.ENBN = function() { /* English, Bengali */
324
+ return _JSSC._BN(charsLatin);
325
+ };
326
+ _JSSC.HIBN = function() { /* Hindi, Bengali */
327
+ const chrsBase = {};
328
+ for (let i = 2304; i < 2559; i++) {
329
+ chrsBase[i - 2176 - 128] = _JSSC._char(i);
330
+ }
331
+ chrsBase[255] = ' ';
332
+ return chrsBase;
333
+ };
334
+ _JSSC._JA = [
335
+ [
336
+ 65371, 65373, 65288, 65289, 65339, 65341, 12304, 12305,
337
+ 12289, 65292,
338
+ 12290,
339
+ 12349,
340
+ 12300, 12301, 12302, 12303,
341
+ 12288,
342
+ 12316,
343
+ 65306,
344
+ 65281,
345
+ 65311,
346
+ 12445, 12541,
347
+ 183,
348
+ ],
349
+ [
350
+ 8230, 8229,
351
+ 165,
352
+ ]
353
+ ];
354
+ _JSSC.JA = function() { /* English, Hiragana (Japanese), Katakana (Japanese) */
355
+ const chrsBase = charsLatin();
356
+ let i = 128;
357
+ for (const char of _JSSC._JA[0].concat(
358
+ Array.from({ length : 46 }, (v, j) => j + 12352 ), /* Unicode 3040 - 309F */
359
+ Array.from({ length : 46 }, (v, j) => j + 12448 ), /* Unicode 30A0 - 30FF */
360
+ _JSSC._JA[1], [
361
+ 19968, 20108, 19977,
362
+ 22235, 20116, 20845,
363
+ 19971, 20843, 20061
364
+ ]
365
+ )) {
366
+ chrsBase[i++] = _JSSC._char(char);
367
+ }
368
+ chrsBase[17] = _JSSC._char(21313);
369
+ chrsBase[18] = _JSSC._char(30334);
370
+ chrsBase[19] = _JSSC._char(21315);
371
+ chrsBase[20] = _JSSC._char(19975);
372
+ return chrsBase;
373
+ };
374
+ _JSSC.Telu = function() { /* English, Telugu */
375
+ const chrsBase = charsLatin();
376
+ for (let i = 3073; i < 3184; i++) { /* Unicode 0C01 - 0C6F */
377
+ chrsBase[i - 2945] = _JSSC._char(i);
378
+ }
379
+ let i = 239;
380
+ for (const char of _JSSC._Ind.concat([
381
+ 8364, 0xA3, 0xA2, 0xA5, 0xA7, 0xA9, 0xAE, 8482, 0x2030, 0x2031
382
+ ])) {
383
+ chrsBase[i++] = _JSSC._char(char);
384
+ }
385
+ return chrsBase;
386
+ };
387
+ _JSSC.MR = function() { /* English, Marathi */
388
+ const chrsBase = charsLatin();
389
+ for (let i = 0x900; i < 0x980; i++) {
390
+ chrsBase[i - 2176] = _JSSC._char(i);
391
+ }
392
+ return chrsBase;
393
+ };
394
+ _JSSC.B = function() { /* Baltic */
395
+ const chrsBase = charsLatin();
396
+ for (let i = 0x100; i < 0x17F; i++) {
397
+ chrsBase[i - 128] = _JSSC._char(i);
398
+ }
399
+ chrsBase[255] = _JSSC._char(0x17F); /* U+017F */
400
+ return chrsBase;
401
+ };
402
+ _JSSC.E = function() { /* European */
403
+ const chrsBase = charsLatin();
404
+ for (let i = 0x80; i < 0xFF; i++) {
405
+ chrsBase[i] = _JSSC._char(i);
406
+ }
407
+ chrsBase[255] = _JSSC._char(0x17F); /* U+017F */
408
+ return chrsBase;
409
+ };
410
+ _JSSC.AR = function() { /* Arabic */
411
+ const chrsBase = {};
412
+ for (let i = 0x600; i < 0x6FF; i++) {
413
+ chrsBase[i - 1536] = _JSSC._char(i);
414
+ }
415
+ return chrsBase;
416
+ };
417
+ _JSSC.use = class {
418
+ constructor() {
419
+ let output = {};
420
+ for (const [name, func] of Object.entries(_JSSC)) {
421
+ if (typeof func === 'function' && !name.startsWith('_') && name != 'use') {
422
+ output[name__+name] = func;
423
+ }
424
+ }
425
+ Object.freeze(output);
426
+ return output;
427
+ }
428
+ };
429
+ _JSSC._begin = [
430
+ 'https://', 'http://', 'file://', 'mailto:', 'ftp://', 'data:', 'tel:', 'sms:'
431
+ ];
432
+ Object.freeze(_JSSC.use);
433
+
434
+ function cryptCharCode(
435
+ code, get = false,
436
+ repeatBefore = false, repeatAfter = false,
437
+ beginId = -1, code2 = 0, sequences = false,
438
+ code3 = -1
439
+ ) {
440
+ if (get) {
441
+ const codeBin = decToBin(code, 16);
442
+ const codeSet = codeBin.slice(8,11).split('');
443
+ const codeDec = binToDec(codeBin.slice(11));
444
+ const begid = binToDec(codeBin.slice(5,8));
445
+ return {
446
+ code: codeDec,
447
+ repeatBefore: codeSet[0] === '1',
448
+ repeatAfter: codeSet[1] === '1',
449
+ beginId: codeSet[2] === '1' ? begid : -1,
450
+ code2: binToDec(codeBin.slice(0,4)),
451
+ sequences: codeBin.slice(4,5) === '1',
452
+ code3: codeSet[2] === '0' ? begid : -1,
453
+ bin: codeBin,
454
+ }
455
+ } else {
456
+ const sixteenBits = /* 16-bit Data/Header character */
457
+
458
+ decToBin(code2, 4) + /* Bits 0-3 : code2 */
459
+ (sequences ? '1' : '0') + /* Bit 4 : sequences?|odd? */
460
+ decToBin(beginId >= 0 ? beginId : code3 < 0 ? 0 : code3, 3) + /* Bits 5-7 : beginID | code3 */
461
+ (repeatBefore ? '1' : '0') + /* Bit 8 : inp RLE? | num? */
462
+ (repeatAfter ? '1' : '0') + /* Bit 9 : output RLE? */
463
+ (beginId >= 0 ? '1' : '0') + /* Bit 10 : beginID? */
464
+ decToBin(code, 5); /* Bits 11-15 : code1 */
465
+
466
+ return binToDec(sixteenBits);
467
+ }
468
+ }
469
+ /* Code 1 usage table */
470
+ /* ------------------------------------ */
471
+ /* 00: No Compression */
472
+ /* 01: Two-Digit CharCode Concatenation */
473
+ /* 02: Two-Byte CharCode Concatenation */
474
+ /* 03: Decimal Integer Packing */
475
+ /* 04: Alphabet Encoding */
476
+ /* 05: Character Encoding */
477
+ /* 06: Inline Integer Encoding */
478
+ /* 07: Frequency Map */
479
+ /* 08: URL */
480
+ /* 09: Segmentation */
481
+ /* 10: String Repetition */
482
+ /* 11 - 30: Reserved */
483
+ /* 31: Recursive Compression */
484
+
485
+ const SEQUENCE_MARKER = '\uDBFF'; /* Private Use Area */
486
+
487
+ function findSequences(str, minLength = 2, minCount = 3) {
488
+ const repeats = [];
489
+ const n = str.length;
490
+
491
+ for (let i = 0; i < n - minLength * minCount + 1; i++) {
492
+ for (let len = 2; len <= Math.min(30, Math.floor((n - i) / minCount)); len++) {
493
+ const pattern = str.substr(i, len);
494
+ if (pattern.includes(SEQUENCE_MARKER)) continue;
495
+
496
+ let count = 1;
497
+ for (let j = i + len; j <= n - len; j += len) {
498
+ if (str.substr(j, len) === pattern) {
499
+ count++;
500
+ } else {
501
+ break;
502
+ }
503
+ }
504
+
505
+ if (count >= minCount) {
506
+ const end = i + len * count;
507
+ let overlaps = false;
508
+ for (const r of repeats) {
509
+ if (i < r.end && end > r.start) {
510
+ overlaps = true;
511
+ break;
512
+ }
513
+ }
514
+
515
+ if (!overlaps) {
516
+ repeats.push({
517
+ start: i,
518
+ end: end,
519
+ length: len,
520
+ pattern: pattern,
521
+ count: count,
522
+ saved: (len * count) - (len + 3)
523
+ });
524
+ i = end - 1;
525
+ break;
526
+ }
527
+ }
528
+ }
529
+ }
530
+
531
+ return repeats.sort((a, b) => b.saved - a.saved);
532
+ }
533
+
534
+ function compressSequences(str) {
535
+ if (str.length < 20) return {compressed: str, sequences: false};
536
+
537
+ if (str.includes(SEQUENCE_MARKER)) {
538
+ return {compressed: str, sequences: false};
539
+ }
540
+
541
+ const repeats = findSequences(str, 2, 3);
542
+ if (repeats.length === 0) return {compressed: str, sequences: false};
543
+
544
+ const selected = [];
545
+ let covered = new Array(str.length).fill(false);
546
+
547
+ for (const repeat of repeats) {
548
+ let canUse = true;
549
+ for (let i = repeat.start; i < repeat.end; i++) {
550
+ if (covered[i]) {
551
+ canUse = false;
552
+ break;
553
+ }
554
+ }
555
+
556
+ if (canUse && repeat.saved > 0) {
557
+ selected.push(repeat);
558
+ for (let i = repeat.start; i < repeat.end; i++) {
559
+ covered[i] = true;
560
+ }
561
+ }
562
+ }
563
+
564
+ if (selected.length === 0) return {compressed: str, sequences: false};
565
+
566
+ let result = '';
567
+ let pos = 0;
568
+
569
+ for (const repeat of selected) {
570
+ if (pos < repeat.start) {
571
+ result += str.slice(pos, repeat.start);
572
+ }
573
+
574
+ /* sequence encoding: [marker][length][count][pattern] */
575
+ const lengthChar = String.fromCharCode(Math.min(repeat.length, 30) + 32);
576
+ const countChar = String.fromCharCode(Math.min(repeat.count, 65535) + 32);
577
+ result += SEQUENCE_MARKER + lengthChar + countChar + repeat.pattern;
578
+
579
+ pos = repeat.end;
580
+ }
581
+
582
+ if (pos < str.length) {
583
+ result += str.slice(pos);
584
+ }
585
+
586
+ /* check if it's worth it */
587
+ if (result.length < str.length * 0.9) { /* at least 10% */
588
+ return {compressed: result, sequences: true};
589
+ }
590
+
591
+ return {compressed: str, sequences: false};
592
+ }
593
+
594
+ function decompressSequences(str) {
595
+ let result = '';
596
+ let i = 0;
597
+
598
+ while (i < str.length) {
599
+ if (str.charCodeAt(i) === 0xDBFF) {
600
+ i++;
601
+
602
+ if (i + 2 >= str.length) {
603
+ result += SEQUENCE_MARKER;
604
+ continue;
605
+ }
606
+
607
+ const length = str.charCodeAt(i) - 32;
608
+ const count = str.charCodeAt(i + 1) - 32;
609
+ i += 2;
610
+
611
+ if (i + length > str.length) {
612
+ result += SEQUENCE_MARKER +
613
+ String.fromCharCode(length + 32) +
614
+ String.fromCharCode(count + 32) +
615
+ str.slice(i);
616
+ break;
617
+ }
618
+
619
+ const pattern = str.substr(i, length);
620
+ i += length;
621
+
622
+ for (let j = 0; j < count; j++) {
623
+ result += pattern;
624
+ }
625
+ } else {
626
+ result += str.charAt(i);
627
+ i++;
628
+ }
629
+ }
630
+
631
+ return result;
632
+ }
633
+
634
+ const freqMap = {
635
+ ESCAPE_BYTE: 0xFF,
636
+ TOP_COUNT: 254,
637
+ SPLITTER: " \u200B",
638
+
639
+ compress(text, splitter = this.SPLITTER) {
640
+ const freq = {};
641
+ for (let char of text) {
642
+ freq[char] = (freq[char] || 0) + 1;
643
+ }
644
+
645
+ const topChars = Object.entries(freq)
646
+ .sort((a, b) => b[1] - a[1])
647
+ .slice(0, this.TOP_COUNT)
648
+ .map(entry => entry[0]);
649
+
650
+ const charToIndex = new Map(topChars.map((char, i) => [char, i]));
651
+
652
+ let header = String.fromCharCode(topChars.length) + topChars.join('');
653
+
654
+ let bytes = [];
655
+ for (let char of text) {
656
+ if (charToIndex.has(char)) {
657
+ /* frequent */
658
+ bytes.push(charToIndex.get(char));
659
+ } else {
660
+ /* rare */
661
+ bytes.push(this.ESCAPE_BYTE);
662
+ const code = char.charCodeAt(0);
663
+ bytes.push((code >> 8) & 0xFF);
664
+ bytes.push(code & 0xFF);
665
+ }
666
+ }
667
+
668
+ /* to UTF16 */
669
+ let compressedBody = "";
670
+ for (let i = 0; i < bytes.length; i += 2) {
671
+ const b1 = bytes[i];
672
+ const b2 = (i + 1 < bytes.length) ? bytes[i + 1] : 0x00;
673
+ compressedBody += String.fromCharCode((b1 << 8) | b2);
674
+ }
675
+
676
+ return header + splitter + compressedBody;
677
+ },
678
+
679
+ decompress(compressedText, splitter = this.SPLITTER) {
680
+ const parts = compressedText.split(splitter);
681
+
682
+ if (parts.length < 2) {
683
+ throw new Error(prefix+'Invalid freqMap data: splitter not found');
684
+ }
685
+
686
+ const headerPart = parts[0];
687
+ const bodyPart = parts.slice(1).join(splitter);
688
+
689
+ const topCount = headerPart.charCodeAt(0);
690
+ const topChars = headerPart.substring(1, topCount + 1);
691
+
692
+ let bytes = [];
693
+ for (let i = 0; i < bodyPart.length; i++) {
694
+ const code = bodyPart.charCodeAt(i);
695
+ bytes.push((code >> 8) & 0xFF);
696
+ bytes.push(code & 0xFF);
697
+ }
698
+
699
+ let result = "";
700
+ for (let i = 0; i < bytes.length; i++) {
701
+ const b = bytes[i];
702
+ if (b === this.ESCAPE_BYTE) {
703
+ const charCode = (bytes[i + 1] << 8) | bytes[i + 2];
704
+ result += String.fromCharCode(charCode);
705
+ i += 2;
706
+ } else if (b < topCount) {
707
+ result += topChars[b];
708
+ }
709
+ }
710
+ return result;
711
+ },
712
+
713
+ /**
714
+ * 0 = Fail
715
+ * 1 = Success
716
+ * 2 = Remove last character (Success)
717
+ * @param {string} text
718
+ * @param {string?} splitter
719
+ * @returns {number|[number, number, string, string]}
720
+ */
721
+ test(text, splitter = this.SPLITTER) {
722
+ try {
723
+ if (text.includes(splitter)) return 0;
724
+ const packed = this.compress(text, splitter);
725
+ const unpacked = this.decompress(packed, splitter);
726
+ if (packed.length < text.length) {
727
+ if (unpacked == text) return [1, packed.length, splitter, packed];
728
+ else if (unpacked.slice(0,-1) == text) return [2, packed.length, splitter, packed];
729
+ else return 0;
730
+ }
731
+ return 0;
732
+ } catch (_) {
733
+ return 0;
734
+ }
735
+ }
736
+ };
737
+
738
+ const freqMapSplitters = [
739
+ " \u200B","\u0000",
740
+ "\u001F", "\u0001",
741
+ "\uFFFD", "\u2022",
742
+ "|§|", "\uFEFF"
743
+ ];
744
+
745
+ function segments(str) {
746
+ if (typeof str !== 'string' || str.length === 0) return [];
747
+
748
+ const THRESHOLD = 128;
749
+ const segs = [];
750
+ let currentSeg = str[0];
751
+
752
+ for (let i = 1; i < str.length; i++) {
753
+ const prevCode = str.charCodeAt(i - 1);
754
+ const currCode = str.charCodeAt(i);
755
+
756
+ if (Math.abs(currCode - prevCode) > THRESHOLD) {
757
+ segs.push(currentSeg);
758
+ currentSeg = str[i];
759
+ } else {
760
+ currentSeg += str[i];
761
+ }
762
+ }
763
+
764
+ if (currentSeg) segs.push(currentSeg);
765
+
766
+ return segs;
767
+ }
768
+
769
+ async function tryRecursive(base, opts) {
770
+ if (!opts.recursivecompression) return base;
771
+
772
+ let cur = base;
773
+ let depth = 0;
774
+
775
+ while (depth < 15) {
776
+ depth++;
777
+ const next = await compress(cur, {
778
+ ...opts,
779
+ recursivecompression: false
780
+ });
781
+
782
+ if (next.length >= cur.length) break;
783
+
784
+ const dec = await decompress(next, true);
785
+ if (dec !== cur) break;
786
+
787
+ cur = next;
788
+ }
789
+
790
+ if (depth === 0) return null;
791
+
792
+ return (
793
+ charCode(
794
+ cryptCharCode(
795
+ 31,
796
+ false,
797
+ false,
798
+ false,
799
+ -1,
800
+ depth,
801
+ false,
802
+ -1
803
+ )
804
+ ) + cur
805
+ );
806
+ }
807
+
808
+ /**
809
+ * **JavaScript String Compressor - compress function.**
810
+ * @param {string|object|number} input string
811
+ * @param {{segmentation?: boolean, recursiveCompression?: boolean, JUSTC?: boolean}} [options]
812
+ * @returns {Promise<string>} Compressed string
813
+ * @example await compress('Hello, World!');
814
+ * @since 1.0.0
815
+ */
816
+ async function compress(input, options) {
817
+ if (typeof input != 'string' && typeof input != 'object' && typeof input != 'number') throw new Error(prefix+'Invalid input.');
818
+ const opts = {
819
+ segmentation: true,
820
+ recursivecompression: true,
821
+ justc: JUSTC ? true : false,
822
+ };
823
+
824
+ /* Read options */
825
+ if (options) {
826
+ if (typeof options != 'object') throw new Error(prefix+'Invalid options input.');
827
+ for (const [key, value] of Object.entries(options)) {
828
+ if (typeof value == 'undefined') continue;
829
+ if (typeof value != 'boolean') throw new Error(prefix+'Invalid options input.');
830
+ if (key.toLowerCase() in opts) {
831
+ opts[key.toLowerCase()] = value;
832
+ continue;
833
+ }
834
+ console.warn(prefix+`Unknown option: "${key}".`);
835
+ }
836
+ }
837
+
838
+ const originalInput = input;
839
+ let str = input;
840
+ let isNum = false;
841
+
842
+ if (typeof str === 'number') {
843
+ isNum = true;
844
+ str = str.toString();
845
+ if (str.includes('.')) throw new Error(prefix+'Invalid input.');
846
+ }
847
+
848
+ let repeatBefore = false;
849
+ function repeatChars(txt) {
850
+ return txt.replace(/(.)\1+/g, ( a , b ) => b + a.length);
851
+ }
852
+
853
+ let beginId = -1;
854
+ if (typeof str == 'string') for (const begin of _JSSC._begin) {
855
+ if (str.startsWith(begin)) {
856
+ beginId = _JSSC._begin.indexOf(begin);
857
+ str = str.slice(begin.length);
858
+ break;
859
+ }
860
+ }
861
+ let code3 = -1;
862
+ async function toJUSTC(obj) {
863
+ try {
864
+ const result = await JUSTC.stringify(obj);
865
+ if (result && typeof result.then === 'function') {
866
+ return await result;
867
+ }
868
+ return result;
869
+ } catch (_) {
870
+ /* Browsers */
871
+ await JUSTC.initialize();
872
+ return JUSTC.stringify(obj);
873
+ }
874
+ }
875
+ if (beginId == -1) {
876
+ /* JSON Array (as object) */
877
+ if (typeof str == 'object' && Array.isArray(str)) {
878
+ str = JSON.stringify(str).slice(1,-1);
879
+ code3 = 4;
880
+ } else
881
+ /* JSON Object (as object) */
882
+ if (typeof str == 'object') try {
883
+ if (opts.justc) {
884
+ const JUSTCobj = await toJUSTC(str);
885
+ str = JUSTCobj;
886
+ code3 = 2;
887
+ } else {
888
+ str = JSON.stringify(str);
889
+ code3 = 6;
890
+ }
891
+ } catch (error) {
892
+ const msg = new Error(prefix+'Invalid input.');
893
+ throw new AggregateError([msg, error], msg.message);
894
+ } else
895
+ /* JSON Object (as string) */
896
+ try {
897
+ const obj = JSON.parse(str);
898
+ if (!Array.isArray(obj)) {
899
+
900
+ const JUSTCobj = opts.justc ? await toJUSTC(obj) : false;
901
+
902
+ if (JUSTCobj && JUSTCobj.length < str.length && str == JSON.stringify(obj)) {
903
+ str = JUSTCobj;
904
+ code3 = 1;
905
+ } else {
906
+ str = str.slice(1,-1);
907
+ code3 = 5;
908
+ }
909
+ } else {
910
+ /* JSON Array (as string) */
911
+ str = str.slice(1,-1);
912
+ code3 = 3;
913
+ }} catch (_) {
914
+ }}
915
+
916
+ if (!/\d/.test(str)) {
917
+ str = repeatChars(str);
918
+ repeatBefore = true;
919
+ }
920
+
921
+ function processOutput(output, disableSeq = false) {
922
+ let repeatAfter = false;
923
+ let sequences = false;
924
+
925
+ const hasDigits = /\d/.test(output);
926
+ if (!hasDigits) {
927
+ repeatAfter = true;
928
+ output = repeatChars(output);
929
+ }
930
+
931
+ if (!disableSeq) {
932
+ const compressed = compressSequences(output);
933
+ if (compressed.sequences) {
934
+ sequences = true;
935
+ return [compressed.compressed, repeatAfter, sequences];
936
+ }
937
+ }
938
+
939
+ return [output, repeatAfter, sequences];
940
+ }
941
+
942
+ const safeTry = async (fn) => {
943
+ try {
944
+ return await fn();
945
+ } catch {
946
+ return null;
947
+ }
948
+ };
949
+
950
+ const validate = async (compressed) => {
951
+ try {
952
+ const dec = await decompress(compressed, true);
953
+ return dec === String(originalInput);
954
+ } catch {
955
+ return false;
956
+ }
957
+ };
958
+
959
+ const candidates = [];
960
+
961
+ if (/^\d+$/.test(str)) {
962
+ /* Inline Integer Encoding */
963
+ candidates.push(async () => {
964
+ const out = await (async () => {
965
+ const num = parseInt(str);
966
+ if (num < 15) {
967
+ return charCode(
968
+ cryptCharCode(isNum ? 6 : 0, false, false, false, -1, num + 1, false, code3)
969
+ );
970
+ }
971
+ return null;
972
+ })();
973
+ if (!out) return null;
974
+ if (!(await validate(out))) return null;
975
+ return out;
976
+ });
977
+ /* Decimal Integer Packing */
978
+ candidates.push(async () => {
979
+ const convertNums = {
980
+ 'A': 10,
981
+ 'B': 11,
982
+ 'C': 12,
983
+ 'D': 13,
984
+ 'E': 14
985
+ };
986
+ const inputt = str
987
+ .replaceAll('10', 'A')
988
+ .replaceAll('11', 'B')
989
+ .replaceAll('12', 'C')
990
+ .replaceAll('13', 'D')
991
+ .replaceAll('14', 'E');
992
+ const binOut = [];
993
+ for (const character of inputt.split('')) {
994
+ if (/\d/.test(character)) {
995
+ binOut.push(decToBin(parseInt(character), 4));
996
+ } else {
997
+ binOut.push(decToBin(convertNums[character], 4));
998
+ }
999
+ } let [output, RLE, sequences] = ['', false, false];
1000
+ function binPadStart(bin) {
1001
+ if (bin.length < 16) {
1002
+ const numm = 4 - stringChunks(bin, 4).length;
1003
+ return decToBin(15, 4).repeat(numm)+bin;
1004
+ } else return bin;
1005
+ }
1006
+ for (const character of chunkArray(binOut, 4)) {
1007
+ output += String.fromCharCode(binToDec(binPadStart(character.join(''))));
1008
+ }
1009
+ [output, RLE, sequences] = processOutput(output);
1010
+ output = charCode(cryptCharCode(3, false, isNum, RLE, -1, 0, sequences, code3)) + output;
1011
+ if (!(await validate(output))) return null;
1012
+ return output;
1013
+ });
1014
+ }
1015
+
1016
+ /* Two-Digit CharCode Concatenation */
1017
+ candidates.push(async () => {
1018
+ const strdata = stringCodes(str);
1019
+ if (!(strdata.max === 2 && strdata.min === 2)) return null;
1020
+
1021
+ let chars = strdata.output;
1022
+ let [output, repeatAfter, seq] = ['', false, false];
1023
+ function addChar(codee) {
1024
+ output += String.fromCharCode(codee);
1025
+ }
1026
+ function sliceChars(numbr) {
1027
+ chars = chars.slice(numbr);
1028
+ }
1029
+ while (chars.length > 0) {
1030
+ if (chars.length === 1) {
1031
+ addChar(chars[0]);
1032
+ sliceChars(1);
1033
+ } else if (chars.length < 3) {
1034
+ for (const char of chars) {
1035
+ addChar(char);
1036
+ }
1037
+ sliceChars(chars.length);
1038
+ } else {
1039
+ const a1 = parseInt(String(chars[0]) + String(chars[1]) + String(chars[2]));
1040
+ const a2 = parseInt(String(chars[0]) + String(chars[1]));
1041
+ if (checkChar(a1)) {
1042
+ addChar(a1);
1043
+ sliceChars(3);
1044
+ } else if (checkChar(a2)) {
1045
+ addChar(a2);
1046
+ sliceChars(2);
1047
+ } else {
1048
+ addChar(chars[0]);
1049
+ sliceChars(1);
1050
+ }
1051
+ }
1052
+ }
1053
+ [output, repeatAfter, seq] = processOutput(out);
1054
+ const res = charCode(cryptCharCode(1, false, repeatBefore, repeatAfter, beginId, 0, seq, code3)) + output;
1055
+ if (!(await validate(res))) return null;
1056
+ return res;
1057
+ });
1058
+
1059
+ /* Two-Byte CharCode Concatenation */
1060
+ candidates.push(async () => {
1061
+ const strdata = stringCodes(str);
1062
+ if (strdata.maxCharCode >= 256) return null;
1063
+
1064
+ let [out, repeatAfter, seq] = ['', false, false];
1065
+ for (const pair of stringChunks(str, 2)) {
1066
+ let bin = '';
1067
+ for (const c of pair) bin += decToBin(c.charCodeAt(0), 8);
1068
+ out += String.fromCharCode(binToDec(bin));
1069
+ }
1070
+
1071
+ [out, repeatAfter, seq] = processOutput(out);
1072
+ const res = charCode(cryptCharCode(2, false, repeatBefore, repeatAfter, beginId, 0, seq, code3)) + out;
1073
+ if (!(await validate(res))) return null;
1074
+ return res;
1075
+ });
1076
+
1077
+ /* Character Encoding */
1078
+ candidates.push(async () => {
1079
+ const characterEncodings = new _JSSC.use();
1080
+ const stringArray = str.split('');
1081
+ let useCharacterEncoding;
1082
+ let charEncodingID = NaN;
1083
+
1084
+ for (const [characterEncodingName, characterEncoding] of Object.entries(characterEncodings)) {
1085
+ const table = characterEncoding();
1086
+ table.length = 256;
1087
+ const arrayy = Array.from(table);
1088
+ let usethisone = true;
1089
+ for (const character of stringArray) {
1090
+ if (!arrayy.includes(character)) {
1091
+ usethisone = false;
1092
+ break;
1093
+ }
1094
+ }
1095
+ if (usethisone) {
1096
+ useCharacterEncoding = characterEncoding();
1097
+ charEncodingID = _JSSC._IDs[characterEncodingName.slice(4)];
1098
+ break;
1099
+ }
1100
+ }
1101
+
1102
+ if (useCharacterEncoding) {
1103
+ const reverseCharacterEncoding = {};
1104
+ for (const [charCode, character] of Object.entries(useCharacterEncoding)) {
1105
+ reverseCharacterEncoding[character] = charCode;
1106
+ }
1107
+ const binaryCharCodes = [];
1108
+ const convertCharCodes = [];
1109
+ for (const character of stringArray) {
1110
+ binaryCharCodes.push(decToBin(parseInt(reverseCharacterEncoding[character]), 8));
1111
+ }
1112
+ for (const binCharCodes of chunkArray(binaryCharCodes, 2)) {
1113
+ convertCharCodes.push(binCharCodes.join('').padStart(16, '0'));
1114
+ }
1115
+ let [outputStr, repeatAfter, seq] = ['', false, false];
1116
+ for (const characterCode of convertCharCodes) {
1117
+ outputStr += String.fromCharCode(binToDec(characterCode));
1118
+ }
1119
+
1120
+ [outputStr, repeatAfter, seq] = processOutput(outputStr);
1121
+ outputStr = charCode(cryptCharCode(5, false, repeatBefore, repeatAfter, beginId, charEncodingID, seq, code3)) + outputStr;
1122
+ if (await validate(outputStr)) return outputStr;
1123
+ }
1124
+ return null;
1125
+ });
1126
+
1127
+ /* Alphabet Encoding */
1128
+ candidates.push(async () => {
1129
+ const uniq = [...new Set(str.split('').map(c => c.charCodeAt(0)))];
1130
+ if (uniq.length >= 16) return null;
1131
+
1132
+ let out = uniq.map(c => String.fromCharCode(c)).join('');
1133
+ let buf = [];
1134
+ let [repeatAfter, seq] = [false, false];
1135
+
1136
+ for (const c of str) {
1137
+ buf.push(uniq.indexOf(c.charCodeAt(0)));
1138
+ if (buf.length === 4) {
1139
+ out += String.fromCharCode(binToDec(buf.map(n => decToBin(n, 4)).join('')));
1140
+ buf = [];
1141
+ }
1142
+ }
1143
+
1144
+ if (buf.length) {
1145
+ out += String.fromCharCode(
1146
+ binToDec(buf.map(n => decToBin(n, 4)).join('').padStart(16, '1'))
1147
+ );
1148
+ }
1149
+
1150
+ [out, repeatAfter, seq] = processOutput(out);
1151
+ const res = charCode(cryptCharCode(4, false, repeatBefore, repeatAfter, beginId, uniq.length, seq, code3)) + out;
1152
+ if (!(await validate(res))) return null;
1153
+ return res;
1154
+ });
1155
+
1156
+ /* Frequency Map */
1157
+ candidates.push(async () => {
1158
+ for (const splitter of freqMapSplitters) {
1159
+ const test = freqMap.test(str, splitter);
1160
+ if (!Array.isArray(test)) continue;
1161
+
1162
+ const [, , sp, packed] = test;
1163
+ const code2 = binToDec((test[0] - 1).toString() + decToBin(freqMapSplitters.indexOf(sp), 3));
1164
+ const res = charCode(cryptCharCode(7, false, false, false, -1, code2)) + packed;
1165
+
1166
+ if (await validate(res)) return res;
1167
+ }
1168
+ return null;
1169
+ });
1170
+
1171
+ /* URL */
1172
+ candidates.push(async () => {
1173
+ if (typeof str !== 'string') return null;
1174
+
1175
+ let url;
1176
+ try {
1177
+ url = new URL(_JSSC._begin[beginId] + str);
1178
+ } catch {
1179
+ return null;
1180
+ }
1181
+
1182
+ const originalHref = url.href;
1183
+
1184
+ let hasPercent = /%[0-9A-Fa-f]{2}/.test(originalHref);
1185
+ let hasPunycode = url.hostname.includes('xn--');
1186
+ let hasQuery = !!url.search;
1187
+ let hasFragment = !!url.hash;
1188
+
1189
+ /* normalize */
1190
+ let normalized = originalHref.slice(_JSSC._begin[beginId].length);
1191
+
1192
+ /* punycode to unicode */
1193
+ if (hasPunycode && typeof punycode !== 'undefined') {
1194
+ url.hostname = punycode.toUnicode(url.hostname);
1195
+ normalized = url.href.slice(_JSSC._begin[beginId].length);
1196
+ }
1197
+
1198
+ /* percent to bytes */
1199
+ let bytes = [];
1200
+ for (let i = 0; i < normalized.length; i++) {
1201
+ const ch = normalized[i];
1202
+ if (ch === '%' && i + 2 < normalized.length) {
1203
+ const hex = normalized.slice(i + 1, i + 3);
1204
+ if (/^[0-9A-Fa-f]{2}$/.test(hex)) {
1205
+ bytes.push(parseInt(hex, 16));
1206
+ i += 2;
1207
+ continue;
1208
+ }
1209
+ }
1210
+ bytes.push(normalized.charCodeAt(i));
1211
+ }
1212
+
1213
+ let odd = bytes.length & 1;
1214
+ if (odd) bytes.push(0);
1215
+
1216
+ /* bytes to UTF16 */
1217
+ let out = '';
1218
+ for (let i = 0; i < bytes.length; i += 2) {
1219
+ out += String.fromCharCode(
1220
+ (bytes[i] << 8) | (bytes[i + 1] ?? 0)
1221
+ );
1222
+ }
1223
+
1224
+ let code2 =
1225
+ (hasPercent ? 1 : 0) |
1226
+ (hasPunycode ? 2 : 0) |
1227
+ (hasQuery ? 4 : 0) |
1228
+ (hasFragment ? 8 : 0);
1229
+
1230
+ let repeatAfter = false;
1231
+ [out, repeatAfter,] = processOutput(out, true);
1232
+
1233
+ const res =
1234
+ charCode(
1235
+ cryptCharCode(
1236
+ 8,
1237
+ false,
1238
+ repeatBefore,
1239
+ repeatAfter,
1240
+ beginId,
1241
+ code2,
1242
+ odd,
1243
+ code3
1244
+ )
1245
+ ) + out;
1246
+
1247
+ if (!(await validate(res))) return null;
1248
+ return res;
1249
+ });
1250
+
1251
+ /* Segmentation */
1252
+ if (opts.segmentation) candidates.push(async () => {
1253
+ const segs = segments(str);
1254
+
1255
+ if (segs.length < 2) return null;
1256
+
1257
+ let out = segs.length - 2 < 15 ? '' : String.fromCharCode(segs.length - 2);
1258
+
1259
+ for (const seg of segs) {
1260
+ const segOpts = {
1261
+ ...opts,
1262
+ segmentation: false
1263
+ };
1264
+ const compressed = await compress(seg, segOpts);
1265
+
1266
+ out += String.fromCharCode(seg.length);
1267
+ out += compressed;
1268
+ }
1269
+
1270
+ const res =
1271
+ charCode(
1272
+ cryptCharCode(
1273
+ 9,
1274
+ false,
1275
+ repeatBefore,
1276
+ opts.justc,
1277
+ beginId,
1278
+ Math.min(segs.length - 2, 15),
1279
+ opts.recursivecompression,
1280
+ code3
1281
+ )
1282
+ ) + out;
1283
+
1284
+ if (!(await validate(res))) return null;
1285
+ return res;
1286
+ });
1287
+
1288
+ /* String Repetition */
1289
+ const rcheck = str.match(/^(.{1,7}?)(?:\1)+$/);
1290
+ if (rcheck) candidates.push(async () => {
1291
+ const main = rcheck[1];
1292
+ const count = str.length / main.length;
1293
+ if (Math.floor(count) != count || count < 1 || count > 65535 + 15) return null;
1294
+ let [out, repeatAfter, seq] = ['', false, false];
1295
+ [out, repeatAfter, seq] = processOutput(main);
1296
+
1297
+ const res =
1298
+ charCode(
1299
+ cryptCharCode(
1300
+ 10,
1301
+ false,
1302
+ repeatBefore,
1303
+ repeatAfter,
1304
+ beginId,
1305
+ Math.min(count - 1, 15),
1306
+ seq,
1307
+ code3
1308
+ )
1309
+ ) + (
1310
+ (count - 1) > 14 ? String.fromCharCode(count - 15) : ''
1311
+ ) + out;
1312
+
1313
+ if (!(await validate(res))) return null;
1314
+ return res;
1315
+ });
1316
+
1317
+ /* run all */
1318
+ const results = (await Promise.all(candidates.map(fn => safeTry(fn))))
1319
+ .filter(r => typeof r === 'string' && r.length <= String(str).length);
1320
+
1321
+ let best;
1322
+ if (!results.length) {
1323
+ let [repeatAfter, sequences] = [false, false];
1324
+ const savedStr = str;
1325
+ [str, repeatAfter, sequences] = processOutput(str);
1326
+ if (await validate(str)) best = charCode(cryptCharCode(0, false, repeatBefore, repeatAfter, beginId, 0, sequences, code3)) + str;
1327
+ else best = charCode(cryptCharCode(0, false, repeatBefore, false, beginId, 0, false, code3)) + savedStr;
1328
+ } else best = results.reduce((a, b) => (b.length < a.length ? b : a));
1329
+
1330
+ if (opts.recursivecompression) try {
1331
+ for (const r of results) {
1332
+ const rc = await tryRecursive(r, opts);
1333
+ if (rc && rc.length <= best.length && await validate(rc)) {
1334
+ best = rc;
1335
+ }
1336
+ }
1337
+ } catch (_){}
1338
+ return best;
1339
+ }
1340
+
1341
+ function characterEncodings(id, realstr) {
1342
+ const strcode2charencoding = {};
1343
+ for (const [name, code] of Object.entries(_JSSC._IDs)) {
1344
+ strcode2charencoding[code] = name;
1345
+ }
1346
+ const possibleCharEncoding = strcode2charencoding[id];
1347
+ if (possibleCharEncoding) {
1348
+ const characterEncodings_ = new _JSSC.use();
1349
+ const characterEncoding = characterEncodings_[name__+possibleCharEncoding]();
1350
+ let output = '';
1351
+ for (const characters of realstr.split('')) {
1352
+ const characterCode = characters.charCodeAt();
1353
+ const binCode0 = decToBin(characterCode, 0);
1354
+ function binCodeToChar(charr) {
1355
+ return String(characterEncoding[String(binToDec(charr))]);
1356
+ }
1357
+ if (binCode0.length > 8) {
1358
+ const [character1, character2] = stringChunks(decToBin(characterCode, 16), 8);
1359
+ output += binCodeToChar(character1) + binCodeToChar(character2);
1360
+ } else {
1361
+ const character = decToBin(characterCode, 8);
1362
+ output += binCodeToChar(character);
1363
+ }
1364
+ }
1365
+ return output;
1366
+ }
1367
+ }
1368
+
1369
+ async function parseJUSTC(str) {
1370
+ try {
1371
+ const result = JUSTC.parse(str);
1372
+
1373
+ if (result && typeof result.then === 'function') {
1374
+ return await result;
1375
+ }
1376
+
1377
+ return result;
1378
+ } catch (err) {
1379
+ if (typeof window !== 'undefined') { /* Browsers */
1380
+ try {
1381
+ await JUSTC.initialize();
1382
+
1383
+ const retry = JUSTC.parse(str);
1384
+ if (retry && typeof retry.then === 'function') {
1385
+ return await retry;
1386
+ }
1387
+
1388
+ return retry;
1389
+ } catch {
1390
+ return null;
1391
+ }
1392
+ }
1393
+
1394
+ return null;
1395
+ }
1396
+ }
1397
+
1398
+ /**
1399
+ * **JavaScript String Compressor - decompress function.**
1400
+ * @param {string} str Compressed string
1401
+ * @param {boolean?} [stringify] Return only string in any way
1402
+ * @returns {Promise<string|object|number>} Decompressed string/object/integer
1403
+ * @since 1.0.0
1404
+ */
1405
+ async function decompress(str, stringify = false) {
1406
+ if (typeof str != 'string') throw new Error(prefix+'Invalid input.');
1407
+ const strcodes = cryptCharCode((
1408
+ (str.charCodeAt(0) - 32 + 65535) % 65535
1409
+ ), true);
1410
+ const strcode = strcodes.code;
1411
+
1412
+ function repeatChars(txt) {
1413
+ return txt.replace(/(\D)(\d+)/g, (_, g1, g2) => g1.repeat(g2));
1414
+ }
1415
+
1416
+ /* sequences */
1417
+ let realstr = str.slice(1);
1418
+ if (strcodes.sequences && strcode != 8 && strcode != 9) {
1419
+ realstr = decompressSequences(realstr);
1420
+ }
1421
+
1422
+ /* RLE */
1423
+ if (strcodes.repeatAfter && strcode != 9) {
1424
+ realstr = repeatChars(realstr);
1425
+ }
1426
+
1427
+ async function begin(out) {
1428
+ if (strcodes.beginId >= 0) {
1429
+ return _JSSC._begin[strcodes.beginId] + out;
1430
+ } else if (strcodes.code3 == 1 || strcodes.code3 == 2) {
1431
+ /* JSON Object */
1432
+ const result = await parseJUSTC(out);
1433
+ if (result && typeof result.then === 'function') {
1434
+ return JSON.stringify(await result);
1435
+ } else return JSON.stringify(result);
1436
+ } else return out;
1437
+ }
1438
+
1439
+ async function processOutput(out) {
1440
+ let output = out;
1441
+ if (strcodes.repeatBefore && strcode != 3) {
1442
+ output = repeatChars(await begin(out));
1443
+ } else output = await begin(out);
1444
+
1445
+ if ((strcodes.repeatBefore && strcode == 3) || strcode == 30) output = parseInt(output); else { /* Integer */
1446
+ if (strcodes.code3 == 3 || strcodes.code3 == 4) output = '[' + output + ']'; /* JSON Array */
1447
+ else if (strcodes.code3 == 5) output = '{' + output + '}'; /* JSON Object (as string) */
1448
+ if (strcodes.code3 == 2 || strcodes.code3 == 4 || strcodes.code3 == 6) output = JSON.parse(output);} /* JSON Object/Array (as object) */
1449
+
1450
+ if (stringify) {
1451
+ if (typeof output == 'object') output = JSON.stringify(output);
1452
+ else if (typeof output == 'number') output = output.toString();
1453
+ }
1454
+
1455
+ return output;
1456
+ }
1457
+
1458
+ let output = '';
1459
+ switch (strcode) {
1460
+ case 0: case 6:
1461
+ if (strcodes.code2 > 0) return await processOutput(String(strcodes.code2 - 1));
1462
+ return await processOutput(realstr);
1463
+ case 1:
1464
+ function addChar(cde) {
1465
+ output += String.fromCharCode(cde);
1466
+ }
1467
+ for (const char of realstr.split('')) {
1468
+ const charcde = String(char.charCodeAt(0));
1469
+ if (charcde.length > 2) {
1470
+ const charcds = stringChunks(charcde, 2);
1471
+ for (const chrcode of charcds) {
1472
+ addChar(parseInt(chrcode));
1473
+ }
1474
+ } else {
1475
+ addChar(char.charCodeAt(0));
1476
+ }
1477
+ }
1478
+ return await processOutput(output);
1479
+ case 2:
1480
+ function toChar(binCode) {
1481
+ return String.fromCharCode(binToDec(binCode));
1482
+ }
1483
+ for (const char of realstr.split('')) {
1484
+ const binCode = decToBin(char.charCodeAt(0), 16);
1485
+ const binCode0 = decToBin(char.charCodeAt(0), 0);
1486
+ if (binCode0.length > 8) {
1487
+ const [bin1, bin2] = stringChunks(binCode, 8);
1488
+ output += toChar(bin1) + toChar(bin2);
1489
+ } else {
1490
+ const binCode8 = decToBin(char.charCodeAt(0), 8);
1491
+ output += toChar(binCode8);
1492
+ }
1493
+ }
1494
+ return await processOutput(output);
1495
+ case 3:
1496
+ for (const char of realstr.split('')) {
1497
+ const binCodes = stringChunks(decToBin(char.charCodeAt(0), 16), 4);
1498
+ for (const binCode of binCodes) {
1499
+ const numm = binToDec(binCode);
1500
+ if (numm != 15) {
1501
+ output += numm.toString(10);
1502
+ }
1503
+ }
1504
+ }
1505
+ return await processOutput(output);
1506
+ case 4:
1507
+ const chars = [];
1508
+ for (const char of realstr.slice(0, strcodes.code2).split('')) {
1509
+ chars.push(char);
1510
+ }
1511
+ for (const char of realstr.slice(strcodes.code2).split('')) {
1512
+ const binCodes = stringChunks(decToBin(char.charCodeAt(0), 16), 4);
1513
+ for (const binCode of binCodes) {
1514
+ if (binCode != '1111') {
1515
+ const numm = binToDec(binCode);
1516
+ output += chars[numm];
1517
+ }
1518
+ }
1519
+ }
1520
+ return await processOutput(output);
1521
+ case 5:
1522
+ const decoded = characterEncodings(strcodes.code2, realstr);
1523
+ if (decoded) {
1524
+ return await processOutput(decoded);
1525
+ } else throw new Error(prefix+'Invalid compressed string');
1526
+ case 7:
1527
+ const splitter = freqMapSplitters[binToDec(decToBin(strcodes.code2).slice(1))];
1528
+ output = freqMap.decompress(realstr, splitter);
1529
+ if (parseInt(decToBin(strcodes.code2).slice(0,1)) == 1) output = output.slice(0,-1);
1530
+ return await processOutput(output);
1531
+ case 8: {
1532
+ let bytes = [];
1533
+ for (const ch of realstr) {
1534
+ const c = ch.charCodeAt(0);
1535
+ bytes.push((c >> 8) & 0xFF, c & 0xFF);
1536
+ }
1537
+ if (strcodes.sequences) bytes.pop();
1538
+
1539
+ let out = '';
1540
+ for (const b of bytes) {
1541
+ out += String.fromCharCode(b);
1542
+ }
1543
+
1544
+ /* percent restore if needed */
1545
+ if (strcodes.code2 & 1) {
1546
+ out = out.replace(
1547
+ /[\x00-\x20\x7F-\xFF]/g,
1548
+ c => '%' + c.charCodeAt(0).toString(16).padStart(2, '0').toUpperCase()
1549
+ );
1550
+ }
1551
+
1552
+ /* punycode restore */
1553
+ if (strcodes.code2 & 2 && typeof punycode !== 'undefined') {
1554
+ const u = new URL(out);
1555
+ u.hostname = punycode.toASCII(u.hostname);
1556
+ out = u.href;
1557
+ }
1558
+
1559
+ return await processOutput(out);}
1560
+ case 9: {
1561
+ let idx = 0;
1562
+ const segCount = strcodes.code2 < 15 ? strcodes.code2 + 2 : realstr.charCodeAt(idx++) + 2;
1563
+ let out = '';
1564
+
1565
+ for (let i = 0; i < segCount; i++) {
1566
+ const len = realstr.charCodeAt(idx++);
1567
+ const segmentCompressed = realstr.slice(idx);
1568
+
1569
+ const seg = (await decompress(
1570
+ segmentCompressed, true
1571
+ )).slice(0, len);
1572
+
1573
+ out += seg;
1574
+ idx += (await compress(seg, {segmentation: false, justc: strcodes.repeatAfter, recursivecompression: strcodes.sequences})).length;
1575
+ }
1576
+
1577
+ return await processOutput(out);}
1578
+ case 10:
1579
+ const sliceChar = strcodes.code2 == 15;
1580
+ const repeatCount = sliceChar ? realstr.charCodeAt(0) + 15 : strcodes.code2;
1581
+ if (sliceChar) realstr = realstr.slice(1);
1582
+ return await processOutput(realstr.repeat(repeatCount));
1583
+ case 31: {
1584
+ let out = realstr;
1585
+ const depth = strcodes.code2;
1586
+
1587
+ for (let i = 0; i < depth; i++) {
1588
+ const first = out.charCodeAt(0) - 32;
1589
+ const meta = cryptCharCode(first, true);
1590
+
1591
+ if (meta.code === 31) {
1592
+ throw new Error(prefix+'Attempt to nested recursive compression');
1593
+ }
1594
+
1595
+ out = await decompress(out, true);
1596
+ }
1597
+
1598
+ return out;
1599
+ }
1600
+ default:
1601
+ throw new Error(prefix+'Invalid compressed string');
1602
+ }
1603
+ }
1604
+
1605
+ var index = {
1606
+ compress,
1607
+ decompress,
1608
+ get [Symbol.toStringTag]() {
1609
+ return name__;
1610
+ }
1611
+ };
1612
+
1613
+ exports.compress = compress;
1614
+ exports.decompress = decompress;
1615
+ exports.default = index;