bitaboom 1.1.1 → 1.3.0

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/README.md CHANGED
@@ -176,6 +176,22 @@ convertUrduSymbolsToArabic('ھذا');
176
176
 
177
177
  ---
178
178
 
179
+ ### `ensureSpaceBeforeBrackets`
180
+
181
+ Ensures there is exactly one space before parentheses that follow non-whitespace characters. Normalizes multiple spaces to a single space.
182
+
183
+ #### Example:
184
+
185
+ ```javascript
186
+ ensureSpaceBeforeBrackets('text(note)');
187
+ // Output: 'text (note)'
188
+
189
+ ensureSpaceBeforeBrackets('text (note)');
190
+ // Output: 'text (note)'
191
+ ```
192
+
193
+ ---
194
+
179
195
  ### `extractInitials`
180
196
 
181
197
  Extracts initials from the input string, typically for names or titles.
@@ -227,6 +243,22 @@ insertLineBreaksAfterPunctuation('Text.');
227
243
 
228
244
  ---
229
245
 
246
+ ### `isBalanced`
247
+
248
+ Checks if both quotes and brackets are balanced in a string. A string is considered balanced when all double quotes have matching pairs (even count) and all brackets (parentheses, square brackets, curly braces) are properly matched and nested.
249
+
250
+ #### Example:
251
+
252
+ ```javascript
253
+ isBalanced('He said "Hello (world)!"');
254
+ // Output: true
255
+
256
+ isBalanced('He said "Hello (world!"');
257
+ // Output: false (unbalanced quote)
258
+ ```
259
+
260
+ ---
261
+
230
262
  ### `isJsonStructureValid`
231
263
 
232
264
  Checks if a given string resembles a JSON object with numeric or quoted keys and values that are single or double quoted. Useful for detecting malformed JSON-like structures that can be fixed.
@@ -394,6 +426,22 @@ removeNumbersAndDashes('ABC 123-Xyz');
394
426
 
395
427
  ---
396
428
 
429
+ ### `removeRedundantPunctuation`
430
+
431
+ Removes redundant punctuation marks that follow Arabic question marks or exclamation marks. This function cleans up text by removing periods (.) or Arabic commas (،) that immediately follow Arabic question marks (؟) or exclamation marks (!).
432
+
433
+ #### Example:
434
+
435
+ ```javascript
436
+ removeRedundantPunctuation('كيف حالك؟.');
437
+ // Output: 'كيف حالك؟'
438
+
439
+ removeRedundantPunctuation('ممتاز!،');
440
+ // Output: 'ممتاز!'
441
+ ```
442
+
443
+ ---
444
+
397
445
  ### `removeSingleDigitReferences`
398
446
 
399
447
  Removes single digit references like (1), «2», [3] from the text.
@@ -433,15 +481,21 @@ removeSolitaryArabicLetters('ب ا الكلمات ت');
433
481
 
434
482
  ---
435
483
 
436
- ### `removeTatwil`
484
+ ### `removeTatwil` (Updated)
437
485
 
438
- Removes tatweel characters from Arabic text while preserving the Hijri years.
486
+ Removes tatweel characters while preserving dates references and numbered list items. Example: "1435/3/29 هـ" remains as "1435/3/29 هـ" but "أبـــتِـــكَةُ" becomes "أبتِكَةُ". Also preserves tatweels in numbered list items like "3 ـ item".
439
487
 
440
488
  #### Example:
441
489
 
442
490
  ```javascript
443
491
  removeTatwil('أبـــتِـــكَةُ');
444
492
  // Output: 'أبتِكَةُ'
493
+
494
+ removeTatwil('1435/3/29 هـ');
495
+ // Output: '1435/3/29 هـ' (unchanged)
496
+
497
+ removeTatwil('3 ـ وشريط');
498
+ // Output: '3 ـ وشريط' (unchanged)
445
499
  ```
446
500
 
447
501
  ---
@@ -470,6 +524,22 @@ replaceAlifMaqsurah('رؤيى');
470
524
 
471
525
  ---
472
526
 
527
+ ### `replaceDoubleBracketsWithArrows`
528
+
529
+ Replaces double parentheses with single arrow quotation marks. Converts `((text))` format to `«text»` format, handling optional spaces inside the brackets.
530
+
531
+ #### Example:
532
+
533
+ ```javascript
534
+ replaceDoubleBracketsWithArrows('((text))');
535
+ // Output: '«text»'
536
+
537
+ replaceDoubleBracketsWithArrows('(( spaced text ))');
538
+ // Output: '«spaced text»'
539
+ ```
540
+
541
+ ---
542
+
473
543
  ### `replaceEnglishPunctuationWithArabic`
474
544
 
475
545
  Replaces English punctuation marks (e.g., ? and ;) with their Arabic equivalents.
@@ -584,3 +654,57 @@ stripZeroWidthCharacters('يَخْلُوَ ‏.');
584
654
  ```
585
655
 
586
656
  ---
657
+
658
+ ### `truncate`
659
+
660
+ Truncates a string to a specified length, adding an ellipsis if truncated.
661
+
662
+ #### Example:
663
+
664
+ ```javascript
665
+ truncate('The quick brown fox jumps over the lazy dog', 20);
666
+ // Output: 'The quick brown fox…'
667
+
668
+ truncate('Short text', 50);
669
+ // Output: 'Short text'
670
+ ```
671
+
672
+ ---
673
+
674
+ ### `truncateMiddle`
675
+
676
+ Truncates a string from the middle, preserving both the beginning and end portions.
677
+
678
+ #### Example:
679
+
680
+ ```javascript
681
+ truncateMiddle('The quick brown fox jumps right over the lazy dog', 20);
682
+ // Output: 'The quick bro…zy dog'
683
+
684
+ truncateMiddle('The quick brown fox jumps right over the lazy dog', 25, 8);
685
+ // Output: 'The quick brown …lazy dog'
686
+
687
+ truncateMiddle('Short text', 50);
688
+ // Output: 'Short text'
689
+ ```
690
+
691
+ ---
692
+
693
+ ### `unescapeSpaces`
694
+
695
+ Unescapes backslash-escaped spaces and trims whitespace from both ends. Commonly used to clean file paths that have been escaped when pasted into terminals.
696
+
697
+ #### Example:
698
+
699
+ ```javascript
700
+ unescapeSpaces('My\\ Folder\\ Name');
701
+ // Output: 'My Folder Name'
702
+
703
+ unescapeSpaces(' /path/to/My\\ Document.txt ');
704
+ // Output: '/path/to/My Document.txt'
705
+
706
+ unescapeSpaces('regular text');
707
+ // Output: 'regular text'
708
+ ```
709
+
710
+ ---
package/dist/index.d.ts CHANGED
@@ -57,7 +57,7 @@ export const removeSingularCodes: (text: string) => string;
57
57
  */
58
58
  export const removeSolitaryArabicLetters: (text: string) => string;
59
59
  /**
60
- * Removes tatweel characters while preserving dates references.
60
+ * Removes tatweel characters while preserving dates references and numbered list items.
61
61
  * Example: "1435/3/29 هـ" remains as "1435/3/29 هـ" but "أبـــتِـــكَةُ" becomes "أبتِكَةُ"
62
62
  * @param text The text to format.
63
63
  * @returns The modified text with the tatweel characters removed.
@@ -224,6 +224,13 @@ export const condenseUnderscores: (text: string) => string;
224
224
  * @returns {string} - The modified text with condensed brackets.
225
225
  */
226
226
  export const doubleToSingleBrackets: (text: string) => string;
227
+ /**
228
+ * Replaces double parentheses single a single arrow variation.
229
+ * Example: '((text))' becomes '«text»'.
230
+ * @param {string} text - The input text to apply the rule to.
231
+ * @returns {string} - The modified text with condensed brackets.
232
+ */
233
+ export const replaceDoubleBracketsWithArrows: (text: string) => string;
227
234
  /**
228
235
  * Formats a multiline string by joining sentences and maintaining footnotes on their own lines.
229
236
  * Footnotes are identified by Arabic and English numerals.
@@ -246,6 +253,30 @@ export const normalizeSlashInReferences: (text: string) => string;
246
253
  * @returns {string} - The modified text with reduced spaces.
247
254
  */
248
255
  export const normalizeSpaces: (text: string) => string;
256
+ /**
257
+ * Ensures at most 1 space exists before any word before brackets.
258
+ * Adds a space if there isn't one, or reduces multiple spaces to one.
259
+ * @param {string} text - The input text to modify
260
+ * @returns {string} - The modified text with proper spacing before brackets
261
+ */
262
+ export const ensureSpaceBeforeBrackets: (text: string) => string;
263
+ /**
264
+ * Removes redundant punctuation marks that follow Arabic question marks or exclamation marks.
265
+ * This function cleans up text by removing periods (.) or Arabic commas (،) that immediately
266
+ * follow Arabic question marks (؟) or exclamation marks (!), as they are considered redundant
267
+ * in proper Arabic punctuation.
268
+ *
269
+ * @param text - The Arabic text to clean up
270
+ * @returns The text with redundant punctuation removed
271
+ *
272
+ * @example
273
+ * ```typescript
274
+ * removeRedundantPunctuation('كيف حالك؟.') // Returns: 'كيف حالك؟'
275
+ * removeRedundantPunctuation('ممتاز!،') // Returns: 'ممتاز!'
276
+ * removeRedundantPunctuation('هذا جيد.') // Returns: 'هذا جيد.' (unchanged)
277
+ * ```
278
+ */
279
+ export const removeRedundantPunctuation: (text: string) => string;
249
280
  /**
250
281
  * Removes spaces inside brackets, parentheses, or square brackets.
251
282
  * Example: '( a b )' becomes '(a b)'.
@@ -320,6 +351,27 @@ export const isJsonStructureValid: (str: string) => boolean;
320
351
  * console.log(result); // ["This is", "a part of the", "string and"]
321
352
  */
322
353
  export const splitByQuotes: (query: string) => string[];
354
+ /**
355
+ * Checks if both quotes and brackets are balanced in a string.
356
+ * This function combines quote balance checking and bracket balance checking
357
+ * to ensure the entire string has properly balanced punctuation.
358
+ *
359
+ * A string is considered balanced when:
360
+ * - All double quotes have matching pairs (even count)
361
+ * - All brackets (parentheses, square brackets, curly braces) are properly matched and nested
362
+ *
363
+ * @param str - The string to check for balanced quotes and brackets
364
+ * @returns True if both quotes and brackets are balanced, false otherwise
365
+ *
366
+ * @example
367
+ * ```typescript
368
+ * isBalanced('He said "Hello (world)!"') // Returns: true
369
+ * isBalanced('He said "Hello (world!"') // Returns: false (unbalanced quote)
370
+ * isBalanced('He said "Hello (world)"') // Returns: false (unbalanced quote)
371
+ * isBalanced('Hello (world) [test]') // Returns: true
372
+ * ```
373
+ */
374
+ export const isBalanced: (str: string) => boolean;
323
375
  /**
324
376
  * Removes various symbols, part references, and numerical markers from the text.
325
377
  * Example: '(1) (2/3)' becomes ''.
@@ -376,6 +428,64 @@ export const removeSingleDigitReferences: (text: string) => string;
376
428
  * @returns {string} - The modified text with URLs removed.
377
429
  */
378
430
  export const removeUrls: (text: string) => string;
431
+ /**
432
+ * Truncates a string to a specified length, adding an ellipsis if truncated.
433
+ *
434
+ * @param val - The string to truncate
435
+ * @param n - Maximum length of the string (default: 150)
436
+ * @returns The truncated string with ellipsis if needed, otherwise the original string
437
+ *
438
+ * @example
439
+ * ```javascript
440
+ * truncate('The quick brown fox jumps over the lazy dog', 20);
441
+ * // Output: 'The quick brown fox…'
442
+ *
443
+ * truncate('Short text', 50);
444
+ * // Output: 'Short text'
445
+ * ```
446
+ */
447
+ export const truncate: (val: string, n?: number) => string;
448
+ /**
449
+ * Truncates a string from the middle, preserving both the beginning and end portions.
450
+ *
451
+ * @param text - The string to truncate
452
+ * @param maxLength - Maximum length of the resulting string (default: 50)
453
+ * @param endLength - Number of characters to preserve at the end (default: 1/3 of maxLength, minimum 3)
454
+ * @returns The truncated string with ellipsis in the middle if needed, otherwise the original string
455
+ *
456
+ * @example
457
+ * ```javascript
458
+ * truncateMiddle('The quick brown fox jumps right over the lazy dog', 20);
459
+ * // Output: 'The quick bro…zy dog'
460
+ *
461
+ * truncateMiddle('The quick brown fox jumps right over the lazy dog', 25, 8);
462
+ * // Output: 'The quick brown …lazy dog'
463
+ *
464
+ * truncateMiddle('Short text', 50);
465
+ * // Output: 'Short text'
466
+ * ```
467
+ */
468
+ export const truncateMiddle: (text: string, maxLength?: number, endLength?: number) => string;
469
+ /**
470
+ * Unescapes backslash-escaped spaces and trims whitespace from both ends.
471
+ * Commonly used to clean file paths that have been escaped when pasted into terminals.
472
+ *
473
+ * @param input - The string to unescape and clean
474
+ * @returns The cleaned string with escaped spaces converted to regular spaces and trimmed
475
+ *
476
+ * @example
477
+ * ```javascript
478
+ * unescapeSpaces('My\\ Folder\\ Name');
479
+ * // Output: 'My Folder Name'
480
+ *
481
+ * unescapeSpaces(' /path/to/My\\ Document.txt ');
482
+ * // Output: '/path/to/My Document.txt'
483
+ *
484
+ * unescapeSpaces('regular text');
485
+ * // Output: 'regular text'
486
+ * ```
487
+ */
488
+ export const unescapeSpaces: (input: string) => string;
379
489
  /**
380
490
  * Replaces common Arabic prefixes (like 'Al-', 'Ar-', 'Ash-', etc.) with 'al-' in the text.
381
491
  * Handles different variations of prefixes such as Ash- and Al- but not when the second word
package/dist/main.js CHANGED
@@ -2,173 +2,182 @@
2
2
  function $parcel$export(e, n, v, s) {
3
3
  Object.defineProperty(e, n, {get: v, set: s, enumerable: true, configurable: true});
4
4
  }
5
- var $28624456cd7e4cb8$exports = {};
5
+ var $798f85a7713a6ff1$exports = {};
6
6
 
7
- $parcel$export($28624456cd7e4cb8$exports, "cleanExtremeArabicUnderscores", () => $28624456cd7e4cb8$export$60dc7fb96c441688);
8
- $parcel$export($28624456cd7e4cb8$exports, "convertUrduSymbolsToArabic", () => $28624456cd7e4cb8$export$dcf00cfaf31fd188);
9
- $parcel$export($28624456cd7e4cb8$exports, "fixTrailingWow", () => $28624456cd7e4cb8$export$6c58e29008d10c1d);
10
- $parcel$export($28624456cd7e4cb8$exports, "addSpaceBetweenArabicTextAndNumbers", () => $28624456cd7e4cb8$export$cf81487e80b00e26);
11
- $parcel$export($28624456cd7e4cb8$exports, "stripEnglishCharactersAndSymbols", () => $28624456cd7e4cb8$export$df81ab2e9352ca65);
12
- $parcel$export($28624456cd7e4cb8$exports, "removeNonIndexSignatures", () => $28624456cd7e4cb8$export$d580a3cb14401529);
13
- $parcel$export($28624456cd7e4cb8$exports, "removeSingularCodes", () => $28624456cd7e4cb8$export$84d849da647fa2e5);
14
- $parcel$export($28624456cd7e4cb8$exports, "removeSolitaryArabicLetters", () => $28624456cd7e4cb8$export$7dedbc726019ed0f);
15
- $parcel$export($28624456cd7e4cb8$exports, "removeTatwil", () => $28624456cd7e4cb8$export$9571c9c2c203652d);
16
- $parcel$export($28624456cd7e4cb8$exports, "replaceTaMarbutahWithHa", () => $28624456cd7e4cb8$export$f95230335378ec58);
17
- $parcel$export($28624456cd7e4cb8$exports, "stripDiacritics", () => $28624456cd7e4cb8$export$b5bee4b27048330b);
18
- $parcel$export($28624456cd7e4cb8$exports, "stripZeroWidthCharacters", () => $28624456cd7e4cb8$export$8696bb09194c5fb5);
19
- $parcel$export($28624456cd7e4cb8$exports, "replaceAlifMaqsurah", () => $28624456cd7e4cb8$export$b1d6cb321dee12ad);
20
- $parcel$export($28624456cd7e4cb8$exports, "replaceEnglishPunctuationWithArabic", () => $28624456cd7e4cb8$export$db0c96cd03237332);
21
- $parcel$export($28624456cd7e4cb8$exports, "normalizeAlifVariants", () => $28624456cd7e4cb8$export$1d28b07894af8a98);
7
+ $parcel$export($798f85a7713a6ff1$exports, "cleanExtremeArabicUnderscores", () => $798f85a7713a6ff1$export$60dc7fb96c441688);
8
+ $parcel$export($798f85a7713a6ff1$exports, "convertUrduSymbolsToArabic", () => $798f85a7713a6ff1$export$dcf00cfaf31fd188);
9
+ $parcel$export($798f85a7713a6ff1$exports, "fixTrailingWow", () => $798f85a7713a6ff1$export$6c58e29008d10c1d);
10
+ $parcel$export($798f85a7713a6ff1$exports, "addSpaceBetweenArabicTextAndNumbers", () => $798f85a7713a6ff1$export$cf81487e80b00e26);
11
+ $parcel$export($798f85a7713a6ff1$exports, "stripEnglishCharactersAndSymbols", () => $798f85a7713a6ff1$export$df81ab2e9352ca65);
12
+ $parcel$export($798f85a7713a6ff1$exports, "removeNonIndexSignatures", () => $798f85a7713a6ff1$export$d580a3cb14401529);
13
+ $parcel$export($798f85a7713a6ff1$exports, "removeSingularCodes", () => $798f85a7713a6ff1$export$84d849da647fa2e5);
14
+ $parcel$export($798f85a7713a6ff1$exports, "removeSolitaryArabicLetters", () => $798f85a7713a6ff1$export$7dedbc726019ed0f);
15
+ $parcel$export($798f85a7713a6ff1$exports, "removeTatwil", () => $798f85a7713a6ff1$export$9571c9c2c203652d);
16
+ $parcel$export($798f85a7713a6ff1$exports, "replaceTaMarbutahWithHa", () => $798f85a7713a6ff1$export$f95230335378ec58);
17
+ $parcel$export($798f85a7713a6ff1$exports, "stripDiacritics", () => $798f85a7713a6ff1$export$b5bee4b27048330b);
18
+ $parcel$export($798f85a7713a6ff1$exports, "stripZeroWidthCharacters", () => $798f85a7713a6ff1$export$8696bb09194c5fb5);
19
+ $parcel$export($798f85a7713a6ff1$exports, "replaceAlifMaqsurah", () => $798f85a7713a6ff1$export$b1d6cb321dee12ad);
20
+ $parcel$export($798f85a7713a6ff1$exports, "replaceEnglishPunctuationWithArabic", () => $798f85a7713a6ff1$export$db0c96cd03237332);
21
+ $parcel$export($798f85a7713a6ff1$exports, "normalizeAlifVariants", () => $798f85a7713a6ff1$export$1d28b07894af8a98);
22
22
  /**
23
23
  * Removes extreme Arabic underscores (ـ) that appear at the beginning or end of a line or in text.
24
24
  * Does not affect Hijri dates (e.g., 1424هـ) or specific Arabic terms.
25
25
  * Example: "ـThis is a textـ" will be changed to "This is a text".
26
26
  * @param {string} text - The input text to apply the rule to.
27
27
  * @returns {string} - The modified text with extreme underscores removed.
28
- */ const $28624456cd7e4cb8$export$60dc7fb96c441688 = (text)=>{
28
+ */ const $798f85a7713a6ff1$export$60dc7fb96c441688 = (text)=>{
29
29
  return text.replace(/(?<!\d ?ه|اه)ـ(?=\r?$)|^ـ(?!اهـ)/gm, '');
30
30
  };
31
- const $28624456cd7e4cb8$export$dcf00cfaf31fd188 = (text)=>{
31
+ const $798f85a7713a6ff1$export$dcf00cfaf31fd188 = (text)=>{
32
32
  return text.replace(/ھ/g, "\u0647").replace(/ی/g, "\u064A");
33
33
  };
34
- const $28624456cd7e4cb8$export$6c58e29008d10c1d = (text)=>{
34
+ const $798f85a7713a6ff1$export$6c58e29008d10c1d = (text)=>{
35
35
  return text.replace(/ و /g, " \u0648");
36
36
  };
37
- const $28624456cd7e4cb8$export$cf81487e80b00e26 = (text)=>{
37
+ const $798f85a7713a6ff1$export$cf81487e80b00e26 = (text)=>{
38
38
  return text.replace(/([\u0600-\u06FF]+)(\d+)/g, '$1 $2');
39
39
  };
40
- const $28624456cd7e4cb8$export$df81ab2e9352ca65 = (text)=>{
40
+ const $798f85a7713a6ff1$export$df81ab2e9352ca65 = (text)=>{
41
41
  return text.replace(/[a-zA-Z]+[0-9]*|[¬§`ﷺ=]|\/{2,}|&/g, ' ');
42
42
  };
43
- const $28624456cd7e4cb8$export$d580a3cb14401529 = (text)=>{
43
+ const $798f85a7713a6ff1$export$d580a3cb14401529 = (text)=>{
44
44
  return text.replace(/(?<![0-9] ?)-|(?<=[\u0600-\u06FF])\s?\d\s?(?=[\u0600-\u06FF])/g, ' ').replace(/(?<=[\u0600-\u06FF]\s)(\d+\s)+\d+(?=(\s[\u0600-\u06FF]|$))/g, ' ');
45
45
  };
46
- const $28624456cd7e4cb8$export$84d849da647fa2e5 = (text)=>{
47
- return text.replace(/[\[\({][\u0621-\u064A\u0660-\u0669][\]\)}]/g, '');
46
+ const $798f85a7713a6ff1$export$84d849da647fa2e5 = (text)=>{
47
+ return text.replace(/[[({][\u0621-\u064A\u0660-\u0669][\])}]/g, '');
48
48
  };
49
- const $28624456cd7e4cb8$export$7dedbc726019ed0f = (text)=>{
49
+ const $798f85a7713a6ff1$export$7dedbc726019ed0f = (text)=>{
50
50
  return text.replace(/(^| )[\u0621-\u064A]( |$)/g, ' ');
51
51
  };
52
- const $28624456cd7e4cb8$export$9571c9c2c203652d = (text)=>{
53
- return text.replace(/(?<![0-9ه])ـ/g, '');
52
+ const $798f85a7713a6ff1$export$9571c9c2c203652d = (text)=>{
53
+ // Don't remove tatweel if:
54
+ // 1. Immediately preceded by a number or ه (for dates like "1435هـ")
55
+ // 2. Preceded by a number with optional spaces (for list items like "3 ـ")
56
+ return text.replace(/(?<![0-9ه])(?<![0-9]\s*)ـ/g, '');
54
57
  };
55
- const $28624456cd7e4cb8$export$f95230335378ec58 = (text)=>{
58
+ const $798f85a7713a6ff1$export$f95230335378ec58 = (text)=>{
56
59
  return text.replace(/[ة]/g, "\u0647");
57
60
  };
58
- const $28624456cd7e4cb8$export$b5bee4b27048330b = (text)=>{
61
+ const $798f85a7713a6ff1$export$b5bee4b27048330b = (text)=>{
59
62
  return text.replace(/[\u0610\u0611\u0612\u0613\u0614\u0615\u0616\u0617\u0618\u0619\u061A\u064B\u064C\u064D\u064E\u064F\u0650\u0651\u0652\u0653\u0654\u0655\u0656\u0657\u0658\u065A\u065B\u065C\u065D\u065E\u0640]/g, '');
60
63
  };
61
- const $28624456cd7e4cb8$export$8696bb09194c5fb5 = (text)=>{
64
+ const $798f85a7713a6ff1$export$8696bb09194c5fb5 = (text)=>{
62
65
  return text.replace(/[\u200B-\u200F\u202A-\u202E\u2060-\u2064\uFEFF]/g, ' ');
63
66
  };
64
- const $28624456cd7e4cb8$export$b1d6cb321dee12ad = (text)=>{
67
+ const $798f85a7713a6ff1$export$b1d6cb321dee12ad = (text)=>{
65
68
  return text.replace(/[ىي]/g, "\u064A");
66
69
  };
67
- const $28624456cd7e4cb8$export$db0c96cd03237332 = (text)=>{
70
+ const $798f85a7713a6ff1$export$db0c96cd03237332 = (text)=>{
68
71
  return text.replace(/\?|؟\./g, "\u061F").replace(/(;|؛)\s*(\1\s*)*/g, "\u061B").replace(/,|-،/g, "\u060C");
69
72
  };
70
- const $28624456cd7e4cb8$export$1d28b07894af8a98 = (text)=>{
73
+ const $798f85a7713a6ff1$export$1d28b07894af8a98 = (text)=>{
71
74
  return text.replace(/[أإآ]/g, "\u0627");
72
75
  };
73
76
 
74
77
 
75
- var $f4495ebb65d3b1e0$exports = {};
78
+ var $86c5c45def76a44f$exports = {};
76
79
 
77
- $parcel$export($f4495ebb65d3b1e0$exports, "insertLineBreaksAfterPunctuation", () => $f4495ebb65d3b1e0$export$814bebc253f2e5df);
78
- $parcel$export($f4495ebb65d3b1e0$exports, "addSpaceBeforeAndAfterPunctuation", () => $f4495ebb65d3b1e0$export$f0306841cd6b95d5);
79
- $parcel$export($f4495ebb65d3b1e0$exports, "applySmartQuotes", () => $f4495ebb65d3b1e0$export$42f47e081bfe828c);
80
- $parcel$export($f4495ebb65d3b1e0$exports, "cleanLiteralNewLines", () => $f4495ebb65d3b1e0$export$b4922cc8c111eae2);
81
- $parcel$export($f4495ebb65d3b1e0$exports, "cleanMultilines", () => $f4495ebb65d3b1e0$export$95680a0d9bdd5dba);
82
- $parcel$export($f4495ebb65d3b1e0$exports, "hasWordInSingleLine", () => $f4495ebb65d3b1e0$export$20a121a9317a6ed4);
83
- $parcel$export($f4495ebb65d3b1e0$exports, "isOnlyPunctuation", () => $f4495ebb65d3b1e0$export$d936e191dd6a8e06);
84
- $parcel$export($f4495ebb65d3b1e0$exports, "cleanJunkFromText", () => $f4495ebb65d3b1e0$export$38e1db3c2502e6cc);
85
- $parcel$export($f4495ebb65d3b1e0$exports, "cleanSpacesBeforePeriod", () => $f4495ebb65d3b1e0$export$e65ff0050dc4971d);
86
- $parcel$export($f4495ebb65d3b1e0$exports, "condenseAsterisks", () => $f4495ebb65d3b1e0$export$6e89dcbda2f1dcad);
87
- $parcel$export($f4495ebb65d3b1e0$exports, "condenseColons", () => $f4495ebb65d3b1e0$export$64ee6721b5d4cefa);
88
- $parcel$export($f4495ebb65d3b1e0$exports, "condenseDashes", () => $f4495ebb65d3b1e0$export$9f873c000de6f69a);
89
- $parcel$export($f4495ebb65d3b1e0$exports, "condenseEllipsis", () => $f4495ebb65d3b1e0$export$35abf980a52dfe44);
90
- $parcel$export($f4495ebb65d3b1e0$exports, "reduceMultilineBreaksToDouble", () => $f4495ebb65d3b1e0$export$660f127778d3db20);
91
- $parcel$export($f4495ebb65d3b1e0$exports, "reduceMultilineBreaksToSingle", () => $f4495ebb65d3b1e0$export$7b984b558843c423);
92
- $parcel$export($f4495ebb65d3b1e0$exports, "condensePeriods", () => $f4495ebb65d3b1e0$export$3468167fbf4483d7);
93
- $parcel$export($f4495ebb65d3b1e0$exports, "condenseUnderscores", () => $f4495ebb65d3b1e0$export$a299139a27d861bb);
94
- $parcel$export($f4495ebb65d3b1e0$exports, "doubleToSingleBrackets", () => $f4495ebb65d3b1e0$export$55102718dfa8db7e);
95
- $parcel$export($f4495ebb65d3b1e0$exports, "formatStringBySentence", () => $f4495ebb65d3b1e0$export$748703bb362bd52c);
96
- $parcel$export($f4495ebb65d3b1e0$exports, "normalizeSlashInReferences", () => $f4495ebb65d3b1e0$export$9027754b4b9f4cf4);
97
- $parcel$export($f4495ebb65d3b1e0$exports, "normalizeSpaces", () => $f4495ebb65d3b1e0$export$85f748ccc2d3e888);
98
- $parcel$export($f4495ebb65d3b1e0$exports, "removeSpaceInsideBrackets", () => $f4495ebb65d3b1e0$export$6726e05a22c5d4c9);
99
- $parcel$export($f4495ebb65d3b1e0$exports, "stripBoldStyling", () => $f4495ebb65d3b1e0$export$6db2c5d62fd5ffe9);
100
- $parcel$export($f4495ebb65d3b1e0$exports, "stripItalicsStyling", () => $f4495ebb65d3b1e0$export$9340b5fbcad6fe5a);
101
- $parcel$export($f4495ebb65d3b1e0$exports, "stripStyling", () => $f4495ebb65d3b1e0$export$e166e222302a97bd);
102
- $parcel$export($f4495ebb65d3b1e0$exports, "trimSpaceInsideQuotes", () => $f4495ebb65d3b1e0$export$eedf7f8c32995e56);
80
+ $parcel$export($86c5c45def76a44f$exports, "insertLineBreaksAfterPunctuation", () => $86c5c45def76a44f$export$814bebc253f2e5df);
81
+ $parcel$export($86c5c45def76a44f$exports, "addSpaceBeforeAndAfterPunctuation", () => $86c5c45def76a44f$export$f0306841cd6b95d5);
82
+ $parcel$export($86c5c45def76a44f$exports, "applySmartQuotes", () => $86c5c45def76a44f$export$42f47e081bfe828c);
83
+ $parcel$export($86c5c45def76a44f$exports, "cleanLiteralNewLines", () => $86c5c45def76a44f$export$b4922cc8c111eae2);
84
+ $parcel$export($86c5c45def76a44f$exports, "cleanMultilines", () => $86c5c45def76a44f$export$95680a0d9bdd5dba);
85
+ $parcel$export($86c5c45def76a44f$exports, "hasWordInSingleLine", () => $86c5c45def76a44f$export$20a121a9317a6ed4);
86
+ $parcel$export($86c5c45def76a44f$exports, "isOnlyPunctuation", () => $86c5c45def76a44f$export$d936e191dd6a8e06);
87
+ $parcel$export($86c5c45def76a44f$exports, "cleanJunkFromText", () => $86c5c45def76a44f$export$38e1db3c2502e6cc);
88
+ $parcel$export($86c5c45def76a44f$exports, "cleanSpacesBeforePeriod", () => $86c5c45def76a44f$export$e65ff0050dc4971d);
89
+ $parcel$export($86c5c45def76a44f$exports, "condenseAsterisks", () => $86c5c45def76a44f$export$6e89dcbda2f1dcad);
90
+ $parcel$export($86c5c45def76a44f$exports, "condenseColons", () => $86c5c45def76a44f$export$64ee6721b5d4cefa);
91
+ $parcel$export($86c5c45def76a44f$exports, "condenseDashes", () => $86c5c45def76a44f$export$9f873c000de6f69a);
92
+ $parcel$export($86c5c45def76a44f$exports, "condenseEllipsis", () => $86c5c45def76a44f$export$35abf980a52dfe44);
93
+ $parcel$export($86c5c45def76a44f$exports, "reduceMultilineBreaksToDouble", () => $86c5c45def76a44f$export$660f127778d3db20);
94
+ $parcel$export($86c5c45def76a44f$exports, "reduceMultilineBreaksToSingle", () => $86c5c45def76a44f$export$7b984b558843c423);
95
+ $parcel$export($86c5c45def76a44f$exports, "condensePeriods", () => $86c5c45def76a44f$export$3468167fbf4483d7);
96
+ $parcel$export($86c5c45def76a44f$exports, "condenseUnderscores", () => $86c5c45def76a44f$export$a299139a27d861bb);
97
+ $parcel$export($86c5c45def76a44f$exports, "doubleToSingleBrackets", () => $86c5c45def76a44f$export$55102718dfa8db7e);
98
+ $parcel$export($86c5c45def76a44f$exports, "replaceDoubleBracketsWithArrows", () => $86c5c45def76a44f$export$803cc4592448c009);
99
+ $parcel$export($86c5c45def76a44f$exports, "formatStringBySentence", () => $86c5c45def76a44f$export$748703bb362bd52c);
100
+ $parcel$export($86c5c45def76a44f$exports, "normalizeSlashInReferences", () => $86c5c45def76a44f$export$9027754b4b9f4cf4);
101
+ $parcel$export($86c5c45def76a44f$exports, "normalizeSpaces", () => $86c5c45def76a44f$export$85f748ccc2d3e888);
102
+ $parcel$export($86c5c45def76a44f$exports, "ensureSpaceBeforeBrackets", () => $86c5c45def76a44f$export$5c77851c03e0da0a);
103
+ $parcel$export($86c5c45def76a44f$exports, "removeRedundantPunctuation", () => $86c5c45def76a44f$export$a97ebab70a927fe1);
104
+ $parcel$export($86c5c45def76a44f$exports, "removeSpaceInsideBrackets", () => $86c5c45def76a44f$export$6726e05a22c5d4c9);
105
+ $parcel$export($86c5c45def76a44f$exports, "stripBoldStyling", () => $86c5c45def76a44f$export$6db2c5d62fd5ffe9);
106
+ $parcel$export($86c5c45def76a44f$exports, "stripItalicsStyling", () => $86c5c45def76a44f$export$9340b5fbcad6fe5a);
107
+ $parcel$export($86c5c45def76a44f$exports, "stripStyling", () => $86c5c45def76a44f$export$e166e222302a97bd);
108
+ $parcel$export($86c5c45def76a44f$exports, "trimSpaceInsideQuotes", () => $86c5c45def76a44f$export$eedf7f8c32995e56);
103
109
  /**
104
110
  * Adds line breaks after punctuation marks such as periods, exclamation points, and question marks.
105
111
  * Example: 'Text.' becomes 'Text.\n'.
106
112
  * @param {string} text - The input text containing punctuation.
107
113
  * @returns {string} - The modified text with line breaks added after punctuation.
108
- */ const $f4495ebb65d3b1e0$export$814bebc253f2e5df = (text)=>{
114
+ */ const $86c5c45def76a44f$export$814bebc253f2e5df = (text)=>{
109
115
  // Define the punctuation marks that should trigger a new line
110
116
  const punctuation = /([.?!؟])/g;
111
117
  // Replace occurrences of punctuation marks followed by a space with the punctuation mark, a newline, and the space
112
118
  const formattedText = text.replace(punctuation, '$1\n').replace(/\n\s+/g, '\n').trim();
113
119
  return formattedText;
114
120
  };
115
- const $f4495ebb65d3b1e0$export$f0306841cd6b95d5 = (text)=>{
116
- return text.replace(/( ?)([.!?,،؟;؛])((?![ '”“\)"\]\n])|(?=\s{2,}))/g, '$1$2 ').replace(/\s([.!?,،؟;؛])\s*([ '”“\)"\]\n])/g, '$1$2').replace(/([^\s\w\d'”“\)"\]]+)\s+([.!?,،؟;؛])|([.!?,،؟;؛])\s+$/g, '$1$2$3').replace(/(?<=\D)( ?: ?)(?!(\d+:)|(:\d+))|(?<=\d) ?: ?(?=\D)|(?<=\D) ?: ?(?=\d)/g, ': ');
121
+ const $86c5c45def76a44f$export$f0306841cd6b95d5 = (text)=>{
122
+ return text.replace(/( ?)([.!?,،؟;؛])((?![ '”“)"\]\n])|(?=\s{2,}))/g, '$1$2 ').replace(/\s([.!?,،؟;؛])\s*([ '”“)"\]\n])/g, '$1$2').replace(/([^\s\w\d'”“)"\]]+)\s+([.!?,،؟;؛])|([.!?,،؟;؛])\s+$/g, '$1$2$3').replace(/(?<=\D)( ?: ?)(?!(\d+:)|(:\d+))|(?<=\d) ?: ?(?=\D)|(?<=\D) ?: ?(?=\d)/g, ': ');
117
123
  };
118
- const $f4495ebb65d3b1e0$export$42f47e081bfe828c = (text)=>{
124
+ const $86c5c45def76a44f$export$42f47e081bfe828c = (text)=>{
119
125
  return text.replace(/[“”]/g, '"').replace(/"([^"]*)"/g, "\u201C$1\u201D").replace(/^”/g, "\u201C");
120
126
  };
121
- const $f4495ebb65d3b1e0$export$b4922cc8c111eae2 = (text)=>{
127
+ const $86c5c45def76a44f$export$b4922cc8c111eae2 = (text)=>{
122
128
  return text.replace(/\\n|\r/g, '\n');
123
129
  };
124
- const $f4495ebb65d3b1e0$export$95680a0d9bdd5dba = (text)=>{
130
+ const $86c5c45def76a44f$export$95680a0d9bdd5dba = (text)=>{
125
131
  return text.replace(/^ +| +$/gm, '');
126
132
  };
127
- const $f4495ebb65d3b1e0$export$20a121a9317a6ed4 = (text)=>{
133
+ const $86c5c45def76a44f$export$20a121a9317a6ed4 = (text)=>{
128
134
  return /^\s*\S+\s*$/gm.test(text);
129
135
  };
130
- const $f4495ebb65d3b1e0$export$d936e191dd6a8e06 = (text)=>{
136
+ const $86c5c45def76a44f$export$d936e191dd6a8e06 = (text)=>{
131
137
  const regex = /^[\u0020-\u002f\u003a-\u0040\u005b-\u0060\u007b-\u007e0-9٠-٩]+$/;
132
138
  return regex.test(text);
133
139
  };
134
- const $f4495ebb65d3b1e0$export$38e1db3c2502e6cc = (text)=>{
135
- const newBody = $f4495ebb65d3b1e0$export$95680a0d9bdd5dba(text);
140
+ const $86c5c45def76a44f$export$38e1db3c2502e6cc = (text)=>{
141
+ const newBody = $86c5c45def76a44f$export$95680a0d9bdd5dba(text);
136
142
  const lines = newBody.split('\n').filter((line)=>{
137
- return !line || line.length > 1 && !$f4495ebb65d3b1e0$export$d936e191dd6a8e06(line);
143
+ return !line || line.length > 1 && !$86c5c45def76a44f$export$d936e191dd6a8e06(line);
138
144
  });
139
145
  return lines.join('\n').trim();
140
146
  };
141
- const $f4495ebb65d3b1e0$export$e65ff0050dc4971d = (text)=>{
147
+ const $86c5c45def76a44f$export$e65ff0050dc4971d = (text)=>{
142
148
  return text.replace(/\s+([.؟!,،؛:?])/g, '$1');
143
149
  };
144
- const $f4495ebb65d3b1e0$export$6e89dcbda2f1dcad = (text)=>{
150
+ const $86c5c45def76a44f$export$6e89dcbda2f1dcad = (text)=>{
145
151
  return text.replace(/(\*\s*)+/g, '*');
146
152
  };
147
- const $f4495ebb65d3b1e0$export$64ee6721b5d4cefa = (text)=>{
148
- return text.replace(/[\.-]?:[\.-]?/g, ':');
153
+ const $86c5c45def76a44f$export$64ee6721b5d4cefa = (text)=>{
154
+ return text.replace(/[.-]?:[.-]?/g, ':');
149
155
  };
150
- const $f4495ebb65d3b1e0$export$9f873c000de6f69a = (text)=>{
156
+ const $86c5c45def76a44f$export$9f873c000de6f69a = (text)=>{
151
157
  return text.replace(/-{2,}/g, '-');
152
158
  };
153
- const $f4495ebb65d3b1e0$export$35abf980a52dfe44 = (text)=>{
159
+ const $86c5c45def76a44f$export$35abf980a52dfe44 = (text)=>{
154
160
  return text.replace(/\.{2,}/g, "\u2026");
155
161
  };
156
- const $f4495ebb65d3b1e0$export$660f127778d3db20 = (text)=>{
162
+ const $86c5c45def76a44f$export$660f127778d3db20 = (text)=>{
157
163
  return text.replace(/(\n\s*){3,}/g, '\n\n');
158
164
  };
159
- const $f4495ebb65d3b1e0$export$7b984b558843c423 = (text)=>{
165
+ const $86c5c45def76a44f$export$7b984b558843c423 = (text)=>{
160
166
  return text.replace(/(\n\s*){2,}/g, '\n');
161
167
  };
162
- const $f4495ebb65d3b1e0$export$3468167fbf4483d7 = (text)=>{
168
+ const $86c5c45def76a44f$export$3468167fbf4483d7 = (text)=>{
163
169
  return text.replace(/\. +\./g, '.');
164
170
  };
165
- const $f4495ebb65d3b1e0$export$a299139a27d861bb = (text)=>{
171
+ const $86c5c45def76a44f$export$a299139a27d861bb = (text)=>{
166
172
  return text.replace(/ـ{2,}/g, "\u0640").replace(/_+/g, '_');
167
173
  };
168
- const $f4495ebb65d3b1e0$export$55102718dfa8db7e = (text)=>{
174
+ const $86c5c45def76a44f$export$55102718dfa8db7e = (text)=>{
169
175
  return text.replace(/(\(|\)){2,}|(\[|\]){2,}/g, '$1$2');
170
176
  };
171
- const $f4495ebb65d3b1e0$export$748703bb362bd52c = (input)=>{
177
+ const $86c5c45def76a44f$export$803cc4592448c009 = (text)=>{
178
+ return text.replace(/\(\(\s?/g, "\xab").replace(/\s?\)\)/g, "\xbb");
179
+ };
180
+ const $86c5c45def76a44f$export$748703bb362bd52c = (input)=>{
172
181
  const footnoteRegex = /^\((?:\d+|۱|۲|۳|۴|۵|۶|۷|۸|۹)\)\s/;
173
182
  const sentences = [];
174
183
  const lines = input.split('\n');
@@ -196,37 +205,43 @@ const $f4495ebb65d3b1e0$export$748703bb362bd52c = (input)=>{
196
205
  if (currentSentence) sentences.push(currentSentence.trim());
197
206
  return sentences.join('\n');
198
207
  };
199
- const $f4495ebb65d3b1e0$export$9027754b4b9f4cf4 = (text)=>{
208
+ const $86c5c45def76a44f$export$9027754b4b9f4cf4 = (text)=>{
200
209
  return text.replace(/(\d+)\s?\/\s?(\d+)/g, '$1/$2');
201
210
  };
202
- const $f4495ebb65d3b1e0$export$85f748ccc2d3e888 = (text)=>{
211
+ const $86c5c45def76a44f$export$85f748ccc2d3e888 = (text)=>{
203
212
  return text.replace(/[ \t]+/g, ' ');
204
213
  };
205
- const $f4495ebb65d3b1e0$export$6726e05a22c5d4c9 = (text)=>{
206
- return text.replace(/([\[\(])\s*(.*?)\s*([\]\)])/g, '$1$2$3');
214
+ const $86c5c45def76a44f$export$5c77851c03e0da0a = (text)=>{
215
+ return text.replace(/(\S) *(\([^)]*\))/g, '$1 $2');
216
+ };
217
+ const $86c5c45def76a44f$export$a97ebab70a927fe1 = (text)=>{
218
+ return text.replace(/([؟!])[.،]/g, '$1');
207
219
  };
208
- const $f4495ebb65d3b1e0$export$6db2c5d62fd5ffe9 = (text)=>{
220
+ const $86c5c45def76a44f$export$6726e05a22c5d4c9 = (text)=>{
221
+ return text.replace(/([[(])\s*(.*?)\s*([\])])/g, '$1$2$3');
222
+ };
223
+ const $86c5c45def76a44f$export$6db2c5d62fd5ffe9 = (text)=>{
209
224
  // Normalize the string to NFKD form
210
225
  const normalizedString = text.normalize('NFKD');
211
226
  // Remove combining marks (diacritics) and stylistic characters from the string
212
227
  return normalizedString.replace(/[\u0300-\u036f]/g, '').trim();
213
228
  };
214
- const $f4495ebb65d3b1e0$export$9340b5fbcad6fe5a = (text)=>{
229
+ const $86c5c45def76a44f$export$9340b5fbcad6fe5a = (text)=>{
215
230
  const italicMap = {
216
231
  '\uD835\uDC4E': 'I',
217
232
  '\uD835\uDC68': 'g',
218
- '\u{1D63C}': '!',
233
+ "\uD835\uDE3C": '!',
219
234
  '\uD835\uDC4F': 'J',
220
235
  '\uD835\uDC69': 'h',
221
- '\u{1D63D}': '?',
236
+ "\uD835\uDE3D": '?',
222
237
  '\uD835\uDC50': 'K',
223
238
  '\uD835\uDC6A': 'i',
224
239
  '\uD835\uDC51': 'L',
225
240
  '\uD835\uDC6B': 'j',
226
- '\u{1D63F}': ',',
241
+ "\uD835\uDE3F": ',',
227
242
  '\uD835\uDC52': 'M',
228
243
  '\uD835\uDC6C': 'k',
229
- '\u{1D640}': '.',
244
+ "\uD835\uDE40": '.',
230
245
  '\uD835\uDC53': 'N',
231
246
  '\uD835\uDC6D': 'l',
232
247
  '\uD835\uDC54': 'O',
@@ -240,7 +255,7 @@ const $f4495ebb65d3b1e0$export$9340b5fbcad6fe5a = (text)=>{
240
255
  '\uD835\uDC72': 'q',
241
256
  '\uD835\uDC59': 'T',
242
257
  '\uD835\uDC73': 'r',
243
- '\u{1D647}': '-',
258
+ "\uD835\uDE47": '-',
244
259
  '\uD835\uDC5A': 'U',
245
260
  '\uD835\uDC74': 's',
246
261
  '\uD835\uDC5B': 'V',
@@ -275,19 +290,20 @@ const $f4495ebb65d3b1e0$export$9340b5fbcad6fe5a = (text)=>{
275
290
  return italicMap[match] || match;
276
291
  });
277
292
  };
278
- const $f4495ebb65d3b1e0$export$e166e222302a97bd = (text)=>{
279
- return $f4495ebb65d3b1e0$export$9340b5fbcad6fe5a($f4495ebb65d3b1e0$export$6db2c5d62fd5ffe9(text));
293
+ const $86c5c45def76a44f$export$e166e222302a97bd = (text)=>{
294
+ return $86c5c45def76a44f$export$9340b5fbcad6fe5a($86c5c45def76a44f$export$6db2c5d62fd5ffe9(text));
280
295
  };
281
- const $f4495ebb65d3b1e0$export$eedf7f8c32995e56 = (text)=>{
296
+ const $86c5c45def76a44f$export$eedf7f8c32995e56 = (text)=>{
282
297
  return text.replace(/([“”"]|«) *(.*?) *([“”"]|»)/g, '$1$2$3');
283
298
  };
284
299
 
285
300
 
286
- var $0a00bc254018888e$exports = {};
301
+ var $045191e51bf3eda2$exports = {};
287
302
 
288
- $parcel$export($0a00bc254018888e$exports, "normalizeJsonSyntax", () => $0a00bc254018888e$export$62c7e2fbc3880e40);
289
- $parcel$export($0a00bc254018888e$exports, "isJsonStructureValid", () => $0a00bc254018888e$export$70726570eaa51acb);
290
- $parcel$export($0a00bc254018888e$exports, "splitByQuotes", () => $0a00bc254018888e$export$ae2dc619900afbaa);
303
+ $parcel$export($045191e51bf3eda2$exports, "normalizeJsonSyntax", () => $045191e51bf3eda2$export$62c7e2fbc3880e40);
304
+ $parcel$export($045191e51bf3eda2$exports, "isJsonStructureValid", () => $045191e51bf3eda2$export$70726570eaa51acb);
305
+ $parcel$export($045191e51bf3eda2$exports, "splitByQuotes", () => $045191e51bf3eda2$export$ae2dc619900afbaa);
306
+ $parcel$export($045191e51bf3eda2$exports, "isBalanced", () => $045191e51bf3eda2$export$1e23eb8d8fab7cc);
291
307
  /**
292
308
  * Converts a string that resembles JSON but with numeric keys and single-quoted values
293
309
  * into valid JSON format. This function replaces numeric keys with quoted numeric keys
@@ -299,96 +315,181 @@ $parcel$export($0a00bc254018888e$exports, "splitByQuotes", () => $0a00bc25401888
299
315
  * @example
300
316
  * const result = normalizeJsonSyntax("{10: 'abc', 20: 'def'}");
301
317
  * console.log(result); // '{"10": "abc", "20": "def"}'
302
- */ const $0a00bc254018888e$export$62c7e2fbc3880e40 = (str)=>{
318
+ */ const $045191e51bf3eda2$export$62c7e2fbc3880e40 = (str)=>{
303
319
  let input = str.replace(/(\b\d+\b)(?=:)/g, '"$1"');
304
320
  input = input.replace(/:\s*'([^']+)'/g, ': "$1"');
305
321
  input = input.replace(/:\s*"([^"]+)"/g, ': "$1"');
306
322
  return JSON.stringify(JSON.parse(input));
307
323
  };
308
- const $0a00bc254018888e$export$70726570eaa51acb = (str)=>{
324
+ const $045191e51bf3eda2$export$70726570eaa51acb = (str)=>{
309
325
  // Checks for a pattern with numeric keys or quoted keys and values in quotes
310
326
  const jsonLikePattern = /^{(\s*(\d+|'[^']*'|"[^"]*")\s*:\s*('|")[^'"]*\3\s*,)*(?:\s*(\d+|'[^']*'|"[^"]*")\s*:\s*('|")[^'"]*\5\s*)}$/;
311
327
  return jsonLikePattern.test(str.trim());
312
328
  };
313
- const $0a00bc254018888e$export$ae2dc619900afbaa = (query)=>{
329
+ const $045191e51bf3eda2$export$ae2dc619900afbaa = (query)=>{
314
330
  const regex = /(?:[^\s"]+|"(.*?)")+/g;
315
331
  return (query.match(regex) || []).map((s)=>s.startsWith('"') ? s.slice(1, -1) : s);
316
332
  };
333
+ /**
334
+ * Checks if all double quotes in a string are balanced (even count).
335
+ * A string has balanced quotes if every opening quote has a corresponding closing quote.
336
+ *
337
+ * @param str - The string to check for balanced quotes
338
+ * @returns True if quotes are balanced (even count), false otherwise
339
+ *
340
+ * @example
341
+ * ```typescript
342
+ * areQuotesBalanced('Hello "world"') // Returns: true
343
+ * areQuotesBalanced('Hello "world') // Returns: false
344
+ * areQuotesBalanced('No quotes') // Returns: true
345
+ * ```
346
+ */ const $045191e51bf3eda2$var$areQuotesBalanced = (str)=>{
347
+ let quoteCount = 0;
348
+ for (const char of str)if (char === '"') quoteCount++;
349
+ return quoteCount % 2 === 0;
350
+ };
351
+ const $045191e51bf3eda2$var$brackets = {
352
+ '(': ')',
353
+ '[': ']',
354
+ '{': '}'
355
+ };
356
+ const $045191e51bf3eda2$var$openBrackets = new Set([
357
+ '(',
358
+ '[',
359
+ '{'
360
+ ]);
361
+ const $045191e51bf3eda2$var$closeBrackets = new Set([
362
+ ')',
363
+ ']',
364
+ '}'
365
+ ]);
366
+ /**
367
+ * Checks if all brackets in a string are properly balanced and matched.
368
+ * This function validates that every opening bracket has a corresponding closing bracket
369
+ * in the correct order and of the matching type.
370
+ *
371
+ * Supported bracket types: parentheses (), square brackets [], curly braces {}
372
+ *
373
+ * @param str - The string to check for balanced brackets
374
+ * @returns True if all brackets are properly balanced and matched, false otherwise
375
+ *
376
+ * @example
377
+ * ```typescript
378
+ * areBracketsBalanced('(hello [world])') // Returns: true
379
+ * areBracketsBalanced('(hello [world)') // Returns: false (mismatched)
380
+ * areBracketsBalanced('((hello))') // Returns: true
381
+ * areBracketsBalanced('(hello') // Returns: false (unclosed)
382
+ * ```
383
+ */ const $045191e51bf3eda2$var$areBracketsBalanced = (str)=>{
384
+ const stack = [];
385
+ for (const char of str){
386
+ if ($045191e51bf3eda2$var$openBrackets.has(char)) stack.push(char);
387
+ else if ($045191e51bf3eda2$var$closeBrackets.has(char)) {
388
+ const lastOpen = stack.pop();
389
+ if (!lastOpen || $045191e51bf3eda2$var$brackets[lastOpen] !== char) return false;
390
+ }
391
+ }
392
+ return stack.length === 0;
393
+ };
394
+ const $045191e51bf3eda2$export$1e23eb8d8fab7cc = (str)=>{
395
+ return $045191e51bf3eda2$var$areQuotesBalanced(str) && $045191e51bf3eda2$var$areBracketsBalanced(str);
396
+ };
317
397
 
318
398
 
319
- var $1f25f0941eacce7f$exports = {};
399
+ var $15eb38b546e8440a$exports = {};
320
400
 
321
- $parcel$export($1f25f0941eacce7f$exports, "cleanSymbolsAndPartReferences", () => $1f25f0941eacce7f$export$70476c4e7ef0b147);
322
- $parcel$export($1f25f0941eacce7f$exports, "cleanTrailingPageNumbers", () => $1f25f0941eacce7f$export$9f81734a6223638b);
323
- $parcel$export($1f25f0941eacce7f$exports, "replaceLineBreaksWithSpaces", () => $1f25f0941eacce7f$export$631d05f860fc7118);
324
- $parcel$export($1f25f0941eacce7f$exports, "stripAllDigits", () => $1f25f0941eacce7f$export$edd6c3bb8fa3bc01);
325
- $parcel$export($1f25f0941eacce7f$exports, "removeDeathYear", () => $1f25f0941eacce7f$export$a537ffbd78859923);
326
- $parcel$export($1f25f0941eacce7f$exports, "removeNumbersAndDashes", () => $1f25f0941eacce7f$export$c8e7d4d7d9f46256);
327
- $parcel$export($1f25f0941eacce7f$exports, "removeSingleDigitReferences", () => $1f25f0941eacce7f$export$8e7f001aa315ad82);
328
- $parcel$export($1f25f0941eacce7f$exports, "removeUrls", () => $1f25f0941eacce7f$export$e4a0bb7881a4591a);
401
+ $parcel$export($15eb38b546e8440a$exports, "cleanSymbolsAndPartReferences", () => $15eb38b546e8440a$export$70476c4e7ef0b147);
402
+ $parcel$export($15eb38b546e8440a$exports, "cleanTrailingPageNumbers", () => $15eb38b546e8440a$export$9f81734a6223638b);
403
+ $parcel$export($15eb38b546e8440a$exports, "replaceLineBreaksWithSpaces", () => $15eb38b546e8440a$export$631d05f860fc7118);
404
+ $parcel$export($15eb38b546e8440a$exports, "stripAllDigits", () => $15eb38b546e8440a$export$edd6c3bb8fa3bc01);
405
+ $parcel$export($15eb38b546e8440a$exports, "removeDeathYear", () => $15eb38b546e8440a$export$a537ffbd78859923);
406
+ $parcel$export($15eb38b546e8440a$exports, "removeNumbersAndDashes", () => $15eb38b546e8440a$export$c8e7d4d7d9f46256);
407
+ $parcel$export($15eb38b546e8440a$exports, "removeSingleDigitReferences", () => $15eb38b546e8440a$export$8e7f001aa315ad82);
408
+ $parcel$export($15eb38b546e8440a$exports, "removeUrls", () => $15eb38b546e8440a$export$e4a0bb7881a4591a);
409
+ $parcel$export($15eb38b546e8440a$exports, "truncate", () => $15eb38b546e8440a$export$6a506b36fdea397d);
410
+ $parcel$export($15eb38b546e8440a$exports, "truncateMiddle", () => $15eb38b546e8440a$export$f3a88d5244308057);
411
+ $parcel$export($15eb38b546e8440a$exports, "unescapeSpaces", () => $15eb38b546e8440a$export$1791d17c7d9c448);
329
412
  /**
330
413
  * Removes various symbols, part references, and numerical markers from the text.
331
414
  * Example: '(1) (2/3)' becomes ''.
332
415
  * @param {string} text - The input text to apply the rule to.
333
416
  * @returns {string} - The modified text with symbols and part references removed.
334
- */ const $1f25f0941eacce7f$export$70476c4e7ef0b147 = (text)=>{
335
- return text.replace(/ *\(?:\d+(?:\/\d+){0,2}\)? *| *\[\d+(?:\/\d+)?\] *| *«\d+» *|\d+\/\d+(?:\/\d+)?|[،§{}۝؍‎﴿﴾<>;_؟»«:!،؛\[\]…ـ¬\.\\\/\*\(\)"]/g, ' ');
417
+ */ const $15eb38b546e8440a$export$70476c4e7ef0b147 = (text)=>{
418
+ return text.replace(/ *\(?:\d+(?:\/\d+){0,2}\)? *| *\[\d+(?:\/\d+)?\] *| *«\d+» *|\d+\/\d+(?:\/\d+)?|[،§{}۝؍‎﴿﴾<>;_؟»«:!،؛[\]…ـ¬.\\/*()"]/g, ' ');
336
419
  };
337
- const $1f25f0941eacce7f$export$9f81734a6223638b = (text)=>{
420
+ const $15eb38b546e8440a$export$9f81734a6223638b = (text)=>{
338
421
  return text.replace(/-\[\d+\]-/g, '');
339
422
  };
340
- const $1f25f0941eacce7f$export$631d05f860fc7118 = (text)=>{
423
+ const $15eb38b546e8440a$export$631d05f860fc7118 = (text)=>{
341
424
  return text.replace(/\s+/g, ' ');
342
425
  };
343
- const $1f25f0941eacce7f$export$edd6c3bb8fa3bc01 = (text)=>{
426
+ const $15eb38b546e8440a$export$edd6c3bb8fa3bc01 = (text)=>{
344
427
  return text.replace(/[0-9]/g, '');
345
428
  };
346
- const $1f25f0941eacce7f$export$a537ffbd78859923 = (text)=>{
429
+ const $15eb38b546e8440a$export$a537ffbd78859923 = (text)=>{
347
430
  return text.replace(/\[(d)\.\s*\d{1,4}[hH]\]\s*|\((d)\.\s*\d{1,4}[hH]\)\s*/g, '');
348
431
  };
349
- const $1f25f0941eacce7f$export$c8e7d4d7d9f46256 = (text)=>{
432
+ const $15eb38b546e8440a$export$c8e7d4d7d9f46256 = (text)=>{
350
433
  return text.replace(/[\d-]/g, '');
351
434
  };
352
- const $1f25f0941eacce7f$export$8e7f001aa315ad82 = (text)=>{
435
+ const $15eb38b546e8440a$export$8e7f001aa315ad82 = (text)=>{
353
436
  return text.replace(/\(\d{1}\)|\[\d{1}\]|«\d»/g, '');
354
437
  };
355
- const $1f25f0941eacce7f$export$e4a0bb7881a4591a = (text)=>{
438
+ const $15eb38b546e8440a$export$e4a0bb7881a4591a = (text)=>{
356
439
  return text.replace(/https?:\/\/(www\.)?[-a-zA-Z0-9@:%._+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_+.~#?&//=]*)/g, '');
357
440
  };
441
+ const $15eb38b546e8440a$export$6a506b36fdea397d = (val, n = 150)=>val.length > n ? `${val.substring(0, n - 1)}\u{2026}` : val;
442
+ const $15eb38b546e8440a$export$f3a88d5244308057 = (text, maxLength = 50, endLength)=>{
443
+ if (text.length <= maxLength) return text;
444
+ // Default end length is roughly 1/3 of max length, minimum 3 characters
445
+ const defaultEndLength = Math.max(3, Math.floor(maxLength / 3));
446
+ const actualEndLength = endLength ?? defaultEndLength;
447
+ // Reserve space for the ellipsis character (1 char)
448
+ const availableLength = maxLength - 1;
449
+ // Calculate start length (remaining space after end portion)
450
+ const startLength = availableLength - actualEndLength;
451
+ // Ensure we have at least some characters at the start
452
+ if (startLength < 1) // If we can't fit both start and end, just truncate normally
453
+ return `${text.substring(0, maxLength - 1)}\u{2026}`;
454
+ const startPortion = text.substring(0, startLength);
455
+ const endPortion = text.substring(text.length - actualEndLength);
456
+ return `${startPortion}\u{2026}${endPortion}`;
457
+ };
458
+ const $15eb38b546e8440a$export$1791d17c7d9c448 = (input)=>input.replace(/\\ /g, ' ').trim();
358
459
 
359
460
 
360
- var $2d6eb7113bd26878$exports = {};
461
+ var $0c91e05aa031e32a$exports = {};
361
462
 
362
- $parcel$export($2d6eb7113bd26878$exports, "normalizeArabicPrefixesToAl", () => $2d6eb7113bd26878$export$2a02c946f8bfe63e);
363
- $parcel$export($2d6eb7113bd26878$exports, "normalizeDoubleApostrophes", () => $2d6eb7113bd26878$export$bdee7fc4cb327c1a);
364
- $parcel$export($2d6eb7113bd26878$exports, "replaceSalutationsWithSymbol", () => $2d6eb7113bd26878$export$a0f0be7fbc73baaa);
365
- $parcel$export($2d6eb7113bd26878$exports, "normalize", () => $2d6eb7113bd26878$export$a3295358bff77e);
366
- $parcel$export($2d6eb7113bd26878$exports, "normalizeApostrophes", () => $2d6eb7113bd26878$export$a4e89c859f54cbf3);
367
- $parcel$export($2d6eb7113bd26878$exports, "removeArabicPrefixes", () => $2d6eb7113bd26878$export$dcfbf7d1ecba5f64);
368
- $parcel$export($2d6eb7113bd26878$exports, "normalizeTransliteratedEnglish", () => $2d6eb7113bd26878$export$17df925670d0176a);
369
- $parcel$export($2d6eb7113bd26878$exports, "extractInitials", () => $2d6eb7113bd26878$export$d421e6fd95c29a67);
463
+ $parcel$export($0c91e05aa031e32a$exports, "normalizeArabicPrefixesToAl", () => $0c91e05aa031e32a$export$2a02c946f8bfe63e);
464
+ $parcel$export($0c91e05aa031e32a$exports, "normalizeDoubleApostrophes", () => $0c91e05aa031e32a$export$bdee7fc4cb327c1a);
465
+ $parcel$export($0c91e05aa031e32a$exports, "replaceSalutationsWithSymbol", () => $0c91e05aa031e32a$export$a0f0be7fbc73baaa);
466
+ $parcel$export($0c91e05aa031e32a$exports, "normalize", () => $0c91e05aa031e32a$export$a3295358bff77e);
467
+ $parcel$export($0c91e05aa031e32a$exports, "normalizeApostrophes", () => $0c91e05aa031e32a$export$a4e89c859f54cbf3);
468
+ $parcel$export($0c91e05aa031e32a$exports, "removeArabicPrefixes", () => $0c91e05aa031e32a$export$dcfbf7d1ecba5f64);
469
+ $parcel$export($0c91e05aa031e32a$exports, "normalizeTransliteratedEnglish", () => $0c91e05aa031e32a$export$17df925670d0176a);
470
+ $parcel$export($0c91e05aa031e32a$exports, "extractInitials", () => $0c91e05aa031e32a$export$d421e6fd95c29a67);
370
471
 
371
- const $2d6eb7113bd26878$export$2a02c946f8bfe63e = (text)=>{
472
+ const $0c91e05aa031e32a$export$2a02c946f8bfe63e = (text)=>{
372
473
  return text.replace(/(\b|\W)(Al |Al-|Ar-|As-|Adh-|Ad-|Ats-|Ath |Ath-|Az |Az-|az-|adh-|as-|ar-)/g, '$1al-').replace(/(\b|\W)(Ash-S|ash-S)/g, '$1al-S').replace(/al- (.+?)\b/g, 'al-$1');
373
474
  };
374
- const $2d6eb7113bd26878$export$bdee7fc4cb327c1a = (text)=>{
475
+ const $0c91e05aa031e32a$export$bdee7fc4cb327c1a = (text)=>{
375
476
  return text.replace(/ʿʿ/g, "\u02BF").replace(/ʾʾ/g, "\u02BE");
376
477
  };
377
- const $2d6eb7113bd26878$export$a0f0be7fbc73baaa = (text)=>{
478
+ const $0c91e05aa031e32a$export$a0f0be7fbc73baaa = (text)=>{
378
479
  return text.replace(/\(peace be upon him\)|(Messenger of (Allah|Allāh)|Messenger|Prophet|Mu[hḥ]ammad) *\((s[^)]*m|peace[^)]*him|May[^)]*him|may[^)]*him)\)*/gi, "$1 \uFDFA").replace(/,\s*ﷺ\s*,/g, " \uFDFA");
379
480
  };
380
- const $2d6eb7113bd26878$export$a3295358bff77e = (input)=>{
481
+ const $0c91e05aa031e32a$export$a3295358bff77e = (input)=>{
381
482
  return input.normalize('NFKD').replace(/[\u0300-\u036f]/g, '').replace(/`|ʾ|ʿ|-/g, '');
382
483
  };
383
- const $2d6eb7113bd26878$export$a4e89c859f54cbf3 = (text)=>{
484
+ const $0c91e05aa031e32a$export$a4e89c859f54cbf3 = (text)=>{
384
485
  return text.replace(/‛|’|‘/g, "'");
385
486
  };
386
- const $2d6eb7113bd26878$export$dcfbf7d1ecba5f64 = (text)=>{
387
- return (0, $f4495ebb65d3b1e0$export$85f748ccc2d3e888)(text.replace(/(\bal-|\bli-|\bbi-|\bfī|\bwa[-\s]+|\bl-|\bliʿl|\Bʿalá|\Bʿan|\bb\.)/gi, ''));
487
+ const $0c91e05aa031e32a$export$dcfbf7d1ecba5f64 = (text)=>{
488
+ return (0, $86c5c45def76a44f$export$85f748ccc2d3e888)(text.replace(/(\bal-|\bli-|\bbi-|\bfī|\bwa[-\s]+|\bl-|\bliʿl|\Bʿalá|\Bʿan|\bb\.)/gi, ''));
388
489
  };
389
- const $2d6eb7113bd26878$export$17df925670d0176a = (text)=>$2d6eb7113bd26878$export$a3295358bff77e($2d6eb7113bd26878$export$dcfbf7d1ecba5f64(text));
390
- const $2d6eb7113bd26878$export$d421e6fd95c29a67 = (fullName)=>{
391
- const initials = $2d6eb7113bd26878$export$17df925670d0176a(fullName).trim().split(/[ -]/).slice(0, 2).map((word)=>{
490
+ const $0c91e05aa031e32a$export$17df925670d0176a = (text)=>$0c91e05aa031e32a$export$a3295358bff77e($0c91e05aa031e32a$export$dcfbf7d1ecba5f64(text));
491
+ const $0c91e05aa031e32a$export$d421e6fd95c29a67 = (fullName)=>{
492
+ const initials = $0c91e05aa031e32a$export$17df925670d0176a(fullName).trim().split(/[ -]/).slice(0, 2).map((word)=>{
392
493
  return word.charAt(0).toUpperCase();
393
494
  }).join('');
394
495
  return initials;
@@ -397,5 +498,5 @@ const $2d6eb7113bd26878$export$d421e6fd95c29a67 = (fullName)=>{
397
498
 
398
499
 
399
500
 
400
- export {$28624456cd7e4cb8$export$60dc7fb96c441688 as cleanExtremeArabicUnderscores, $28624456cd7e4cb8$export$dcf00cfaf31fd188 as convertUrduSymbolsToArabic, $28624456cd7e4cb8$export$6c58e29008d10c1d as fixTrailingWow, $28624456cd7e4cb8$export$cf81487e80b00e26 as addSpaceBetweenArabicTextAndNumbers, $28624456cd7e4cb8$export$df81ab2e9352ca65 as stripEnglishCharactersAndSymbols, $28624456cd7e4cb8$export$d580a3cb14401529 as removeNonIndexSignatures, $28624456cd7e4cb8$export$84d849da647fa2e5 as removeSingularCodes, $28624456cd7e4cb8$export$7dedbc726019ed0f as removeSolitaryArabicLetters, $28624456cd7e4cb8$export$9571c9c2c203652d as removeTatwil, $28624456cd7e4cb8$export$f95230335378ec58 as replaceTaMarbutahWithHa, $28624456cd7e4cb8$export$b5bee4b27048330b as stripDiacritics, $28624456cd7e4cb8$export$8696bb09194c5fb5 as stripZeroWidthCharacters, $28624456cd7e4cb8$export$b1d6cb321dee12ad as replaceAlifMaqsurah, $28624456cd7e4cb8$export$db0c96cd03237332 as replaceEnglishPunctuationWithArabic, $28624456cd7e4cb8$export$1d28b07894af8a98 as normalizeAlifVariants, $f4495ebb65d3b1e0$export$814bebc253f2e5df as insertLineBreaksAfterPunctuation, $f4495ebb65d3b1e0$export$f0306841cd6b95d5 as addSpaceBeforeAndAfterPunctuation, $f4495ebb65d3b1e0$export$42f47e081bfe828c as applySmartQuotes, $f4495ebb65d3b1e0$export$b4922cc8c111eae2 as cleanLiteralNewLines, $f4495ebb65d3b1e0$export$95680a0d9bdd5dba as cleanMultilines, $f4495ebb65d3b1e0$export$20a121a9317a6ed4 as hasWordInSingleLine, $f4495ebb65d3b1e0$export$d936e191dd6a8e06 as isOnlyPunctuation, $f4495ebb65d3b1e0$export$38e1db3c2502e6cc as cleanJunkFromText, $f4495ebb65d3b1e0$export$e65ff0050dc4971d as cleanSpacesBeforePeriod, $f4495ebb65d3b1e0$export$6e89dcbda2f1dcad as condenseAsterisks, $f4495ebb65d3b1e0$export$64ee6721b5d4cefa as condenseColons, $f4495ebb65d3b1e0$export$9f873c000de6f69a as condenseDashes, $f4495ebb65d3b1e0$export$35abf980a52dfe44 as condenseEllipsis, $f4495ebb65d3b1e0$export$660f127778d3db20 as reduceMultilineBreaksToDouble, $f4495ebb65d3b1e0$export$7b984b558843c423 as reduceMultilineBreaksToSingle, $f4495ebb65d3b1e0$export$3468167fbf4483d7 as condensePeriods, $f4495ebb65d3b1e0$export$a299139a27d861bb as condenseUnderscores, $f4495ebb65d3b1e0$export$55102718dfa8db7e as doubleToSingleBrackets, $f4495ebb65d3b1e0$export$748703bb362bd52c as formatStringBySentence, $f4495ebb65d3b1e0$export$9027754b4b9f4cf4 as normalizeSlashInReferences, $f4495ebb65d3b1e0$export$85f748ccc2d3e888 as normalizeSpaces, $f4495ebb65d3b1e0$export$6726e05a22c5d4c9 as removeSpaceInsideBrackets, $f4495ebb65d3b1e0$export$6db2c5d62fd5ffe9 as stripBoldStyling, $f4495ebb65d3b1e0$export$9340b5fbcad6fe5a as stripItalicsStyling, $f4495ebb65d3b1e0$export$e166e222302a97bd as stripStyling, $f4495ebb65d3b1e0$export$eedf7f8c32995e56 as trimSpaceInsideQuotes, $0a00bc254018888e$export$62c7e2fbc3880e40 as normalizeJsonSyntax, $0a00bc254018888e$export$70726570eaa51acb as isJsonStructureValid, $0a00bc254018888e$export$ae2dc619900afbaa as splitByQuotes, $1f25f0941eacce7f$export$70476c4e7ef0b147 as cleanSymbolsAndPartReferences, $1f25f0941eacce7f$export$9f81734a6223638b as cleanTrailingPageNumbers, $1f25f0941eacce7f$export$631d05f860fc7118 as replaceLineBreaksWithSpaces, $1f25f0941eacce7f$export$edd6c3bb8fa3bc01 as stripAllDigits, $1f25f0941eacce7f$export$a537ffbd78859923 as removeDeathYear, $1f25f0941eacce7f$export$c8e7d4d7d9f46256 as removeNumbersAndDashes, $1f25f0941eacce7f$export$8e7f001aa315ad82 as removeSingleDigitReferences, $1f25f0941eacce7f$export$e4a0bb7881a4591a as removeUrls, $2d6eb7113bd26878$export$2a02c946f8bfe63e as normalizeArabicPrefixesToAl, $2d6eb7113bd26878$export$bdee7fc4cb327c1a as normalizeDoubleApostrophes, $2d6eb7113bd26878$export$a0f0be7fbc73baaa as replaceSalutationsWithSymbol, $2d6eb7113bd26878$export$a3295358bff77e as normalize, $2d6eb7113bd26878$export$a4e89c859f54cbf3 as normalizeApostrophes, $2d6eb7113bd26878$export$dcfbf7d1ecba5f64 as removeArabicPrefixes, $2d6eb7113bd26878$export$17df925670d0176a as normalizeTransliteratedEnglish, $2d6eb7113bd26878$export$d421e6fd95c29a67 as extractInitials};
501
+ export {$798f85a7713a6ff1$export$60dc7fb96c441688 as cleanExtremeArabicUnderscores, $798f85a7713a6ff1$export$dcf00cfaf31fd188 as convertUrduSymbolsToArabic, $798f85a7713a6ff1$export$6c58e29008d10c1d as fixTrailingWow, $798f85a7713a6ff1$export$cf81487e80b00e26 as addSpaceBetweenArabicTextAndNumbers, $798f85a7713a6ff1$export$df81ab2e9352ca65 as stripEnglishCharactersAndSymbols, $798f85a7713a6ff1$export$d580a3cb14401529 as removeNonIndexSignatures, $798f85a7713a6ff1$export$84d849da647fa2e5 as removeSingularCodes, $798f85a7713a6ff1$export$7dedbc726019ed0f as removeSolitaryArabicLetters, $798f85a7713a6ff1$export$9571c9c2c203652d as removeTatwil, $798f85a7713a6ff1$export$f95230335378ec58 as replaceTaMarbutahWithHa, $798f85a7713a6ff1$export$b5bee4b27048330b as stripDiacritics, $798f85a7713a6ff1$export$8696bb09194c5fb5 as stripZeroWidthCharacters, $798f85a7713a6ff1$export$b1d6cb321dee12ad as replaceAlifMaqsurah, $798f85a7713a6ff1$export$db0c96cd03237332 as replaceEnglishPunctuationWithArabic, $798f85a7713a6ff1$export$1d28b07894af8a98 as normalizeAlifVariants, $86c5c45def76a44f$export$814bebc253f2e5df as insertLineBreaksAfterPunctuation, $86c5c45def76a44f$export$f0306841cd6b95d5 as addSpaceBeforeAndAfterPunctuation, $86c5c45def76a44f$export$42f47e081bfe828c as applySmartQuotes, $86c5c45def76a44f$export$b4922cc8c111eae2 as cleanLiteralNewLines, $86c5c45def76a44f$export$95680a0d9bdd5dba as cleanMultilines, $86c5c45def76a44f$export$20a121a9317a6ed4 as hasWordInSingleLine, $86c5c45def76a44f$export$d936e191dd6a8e06 as isOnlyPunctuation, $86c5c45def76a44f$export$38e1db3c2502e6cc as cleanJunkFromText, $86c5c45def76a44f$export$e65ff0050dc4971d as cleanSpacesBeforePeriod, $86c5c45def76a44f$export$6e89dcbda2f1dcad as condenseAsterisks, $86c5c45def76a44f$export$64ee6721b5d4cefa as condenseColons, $86c5c45def76a44f$export$9f873c000de6f69a as condenseDashes, $86c5c45def76a44f$export$35abf980a52dfe44 as condenseEllipsis, $86c5c45def76a44f$export$660f127778d3db20 as reduceMultilineBreaksToDouble, $86c5c45def76a44f$export$7b984b558843c423 as reduceMultilineBreaksToSingle, $86c5c45def76a44f$export$3468167fbf4483d7 as condensePeriods, $86c5c45def76a44f$export$a299139a27d861bb as condenseUnderscores, $86c5c45def76a44f$export$55102718dfa8db7e as doubleToSingleBrackets, $86c5c45def76a44f$export$803cc4592448c009 as replaceDoubleBracketsWithArrows, $86c5c45def76a44f$export$748703bb362bd52c as formatStringBySentence, $86c5c45def76a44f$export$9027754b4b9f4cf4 as normalizeSlashInReferences, $86c5c45def76a44f$export$85f748ccc2d3e888 as normalizeSpaces, $86c5c45def76a44f$export$5c77851c03e0da0a as ensureSpaceBeforeBrackets, $86c5c45def76a44f$export$a97ebab70a927fe1 as removeRedundantPunctuation, $86c5c45def76a44f$export$6726e05a22c5d4c9 as removeSpaceInsideBrackets, $86c5c45def76a44f$export$6db2c5d62fd5ffe9 as stripBoldStyling, $86c5c45def76a44f$export$9340b5fbcad6fe5a as stripItalicsStyling, $86c5c45def76a44f$export$e166e222302a97bd as stripStyling, $86c5c45def76a44f$export$eedf7f8c32995e56 as trimSpaceInsideQuotes, $045191e51bf3eda2$export$62c7e2fbc3880e40 as normalizeJsonSyntax, $045191e51bf3eda2$export$70726570eaa51acb as isJsonStructureValid, $045191e51bf3eda2$export$ae2dc619900afbaa as splitByQuotes, $045191e51bf3eda2$export$1e23eb8d8fab7cc as isBalanced, $15eb38b546e8440a$export$70476c4e7ef0b147 as cleanSymbolsAndPartReferences, $15eb38b546e8440a$export$9f81734a6223638b as cleanTrailingPageNumbers, $15eb38b546e8440a$export$631d05f860fc7118 as replaceLineBreaksWithSpaces, $15eb38b546e8440a$export$edd6c3bb8fa3bc01 as stripAllDigits, $15eb38b546e8440a$export$a537ffbd78859923 as removeDeathYear, $15eb38b546e8440a$export$c8e7d4d7d9f46256 as removeNumbersAndDashes, $15eb38b546e8440a$export$8e7f001aa315ad82 as removeSingleDigitReferences, $15eb38b546e8440a$export$e4a0bb7881a4591a as removeUrls, $15eb38b546e8440a$export$6a506b36fdea397d as truncate, $15eb38b546e8440a$export$f3a88d5244308057 as truncateMiddle, $15eb38b546e8440a$export$1791d17c7d9c448 as unescapeSpaces, $0c91e05aa031e32a$export$2a02c946f8bfe63e as normalizeArabicPrefixesToAl, $0c91e05aa031e32a$export$bdee7fc4cb327c1a as normalizeDoubleApostrophes, $0c91e05aa031e32a$export$a0f0be7fbc73baaa as replaceSalutationsWithSymbol, $0c91e05aa031e32a$export$a3295358bff77e as normalize, $0c91e05aa031e32a$export$a4e89c859f54cbf3 as normalizeApostrophes, $0c91e05aa031e32a$export$dcfbf7d1ecba5f64 as removeArabicPrefixes, $0c91e05aa031e32a$export$17df925670d0176a as normalizeTransliteratedEnglish, $0c91e05aa031e32a$export$d421e6fd95c29a67 as extractInitials};
401
502
  //# sourceMappingURL=main.js.map
package/dist/main.js.map CHANGED
@@ -1 +1 @@
1
- {"mappings":"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","sources":["src/index.ts","src/arabic.ts","src/formatting.ts","src/parsing.ts","src/sanitization.ts","src/transliteration.ts"],"sourcesContent":["export * from './arabic';\nexport * from './formatting';\nexport * from './parsing';\nexport * from './sanitization';\nexport * from './transliteration';\n","/**\n * Removes extreme Arabic underscores (ـ) that appear at the beginning or end of a line or in text.\n * Does not affect Hijri dates (e.g., 1424هـ) or specific Arabic terms.\n * Example: \"ـThis is a textـ\" will be changed to \"This is a text\".\n * @param {string} text - The input text to apply the rule to.\n * @returns {string} - The modified text with extreme underscores removed.\n */\nexport const cleanExtremeArabicUnderscores = (text: string): string => {\n return text.replace(/(?<!\\d ?ه|اه)ـ(?=\\r?$)|^ـ(?!اهـ)/gm, '');\n};\n\n/**\n * Converts Urdu symbols to their Arabic equivalents.\n * Example: 'ھذا' will be changed to 'هذا', 'ی' to 'ي'.\n * @param {string} text - The input text containing Urdu symbols.\n * @returns {string} - The modified text with Urdu symbols converted to Arabic symbols.\n */\nexport const convertUrduSymbolsToArabic = (text: string): string => {\n return text.replace(/ھ/g, 'ه').replace(/ی/g, 'ي');\n};\n\n/**\n * Fixes the trailing \"و\" (wow) in phrases such as \"عليكم و رحمة\" to \"عليكم ورحمة\".\n * This function attempts to correct phrases where \"و\" appears unnecessarily, particularly in greetings.\n * Example: 'السلام عليكم و رحمة' will be changed to 'السلام عليكم ورحمة'.\n * @param {string} text - The input text containing the \"و\" character.\n * @returns {string} - The modified text with unnecessary trailing \"و\" characters corrected.\n */\nexport const fixTrailingWow = (text: string): string => {\n return text.replace(/ و /g, ' و');\n};\n\n/**\n * Inserts a space between Arabic text and numbers.\n * Example: 'الآية37' will be changed to 'الآية 37'.\n * @param {string} text - The input text containing Arabic text followed by numbers.\n * @returns {string} - The modified text with spaces inserted between Arabic text and numbers.\n */\nexport const addSpaceBetweenArabicTextAndNumbers = (text: string): string => {\n return text.replace(/([\\u0600-\\u06FF]+)(\\d+)/g, '$1 $2');\n};\n\n/**\n * Removes English letters and symbols from the text, including ampersands, slashes, and other symbols.\n * Example: 'أحب & لنفسي' will be changed to 'أحب لنفسي'.\n * @param {string} text - The input text containing English letters and symbols.\n * @returns {string} - The modified text with English letters and symbols removed.\n */\nexport const stripEnglishCharactersAndSymbols = (text: string): string => {\n return text.replace(/[a-zA-Z]+[0-9]*|[¬§`ﷺ=]|\\/{2,}|&/g, ' ');\n};\n\n/**\n * Removes single-digit numbers surrounded by Arabic text. Also removes dashes (-) not followed by a number.\n * For example, removes '3' from 'وهب 3 وقال' but does not remove '121' from 'لوحه 121 الجرح'.\n * @param {string} text - The input text to apply the rule to.\n * @returns {string} - The modified text with non-index numbers and dashes removed.\n */\nexport const removeNonIndexSignatures = (text: string): string => {\n return text\n .replace(/(?<![0-9] ?)-|(?<=[\\u0600-\\u06FF])\\s?\\d\\s?(?=[\\u0600-\\u06FF])/g, ' ')\n .replace(/(?<=[\\u0600-\\u06FF]\\s)(\\d+\\s)+\\d+(?=(\\s[\\u0600-\\u06FF]|$))/g, ' ');\n};\n\n/**\n * Removes characters enclosed in square brackets [] or parentheses () if they are Arabic letters or Arabic-Indic numerals.\n * Example: '[س]' or '(س)' will be removed.\n * @param {string} text - The input text to apply the rule to.\n * @returns {string} - The modified text with singular codes removed.\n */\nexport const removeSingularCodes = (text: string): string => {\n return text.replace(/[\\[\\({][\\u0621-\\u064A\\u0660-\\u0669][\\]\\)}]/g, '');\n};\n\n/**\n * Removes solitary Arabic letters unless they are the 'ha' letter, which is used in Hijri years.\n * Example: \"ب ا الكلمات ت\" will be changed to \"ا الكلمات\".\n * @param {string} text - The input text to apply the rule to.\n * @returns {string} - The modified text with solitary Arabic letters removed.\n */\nexport const removeSolitaryArabicLetters = (text: string): string => {\n return text.replace(/(^| )[\\u0621-\\u064A]( |$)/g, ' ');\n};\n\n/**\n * Removes tatweel characters while preserving dates references.\n * Example: \"1435/3/29 هـ\" remains as \"1435/3/29 هـ\" but \"أبـــتِـــكَةُ\" becomes \"أبتِكَةُ\"\n * @param text The text to format.\n * @returns The modified text with the tatweel characters removed.\n */\nexport const removeTatwil = (text: string) => {\n return text.replace(/(?<![0-9ه])ـ/g, '');\n};\n\n/**\n * Replaces the 'tah marbutah' (ة) character with 'ha' (ه).\n * Example: 'مدرسة' will be changed to 'مدرسه'.\n * @param {string} text - The input text to apply the rule to.\n * @returns {string} - The modified text with 'ta marbutah' replaced by 'ha'.\n */\nexport const replaceTaMarbutahWithHa = (text: string): string => {\n return text.replace(/[ة]/g, 'ه');\n};\n\n/**\n * Removes Arabic diacritics (tashkeel) and the tatweel (elongation) character.\n * Example: 'مُحَمَّدٌ' will be changed to 'محمد'.\n * @param {string} text - The input text to apply the rule to.\n * @returns {string} - The modified text with diacritics and tatweel removed.\n */\nexport const stripDiacritics = (text: string): string => {\n return text.replace(\n /[\\u0610\\u0611\\u0612\\u0613\\u0614\\u0615\\u0616\\u0617\\u0618\\u0619\\u061A\\u064B\\u064C\\u064D\\u064E\\u064F\\u0650\\u0651\\u0652\\u0653\\u0654\\u0655\\u0656\\u0657\\u0658\\u065A\\u065B\\u065C\\u065D\\u065E\\u0640]/g,\n '',\n );\n};\n\n/**\n * Removes zero-width joiners (ZWJ) and other zero-width characters from the input text.\n * Zero-width characters include U+200B to U+200F, U+202A to U+202E, U+2060 to U+2064, and U+FEFF.\n * @param {string} text - The input text to apply the rule to.\n * @returns {string} - The modified text with zero-width characters removed.\n */\nexport const stripZeroWidthCharacters = (text: string): string => {\n return text.replace(/[\\u200B-\\u200F\\u202A-\\u202E\\u2060-\\u2064\\uFEFF]/g, ' ');\n};\n\n/**\n * Replaces the 'alif maqsurah' (ى) character with the regular 'ya' (ي).\n * Example: 'رؤيى' will be changed to 'رؤيي'.\n * @param {string} text - The input text to apply the rule to.\n * @returns {string} - The modified text with 'alif maqsurah' replaced by 'ya'.\n */\nexport const replaceAlifMaqsurah = (text: string): string => {\n return text.replace(/[ىي]/g, 'ي');\n};\n\n/**\n * Replaces English punctuation (question mark and semicolon) with their Arabic equivalents.\n * Example: '?' will be replaced with '؟', and ';' with '؛'.\n * @param {string} text - The input text to apply the rule to.\n * @returns {string} - The modified text with English punctuation replaced by Arabic punctuation.\n */\nexport const replaceEnglishPunctuationWithArabic = (text: string): string => {\n return text\n .replace(/\\?|؟\\./g, '؟')\n .replace(/(;|؛)\\s*(\\1\\s*)*/g, '؛')\n .replace(/,|-،/g, '،');\n};\n\n/**\n * Simplifies all forms of 'alif' (أ, إ, and آ) to the basic 'ا'.\n * Example: 'أنا إلى الآفاق' will be changed to 'انا الى الافاق'.\n * @param {string} text - The input text to apply the rule to.\n * @returns {string} - The modified text with simplified 'alif' characters.\n */\nexport const normalizeAlifVariants = (text: string): string => {\n return text.replace(/[أإآ]/g, 'ا');\n};\n","/**\n * Adds line breaks after punctuation marks such as periods, exclamation points, and question marks.\n * Example: 'Text.' becomes 'Text.\\n'.\n * @param {string} text - The input text containing punctuation.\n * @returns {string} - The modified text with line breaks added after punctuation.\n */\nexport const insertLineBreaksAfterPunctuation = (text: string): string => {\n // Define the punctuation marks that should trigger a new line\n const punctuation = /([.?!؟])/g;\n\n // Replace occurrences of punctuation marks followed by a space with the punctuation mark, a newline, and the space\n const formattedText = text.replace(punctuation, '$1\\n').replace(/\\n\\s+/g, '\\n').trim();\n\n return formattedText;\n};\n\n/**\n * Adds spaces before and after punctuation, except for certain cases like quoted text or ayah references.\n * Example: 'Text,word' becomes 'Text, word'.\n * @param {string} text - The input text containing punctuation.\n * @returns {string} - The modified text with spaces added before and after punctuation.\n */\nexport const addSpaceBeforeAndAfterPunctuation = (text: string): string => {\n return text\n .replace(/( ?)([.!?,،؟;؛])((?![ '”“\\)\"\\]\\n])|(?=\\s{2,}))/g, '$1$2 ')\n .replace(/\\s([.!?,،؟;؛])\\s*([ '”“\\)\"\\]\\n])/g, '$1$2')\n .replace(/([^\\s\\w\\d'”“\\)\"\\]]+)\\s+([.!?,،؟;؛])|([.!?,،؟;؛])\\s+$/g, '$1$2$3')\n .replace(/(?<=\\D)( ?: ?)(?!(\\d+:)|(:\\d+))|(?<=\\d) ?: ?(?=\\D)|(?<=\\D) ?: ?(?=\\d)/g, ': ');\n};\n\n/**\n * Turns regular double quotes surrounding a body of text into smart quotes.\n * Also fixes incorrect starting quotes by ensuring the string starts with an opening quote if needed.\n * Example: 'The \"quick brown\" fox' becomes 'The “quick brown” fox'.\n * @param {string} text - The input text to apply the rule to.\n * @returns {string} - The modified text with smart quotes applied.\n */\nexport const applySmartQuotes = (text: string): string => {\n return text\n .replace(/[“”]/g, '\"')\n .replace(/\"([^\"]*)\"/g, '“$1”')\n .replace(/^”/g, '“');\n};\n\n/**\n * Replaces literal new line characters (\\n) and carriage returns (\\r) with actual line breaks.\n * Example: 'A\\\\nB' becomes 'A\\nB'.\n * @param {string} text - The input text containing literal new lines.\n * @returns {string} - The modified text with actual line breaks.\n */\nexport const cleanLiteralNewLines = (text: string): string => {\n return text.replace(/\\\\n|\\r/g, '\\n');\n};\n\n/**\n * Removes trailing spaces from each line in a multiline string.\n * Example: \" This is a line \\nAnother line \" becomes \"This is a line\\nAnother line\".\n * @param {string} text - The input text to apply the rule to.\n * @returns {string} - The modified text with trailing spaces removed.\n */\nexport const cleanMultilines = (text: string): string => {\n return text.replace(/^ +| +$/gm, '');\n};\n\n/**\n * Detects if a word is by itself in a line.\n * @param text The text to check.\n * @returns true if there exists a word in any of the lines in the text that is by itself.\n */\nexport const hasWordInSingleLine = (text: string): boolean => {\n return /^\\s*\\S+\\s*$/gm.test(text);\n};\n\n/**\n * Checks if the input string consists of only punctuation characters.\n * @param {string} text - The input text to check.\n * @returns {boolean} - Returns true if the string contains only punctuation, false otherwise.\n */\nexport const isOnlyPunctuation = (text: string): boolean => {\n const regex = /^[\\u0020-\\u002f\\u003a-\\u0040\\u005b-\\u0060\\u007b-\\u007e0-9٠-٩]+$/;\n return regex.test(text);\n};\n\nexport const cleanJunkFromText = (text: string): string => {\n const newBody = cleanMultilines(text);\n const lines = newBody.split('\\n').filter((line) => {\n return !line || (line.length > 1 && !isOnlyPunctuation(line));\n });\n\n return lines.join('\\n').trim();\n};\n\n/**\n * Cleans unnecessary spaces before punctuation marks such as periods, commas, and question marks.\n * Example: 'This is a sentence , with extra space .' becomes 'This is a sentence, with extra space.'.\n * @param {string} text - The input text to apply the rule to.\n * @returns {string} - The modified text with cleaned spaces before punctuation.\n */\nexport const cleanSpacesBeforePeriod = (text: string): string => {\n return text.replace(/\\s+([.؟!,،؛:?])/g, '$1');\n};\n\n/**\n * Condenses multiple asterisks (*) into a single one.\n * Example: '***' becomes '*'.\n * @param {string} text - The input text to apply the rule to.\n * @returns {string} - The modified text with condensed asterisks.\n */\nexport const condenseAsterisks = (text: string): string => {\n return text.replace(/(\\*\\s*)+/g, '*');\n};\n\n/**\n * Replaces occurrences of colons surrounded by periods (e.g., '.:.' or ':') with a single colon.\n * Example: 'This.:. is a test' becomes 'This: is a test'.\n * @param {string} text - The input text to apply the rule to.\n * @returns {string} - The modified text with condensed colons.\n */\nexport const condenseColons = (text: string): string => {\n return text.replace(/[\\.-]?:[\\.-]?/g, ':');\n};\n\n/**\n * Condenses two or more dashes (--) into a single dash (-).\n * Example: 'This is some ---- text' becomes 'This is some - text'.\n * @param {string} text - The input text to apply the rule to.\n * @returns {string} - The modified text with condensed dashes.\n */\nexport const condenseDashes = (text: string): string => {\n return text.replace(/-{2,}/g, '-');\n};\n\n/**\n * Replaces sequences of two or more periods (e.g., '...') with an ellipsis character (…).\n * Example: 'This is a test...' becomes 'This is a test…'.\n * @param {string} text - The input text to apply the rule to.\n * @returns {string} - The modified text with ellipses condensed.\n */\nexport const condenseEllipsis = (text: string): string => {\n return text.replace(/\\.{2,}/g, '…');\n};\n\n/**\n * Reduces multiple consecutive line breaks (3 or more) to exactly 2 line breaks.\n * Example: 'This is line 1\\n\\n\\n\\nThis is line 2' becomes 'This is line 1\\n\\nThis is line 2'.\n * @param {string} text - The input text to apply the rule to.\n * @returns {string} - The modified text with condensed line breaks.\n */\nexport const reduceMultilineBreaksToDouble = (text: string): string => {\n return text.replace(/(\\n\\s*){3,}/g, '\\n\\n');\n};\n\n/**\n * Reduces multiple consecutive line breaks (2 or more) to exactly 1 line break.\n * Example: 'This is line 1\\n\\nThis is line 2' becomes 'This is line 1\\nThis is line 2'.\n * @param {string} text - The input text to apply the rule to.\n * @returns {string} - The modified text with condensed line breaks.\n */\nexport const reduceMultilineBreaksToSingle = (text: string): string => {\n return text.replace(/(\\n\\s*){2,}/g, '\\n');\n};\n\n/**\n * Condenses multiple periods separated by spaces (e.g., '. . .') into a single period.\n * Example: 'This . . . is a test' becomes 'This. is a test'.\n * @param {string} text - The input text to apply the rule to.\n * @returns {string} - The modified text with condensed periods.\n */\nexport const condensePeriods = (text: string): string => {\n return text.replace(/\\. +\\./g, '.');\n};\n\n/**\n * Condenses multiple underscores (__) or Arabic Tatweel characters (ـــــ) into a single underscore or Tatweel.\n * Example: 'This is ـــ some text __' becomes 'This is ـ some text _'.\n * @param {string} text - The input text to apply the rule to.\n * @returns {string} - The modified text with condensed underscores.\n */\nexport const condenseUnderscores = (text: string): string => {\n return text.replace(/ـ{2,}/g, 'ـ').replace(/_+/g, '_');\n};\n\n/**\n * Replaces double parentheses or brackets with single ones.\n * Example: '((text))' becomes '(text)'.\n * @param {string} text - The input text to apply the rule to.\n * @returns {string} - The modified text with condensed brackets.\n */\nexport const doubleToSingleBrackets = (text: string): string => {\n return text.replace(/(\\(|\\)){2,}|(\\[|\\]){2,}/g, '$1$2');\n};\n\n/**\n * Formats a multiline string by joining sentences and maintaining footnotes on their own lines.\n * Footnotes are identified by Arabic and English numerals.\n * Example: 'Sentence one.\\n(1) A footnote.\\nSentence two.' remains the same, while regular sentences are joined.\n * @param {string} input - The input text containing sentences and footnotes.\n * @returns {string} - The formatted text.\n */\nexport const formatStringBySentence = (input: string): string => {\n const footnoteRegex = /^\\((?:\\d+|۱|۲|۳|۴|۵|۶|۷|۸|۹)\\)\\s/;\n const sentences: string[] = [];\n const lines = input.split('\\n');\n let currentSentence = '';\n\n lines.forEach((line) => {\n const trimmedLine = line.trim();\n const isFootnote = footnoteRegex.test(trimmedLine);\n const isNumber = /^\\(\\d+\\/\\d+\\)/.test(trimmedLine);\n\n if (isFootnote && !isNumber) {\n if (currentSentence) {\n sentences.push(currentSentence.trim());\n currentSentence = '';\n }\n sentences.push(trimmedLine);\n } else {\n currentSentence += `${trimmedLine} `;\n const lastChar = currentSentence.trim().slice(-1);\n if (/[.!؟]/.test(lastChar)) {\n sentences.push(currentSentence.trim());\n currentSentence = '';\n }\n }\n });\n\n // Add any remaining text to the output\n if (currentSentence) {\n sentences.push(currentSentence.trim());\n }\n\n return sentences.join('\\n');\n};\n\n/**\n * Removes unnecessary spaces around slashes in references.\n * Example: '127 / 11' becomes '127/11'.\n * @param {string} text - The input text containing references.\n * @returns {string} - The modified text with spaces removed around slashes.\n */\nexport const normalizeSlashInReferences = (text: string): string => {\n return text.replace(/(\\d+)\\s?\\/\\s?(\\d+)/g, '$1/$2');\n};\n\n/**\n * Reduces multiple spaces or tabs to a single space.\n * Example: 'This is a text' becomes 'This is a text'.\n * @param {string} text - The input text containing extra spaces.\n * @returns {string} - The modified text with reduced spaces.\n */\nexport const normalizeSpaces = (text: string): string => {\n return text.replace(/[ \\t]+/g, ' ');\n};\n\n/**\n * Removes spaces inside brackets, parentheses, or square brackets.\n * Example: '( a b )' becomes '(a b)'.\n * @param {string} text - The input text with spaces inside brackets.\n * @returns {string} - The modified text with spaces removed inside brackets.\n */\nexport const removeSpaceInsideBrackets = (text: string): string => {\n return text.replace(/([\\[\\(])\\s*(.*?)\\s*([\\]\\)])/g, '$1$2$3');\n};\n\n/**\n * Removes bold styling from text by normalizing the string and removing stylistic characters.\n * @param {string} text - The input text containing bold characters.\n * @returns {string} - The modified text with bold styling removed.\n */\nexport const stripBoldStyling = (text: string): string => {\n // Normalize the string to NFKD form\n const normalizedString = text.normalize('NFKD');\n\n // Remove combining marks (diacritics) and stylistic characters from the string\n return normalizedString.replace(/[\\u0300-\\u036f]/g, '').trim();\n};\n\n/**\n * Removes italicized characters by replacing italic Unicode characters with their normal counterparts.\n * Example: '𝘼𝘽𝘾' becomes 'ABC'.\n * @param {string} text - The input text containing italicized characters.\n * @returns {string} - The modified text with italics removed.\n */\nexport const stripItalicsStyling = (text: string): string => {\n const italicMap: Record<string, string> = {\n '\\uD835\\uDC4E': 'I',\n '\\uD835\\uDC68': 'g',\n '\\u{1D63C}': '!',\n '\\uD835\\uDC4F': 'J',\n '\\uD835\\uDC69': 'h',\n '\\u{1D63D}': '?',\n '\\uD835\\uDC50': 'K',\n '\\uD835\\uDC6A': 'i',\n '\\uD835\\uDC51': 'L',\n '\\uD835\\uDC6B': 'j',\n '\\u{1D63F}': ',',\n '\\uD835\\uDC52': 'M',\n '\\uD835\\uDC6C': 'k',\n '\\u{1D640}': '.',\n '\\uD835\\uDC53': 'N',\n '\\uD835\\uDC6D': 'l',\n '\\uD835\\uDC54': 'O',\n '\\uD835\\uDC6E': 'm',\n '\\uD835\\uDC6F': 'n',\n '\\uD835\\uDC56': 'Q',\n '\\uD835\\uDC70': 'o',\n '\\uD835\\uDC57': 'R',\n '\\uD835\\uDC71': 'p',\n '\\uD835\\uDC58': 'S',\n '\\uD835\\uDC72': 'q',\n '\\uD835\\uDC59': 'T',\n '\\uD835\\uDC73': 'r',\n '\\u{1D647}': '-',\n '\\uD835\\uDC5A': 'U',\n '\\uD835\\uDC74': 's',\n '\\uD835\\uDC5B': 'V',\n '\\uD835\\uDC75': 't',\n '\\uD835\\uDC5C': 'W',\n '\\uD835\\uDC76': 'u',\n '\\uD835\\uDC5D': 'X',\n '\\uD835\\uDC77': 'v',\n '\\uD835\\uDC5E': 'Y',\n '\\uD835\\uDC78': 'w',\n '\\uD835\\uDC5F': 'Z',\n '\\uD835\\uDC79': 'x',\n '\\uD835\\uDC46': 'A',\n '\\uD835\\uDC7A': 'y',\n '\\uD835\\uDC47': 'B',\n '\\uD835\\uDC7B': 'z',\n '\\uD835\\uDC62': 'a',\n '\\uD835\\uDC48': 'C',\n '\\uD835\\uDC63': 'b',\n '\\uD835\\uDC49': 'D',\n '\\uD835\\uDC64': 'c',\n '\\uD835\\uDC4A': 'E',\n '\\uD835\\uDC65': 'd',\n '\\uD835\\uDC4B': 'F',\n '\\uD835\\uDC66': 'e',\n '\\uD835\\uDC4C': 'G',\n '\\uD835\\uDC67': 'f',\n '\\uD835\\uDC4D': 'H',\n '\\uD835\\uDC55': 'P',\n };\n\n return text.replace(/[\\uD835\\uDC62-\\uD835\\uDC7B\\uD835\\uDC46-\\uD835\\uDC5F\\u{1D63C}-\\u{1D647}]/gu, (match) => {\n return italicMap[match] || match;\n });\n};\n\n/**\n * Removes all bold and italic styling from the input text.\n * @param {string} text - The input text to remove styling from.\n * @returns {string} - The modified text with all styling removed.\n */\nexport const stripStyling = (text: string): string => {\n return stripItalicsStyling(stripBoldStyling(text));\n};\n\n/**\n * Removes unnecessary spaces inside quotes.\n * Example: '“ Text ”' becomes '“Text”'.\n * @param {string} text - The input text with spaces inside quotes.\n * @returns {string} - The modified text with spaces removed inside quotes.\n */\nexport const trimSpaceInsideQuotes = (text: string): string => {\n return text.replace(/([“”\"]|«) *(.*?) *([“”\"]|»)/g, '$1$2$3');\n};\n","/**\n * Converts a string that resembles JSON but with numeric keys and single-quoted values\n * into valid JSON format. This function replaces numeric keys with quoted numeric keys\n * and ensures all values are double-quoted as required by JSON.\n *\n * @param {string} str - The input string that needs to be fixed into valid JSON.\n * @returns {string} - A valid JSON string.\n *\n * @example\n * const result = normalizeJsonSyntax(\"{10: 'abc', 20: 'def'}\");\n * console.log(result); // '{\"10\": \"abc\", \"20\": \"def\"}'\n */\nexport const normalizeJsonSyntax = (str: string): string => {\n let input = str.replace(/(\\b\\d+\\b)(?=:)/g, '\"$1\"');\n input = input.replace(/:\\s*'([^']+)'/g, ': \"$1\"');\n input = input.replace(/:\\s*\"([^\"]+)\"/g, ': \"$1\"');\n\n return JSON.stringify(JSON.parse(input));\n};\n\n/**\n * Checks if a given string resembles a JSON object with numeric or quoted keys and values\n * that are single or double quoted. This is useful for detecting malformed JSON-like\n * structures that can be fixed by the `normalizeJsonSyntax` function.\n *\n * @param {string} str - The input string to check.\n * @returns {boolean} - Returns true if the string is JSON-like, false otherwise.\n *\n * @example\n * const result = isJsonStructureValid(\"{10: 'abc', 'key': 'value'}\");\n * console.log(result); // true\n */\nexport const isJsonStructureValid = (str: string): boolean => {\n // Checks for a pattern with numeric keys or quoted keys and values in quotes\n const jsonLikePattern =\n /^{(\\s*(\\d+|'[^']*'|\"[^\"]*\")\\s*:\\s*('|\")[^'\"]*\\3\\s*,)*(?:\\s*(\\d+|'[^']*'|\"[^\"]*\")\\s*:\\s*('|\")[^'\"]*\\5\\s*)}$/;\n return jsonLikePattern.test(str.trim());\n};\n\n/**\n * Splits a string by spaces and quoted substrings.\n *\n * This function takes an input string and splits it into parts where substrings\n * enclosed in double quotes are treated as a single part. Other substrings\n * separated by spaces are split normally.\n *\n * @param {string} query - The input string to be split.\n * @returns {string[]} An array of strings, with quoted substrings kept intact.\n *\n * @example\n * const result = splitByQuotes('\"This is\" \"a part of the\" \"string and\"');\n * console.log(result); // [\"This is\", \"a part of the\", \"string and\"]\n */\nexport const splitByQuotes = (query: string): string[] => {\n const regex = /(?:[^\\s\"]+|\"(.*?)\")+/g;\n return (query.match(regex) || []).map((s: string) => (s.startsWith('\"') ? s.slice(1, -1) : s));\n};\n","/**\n * Removes various symbols, part references, and numerical markers from the text.\n * Example: '(1) (2/3)' becomes ''.\n * @param {string} text - The input text to apply the rule to.\n * @returns {string} - The modified text with symbols and part references removed.\n */\nexport const cleanSymbolsAndPartReferences = (text: string): string => {\n return text.replace(\n / *\\(?:\\d+(?:\\/\\d+){0,2}\\)? *| *\\[\\d+(?:\\/\\d+)?\\] *| *«\\d+» *|\\d+\\/\\d+(?:\\/\\d+)?|[،§{}۝؍‎﴿﴾<>;_؟»«:!،؛\\[\\]…ـ¬\\.\\\\\\/\\*\\(\\)\"]/g,\n ' ',\n );\n};\n\n/**\n * Removes trailing page numbers formatted as '-[46]-' from the text.\n * Example: 'This is some -[46]- text' becomes 'This is some text'.\n * @param {string} text - The input text with trailing page numbers.\n * @returns {string} - The modified text with page numbers removed.\n */\nexport const cleanTrailingPageNumbers = (text: string): string => {\n return text.replace(/-\\[\\d+\\]-/g, '');\n};\n\n/**\n * Replaces consecutive line breaks and whitespace characters with a single space.\n * Example: 'a\\nb' becomes 'a b'.\n * @param {string} text - The input text containing line breaks or multiple spaces.\n * @returns {string} - The modified text with spaces.\n */\nexport const replaceLineBreaksWithSpaces = (text: string): string => {\n return text.replace(/\\s+/g, ' ');\n};\n\n/**\n * Removes all numeric digits from the text.\n * Example: 'abc123' becomes 'abc'.\n * @param {string} text - The input text containing digits.\n * @returns {string} - The modified text with digits removed.\n */\nexport const stripAllDigits = (text: string): string => {\n return text.replace(/[0-9]/g, '');\n};\n\n/**\n * Removes death year references like \"(d. 390H)\" and \"[d. 100h]\" from the text.\n * Example: 'Sufyān ibn ‘Uyaynah (d. 198h)' becomes 'Sufyān ibn ‘Uyaynah'.\n * @param {string} text - The input text containing death year references.\n * @returns {string} - The modified text with death years removed.\n */\nexport const removeDeathYear = (text: string): string => {\n return text.replace(/\\[(d)\\.\\s*\\d{1,4}[hH]\\]\\s*|\\((d)\\.\\s*\\d{1,4}[hH]\\)\\s*/g, '');\n};\n\n/**\n * Removes numeric digits and dashes from the text.\n * Example: 'ABC 123-Xyz' becomes 'ABC Xyz'.\n * @param {string} text - The input text containing digits and dashes.\n * @returns {string} - The modified text with numbers and dashes removed.\n */\nexport const removeNumbersAndDashes = (text: string): string => {\n return text.replace(/[\\d-]/g, '');\n};\n\n/**\n * Removes single digit references like (1), «2», [3] from the text.\n * Example: 'Ref (1), Ref «2», Ref [3]' becomes 'Ref , Ref , Ref '.\n * @param {string} text - The input text containing single digit references.\n * @returns {string} - The modified text with single digit references removed.\n */\nexport const removeSingleDigitReferences = (text: string): string => {\n return text.replace(/\\(\\d{1}\\)|\\[\\d{1}\\]|«\\d»/g, '');\n};\n\n/**\n * Removes URLs from the text.\n * Example: 'Visit https://example.com' becomes 'Visit '.\n * @param {string} text - The input text containing URLs.\n * @returns {string} - The modified text with URLs removed.\n */\nexport const removeUrls = (text: string): string => {\n return text.replace(\n /https?:\\/\\/(www\\.)?[-a-zA-Z0-9@:%._+~#=]{1,256}\\.[a-zA-Z0-9()]{1,6}\\b([-a-zA-Z0-9()@:%_+.~#?&//=]*)/g,\n '',\n );\n};\n","import { normalizeSpaces } from './formatting';\n\n/**\n * Replaces common Arabic prefixes (like 'Al-', 'Ar-', 'Ash-', etc.) with 'al-' in the text.\n * Handles different variations of prefixes such as Ash- and Al- but not when the second word\n * does not start with 'S'.\n * Example: 'Ash-Shafiee' becomes 'al-Shafiee'.\n *\n * @param {string} text - The input text containing Arabic prefixes.\n * @returns {string} - The modified text with standardized 'al-' prefixes.\n */\nexport const normalizeArabicPrefixesToAl = (text: string): string => {\n return text\n .replace(/(\\b|\\W)(Al |Al-|Ar-|As-|Adh-|Ad-|Ats-|Ath |Ath-|Az |Az-|az-|adh-|as-|ar-)/g, '$1al-')\n .replace(/(\\b|\\W)(Ash-S|ash-S)/g, '$1al-S')\n .replace(/al- (.+?)\\b/g, 'al-$1');\n};\n\n/**\n * Removes double occurrences of Arabic apostrophes such as ʿʿ or ʾʾ in the text.\n * Example: 'ʿulamāʾʾ' becomes 'ʿulamāʾ'.\n *\n * @param {string} text - The input text containing double apostrophes.\n * @returns {string} - The modified text with condensed apostrophes.\n */\nexport const normalizeDoubleApostrophes = (text: string): string => {\n return text.replace(/ʿʿ/g, 'ʿ').replace(/ʾʾ/g, 'ʾ');\n};\n\n/**\n * Replaces common salutations such as \"sallahu alayhi wasallam\" with \"ﷺ\" in the text.\n * It also handles variations of the salutation phrase, including 'peace and blessings be upon him'.\n * Example: 'Then Muḥammad (sallahu alayhi wasallam)' becomes 'Then Muḥammad ﷺ'.\n *\n * @param {string} text - The input text containing salutations.\n * @returns {string} - The modified text with salutations replaced.\n */\nexport const replaceSalutationsWithSymbol = (text: string): string => {\n return text\n .replace(\n /\\(peace be upon him\\)|(Messenger of (Allah|Allāh)|Messenger|Prophet|Mu[hḥ]ammad) *\\((s[^)]*m|peace[^)]*him|May[^)]*him|may[^)]*him)\\)*/gi,\n '$1 ﷺ',\n )\n .replace(/,\\s*ﷺ\\s*,/g, ' ﷺ');\n};\n\n/**\n * Normalizes the text by removing diacritics, apostrophes, and dashes.\n * Example: 'Al-Jadwal' becomes 'AlJadwal'.\n *\n * @param {string} input - The input text to normalize.\n * @returns {string} - The normalized text.\n */\nexport const normalize = (input: string) => {\n return input\n .normalize('NFKD')\n .replace(/[\\u0300-\\u036f]/g, '')\n .replace(/`|ʾ|ʿ|-/g, '');\n};\n\n/**\n * Replaces various apostrophe characters (‛, ’, ‘) with the standard apostrophe (').\n * Example: '‛ulama’ al-su‘' becomes ''ulama' al-su''.\n *\n * @param {string} text - The input text containing different apostrophe characters.\n * @returns {string} - The modified text with normalized apostrophes.\n */\nexport const normalizeApostrophes = (text: string): string => {\n return text.replace(/‛|’|‘/g, \"'\");\n};\n\n/**\n * Strips common Arabic prefixes like 'al-', 'bi-', 'fī', 'wa-', etc. from the beginning of words.\n * Example: 'al-Bukhari' becomes 'Bukhari'.\n *\n * @param {string} text - The input text containing Arabic prefixes.\n * @returns {string} - The modified text with prefixes stripped.\n */\nexport const removeArabicPrefixes = (text: string): string => {\n return normalizeSpaces(text.replace(/(\\bal-|\\bli-|\\bbi-|\\bfī|\\bwa[-\\s]+|\\bl-|\\bliʿl|\\Bʿalá|\\Bʿan|\\bb\\.)/gi, ''));\n};\n\n/**\n * Simplifies English transliterations by removing diacritics, apostrophes, and common prefixes.\n * Example: 'Al-Jadwal' becomes 'Jadwal', and 'āḍġḥīṣṭū' becomes 'adghistu'.\n *\n * @param {string} text - The input text to simplify.\n * @returns {string} - The simplified text.\n */\nexport const normalizeTransliteratedEnglish = (text: string): string => normalize(removeArabicPrefixes(text));\n\n/**\n * Extracts the initials from the input string, typically used for names or titles.\n * Example: 'Nayl al-Awtar' becomes 'NA'.\n *\n * @param {string} text - The input text to extract initials from.\n * @returns {string} - The extracted initials.\n */\nexport const extractInitials = (fullName: string) => {\n const initials = normalizeTransliteratedEnglish(fullName)\n .trim()\n .split(/[ -]/)\n .slice(0, 2)\n .map((word) => {\n return word.charAt(0).toUpperCase();\n })\n .join('');\n return initials;\n};\n"],"names":[],"version":3,"file":"main.js.map","sourceRoot":"../"}
1
+ {"mappings":";;;;;;;;;;;;;;;;;;;;;ACAA;;;;;;CAMC,GACM,MAAM,4CAAgC,CAAC;IAC1C,OAAO,KAAK,OAAO,CAAC,sCAAsC;AAC9D;AAQO,MAAM,4CAA6B,CAAC;IACvC,OAAO,KAAK,OAAO,CAAC,MAAM,UAAK,OAAO,CAAC,MAAM;AACjD;AASO,MAAM,4CAAiB,CAAC;IAC3B,OAAO,KAAK,OAAO,CAAC,QAAQ;AAChC;AAQO,MAAM,4CAAsC,CAAC;IAChD,OAAO,KAAK,OAAO,CAAC,4BAA4B;AACpD;AAQO,MAAM,4CAAmC,CAAC;IAC7C,OAAO,KAAK,OAAO,CAAC,yCAAyC;AACjE;AAQO,MAAM,4CAA2B,CAAC;IACrC,OAAO,KACF,OAAO,CAAC,kEAAkE,KAC1E,OAAO,CAAC,+DAA+D;AAChF;AAQO,MAAM,4CAAsB,CAAC;IAChC,OAAO,KAAK,OAAO,CAAC,4CAA4C;AACpE;AAQO,MAAM,4CAA8B,CAAC;IACxC,OAAO,KAAK,OAAO,CAAC,8BAA8B;AACtD;AAQO,MAAM,4CAAe,CAAC;IACzB,2BAA2B;IAC3B,qEAAqE;IACrE,2EAA2E;IAC3E,OAAO,KAAK,OAAO,CAAC,8BAA8B;AACtD;AAQO,MAAM,4CAA0B,CAAC;IACpC,OAAO,KAAK,OAAO,CAAC,QAAQ;AAChC;AAQO,MAAM,4CAAkB,CAAC;IAC5B,OAAO,KAAK,OAAO,CACf,iMACA;AAER;AAQO,MAAM,4CAA2B,CAAC;IACrC,OAAO,KAAK,OAAO,CAAC,oDAAoD;AAC5E;AAQO,MAAM,4CAAsB,CAAC;IAChC,OAAO,KAAK,OAAO,CAAC,SAAS;AACjC;AAQO,MAAM,4CAAsC,CAAC;IAChD,OAAO,KACF,OAAO,CAAC,WAAW,UACnB,OAAO,CAAC,qBAAqB,UAC7B,OAAO,CAAC,SAAS;AAC1B;AAQO,MAAM,4CAAwB,CAAC;IAClC,OAAO,KAAK,OAAO,CAAC,UAAU;AAClC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACjKA;;;;;CAKC,GACM,MAAM,4CAAmC,CAAC;IAC7C,8DAA8D;IAC9D,MAAM,cAAc;IAEpB,mHAAmH;IACnH,MAAM,gBAAgB,KAAK,OAAO,CAAC,aAAa,QAAQ,OAAO,CAAC,UAAU,MAAM,IAAI;IAEpF,OAAO;AACX;AAQO,MAAM,4CAAoC,CAAC;IAC9C,OAAO,KACF,OAAO,CAAC,kDAAkD,SAC1D,OAAO,CAAC,oCAAoC,QAC5C,OAAO,CAAC,wDAAwD,UAChE,OAAO,CAAC,0EAA0E;AAC3F;AASO,MAAM,4CAAmB,CAAC;IAC7B,OAAO,KACF,OAAO,CAAC,SAAS,KACjB,OAAO,CAAC,cAAc,kBACtB,OAAO,CAAC,OAAO;AACxB;AAQO,MAAM,4CAAuB,CAAC;IACjC,OAAO,KAAK,OAAO,CAAC,WAAW;AACnC;AAQO,MAAM,4CAAkB,CAAC;IAC5B,OAAO,KAAK,OAAO,CAAC,aAAa;AACrC;AAOO,MAAM,4CAAsB,CAAC;IAChC,OAAO,gBAAgB,IAAI,CAAC;AAChC;AAOO,MAAM,4CAAoB,CAAC;IAC9B,MAAM,QAAQ;IACd,OAAO,MAAM,IAAI,CAAC;AACtB;AAEO,MAAM,4CAAoB,CAAC;IAC9B,MAAM,UAAU,0CAAgB;IAChC,MAAM,QAAQ,QAAQ,KAAK,CAAC,MAAM,MAAM,CAAC,CAAC;QACtC,OAAO,CAAC,QAAS,KAAK,MAAM,GAAG,KAAK,CAAC,0CAAkB;IAC3D;IAEA,OAAO,MAAM,IAAI,CAAC,MAAM,IAAI;AAChC;AAQO,MAAM,4CAA0B,CAAC;IACpC,OAAO,KAAK,OAAO,CAAC,oBAAoB;AAC5C;AAQO,MAAM,4CAAoB,CAAC;IAC9B,OAAO,KAAK,OAAO,CAAC,aAAa;AACrC;AAQO,MAAM,4CAAiB,CAAC;IAC3B,OAAO,KAAK,OAAO,CAAC,gBAAgB;AACxC;AAQO,MAAM,4CAAiB,CAAC;IAC3B,OAAO,KAAK,OAAO,CAAC,UAAU;AAClC;AAQO,MAAM,4CAAmB,CAAC;IAC7B,OAAO,KAAK,OAAO,CAAC,WAAW;AACnC;AAQO,MAAM,4CAAgC,CAAC;IAC1C,OAAO,KAAK,OAAO,CAAC,gBAAgB;AACxC;AAQO,MAAM,4CAAgC,CAAC;IAC1C,OAAO,KAAK,OAAO,CAAC,gBAAgB;AACxC;AAQO,MAAM,4CAAkB,CAAC;IAC5B,OAAO,KAAK,OAAO,CAAC,WAAW;AACnC;AAQO,MAAM,4CAAsB,CAAC;IAChC,OAAO,KAAK,OAAO,CAAC,UAAU,UAAK,OAAO,CAAC,OAAO;AACtD;AAQO,MAAM,4CAAyB,CAAC;IACnC,OAAO,KAAK,OAAO,CAAC,4BAA4B;AACpD;AAQO,MAAM,4CAAkC,CAAC;IAC5C,OAAO,KAAK,OAAO,CAAC,YAAY,QAAK,OAAO,CAAC,YAAY;AAC7D;AASO,MAAM,4CAAyB,CAAC;IACnC,MAAM,gBAAgB;IACtB,MAAM,YAAsB,EAAE;IAC9B,MAAM,QAAQ,MAAM,KAAK,CAAC;IAC1B,IAAI,kBAAkB;IAEtB,MAAM,OAAO,CAAC,CAAC;QACX,MAAM,cAAc,KAAK,IAAI;QAC7B,MAAM,aAAa,cAAc,IAAI,CAAC;QACtC,MAAM,WAAW,gBAAgB,IAAI,CAAC;QAEtC,IAAI,cAAc,CAAC,UAAU;YACzB,IAAI,iBAAiB;gBACjB,UAAU,IAAI,CAAC,gBAAgB,IAAI;gBACnC,kBAAkB;YACtB;YACA,UAAU,IAAI,CAAC;QACnB,OAAO;YACH,mBAAmB,GAAG,YAAY,CAAC,CAAC;YACpC,MAAM,WAAW,gBAAgB,IAAI,GAAG,KAAK,CAAC;YAC9C,IAAI,QAAQ,IAAI,CAAC,WAAW;gBACxB,UAAU,IAAI,CAAC,gBAAgB,IAAI;gBACnC,kBAAkB;YACtB;QACJ;IACJ;IAEA,uCAAuC;IACvC,IAAI,iBACA,UAAU,IAAI,CAAC,gBAAgB,IAAI;IAGvC,OAAO,UAAU,IAAI,CAAC;AAC1B;AAQO,MAAM,4CAA6B,CAAC;IACvC,OAAO,KAAK,OAAO,CAAC,uBAAuB;AAC/C;AAQO,MAAM,4CAAkB,CAAC;IAC5B,OAAO,KAAK,OAAO,CAAC,WAAW;AACnC;AAQO,MAAM,4CAA4B,CAAC;IACtC,OAAO,KAAK,OAAO,CAAC,sBAAsB;AAC9C;AAkBO,MAAM,4CAA6B,CAAC;IACvC,OAAO,KAAK,OAAO,CAAC,eAAe;AACvC;AAQO,MAAM,4CAA4B,CAAC;IACtC,OAAO,KAAK,OAAO,CAAC,6BAA6B;AACrD;AAOO,MAAM,4CAAmB,CAAC;IAC7B,oCAAoC;IACpC,MAAM,mBAAmB,KAAK,SAAS,CAAC;IAExC,+EAA+E;IAC/E,OAAO,iBAAiB,OAAO,CAAC,oBAAoB,IAAI,IAAI;AAChE;AAQO,MAAM,4CAAsB,CAAC;IAChC,MAAM,YAAoC;QACtC,gBAAgB;QAChB,gBAAgB;QAChB,gBAAa;QACb,gBAAgB;QAChB,gBAAgB;QAChB,gBAAa;QACb,gBAAgB;QAChB,gBAAgB;QAChB,gBAAgB;QAChB,gBAAgB;QAChB,gBAAa;QACb,gBAAgB;QAChB,gBAAgB;QAChB,gBAAa;QACb,gBAAgB;QAChB,gBAAgB;QAChB,gBAAgB;QAChB,gBAAgB;QAChB,gBAAgB;QAChB,gBAAgB;QAChB,gBAAgB;QAChB,gBAAgB;QAChB,gBAAgB;QAChB,gBAAgB;QAChB,gBAAgB;QAChB,gBAAgB;QAChB,gBAAgB;QAChB,gBAAa;QACb,gBAAgB;QAChB,gBAAgB;QAChB,gBAAgB;QAChB,gBAAgB;QAChB,gBAAgB;QAChB,gBAAgB;QAChB,gBAAgB;QAChB,gBAAgB;QAChB,gBAAgB;QAChB,gBAAgB;QAChB,gBAAgB;QAChB,gBAAgB;QAChB,gBAAgB;QAChB,gBAAgB;QAChB,gBAAgB;QAChB,gBAAgB;QAChB,gBAAgB;QAChB,gBAAgB;QAChB,gBAAgB;QAChB,gBAAgB;QAChB,gBAAgB;QAChB,gBAAgB;QAChB,gBAAgB;QAChB,gBAAgB;QAChB,gBAAgB;QAChB,gBAAgB;QAChB,gBAAgB;QAChB,gBAAgB;QAChB,gBAAgB;IACpB;IAEA,OAAO,KAAK,OAAO,CAAC,6EAA6E,CAAC;QAC9F,OAAO,SAAS,CAAC,MAAM,IAAI;IAC/B;AACJ;AAOO,MAAM,4CAAe,CAAC;IACzB,OAAO,0CAAoB,0CAAiB;AAChD;AAQO,MAAM,4CAAwB,CAAC;IAClC,OAAO,KAAK,OAAO,CAAC,gCAAgC;AACxD;;;;;;;;;ACtZA;;;;;;;;;;;CAWC,GACM,MAAM,4CAAsB,CAAC;IAChC,IAAI,QAAQ,IAAI,OAAO,CAAC,mBAAmB;IAC3C,QAAQ,MAAM,OAAO,CAAC,kBAAkB;IACxC,QAAQ,MAAM,OAAO,CAAC,kBAAkB;IAExC,OAAO,KAAK,SAAS,CAAC,KAAK,KAAK,CAAC;AACrC;AAcO,MAAM,4CAAuB,CAAC;IACjC,6EAA6E;IAC7E,MAAM,kBACF;IACJ,OAAO,gBAAgB,IAAI,CAAC,IAAI,IAAI;AACxC;AAgBO,MAAM,4CAAgB,CAAC;IAC1B,MAAM,QAAQ;IACd,OAAO,AAAC,CAAA,MAAM,KAAK,CAAC,UAAU,EAAE,AAAD,EAAG,GAAG,CAAC,CAAC,IAAe,EAAE,UAAU,CAAC,OAAO,EAAE,KAAK,CAAC,GAAG,MAAM;AAC/F;AAEA;;;;;;;;;;;;;CAaC,GACD,MAAM,0CAAoB,CAAC;IACvB,IAAI,aAAa;IACjB,KAAK,MAAM,QAAQ,IACf,IAAI,SAAS,KACT;IAGR,OAAO,aAAa,MAAM;AAC9B;AAEA,MAAM,iCAAW;IAAE,KAAK;IAAK,KAAK;IAAK,KAAK;AAAI;AAChD,MAAM,qCAAe,IAAI,IAAI;IAAC;IAAK;IAAK;CAAI;AAC5C,MAAM,sCAAgB,IAAI,IAAI;IAAC;IAAK;IAAK;CAAI;AAE7C;;;;;;;;;;;;;;;;;CAiBC,GAED,MAAM,4CAAsB,CAAC;IACzB,MAAM,QAAkB,EAAE;IAE1B,KAAK,MAAM,QAAQ,IAAK;QACpB,IAAI,mCAAa,GAAG,CAAC,OACjB,MAAM,IAAI,CAAC;aACR,IAAI,oCAAc,GAAG,CAAC,OAAO;YAChC,MAAM,WAAW,MAAM,GAAG;YAC1B,IAAI,CAAC,YAAY,8BAAQ,CAAC,SAAkC,KAAK,MAC7D,OAAO;QAEf;IACJ;IAEA,OAAO,MAAM,MAAM,KAAK;AAC5B;AAsBO,MAAM,2CAAa,CAAC;IACvB,OAAO,wCAAkB,QAAQ,0CAAoB;AACzD;;;;;;;;;;;;;;;;AChJA;;;;;CAKC,GACM,MAAM,4CAAgC,CAAC;IAC1C,OAAO,KAAK,OAAO,CACf,yHACA;AAER;AAQO,MAAM,4CAA2B,CAAC;IACrC,OAAO,KAAK,OAAO,CAAC,cAAc;AACtC;AAQO,MAAM,4CAA8B,CAAC;IACxC,OAAO,KAAK,OAAO,CAAC,QAAQ;AAChC;AAQO,MAAM,4CAAiB,CAAC;IAC3B,OAAO,KAAK,OAAO,CAAC,UAAU;AAClC;AAQO,MAAM,4CAAkB,CAAC;IAC5B,OAAO,KAAK,OAAO,CAAC,0DAA0D;AAClF;AAQO,MAAM,4CAAyB,CAAC;IACnC,OAAO,KAAK,OAAO,CAAC,UAAU;AAClC;AAQO,MAAM,4CAA8B,CAAC;IACxC,OAAO,KAAK,OAAO,CAAC,6BAA6B;AACrD;AAQO,MAAM,4CAAa,CAAC;IACvB,OAAO,KAAK,OAAO,CACf,wGACA;AAER;AAkBO,MAAM,4CAAW,CAAC,KAAa,IAAI,GAAG,GAAc,IAAI,MAAM,GAAG,IAAI,GAAG,IAAI,SAAS,CAAC,GAAG,IAAI,GAAG,QAAC,CAAC,GAAG;AAsBrG,MAAM,4CAAiB,CAAC,MAAc,YAAoB,EAAE,EAAE;IACjE,IAAI,KAAK,MAAM,IAAI,WACf,OAAO;IAGX,wEAAwE;IACxE,MAAM,mBAAmB,KAAK,GAAG,CAAC,GAAG,KAAK,KAAK,CAAC,YAAY;IAC5D,MAAM,kBAAkB,aAAa;IAErC,oDAAoD;IACpD,MAAM,kBAAkB,YAAY;IAEpC,6DAA6D;IAC7D,MAAM,cAAc,kBAAkB;IAEtC,uDAAuD;IACvD,IAAI,cAAc,GACd,6DAA6D;IAC7D,OAAO,GAAG,KAAK,SAAS,CAAC,GAAG,YAAY,GAAG,QAAC,CAAC;IAGjD,MAAM,eAAe,KAAK,SAAS,CAAC,GAAG;IACvC,MAAM,aAAa,KAAK,SAAS,CAAC,KAAK,MAAM,GAAG;IAEhD,OAAO,GAAG,aAAa,QAAC,EAAE,YAAY;AAC1C;AAqBO,MAAM,2CAAiB,CAAC,QAAkB,MAAM,OAAO,CAAC,QAAQ,KAAK,IAAI;;;;;;;;;;;;;;AC/JzE,MAAM,4CAA8B,CAAC;IACxC,OAAO,KACF,OAAO,CAAC,8EAA8E,SACtF,OAAO,CAAC,yBAAyB,UACjC,OAAO,CAAC,gBAAgB;AACjC;AASO,MAAM,4CAA6B,CAAC;IACvC,OAAO,KAAK,OAAO,CAAC,OAAO,UAAK,OAAO,CAAC,OAAO;AACnD;AAUO,MAAM,4CAA+B,CAAC;IACzC,OAAO,KACF,OAAO,CACJ,4IACA,aAEH,OAAO,CAAC,cAAc;AAC/B;AASO,MAAM,0CAAY,CAAC;IACtB,OAAO,MACF,SAAS,CAAC,QACV,OAAO,CAAC,oBAAoB,IAC5B,OAAO,CAAC,YAAY;AAC7B;AASO,MAAM,4CAAuB,CAAC;IACjC,OAAO,KAAK,OAAO,CAAC,UAAU;AAClC;AASO,MAAM,4CAAuB,CAAC;IACjC,OAAO,CAAA,GAAA,yCAAc,EAAE,KAAK,OAAO,CAAC,wEAAwE;AAChH;AASO,MAAM,4CAAiC,CAAC,OAAiB,wCAAU,0CAAqB;AASxF,MAAM,4CAAkB,CAAC;IAC5B,MAAM,WAAW,0CAA+B,UAC3C,IAAI,GACJ,KAAK,CAAC,QACN,KAAK,CAAC,GAAG,GACT,GAAG,CAAC,CAAC;QACF,OAAO,KAAK,MAAM,CAAC,GAAG,WAAW;IACrC,GACC,IAAI,CAAC;IACV,OAAO;AACX;","sources":["src/index.ts","src/arabic.ts","src/formatting.ts","src/parsing.ts","src/sanitization.ts","src/transliteration.ts"],"sourcesContent":["export * from './arabic';\nexport * from './formatting';\nexport * from './parsing';\nexport * from './sanitization';\nexport * from './transliteration';\n","/**\n * Removes extreme Arabic underscores (ـ) that appear at the beginning or end of a line or in text.\n * Does not affect Hijri dates (e.g., 1424هـ) or specific Arabic terms.\n * Example: \"ـThis is a textـ\" will be changed to \"This is a text\".\n * @param {string} text - The input text to apply the rule to.\n * @returns {string} - The modified text with extreme underscores removed.\n */\nexport const cleanExtremeArabicUnderscores = (text: string) => {\n return text.replace(/(?<!\\d ?ه|اه)ـ(?=\\r?$)|^ـ(?!اهـ)/gm, '');\n};\n\n/**\n * Converts Urdu symbols to their Arabic equivalents.\n * Example: 'ھذا' will be changed to 'هذا', 'ی' to 'ي'.\n * @param {string} text - The input text containing Urdu symbols.\n * @returns {string} - The modified text with Urdu symbols converted to Arabic symbols.\n */\nexport const convertUrduSymbolsToArabic = (text: string) => {\n return text.replace(/ھ/g, 'ه').replace(/ی/g, 'ي');\n};\n\n/**\n * Fixes the trailing \"و\" (wow) in phrases such as \"عليكم و رحمة\" to \"عليكم ورحمة\".\n * This function attempts to correct phrases where \"و\" appears unnecessarily, particularly in greetings.\n * Example: 'السلام عليكم و رحمة' will be changed to 'السلام عليكم ورحمة'.\n * @param {string} text - The input text containing the \"و\" character.\n * @returns {string} - The modified text with unnecessary trailing \"و\" characters corrected.\n */\nexport const fixTrailingWow = (text: string) => {\n return text.replace(/ و /g, ' و');\n};\n\n/**\n * Inserts a space between Arabic text and numbers.\n * Example: 'الآية37' will be changed to 'الآية 37'.\n * @param {string} text - The input text containing Arabic text followed by numbers.\n * @returns {string} - The modified text with spaces inserted between Arabic text and numbers.\n */\nexport const addSpaceBetweenArabicTextAndNumbers = (text: string) => {\n return text.replace(/([\\u0600-\\u06FF]+)(\\d+)/g, '$1 $2');\n};\n\n/**\n * Removes English letters and symbols from the text, including ampersands, slashes, and other symbols.\n * Example: 'أحب & لنفسي' will be changed to 'أحب لنفسي'.\n * @param {string} text - The input text containing English letters and symbols.\n * @returns {string} - The modified text with English letters and symbols removed.\n */\nexport const stripEnglishCharactersAndSymbols = (text: string) => {\n return text.replace(/[a-zA-Z]+[0-9]*|[¬§`ﷺ=]|\\/{2,}|&/g, ' ');\n};\n\n/**\n * Removes single-digit numbers surrounded by Arabic text. Also removes dashes (-) not followed by a number.\n * For example, removes '3' from 'وهب 3 وقال' but does not remove '121' from 'لوحه 121 الجرح'.\n * @param {string} text - The input text to apply the rule to.\n * @returns {string} - The modified text with non-index numbers and dashes removed.\n */\nexport const removeNonIndexSignatures = (text: string) => {\n return text\n .replace(/(?<![0-9] ?)-|(?<=[\\u0600-\\u06FF])\\s?\\d\\s?(?=[\\u0600-\\u06FF])/g, ' ')\n .replace(/(?<=[\\u0600-\\u06FF]\\s)(\\d+\\s)+\\d+(?=(\\s[\\u0600-\\u06FF]|$))/g, ' ');\n};\n\n/**\n * Removes characters enclosed in square brackets [] or parentheses () if they are Arabic letters or Arabic-Indic numerals.\n * Example: '[س]' or '(س)' will be removed.\n * @param {string} text - The input text to apply the rule to.\n * @returns {string} - The modified text with singular codes removed.\n */\nexport const removeSingularCodes = (text: string) => {\n return text.replace(/[[({][\\u0621-\\u064A\\u0660-\\u0669][\\])}]/g, '');\n};\n\n/**\n * Removes solitary Arabic letters unless they are the 'ha' letter, which is used in Hijri years.\n * Example: \"ب ا الكلمات ت\" will be changed to \"ا الكلمات\".\n * @param {string} text - The input text to apply the rule to.\n * @returns {string} - The modified text with solitary Arabic letters removed.\n */\nexport const removeSolitaryArabicLetters = (text: string) => {\n return text.replace(/(^| )[\\u0621-\\u064A]( |$)/g, ' ');\n};\n\n/**\n * Removes tatweel characters while preserving dates references and numbered list items.\n * Example: \"1435/3/29 هـ\" remains as \"1435/3/29 هـ\" but \"أبـــتِـــكَةُ\" becomes \"أبتِكَةُ\"\n * @param text The text to format.\n * @returns The modified text with the tatweel characters removed.\n */\nexport const removeTatwil = (text: string) => {\n // Don't remove tatweel if:\n // 1. Immediately preceded by a number or ه (for dates like \"1435هـ\")\n // 2. Preceded by a number with optional spaces (for list items like \"3 ـ\")\n return text.replace(/(?<![0-9ه])(?<![0-9]\\s*)ـ/g, '');\n};\n\n/**\n * Replaces the 'tah marbutah' (ة) character with 'ha' (ه).\n * Example: 'مدرسة' will be changed to 'مدرسه'.\n * @param {string} text - The input text to apply the rule to.\n * @returns {string} - The modified text with 'ta marbutah' replaced by 'ha'.\n */\nexport const replaceTaMarbutahWithHa = (text: string) => {\n return text.replace(/[ة]/g, 'ه');\n};\n\n/**\n * Removes Arabic diacritics (tashkeel) and the tatweel (elongation) character.\n * Example: 'مُحَمَّدٌ' will be changed to 'محمد'.\n * @param {string} text - The input text to apply the rule to.\n * @returns {string} - The modified text with diacritics and tatweel removed.\n */\nexport const stripDiacritics = (text: string) => {\n return text.replace(\n /[\\u0610\\u0611\\u0612\\u0613\\u0614\\u0615\\u0616\\u0617\\u0618\\u0619\\u061A\\u064B\\u064C\\u064D\\u064E\\u064F\\u0650\\u0651\\u0652\\u0653\\u0654\\u0655\\u0656\\u0657\\u0658\\u065A\\u065B\\u065C\\u065D\\u065E\\u0640]/g,\n '',\n );\n};\n\n/**\n * Removes zero-width joiners (ZWJ) and other zero-width characters from the input text.\n * Zero-width characters include U+200B to U+200F, U+202A to U+202E, U+2060 to U+2064, and U+FEFF.\n * @param {string} text - The input text to apply the rule to.\n * @returns {string} - The modified text with zero-width characters removed.\n */\nexport const stripZeroWidthCharacters = (text: string) => {\n return text.replace(/[\\u200B-\\u200F\\u202A-\\u202E\\u2060-\\u2064\\uFEFF]/g, ' ');\n};\n\n/**\n * Replaces the 'alif maqsurah' (ى) character with the regular 'ya' (ي).\n * Example: 'رؤيى' will be changed to 'رؤيي'.\n * @param {string} text - The input text to apply the rule to.\n * @returns {string} - The modified text with 'alif maqsurah' replaced by 'ya'.\n */\nexport const replaceAlifMaqsurah = (text: string) => {\n return text.replace(/[ىي]/g, 'ي');\n};\n\n/**\n * Replaces English punctuation (question mark and semicolon) with their Arabic equivalents.\n * Example: '?' will be replaced with '؟', and ';' with '؛'.\n * @param {string} text - The input text to apply the rule to.\n * @returns {string} - The modified text with English punctuation replaced by Arabic punctuation.\n */\nexport const replaceEnglishPunctuationWithArabic = (text: string) => {\n return text\n .replace(/\\?|؟\\./g, '؟')\n .replace(/(;|؛)\\s*(\\1\\s*)*/g, '؛')\n .replace(/,|-،/g, '،');\n};\n\n/**\n * Simplifies all forms of 'alif' (أ, إ, and آ) to the basic 'ا'.\n * Example: 'أنا إلى الآفاق' will be changed to 'انا الى الافاق'.\n * @param {string} text - The input text to apply the rule to.\n * @returns {string} - The modified text with simplified 'alif' characters.\n */\nexport const normalizeAlifVariants = (text: string) => {\n return text.replace(/[أإآ]/g, 'ا');\n};\n","/**\n * Adds line breaks after punctuation marks such as periods, exclamation points, and question marks.\n * Example: 'Text.' becomes 'Text.\\n'.\n * @param {string} text - The input text containing punctuation.\n * @returns {string} - The modified text with line breaks added after punctuation.\n */\nexport const insertLineBreaksAfterPunctuation = (text: string) => {\n // Define the punctuation marks that should trigger a new line\n const punctuation = /([.?!؟])/g;\n\n // Replace occurrences of punctuation marks followed by a space with the punctuation mark, a newline, and the space\n const formattedText = text.replace(punctuation, '$1\\n').replace(/\\n\\s+/g, '\\n').trim();\n\n return formattedText;\n};\n\n/**\n * Adds spaces before and after punctuation, except for certain cases like quoted text or ayah references.\n * Example: 'Text,word' becomes 'Text, word'.\n * @param {string} text - The input text containing punctuation.\n * @returns {string} - The modified text with spaces added before and after punctuation.\n */\nexport const addSpaceBeforeAndAfterPunctuation = (text: string) => {\n return text\n .replace(/( ?)([.!?,،؟;؛])((?![ '”“)\"\\]\\n])|(?=\\s{2,}))/g, '$1$2 ')\n .replace(/\\s([.!?,،؟;؛])\\s*([ '”“)\"\\]\\n])/g, '$1$2')\n .replace(/([^\\s\\w\\d'”“)\"\\]]+)\\s+([.!?,،؟;؛])|([.!?,،؟;؛])\\s+$/g, '$1$2$3')\n .replace(/(?<=\\D)( ?: ?)(?!(\\d+:)|(:\\d+))|(?<=\\d) ?: ?(?=\\D)|(?<=\\D) ?: ?(?=\\d)/g, ': ');\n};\n\n/**\n * Turns regular double quotes surrounding a body of text into smart quotes.\n * Also fixes incorrect starting quotes by ensuring the string starts with an opening quote if needed.\n * Example: 'The \"quick brown\" fox' becomes 'The “quick brown” fox'.\n * @param {string} text - The input text to apply the rule to.\n * @returns {string} - The modified text with smart quotes applied.\n */\nexport const applySmartQuotes = (text: string) => {\n return text\n .replace(/[“”]/g, '\"')\n .replace(/\"([^\"]*)\"/g, '“$1”')\n .replace(/^”/g, '“');\n};\n\n/**\n * Replaces literal new line characters (\\n) and carriage returns (\\r) with actual line breaks.\n * Example: 'A\\\\nB' becomes 'A\\nB'.\n * @param {string} text - The input text containing literal new lines.\n * @returns {string} - The modified text with actual line breaks.\n */\nexport const cleanLiteralNewLines = (text: string) => {\n return text.replace(/\\\\n|\\r/g, '\\n');\n};\n\n/**\n * Removes trailing spaces from each line in a multiline string.\n * Example: \" This is a line \\nAnother line \" becomes \"This is a line\\nAnother line\".\n * @param {string} text - The input text to apply the rule to.\n * @returns {string} - The modified text with trailing spaces removed.\n */\nexport const cleanMultilines = (text: string) => {\n return text.replace(/^ +| +$/gm, '');\n};\n\n/**\n * Detects if a word is by itself in a line.\n * @param text The text to check.\n * @returns true if there exists a word in any of the lines in the text that is by itself.\n */\nexport const hasWordInSingleLine = (text: string): boolean => {\n return /^\\s*\\S+\\s*$/gm.test(text);\n};\n\n/**\n * Checks if the input string consists of only punctuation characters.\n * @param {string} text - The input text to check.\n * @returns {boolean} - Returns true if the string contains only punctuation, false otherwise.\n */\nexport const isOnlyPunctuation = (text: string): boolean => {\n const regex = /^[\\u0020-\\u002f\\u003a-\\u0040\\u005b-\\u0060\\u007b-\\u007e0-9٠-٩]+$/;\n return regex.test(text);\n};\n\nexport const cleanJunkFromText = (text: string) => {\n const newBody = cleanMultilines(text);\n const lines = newBody.split('\\n').filter((line) => {\n return !line || (line.length > 1 && !isOnlyPunctuation(line));\n });\n\n return lines.join('\\n').trim();\n};\n\n/**\n * Cleans unnecessary spaces before punctuation marks such as periods, commas, and question marks.\n * Example: 'This is a sentence , with extra space .' becomes 'This is a sentence, with extra space.'.\n * @param {string} text - The input text to apply the rule to.\n * @returns {string} - The modified text with cleaned spaces before punctuation.\n */\nexport const cleanSpacesBeforePeriod = (text: string) => {\n return text.replace(/\\s+([.؟!,،؛:?])/g, '$1');\n};\n\n/**\n * Condenses multiple asterisks (*) into a single one.\n * Example: '***' becomes '*'.\n * @param {string} text - The input text to apply the rule to.\n * @returns {string} - The modified text with condensed asterisks.\n */\nexport const condenseAsterisks = (text: string) => {\n return text.replace(/(\\*\\s*)+/g, '*');\n};\n\n/**\n * Replaces occurrences of colons surrounded by periods (e.g., '.:.' or ':') with a single colon.\n * Example: 'This.:. is a test' becomes 'This: is a test'.\n * @param {string} text - The input text to apply the rule to.\n * @returns {string} - The modified text with condensed colons.\n */\nexport const condenseColons = (text: string) => {\n return text.replace(/[.-]?:[.-]?/g, ':');\n};\n\n/**\n * Condenses two or more dashes (--) into a single dash (-).\n * Example: 'This is some ---- text' becomes 'This is some - text'.\n * @param {string} text - The input text to apply the rule to.\n * @returns {string} - The modified text with condensed dashes.\n */\nexport const condenseDashes = (text: string) => {\n return text.replace(/-{2,}/g, '-');\n};\n\n/**\n * Replaces sequences of two or more periods (e.g., '...') with an ellipsis character (…).\n * Example: 'This is a test...' becomes 'This is a test…'.\n * @param {string} text - The input text to apply the rule to.\n * @returns {string} - The modified text with ellipses condensed.\n */\nexport const condenseEllipsis = (text: string) => {\n return text.replace(/\\.{2,}/g, '…');\n};\n\n/**\n * Reduces multiple consecutive line breaks (3 or more) to exactly 2 line breaks.\n * Example: 'This is line 1\\n\\n\\n\\nThis is line 2' becomes 'This is line 1\\n\\nThis is line 2'.\n * @param {string} text - The input text to apply the rule to.\n * @returns {string} - The modified text with condensed line breaks.\n */\nexport const reduceMultilineBreaksToDouble = (text: string) => {\n return text.replace(/(\\n\\s*){3,}/g, '\\n\\n');\n};\n\n/**\n * Reduces multiple consecutive line breaks (2 or more) to exactly 1 line break.\n * Example: 'This is line 1\\n\\nThis is line 2' becomes 'This is line 1\\nThis is line 2'.\n * @param {string} text - The input text to apply the rule to.\n * @returns {string} - The modified text with condensed line breaks.\n */\nexport const reduceMultilineBreaksToSingle = (text: string) => {\n return text.replace(/(\\n\\s*){2,}/g, '\\n');\n};\n\n/**\n * Condenses multiple periods separated by spaces (e.g., '. . .') into a single period.\n * Example: 'This . . . is a test' becomes 'This. is a test'.\n * @param {string} text - The input text to apply the rule to.\n * @returns {string} - The modified text with condensed periods.\n */\nexport const condensePeriods = (text: string) => {\n return text.replace(/\\. +\\./g, '.');\n};\n\n/**\n * Condenses multiple underscores (__) or Arabic Tatweel characters (ـــــ) into a single underscore or Tatweel.\n * Example: 'This is ـــ some text __' becomes 'This is ـ some text _'.\n * @param {string} text - The input text to apply the rule to.\n * @returns {string} - The modified text with condensed underscores.\n */\nexport const condenseUnderscores = (text: string) => {\n return text.replace(/ـ{2,}/g, 'ـ').replace(/_+/g, '_');\n};\n\n/**\n * Replaces double parentheses or brackets with single ones.\n * Example: '((text))' becomes '(text)'.\n * @param {string} text - The input text to apply the rule to.\n * @returns {string} - The modified text with condensed brackets.\n */\nexport const doubleToSingleBrackets = (text: string) => {\n return text.replace(/(\\(|\\)){2,}|(\\[|\\]){2,}/g, '$1$2');\n};\n\n/**\n * Replaces double parentheses single a single arrow variation.\n * Example: '((text))' becomes '«text»'.\n * @param {string} text - The input text to apply the rule to.\n * @returns {string} - The modified text with condensed brackets.\n */\nexport const replaceDoubleBracketsWithArrows = (text: string) => {\n return text.replace(/\\(\\(\\s?/g, '«').replace(/\\s?\\)\\)/g, '»');\n};\n\n/**\n * Formats a multiline string by joining sentences and maintaining footnotes on their own lines.\n * Footnotes are identified by Arabic and English numerals.\n * Example: 'Sentence one.\\n(1) A footnote.\\nSentence two.' remains the same, while regular sentences are joined.\n * @param {string} input - The input text containing sentences and footnotes.\n * @returns {string} - The formatted text.\n */\nexport const formatStringBySentence = (input: string) => {\n const footnoteRegex = /^\\((?:\\d+|۱|۲|۳|۴|۵|۶|۷|۸|۹)\\)\\s/;\n const sentences: string[] = [];\n const lines = input.split('\\n');\n let currentSentence = '';\n\n lines.forEach((line) => {\n const trimmedLine = line.trim();\n const isFootnote = footnoteRegex.test(trimmedLine);\n const isNumber = /^\\(\\d+\\/\\d+\\)/.test(trimmedLine);\n\n if (isFootnote && !isNumber) {\n if (currentSentence) {\n sentences.push(currentSentence.trim());\n currentSentence = '';\n }\n sentences.push(trimmedLine);\n } else {\n currentSentence += `${trimmedLine} `;\n const lastChar = currentSentence.trim().slice(-1);\n if (/[.!؟]/.test(lastChar)) {\n sentences.push(currentSentence.trim());\n currentSentence = '';\n }\n }\n });\n\n // Add any remaining text to the output\n if (currentSentence) {\n sentences.push(currentSentence.trim());\n }\n\n return sentences.join('\\n');\n};\n\n/**\n * Removes unnecessary spaces around slashes in references.\n * Example: '127 / 11' becomes '127/11'.\n * @param {string} text - The input text containing references.\n * @returns {string} - The modified text with spaces removed around slashes.\n */\nexport const normalizeSlashInReferences = (text: string) => {\n return text.replace(/(\\d+)\\s?\\/\\s?(\\d+)/g, '$1/$2');\n};\n\n/**\n * Reduces multiple spaces or tabs to a single space.\n * Example: 'This is a text' becomes 'This is a text'.\n * @param {string} text - The input text containing extra spaces.\n * @returns {string} - The modified text with reduced spaces.\n */\nexport const normalizeSpaces = (text: string) => {\n return text.replace(/[ \\t]+/g, ' ');\n};\n\n/**\n * Ensures at most 1 space exists before any word before brackets.\n * Adds a space if there isn't one, or reduces multiple spaces to one.\n * @param {string} text - The input text to modify\n * @returns {string} - The modified text with proper spacing before brackets\n */\nexport const ensureSpaceBeforeBrackets = (text: string) => {\n return text.replace(/(\\S) *(\\([^)]*\\))/g, '$1 $2');\n};\n\n/**\n * Removes redundant punctuation marks that follow Arabic question marks or exclamation marks.\n * This function cleans up text by removing periods (.) or Arabic commas (،) that immediately\n * follow Arabic question marks (؟) or exclamation marks (!), as they are considered redundant\n * in proper Arabic punctuation.\n *\n * @param text - The Arabic text to clean up\n * @returns The text with redundant punctuation removed\n *\n * @example\n * ```typescript\n * removeRedundantPunctuation('كيف حالك؟.') // Returns: 'كيف حالك؟'\n * removeRedundantPunctuation('ممتاز!،') // Returns: 'ممتاز!'\n * removeRedundantPunctuation('هذا جيد.') // Returns: 'هذا جيد.' (unchanged)\n * ```\n */\nexport const removeRedundantPunctuation = (text: string) => {\n return text.replace(/([؟!])[.،]/g, '$1');\n};\n\n/**\n * Removes spaces inside brackets, parentheses, or square brackets.\n * Example: '( a b )' becomes '(a b)'.\n * @param {string} text - The input text with spaces inside brackets.\n * @returns {string} - The modified text with spaces removed inside brackets.\n */\nexport const removeSpaceInsideBrackets = (text: string) => {\n return text.replace(/([[(])\\s*(.*?)\\s*([\\])])/g, '$1$2$3');\n};\n\n/**\n * Removes bold styling from text by normalizing the string and removing stylistic characters.\n * @param {string} text - The input text containing bold characters.\n * @returns {string} - The modified text with bold styling removed.\n */\nexport const stripBoldStyling = (text: string) => {\n // Normalize the string to NFKD form\n const normalizedString = text.normalize('NFKD');\n\n // Remove combining marks (diacritics) and stylistic characters from the string\n return normalizedString.replace(/[\\u0300-\\u036f]/g, '').trim();\n};\n\n/**\n * Removes italicized characters by replacing italic Unicode characters with their normal counterparts.\n * Example: '𝘼𝘽𝘾' becomes 'ABC'.\n * @param {string} text - The input text containing italicized characters.\n * @returns {string} - The modified text with italics removed.\n */\nexport const stripItalicsStyling = (text: string) => {\n const italicMap: Record<string, string> = {\n '\\uD835\\uDC4E': 'I',\n '\\uD835\\uDC68': 'g',\n '\\u{1D63C}': '!',\n '\\uD835\\uDC4F': 'J',\n '\\uD835\\uDC69': 'h',\n '\\u{1D63D}': '?',\n '\\uD835\\uDC50': 'K',\n '\\uD835\\uDC6A': 'i',\n '\\uD835\\uDC51': 'L',\n '\\uD835\\uDC6B': 'j',\n '\\u{1D63F}': ',',\n '\\uD835\\uDC52': 'M',\n '\\uD835\\uDC6C': 'k',\n '\\u{1D640}': '.',\n '\\uD835\\uDC53': 'N',\n '\\uD835\\uDC6D': 'l',\n '\\uD835\\uDC54': 'O',\n '\\uD835\\uDC6E': 'm',\n '\\uD835\\uDC6F': 'n',\n '\\uD835\\uDC56': 'Q',\n '\\uD835\\uDC70': 'o',\n '\\uD835\\uDC57': 'R',\n '\\uD835\\uDC71': 'p',\n '\\uD835\\uDC58': 'S',\n '\\uD835\\uDC72': 'q',\n '\\uD835\\uDC59': 'T',\n '\\uD835\\uDC73': 'r',\n '\\u{1D647}': '-',\n '\\uD835\\uDC5A': 'U',\n '\\uD835\\uDC74': 's',\n '\\uD835\\uDC5B': 'V',\n '\\uD835\\uDC75': 't',\n '\\uD835\\uDC5C': 'W',\n '\\uD835\\uDC76': 'u',\n '\\uD835\\uDC5D': 'X',\n '\\uD835\\uDC77': 'v',\n '\\uD835\\uDC5E': 'Y',\n '\\uD835\\uDC78': 'w',\n '\\uD835\\uDC5F': 'Z',\n '\\uD835\\uDC79': 'x',\n '\\uD835\\uDC46': 'A',\n '\\uD835\\uDC7A': 'y',\n '\\uD835\\uDC47': 'B',\n '\\uD835\\uDC7B': 'z',\n '\\uD835\\uDC62': 'a',\n '\\uD835\\uDC48': 'C',\n '\\uD835\\uDC63': 'b',\n '\\uD835\\uDC49': 'D',\n '\\uD835\\uDC64': 'c',\n '\\uD835\\uDC4A': 'E',\n '\\uD835\\uDC65': 'd',\n '\\uD835\\uDC4B': 'F',\n '\\uD835\\uDC66': 'e',\n '\\uD835\\uDC4C': 'G',\n '\\uD835\\uDC67': 'f',\n '\\uD835\\uDC4D': 'H',\n '\\uD835\\uDC55': 'P',\n };\n\n return text.replace(/[\\uD835\\uDC62-\\uD835\\uDC7B\\uD835\\uDC46-\\uD835\\uDC5F\\u{1D63C}-\\u{1D647}]/gu, (match) => {\n return italicMap[match] || match;\n });\n};\n\n/**\n * Removes all bold and italic styling from the input text.\n * @param {string} text - The input text to remove styling from.\n * @returns {string} - The modified text with all styling removed.\n */\nexport const stripStyling = (text: string) => {\n return stripItalicsStyling(stripBoldStyling(text));\n};\n\n/**\n * Removes unnecessary spaces inside quotes.\n * Example: '“ Text ”' becomes '“Text”'.\n * @param {string} text - The input text with spaces inside quotes.\n * @returns {string} - The modified text with spaces removed inside quotes.\n */\nexport const trimSpaceInsideQuotes = (text: string) => {\n return text.replace(/([“”\"]|«) *(.*?) *([“”\"]|»)/g, '$1$2$3');\n};\n","/**\n * Converts a string that resembles JSON but with numeric keys and single-quoted values\n * into valid JSON format. This function replaces numeric keys with quoted numeric keys\n * and ensures all values are double-quoted as required by JSON.\n *\n * @param {string} str - The input string that needs to be fixed into valid JSON.\n * @returns {string} - A valid JSON string.\n *\n * @example\n * const result = normalizeJsonSyntax(\"{10: 'abc', 20: 'def'}\");\n * console.log(result); // '{\"10\": \"abc\", \"20\": \"def\"}'\n */\nexport const normalizeJsonSyntax = (str: string) => {\n let input = str.replace(/(\\b\\d+\\b)(?=:)/g, '\"$1\"');\n input = input.replace(/:\\s*'([^']+)'/g, ': \"$1\"');\n input = input.replace(/:\\s*\"([^\"]+)\"/g, ': \"$1\"');\n\n return JSON.stringify(JSON.parse(input));\n};\n\n/**\n * Checks if a given string resembles a JSON object with numeric or quoted keys and values\n * that are single or double quoted. This is useful for detecting malformed JSON-like\n * structures that can be fixed by the `normalizeJsonSyntax` function.\n *\n * @param {string} str - The input string to check.\n * @returns {boolean} - Returns true if the string is JSON-like, false otherwise.\n *\n * @example\n * const result = isJsonStructureValid(\"{10: 'abc', 'key': 'value'}\");\n * console.log(result); // true\n */\nexport const isJsonStructureValid = (str: string) => {\n // Checks for a pattern with numeric keys or quoted keys and values in quotes\n const jsonLikePattern =\n /^{(\\s*(\\d+|'[^']*'|\"[^\"]*\")\\s*:\\s*('|\")[^'\"]*\\3\\s*,)*(?:\\s*(\\d+|'[^']*'|\"[^\"]*\")\\s*:\\s*('|\")[^'\"]*\\5\\s*)}$/;\n return jsonLikePattern.test(str.trim());\n};\n\n/**\n * Splits a string by spaces and quoted substrings.\n *\n * This function takes an input string and splits it into parts where substrings\n * enclosed in double quotes are treated as a single part. Other substrings\n * separated by spaces are split normally.\n *\n * @param {string} query - The input string to be split.\n * @returns {string[]} An array of strings, with quoted substrings kept intact.\n *\n * @example\n * const result = splitByQuotes('\"This is\" \"a part of the\" \"string and\"');\n * console.log(result); // [\"This is\", \"a part of the\", \"string and\"]\n */\nexport const splitByQuotes = (query: string): string[] => {\n const regex = /(?:[^\\s\"]+|\"(.*?)\")+/g;\n return (query.match(regex) || []).map((s: string) => (s.startsWith('\"') ? s.slice(1, -1) : s));\n};\n\n/**\n * Checks if all double quotes in a string are balanced (even count).\n * A string has balanced quotes if every opening quote has a corresponding closing quote.\n *\n * @param str - The string to check for balanced quotes\n * @returns True if quotes are balanced (even count), false otherwise\n *\n * @example\n * ```typescript\n * areQuotesBalanced('Hello \"world\"') // Returns: true\n * areQuotesBalanced('Hello \"world') // Returns: false\n * areQuotesBalanced('No quotes') // Returns: true\n * ```\n */\nconst areQuotesBalanced = (str: string) => {\n let quoteCount = 0;\n for (const char of str) {\n if (char === '\"') {\n quoteCount++;\n }\n }\n return quoteCount % 2 === 0;\n};\n\nconst brackets = { '(': ')', '[': ']', '{': '}' };\nconst openBrackets = new Set(['(', '[', '{']);\nconst closeBrackets = new Set([')', ']', '}']);\n\n/**\n * Checks if all brackets in a string are properly balanced and matched.\n * This function validates that every opening bracket has a corresponding closing bracket\n * in the correct order and of the matching type.\n *\n * Supported bracket types: parentheses (), square brackets [], curly braces {}\n *\n * @param str - The string to check for balanced brackets\n * @returns True if all brackets are properly balanced and matched, false otherwise\n *\n * @example\n * ```typescript\n * areBracketsBalanced('(hello [world])') // Returns: true\n * areBracketsBalanced('(hello [world)') // Returns: false (mismatched)\n * areBracketsBalanced('((hello))') // Returns: true\n * areBracketsBalanced('(hello') // Returns: false (unclosed)\n * ```\n */\n\nconst areBracketsBalanced = (str: string) => {\n const stack: string[] = [];\n\n for (const char of str) {\n if (openBrackets.has(char)) {\n stack.push(char);\n } else if (closeBrackets.has(char)) {\n const lastOpen = stack.pop();\n if (!lastOpen || brackets[lastOpen as keyof typeof brackets] !== char) {\n return false;\n }\n }\n }\n\n return stack.length === 0;\n};\n\n/**\n * Checks if both quotes and brackets are balanced in a string.\n * This function combines quote balance checking and bracket balance checking\n * to ensure the entire string has properly balanced punctuation.\n *\n * A string is considered balanced when:\n * - All double quotes have matching pairs (even count)\n * - All brackets (parentheses, square brackets, curly braces) are properly matched and nested\n *\n * @param str - The string to check for balanced quotes and brackets\n * @returns True if both quotes and brackets are balanced, false otherwise\n *\n * @example\n * ```typescript\n * isBalanced('He said \"Hello (world)!\"') // Returns: true\n * isBalanced('He said \"Hello (world!\"') // Returns: false (unbalanced quote)\n * isBalanced('He said \"Hello (world)\"') // Returns: false (unbalanced quote)\n * isBalanced('Hello (world) [test]') // Returns: true\n * ```\n */\nexport const isBalanced = (str: string) => {\n return areQuotesBalanced(str) && areBracketsBalanced(str);\n};\n","/**\n * Removes various symbols, part references, and numerical markers from the text.\n * Example: '(1) (2/3)' becomes ''.\n * @param {string} text - The input text to apply the rule to.\n * @returns {string} - The modified text with symbols and part references removed.\n */\nexport const cleanSymbolsAndPartReferences = (text: string) => {\n return text.replace(\n / *\\(?:\\d+(?:\\/\\d+){0,2}\\)? *| *\\[\\d+(?:\\/\\d+)?\\] *| *«\\d+» *|\\d+\\/\\d+(?:\\/\\d+)?|[،§{}۝؍‎﴿﴾<>;_؟»«:!،؛[\\]…ـ¬.\\\\/*()\"]/g,\n ' ',\n );\n};\n\n/**\n * Removes trailing page numbers formatted as '-[46]-' from the text.\n * Example: 'This is some -[46]- text' becomes 'This is some text'.\n * @param {string} text - The input text with trailing page numbers.\n * @returns {string} - The modified text with page numbers removed.\n */\nexport const cleanTrailingPageNumbers = (text: string) => {\n return text.replace(/-\\[\\d+\\]-/g, '');\n};\n\n/**\n * Replaces consecutive line breaks and whitespace characters with a single space.\n * Example: 'a\\nb' becomes 'a b'.\n * @param {string} text - The input text containing line breaks or multiple spaces.\n * @returns {string} - The modified text with spaces.\n */\nexport const replaceLineBreaksWithSpaces = (text: string) => {\n return text.replace(/\\s+/g, ' ');\n};\n\n/**\n * Removes all numeric digits from the text.\n * Example: 'abc123' becomes 'abc'.\n * @param {string} text - The input text containing digits.\n * @returns {string} - The modified text with digits removed.\n */\nexport const stripAllDigits = (text: string) => {\n return text.replace(/[0-9]/g, '');\n};\n\n/**\n * Removes death year references like \"(d. 390H)\" and \"[d. 100h]\" from the text.\n * Example: 'Sufyān ibn ‘Uyaynah (d. 198h)' becomes 'Sufyān ibn ‘Uyaynah'.\n * @param {string} text - The input text containing death year references.\n * @returns {string} - The modified text with death years removed.\n */\nexport const removeDeathYear = (text: string) => {\n return text.replace(/\\[(d)\\.\\s*\\d{1,4}[hH]\\]\\s*|\\((d)\\.\\s*\\d{1,4}[hH]\\)\\s*/g, '');\n};\n\n/**\n * Removes numeric digits and dashes from the text.\n * Example: 'ABC 123-Xyz' becomes 'ABC Xyz'.\n * @param {string} text - The input text containing digits and dashes.\n * @returns {string} - The modified text with numbers and dashes removed.\n */\nexport const removeNumbersAndDashes = (text: string) => {\n return text.replace(/[\\d-]/g, '');\n};\n\n/**\n * Removes single digit references like (1), «2», [3] from the text.\n * Example: 'Ref (1), Ref «2», Ref [3]' becomes 'Ref , Ref , Ref '.\n * @param {string} text - The input text containing single digit references.\n * @returns {string} - The modified text with single digit references removed.\n */\nexport const removeSingleDigitReferences = (text: string) => {\n return text.replace(/\\(\\d{1}\\)|\\[\\d{1}\\]|«\\d»/g, '');\n};\n\n/**\n * Removes URLs from the text.\n * Example: 'Visit https://example.com' becomes 'Visit '.\n * @param {string} text - The input text containing URLs.\n * @returns {string} - The modified text with URLs removed.\n */\nexport const removeUrls = (text: string) => {\n return text.replace(\n /https?:\\/\\/(www\\.)?[-a-zA-Z0-9@:%._+~#=]{1,256}\\.[a-zA-Z0-9()]{1,6}\\b([-a-zA-Z0-9()@:%_+.~#?&//=]*)/g,\n '',\n );\n};\n\n/**\n * Truncates a string to a specified length, adding an ellipsis if truncated.\n *\n * @param val - The string to truncate\n * @param n - Maximum length of the string (default: 150)\n * @returns The truncated string with ellipsis if needed, otherwise the original string\n *\n * @example\n * ```javascript\n * truncate('The quick brown fox jumps over the lazy dog', 20);\n * // Output: 'The quick brown fox…'\n *\n * truncate('Short text', 50);\n * // Output: 'Short text'\n * ```\n */\nexport const truncate = (val: string, n = 150): string => (val.length > n ? `${val.substring(0, n - 1)}…` : val);\n\n/**\n * Truncates a string from the middle, preserving both the beginning and end portions.\n *\n * @param text - The string to truncate\n * @param maxLength - Maximum length of the resulting string (default: 50)\n * @param endLength - Number of characters to preserve at the end (default: 1/3 of maxLength, minimum 3)\n * @returns The truncated string with ellipsis in the middle if needed, otherwise the original string\n *\n * @example\n * ```javascript\n * truncateMiddle('The quick brown fox jumps right over the lazy dog', 20);\n * // Output: 'The quick bro…zy dog'\n *\n * truncateMiddle('The quick brown fox jumps right over the lazy dog', 25, 8);\n * // Output: 'The quick brown …lazy dog'\n *\n * truncateMiddle('Short text', 50);\n * // Output: 'Short text'\n * ```\n */\nexport const truncateMiddle = (text: string, maxLength: number = 50, endLength?: number) => {\n if (text.length <= maxLength) {\n return text;\n }\n\n // Default end length is roughly 1/3 of max length, minimum 3 characters\n const defaultEndLength = Math.max(3, Math.floor(maxLength / 3));\n const actualEndLength = endLength ?? defaultEndLength;\n\n // Reserve space for the ellipsis character (1 char)\n const availableLength = maxLength - 1;\n\n // Calculate start length (remaining space after end portion)\n const startLength = availableLength - actualEndLength;\n\n // Ensure we have at least some characters at the start\n if (startLength < 1) {\n // If we can't fit both start and end, just truncate normally\n return `${text.substring(0, maxLength - 1)}…`;\n }\n\n const startPortion = text.substring(0, startLength);\n const endPortion = text.substring(text.length - actualEndLength);\n\n return `${startPortion}…${endPortion}`;\n};\n\n/**\n * Unescapes backslash-escaped spaces and trims whitespace from both ends.\n * Commonly used to clean file paths that have been escaped when pasted into terminals.\n *\n * @param input - The string to unescape and clean\n * @returns The cleaned string with escaped spaces converted to regular spaces and trimmed\n *\n * @example\n * ```javascript\n * unescapeSpaces('My\\\\ Folder\\\\ Name');\n * // Output: 'My Folder Name'\n *\n * unescapeSpaces(' /path/to/My\\\\ Document.txt ');\n * // Output: '/path/to/My Document.txt'\n *\n * unescapeSpaces('regular text');\n * // Output: 'regular text'\n * ```\n */\nexport const unescapeSpaces = (input: string) => input.replace(/\\\\ /g, ' ').trim();\n","import { normalizeSpaces } from './formatting';\n\n/**\n * Replaces common Arabic prefixes (like 'Al-', 'Ar-', 'Ash-', etc.) with 'al-' in the text.\n * Handles different variations of prefixes such as Ash- and Al- but not when the second word\n * does not start with 'S'.\n * Example: 'Ash-Shafiee' becomes 'al-Shafiee'.\n *\n * @param {string} text - The input text containing Arabic prefixes.\n * @returns {string} - The modified text with standardized 'al-' prefixes.\n */\nexport const normalizeArabicPrefixesToAl = (text: string) => {\n return text\n .replace(/(\\b|\\W)(Al |Al-|Ar-|As-|Adh-|Ad-|Ats-|Ath |Ath-|Az |Az-|az-|adh-|as-|ar-)/g, '$1al-')\n .replace(/(\\b|\\W)(Ash-S|ash-S)/g, '$1al-S')\n .replace(/al- (.+?)\\b/g, 'al-$1');\n};\n\n/**\n * Removes double occurrences of Arabic apostrophes such as ʿʿ or ʾʾ in the text.\n * Example: 'ʿulamāʾʾ' becomes 'ʿulamāʾ'.\n *\n * @param {string} text - The input text containing double apostrophes.\n * @returns {string} - The modified text with condensed apostrophes.\n */\nexport const normalizeDoubleApostrophes = (text: string) => {\n return text.replace(/ʿʿ/g, 'ʿ').replace(/ʾʾ/g, 'ʾ');\n};\n\n/**\n * Replaces common salutations such as \"sallahu alayhi wasallam\" with \"ﷺ\" in the text.\n * It also handles variations of the salutation phrase, including 'peace and blessings be upon him'.\n * Example: 'Then Muḥammad (sallahu alayhi wasallam)' becomes 'Then Muḥammad ﷺ'.\n *\n * @param {string} text - The input text containing salutations.\n * @returns {string} - The modified text with salutations replaced.\n */\nexport const replaceSalutationsWithSymbol = (text: string) => {\n return text\n .replace(\n /\\(peace be upon him\\)|(Messenger of (Allah|Allāh)|Messenger|Prophet|Mu[hḥ]ammad) *\\((s[^)]*m|peace[^)]*him|May[^)]*him|may[^)]*him)\\)*/gi,\n '$1 ﷺ',\n )\n .replace(/,\\s*ﷺ\\s*,/g, ' ﷺ');\n};\n\n/**\n * Normalizes the text by removing diacritics, apostrophes, and dashes.\n * Example: 'Al-Jadwal' becomes 'AlJadwal'.\n *\n * @param {string} input - The input text to normalize.\n * @returns {string} - The normalized text.\n */\nexport const normalize = (input: string) => {\n return input\n .normalize('NFKD')\n .replace(/[\\u0300-\\u036f]/g, '')\n .replace(/`|ʾ|ʿ|-/g, '');\n};\n\n/**\n * Replaces various apostrophe characters (‛, ’, ‘) with the standard apostrophe (').\n * Example: '‛ulama’ al-su‘' becomes ''ulama' al-su''.\n *\n * @param {string} text - The input text containing different apostrophe characters.\n * @returns {string} - The modified text with normalized apostrophes.\n */\nexport const normalizeApostrophes = (text: string) => {\n return text.replace(/‛|’|‘/g, \"'\");\n};\n\n/**\n * Strips common Arabic prefixes like 'al-', 'bi-', 'fī', 'wa-', etc. from the beginning of words.\n * Example: 'al-Bukhari' becomes 'Bukhari'.\n *\n * @param {string} text - The input text containing Arabic prefixes.\n * @returns {string} - The modified text with prefixes stripped.\n */\nexport const removeArabicPrefixes = (text: string) => {\n return normalizeSpaces(text.replace(/(\\bal-|\\bli-|\\bbi-|\\bfī|\\bwa[-\\s]+|\\bl-|\\bliʿl|\\Bʿalá|\\Bʿan|\\bb\\.)/gi, ''));\n};\n\n/**\n * Simplifies English transliterations by removing diacritics, apostrophes, and common prefixes.\n * Example: 'Al-Jadwal' becomes 'Jadwal', and 'āḍġḥīṣṭū' becomes 'adghistu'.\n *\n * @param {string} text - The input text to simplify.\n * @returns {string} - The simplified text.\n */\nexport const normalizeTransliteratedEnglish = (text: string) => normalize(removeArabicPrefixes(text));\n\n/**\n * Extracts the initials from the input string, typically used for names or titles.\n * Example: 'Nayl al-Awtar' becomes 'NA'.\n *\n * @param {string} text - The input text to extract initials from.\n * @returns {string} - The extracted initials.\n */\nexport const extractInitials = (fullName: string) => {\n const initials = normalizeTransliteratedEnglish(fullName)\n .trim()\n .split(/[ -]/)\n .slice(0, 2)\n .map((word) => {\n return word.charAt(0).toUpperCase();\n })\n .join('');\n return initials;\n};\n"],"names":[],"version":3,"file":"main.js.map","sourceRoot":"../"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "bitaboom",
3
3
  "description": "Use string utils library to format Arabic and English translations.",
4
- "version": "1.1.1",
4
+ "version": "1.3.0",
5
5
  "author": "Ragaeeb Haq",
6
6
  "license": "MIT",
7
7
  "private": false,
@@ -14,7 +14,7 @@
14
14
  "url": "git+https://github.com/ragaeeb/bitaboom.git"
15
15
  },
16
16
  "engines": {
17
- "node": ">=23.0.0"
17
+ "node": ">=22.0.0"
18
18
  },
19
19
  "files": [
20
20
  "dist/main.js",
@@ -30,24 +30,24 @@
30
30
  "arabic"
31
31
  ],
32
32
  "devDependencies": {
33
- "@eslint/js": "^9.24.0",
34
- "@parcel/packager-ts": "^2.14.4",
35
- "@parcel/transformer-typescript-types": "^2.14.4",
33
+ "@eslint/js": "^9.28.0",
34
+ "@parcel/packager-ts": "^2.15.2",
35
+ "@parcel/transformer-typescript-types": "^2.15.2",
36
36
  "@semantic-release/git": "^10.0.1",
37
- "@types/node": "^22.14.1",
38
- "@vitest/coverage-v8": "^3.1.1",
39
- "eslint": "^9.24.0",
40
- "eslint-config-prettier": "^10.1.2",
41
- "eslint-plugin-perfectionist": "^4.11.0",
42
- "eslint-plugin-prettier": "^5.2.6",
43
- "globals": "^16.0.0",
44
- "parcel": "^2.14.4",
37
+ "@types/node": "^22.15.30",
38
+ "@vitest/coverage-v8": "^3.2.2",
39
+ "eslint": "^9.28.0",
40
+ "eslint-config-prettier": "^10.1.5",
41
+ "eslint-plugin-perfectionist": "^4.14.0",
42
+ "eslint-plugin-prettier": "^5.4.1",
43
+ "globals": "^16.2.0",
44
+ "parcel": "^2.15.2",
45
45
  "prettier": "^3.5.3",
46
- "semantic-release": "^24.2.3",
46
+ "semantic-release": "^24.2.5",
47
47
  "ts-node": "^10.9.2",
48
48
  "typescript": "^5.8.3",
49
- "typescript-eslint": "^8.30.1",
50
- "vitest": "^3.1.1"
49
+ "typescript-eslint": "^8.33.1",
50
+ "vitest": "^3.2.2"
51
51
  },
52
- "packageManager": "pnpm@10.8.1+sha512.c50088ba998c67b8ca8c99df8a5e02fd2ae2e2b29aaf238feaa9e124248d3f48f9fb6db2424949ff901cffbb5e0f0cc1ad6aedb602cd29450751d11c35023677"
52
+ "packageManager": "pnpm@10.12.1+sha512.f0dda8580f0ee9481c5c79a1d927b9164f2c478e90992ad268bbb2465a736984391d6333d2c327913578b2804af33474ca554ba29c04a8b13060a717675ae3ac"
53
53
  }