usemods-nuxt 0.0.22 → 1.1.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/dist/module.json +1 -1
- package/dist/runtime/utils/README.txt +2 -0
- package/dist/runtime/utils/actions.d.ts +1 -0
- package/dist/runtime/utils/actions.mjs +19 -5
- package/dist/runtime/utils/data.d.ts +1 -1
- package/dist/runtime/utils/data.mjs +5 -6
- package/dist/runtime/utils/detections.d.ts +2 -0
- package/dist/runtime/utils/formatters.d.ts +11 -4
- package/dist/runtime/utils/formatters.mjs +32 -19
- package/dist/runtime/utils/generators.d.ts +12 -2
- package/dist/runtime/utils/generators.mjs +44 -22
- package/dist/runtime/utils/goodies.d.ts +12 -5
- package/dist/runtime/utils/goodies.mjs +10 -9
- package/dist/runtime/utils/modifiers.d.ts +2 -0
- package/dist/runtime/utils/modifiers.mjs +1 -1
- package/dist/runtime/utils/numbers.d.ts +2 -3
- package/dist/runtime/utils/numbers.mjs +7 -1
- package/dist/runtime/utils/validators.mjs +1 -1
- package/package.json +1 -1
package/dist/module.json
CHANGED
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
export declare function scrollToAnchor(id: string): Promise<void>;
|
|
5
5
|
/**
|
|
6
6
|
* Toggles the body scroll with specified class names and returns a promise
|
|
7
|
+
* @info Use your own class names, or ensure fixed is within your Tailwindcss JIT
|
|
7
8
|
*/
|
|
8
9
|
export declare function toggleBodyScroll(className?: string, action?: 'add' | 'remove' | 'toggle'): Promise<void>;
|
|
9
10
|
/**
|
|
@@ -4,6 +4,7 @@ export function scrollToAnchor(id) {
|
|
|
4
4
|
const selector = `#${id}`;
|
|
5
5
|
const element = document.querySelector(selector);
|
|
6
6
|
if (!element) {
|
|
7
|
+
console.warn(`[MODS] Element with id '${id}' not found.`);
|
|
7
8
|
reject(`Element with id '${id}' not found.`);
|
|
8
9
|
return;
|
|
9
10
|
}
|
|
@@ -22,17 +23,28 @@ export function toggleBodyScroll(className = "fixed", action = "toggle") {
|
|
|
22
23
|
const isFixed = body.classList.contains(className);
|
|
23
24
|
const scrollY = isFixed ? parseInt(body.style.top, 10) : window.scrollY;
|
|
24
25
|
body.style.top = isFixed ? "" : `-${scrollY}px`;
|
|
25
|
-
|
|
26
|
+
if (action === "add") {
|
|
27
|
+
body.classList.add(className);
|
|
28
|
+
} else if (action === "remove") {
|
|
29
|
+
body.classList.remove(className);
|
|
30
|
+
} else {
|
|
31
|
+
body.classList.toggle(className);
|
|
32
|
+
}
|
|
26
33
|
if (isFixed)
|
|
27
34
|
window.scrollTo(0, -scrollY);
|
|
28
35
|
resolve();
|
|
29
36
|
} catch (error) {
|
|
37
|
+
console.warn("[MODS] Failed to toggle body scroll.");
|
|
30
38
|
reject(error);
|
|
31
39
|
}
|
|
32
40
|
});
|
|
33
41
|
}
|
|
34
42
|
export function toggleElementScroll(element) {
|
|
35
43
|
return new Promise((resolve) => {
|
|
44
|
+
if (!element) {
|
|
45
|
+
console.warn("[MODS] Element is required to toggle scroll.");
|
|
46
|
+
return resolve();
|
|
47
|
+
}
|
|
36
48
|
if (element.dataset.isScrollLocked === "true") {
|
|
37
49
|
element.style.overflow = "";
|
|
38
50
|
delete element.dataset.isScrollLocked;
|
|
@@ -43,14 +55,16 @@ export function toggleElementScroll(element) {
|
|
|
43
55
|
resolve();
|
|
44
56
|
});
|
|
45
57
|
}
|
|
46
|
-
export function copyToClipboard(value) {
|
|
58
|
+
export async function copyToClipboard(value) {
|
|
47
59
|
if (!navigator.clipboard || !navigator.clipboard.writeText) {
|
|
48
|
-
|
|
60
|
+
throw new Error("Clipboard API is not available");
|
|
49
61
|
}
|
|
50
|
-
|
|
62
|
+
try {
|
|
63
|
+
await navigator.clipboard.writeText(String(value));
|
|
64
|
+
} catch (error) {
|
|
51
65
|
console.error("Failed to copy text: ", error);
|
|
52
66
|
throw error;
|
|
53
|
-
}
|
|
67
|
+
}
|
|
54
68
|
}
|
|
55
69
|
export function toggleFullScreen() {
|
|
56
70
|
return new Promise((resolve, reject) => {
|
|
@@ -16,7 +16,7 @@ export declare function dataRemoveDuplicates<T extends string | number>(...array
|
|
|
16
16
|
/**
|
|
17
17
|
* Flatten an array of arrays or an object of objects into a single array or object. That was hard to say.
|
|
18
18
|
*/
|
|
19
|
-
export declare function dataFlatten(items: object |
|
|
19
|
+
export declare function dataFlatten(items: object | any[]): object | any[];
|
|
20
20
|
/**
|
|
21
21
|
* Returns an array without a property or properties.
|
|
22
22
|
*/
|
|
@@ -32,18 +32,17 @@ export function dataReverse(items) {
|
|
|
32
32
|
}
|
|
33
33
|
export function dataRemoveDuplicates(...arrays) {
|
|
34
34
|
const mergedArray = arrays.flat();
|
|
35
|
-
return
|
|
35
|
+
return Array.from(new Set(mergedArray));
|
|
36
36
|
}
|
|
37
37
|
export function dataFlatten(items) {
|
|
38
38
|
if (isObject(items)) {
|
|
39
39
|
const flattened = {};
|
|
40
|
-
Object.
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
});
|
|
40
|
+
for (const [key, value] of Object.entries(items)) {
|
|
41
|
+
flattened[key] = Array.isArray(value) ? dataFlatten(value) : value;
|
|
42
|
+
}
|
|
44
43
|
return flattened;
|
|
45
44
|
} else if (Array.isArray(items)) {
|
|
46
|
-
return items.
|
|
45
|
+
return items.flatMap((item) => Array.isArray(item) ? dataFlatten(item) : item);
|
|
47
46
|
} else {
|
|
48
47
|
return items;
|
|
49
48
|
}
|
|
@@ -7,6 +7,7 @@ export declare function detectScrollPosition(): {
|
|
|
7
7
|
};
|
|
8
8
|
/**
|
|
9
9
|
* Detect the absolute mouse position with the page
|
|
10
|
+
* @info Don't forget to add a mousemove event listener to the window
|
|
10
11
|
*/
|
|
11
12
|
export declare function detectMousePosition(event: MouseEvent): {
|
|
12
13
|
x: number;
|
|
@@ -14,6 +15,7 @@ export declare function detectMousePosition(event: MouseEvent): {
|
|
|
14
15
|
};
|
|
15
16
|
/**
|
|
16
17
|
* Detect the relative mouse position with the window size and returns a percentage value
|
|
18
|
+
* @info Don't forget to add a mousemove event listener to the window
|
|
17
19
|
*/
|
|
18
20
|
export declare function detectRelativeMousePosition(event: MouseEvent): {
|
|
19
21
|
x: number;
|
|
@@ -26,6 +26,15 @@ export declare function formatPercentage(value: number, options?: {
|
|
|
26
26
|
decimals?: number;
|
|
27
27
|
locale?: string;
|
|
28
28
|
}): string;
|
|
29
|
+
/**
|
|
30
|
+
* Format a number into a your unit of choice
|
|
31
|
+
*/
|
|
32
|
+
export declare function formatUnit(value: number, options: {
|
|
33
|
+
unit: string;
|
|
34
|
+
decimals?: number;
|
|
35
|
+
unitDisplay?: 'short' | 'long';
|
|
36
|
+
locale?: string;
|
|
37
|
+
}): string;
|
|
29
38
|
/**
|
|
30
39
|
* Format time into a human-readable string
|
|
31
40
|
*/
|
|
@@ -40,7 +49,7 @@ export declare function formatDurationNumbers(seconds: number): string;
|
|
|
40
49
|
/**
|
|
41
50
|
* Format numbers into words
|
|
42
51
|
*/
|
|
43
|
-
export declare function formatNumberToWords(
|
|
52
|
+
export declare function formatNumberToWords(number: number): string;
|
|
44
53
|
/**
|
|
45
54
|
* Generate initials from any string while ignoring common titles
|
|
46
55
|
*/
|
|
@@ -68,8 +77,6 @@ export declare function formatTitle(text: string): string;
|
|
|
68
77
|
export declare function formatSentenceCase(text: string): string;
|
|
69
78
|
/**
|
|
70
79
|
* Adds a space between the last two words in a string to prevent lonely words.
|
|
80
|
+
* @info Remember `text-wrap: pretty` and `text-wrap: balance` are available for most browsers.
|
|
71
81
|
*/
|
|
72
82
|
export declare function formatTextWrap(value: string): string;
|
|
73
|
-
/**
|
|
74
|
-
* Format a number into a unit formatting
|
|
75
|
-
*/
|
|
@@ -79,6 +79,17 @@ export function formatPercentage(value, options) {
|
|
|
79
79
|
};
|
|
80
80
|
return new Intl.NumberFormat(options?.locale ?? "en-US", config).format(value);
|
|
81
81
|
}
|
|
82
|
+
export function formatUnit(value, options) {
|
|
83
|
+
const safeDecimals = Math.max(0, Math.min(options?.decimals ?? 2, 20));
|
|
84
|
+
const config = {
|
|
85
|
+
unit: options.unit,
|
|
86
|
+
style: "unit",
|
|
87
|
+
unitDisplay: options.unitDisplay ?? "long",
|
|
88
|
+
minimumFractionDigits: safeDecimals === 0 ? 0 : safeDecimals === 1 ? 1 : 2,
|
|
89
|
+
maximumFractionDigits: safeDecimals
|
|
90
|
+
};
|
|
91
|
+
return new Intl.NumberFormat(options.locale ?? "en-US", config).format(value);
|
|
92
|
+
}
|
|
82
93
|
export function formatDurationLabels(seconds, options) {
|
|
83
94
|
const time = [
|
|
84
95
|
{ unit: options?.labels === "short" ? "yr" : " year", secondsInUnit: 31536e3 },
|
|
@@ -116,7 +127,7 @@ export function formatDurationNumbers(seconds) {
|
|
|
116
127
|
const remainingSeconds = seconds - hours * 3600 - minutes * 60;
|
|
117
128
|
return [hours, minutes, remainingSeconds].map((value) => value.toString().padStart(2, "0")).join(":");
|
|
118
129
|
}
|
|
119
|
-
export function formatNumberToWords(
|
|
130
|
+
export function formatNumberToWords(number) {
|
|
120
131
|
const underTwenty = [
|
|
121
132
|
"zero",
|
|
122
133
|
"one",
|
|
@@ -140,29 +151,27 @@ export function formatNumberToWords(value) {
|
|
|
140
151
|
"nineteen"
|
|
141
152
|
];
|
|
142
153
|
const tens = ["twenty", "thirty", "forty", "fifty", "sixty", "seventy", "eighty", "ninety"];
|
|
143
|
-
if (value < 20)
|
|
144
|
-
return underTwenty[value];
|
|
145
|
-
if (value < 100)
|
|
146
|
-
return `${tens[Math.floor(value / 10) - 2]}${value % 10 ? "-" + underTwenty[value % 10] : ""}`;
|
|
147
|
-
const formatGroup = (number) => {
|
|
148
|
-
if (number >= 100) {
|
|
149
|
-
const remainder = number % 100;
|
|
150
|
-
return `${underTwenty[Math.floor(number / 100)]} hundred${remainder ? ` and ${formatGroup(remainder)}` : ""}`;
|
|
151
|
-
} else if (number >= 20) {
|
|
152
|
-
return `${tens[Math.floor(number / 10) - 2]}${number % 10 ? "-" + underTwenty[number % 10] : ""}`;
|
|
153
|
-
} else {
|
|
154
|
-
return underTwenty[number];
|
|
155
|
-
}
|
|
156
|
-
};
|
|
157
154
|
const scales = ["", " thousand", " million", " billion", " trillion", " quadrillion", " quintillion"];
|
|
155
|
+
if (number < 20)
|
|
156
|
+
return underTwenty[number];
|
|
157
|
+
if (number < 100)
|
|
158
|
+
return `${tens[Math.floor(number / 10) - 2]}${number % 10 ? "-" + underTwenty[number % 10] : ""}`;
|
|
159
|
+
const formatGroup = (num) => {
|
|
160
|
+
if (num < 20)
|
|
161
|
+
return underTwenty[num];
|
|
162
|
+
if (num < 100)
|
|
163
|
+
return `${tens[Math.floor(num / 10) - 2]}${num % 10 ? "-" + underTwenty[num % 10] : ""}`;
|
|
164
|
+
const remainder = num % 100;
|
|
165
|
+
return `${underTwenty[Math.floor(num / 100)]} hundred${remainder ? ` and ${formatGroup(remainder)}` : ""}`;
|
|
166
|
+
};
|
|
158
167
|
let scaleIndex = 0;
|
|
159
168
|
let result = "";
|
|
160
|
-
while (
|
|
161
|
-
const groupValue =
|
|
169
|
+
while (number > 0) {
|
|
170
|
+
const groupValue = number % 1e3;
|
|
162
171
|
if (groupValue > 0) {
|
|
163
172
|
result = formatGroup(groupValue) + scales[scaleIndex] + (result ? ", " + result : "");
|
|
164
173
|
}
|
|
165
|
-
|
|
174
|
+
number = Math.floor(number / 1e3);
|
|
166
175
|
scaleIndex++;
|
|
167
176
|
}
|
|
168
177
|
return result.trim();
|
|
@@ -170,10 +179,14 @@ export function formatNumberToWords(value) {
|
|
|
170
179
|
export function formatInitials(text, options) {
|
|
171
180
|
if (!text)
|
|
172
181
|
return "";
|
|
173
|
-
text = text.replace(
|
|
182
|
+
text = text.replace(/\b(Mrs|Mr|Ms|Dr|Jr|Sr|Prof|Hon|Snr|Jnr|St)\b\.?/g, " ").trim();
|
|
174
183
|
return text.split(" ").filter((word) => !["the", "third"].includes(word.toLowerCase())).map((word) => word.charAt(0).toUpperCase()).join("").substring(0, options?.length ?? 2);
|
|
175
184
|
}
|
|
176
185
|
export function formatUnixTime(timestamp) {
|
|
186
|
+
if (isNaN(timestamp) || timestamp < 0 || timestamp > 9999999999) {
|
|
187
|
+
console.warn("[MODS] Invalid Unix timestamp:", timestamp);
|
|
188
|
+
return String(timestamp);
|
|
189
|
+
}
|
|
177
190
|
return new Date(timestamp * 1e3).toISOString().replace("T", " ").replace("Z", "");
|
|
178
191
|
}
|
|
179
192
|
export function formatList(items, options) {
|
|
@@ -15,9 +15,19 @@ export declare function generateUuid(): string;
|
|
|
15
15
|
*/
|
|
16
16
|
export declare function generateShortId(length?: number): string;
|
|
17
17
|
/**
|
|
18
|
-
* Generate a random, secure password with a mix of character types.
|
|
18
|
+
* Generate a random, secure password with a mix of character types and pleasant special characters.
|
|
19
|
+
* @info Don't forget to use our Password Checker in the Goodies section
|
|
19
20
|
*/
|
|
20
|
-
export declare function generatePassword(
|
|
21
|
+
export declare function generatePassword(options?: {
|
|
22
|
+
length?: number;
|
|
23
|
+
uppercase?: number;
|
|
24
|
+
number?: number;
|
|
25
|
+
special?: number;
|
|
26
|
+
}): string;
|
|
27
|
+
/**
|
|
28
|
+
* Random number generator using cryptographic methods to avoid random().
|
|
29
|
+
*/
|
|
30
|
+
export declare function generateRandomIndex(max: number): number;
|
|
21
31
|
/**
|
|
22
32
|
* Generate Lorem Ipsum text in various formats.
|
|
23
33
|
*/
|
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
export function generateNumber(length) {
|
|
2
|
-
|
|
3
|
-
|
|
2
|
+
if (!Number.isInteger(length) || length <= 0) {
|
|
3
|
+
console.warn("[MODS] Warning: length must be a positive integer");
|
|
4
|
+
return 0;
|
|
5
|
+
}
|
|
6
|
+
const min = 10 ** (length - 1);
|
|
7
|
+
const max = 10 ** length - 1;
|
|
4
8
|
return Math.floor(Math.random() * (max - min + 1) + min);
|
|
5
9
|
}
|
|
6
10
|
export function generateNumberBetween(min, max) {
|
|
@@ -19,28 +23,46 @@ export function generateShortId(length = 19) {
|
|
|
19
23
|
const randomPart = Math.random().toString().slice(2).toUpperCase();
|
|
20
24
|
return (timestampPart + randomPart).slice(0, length);
|
|
21
25
|
}
|
|
22
|
-
export function generatePassword(
|
|
23
|
-
length =
|
|
24
|
-
const
|
|
25
|
-
const
|
|
26
|
-
const
|
|
27
|
-
const
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
const randomIndex = window.crypto.getRandomValues(new Uint32Array(1))[0] % type.length;
|
|
33
|
-
passwordArray.push(type[randomIndex]);
|
|
34
|
-
});
|
|
35
|
-
for (let i = passwordArray.length; i < length; i++) {
|
|
36
|
-
const randomIndex = window.crypto.getRandomValues(new Uint32Array(1))[0] % allChars.length;
|
|
37
|
-
passwordArray.push(allChars[randomIndex]);
|
|
26
|
+
export function generatePassword(options) {
|
|
27
|
+
const { length = 8, uppercase = 1, number = 1, special = 1 } = options || {};
|
|
28
|
+
const uppercaseChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
|
29
|
+
const numberChars = "0123456789";
|
|
30
|
+
const specialChars = "!@#$%&()_+?";
|
|
31
|
+
const allChars = "abcdefghijklmnopqrstuvwxyz" + uppercaseChars + numberChars + specialChars;
|
|
32
|
+
let password = "";
|
|
33
|
+
password += allChars.charAt(generateRandomIndex(52));
|
|
34
|
+
for (let i = 1; i < length; i++) {
|
|
35
|
+
password += allChars.charAt(Math.floor(Math.random() * allChars.length));
|
|
38
36
|
}
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
37
|
+
const ensureCriteria = (regex, chars, count) => {
|
|
38
|
+
while ((password.match(regex) || []).length < count) {
|
|
39
|
+
const randomIndex = generateRandomIndex(password.length);
|
|
40
|
+
password = password.substring(0, randomIndex) + chars.charAt(Math.floor(Math.random() * chars.length)) + password.substring(randomIndex + 1);
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
ensureCriteria(/[A-Z]/g, uppercaseChars, uppercase);
|
|
44
|
+
ensureCriteria(/[0-9]/g, numberChars, number);
|
|
45
|
+
ensureCriteria(/[^a-zA-Z0-9]/g, specialChars, special);
|
|
46
|
+
return password;
|
|
47
|
+
}
|
|
48
|
+
export function generateRandomIndex(max) {
|
|
49
|
+
if (max <= 0)
|
|
50
|
+
throw new Error("[MODS] Max value must be a positive integer");
|
|
51
|
+
if (max > 256)
|
|
52
|
+
throw new Error("[MODS] Max value must be less than 256");
|
|
53
|
+
const range = 256 - 256 % max;
|
|
54
|
+
let randomValue;
|
|
55
|
+
if (typeof window !== "undefined" && window.crypto && window.crypto.getRandomValues) {
|
|
56
|
+
do {
|
|
57
|
+
randomValue = window.crypto.getRandomValues(new Uint8Array(1))[0];
|
|
58
|
+
} while (randomValue >= range);
|
|
59
|
+
} else {
|
|
60
|
+
const crypto2 = require("crypto");
|
|
61
|
+
do {
|
|
62
|
+
randomValue = crypto2.randomBytes(1)[0];
|
|
63
|
+
} while (randomValue >= range);
|
|
42
64
|
}
|
|
43
|
-
return
|
|
65
|
+
return randomValue % max;
|
|
44
66
|
}
|
|
45
67
|
export function generateLoremIpsum(count = 5, format = "words") {
|
|
46
68
|
const lorem = "lorem ipsum dolor sit amet consectetur adipiscing elit sed do eiusmod tempor incididunt ut labore et dolore magna aliqua".split(" ");
|
|
@@ -1,16 +1,23 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Wraps each word, sentence or paragraph in a string with a tag.
|
|
3
|
+
* @info Don't forget to render the HTML safely.
|
|
3
4
|
*/
|
|
4
5
|
export declare function splitByWords(text: string): string;
|
|
5
6
|
/**
|
|
6
7
|
* Check the strength of a password against a given policy.
|
|
8
|
+
* @info Don't forget to use our Password Generator in the Generators section
|
|
7
9
|
*/
|
|
8
|
-
export declare function checkPasswordStrength(value: string,
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
10
|
+
export declare function checkPasswordStrength(value: string, options?: {
|
|
11
|
+
length?: number;
|
|
12
|
+
uppercase?: number;
|
|
13
|
+
number?: number;
|
|
14
|
+
special?: number;
|
|
15
|
+
}): object;
|
|
13
16
|
/**
|
|
14
17
|
* Replaces placeholders in a string with values from an object.
|
|
15
18
|
*/
|
|
16
19
|
export declare function mergeFields(text: string, fields: Record<string | number, string | number>): string;
|
|
20
|
+
/**
|
|
21
|
+
* Returns the reading time of a string in Hours, Minutes, and Seconds.
|
|
22
|
+
*/
|
|
23
|
+
export declare function readingTime(text: string, wordsPerMinute?: number): string;
|
|
@@ -15,7 +15,8 @@ export function splitByWords(text) {
|
|
|
15
15
|
}
|
|
16
16
|
return combinedSentences.join(" ");
|
|
17
17
|
}
|
|
18
|
-
export function checkPasswordStrength(value,
|
|
18
|
+
export function checkPasswordStrength(value, options) {
|
|
19
|
+
const { length = 8, uppercase = 1, number = 1, special = 1 } = options || {};
|
|
19
20
|
let strength = 0;
|
|
20
21
|
const counts = {
|
|
21
22
|
uppercase: (value.match(/[A-Z]/g) || []).length,
|
|
@@ -26,15 +27,15 @@ export function checkPasswordStrength(value, length, uppercase, numbers, special
|
|
|
26
27
|
return { score: 1, label: `Password must be at least ${length} characters long` };
|
|
27
28
|
if (counts.uppercase < uppercase)
|
|
28
29
|
return { score: 1, label: `Password must contain ${uppercase} uppercase letter` };
|
|
29
|
-
if (counts.numbers <
|
|
30
|
-
return { score: 1, label: `Password must contain ${
|
|
30
|
+
if (counts.numbers < number)
|
|
31
|
+
return { score: 1, label: `Password must contain ${number} number` };
|
|
31
32
|
if (counts.special < special)
|
|
32
33
|
return { score: 1, label: `Password must contain ${special} special character` };
|
|
33
34
|
if (value.length >= length)
|
|
34
35
|
strength++;
|
|
35
36
|
if (counts.uppercase >= uppercase)
|
|
36
37
|
strength++;
|
|
37
|
-
if (counts.numbers >=
|
|
38
|
+
if (counts.numbers >= number)
|
|
38
39
|
strength++;
|
|
39
40
|
if (counts.special >= special)
|
|
40
41
|
strength++;
|
|
@@ -48,11 +49,6 @@ export function checkPasswordStrength(value, length, uppercase, numbers, special
|
|
|
48
49
|
return { score: 1, label: "Weak" };
|
|
49
50
|
return { score: 0, label: "Very Weak" };
|
|
50
51
|
}
|
|
51
|
-
export function readingTime(text, wordsPerMinute = 200) {
|
|
52
|
-
const words = text.split(" ").length;
|
|
53
|
-
const minutes = Math.ceil(words / wordsPerMinute);
|
|
54
|
-
return formatDurationLabels(minutes * 60);
|
|
55
|
-
}
|
|
56
52
|
export function mergeFields(text, fields) {
|
|
57
53
|
const pattern = /\{\{\s*(\w+)\s*\}\}/g;
|
|
58
54
|
return text.replace(pattern, (match, key) => {
|
|
@@ -64,3 +60,8 @@ export function mergeFields(text, fields) {
|
|
|
64
60
|
}
|
|
65
61
|
});
|
|
66
62
|
}
|
|
63
|
+
export function readingTime(text, wordsPerMinute = 200) {
|
|
64
|
+
const words = text.split(" ").length;
|
|
65
|
+
const minutes = Math.ceil(words / wordsPerMinute);
|
|
66
|
+
return formatDurationLabels(minutes * 60);
|
|
67
|
+
}
|
|
@@ -20,10 +20,12 @@ export declare function endWithout(text: string, end: string): string;
|
|
|
20
20
|
export declare function surroundWith(text: string, start: string, end: string): string;
|
|
21
21
|
/**
|
|
22
22
|
* Adds plurals to a string except for excluded words.
|
|
23
|
+
* @info This handles most english pluralisation rules, but there are exceptions.
|
|
23
24
|
*/
|
|
24
25
|
export declare function pluralize(value: string, count: number): string;
|
|
25
26
|
/**
|
|
26
27
|
* Removes plurals from a string.
|
|
28
|
+
* @info This handles most english pluralisation rules, but there are exceptions.
|
|
27
29
|
*/
|
|
28
30
|
export declare function singularize(value: string): string;
|
|
29
31
|
/**
|
|
@@ -139,7 +139,7 @@ export function ordinalize(value) {
|
|
|
139
139
|
return value + (suffixes[(remainder - 20) % 10] || suffixes[remainder] || suffixes[0]);
|
|
140
140
|
}
|
|
141
141
|
export function stripHtml(text) {
|
|
142
|
-
return text.replace(
|
|
142
|
+
return text.replace(/<\/?[^>]+(>|$)/g, "");
|
|
143
143
|
}
|
|
144
144
|
export function stripWhitespace(text) {
|
|
145
145
|
return text.replace(/\s+/g, "");
|
|
@@ -59,7 +59,6 @@ export declare function range(numbers: number[]): number;
|
|
|
59
59
|
*/
|
|
60
60
|
export declare function standardDeviation(numbers: number[]): number;
|
|
61
61
|
/**
|
|
62
|
-
* Returns the measure of asymmetry of the probability distribution of an array of numbers.
|
|
63
|
-
* The skewness value can be positive, zero, negative, or undefined.
|
|
62
|
+
* Returns the measure of asymmetry of the probability distribution of an array of numbers. The skewness value can be positive, zero, negative, or undefined.
|
|
64
63
|
*/
|
|
65
|
-
export declare function skewness(numbers: number[]): number
|
|
64
|
+
export declare function skewness(numbers: number[]): number;
|
|
@@ -1,10 +1,16 @@
|
|
|
1
1
|
export function sum(numbers) {
|
|
2
|
+
if (numbers.length === 0)
|
|
3
|
+
return 0;
|
|
2
4
|
return numbers.reduce((a, b) => a + b, 0);
|
|
3
5
|
}
|
|
4
6
|
export function mean(numbers) {
|
|
7
|
+
if (numbers.length === 0)
|
|
8
|
+
return 0;
|
|
5
9
|
return sum(numbers) / numbers.length;
|
|
6
10
|
}
|
|
7
11
|
export function average(numbers) {
|
|
12
|
+
if (numbers.length === 0)
|
|
13
|
+
return 0;
|
|
8
14
|
return mean(numbers);
|
|
9
15
|
}
|
|
10
16
|
export function margin(value, percentage) {
|
|
@@ -63,7 +69,7 @@ export function skewness(numbers) {
|
|
|
63
69
|
const n = numbers.length;
|
|
64
70
|
const meanValue = mean(numbers);
|
|
65
71
|
if (standardDeviation(numbers) === 0)
|
|
66
|
-
return
|
|
72
|
+
return 0;
|
|
67
73
|
let sum2 = 0;
|
|
68
74
|
for (const num of numbers)
|
|
69
75
|
sum2 += (num - meanValue) ** 3;
|