magic-utils-yonava 1.0.2 → 1.0.3

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 (65) hide show
  1. package/dist/clone.d.ts +9 -0
  2. package/dist/clone.js +15 -0
  3. package/dist/clone.test.d.ts +1 -0
  4. package/dist/clone.test.js +42 -0
  5. package/dist/colors.d.ts +522 -0
  6. package/{src/colors.ts → dist/colors.js} +224 -274
  7. package/dist/ctx/index.d.ts +10 -0
  8. package/dist/ctx/index.js +19 -0
  9. package/dist/debounce.d.ts +9 -0
  10. package/{src/debounce.ts → dist/debounce.js} +6 -6
  11. package/dist/debugging.d.ts +2 -0
  12. package/dist/debugging.js +21 -0
  13. package/dist/deepDelta/delta.test.d.ts +1 -0
  14. package/dist/deepDelta/delta.test.js +114 -0
  15. package/dist/deepDelta/index.d.ts +8 -0
  16. package/dist/deepDelta/index.js +40 -0
  17. package/dist/deepMerge.d.ts +16 -0
  18. package/dist/deepMerge.js +32 -0
  19. package/dist/deepMerge.test.d.ts +1 -0
  20. package/dist/deepMerge.test.js +68 -0
  21. package/dist/fps.d.ts +6 -0
  22. package/dist/fps.js +51 -0
  23. package/dist/fracDecConverter/index.d.ts +9 -0
  24. package/dist/fracDecConverter/index.js +34 -0
  25. package/dist/hashing.d.ts +2 -0
  26. package/dist/hashing.js +7 -0
  27. package/dist/id.d.ts +5 -0
  28. package/dist/localStorage.d.ts +37 -0
  29. package/dist/localStorage.js +22 -0
  30. package/dist/math.d.ts +60 -0
  31. package/{src/math.ts → dist/math.js} +28 -32
  32. package/dist/math.test.d.ts +1 -0
  33. package/dist/math.test.js +42 -0
  34. package/{src/maybeGetter/index.ts → dist/maybeGetter/index.d.ts} +3 -18
  35. package/dist/maybeGetter/index.js +15 -0
  36. package/dist/mouse.d.ts +8 -0
  37. package/{src/mouse.ts → dist/mouse.js} +4 -4
  38. package/dist/random.d.ts +19 -0
  39. package/dist/random.js +21 -0
  40. package/dist/sets.d.ts +8 -0
  41. package/{src/sets.ts → dist/sets.js} +2 -2
  42. package/dist/string.d.ts +21 -0
  43. package/{src/string.ts → dist/string.js} +11 -11
  44. package/dist/string.test.d.ts +1 -0
  45. package/dist/string.test.js +14 -0
  46. package/{src/types.ts → dist/types.d.ts} +13 -38
  47. package/dist/types.js +1 -0
  48. package/package.json +4 -1
  49. package/src/clone.test.ts +0 -47
  50. package/src/clone.ts +0 -15
  51. package/src/ctx/index.ts +0 -20
  52. package/src/debugging.ts +0 -23
  53. package/src/deepDelta/delta.test.ts +0 -129
  54. package/src/deepDelta/index.ts +0 -48
  55. package/src/deepMerge.test.ts +0 -89
  56. package/src/deepMerge.ts +0 -37
  57. package/src/fps.ts +0 -64
  58. package/src/fracDecConverter/index.ts +0 -36
  59. package/src/hashing.ts +0 -9
  60. package/src/localStorage.ts +0 -49
  61. package/src/math.test.ts +0 -57
  62. package/src/random.ts +0 -27
  63. package/src/string.test.ts +0 -17
  64. package/tsconfig.json +0 -20
  65. /package/{src/id.ts → dist/id.js} +0 -0
@@ -6,10 +6,10 @@
6
6
  * @param ms time in milliseconds
7
7
  * @returns a debounced function
8
8
  */
9
- export const debounce = <T extends () => void>(fn: T, ms: number) => {
10
- let timeout: NodeJS.Timeout;
11
- return () => {
12
- clearTimeout(timeout);
13
- timeout = setTimeout(fn, ms);
14
- };
9
+ export const debounce = (fn, ms) => {
10
+ let timeout;
11
+ return () => {
12
+ clearTimeout(timeout);
13
+ timeout = setTimeout(fn, ms);
14
+ };
15
15
  };
@@ -0,0 +1,2 @@
1
+ export declare const useLogReport: <T = string>(frequencyMs?: number, resetReportAfterLogging?: boolean) => Set<T>;
2
+ export declare const useCooldownLog: (frequencyMs?: number) => (...data: any[]) => void;
@@ -0,0 +1,21 @@
1
+ export const useLogReport = (frequencyMs = 1000, resetReportAfterLogging = true) => {
2
+ const report = new Set();
3
+ const logReport = () => {
4
+ console.log(Array.from(report));
5
+ if (resetReportAfterLogging)
6
+ report.clear();
7
+ };
8
+ setInterval(logReport, frequencyMs);
9
+ return report;
10
+ };
11
+ export const useCooldownLog = (frequencyMs = 1000) => {
12
+ let cooldown = false;
13
+ const log = (...data) => {
14
+ if (cooldown)
15
+ return;
16
+ console.log(...data);
17
+ cooldown = true;
18
+ };
19
+ setInterval(() => (cooldown = false), frequencyMs);
20
+ return log;
21
+ };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,114 @@
1
+ import { expect, test } from 'vitest';
2
+ import { delta } from '.';
3
+ test('deepDelta standard', () => {
4
+ const yona = {
5
+ name: 'yona',
6
+ sex: 'm',
7
+ residence: 'amherst',
8
+ school: {
9
+ name: 'umass',
10
+ year: 'senior',
11
+ info: {
12
+ major: ['cs'],
13
+ minor: [],
14
+ start: '2023',
15
+ },
16
+ },
17
+ test: {
18
+ hello: 'world',
19
+ removeMe: {
20
+ removeMe: 'removeMe',
21
+ removeMe2: {},
22
+ },
23
+ test2: {
24
+ test3: 'secret',
25
+ },
26
+ },
27
+ };
28
+ const dila = {
29
+ name: 'dila',
30
+ sex: 'f',
31
+ residence: 'amherst',
32
+ school: {
33
+ name: 'umass',
34
+ year: 'junior',
35
+ info: {
36
+ major: ['cs', 'japanese'],
37
+ minor: [],
38
+ start: '2022',
39
+ },
40
+ },
41
+ test: {
42
+ hello: 'world',
43
+ removeMe: {
44
+ removeMe: 'removeMe',
45
+ removeMe2: {},
46
+ },
47
+ test2: {
48
+ test3: 'secret changed',
49
+ },
50
+ },
51
+ };
52
+ const expected = {
53
+ name: 'dila',
54
+ sex: 'f',
55
+ school: {
56
+ year: 'junior',
57
+ info: {
58
+ major: ['cs', 'japanese'],
59
+ start: '2022',
60
+ },
61
+ },
62
+ test: {
63
+ test2: {
64
+ test3: 'secret changed',
65
+ },
66
+ },
67
+ };
68
+ const result = delta(yona, dila);
69
+ expect(result).toEqual(expected);
70
+ });
71
+ test('deepDelta works if new object has more keys', () => {
72
+ const yona = {
73
+ name: 'yona',
74
+ };
75
+ const dila = {
76
+ name: 'dila',
77
+ favoriteColor: 'blue',
78
+ anime: {
79
+ naruto: 'meh',
80
+ bleach: 'good',
81
+ },
82
+ };
83
+ const expected = {
84
+ name: 'dila',
85
+ favoriteColor: 'blue',
86
+ anime: {
87
+ naruto: 'meh',
88
+ bleach: 'good',
89
+ },
90
+ };
91
+ const result = delta(yona, dila);
92
+ expect(result).toEqual(expected);
93
+ });
94
+ test('deepDelta works on fields that are null or undefined', () => {
95
+ const colorGetter = () => 'blue';
96
+ const yona = {
97
+ name: 'yona',
98
+ favoriteColor: {
99
+ color: colorGetter,
100
+ },
101
+ sbahn: 's1',
102
+ };
103
+ const dila = {
104
+ name: 'dila',
105
+ favoriteColor: null,
106
+ sbahn: undefined,
107
+ };
108
+ const expected = {
109
+ name: 'dila',
110
+ sbahn: undefined,
111
+ };
112
+ const result = delta(yona, dila);
113
+ expect(result).toEqual(expected);
114
+ });
@@ -0,0 +1,8 @@
1
+ /**
2
+ * gets the delta between two objects
3
+ *
4
+ * @param oldObject
5
+ * @param newObject
6
+ * @returns an object with only the changes, the values are the new values
7
+ */
8
+ export declare const delta: (oldObject: Record<any, any>, newObject: Record<any, any>) => Record<any, any> | null;
@@ -0,0 +1,40 @@
1
+ // recursively compare two objects and return the delta
2
+ // -----------------
3
+ const isObj = (obj) => Object.prototype.toString.call(obj) === '[object Object]';
4
+ /**
5
+ * gets the delta between two objects
6
+ *
7
+ * @param oldObject
8
+ * @param newObject
9
+ * @returns an object with only the changes, the values are the new values
10
+ */
11
+ export const delta = (oldObject, newObject) => {
12
+ const output = {};
13
+ if (!oldObject)
14
+ return newObject;
15
+ if (!newObject)
16
+ return null;
17
+ const oldObjectKeys = Object.keys(oldObject);
18
+ const newObjectKeys = Object.keys(newObject);
19
+ for (const key of newObjectKeys) {
20
+ if (!oldObjectKeys.includes(key)) {
21
+ output[key] = newObject[key];
22
+ }
23
+ }
24
+ for (const key of oldObjectKeys) {
25
+ if (isObj(oldObject[key])) {
26
+ const diffObj = delta(oldObject[key], newObject[key]);
27
+ if (diffObj)
28
+ output[key] = diffObj;
29
+ continue;
30
+ }
31
+ if (Array.isArray(oldObject[key])) {
32
+ if (JSON.stringify(oldObject[key]) !== JSON.stringify(newObject[key]))
33
+ output[key] = newObject[key];
34
+ continue;
35
+ }
36
+ else if (oldObject[key] !== newObject[key])
37
+ output[key] = newObject[key];
38
+ }
39
+ return Object.keys(output).length ? output : null;
40
+ };
@@ -0,0 +1,16 @@
1
+ export declare const isPlainObject: (obj: any) => obj is Record<string | number | symbol, unknown>;
2
+ /**
3
+ * Deeply merges multiple objects. Properties from later objects overwrite those from earlier ones.
4
+ * Non-object values (including arrays) are replaced, not merged.
5
+ *
6
+ * @param {...any[]} objects - Objects to merge. The rightmost object's properties take precedence.
7
+ * @returns {any} - A new deeply merged object.
8
+ *
9
+ * @example
10
+ * const result = deepMerge(
11
+ * { a: 1, b: { c: 2 } },
12
+ * { b: { d: 3 }, e: 4 }
13
+ * );
14
+ * // result: { a: 1, b: { c: 2, d: 3 }, e: 4 }
15
+ */
16
+ export declare const deepMerge: (...objects: any[]) => any;
@@ -0,0 +1,32 @@
1
+ export const isPlainObject = (obj) => !!obj &&
2
+ typeof obj === 'object' &&
3
+ Object.getPrototypeOf(obj) === Object.prototype;
4
+ /**
5
+ * Deeply merges multiple objects. Properties from later objects overwrite those from earlier ones.
6
+ * Non-object values (including arrays) are replaced, not merged.
7
+ *
8
+ * @param {...any[]} objects - Objects to merge. The rightmost object's properties take precedence.
9
+ * @returns {any} - A new deeply merged object.
10
+ *
11
+ * @example
12
+ * const result = deepMerge(
13
+ * { a: 1, b: { c: 2 } },
14
+ * { b: { d: 3 }, e: 4 }
15
+ * );
16
+ * // result: { a: 1, b: { c: 2, d: 3 }, e: 4 }
17
+ */
18
+ export const deepMerge = (...objects) => objects.reduce((acc, obj) => {
19
+ if (obj === undefined || obj === null)
20
+ return acc;
21
+ if (!isPlainObject(obj))
22
+ return obj;
23
+ Object.keys(obj).forEach((key) => {
24
+ if (isPlainObject(obj[key]) && isPlainObject(acc[key])) {
25
+ acc[key] = deepMerge(acc[key], obj[key]);
26
+ }
27
+ else {
28
+ acc[key] = obj[key];
29
+ }
30
+ });
31
+ return acc;
32
+ }, {});
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,68 @@
1
+ import { describe, expect, it } from 'vitest';
2
+ import { deepMerge } from './deepMerge';
3
+ describe('deepMerge', () => {
4
+ it('merges flat objects with rightmost priority', () => {
5
+ const result = deepMerge({ a: 1 }, { a: 2, b: 3 });
6
+ expect(result).toEqual({ a: 2, b: 3 });
7
+ });
8
+ it('merges nested objects deeply', () => {
9
+ const result = deepMerge({ a: { b: 1, c: 2 } }, { a: { b: 3, d: 4 } });
10
+ expect(result).toEqual({ a: { b: 3, c: 2, d: 4 } });
11
+ });
12
+ it('overwrites arrays instead of merging them', () => {
13
+ const result = deepMerge({ a: [1, 2], b: { c: [3, 4] } }, { a: [5], b: { c: [6] } });
14
+ expect(result).toEqual({ a: [5], b: { c: [6] } });
15
+ });
16
+ it('handles primitive overwrites correctly', () => {
17
+ const result = deepMerge({ a: { b: 1 } }, { a: 5 });
18
+ expect(result).toEqual({ a: 5 });
19
+ });
20
+ it('returns non-object when passed a primitive last', () => {
21
+ const result = deepMerge({ a: 1 }, 5);
22
+ expect(result).toBe(5);
23
+ });
24
+ it('handles merging with undefined and null safely', () => {
25
+ const result = deepMerge({ a: { b: 1 } }, undefined, null, { a: { c: 2 } });
26
+ expect(result).toEqual({ a: { b: 1, c: 2 } });
27
+ });
28
+ it('handles empty inputs', () => {
29
+ const result = deepMerge();
30
+ expect(result).toEqual({});
31
+ });
32
+ });
33
+ describe('deepMerge - special cases', () => {
34
+ it('overwrites Date objects', () => {
35
+ const date1 = new Date('2020-01-01');
36
+ const date2 = new Date('2021-01-01');
37
+ const result = deepMerge({ date: date1 }, { date: date2 });
38
+ expect(result.date).toBe(date2);
39
+ });
40
+ it('overwrites Map objects', () => {
41
+ const map1 = new Map([['a', 1]]);
42
+ const map2 = new Map([['b', 2]]);
43
+ const result = deepMerge({ map: map1 }, { map: map2 });
44
+ expect(result.map).toBe(map2);
45
+ });
46
+ it('overwrites Set objects', () => {
47
+ const set1 = new Set([1, 2]);
48
+ const set2 = new Set([3, 4]);
49
+ const result = deepMerge({ set: set1 }, { set: set2 });
50
+ expect(result.set).toBe(set2);
51
+ });
52
+ it('overwrites functions', () => {
53
+ const fn1 = () => 1;
54
+ const fn2 = () => 2;
55
+ const result = deepMerge({ fn: fn1 }, { fn: fn2 });
56
+ expect(result.fn).toBe(fn2);
57
+ expect(result.fn()).toBe(2);
58
+ });
59
+ it('overwrites class instances', () => {
60
+ class Example {
61
+ x = 1;
62
+ }
63
+ const obj1 = { instance: new Example() };
64
+ const obj2 = { instance: { y: 2 } };
65
+ const result = deepMerge(obj1, obj2);
66
+ expect(result.instance).toEqual({ y: 2 });
67
+ });
68
+ });
package/dist/fps.d.ts ADDED
@@ -0,0 +1,6 @@
1
+ export declare function useFPS(): {
2
+ fps: import("vue").Ref<number, number>;
3
+ frameTime: import("vue").Ref<number, number>;
4
+ slowFrameCount: import("vue").Ref<number, number>;
5
+ slowFrameRatio: import("vue").Ref<number, number>;
6
+ };
package/dist/fps.js ADDED
@@ -0,0 +1,51 @@
1
+ import { onMounted, onUnmounted, ref } from "vue";
2
+ export function useFPS() {
3
+ const fps = ref(0);
4
+ const frameTime = ref(0);
5
+ const slowFrameCount = ref(0);
6
+ const slowFrameRatio = ref(0);
7
+ let frameId;
8
+ let intervalId;
9
+ let lastMeasure = performance.now();
10
+ let lastFrame = performance.now();
11
+ let frames = 0;
12
+ let slowFrames = 0;
13
+ const SLOW_FRAME_THRESHOLD = 33.3; // ms
14
+ const update = () => {
15
+ const now = performance.now();
16
+ const delta = now - lastFrame;
17
+ frameTime.value = delta;
18
+ lastFrame = now;
19
+ if (delta > SLOW_FRAME_THRESHOLD) {
20
+ slowFrames++;
21
+ }
22
+ frames++;
23
+ frameId = requestAnimationFrame(update);
24
+ };
25
+ const measure = () => {
26
+ const now = performance.now();
27
+ const delta = now - lastMeasure;
28
+ fps.value = Math.round((frames * 1000) / delta);
29
+ slowFrameCount.value = slowFrames;
30
+ slowFrameRatio.value = frames > 0 ? slowFrames / frames : 0;
31
+ frames = 0;
32
+ slowFrames = 0;
33
+ lastMeasure = now;
34
+ };
35
+ onMounted(() => {
36
+ lastFrame = performance.now();
37
+ lastMeasure = performance.now();
38
+ frameId = requestAnimationFrame(update);
39
+ intervalId = setInterval(measure, 500);
40
+ });
41
+ onUnmounted(() => {
42
+ cancelAnimationFrame(frameId);
43
+ clearInterval(intervalId);
44
+ });
45
+ return {
46
+ fps,
47
+ frameTime,
48
+ slowFrameCount,
49
+ slowFrameRatio,
50
+ };
51
+ }
@@ -0,0 +1,9 @@
1
+ export declare const gcd: (a: number, b: number) => number;
2
+ export declare const isNullOrUnd: (input: any) => boolean;
3
+ export declare const isFraction: (input: string) => boolean;
4
+ export declare const decimalToFraction: (decimalInput: number) => string;
5
+ /**
6
+ * @param fractionInput a string representing a fraction
7
+ * @returns the decimal representation of the fraction or undefined if the input is not a fraction
8
+ */
9
+ export declare const fractionToDecimal: (fractionInput: string) => number | undefined;
@@ -0,0 +1,34 @@
1
+ export const gcd = (a, b) => (b ? gcd(b, a % b) : a);
2
+ export const isNullOrUnd = (input) => input === null || input === undefined;
3
+ export const isFraction = (input) => {
4
+ const fraction = input.trim().split('/').filter(Boolean);
5
+ if (fraction.length !== 2)
6
+ return false;
7
+ const [numerator, denominator] = fraction.map(Number);
8
+ if (isNullOrUnd(numerator) || isNullOrUnd(denominator))
9
+ return false;
10
+ return true;
11
+ };
12
+ export const decimalToFraction = (decimalInput) => {
13
+ const decimal = Math.round(decimalInput * 1e10) / 1e10;
14
+ const len = decimal.toString().length - 2;
15
+ let denominator = 10 ** len;
16
+ let numerator = decimal * denominator;
17
+ const divisor = gcd(numerator, denominator);
18
+ numerator /= divisor;
19
+ denominator /= divisor;
20
+ if (denominator === 1)
21
+ return numerator.toString();
22
+ return `${numerator}/${denominator}`;
23
+ };
24
+ /**
25
+ * @param fractionInput a string representing a fraction
26
+ * @returns the decimal representation of the fraction or undefined if the input is not a fraction
27
+ */
28
+ export const fractionToDecimal = (fractionInput) => {
29
+ if (!isFraction(fractionInput))
30
+ return;
31
+ const fraction = fractionInput.split('/');
32
+ const [numerator, denominator] = fraction.map(Number);
33
+ return numerator / denominator;
34
+ };
@@ -0,0 +1,2 @@
1
+ export declare const djb2Hasher: (str: string) => number;
2
+ export type DJB2Hash = ReturnType<typeof djb2Hasher>;
@@ -0,0 +1,7 @@
1
+ export const djb2Hasher = (str) => {
2
+ let hash = 5381;
3
+ for (let i = 0; i < str.length; i++) {
4
+ hash = (hash << 5) + hash + str.charCodeAt(i);
5
+ }
6
+ return hash >>> 0;
7
+ };
package/dist/id.d.ts ADDED
@@ -0,0 +1,5 @@
1
+ /**
2
+ * generates a new, random, id
3
+ * @example generateId() // 'abc123'
4
+ */
5
+ export declare const generateId: () => string;
@@ -0,0 +1,37 @@
1
+ /**
2
+ * a registry for all localStorage keys this application uses
3
+ */
4
+ export declare const localKeys: {
5
+ /** nodes in graph product */
6
+ readonly nodes: (key: string) => `nodes-${string}`;
7
+ /** edges in graph product */
8
+ readonly edges: (key: string) => `edges-${string}`;
9
+ /** graph product simulation speed */
10
+ readonly simulationPlaybackSpeed: "simulation-playback-speed";
11
+ /** graph theme set by user - {@link Graph.preferredTheme} */
12
+ readonly preferredTheme: "preferred-theme";
13
+ };
14
+ /**
15
+ * all return values of localStorage are, by default, string.
16
+ * this type allows string to be narrowed to types such as 'true' | 'false'
17
+ */
18
+ type TypeOverride = {};
19
+ type LocalObj = typeof localKeys;
20
+ /**
21
+ * @example
22
+ * type T = TypeOrReturnType<number> // number
23
+ * type TFunc = TypeOrReturnType<() => number> // number
24
+ */
25
+ type TypeOrReturnType<T> = T extends (...args: any[]) => infer U ? U : T;
26
+ type LocalKeys = TypeOrReturnType<LocalObj[keyof LocalObj]>;
27
+ type LocalType<T extends LocalKeys> = T extends keyof TypeOverride ? TypeOverride[T] : string;
28
+ /**
29
+ * perform **type safe** localStorage actions
30
+ */
31
+ export declare const local: {
32
+ get: <T extends LocalKeys>(key: T) => string | null;
33
+ set: <T extends LocalKeys, K extends LocalType<T>>(key: T, value: K) => void;
34
+ remove: <T extends LocalKeys>(key: T) => void;
35
+ clear: () => void;
36
+ };
37
+ export {};
@@ -0,0 +1,22 @@
1
+ /**
2
+ * a registry for all localStorage keys this application uses
3
+ */
4
+ export const localKeys = {
5
+ /** nodes in graph product */
6
+ nodes: (key) => `nodes-${key}`,
7
+ /** edges in graph product */
8
+ edges: (key) => `edges-${key}`,
9
+ /** graph product simulation speed */
10
+ simulationPlaybackSpeed: 'simulation-playback-speed',
11
+ /** graph theme set by user - {@link Graph.preferredTheme} */
12
+ preferredTheme: 'preferred-theme',
13
+ };
14
+ /**
15
+ * perform **type safe** localStorage actions
16
+ */
17
+ export const local = {
18
+ get: (key) => localStorage.getItem(key),
19
+ set: (key, value) => localStorage.setItem(key, value),
20
+ remove: (key) => localStorage.removeItem(key),
21
+ clear: localStorage.clear,
22
+ };
package/dist/math.d.ts ADDED
@@ -0,0 +1,60 @@
1
+ /**
2
+ * the golden ratio constant.
3
+ * {@link} https://en.wikipedia.org/wiki/Golden_ratio
4
+ */
5
+ export declare const GOLDEN_RATIO = 1.618;
6
+ /**
7
+ * rounds a number to the nearest multiple of another number
8
+ *
9
+ * @param n the number to round
10
+ * @param nearest the number to round to
11
+ * @returns the rounded number
12
+ * @example const roundToNearest5 = roundToNearestN(5);
13
+ * roundToNearest5(13) // 15
14
+ * roundToNearest5(12) // 10
15
+ */
16
+ export declare const roundToNearestN: (nearest: number) => (n: number) => number;
17
+ /**
18
+ * get the prime factors of a number
19
+ *
20
+ * @param num the number to get the prime factors of
21
+ * @returns the prime factors of the number
22
+ * @example getPrimeFactors(12) // [2, 2, 3]
23
+ * getPrimeFactors(15) // [3, 5]
24
+ */
25
+ export declare const getPrimeFactors: (num: number) => number[];
26
+ /**
27
+ * get the lowest prime factor of a number
28
+ *
29
+ * @param num the number to get the lowest prime factor of
30
+ * @returns the lowest prime factor of the number
31
+ * @example
32
+ * lowestPrimeFactor(12) // 12 = 2 * 2 * 3, min(2, 2, 3) = 2
33
+ * lowestPrimeFactor(15) // 15 = 3 * 5, min(3, 5) = 3
34
+ */
35
+ export declare const lowestPrimeFactor: (num: number) => number;
36
+ /**
37
+ * get the greatest common divisor of two numbers.
38
+ * {@link} https://en.wikipedia.org/wiki/Euclidean_algorithm
39
+ * {@link} https://en.wikipedia.org/wiki/Greatest_common_divisor
40
+ *
41
+ * @param a the first number
42
+ * @param b the second number
43
+ * @returns the greatest common divisor of the two numbers
44
+ * @example gcd(12, 15) // 3
45
+ * gcd(12, 18) // 6
46
+ */
47
+ export declare const gcd: (a: number, b: number) => number;
48
+ /**
49
+ * check if two numbers are within a certain tolerance of each other
50
+ */
51
+ export declare const within: (tolerance: number) => (a: number, b: number) => boolean;
52
+ /**
53
+ * get the average of an array of numbers
54
+ *
55
+ * @param arr the array of numbers to average
56
+ * @returns the average of the array
57
+ * @example average([1, 2, 3]) // 2
58
+ * average([1, 2, 3, 4]) // 2.5
59
+ */
60
+ export declare const average: (arr: number[]) => number;