@zoodogood/utils 2.0.2-change.1508 → 3.0.0-change.2568

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.
@@ -6,7 +6,7 @@ export type APIBaseButton = import("discord-api-types/v10").APIButtonComponentBa
6
6
  *
7
7
  * @param {Partial<APIBaseButton>[]} resolable
8
8
  */
9
- export function justButtonComponents(...resolable: Partial<import("discord-api-types/v10").APIButtonComponentBase<any>>[]): {
9
+ export function justButtonComponents(...resolable: Partial<APIBaseButton>[]): {
10
10
  label?: string | undefined;
11
11
  style: any;
12
12
  emoji?: import("discord-api-types/v10").APIMessageComponentEmoji | undefined;
@@ -15,4 +15,4 @@ export function justButtonComponents(...resolable: Partial<import("discord-api-t
15
15
  customId: string;
16
16
  }[];
17
17
  export function justSendMessage(target: any, options: any): Promise<any>;
18
- import { ComponentType as ComponentType_1 } from "discord.js";
18
+ import { ComponentType } from "discord.js";
@@ -1,12 +1,3 @@
1
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
- return new (P || (P = Promise))(function (resolve, reject) {
4
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
- step((generator = generator.apply(thisArg, _arguments || [])).next());
8
- });
9
- };
10
1
  import { BaseInteraction, ButtonStyle, ComponentType } from "discord.js";
11
2
  import { CreateMessage } from "./simplify.js";
12
3
  const DEFAULTS_FOR_BUTTON = {
@@ -21,34 +12,36 @@ const DEFAULTS_FOR_BUTTON = {
21
12
  * @param {Partial<APIBaseButton>[]} resolable
22
13
  */
23
14
  function justButtonComponents(...resolable) {
24
- const buttons = resolable.map((data, i) => (Object.assign(Object.assign(Object.assign({}, DEFAULTS_FOR_BUTTON), { customId: `button.${i + 1}` }), data)));
15
+ const buttons = resolable.map((data, i) => ({
16
+ ...DEFAULTS_FOR_BUTTON,
17
+ customId: `button.${i + 1}`,
18
+ ...data,
19
+ }));
25
20
  return buttons;
26
21
  }
27
- function justSendMessage(target, options) {
28
- return __awaiter(this, void 0, void 0, function* () {
29
- const messagePayload = CreateMessage(options);
30
- const message = target instanceof BaseInteraction
31
- ? yield (options.edit
32
- ? target.replied
33
- ? target.editReply(messagePayload)
34
- : target.update(messagePayload)
35
- : target.reply(messagePayload))
36
- : yield (options.edit
37
- ? target.edit(messagePayload)
38
- : target.send(messagePayload));
39
- if (options.delete) {
40
- setTimeout(() => message.delete(), options.delete);
41
- }
42
- if (options.reactions) {
43
- options.reactions
44
- .filter(Boolean)
45
- .filter((react) => {
46
- var _a;
47
- return !((_a = message.reactions) === null || _a === void 0 ? void 0 : _a.cache.some((compared) => compared.emoji.code === react));
48
- })
49
- .forEach((react) => message.react(react));
50
- }
51
- return message;
52
- });
22
+ async function justSendMessage(target, options) {
23
+ const messagePayload = CreateMessage(options);
24
+ const message = target instanceof BaseInteraction
25
+ ? await (options.edit
26
+ ? target.replied
27
+ ? target.editReply(messagePayload)
28
+ : target.update(messagePayload)
29
+ : target.reply(messagePayload))
30
+ : await (options.edit
31
+ ? target.edit(messagePayload)
32
+ : target.send(messagePayload));
33
+ if (options.delete) {
34
+ setTimeout(() => message.delete(), options.delete);
35
+ }
36
+ if (options.reactions) {
37
+ options.reactions
38
+ .filter(Boolean)
39
+ .filter((react) => {
40
+ var _a;
41
+ return !((_a = message.reactions) === null || _a === void 0 ? void 0 : _a.cache.some((compared) => compared.emoji.code === react));
42
+ })
43
+ .forEach((react) => message.react(react));
44
+ }
45
+ return message;
53
46
  }
54
47
  export { justButtonComponents, justSendMessage };
@@ -1,4 +1,3 @@
1
- /// <reference types="node" resolution-mode="require"/>
2
1
  import type { ChildProcessWithoutNullStreams } from "child_process";
3
2
  import EventsEmitter from "events";
4
3
  interface IContext {
@@ -0,0 +1,29 @@
1
+ /**
2
+ * MARK: Представьте отель
3
+ * Часть его номеров свободны, а часть — заняты
4
+ * Есть две особенности.
5
+ * 1) При заселении ищется случайный номер
6
+ * 2) Хотя у нас есть список занятых номеров, у нас не может быть списка свободных (за условием задачи)
7
+ * Этот алгоритм используется для эффективного поиска тех самых свободных номеров, которые удовлетворяют заданному условию
8
+ */
9
+ export declare class BusyNumeric {
10
+ #private;
11
+ readonly range: number;
12
+ readonly busy_areas: (readonly [number, number])[];
13
+ get peak_start_busy(): boolean;
14
+ get peak_end_busy(): boolean;
15
+ constructor(range: number);
16
+ bifurcate(point: number): void;
17
+ segments_count(): number;
18
+ segment(at: number): {
19
+ size: number;
20
+ left: readonly [number, number];
21
+ right: readonly [number, number];
22
+ } | undefined;
23
+ insert_area(start: number, end: number): void;
24
+ refresh: {
25
+ _areas: () => number;
26
+ _peak: () => void;
27
+ full: () => void;
28
+ };
29
+ }
@@ -0,0 +1,167 @@
1
+ // task: честный алгоритм , для которого каждый из элеметов списка имеет равный шанс на реализацию своей вероятности.
2
+ // Обычно весь список фильтруется и после выбирается элемент. В нашем случае фильтр будет срабатывать только для тех элементов,
3
+ // которые на этапе фильтрации «выбраны» — то есть имеют свою стопроцентную вероятность быть окончательными после успешного прохождения фильтра
4
+ // требования: честная вероятность; итоговая производительность должна быть выше обычной при проходе списка фильтром
5
+ // Алгоритм:
6
+ /*
7
+ Оптимальный алгоритм поиска случайного элемента списка, удовлетворяющего условию. Поддерживается возможность задавать элементам коэффициент вероятности
8
+
9
+ Перед выбором элемента выбираем случайный сегмент, далее случайный элемент в этом сегменте
10
+
11
+ Если соответствует условию, возвращаем элемент. Завершаем поиск
12
+
13
+ Иначе исключаем элемент путем раздвоения текущего сегмента так, чтобы элемент не оказался ни в одном сегменте списка
14
+
15
+ Повторяем
16
+ */
17
+ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
18
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
19
+ if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
20
+ return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
21
+ };
22
+ var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
23
+ if (kind === "m") throw new TypeError("Private method is not writable");
24
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
25
+ if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
26
+ return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
27
+ };
28
+ var _BusyNumeric_peak_start_busy, _BusyNumeric_peak_end_busy;
29
+ import { binary_search } from "../primitives/binary_search.js";
30
+ /**
31
+ * MARK: Представьте отель
32
+ * Часть его номеров свободны, а часть — заняты
33
+ * Есть две особенности.
34
+ * 1) При заселении ищется случайный номер
35
+ * 2) Хотя у нас есть список занятых номеров, у нас не может быть списка свободных (за условием задачи)
36
+ * Этот алгоритм используется для эффективного поиска тех самых свободных номеров, которые удовлетворяют заданному условию
37
+ */
38
+ // Убежден что в алгоритме список busy_areas можно применить структуру бинарных деревьев.
39
+ // Если основное количество производительности не реализуется из-за особенностей структуры списка, то это можно оптимизировать
40
+ // Интересно что ветки дерева можно определять по индексу. Да, это интересное замечание.
41
+ // В BusyNumeric можно добавить ещё метод separate
42
+ export class BusyNumeric {
43
+ get peak_start_busy() {
44
+ var _a;
45
+ if (__classPrivateFieldGet(this, _BusyNumeric_peak_start_busy, "f")) {
46
+ return true;
47
+ }
48
+ if (((_a = this.busy_areas[0]) === null || _a === void 0 ? void 0 : _a[0]) !== 0) {
49
+ return false;
50
+ }
51
+ __classPrivateFieldSet(this, _BusyNumeric_peak_start_busy, true, "f");
52
+ return true;
53
+ }
54
+ get peak_end_busy() {
55
+ var _a;
56
+ if (__classPrivateFieldGet(this, _BusyNumeric_peak_end_busy, "f")) {
57
+ return true;
58
+ }
59
+ if (((_a = this.busy_areas.at(-1)) === null || _a === void 0 ? void 0 : _a[1]) !== this.range) {
60
+ return false;
61
+ }
62
+ __classPrivateFieldSet(this, _BusyNumeric_peak_end_busy, true, "f");
63
+ return true;
64
+ }
65
+ constructor(range) {
66
+ this.busy_areas = [];
67
+ _BusyNumeric_peak_start_busy.set(this, false);
68
+ _BusyNumeric_peak_end_busy.set(this, false);
69
+ this.refresh = {
70
+ _areas: () => (this.busy_areas.length = 0),
71
+ _peak: () => {
72
+ __classPrivateFieldSet(this, _BusyNumeric_peak_start_busy, false, "f");
73
+ __classPrivateFieldSet(this, _BusyNumeric_peak_end_busy, false, "f");
74
+ },
75
+ full: () => {
76
+ this.refresh._areas();
77
+ this.refresh._peak();
78
+ },
79
+ };
80
+ if (range <= 0) {
81
+ throw new Error("Assertion: range must be positive");
82
+ }
83
+ this.range = range;
84
+ }
85
+ bifurcate(point) {
86
+ this.insert_area(point, point);
87
+ }
88
+ segments_count() {
89
+ return (this.busy_areas.length + 1 - +this.peak_start_busy - +this.peak_end_busy);
90
+ }
91
+ segment(at) {
92
+ if (!this.range) {
93
+ return undefined;
94
+ }
95
+ const { peak_start_busy, peak_end_busy } = this;
96
+ const segments_count = this.segments_count();
97
+ if (at < 0) {
98
+ if (segments_count + at < 0) {
99
+ return undefined;
100
+ }
101
+ at = segments_count + at;
102
+ }
103
+ if (peak_start_busy) {
104
+ at += 1;
105
+ }
106
+ if (peak_end_busy && at > segments_count) {
107
+ return undefined;
108
+ }
109
+ if (at > segments_count + 1) {
110
+ return undefined;
111
+ }
112
+ const left = this.busy_areas[at - 1];
113
+ const right = this.busy_areas[at];
114
+ // formula: busy_area_point ± 1 (jump to segment)
115
+ const start = (left === null || left === void 0 ? void 0 : left[1]) + 1 || 0;
116
+ const end = right ? right[0] - 1 : this.range;
117
+ const size = end - start + 1;
118
+ return { size, left, right };
119
+ }
120
+ insert_area(start, end) {
121
+ if (!Number.isInteger(start) || !Number.isInteger(end)) {
122
+ throw new Error(`Assertion error: start or end not integer ${start} ${end}, maybe float?`);
123
+ }
124
+ if (start > end) {
125
+ [start, end] = [end, start];
126
+ }
127
+ if (start < 0) {
128
+ throw new Error("Assertion error: start < 0");
129
+ }
130
+ if (end > this.range) {
131
+ throw new Error("Assertion error: end > this.range");
132
+ }
133
+ const place_index = binary_search(this.busy_areas.length - 1, (index) => {
134
+ var _a, _b, _c;
135
+ const value = (_a = this.busy_areas[index]) === null || _a === void 0 ? void 0 : _a[1];
136
+ const biggest = end < value;
137
+ if (biggest) {
138
+ return 1;
139
+ }
140
+ return (+(((_c = (_b = this.busy_areas[index + 1]) === null || _b === void 0 ? void 0 : _b[1]) !== null && _c !== void 0 ? _c : Number.MAX_SAFE_INTEGER) > end) - 1);
141
+ }) + 1;
142
+ const left = this.busy_areas[place_index - 1];
143
+ const right = this.busy_areas[place_index];
144
+ const is_left_included = !!left && left[1] + 1 >= start;
145
+ const is_right_included = !!right && right[0] - 1 <= end;
146
+ // Merge strategy 3
147
+ if (is_left_included && is_right_included) {
148
+ this.busy_areas.splice(place_index - 1, 2, [left[0], right[1]]);
149
+ return;
150
+ }
151
+ // Merge strategy 2
152
+ if (is_left_included || is_right_included) {
153
+ const target = is_left_included ? left : right;
154
+ const [index, points] = is_left_included
155
+ ? [place_index - 1, [target[0], end]]
156
+ : [place_index, [start, target[1]]];
157
+ if (target[0] <= start && target[1] >= end) {
158
+ throw new Error("Assertion error: [start, end] in range");
159
+ }
160
+ this.busy_areas.splice(index, 1, points);
161
+ return;
162
+ }
163
+ // Merge strategy 1
164
+ this.busy_areas.splice(place_index, 0, [start, end]);
165
+ }
166
+ }
167
+ _BusyNumeric_peak_start_busy = new WeakMap(), _BusyNumeric_peak_end_busy = new WeakMap();
@@ -1,4 +1,3 @@
1
- /// <reference types="node" resolution-mode="require"/>
2
1
  interface ICustomCollectorOptions {
3
2
  target: Required<{
4
3
  removeListener: CallableFunction;
@@ -1,7 +1,27 @@
1
- interface IParams {
2
- needPop?: boolean;
1
+ import { create_default_preventable } from "../primitives/createDefaultPreventable.js";
2
+ import { BusyNumeric } from "./BusyNumeric.js";
3
+ interface IParams<T> {
3
4
  associatedWeights?: number[];
5
+ filter?: (item: T) => boolean;
4
6
  }
5
- export declare function getRandomElementIndexInWeights(weights: NonNullable<IParams["associatedWeights"]>): number | never;
6
- export declare function getRandomElementFromArray<T>(array: T[], { needPop, associatedWeights }?: IParams): T;
7
+ interface IPickContext<T> {
8
+ busy_preventable: ReturnType<typeof create_default_preventable>;
9
+ item: T;
10
+ pick: (context: IPickContext<T>) => boolean;
11
+ threshold: number;
12
+ point: number;
13
+ }
14
+ export declare class RandomizerContext<T> {
15
+ hotel: BusyNumeric;
16
+ array: T[];
17
+ thresholds?: number[];
18
+ constructor(array: T[], thresholds?: number[]);
19
+ static from<T>({ array, associatedWeights, }: {
20
+ array: T[];
21
+ associatedWeights?: IParams<T>["associatedWeights"];
22
+ }): RandomizerContext<T>;
23
+ pickRandom(pick?: IPickContext<T>["pick"]): T | undefined;
24
+ }
25
+ export declare function getRandomElementIndexInWeights(weights: NonNullable<IParams<unknown>["associatedWeights"]>): number | never;
26
+ export declare function getRandomElementFromArray<T>(array: T[], { associatedWeights, filter }?: IParams<T>): void;
7
27
  export {};
@@ -1,24 +1,103 @@
1
+ import { binary_search } from "../primitives/binary_search.js";
2
+ import { create_default_preventable } from "../primitives/createDefaultPreventable.js";
3
+ import { BusyNumeric } from "./BusyNumeric.js";
1
4
  import { getRandomNumberInRange } from "./getRandomNumberInRange.js";
2
- export function getRandomElementIndexInWeights(weights) {
5
+ export class RandomizerContext {
6
+ constructor(array, thresholds) {
7
+ var _a;
8
+ this.array = array;
9
+ this.thresholds = thresholds;
10
+ const range = (_a = thresholds === null || thresholds === void 0 ? void 0 : thresholds.at(-1)) !== null && _a !== void 0 ? _a : array.length;
11
+ this.hotel = new BusyNumeric(range);
12
+ }
13
+ static from({ array, associatedWeights, }) {
14
+ const thresholds = associatedWeights &&
15
+ _getRandomElementIndexInWeight_thresholds(associatedWeights);
16
+ return new RandomizerContext(array, thresholds);
17
+ }
18
+ pickRandom(pick = () => true) {
19
+ var _a;
20
+ const { hotel, thresholds, array } = this;
21
+ while (true) {
22
+ const segments_count = hotel.segments_count();
23
+ if (!segments_count) {
24
+ break;
25
+ }
26
+ const { left, size } = hotel.segment(getRandomNumberInRange({ max: segments_count - 1 }));
27
+ const point = ((_a = left === null || left === void 0 ? void 0 : left[1]) !== null && _a !== void 0 ? _a : -1) + getRandomNumberInRange({ min: 1, max: size });
28
+ const index = thresholds
29
+ ? _getRandomElementIndexInWeight_of_thresholds(thresholds, point)
30
+ : point;
31
+ const element = array[index];
32
+ const pickContext = {
33
+ busy_preventable: create_default_preventable(),
34
+ item: element,
35
+ pick,
36
+ threshold: index,
37
+ point,
38
+ };
39
+ if (pick(pickContext)) {
40
+ return element;
41
+ }
42
+ if (!pickContext.busy_preventable.default_prevented()) {
43
+ thresholds
44
+ ? hotel.insert_area(thresholds[index - 1] + 1 || 0, thresholds[index])
45
+ : hotel.bifurcate(index);
46
+ }
47
+ }
48
+ return undefined;
49
+ }
50
+ }
51
+ function _getRandomElementIndexInWeight_of_thresholds(thresholds, value) {
52
+ if (!thresholds.length) {
53
+ return -1;
54
+ }
55
+ return binary_search(thresholds.length - 1, (index) => {
56
+ var _a;
57
+ const hold = thresholds[index];
58
+ if (hold >= value && ((_a = thresholds[index - 1]) !== null && _a !== void 0 ? _a : -1) < value) {
59
+ return 0;
60
+ }
61
+ if (hold < value) {
62
+ return -1;
63
+ }
64
+ return 1;
65
+ });
66
+ }
67
+ function _getRandomElementIndexInWeight_thresholds(weights) {
3
68
  if (weights.length < 1) {
4
69
  new Error("Invalid array length");
5
70
  }
6
71
  let previousLimit = 0;
7
- const thresholds = weights.map((weight) => (previousLimit += weight));
72
+ return weights.map((weight) => (previousLimit += weight));
73
+ }
74
+ export function getRandomElementIndexInWeights(weights) {
75
+ const thresholds = _getRandomElementIndexInWeight_thresholds(weights);
8
76
  const lotterySecretNumber = Math.random() * thresholds.at(-1);
9
- return thresholds.findIndex((threshold) => threshold >= lotterySecretNumber);
77
+ return _getRandomElementIndexInWeight_of_thresholds(thresholds, lotterySecretNumber);
10
78
  }
11
- export function getRandomElementFromArray(array, { needPop, associatedWeights } = {}) {
79
+ // task: честный алгоритм , для которого каждый из элеметов списка имеет равный шанс на реализацию своей вероятности.
80
+ // Обычно весь список фильтруется и после выбирается элемент. В нашем случае фильтр будет срабатывать только для тех элементов,
81
+ // которые на этапе фильтрации «выбраны» — то есть имеют свою стопроцентную вероятность быть окончательными после успешного прохождения фильтра
82
+ // требования: честная вероятность; итоговая производительность должна быть выше обычной при проходе списка фильтром
83
+ // Алгоритм:
84
+ /*
85
+ Оптимальный алгоритм поиска случайного элемента списка, удовлетворяющего условию. Поддерживается возможность задавать элементам коэффициент вероятности
86
+
87
+ Перед выбором элемента выбираем случайный сегмент, далее случайный элемент в этом сегменте
88
+
89
+ Если соответствует условию, возвращаем элемент. Завершаем поиск
90
+
91
+ Иначе исключаем элемент путем раздвоения текущего сегмента так, чтобы элемент не оказался ни в одном сегменте списка
92
+
93
+ Повторяем
94
+ */
95
+ export function getRandomElementFromArray(array, { associatedWeights, filter = () => true } = {}) {
12
96
  if (associatedWeights && associatedWeights.length !== array.length) {
13
97
  throw new Error("Incorrectly passed argument associatedWeights: The length of the associatedWeights must exactly match the length of the weights array");
14
98
  }
15
- const index = associatedWeights
16
- ? getRandomElementIndexInWeights(associatedWeights)
17
- : getRandomNumberInRange({ max: array.length - 1 });
18
- const input = array[index];
19
- if (needPop) {
20
- array.splice(index, 1);
21
- associatedWeights === null || associatedWeights === void 0 ? void 0 : associatedWeights.splice(index, 1);
22
- }
23
- return input;
99
+ RandomizerContext.from({
100
+ array,
101
+ associatedWeights,
102
+ }).pickRandom(({ item }) => filter(item));
24
103
  }
@@ -97,7 +97,7 @@ export class BracketsParser {
97
97
  return;
98
98
  }
99
99
  const start = context.stack.pop();
100
- const end = StackElement.from(Object.assign(Object.assign({}, match), { key: variant.key, variant }));
100
+ const end = StackElement.from({ ...match, key: variant.key, variant });
101
101
  const group = this._createGroup(start, end, context);
102
102
  context.appendGroup(group);
103
103
  return end;
@@ -127,7 +127,7 @@ export class BracketsParser {
127
127
  return null;
128
128
  }
129
129
  const { match, variant } = result;
130
- const start = StackElement.from(Object.assign(Object.assign({}, match), { key: variant.key, variant }));
130
+ const start = StackElement.from({ ...match, key: variant.key, variant });
131
131
  context.stack.push(start);
132
132
  return start;
133
133
  }
@@ -227,7 +227,7 @@ var SpecialRowTypeEnum;
227
227
  class TextTableBuilder {
228
228
  constructor() {
229
229
  this.rows = [];
230
- this.options = Object.assign({}, DEFAULT_TABLE_OPTIONS);
230
+ this.options = { ...DEFAULT_TABLE_OPTIONS };
231
231
  }
232
232
  setBorderOptions(callback = () => "|", directions = [
233
233
  BorderDirectionEnum.BorderLeft,
@@ -0,0 +1 @@
1
+ export declare function binary_search(max: number, compare: (index: number) => number): number;
@@ -0,0 +1,19 @@
1
+ // Если большее, то идёт к меньшим
2
+ export function binary_search(max, compare) {
3
+ let min = 0;
4
+ while (true) {
5
+ const index = Math.floor((min + max) / 2);
6
+ const compared = compare(index);
7
+ if (compared === 0) {
8
+ return index;
9
+ }
10
+ if (min === max) {
11
+ return -1;
12
+ }
13
+ if (compared > 0) {
14
+ max = index - 1;
15
+ continue;
16
+ }
17
+ min = index + 1;
18
+ }
19
+ }
@@ -0,0 +1,4 @@
1
+ export declare function create_default_preventable(): {
2
+ default_prevented: () => boolean;
3
+ prevent_default: () => void;
4
+ };
@@ -0,0 +1,8 @@
1
+ export function create_default_preventable() {
2
+ let is_prevented = false;
3
+ const default_prevented = () => is_prevented;
4
+ const prevent_default = () => {
5
+ is_prevented = true;
6
+ };
7
+ return { default_prevented, prevent_default };
8
+ }
@@ -0,0 +1 @@
1
+ export declare function normalize_to_integer(list: number[]): number[];
@@ -0,0 +1,5 @@
1
+ export function normalize_to_integer(list) {
2
+ // (1 / 3) * 1e15 === 333 333 333 333 333.3
3
+ const MIN_OPTIMAL_VALUE = 1e16;
4
+ return list.map((x) => Math.floor(x * MIN_OPTIMAL_VALUE));
5
+ }
package/package.json CHANGED
@@ -1,11 +1,11 @@
1
1
  {
2
2
  "name": "@zoodogood/utils",
3
3
  "type": "module",
4
- "version": "2.0.2-change.1508",
4
+ "version": "3.0.0-change.2568",
5
5
  "description": "",
6
6
  "main": "lib/index.js",
7
- "types": "lib/index.d.ts",
8
7
  "homepage": "https://zoodogood.github.io/utils",
8
+ "types": "lib/index.d.ts",
9
9
  "typings": "lib/index",
10
10
  "exports": {
11
11
  ".": "./lib/index.js",
@@ -23,19 +23,19 @@
23
23
  "author": "",
24
24
  "license": "ISC",
25
25
  "devDependencies": {
26
- "@types/node": "^20.5.9",
27
- "@typescript-eslint/eslint-plugin": "^6.13.1",
28
- "@typescript-eslint/parser": "^6.13.1",
29
- "@vitest/ui": "^1.2.1",
30
- "discord-api-types": "^0.37.65",
31
- "discord.js": "^14.13.0",
32
- "eslint": "^8.54.0",
33
- "eslint-config-prettier": "^9.0.0",
34
- "eslint-plugin-prettier": "^5.0.1",
35
- "prettier": "^3.1.0",
36
- "retypeapp-linux-x64": "^3.3.0",
37
- "typescript": "^5.2.2",
38
- "vitest": "^0.34.5"
26
+ "@types/node": "^22.5.4",
27
+ "@typescript-eslint/eslint-plugin": "^6.21.0",
28
+ "@typescript-eslint/parser": "^6.21.0",
29
+ "@vitest/ui": "^2.0.5",
30
+ "discord-api-types": "^0.37.99",
31
+ "discord.js": "^14.16.1",
32
+ "eslint": "^8.57.0",
33
+ "eslint-config-prettier": "^9.1.0",
34
+ "eslint-plugin-prettier": "^5.2.1",
35
+ "prettier": "^3.3.3",
36
+ "retypeapp-linux-x64": "^3.5.0",
37
+ "typescript": "^5.5.4",
38
+ "vitest": "^2.0.5"
39
39
  },
40
40
  "peerDependencies": {
41
41
  "discord.js": ">=14.x.x"
@@ -66,7 +66,7 @@
66
66
  }
67
67
  },
68
68
  "scripts": {
69
- "test": "vitest run",
69
+ "test": "vitest --help",
70
70
  "docs-build": "cd ./docs && retype build --output ./public",
71
71
  "docs-watch": "cd ./docs && retype watch",
72
72
  "build": "tsc",