stringzy 3.0.0 → 4.0.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.
Files changed (111) hide show
  1. package/.prettierignore +4 -0
  2. package/.prettierrc +7 -0
  3. package/CONTRIBUTING.md +41 -29
  4. package/README.md +397 -160
  5. package/dist/analyzing/characterCount.d.ts +19 -0
  6. package/dist/analyzing/characterCount.js +21 -2
  7. package/dist/analyzing/characterFrequency.d.ts +19 -0
  8. package/dist/analyzing/characterFrequency.js +22 -3
  9. package/dist/analyzing/complexity.d.ts +33 -0
  10. package/dist/analyzing/complexity.js +35 -2
  11. package/dist/analyzing/index.d.ts +18 -12
  12. package/dist/analyzing/index.js +10 -2
  13. package/dist/analyzing/patternCount.d.ts +10 -0
  14. package/dist/analyzing/patternCount.js +52 -0
  15. package/dist/analyzing/stringSimilarity.js +1 -1
  16. package/dist/analyzing/vowelConsonantCount.d.ts +22 -0
  17. package/dist/analyzing/vowelConsonantCount.js +38 -0
  18. package/dist/analyzing/wordCount.d.ts +22 -0
  19. package/dist/analyzing/wordCount.js +24 -2
  20. package/dist/formatting/capitalize.d.ts +21 -0
  21. package/dist/formatting/capitalize.js +22 -1
  22. package/dist/formatting/index.d.ts +6 -6
  23. package/dist/formatting/number.d.ts +23 -0
  24. package/dist/formatting/number.js +24 -1
  25. package/dist/formatting/phone.d.ts +23 -0
  26. package/dist/formatting/phone.js +23 -0
  27. package/dist/index.d.ts +9 -4
  28. package/dist/tests/analyzing/patternCount.test.d.ts +1 -0
  29. package/dist/tests/analyzing/patternCount.test.js +34 -0
  30. package/dist/tests/analyzing/readingDuration.test.js +12 -12
  31. package/dist/tests/analyzing/vowelConsonantCount.test.d.ts +1 -0
  32. package/dist/tests/analyzing/vowelConsonantCount.test.js +25 -0
  33. package/dist/tests/transformations/numberToText.test.d.ts +1 -0
  34. package/dist/tests/transformations/numberToText.test.js +60 -0
  35. package/dist/tests/transformations/splitChunks.test.d.ts +1 -0
  36. package/dist/tests/transformations/splitChunks.test.js +31 -0
  37. package/dist/tests/validations/isCoordinates.test.d.ts +1 -0
  38. package/dist/tests/validations/isCoordinates.test.js +18 -0
  39. package/dist/tests/validations/isEmail.smtpUTF8.test.d.ts +1 -0
  40. package/dist/tests/validations/isEmail.smtpUTF8.test.js +16 -0
  41. package/dist/tests/validations/isEmail.test.js +56 -6
  42. package/dist/tests/validations/isHexColor.test.js +21 -21
  43. package/dist/tests/validations/isPalindrome.test.d.ts +1 -0
  44. package/dist/tests/validations/isPalindrome.test.js +39 -0
  45. package/dist/tests/validations/isTypeOf.test.d.ts +1 -0
  46. package/dist/tests/validations/isTypeOf.test.js +28 -0
  47. package/dist/transformations/camelCase.d.ts +24 -0
  48. package/dist/transformations/camelCase.js +24 -0
  49. package/dist/transformations/capitalizeWords.d.ts +21 -0
  50. package/dist/transformations/capitalizeWords.js +23 -2
  51. package/dist/transformations/constantCase.d.ts +26 -0
  52. package/dist/transformations/constantCase.js +26 -0
  53. package/dist/transformations/escapeHTML.d.ts +23 -0
  54. package/dist/transformations/escapeHTML.js +24 -2
  55. package/dist/transformations/index.d.ts +3 -0
  56. package/dist/transformations/index.js +6 -2
  57. package/dist/transformations/initials.d.ts +27 -0
  58. package/dist/transformations/initials.js +38 -8
  59. package/dist/transformations/kebabCase.d.ts +26 -0
  60. package/dist/transformations/kebabCase.js +26 -0
  61. package/dist/transformations/maskSegment.js +4 -6
  62. package/dist/transformations/numberToText/helpers.d.ts +10 -0
  63. package/dist/transformations/numberToText/helpers.js +31 -0
  64. package/dist/transformations/numberToText/implementation_EN.d.ts +10 -0
  65. package/dist/transformations/numberToText/implementation_EN.js +45 -0
  66. package/dist/transformations/numberToText/implementation_PL.d.ts +10 -0
  67. package/dist/transformations/numberToText/implementation_PL.js +79 -0
  68. package/dist/transformations/numberToText/main.d.ts +19 -0
  69. package/dist/transformations/numberToText/main.js +67 -0
  70. package/dist/transformations/numberToText/types.d.ts +3 -0
  71. package/dist/transformations/numberToText/types.js +82 -0
  72. package/dist/transformations/pascalCase.d.ts +25 -0
  73. package/dist/transformations/pascalCase.js +25 -0
  74. package/dist/transformations/removeDuplicates.d.ts +21 -0
  75. package/dist/transformations/removeDuplicates.js +25 -4
  76. package/dist/transformations/removeSpecialChars.d.ts +22 -0
  77. package/dist/transformations/removeSpecialChars.js +26 -4
  78. package/dist/transformations/removeWords.d.ts +27 -0
  79. package/dist/transformations/removeWords.js +31 -4
  80. package/dist/transformations/snakeCase.d.ts +26 -0
  81. package/dist/transformations/snakeCase.js +26 -0
  82. package/dist/transformations/splitChunks.d.ts +8 -0
  83. package/dist/transformations/splitChunks.js +24 -0
  84. package/dist/transformations/titleCase.d.ts +25 -0
  85. package/dist/transformations/titleCase.js +25 -0
  86. package/dist/transformations/toSlug.d.ts +24 -0
  87. package/dist/transformations/toSlug.js +28 -4
  88. package/dist/transformations/truncateText.d.ts +25 -0
  89. package/dist/transformations/truncateText.js +28 -3
  90. package/dist/validations/index.d.ts +6 -0
  91. package/dist/validations/index.js +10 -2
  92. package/dist/validations/isCoordinates.d.ts +8 -0
  93. package/dist/validations/isCoordinates.js +19 -0
  94. package/dist/validations/isDate.d.ts +1 -1
  95. package/dist/validations/isDate.js +6 -8
  96. package/dist/validations/isEmail.d.ts +13 -1
  97. package/dist/validations/isEmail.js +176 -3
  98. package/dist/validations/isEmpty.d.ts +9 -0
  99. package/dist/validations/isEmpty.js +9 -0
  100. package/dist/validations/isHexColor.js +1 -1
  101. package/dist/validations/isIPv4.d.ts +21 -0
  102. package/dist/validations/isIPv4.js +22 -2
  103. package/dist/validations/isPalindrome.d.ts +10 -0
  104. package/dist/validations/isPalindrome.js +21 -0
  105. package/dist/validations/isSlug.d.ts +27 -0
  106. package/dist/validations/isSlug.js +27 -0
  107. package/dist/validations/isTypeOf.d.ts +9 -0
  108. package/dist/validations/isTypeOf.js +30 -0
  109. package/dist/validations/isURL.d.ts +21 -0
  110. package/dist/validations/isURL.js +21 -0
  111. package/package.json +5 -3
package/README.md CHANGED
@@ -1,13 +1,12 @@
1
1
  <div align="center">
2
-
3
-
4
- ![Stringzy banner](./assets/stringzy-banner2.jpg)
5
2
 
6
3
 
4
+ ![Stringzy banner](./assets/stringzy-banner2.jpg)
5
+
7
6
  ![NPM Version](https://img.shields.io/npm/v/stringzy)
7
+ ![Typescript](https://img.shields.io/badge/TypeScript-3178C6?style=flat&logo=typescript&logoColor=white)
8
8
  ![Downloads](https://img.shields.io/npm/dt/stringzy)
9
9
  ![License](https://img.shields.io/npm/l/stringzy)
10
- ![Bundle Size](https://img.shields.io/bundlephobia/min/stringzy)
11
10
  [![Open Source Love svg1](https://badges.frapsoft.com/os/v1/open-source.svg?v=103)](https://github.com/ellerbrock/open-source-badges/)
12
11
  [![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat-square)](http://makeapullrequest.com)
13
12
 
@@ -15,15 +14,10 @@
15
14
 
16
15
  [Checkout our Contributors!](#contri)
17
16
 
18
-
19
17
  [Join the Community!](#community)
20
18
 
21
-
22
-
23
-
24
19
  </div>
25
20
 
26
-
27
21
  ## ✨ Features
28
22
 
29
23
  - 💪 **Powerful** - Transform, validate, analyze, and format strings with minimal code
@@ -66,7 +60,8 @@ const count = stringzy.analyze.wordCount('Hello world'); // 2
66
60
 
67
61
  ## 📋 Table of Contents
68
62
 
69
- ### Transformations
63
+ ### Transformations
64
+
70
65
  - [truncateText](#truncatetext) - Truncates text to a specified maximum length
71
66
  - [toSlug](#toslug) - Converts a string to a URL-friendly slug
72
67
  - [capitalizeWords](#capitalizewords) - Capitalizes the first letter of each word
@@ -76,31 +71,43 @@ const count = stringzy.analyze.wordCount('Hello world'); // 2
76
71
  - [initials](#initials) - Extracts initials from a text string
77
72
  - [camelCase](#camelcase) - Converts the given string to Camel Case
78
73
  - [pascalCase](#pascalcase) - Converts the given string to Pascal Case
79
- - [snakeCase](#snakecase) - Converts the given string to Snake Case
74
+ - [snakeCase](#snakecase) - Converts the given string to Snake Case
80
75
  - [kebabCase](#kebabcase) - Converts the given string to Kebab Case
81
76
  - [titleCase](#titlecase) - Converts the given string to Title Case
82
77
  - [constantCase](#constantcase) - Converts the given string to Constant Case
83
78
  - [escapeHTML](#escapehtml) - Escapes HTML special characters to prevent XSS attacks
84
79
  - [maskSegment](#masksegment) - Masks a segment of a string by replacing characters between two indices with a specified character
85
80
  - [deburr](#deburr) – Removes accents and diacritical marks from a string
81
+ - [splitChunks](#splitchunks) - Breaks a string down into chunks of specified length.
82
+ - [numberToText](#numbertotext) - Converts a number to its text representation in specified language
86
83
 
84
+ ### Validations
87
85
 
88
- ### Validations
89
86
  - [isURL](#isurl) - Checks if a string is a valid URL
90
87
  - [isEmail](#isemail) - Checks if a string is a valid email address
91
88
  - [isDate](#isdate) - Checks if a string is a valid date
92
89
  - [isEmpty](#isempty) - Checks if a string is empty or contains only whitespace
93
90
  - [isSlug](#isslug) - Checks if a string is a valid slug
91
+ - [isTypeOf](#istypeof) - Checks if a file or URL has a valid extension for a given type
94
92
  - [isIPv4](#isipv4) - Checks if a string is a valid IPv4 address
95
93
  - [isHexColor](#ishexcolor) - Checks if the input string is a valid hex color
94
+ - [isPalindrome](#ispalindrome) - Checks if the input string is a palindrome (ignores case, spaces, and punctuation)
95
+ - [isCoordinates](#iscoordinates) - Checks if given latitude and longitude are valid coordinates
96
+
97
+ ### Analysis
96
98
 
97
- ### Analysis
98
99
  - [wordCount](#wordcount) - Counts the number of words in a string
99
100
  - [readingDuration](#readingduration) - Calculates the reading duration of a given string
100
101
  - [characterCount](#charactercount) - Counts the number of characters in a string
101
102
  - [characterFrequency](#characterfrequency) - Analyzes character frequency in a string
102
103
  - [stringSimilarity](#stringsimilarity) - Calculates the percentage similarity between two strings
103
- ### Formatting
104
+ - [complexity](#complexity) - Analyzes string complexity including score, uniqueness, and length
105
+ - [patternCount](#patterncount) - calculates the number of times a specific pattern occurs in a given text
106
+ - [vowelConsonantCount](#vowelconsonantcount) - Counts the number of vowels and consonants in a given string
107
+
108
+
109
+ ### Formatting
110
+
104
111
  - [capitalize](#capitalize) - Capitalizes the first letter of each word
105
112
  - [formatNumber](#formatnumber) - Formats a number string with thousand separators
106
113
  - [formatPhone](#formatphone) - Formats a phone number string to standard format
@@ -128,11 +135,11 @@ truncateText('Short', 10);
128
135
  // Returns: 'Short' (no truncation needed)
129
136
  ```
130
137
 
131
- | Parameter | Type | Default | Description |
132
- |-----------|------|---------|-------------|
133
- | text | string | required | The input string to truncate |
138
+ | Parameter | Type | Default | Description |
139
+ | --------- | ------ | -------- | ------------------------------------------------------ |
140
+ | text | string | required | The input string to truncate |
134
141
  | maxLength | number | required | Maximum length of the output string (excluding suffix) |
135
- | suffix | string | '...' | String to append if truncation occurs |
142
+ | suffix | string | '...' | String to append if truncation occurs |
136
143
 
137
144
  #### <a id="toslug"></a>`toSlug(text)`
138
145
 
@@ -151,9 +158,9 @@ toSlug('Special $#@! characters');
151
158
  // Returns: 'special-characters'
152
159
  ```
153
160
 
154
- | Parameter | Type | Default | Description |
155
- |-----------|------|---------|-------------|
156
- | text | string | required | The input string to convert to a slug |
161
+ | Parameter | Type | Default | Description |
162
+ | --------- | ------ | -------- | ------------------------------------- |
163
+ | text | string | required | The input string to convert to a slug |
157
164
 
158
165
  #### <a id="capitalizewords"></a>`capitalizeWords(text)`
159
166
 
@@ -172,9 +179,9 @@ capitalizeWords('already Capitalized');
172
179
  // Returns: 'Already Capitalized'
173
180
  ```
174
181
 
175
- | Parameter | Type | Default | Description |
176
- |-----------|------|---------|-------------|
177
- | text | string | required | The input string to capitalize |
182
+ | Parameter | Type | Default | Description |
183
+ | --------- | ------ | -------- | ------------------------------ |
184
+ | text | string | required | The input string to capitalize |
178
185
 
179
186
  #### <a id="removespecialchars"></a>`removeSpecialChars(text, replacement = '')`
180
187
 
@@ -193,10 +200,10 @@ removeSpecialChars('Phone: (123) 456-7890', '-');
193
200
  // Returns: 'Phone-123-456-7890'
194
201
  ```
195
202
 
196
- | Parameter | Type | Default | Description |
197
- |-----------|------|---------|-------------|
198
- | text | string | required | The input string to process |
199
- | replacement | string | '' | String to replace special characters with |
203
+ | Parameter | Type | Default | Description |
204
+ | ----------- | ------ | -------- | ----------------------------------------- |
205
+ | text | string | required | The input string to process |
206
+ | replacement | string | '' | String to replace special characters with |
200
207
 
201
208
  #### <a id="removewords"></a>`removeWords(text, wordsToRemove)`
202
209
 
@@ -209,20 +216,20 @@ removeWords('Hello world this is a test', ['this', 'is']);
209
216
  // Returns: 'Hello world a test'
210
217
 
211
218
  removeWords('Remove The Quick BROWN fox', ['the', 'brown']);
212
- // Returns: 'Remove Quick fox'
219
+ // Returns: 'Remove Quick fox'
213
220
 
214
221
  removeWords('JavaScript is awesome and JavaScript rocks', ['JavaScript']);
215
222
  // Returns: 'is awesome and rocks'
216
223
  ```
217
224
 
218
- | Parameter | Type | Default | Description |
219
- |-----------|------|---------|-------------|
220
- | text | string | required | The input string to process |
225
+ | Parameter | Type | Default | Description |
226
+ | ------------- | -------- | -------- | ---------------------------------------- |
227
+ | text | string | required | The input string to process |
221
228
  | wordsToRemove | string[] | required | Array of words to remove from the string |
222
229
 
223
230
  #### <a id="removeduplicates"></a>`removeDuplicates(text)`
224
231
 
225
- Removes duplicate case-sensitive words from a given text.
232
+ Removes duplicate case-sensitive words from a given text.
226
233
 
227
234
  ```javascript
228
235
  import { removeDuplicates } from 'stringzy';
@@ -231,15 +238,15 @@ removeDuplicates('Hello world this is a is a test');
231
238
  // Returns: 'Hello world this is a test'
232
239
 
233
240
  removeDuplicates('Remove me me me me or Me');
234
- // Returns: 'Remove me or Me'
241
+ // Returns: 'Remove me or Me'
235
242
 
236
243
  removeDuplicates('JavaScript is not bad and not awesome');
237
244
  // Returns: 'JavaScript is not bad and awesome'
238
245
  ```
239
246
 
240
- | Parameter | Type | Default | Description |
241
- |-----------|------|---------|-------------|
242
- | text | string | required | The input string to process |
247
+ | Parameter | Type | Default | Description |
248
+ | --------- | ------ | -------- | --------------------------- |
249
+ | text | string | required | The input string to process |
243
250
 
244
251
  #### <a id="initials"></a>`initials(text, limit)`
245
252
 
@@ -264,10 +271,10 @@ initials(' Multiple Spaces Between ');
264
271
  // Returns: 'MSB'
265
272
  ```
266
273
 
267
- | Parameter | Type | Default | Description |
268
- |-----------|------|---------|-------------|
269
- | text | string | required | The input string to extract initials from |
270
- | limit | number | undefined | Maximum number of initials to return (optional) |
274
+ | Parameter | Type | Default | Description |
275
+ | --------- | ------ | --------- | ----------------------------------------------- |
276
+ | text | string | required | The input string to extract initials from |
277
+ | limit | number | undefined | Maximum number of initials to return (optional) |
271
278
 
272
279
  #### <a id="camelcase"></a>`camelCase(text)`
273
280
 
@@ -277,43 +284,41 @@ Converts the given string to Camel Case.
277
284
  import { camelCase } from 'stringzy';
278
285
 
279
286
  camelCase('hello world'); // 'helloWorld'
280
- camelCase('this is a test'); // 'thisIsATest'
281
- ```
282
- | Parameter | Type | Default | Description |
283
- |-----------|------|---------|-------------|
284
- | text | string | required | The input string to convert to Camel Case |
287
+ camelCase('this is a test'); // 'thisIsATest'
288
+ ```
285
289
 
290
+ | Parameter | Type | Default | Description |
291
+ | --------- | ------ | -------- | ----------------------------------------- |
292
+ | text | string | required | The input string to convert to Camel Case |
286
293
 
287
294
  #### <a id="pascalcase"></a>`pascalCase(text)`
295
+
288
296
  Converts the given string to Pascal Case.
289
297
 
290
298
  ```javascript
291
299
  import { pascalCase } from 'stringzy';
292
300
 
293
-
294
301
  pascalCase('hello world'); // 'HelloWorld'
295
302
  pascalCase('this is a test'); // 'ThisIsATest'
296
303
  ```
297
- | Parameter | Type | Default | Description |
298
- |-----------|------|---------|-------------|
299
- | text | string | required | The input string to convert to Pascal Case |
304
+
305
+ | Parameter | Type | Default | Description |
306
+ | --------- | ------ | -------- | ------------------------------------------ |
307
+ | text | string | required | The input string to convert to Pascal Case |
300
308
 
301
309
  #### <a id="snakecase"></a>`snakeCase(text)`
302
310
 
303
311
  Converts the given string to Snake Case.
304
312
 
305
- ```javascript
313
+ ```javascript
306
314
  import { snakeCase } from 'stringzy';
307
315
  snakeCase('hello world'); // 'hello_world'
308
316
  snakeCase('this is a test'); // 'this_is_a_test'
309
317
  ```
310
318
 
311
- | Parameter | Type | Default | Description |
312
- |-----------|------|---------|-------------|
313
- | text | string | required | The input string to convert to Snake Case |
314
-
315
-
316
-
319
+ | Parameter | Type | Default | Description |
320
+ | --------- | ------ | -------- | ----------------------------------------- |
321
+ | text | string | required | The input string to convert to Snake Case |
317
322
 
318
323
  #### <a id="kebabcase"></a>`kebabCase(text)`
319
324
 
@@ -322,15 +327,13 @@ Converts the given string to Kebab Case.
322
327
  ```javascript
323
328
  import { kebabCase } from 'stringzy';
324
329
 
325
-
326
330
  kebabCase('hello world'); // 'hello-world'
327
331
  kebabCase('this is a test'); // 'this-is-a-test'
328
- ```
329
- | Parameter | Type | Default | Description |
330
- |-----------|------|---------|-------------|
331
- | text | string | required | The input string to convert to Kebab Case |
332
-
332
+ ```
333
333
 
334
+ | Parameter | Type | Default | Description |
335
+ | --------- | ------ | -------- | ----------------------------------------- |
336
+ | text | string | required | The input string to convert to Kebab Case |
334
337
 
335
338
  #### <a id="titlecase"></a>`titleCase(text)`
336
339
 
@@ -339,28 +342,28 @@ Converts the given string to Title Case.
339
342
  ```javascript
340
343
  import { titleCase } from 'stringzy';
341
344
 
342
-
343
345
  titleCase('hello world'); // 'Hello World'
344
346
  titleCase('this is a test'); // 'This Is A Test'
345
347
  ```
346
- | Parameter | Type | Default | Description |
347
- |-----------|------|---------|-------------|
348
- | text | string | required | The input string to convert to Title Case |
348
+
349
+ | Parameter | Type | Default | Description |
350
+ | --------- | ------ | -------- | ----------------------------------------- |
351
+ | text | string | required | The input string to convert to Title Case |
349
352
 
350
353
  #### <a id="constantcase"></a>`constantCase(text)`
354
+
351
355
  Converts the given string to Constant Case.
352
356
 
353
357
  ```javascript
354
358
  import { constantCase } from 'stringzy';
355
359
 
356
-
357
360
  constantCase('hello world'); // 'HELLO_WORLD'
358
361
  constantCase('this is a test'); // 'THIS_IS_A_TEST'
359
-
360
362
  ```
361
- | Parameter | Type | Default | Description |
362
- |-----------|------|---------|-------------|
363
- | text | string | required | The input string to convert to Constant Case |
363
+
364
+ | Parameter | Type | Default | Description |
365
+ | --------- | ------ | -------- | -------------------------------------------- |
366
+ | text | string | required | The input string to convert to Constant Case |
364
367
 
365
368
  #### <a id="escapehtml"></a>`escapeHTML(text)`
366
369
 
@@ -382,12 +385,13 @@ escapeHTML('Say "Hello" & it\'s < 5 > 2');
382
385
  // Returns: 'Say &quot;Hello&quot; &amp; it&#39;s &lt; 5 &gt; 2'
383
386
  ```
384
387
 
385
- | Parameter | Type | Default | Description |
386
- |-----------|------|---------|-------------|
387
- | text | string | required | The input string to escape HTML characters from |
388
+ | Parameter | Type | Default | Description |
389
+ | --------- | ------ | -------- | ----------------------------------------------- |
390
+ | text | string | required | The input string to escape HTML characters from |
388
391
 
389
392
  #### <a id="masksegment"></a>`maskSegment(text, maskStart, maskEnd, maskChar?)`
390
- Masks a segment of a string by replacing characters between two indices with a specified character (default is '*').
393
+
394
+ Masks a segment of a string by replacing characters between two indices with a specified character (default is '\*').
391
395
 
392
396
  ```javascript
393
397
  import { maskSegment } from 'stringzy';
@@ -400,16 +404,17 @@ maskSegment('abcdef', 1, 4, '#');
400
404
 
401
405
  maskSegment('token');
402
406
  // Returns: '*****'
403
-
404
407
  ```
405
- | Parameter | Type | Default| Description |
406
- |-----------|------|--------|-------------|
407
- |text | string | required | The input string to apply the masking to|
408
- |maskStart |number| `0`| The start index (inclusive) of the segment to mask|
409
- |maskEnd |number| `text.length`| The end index (exclusive) of the segment to mask|
410
- |maskChar |string |`'*'` | The character to use for masking (must be one character)|
408
+
409
+ | Parameter | Type | Default | Description |
410
+ | --------- | ------ | ------------- | -------------------------------------------------------- |
411
+ | text | string | required | The input string to apply the masking to |
412
+ | maskStart | number | `0` | The start index (inclusive) of the segment to mask |
413
+ | maskEnd | number | `text.length` | The end index (exclusive) of the segment to mask |
414
+ | maskChar | string | `'*'` | The character to use for masking (must be one character) |
411
415
 
412
416
  #### <a id="deburr"></a>deburr(text)
417
+
413
418
  Removes accents and diacritics from letters in a string (e.g. déjà vu → deja vu).
414
419
 
415
420
  ```javascript
@@ -423,14 +428,55 @@ deburr('Élève São Paulo');
423
428
 
424
429
  deburr('über cool');
425
430
  // Returns: 'uber cool'
426
-
427
431
  ```
428
- | Parameter | Type | Default | Description |
432
+
433
+ | Parameter | Type | Default | Description |
429
434
  | --------- | ------ | -------- | ----------------------------------------- |
430
435
  | text | string | required | The input string to strip diacritics from |
431
436
 
432
437
  ---
433
438
 
439
+ #### <a id="splitchunks"></a>`splitChunks(text, chunkSize)`
440
+
441
+ Takes a string and chunk size as the argument and splits the string into chunks of given size.
442
+
443
+ ```javascript
444
+ import { splitChunks } from 'stringzy';
445
+
446
+ splitChunks('helloworld', 2);
447
+ // Returns: ['he', 'll', 'ow', 'or', 'ld']
448
+
449
+ splitChunks('helloworld', 3);
450
+ // Returns: ['hel', 'low', 'orl', 'd']
451
+
452
+ splitChunks('helloworld');
453
+ // Returns: ['h', 'e', 'l', 'l', 'o', 'w', 'o', 'r', 'l', 'd']
454
+ ```
455
+
456
+ | Parameter | Type | Default | Description |
457
+ | --------- | ------ | -------- | --------------------------------------------------------- |
458
+ | text | string | required | The input string that needs to be chunked |
459
+ | chunkSize | number | `1` | The size of each chunk in which the string is to be split |
460
+
461
+ ---
462
+ #### <a id="numbertotext"></a>`numberToText(num, lang)`
463
+ Converts a number to its text representation in the specified language.
464
+
465
+ ```javascript
466
+ import { numberToText } from 'stringzy';
467
+ numberToText(12345); // Returns: 'twelve thousand three hundred forty-five'
468
+ numberToText(12345, 'en'); // Returns: 'twelve thousand three hundred forty-five'
469
+ numberToText(12345, 'pl'); // Returns: 'dwanaście tysięcy trzysta czterdzieści pięć'
470
+ ```
471
+
472
+ | Parameter | Type | Default | Description |
473
+ |-----------|--------|---------|-------------|
474
+ | num | number | required | The number to convert to text |
475
+ | lang | string | 'en' | The language code for the text representation (e.g., 'en' for English, 'pl' for Polish) |
476
+
477
+ Available languages: en (English), pl (Polish).
478
+
479
+
434
480
  ### ✅ Validations
435
481
 
436
482
  Functions for validating string formats and content.
@@ -444,9 +490,9 @@ isURL('https://example.com'); // true
444
490
  isURL('not-a-url'); // false
445
491
  ```
446
492
 
447
- | Parameter | Type | Default | Description |
448
- |-----------|------|---------|-------------|
449
- | text | string | required | The input string to validate as URL |
493
+ | Parameter | Type | Default | Description |
494
+ | --------- | ------ | -------- | ----------------------------------- |
495
+ | text | string | required | The input string to validate as URL |
450
496
 
451
497
  #### <a id="isemail"></a>`isEmail(text)`
452
498
 
@@ -457,9 +503,9 @@ isEmail('user@example.com'); // true
457
503
  isEmail('invalid-email'); // false
458
504
  ```
459
505
 
460
- | Parameter | Type | Default | Description |
461
- |-----------|------|---------|-------------|
462
- | text | string | required | The input string to validate as email |
506
+ | Parameter | Type | Default | Description |
507
+ | --------- | ------ | -------- | ------------------------------------- |
508
+ | text | string | required | The input string to validate as email |
463
509
 
464
510
  #### <a id="isdate"></a>`isDate(text)`
465
511
 
@@ -476,11 +522,11 @@ isDate('invalid-date', DateFormat.YYYMMDD); // false
476
522
  isDate('2023-13-45', DateFormat.YYYMMDD); // false
477
523
  ```
478
524
 
479
- | Parameter | Type | Default | Description |
480
- |-----------|------|---------|-------------|
481
- | input | string | required | The input string to validate as date |
482
- | format | DateFormats | required | The date format to validate against |
483
- | separator | string | optional | The separator to be used if it is not "-" |
525
+ | Parameter | Type | Default | Description |
526
+ | --------- | ----------- | -------- | ----------------------------------------- |
527
+ | input | string | required | The input string to validate as date |
528
+ | format | DateFormats | required | The date format to validate against |
529
+ | separator | string | optional | The separator to be used if it is not "-" |
484
530
 
485
531
  #### <a id="isempty"></a>`isEmpty(text)`
486
532
 
@@ -491,26 +537,45 @@ isEmpty(' '); // true
491
537
  isEmpty('hello'); // false
492
538
  ```
493
539
 
494
- | Parameter | Type | Default | Description |
495
- |-----------|------|---------|-------------|
496
- | text | string | required | The input string to check for emptiness |
540
+ | Parameter | Type | Default | Description |
541
+ | --------- | ------ | -------- | --------------------------------------- |
542
+ | text | string | required | The input string to check for emptiness |
497
543
 
498
544
  #### <a id="isslug"></a>`isSlug(text)`
499
545
 
500
546
  Checks if a string is a valid slug.
501
547
 
502
548
  ```javascript
503
- isSlug("hello-world"); // true
504
- isSlug("test-product-123"); // true
505
- isSlug("Hello-World"); // false (uppercase letters)
506
- isSlug("hello--world"); // false (consecutive hyphens)
507
- isSlug("-hello-world"); // false (starts with hyphen)
508
- isSlug("hello_world"); // false (underscore not allowed)
549
+ isSlug('hello-world'); // true
550
+ isSlug('test-product-123'); // true
551
+ isSlug('Hello-World'); // false (uppercase letters)
552
+ isSlug('hello--world'); // false (consecutive hyphens)
553
+ isSlug('-hello-world'); // false (starts with hyphen)
554
+ isSlug('hello_world'); // false (underscore not allowed)
555
+ ```
556
+
557
+ | Parameter | Type | Default | Description |
558
+ | --------- | ------ | -------- | ------------------------------------ |
559
+ | text | string | required | The input string to validate as slug |
560
+
561
+ #### <a id="istypeof"></a>`isTypeOf(input, type)`
562
+
563
+ Checks if a file or URL has a valid extension for a given type
564
+
565
+ ```javascript
566
+ isType("photo.PNG", "image"); // true
567
+ isType("https://example.com/logo.svg", "image"); // true
568
+ isType({ name: "track.mp3" }, "audio"); // true
569
+ isType("filewithoutextension", "image"); // false
570
+ isType("document.zip", "document"); // false
571
+ isType("video.mp4", "document"); // false
509
572
  ```
510
573
 
511
574
  | Parameter | Type | Default | Description |
512
575
  |-----------|------|---------|-------------|
513
- | text | string | required | The input string to validate as slug |
576
+ | input | string | required | The file name, URL string, or object with .name |
577
+ | input | string | required | The file type category to validate (image, video, audio, document, archive) |
578
+
514
579
 
515
580
  #### <a id="isipv4"></a>`isIPv4(text)`
516
581
 
@@ -527,10 +592,9 @@ isIPv4('192.168.01.1'); // false (leading zeros)
527
592
  isIPv4('192.168.1.a'); // false (non-numeric)
528
593
  ```
529
594
 
530
- | Parameter | Type | Default | Description |
531
- |-----------|------|---------|-------------|
532
- | text | string | required | The input string to validate as IPv4 address |
533
-
595
+ | Parameter | Type | Default | Description |
596
+ | --------- | ------ | -------- | -------------------------------------------- |
597
+ | text | string | required | The input string to validate as IPv4 address |
534
598
 
535
599
  #### <a id="ishexcolor"></a>`isHexColor(text)`
536
600
 
@@ -539,21 +603,57 @@ Checks if a string is a valid Hex color.
539
603
  ```javascript
540
604
  import { isHexColor } from 'stringzy';
541
605
 
542
- isHexColor('#fff'); // true
543
- isHexColor('fff'); // true
544
- isHexColor('#a1b2c3'); // true
545
- isHexColor('123abc'); // true
546
- isHexColor('#1234'); // false
547
- isHexColor('blue'); // false
606
+ isHexColor('#fff'); // true
607
+ isHexColor('fff'); // true
608
+ isHexColor('#a1b2c3'); // true
609
+ isHexColor('123abc'); // true
610
+ isHexColor('#1234'); // false
611
+ isHexColor('blue'); // false
548
612
  ```
549
613
 
550
- | Parameter | Type | Default | Description |
551
- |-----------|------|---------|-------------|
552
- | text | string | required | The input string to validate as Hex color |
614
+ | Parameter | Type | Default | Description |
615
+ | --------- | ------ | -------- | ----------------------------------------- |
616
+ | text | string | required | The input string to validate as Hex color |
553
617
 
554
- ---
618
+ #### <a id="ispalindrome"></a>`isPalindrome(text)`
619
+
620
+ Checks if a string is a palindrome.
621
+ The check is case-insensitive and ignores spaces and punctuation.
622
+
623
+ ```javascript
624
+ import { isPalindrome } from 'stringzy';
625
+
626
+ isPalindrome('racecar'); // true
627
+ isPalindrome('A man, a plan, a canal: Panama'); // true
628
+ isPalindrome('No lemon, no melon'); // true
629
+ isPalindrome('hello'); // false
630
+ isPalindrome('Was it a car or a cat I saw?'); // true
631
+ ```
632
+
633
+ | Parameter | Type | Default | Description |
634
+ | --------- | ------ | -------- | ---------------------------------------- |
635
+ | text | string | required | The input string to check for palindrome |
636
+
637
+ #### <a id="iscoordinates"></a>`isCoordinates(latitude, longitude)`
638
+
639
+ Checks if given latitude and longitude are valid coordinates.
640
+
641
+ ```javascript
642
+ import { isCoordinates } from 'stringzy';
643
+
644
+ isCoordinates(48.8582, 2.2945); // true
645
+ isCoordinates(40.748817, -73.985428); // true
646
+ isCoordinates(9999, -9999); // false
647
+ ```
648
+
649
+ | Parameter | Type | Default | Description |
650
+ | --------- | ----------- | -------- | ----------------------------------------- |
651
+ | latitude | number | required | Latitude to validate |
652
+ | longitude | number | required | Longitude to validate |
555
653
 
556
654
 
655
+ ---
656
+
557
657
  ### 📊 Analysis
558
658
 
559
659
  Functions for analyzing string content and structure.
@@ -565,21 +665,25 @@ Calculates the estimated reading duration for a given text based on an average r
565
665
  ```javascript
566
666
  import { readingDuration } from 'stringzy';
567
667
 
568
- readingDuration('This is a sample text with twenty-three words to test the reading duration function.');
668
+ readingDuration(
669
+ 'This is a sample text with twenty-three words to test the reading duration function.'
670
+ );
569
671
  // Returns: 0 (23 words / 230 words per minute ≈ 0 minutes)
570
672
 
571
- readingDuration('This text contains fifty words. It is designed to test the reading duration function with a larger input.', 200);
673
+ readingDuration(
674
+ 'This text contains fifty words. It is designed to test the reading duration function with a larger input.',
675
+ 200
676
+ );
572
677
  // Returns: 1 (50 words / 200 words per minute ≈ 1 minute)
573
678
 
574
679
  readingDuration(Array(9999).fill('Word').join(' '));
575
680
  // Returns: 43 (9999 words / 230 words per minute ≈ 43 minutes)
576
681
  ```
577
682
 
578
- | Parameter | Type | Default | Description |
579
- |----------------|----------|---------|-----------------------------------------------------------------------------|
580
- | text | string | required | The input text for which the reading duration is to be calculated |
581
- | readingSpeed | number | 230 | The reading speed in words per minute. Defaults to 230 (average reading speed) |
582
-
683
+ | Parameter | Type | Default | Description |
684
+ | ------------ | ------ | -------- | ------------------------------------------------------------------------------ |
685
+ | text | string | required | The input text for which the reading duration is to be calculated |
686
+ | readingSpeed | number | 230 | The reading speed in words per minute. Defaults to 230 (average reading speed) |
583
687
 
584
688
  #### <a id="wordcount"></a>`wordCount(text)`
585
689
 
@@ -590,9 +694,9 @@ wordCount('Hello world'); // 2
590
694
  wordCount(''); // 0
591
695
  ```
592
696
 
593
- | Parameter | Type | Default | Description |
594
- |-----------|------|---------|-------------|
595
- | text | string | required | The input string to count words in |
697
+ | Parameter | Type | Default | Description |
698
+ | --------- | ------ | -------- | ---------------------------------- |
699
+ | text | string | required | The input string to count words in |
596
700
 
597
701
  #### <a id="charactercount"></a>`characterCount(text)`
598
702
 
@@ -602,9 +706,9 @@ Counts the number of characters in a string.
602
706
  characterCount('Hello'); // 5
603
707
  ```
604
708
 
605
- | Parameter | Type | Default | Description |
606
- |-----------|------|---------|-------------|
607
- | text | string | required | The input string to count characters in |
709
+ | Parameter | Type | Default | Description |
710
+ | --------- | ------ | -------- | --------------------------------------- |
711
+ | text | string | required | The input string to count characters in |
608
712
 
609
713
  #### <a id="characterfrequency"></a>`characterFrequency(text)`
610
714
 
@@ -614,14 +718,15 @@ Analyzes character frequency in a string (excluding spaces).
614
718
  characterFrequency('hello'); // { h: 1, e: 1, l: 2, o: 1 }
615
719
  ```
616
720
 
617
- | Parameter | Type | Default | Description |
618
- |-----------|------|---------|-------------|
619
- | text | string | required | The input string to analyze character frequency |
721
+ | Parameter | Type | Default | Description |
722
+ | --------- | ------ | -------- | ----------------------------------------------- |
723
+ | text | string | required | The input string to analyze character frequency |
620
724
 
621
725
  #### <a id="stringsimilarity"></a>`stringSimilarity(textA, textB, algorithm = 'Levenshtein')`
622
726
 
623
727
  Calculates the percentage similarity between two texts using the selected algorithm.
624
728
  Method returns a percentage (0–100) value indicating how similar the two strings are.
729
+
625
730
  ```javascript
626
731
  stringSimilarity('kitten', 'sitting'); // Returns: 57.14
627
732
 
@@ -630,11 +735,79 @@ stringSimilarity('hello', 'hello'); // Returns: 100
630
735
  stringSimilarity('flaw', 'lawn', 'Damerau-Levenshtein'); // Returns: 50
631
736
  ```
632
737
 
633
- | Parameter | Type | Default | Description |
634
- |------------|--------|----------------------|-----------------------------------------------------------------------------|
635
- | textA | string | required | The first text to compare. |
636
- | textB | string | required | The second text to compare. |
637
- | algorithm | string | 'Levenshtein' | The algorithm to use: 'Levenshtein' or 'Damerau-Levenshtein'. |
738
+ | Parameter | Type | Default | Description |
739
+ | --------- | ------ | ------------- | ------------------------------------------------------------- |
740
+ | textA | string | required | The first text to compare. |
741
+ | textB | string | required | The second text to compare. |
742
+ | algorithm | string | 'Levenshtein' | The algorithm to use: 'Levenshtein' or 'Damerau-Levenshtein'. |
743
+
744
+
745
+
746
+ #### <a id="complexity"></a>`complexity(text)`
747
+
748
+ Analyzes the complexity of a string, returning an object with detailed metrics.
749
+
750
+ ```javascript
751
+ import { complexity } from 'stringzy';
752
+
753
+ complexity('abc');
754
+ // Returns: { score: [number], uniqueness: [number], length: 3 }
755
+
756
+ complexity('aA1!aA1!');
757
+ // Returns: { score: [number], uniqueness: [number], length: 8 }
758
+
759
+ complexity('');
760
+ // Returns: { score: 0, uniqueness: 0, length: 0 }
761
+ ```
762
+
763
+ | Parameter | Type | Default | Description |
764
+ | --------- | ------ | -------- | -------------------------------------- |
765
+ | text | string | required | The input string to analyze complexity |
766
+
767
+ **Returns:** An object containing:
768
+
769
+ - `score` (number): Overall complexity score
770
+ - `uniqueness` (number): Measure of character uniqueness
771
+ - `length` (number): Length of the input string
772
+
773
+
774
+
775
+ #### <a id="patterncount"></a>`patternCount(text, pattern)`
776
+
777
+ Counts the number of times a substring (pattern) occurs in a string, including overlapping occurrences.
778
+ This function uses the **Knuth–Morris–Pratt (KMP)** algorithm for efficient matching.
779
+
780
+ ```javascript
781
+ patternCount('aaaa', 'aa'); // 3
782
+ patternCount('abababa', 'aba'); // 3
783
+ patternCount('hello world', 'o'); // 2
784
+ patternCount('hello world', 'x'); // 0
785
+ ```
786
+
787
+ | Parameter | Type | Default | Description |
788
+ | --------- | ------ | -------- | ---------------------------------------------- |
789
+ | text | string | required | The input string to search in |
790
+ | pattern | string | required | The substring (pattern) to count (overlapping) |
791
+
792
+ #### <a id="vowelconsonantcount"></a>`vowelConsonantCount(str)`
793
+
794
+ Counts the number of vowels and consonants in a given string.
795
+ This function is case-insensitive and ignores non-alphabetic characters.
796
+
797
+ ```javascript
798
+ vowelConsonantCount('hello');
799
+ // { vowels: 2, consonants: 3 }
800
+
801
+ vowelConsonantCount('stringzy');
802
+ // { vowels: 1, consonants: 7 }
803
+
804
+ vowelConsonantCount('');
805
+ // { vowels: 0, consonants: 0 }
806
+ ```
807
+
808
+ | Parameter | Type | Default | Description |
809
+ | --------- | ------ | -------- | -------------------------------------------------- |
810
+ | str | string | required | The input string to count vowels and consonants in |
638
811
 
639
812
  ---
640
813
 
@@ -651,9 +824,9 @@ capitalize('hello world'); // 'Hello World'
651
824
  capitalize('javaScript programming'); // 'Javascript Programming'
652
825
  ```
653
826
 
654
- | Parameter | Type | Default | Description |
655
- |-----------|------|---------|-------------|
656
- | text | string | required | The input string to capitalize |
827
+ | Parameter | Type | Default | Description |
828
+ | --------- | ------ | -------- | ------------------------------ |
829
+ | text | string | required | The input string to capitalize |
657
830
 
658
831
  #### <a id="formatnumber"></a>`formatNumber(number, separator = ',')`
659
832
 
@@ -664,10 +837,10 @@ formatNumber('1234567'); // '1,234,567'
664
837
  formatNumber('1234567', '.'); // '1.234.567'
665
838
  ```
666
839
 
667
- | Parameter | Type | Default | Description |
668
- |-----------|------|---------|-------------|
669
- | number | string\|number | required | The number to format |
670
- | separator | string | ',' | The separator to use for thousands |
840
+ | Parameter | Type | Default | Description |
841
+ | --------- | -------------- | -------- | ---------------------------------- |
842
+ | number | string\|number | required | The number to format |
843
+ | separator | string | ',' | The separator to use for thousands |
671
844
 
672
845
  #### <a id="formatphone"></a>`formatPhone(phone, format = 'us')`
673
846
 
@@ -678,14 +851,15 @@ formatPhone('1234567890'); // '(123) 456-7890'
678
851
  formatPhone('11234567890', 'international'); // '+1 (123) 456-7890'
679
852
  ```
680
853
 
681
- | Parameter | Type | Default | Description |
682
- |-----------|------|---------|-------------|
683
- | phone | string | required | The phone number string to format |
684
- | format | string | 'us' | Format type: 'us' or 'international' |
854
+ | Parameter | Type | Default | Description |
855
+ | --------- | ------ | -------- | ------------------------------------ |
856
+ | phone | string | required | The phone number string to format |
857
+ | format | string | 'us' | Format type: 'us' or 'international' |
685
858
 
686
859
  ## 🔧 Usage Patterns
687
860
 
688
861
  ### Individual Function Imports
862
+
689
863
  ```javascript
690
864
  import { isEmail, wordCount, capitalize } from 'stringzy';
691
865
 
@@ -696,6 +870,7 @@ if (isEmail(email)) {
696
870
  ```
697
871
 
698
872
  ### Namespace Imports
873
+
699
874
  ```javascript
700
875
  import { validate, analyze, format } from 'stringzy';
701
876
 
@@ -706,6 +881,7 @@ const formatted = format.capitalize('hello world');
706
881
  ```
707
882
 
708
883
  ### Default Import (All Functions)
884
+
709
885
  ```javascript
710
886
  import stringzy from 'stringzy';
711
887
 
@@ -746,19 +922,19 @@ import { validate } from 'stringzy';
746
922
 
747
923
  function validateForm(formData) {
748
924
  const errors = {};
749
-
925
+
750
926
  if (!validate.isEmail(formData.email)) {
751
927
  errors.email = 'Please enter a valid email address';
752
928
  }
753
-
929
+
754
930
  if (!validate.isURL(formData.website)) {
755
931
  errors.website = 'Please enter a valid URL';
756
932
  }
757
-
933
+
758
934
  if (validate.isEmpty(formData.name)) {
759
935
  errors.name = 'Name is required';
760
936
  }
761
-
937
+
762
938
  return errors;
763
939
  }
764
940
  ```
@@ -773,7 +949,7 @@ function getContentStats(text) {
773
949
  words: analyze.wordCount(text),
774
950
  characters: analyze.characterCount(text),
775
951
  frequency: analyze.characterFrequency(text),
776
- readingTime: Math.ceil(analyze.wordCount(text) / 200)
952
+ readingTime: Math.ceil(analyze.wordCount(text) / 200),
777
953
  };
778
954
  }
779
955
  ```
@@ -787,7 +963,7 @@ function formatUserData(userData) {
787
963
  return {
788
964
  name: format.capitalize(userData.name),
789
965
  phone: format.formatPhone(userData.phone),
790
- revenue: format.formatNumber(userData.revenue)
966
+ revenue: format.formatNumber(userData.revenue),
791
967
  };
792
968
  }
793
969
  ```
@@ -810,7 +986,7 @@ const formatted: string = format.capitalize('hello world');
810
986
  stringzy is organized into four specialized modules:
811
987
 
812
988
  - **`transformations.js`** - Core string transformations
813
- - **`validations.js`** - String validation utilities
989
+ - **`validations.js`** - String validation utilities
814
990
  - **`analysis.js`** - String analysis and metrics
815
991
  - **`formatting.js`** - String formatting functions
816
992
 
@@ -820,7 +996,6 @@ Each module can be imported individually or accessed through the main entry poin
820
996
 
821
997
  Contributions are welcome! Please read our [contribution guidelines](CONTRIBUTING.md) before submitting a pull request.
822
998
 
823
-
824
999
  ## <a id="contri"></a>`Contributors`
825
1000
 
826
1001
  <table>
@@ -928,6 +1103,68 @@ Contributions are welcome! Please read our [contribution guidelines](CONTRIBUTIN
928
1103
  </sub>
929
1104
  </a>
930
1105
  </td>
1106
+ <td align="center">
1107
+ <a href="https://github.com/Thenlie">
1108
+ <img src="https://avatars.githubusercontent.com/Thenlie" width="100px;"
1109
+ alt="Thenlie" />
1110
+ <br />
1111
+ <sub>
1112
+ <b>Leithen</b>
1113
+ </sub>
1114
+ </a>
1115
+ </td>
1116
+ <td align="center">
1117
+ <a href="https://github.com/rickyryden">
1118
+ <img src="https://avatars.githubusercontent.com/rickyryden" width="100px;"
1119
+ alt="Ricky Ryden" />
1120
+ <br />
1121
+ <sub>
1122
+ <b>Ricky Ryden</b>
1123
+ </sub>
1124
+ </a>
1125
+ </td>
1126
+ </tr>
1127
+ <tr>
1128
+ <td align="center">
1129
+ <a href="https://github.com/adityaatre26">
1130
+ <img src="https://avatars.githubusercontent.com/adityaatre26" width="100px;"
1131
+ alt="Aditya Atre" />
1132
+ <br />
1133
+ <sub>
1134
+ <b>Aditya Atre</b>
1135
+ </sub>
1136
+ </a>
1137
+ </td>
1138
+ <td align="center">
1139
+ <a href="https://github.com/kittenwarrior-qb">
1140
+ <img src="https://avatars.githubusercontent.com/kittenwarrior-qb" width="100px;"
1141
+ alt="quocbui05" />
1142
+ <br />
1143
+ <sub>
1144
+ <b>quocbui05</b>
1145
+ </sub>
1146
+ </a>
1147
+ </td>
1148
+ <td align="center">
1149
+ <a href="https://github.com/MariamEwas">
1150
+ <img src="https://avatars.githubusercontent.com/MariamEwas" width="100px;"
1151
+ alt="Mariam Hasan" />
1152
+ <br />
1153
+ <sub>
1154
+ <b>Mariam Hasan</b>
1155
+ </sub>
1156
+ </a>
1157
+ </td>
1158
+ <td align="center">
1159
+ <a href="https://github.com/milendrakumarbaghel">
1160
+ <img src="https://avatars.githubusercontent.com/milendrakumarbaghel" width="100px;"
1161
+ alt="Mariam Hasan" />
1162
+ <br />
1163
+ <sub>
1164
+ <b>Milendra Kumar Baghel</b>
1165
+ </sub>
1166
+ </a>
1167
+ </td>
931
1168
  </tr>
932
1169
  </tbody>
933
1170
  </table>