qstd 0.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.
@@ -0,0 +1,75 @@
1
+ export { d as Dict, f as Flow, i as Int, l as List, m as Money, r as Random, s as Str, t as Time } from '../random-DMErOOdk.js';
2
+ import 'date-fns';
3
+
4
+ /**
5
+ * DOM manipulation utilities
6
+ */
7
+ /**
8
+ * Get element by ID
9
+ * @param id
10
+ * @returns
11
+ */
12
+ declare const getElement: (id: string) => HTMLElement | null;
13
+ /**
14
+ * Query selector
15
+ * @param selector
16
+ * @returns
17
+ */
18
+ declare const querySelector: (selector: string) => Element | null;
19
+ /**
20
+ * Query selector all
21
+ * @param selector
22
+ * @returns
23
+ */
24
+ declare const querySelectorAll: (selector: string) => NodeListOf<Element>;
25
+ /**
26
+ * Scroll to top of page
27
+ */
28
+ declare const scrollToTop: () => void;
29
+ /**
30
+ * Scroll to coordinates
31
+ * @param x
32
+ * @param y
33
+ */
34
+ declare const scrollTo: (x: number, y: number) => void;
35
+ /**
36
+ * Get current scroll position
37
+ * @returns
38
+ */
39
+ declare const getScrollPosition: () => {
40
+ x: number;
41
+ y: number;
42
+ };
43
+ /**
44
+ * Check if element is in viewport
45
+ * @param el
46
+ * @returns
47
+ */
48
+ declare const isInViewport: (el: HTMLElement) => boolean;
49
+ /**
50
+ * Scroll element into view
51
+ * @param el
52
+ * @param options
53
+ */
54
+ declare const scrollIntoView: (el: HTMLElement, options?: ScrollIntoViewOptions) => void;
55
+ /**
56
+ * Copy text to clipboard
57
+ * @param text
58
+ * @returns
59
+ */
60
+ declare const copy: (text: string) => Promise<void>;
61
+
62
+ declare const dom_copy: typeof copy;
63
+ declare const dom_getElement: typeof getElement;
64
+ declare const dom_getScrollPosition: typeof getScrollPosition;
65
+ declare const dom_isInViewport: typeof isInViewport;
66
+ declare const dom_querySelector: typeof querySelector;
67
+ declare const dom_querySelectorAll: typeof querySelectorAll;
68
+ declare const dom_scrollIntoView: typeof scrollIntoView;
69
+ declare const dom_scrollTo: typeof scrollTo;
70
+ declare const dom_scrollToTop: typeof scrollToTop;
71
+ declare namespace dom {
72
+ export { dom_copy as copy, dom_getElement as getElement, dom_getScrollPosition as getScrollPosition, dom_isInViewport as isInViewport, dom_querySelector as querySelector, dom_querySelectorAll as querySelectorAll, dom_scrollIntoView as scrollIntoView, dom_scrollTo as scrollTo, dom_scrollToTop as scrollToTop };
73
+ }
74
+
75
+ export { dom as Dom };
@@ -0,0 +1,577 @@
1
+ import { format, formatDistanceToNow, formatISO, isSameYear, isSameMonth, isSameDay, addSeconds, addMinutes, addHours, addDays, addWeeks, addBusinessDays, addMonths, addYears } from 'date-fns';
2
+
3
+ var __defProp = Object.defineProperty;
4
+ var __export = (target, all) => {
5
+ for (var name in all)
6
+ __defProp(target, name, { get: all[name], enumerable: true });
7
+ };
8
+
9
+ // src/shared/list.ts
10
+ var list_exports = {};
11
+ __export(list_exports, {
12
+ chunk: () => chunk,
13
+ create: () => create,
14
+ partition: () => partition,
15
+ zipWith: () => zipWith
16
+ });
17
+ function zipWith(fn, ...arrays) {
18
+ if (arrays.length === 0) return [];
19
+ const minLength = Math.min(...arrays.map((arr) => arr.length));
20
+ const result = [];
21
+ for (let i = 0; i < minLength; i++) {
22
+ const args = arrays.map((arr) => arr[i]);
23
+ result.push(fn(...args));
24
+ }
25
+ return result;
26
+ }
27
+ var create = (size, fn) => fn ? Array(size).fill(null).map(fn) : Array(size).fill(null);
28
+ var partition = (xs, predicate) => xs.reduce(
29
+ ([truthList, falseList], x) => {
30
+ const passes = predicate(x);
31
+ if (passes) truthList.push(x);
32
+ else falseList.push(x);
33
+ return [truthList, falseList];
34
+ },
35
+ [[], []]
36
+ );
37
+ var chunk = (list, chunkSize) => {
38
+ const totalChunks = Math.ceil(list.length / chunkSize);
39
+ return Array.from({ length: totalChunks }, (_, i) => {
40
+ const start = i * chunkSize;
41
+ const end = i * chunkSize + chunkSize;
42
+ return list.slice(start, end);
43
+ });
44
+ };
45
+
46
+ // src/shared/dict.ts
47
+ var dict_exports = {};
48
+ __export(dict_exports, {
49
+ byteSizeOfObj: () => byteSizeOfObj,
50
+ exists: () => exists,
51
+ filter: () => filter,
52
+ isEmpty: () => isEmpty,
53
+ omit: () => omit,
54
+ partition: () => partition2,
55
+ pick: () => pick,
56
+ transform: () => transform
57
+ });
58
+ function byteSizeOfObj(o) {
59
+ const objectList = [];
60
+ const stack = [o];
61
+ const bytes = [0];
62
+ while (stack.length) {
63
+ const value = stack.pop();
64
+ if (value == null) bytes[0] += 4;
65
+ else if (typeof value === "boolean") bytes[0] += 4;
66
+ else if (typeof value === "string") bytes[0] += value.length * 2;
67
+ else if (typeof value === "number") bytes[0] += 8;
68
+ else if (typeof value === "object" && objectList.indexOf(value) === -1) {
69
+ objectList.push(value);
70
+ if (typeof value.byteLength === "number") bytes[0] += value.byteLength;
71
+ else if (value[Symbol.iterator]) {
72
+ for (const v of value) stack.push(v);
73
+ } else {
74
+ Object.keys(value).forEach((k) => {
75
+ bytes[0] += k.length * 2;
76
+ stack.push(value[k]);
77
+ });
78
+ }
79
+ }
80
+ }
81
+ return bytes[0];
82
+ }
83
+ var filter = (r, predicate) => Object.entries(r).reduce(
84
+ (store, [key, value]) => predicate(value) ? { ...store, [key]: value } : store,
85
+ {}
86
+ );
87
+ var transform = (r, transformFn) => Object.entries(r).reduce(
88
+ (store, [key, value]) => ({
89
+ ...store,
90
+ ...transformFn(key, value)
91
+ }),
92
+ {}
93
+ );
94
+ var partition2 = (r, predicate) => {
95
+ const passed = {};
96
+ const failed = {};
97
+ for (const key in r) {
98
+ if (predicate(key)) passed[key] = r[key];
99
+ else failed[key] = r[key];
100
+ }
101
+ return [passed, failed];
102
+ };
103
+ var exists = (obj) => {
104
+ return obj && typeof obj === "object" && Object.keys(obj).length > 0;
105
+ };
106
+ var isEmpty = (obj) => {
107
+ return !obj || Object.keys(obj).length === 0 && obj.constructor === Object;
108
+ };
109
+ var pick = (r, paths) => Object.entries(r).reduce(
110
+ (store, [key, value]) => paths.includes(key) ? { ...store, [key]: value } : store,
111
+ {}
112
+ );
113
+ var omit = (r, paths) => {
114
+ if (!r) {
115
+ throw new Error("[omit] item was not an object");
116
+ }
117
+ return Object.entries(r).reduce((store, [key, value]) => {
118
+ if (paths.includes(key)) {
119
+ return store;
120
+ } else {
121
+ store[key] = value;
122
+ return store;
123
+ }
124
+ }, {});
125
+ };
126
+
127
+ // src/shared/str.ts
128
+ var str_exports = {};
129
+ __export(str_exports, {
130
+ concat: () => concat,
131
+ countChar: () => countChar,
132
+ countWords: () => countWords,
133
+ createSentences: () => createSentences,
134
+ toCase: () => toCase
135
+ });
136
+ var createSentences = (text) => {
137
+ if (!text) return [];
138
+ return text?.replace(/([.?!])\s*(?=[A-Z])/g, "$1|").split("|");
139
+ };
140
+ var countWords = (text) => {
141
+ text = text.trim();
142
+ if (text.length === 0) {
143
+ return 0;
144
+ }
145
+ const wordPattern = /\w+/g;
146
+ const matches = text.match(wordPattern);
147
+ return matches ? matches.length : 0;
148
+ };
149
+ var concat = (xs, delimiter) => {
150
+ return xs.filter((x) => !!x).join(delimiter);
151
+ };
152
+ var countChar = (str, ch) => {
153
+ return str.split("").reduce((x, y) => y === ch ? x + 1 : x, 0);
154
+ };
155
+ var toCase = (text, opts) => {
156
+ switch (opts.to) {
157
+ case "title":
158
+ return text.charAt(0).toUpperCase() + text.slice(1);
159
+ case "snake":
160
+ return text.replace(
161
+ /[A-Z]/g,
162
+ (l, idx) => idx === 0 ? l.toLowerCase() : "_" + l.toLowerCase()
163
+ );
164
+ case "kebab": {
165
+ const lowered = text.toLowerCase().trim();
166
+ const cleaned = opts.clean ? lowered.replaceAll(/[:,]/g, "") : lowered;
167
+ return cleaned.replaceAll(/\s+/g, "-");
168
+ }
169
+ default:
170
+ return text;
171
+ }
172
+ };
173
+
174
+ // src/shared/int.ts
175
+ var int_exports = {};
176
+ __export(int_exports, {
177
+ clamp: () => clamp,
178
+ commaSeparateThousandths: () => commaSeparateThousandths,
179
+ formatBytes: () => formatBytes
180
+ });
181
+ var clamp = (num2, range) => Math.min(Math.max(num2, range.min), range.max);
182
+ var isNumeric = (x) => {
183
+ return /^[0-9]+$/.test(x);
184
+ };
185
+ var commaSeparateThousandths = (n) => {
186
+ if (typeof n === "string" && !isNumeric(n)) {
187
+ throw new Error(`[comma separate thousandths] Value ${n} must be a number`);
188
+ }
189
+ return Number(n).toLocaleString("en-US");
190
+ };
191
+ var formatBytes = (bytes, decimals = 1, binaryUnits = false) => {
192
+ if (!bytes) return {};
193
+ if (bytes === 0) return { value: 0, unit: "Bytes" };
194
+ const unitMultiple = binaryUnits ? 1024 : 1e3;
195
+ const unitNames = unitMultiple === 1024 ? ["Bytes", "KiB", "MiB", "GiB", "TiB", "PiB", "EiB", "ZiB", "YiB"] : ["Bytes", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"];
196
+ const unitChanges = Math.floor(Math.log(bytes) / Math.log(unitMultiple));
197
+ const value = parseFloat(
198
+ (bytes / Math.pow(unitMultiple, unitChanges)).toFixed(decimals || 0)
199
+ );
200
+ const unit = unitNames[unitChanges];
201
+ return { value, unit, display: `${value}${unit}` };
202
+ };
203
+
204
+ // src/shared/money.ts
205
+ var money_exports = {};
206
+ __export(money_exports, {
207
+ convertToCents: () => convertToCents,
208
+ convertToUsd: () => convertToUsd
209
+ });
210
+ var convertToUsd = (cents, opts = {}) => {
211
+ if (!cents) return;
212
+ const dollars = (Number(cents) / 100).toLocaleString("en-US", {
213
+ style: "currency",
214
+ currency: "USD"
215
+ });
216
+ const showSymbol = opts.symbol ?? true;
217
+ return showSymbol ? dollars : dollars.slice(1);
218
+ };
219
+ var convertToCents = (dollars) => {
220
+ const str = dollars.toString().replaceAll(/[\$,]+/g, "");
221
+ return Number(str) * 100;
222
+ };
223
+
224
+ // src/shared/time.ts
225
+ var time_exports = {};
226
+ __export(time_exports, {
227
+ adjustDate: () => adjustDate,
228
+ formatDate: () => formatDate,
229
+ formatDateRange: () => formatDateRange,
230
+ formatDuration: () => formatDuration,
231
+ formatThreadDateRange: () => formatThreadDateRange,
232
+ now: () => now,
233
+ sleep: () => sleep,
234
+ toMs: () => toMs
235
+ });
236
+ var formatDuration = (ms, options = {}) => {
237
+ if (ms === null || ms === void 0) return "--:--";
238
+ const { format: fmt = "clock", showZero = false } = options;
239
+ const totalSeconds = Math.floor(Math.abs(ms) / 1e3);
240
+ const hours = Math.floor(totalSeconds / 3600);
241
+ const minutes = Math.floor(totalSeconds % 3600 / 60);
242
+ const seconds = totalSeconds % 60;
243
+ if (fmt === "clock") {
244
+ if (hours > 0) {
245
+ return `${hours}:${minutes.toString().padStart(2, "0")}:${seconds.toString().padStart(2, "0")}`;
246
+ }
247
+ return `${minutes}:${seconds.toString().padStart(2, "0")}`;
248
+ }
249
+ if (fmt === "full") {
250
+ const parts2 = [];
251
+ if (showZero) {
252
+ const hasHours = hours > 0;
253
+ const hasMinutes = minutes > 0;
254
+ const hasSeconds = seconds > 0;
255
+ if (hasHours || hasMinutes || hasSeconds) {
256
+ if (hasHours) parts2.push(`${hours} ${hours === 1 ? "hour" : "hours"}`);
257
+ if (hasHours || hasMinutes)
258
+ parts2.push(`${minutes} ${minutes === 1 ? "minute" : "minutes"}`);
259
+ parts2.push(`${seconds} ${seconds === 1 ? "second" : "seconds"}`);
260
+ } else {
261
+ parts2.push("0 seconds");
262
+ }
263
+ } else {
264
+ if (hours > 0) parts2.push(`${hours} ${hours === 1 ? "hour" : "hours"}`);
265
+ if (minutes > 0)
266
+ parts2.push(`${minutes} ${minutes === 1 ? "minute" : "minutes"}`);
267
+ if (seconds > 0)
268
+ parts2.push(`${seconds} ${seconds === 1 ? "second" : "seconds"}`);
269
+ }
270
+ return parts2.join(" ") || "0 seconds";
271
+ }
272
+ if (fmt === "fractional") {
273
+ const totalSecondsWithFraction = Math.abs(ms) / 1e3;
274
+ const totalMinutes = Math.floor(totalSecondsWithFraction / 60);
275
+ if (totalMinutes === 0) {
276
+ const fractionalSeconds = totalSecondsWithFraction.toFixed(1);
277
+ return `${fractionalSeconds}s`;
278
+ } else {
279
+ const remainingSeconds = totalSecondsWithFraction % 60;
280
+ const fractionalSeconds = remainingSeconds.toFixed(1);
281
+ return `${totalMinutes}m ${fractionalSeconds}s`;
282
+ }
283
+ }
284
+ const parts = [];
285
+ if (showZero) {
286
+ const hasHours = hours > 0;
287
+ const hasMinutes = minutes > 0;
288
+ const hasSeconds = seconds > 0;
289
+ if (hasHours || hasMinutes || hasSeconds) {
290
+ if (hasHours) parts.push(`${hours}h`);
291
+ if (hasHours || hasMinutes) parts.push(`${minutes}m`);
292
+ parts.push(`${seconds}s`);
293
+ } else {
294
+ parts.push("0s");
295
+ }
296
+ } else {
297
+ if (hours > 0) parts.push(`${hours}h`);
298
+ if (minutes > 0) parts.push(`${minutes}m`);
299
+ if (seconds > 0) parts.push(`${seconds}s`);
300
+ }
301
+ return parts.join(" ") || "0s";
302
+ };
303
+ var formatDate = (input, options = {}) => {
304
+ const { style = "medium", pattern, includeTime = false } = options;
305
+ let date2;
306
+ if (typeof input === "string") {
307
+ date2 = new Date(input);
308
+ } else if (typeof input === "number") {
309
+ date2 = new Date(input);
310
+ } else {
311
+ date2 = input;
312
+ }
313
+ if (isNaN(date2.getTime())) {
314
+ return "Invalid Date";
315
+ }
316
+ if (pattern) {
317
+ return format(date2, pattern);
318
+ }
319
+ switch (style) {
320
+ case "iso":
321
+ return formatISO(date2);
322
+ case "short":
323
+ return includeTime ? format(date2, "M/d/yy h:mm a") : format(date2, "M/d/yy");
324
+ case "medium":
325
+ return includeTime ? format(date2, "MMM d, yyyy h:mm a") : format(date2, "MMM d, yyyy");
326
+ case "long":
327
+ return includeTime ? format(date2, "MMMM d, yyyy 'at' h:mm a") : format(date2, "MMMM d, yyyy");
328
+ case "relative":
329
+ return formatDistanceToNow(date2, { addSuffix: true });
330
+ case "year":
331
+ return format(date2, "yyyy");
332
+ default:
333
+ return includeTime ? format(date2, "MMM d, yyyy h:mm a") : format(date2, "MMM d, yyyy");
334
+ }
335
+ };
336
+ var toDate = (input) => typeof input === "string" || typeof input === "number" ? new Date(input) : input;
337
+ var formatDateRange = (startInput, endInput, options = {}) => {
338
+ const now2 = options.now ?? /* @__PURE__ */ new Date();
339
+ const showTimeWhenSameDay = options.showTimeWhenSameDay ?? true;
340
+ const markToday = options.markToday ?? true;
341
+ const todayLabel = options.todayLabel ?? "today";
342
+ const separator = options.separator ?? " - ";
343
+ const monthPattern = options.monthFormat === "long" ? "MMMM" : "MMM";
344
+ const lowercaseAmPm = options.lowercaseAmPm ?? true;
345
+ const { locale } = options;
346
+ let start = toDate(startInput);
347
+ let end = toDate(endInput);
348
+ if (start.getTime() > end.getTime()) {
349
+ const tmp = start;
350
+ start = end;
351
+ end = tmp;
352
+ }
353
+ if (isNaN(start.getTime()) || isNaN(end.getTime())) return "";
354
+ const sameYear = isSameYear(start, end);
355
+ const sameMonth = sameYear && isSameMonth(start, end);
356
+ const sameDay = sameMonth && isSameDay(start, end);
357
+ const isStartToday = isSameDay(start, now2);
358
+ const isEndToday = isSameDay(end, now2);
359
+ const appendToday = (base, isTodayFlag) => markToday && isTodayFlag ? `${base} (${todayLabel})` : base;
360
+ const fmt = (d, pattern) => locale ? format(d, pattern, { locale }) : format(d, pattern);
361
+ if (sameDay) {
362
+ const dayPart = appendToday(
363
+ fmt(start, `${monthPattern} d`),
364
+ isStartToday || isEndToday
365
+ );
366
+ if (!showTimeWhenSameDay) return dayPart;
367
+ const timePattern = "h:mma";
368
+ const formatTime = (d) => lowercaseAmPm ? fmt(d, timePattern).toLowerCase() : fmt(d, timePattern);
369
+ const startTime = formatTime(start);
370
+ const endTime = formatTime(end);
371
+ return `${dayPart}, ${startTime}${separator}${endTime}`;
372
+ }
373
+ if (sameMonth) {
374
+ const monthPart = fmt(start, monthPattern);
375
+ const startDay = fmt(start, "d");
376
+ const endDay = fmt(end, "d");
377
+ const startSegment = appendToday(startDay, isStartToday);
378
+ const endSegment = appendToday(endDay, isEndToday);
379
+ const yearPart = fmt(start, "yyyy");
380
+ return `${monthPart} ${startSegment}${separator}${endSegment}, ${yearPart}`;
381
+ }
382
+ if (sameYear) {
383
+ const startPart2 = appendToday(
384
+ fmt(start, `${monthPattern} d`),
385
+ isStartToday
386
+ );
387
+ const endPart2 = appendToday(fmt(end, `${monthPattern} d`), isEndToday);
388
+ const yearPart = fmt(start, "yyyy");
389
+ return `${startPart2}${separator}${endPart2}, ${yearPart}`;
390
+ }
391
+ const startPart = appendToday(
392
+ fmt(start, `${monthPattern} d, yyyy`),
393
+ isStartToday
394
+ );
395
+ const endPart = appendToday(fmt(end, `${monthPattern} d, yyyy`), isEndToday);
396
+ return `${startPart}${separator}${endPart}`;
397
+ };
398
+ var formatThreadDateRange = (startInput, endInput, options = {}) => formatDateRange(startInput, endInput, options);
399
+ var adjustDate = (adjustment, baseDate = /* @__PURE__ */ new Date()) => {
400
+ let result = new Date(baseDate);
401
+ if (adjustment.seconds) result = addSeconds(result, adjustment.seconds);
402
+ if (adjustment.minutes) result = addMinutes(result, adjustment.minutes);
403
+ if (adjustment.hours) result = addHours(result, adjustment.hours);
404
+ if (adjustment.days) result = addDays(result, adjustment.days);
405
+ if (adjustment.weeks) result = addWeeks(result, adjustment.weeks);
406
+ if (adjustment.businessDays)
407
+ result = addBusinessDays(result, adjustment.businessDays);
408
+ if (adjustment.months) result = addMonths(result, adjustment.months);
409
+ if (adjustment.years) result = addYears(result, adjustment.years);
410
+ return result;
411
+ };
412
+ var sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
413
+ var now = () => Date.now();
414
+ var toMs = (value, unit = "seconds") => {
415
+ const multipliers = {
416
+ seconds: 1e3,
417
+ minutes: 60 * 1e3,
418
+ hours: 60 * 60 * 1e3,
419
+ days: 24 * 60 * 60 * 1e3,
420
+ weeks: 7 * 24 * 60 * 60 * 1e3,
421
+ months: 30 * 24 * 60 * 60 * 1e3,
422
+ // approximate
423
+ years: 365 * 24 * 60 * 60 * 1e3
424
+ // approximate
425
+ };
426
+ return value * multipliers[unit];
427
+ };
428
+
429
+ // src/shared/flow.ts
430
+ var flow_exports = {};
431
+ __export(flow_exports, {
432
+ asyncPool: () => asyncPool,
433
+ debounce: () => debounce,
434
+ sleep: () => sleep2,
435
+ throttle: () => throttle
436
+ });
437
+ var throttle = (fn, ms) => {
438
+ let time = Date.now();
439
+ return (...args) => {
440
+ if (time + ms - Date.now() < 0) {
441
+ fn(...args);
442
+ time = Date.now();
443
+ }
444
+ };
445
+ };
446
+ var debounce = (fn, timeout) => {
447
+ let timer;
448
+ return (...args) => {
449
+ clearTimeout(timer);
450
+ timer = setTimeout(() => {
451
+ fn(...args);
452
+ }, timeout);
453
+ };
454
+ };
455
+ var sleep2 = (ms) => new Promise((res) => setTimeout(res, ms));
456
+ async function* asyncPool(concurrency, iterable, iterator_fn) {
457
+ const executing = /* @__PURE__ */ new Set();
458
+ const consume = async () => {
459
+ const [promise, value] = await Promise.race(executing);
460
+ executing.delete(promise);
461
+ return value;
462
+ };
463
+ for (const item2 of iterable) {
464
+ const promise = (async () => await iterator_fn(item2, iterable))().then(
465
+ (value) => [promise, value]
466
+ );
467
+ executing.add(promise);
468
+ if (executing.size >= concurrency) {
469
+ yield await consume();
470
+ }
471
+ }
472
+ while (executing.size) {
473
+ yield await consume();
474
+ }
475
+ }
476
+
477
+ // src/shared/random.ts
478
+ var random_exports = {};
479
+ __export(random_exports, {
480
+ coinFlip: () => coinFlip,
481
+ date: () => date,
482
+ hexColor: () => hexColor,
483
+ item: () => item,
484
+ num: () => num,
485
+ shuffle: () => shuffle
486
+ });
487
+ var item = (xs) => {
488
+ const rand = Math.random() * xs.length;
489
+ const flooredRand = Math.floor(rand);
490
+ return xs[flooredRand];
491
+ };
492
+ var num = (props = {}) => {
493
+ const { min = 0, max = Number.MAX_SAFE_INTEGER } = props;
494
+ return Math.floor(Math.pow(10, 14) * Math.random() * Math.random()) % (max - min + 1) + min;
495
+ };
496
+ var shuffle = (xs) => {
497
+ return xs.reduceRight((r, _, __, s) => {
498
+ const randomItem = s.splice(0 | Math.random() * s.length, 1)[0];
499
+ return r.push(randomItem), r;
500
+ }, []);
501
+ };
502
+ var coinFlip = () => {
503
+ return Math.random() < 0.5;
504
+ };
505
+ var date = () => {
506
+ return new Date(+/* @__PURE__ */ new Date() - Math.floor(Math.random() * 1e13));
507
+ };
508
+ var hexColor = () => {
509
+ const hex = Math.floor(Math.random() * 16777215).toString(16);
510
+ if (hex.length !== 6) {
511
+ console.warn(`${hex} was not 6 characters. Regenerating.`);
512
+ return hexColor();
513
+ }
514
+ return hex;
515
+ };
516
+
517
+ // src/client/dom.ts
518
+ var dom_exports = {};
519
+ __export(dom_exports, {
520
+ copy: () => copy,
521
+ getElement: () => getElement,
522
+ getScrollPosition: () => getScrollPosition,
523
+ isInViewport: () => isInViewport,
524
+ querySelector: () => querySelector,
525
+ querySelectorAll: () => querySelectorAll,
526
+ scrollIntoView: () => scrollIntoView,
527
+ scrollTo: () => scrollTo,
528
+ scrollToTop: () => scrollToTop
529
+ });
530
+ var getElement = (id) => {
531
+ return document.getElementById(id);
532
+ };
533
+ var querySelector = (selector) => {
534
+ return document.querySelector(selector);
535
+ };
536
+ var querySelectorAll = (selector) => {
537
+ return document.querySelectorAll(selector);
538
+ };
539
+ var scrollToTop = () => {
540
+ window.scrollTo({ top: 0, behavior: "smooth" });
541
+ };
542
+ var scrollTo = (x, y) => {
543
+ window.scrollTo({ top: y, left: x, behavior: "smooth" });
544
+ };
545
+ var getScrollPosition = () => {
546
+ return {
547
+ x: window.scrollX || window.pageXOffset,
548
+ y: window.scrollY || window.pageYOffset
549
+ };
550
+ };
551
+ var isInViewport = (el) => {
552
+ const rect = el.getBoundingClientRect();
553
+ return rect.top >= 0 && rect.left >= 0 && rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) && rect.right <= (window.innerWidth || document.documentElement.clientWidth);
554
+ };
555
+ var scrollIntoView = (el, options) => {
556
+ el.scrollIntoView(options);
557
+ };
558
+ var copy = async (text) => {
559
+ try {
560
+ await navigator.clipboard.writeText(text);
561
+ } catch (error) {
562
+ const textArea = document.createElement("textarea");
563
+ textArea.value = text;
564
+ textArea.style.position = "fixed";
565
+ textArea.style.left = "-999999px";
566
+ document.body.appendChild(textArea);
567
+ textArea.focus();
568
+ textArea.select();
569
+ try {
570
+ document.execCommand("copy");
571
+ } finally {
572
+ document.body.removeChild(textArea);
573
+ }
574
+ }
575
+ };
576
+
577
+ export { dict_exports as Dict, dom_exports as Dom, flow_exports as Flow, int_exports as Int, list_exports as List, money_exports as Money, random_exports as Random, str_exports as Str, time_exports as Time };