@putkoff/abstract-utilities 1.0.135 → 1.0.139

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,1706 @@
1
+ import { o as callStorage, i as isTokenExpired, d as decodeJwt, q as path$1, p as safeGlobalProp } from './mime_utils-D3LjiFgN.js';
2
+ import path from 'path';
3
+ import { readFileSync } from 'node:fs';
4
+ import { isAbsolute, resolve } from 'node:path';
5
+ import { inspect } from 'util';
6
+
7
+ function getSafeDocument() {
8
+ return typeof document !== 'undefined' ? document : undefined;
9
+ }
10
+ function getDocumentProp(...keys) {
11
+ let obj = getSafeDocument();
12
+ for (const k of keys) {
13
+ if (obj == null || typeof obj !== 'object')
14
+ return undefined;
15
+ obj = obj[k];
16
+ }
17
+ return obj;
18
+ }
19
+
20
+ /**
21
+ * Returns the global window object if it exists, otherwise undefined.
22
+ */
23
+ function getSafeWindow() {
24
+ return typeof window !== 'undefined' ? window : undefined;
25
+ }
26
+ /**
27
+ * Safely call a method on window by name.
28
+ *
29
+ * @param method The Window method to call (e.g. "alert", "open", etc.).
30
+ * @param args Arguments to pass to that method.
31
+ * @returns The method’s return value, or undefined if
32
+ * window/method isn’t available or throws.
33
+ */
34
+ function callWindowMethod(method, ...args) {
35
+ const w = getSafeWindow();
36
+ if (!w)
37
+ return undefined;
38
+ const fn = w[method];
39
+ if (typeof fn !== 'function')
40
+ return undefined;
41
+ try {
42
+ // cast to any so TS doesn’t complain about apply/invoke
43
+ return fn(...args);
44
+ }
45
+ catch {
46
+ return undefined;
47
+ }
48
+ }
49
+ /** implementation */
50
+ function getWindowProp(...keys) {
51
+ let obj = getSafeWindow();
52
+ for (const k of keys) {
53
+ if (obj == null || typeof obj !== 'object')
54
+ return undefined;
55
+ obj = obj[k];
56
+ }
57
+ return obj;
58
+ }
59
+ function getWindowHost() {
60
+ return getWindowProp('location', 'host');
61
+ }
62
+
63
+ /**
64
+ * Helpers for dealing with the JWT stored in localStorage.
65
+ */
66
+ /**
67
+ ***Changes**:
68
+ *- Updated import path for `InputProps` to `../../types/interfaces`.
69
+ *
70
+ *3. **Token Utilities** (`src/functions/auth/token_utils.ts`):
71
+ * Copy from `/var/www/abstractendeavors/my-login-app/src/functions/auth_utils/token_utils.ts`.
72
+ *
73
+ */
74
+ /** Read raw JWT from LocalStorage (or null if absent) */
75
+ function getToken() {
76
+ return callStorage('getItem', 'token');
77
+ }
78
+ function isLoggedIn() {
79
+ const tok = getToken();
80
+ return !!tok && !isTokenExpired(tok ?? "");
81
+ }
82
+ /**
83
+ * Add a Bearer Authorization header.
84
+ * A shallow copy of headers is returned so callers can keep chaining.
85
+ */
86
+ function getAuthorizationHeader(headers = {}, token = null) {
87
+ token = token ?? getToken();
88
+ headers = headers || {};
89
+ if (token)
90
+ headers["Authorization"] = `Bearer ${token}`;
91
+ return { ...headers };
92
+ }
93
+ /** Throw + redirect if there’s no valid token; otherwise return it. */
94
+ function requireToken() {
95
+ const tok = getToken();
96
+ if (!tok || isTokenExpired(tok)) {
97
+ console.warn("→ No token or expired token, redirecting to login…");
98
+ localStorage.removeItem("token");
99
+ window.location.href = '/';
100
+ throw new Error("Redirecting to login…");
101
+ }
102
+ return tok;
103
+ }
104
+ /** Convenience wrapper: return username from the JWT (or null). */
105
+ function currentUsername() {
106
+ const tok = getToken();
107
+ if (!tok)
108
+ return null;
109
+ try {
110
+ const { username } = decodeJwt(tok);
111
+ return username ?? null;
112
+ }
113
+ catch {
114
+ return null;
115
+ }
116
+ }
117
+ function currentUsernames() {
118
+ const tok = getToken();
119
+ if (!tok)
120
+ return null;
121
+ try {
122
+ const parts = tok.split(".");
123
+ if (parts.length !== 3)
124
+ return null;
125
+ let b64 = parts[1].replace(/-/g, "+").replace(/_/g, "/");
126
+ b64 = b64.padEnd(Math.ceil(b64.length / 4) * 4, "=");
127
+ const jsonText = atob(b64);
128
+ const payload = JSON.parse(jsonText);
129
+ return payload.username ?? null;
130
+ }
131
+ catch {
132
+ return null;
133
+ }
134
+ }
135
+ /** Remove the JWT from LocalStorage */
136
+ function removeToken() {
137
+ try {
138
+ callStorage('removeItem', 'token');
139
+ }
140
+ catch (err) {
141
+ console.warn("Failed to remove token:", err);
142
+ }
143
+ }
144
+
145
+ const PROTOCOL = 'https://';
146
+ const DOMAIN_NAME = 'abstractendeavors';
147
+ const BASE_URL = `${PROTOCOL}${DOMAIN_NAME}.com`;
148
+ const SUB_DIR = 'secure-files';
149
+ const PROD_PREFIX = `/${SUB_DIR}/`;
150
+ const API_PREFIX = `/${SUB_DIR}/api`;
151
+ const DEV_PREFIX = `/${SUB_DIR}-dev/`;
152
+
153
+ function get_window() {
154
+ try {
155
+ if (typeof window !== 'undefined') {
156
+ return window;
157
+ }
158
+ }
159
+ catch (err) {
160
+ alert(err);
161
+ }
162
+ return null;
163
+ }
164
+ function get_window_location() {
165
+ try {
166
+ const Window = get_window();
167
+ if (!Window) {
168
+ return BASE_URL;
169
+ }
170
+ return Window.location;
171
+ }
172
+ catch (err) {
173
+ alert(err);
174
+ }
175
+ return null;
176
+ }
177
+ function get_window_pathname() {
178
+ try {
179
+ const Window = get_window();
180
+ if (!Window) {
181
+ return DEV_PREFIX;
182
+ }
183
+ return Window.location.pathname;
184
+ }
185
+ catch (err) {
186
+ alert(err);
187
+ }
188
+ return null;
189
+ }
190
+ function get_window_parts() {
191
+ try {
192
+ return get_window_location();
193
+ }
194
+ catch (err) {
195
+ alert(err);
196
+ }
197
+ return null;
198
+ }
199
+
200
+ /**
201
+ * Unwraps nested { result } fields until you hit a non-object or no more "result" keys.
202
+ */
203
+ function getResult(obj) {
204
+ let current = obj;
205
+ while (current &&
206
+ typeof current === "object" &&
207
+ Object.prototype.hasOwnProperty.call(current, "result")) {
208
+ current = current.result;
209
+ }
210
+ return current;
211
+ }
212
+ // Determines HTTP method, defaults to GET or POST based on body
213
+ function getMethod(method = null, body = null) {
214
+ const validMethods = ['GET', 'POST', 'PUT', 'PATCH', 'PULL'];
215
+ method = (method || '').toUpperCase();
216
+ if (!validMethods.includes(method)) {
217
+ method = body ? 'POST' : 'GET';
218
+ }
219
+ return method;
220
+ }
221
+ // Gets headers, skips JSON headers when body is FormData
222
+ function getHeaders(headers = {}, method = null, body = null) {
223
+ const result = { ...headers };
224
+ // let browser set boundary
225
+ if (body instanceof FormData) {
226
+ return result;
227
+ }
228
+ const upper = method?.toUpperCase();
229
+ if (['POST', 'PUT', 'PATCH'].includes(upper ?? '') &&
230
+ !result['Content-Type']) {
231
+ result['Content-Type'] = 'application/json';
232
+ }
233
+ return result;
234
+ }
235
+ // Prepares request body, serializes to JSON for non-GET requests
236
+ function getBody(body = null, method = null) {
237
+ method = getMethod(method, body);
238
+ if (method === 'GET') {
239
+ return undefined;
240
+ }
241
+ if (body) {
242
+ try {
243
+ return JSON.stringify(body);
244
+ }
245
+ catch (err) {
246
+ return body;
247
+ }
248
+ }
249
+ return undefined;
250
+ }
251
+ // Prepares fetch variables, passes FormData intact
252
+ function getFetchVars(headers = null, method = null, body = null) {
253
+ method = getMethod(method, body);
254
+ headers = getHeaders(headers || {}, method, body);
255
+ // only JSON-stringify non-FormData bodies
256
+ if (!(body instanceof FormData)) {
257
+ body = getBody(body, method);
258
+ }
259
+ return { method, headers, body };
260
+ }
261
+ /*
262
+ * parseResult no longer needs to worry about JSON vs HTML redirect errors;
263
+ * all 401/403 have already been handled above.
264
+ */
265
+ async function parseResult(res) {
266
+ // runs checkResponse first, will throw if session is expired
267
+ res = checkResponse(res);
268
+ if (!res.ok) {
269
+ // for any other non-401 errors, you can still surface them
270
+ const errorText = await res.text();
271
+ throw new Error(errorText || res.statusText);
272
+ }
273
+ // now safely parse JSON
274
+ return res.json();
275
+ }
276
+ /**
277
+ * Intercept 401/403 and force a clean redirect to login
278
+ * without ever showing an alert.
279
+ */
280
+ function checkResponse(res) {
281
+ if (res.status === 401 || res.status === 403) {
282
+ // 1) clear out the stale token
283
+ localStorage.removeItem("token");
284
+ // 2) replace history so "back" doesn’t re-trigger the protected route
285
+ window.history.replaceState({}, "", "/secure-files");
286
+ // 3) short-circuit all further fetch logic
287
+ throw new Error("SessionExpired");
288
+ }
289
+ return res;
290
+ }
291
+
292
+ async function fetchIt(endpoint, body = null, method = null, headers = null, blob = false, configUrl = false, withCredentials = true, returnJson = true, returnReult = true) {
293
+ method = (method || "GET").toUpperCase();
294
+ // 2) choose the URL
295
+ const url = endpoint;
296
+ // 3) prepare headers & body
297
+ headers = {
298
+ ...(body instanceof FormData ? {} : { "Content-Type": "application/json" }),
299
+ ...headers,
300
+ };
301
+ const opts = {
302
+ method,
303
+ credentials: withCredentials ? "include" : "same-origin",
304
+ headers,
305
+ body: body instanceof FormData
306
+ ? body
307
+ : body != null && method !== "GET"
308
+ ? JSON.stringify(body)
309
+ : undefined,
310
+ };
311
+ console.debug("➡️ secureFetchIt →", url, opts);
312
+ const res = await fetch(url, opts);
313
+ if (!res.ok) {
314
+ const err = await res.text();
315
+ throw new Error(`HTTP ${res.status}: ${err}`);
316
+ }
317
+ if (blob)
318
+ return res.blob();
319
+ if (returnReult)
320
+ return getResult(res.json());
321
+ if (returnJson)
322
+ return res.json();
323
+ return res;
324
+ }
325
+ // Constructs HTML directory path
326
+ function getHtmlDirectory(directory, filename) {
327
+ return `${directory}/${filename}.html`;
328
+ }
329
+ // Fetches HTML content
330
+ async function fetchIndexHtml(filename, directory = 'sf_index', base = 'html') {
331
+ const url = `/${base}/${directory}/${filename}.html`;
332
+ const response = await fetch(url);
333
+ return await response.text();
334
+ }
335
+ // Fetches and injects HTML content into container
336
+ async function fetchIndexHtmlContainer(filename, doc = document, directory = 'html') {
337
+ const container = `${filename}-container`;
338
+ const html = await fetchIndexHtml(filename, directory);
339
+ const el = doc.getElementById(container);
340
+ if (el) {
341
+ el.innerHTML = html;
342
+ }
343
+ else {
344
+ console.warn(`⚠️ No container found for: #${container}`);
345
+ }
346
+ }
347
+
348
+ function urlJoin(...parts) {
349
+ const s = (parts.length === 1 && Array.isArray(parts[0]) ? parts[0] : parts);
350
+ let r = "";
351
+ for (let i = 0; i < s.length; i++) {
352
+ let d = (s[i] ?? "").toString();
353
+ if (!d)
354
+ continue;
355
+ if (i === 0)
356
+ r = d;
357
+ else {
358
+ d = d.replace(/^\/+/, "");
359
+ r = r.replace(/\/+$/, "");
360
+ r = `${r}/${d}`;
361
+ }
362
+ }
363
+ return r;
364
+ }
365
+ /**
366
+ * Returns a full URL.
367
+ * If partial_url is already absolute (starts with http), it is returned as is.
368
+ * Otherwise, it is combined with the base URL.
369
+ */
370
+ function get_full_url(partial_url, domain = null) {
371
+ if (typeof partial_url !== 'string') {
372
+ throw new Error('partial_url must be a string');
373
+ }
374
+ // If it already starts with http, assume it is absolute.
375
+ if (partial_url.startsWith('http')) {
376
+ return partial_url;
377
+ }
378
+ return urlJoin(domain, partial_url);
379
+ }
380
+ /**
381
+ * Returns a full file system path.
382
+ * If partial_path is already absolute, it is returned as is.
383
+ * Otherwise, it is joined with the base directory.
384
+ */
385
+ function get_full_path(partial_path, parent_dir = null) {
386
+ if (typeof partial_path !== 'string') {
387
+ throw new Error('partial_path must be a string');
388
+ }
389
+ if (path.isAbsolute(partial_path)) {
390
+ return partial_path;
391
+ }
392
+ return urlJoin(parent_dir, partial_path);
393
+ }
394
+ /**
395
+ * Converts a local file system path into its corresponding URL.
396
+ * It checks against the known directories in all_paths and replaces the matching base.
397
+ */
398
+ function path_to_url(filePath, all_paths) {
399
+ if (typeof filePath !== 'string') {
400
+ throw new Error('filePath must be a string');
401
+ }
402
+ for (const key in all_paths) {
403
+ const mapping = all_paths[key];
404
+ const normalizedBase = path.normalize(mapping.path);
405
+ if (filePath.startsWith(normalizedBase)) {
406
+ const relativePath = filePath.substring(normalizedBase.length);
407
+ return urlJoin(mapping.url, relativePath.replace(/\\/g, '/'));
408
+ }
409
+ }
410
+ return null;
411
+ }
412
+ /**
413
+ * Converts a URL into its corresponding local file system path.
414
+ * It checks against the known URL prefixes in all_paths and replaces the matching base.
415
+ */
416
+ function url_to_path(urlStr, all_paths) {
417
+ if (typeof urlStr !== 'string') {
418
+ throw new Error('urlStr must be a string');
419
+ }
420
+ for (const key in all_paths) {
421
+ const mapping = all_paths[key];
422
+ if (urlStr.startsWith(mapping.url)) {
423
+ const relativeUrl = urlStr.substring(mapping.url.length);
424
+ return urlJoin(mapping.path, relativeUrl);
425
+ }
426
+ }
427
+ return null;
428
+ }
429
+ function urljoin(...parts) {
430
+ return urlJoin(...parts);
431
+ }
432
+
433
+ function split_outside_brackets(s) {
434
+ let depth = 0;
435
+ let start = 0;
436
+ const out = [];
437
+ for (let i = 0; i < s.length; i++) {
438
+ const c = s[i];
439
+ if (c === "[")
440
+ depth++;
441
+ else if (c === "]")
442
+ depth--;
443
+ // split only when NOT inside brackets
444
+ if (c === "," && depth === 0) {
445
+ out.push(s.slice(start, i));
446
+ start = i + 1;
447
+ }
448
+ }
449
+ out.push(s.slice(start));
450
+ return out;
451
+ }
452
+ function parse_nested_list(s) {
453
+ // strip outer brackets
454
+ const inner = s.slice(1, -1).trim();
455
+ const parts = split_outside_brackets(inner);
456
+ const result = [];
457
+ for (let p of parts) {
458
+ p = p.trim();
459
+ if (p.startsWith("[") && p.endsWith("]")) {
460
+ // recursively parse nested list
461
+ result.push(parse_nested_list(p));
462
+ }
463
+ else {
464
+ result.push(p);
465
+ }
466
+ }
467
+ return result;
468
+ }
469
+
470
+ function ensure_list(obj) {
471
+ if (obj == null)
472
+ return [];
473
+ if (Array.isArray(obj)) {
474
+ return obj.flatMap(item => ensure_list(item));
475
+ }
476
+ const s = String(obj).trim();
477
+ if (s.startsWith("[") && s.endsWith("]")) {
478
+ return parse_nested_list(s);
479
+ }
480
+ return split_outside_brackets(s).map(x => x.trim());
481
+ }
482
+ // coerce any single value into a number (0 if it can't)
483
+ function ensure_number(x) {
484
+ const n = Number(x);
485
+ return isNaN(n) ? 0 : n;
486
+ }
487
+ function ensure_string(obj) {
488
+ return String(obj);
489
+ }
490
+ function ensurelist(obj) {
491
+ return ensure_list(obj);
492
+ }
493
+ function assureList(obj) {
494
+ return ensure_list(obj);
495
+ }
496
+ function assure_list(obj) {
497
+ return ensure_list(obj);
498
+ }
499
+ function ensureList(obj) {
500
+ return ensure_list(obj);
501
+ }
502
+ function assurelist(obj) {
503
+ return ensure_list(obj);
504
+ }
505
+ function ensurenumber(x) {
506
+ return ensure_number(x);
507
+ }
508
+ function assureNumber(x) {
509
+ return ensure_number(x);
510
+ }
511
+ function ensureNumber(x) {
512
+ return ensure_number(x);
513
+ }
514
+ function assurenumber(x) {
515
+ return ensure_number(x);
516
+ }
517
+ function assure_number(x) {
518
+ return ensure_number(x);
519
+ }
520
+ function ensurestring(obj) {
521
+ return ensure_string(obj);
522
+ }
523
+ function ensureString(obj) {
524
+ return ensure_string(obj);
525
+ }
526
+ function assureString(obj) {
527
+ return ensure_string(obj);
528
+ }
529
+ function assurestring(obj) {
530
+ return ensure_string(obj);
531
+ }
532
+ function assure_string(obj) {
533
+ return ensure_string(obj);
534
+ }
535
+ function assurearray(obj) {
536
+ return ensure_list(obj);
537
+ }
538
+ function ensurearray(obj) {
539
+ return ensure_list(obj);
540
+ }
541
+ function ensure_array(obj) {
542
+ return ensure_list(obj);
543
+ }
544
+ function ensureArray(obj) {
545
+ return ensure_list(obj);
546
+ }
547
+ function assure_array(obj) {
548
+ return ensure_list(obj);
549
+ }
550
+ function assureArray(obj) {
551
+ return ensure_list(obj);
552
+ }
553
+
554
+ function cleanText(input) {
555
+ // Replace delimiters with spaces and split
556
+ const str = ensure_string(input);
557
+ const words = str.replace(/[_.-]/g, ' '); // Replace _, -, . with space
558
+ return words;
559
+ }
560
+ function cleanArray(obj) {
561
+ obj = ensure_array(obj);
562
+ return Array.from(new Set(obj));
563
+ }
564
+ function getCleanArray(obj) {
565
+ obj = obj.split(/\s+/) // Split on any whitespace
566
+ .filter((item) => typeof item === 'string' && item !== '');
567
+ // Get basename
568
+ // Remove duplicates using Set
569
+ const uniqueWords = cleanArray(obj);
570
+ return uniqueWords;
571
+ }
572
+ // Cache a formatter instance for slightly better performance
573
+ const US_DECIMAL_FORMATTER = new Intl.NumberFormat('en-US', {
574
+ minimumFractionDigits: 2,
575
+ maximumFractionDigits: 2,
576
+ });
577
+ function formatNumber(value) {
578
+ try {
579
+ // coerce to number
580
+ const num = Number(value);
581
+ // if it's NaN or infinite, bail out
582
+ if (!isFinite(num))
583
+ return value;
584
+ return US_DECIMAL_FORMATTER.format(num);
585
+ }
586
+ catch {
587
+ // if anything goes wrong, return the original
588
+ return value;
589
+ }
590
+ }
591
+
592
+ // Constrain T so 'in obj' is allowed
593
+ function get_key_value(obj, key) {
594
+ // we cast to any for the indexing, since TS can’t infer arbitrary string keys
595
+ if (key in obj && obj[key] != null) {
596
+ return obj[key];
597
+ }
598
+ return null;
599
+ }
600
+ function get(obj, keys, defaultValue = null) {
601
+ const keyArray = ensure_array(keys);
602
+ if (!obj || keyArray.length === 0) {
603
+ return defaultValue;
604
+ }
605
+ for (const key of keyArray) {
606
+ const val = get_key_value(obj, key);
607
+ if (val != null) {
608
+ return val;
609
+ }
610
+ }
611
+ return defaultValue;
612
+ }
613
+ // Create the accountInfo table if it doesn't already exist
614
+ function findKeyValue(obj, keyToFind) {
615
+ if (keyToFind in obj)
616
+ return obj[keyToFind];
617
+ for (const key in obj) {
618
+ if (typeof obj[key] === 'object' && obj[key] !== null) {
619
+ const result = findKeyValue(obj[key], keyToFind);
620
+ if (result !== undefined)
621
+ return result;
622
+ }
623
+ }
624
+ return undefined;
625
+ }
626
+ function omitKeys(obj, ...keys) {
627
+ const newObj = { ...obj };
628
+ keys.forEach(key => {
629
+ delete newObj[key];
630
+ });
631
+ return newObj;
632
+ }
633
+ /**
634
+ * Extracts necessary properties from the insertValue to prevent circular references.
635
+ *
636
+ * @param insertValue - The original RPC result.
637
+ * @returns A new object with only the required properties.
638
+ */
639
+ function extractInsertData(insertValue) {
640
+ // Example: Suppose you only need certain fields from the transaction
641
+ // Modify this function based on your actual data structure
642
+ if (insertValue && typeof insertValue === 'object') {
643
+ const { transaction, ...rest } = insertValue; // Exclude 'transaction' property
644
+ return rest;
645
+ }
646
+ return insertValue;
647
+ }
648
+ // Recursive function to load nested JSON
649
+ function loadInnerJson(data) {
650
+ if (typeof data === 'string') {
651
+ try {
652
+ const parsed = JSON.parse(data);
653
+ return loadInnerJson(parsed);
654
+ }
655
+ catch (e) {
656
+ return data;
657
+ }
658
+ }
659
+ else if (Array.isArray(data)) {
660
+ return data.map(item => loadInnerJson(item));
661
+ }
662
+ else if (typeof data === 'object' && data !== null) {
663
+ const result = {};
664
+ for (const key in data) {
665
+ if (data.hasOwnProperty(key)) {
666
+ result[key] = loadInnerJson(data[key]);
667
+ }
668
+ }
669
+ return result;
670
+ }
671
+ return data;
672
+ }
673
+
674
+ function isType(obj, type) {
675
+ if (typeof obj === type) {
676
+ return true;
677
+ }
678
+ return false;
679
+ }
680
+ function isStrInString(obj, string) {
681
+ const obj_str = ensure_string(obj).toLowerCase;
682
+ string = ensure_string(string).toLowerCase;
683
+ if (string.includes(obj_str)) {
684
+ return true;
685
+ }
686
+ return false;
687
+ }
688
+ function getChar(i, string) {
689
+ if (string.length >= i) {
690
+ return ensure_string(string)[i];
691
+ }
692
+ }
693
+ function getAlphaNum(obj) {
694
+ const is_num = isNum(obj);
695
+ const alphas = getAlphas();
696
+ if (is_num) {
697
+ return getChar(obj, alphas);
698
+ }
699
+ if (isStrInString(obj, alphas)) {
700
+ return getChar(obj, alphas);
701
+ }
702
+ }
703
+ function getNums() {
704
+ return '0123456789';
705
+ }
706
+ function isNum(obj) {
707
+ return !Number.isNaN(Number(obj));
708
+ }
709
+ function getAlphas() {
710
+ return 'abcdefghijklmnopqrstuvwxyz';
711
+ }
712
+
713
+ // Function to handle undefined or null values
714
+ function getIfNone(obj, fallback) {
715
+ return obj !== undefined && obj !== null && obj !== '' ? obj : fallback;
716
+ }
717
+ /**
718
+ * Merges non-null values from multiple dictionaries.
719
+ */
720
+ function mergeNotNullValues(dictA, dictB, dictC, dictD, dictE) {
721
+ const result = {};
722
+ for (const key of Object.keys(dictA)) {
723
+ result[key] = dictA[key] ?? dictB?.[key] ?? dictC?.[key] ?? dictD?.[key] ?? dictE?.[key];
724
+ }
725
+ return result;
726
+ }
727
+ /**
728
+ * Converts an empty object to null.
729
+ */
730
+ function emptyObjectToNull(value) {
731
+ return value && typeof value === 'object' && !Array.isArray(value) && Object.keys(value).length === 0 ? null : value;
732
+ }
733
+
734
+ function getSubstring(obj, maxLength = null, minLength = null) {
735
+ const objLength = obj.length;
736
+ const effectiveMaxLength = maxLength ?? objLength; // Use nullish coalescing for clarity
737
+ const effectiveMinLength = minLength ?? 0;
738
+ // Ensure bounds are valid
739
+ const clampedMaxLength = Math.min(Math.max(effectiveMaxLength, 0), objLength);
740
+ const clampedMinLength = Math.min(Math.max(effectiveMinLength, 0), objLength);
741
+ // If minLength exceeds maxLength, return empty string or adjust logic as needed
742
+ if (clampedMinLength >= clampedMaxLength) {
743
+ return '';
744
+ }
745
+ return obj.substring(clampedMinLength, clampedMaxLength);
746
+ }
747
+ /**
748
+ * Sanitize a string by removing null bytes and trimming whitespace.
749
+ */
750
+ function sanitizeString(input) {
751
+ if (!input)
752
+ return input;
753
+ return input.replace(/\u0000/g, "").trim(); // Remove null bytes and whitespace
754
+ }
755
+ function truncateString(obj, maxLength = 20) {
756
+ const objLength = obj.length;
757
+ if (objLength > maxLength && maxLength) {
758
+ obj = getSubstring(obj, maxLength) + '...';
759
+ }
760
+ return obj;
761
+ }
762
+ function capitalize_str(string) {
763
+ string = assureString(string);
764
+ const string_len = string.length;
765
+ let init_char = string.toUpperCase();
766
+ if (string_len > 0) {
767
+ init_char = string[0].toUpperCase();
768
+ }
769
+ let rest_chars = '';
770
+ if (string_len > 1) {
771
+ rest_chars = string.slice(1).toLowerCase();
772
+ }
773
+ const fin_chars = `${init_char}${rest_chars}`;
774
+ return fin_chars;
775
+ }
776
+ function capitalize(string) {
777
+ let nu_string = '';
778
+ string = assureString(string);
779
+ const objs = string.replace('-', '_').split('_');
780
+ for (const obj of objs) {
781
+ const str_obj = capitalize_str(obj);
782
+ nu_string = `${nu_string} ${str_obj}`;
783
+ }
784
+ return eatAll(nu_string, [' ']);
785
+ }
786
+ // string_utils/src/string_utils.ts
787
+ function stripPrefixes(str, bases = []) {
788
+ /* NEW: coerce whatever arrives into a string */
789
+ str = String(str);
790
+ const prefixes = (Array.isArray(bases) ? bases : [bases])
791
+ .filter(Boolean)
792
+ .sort((a, b) => b.length - a.length); // longest first
793
+ let changed = true;
794
+ while (changed) {
795
+ changed = false;
796
+ for (const prefix of prefixes) {
797
+ if (str.startsWith(prefix)) {
798
+ str = str.slice(prefix.length);
799
+ changed = true;
800
+ break; // restart from longest prefix
801
+ }
802
+ }
803
+ }
804
+ return str;
805
+ }
806
+ function tryEatPrefix(str, length, ...objs) {
807
+ str = String(str);
808
+ objs = ensure_list(objs);
809
+ const prefix = str.slice(0, length);
810
+ if (length < 0) {
811
+ const start = str.length + length;
812
+ const actualPrefix = str.slice(start);
813
+ return objs.includes(actualPrefix) ? [str.slice(0, start), true] : [str, false];
814
+ }
815
+ if (objs.includes(prefix)) {
816
+ return [str.slice(length), true];
817
+ }
818
+ return [str, false];
819
+ }
820
+ /** Python-equivalent eatInner */
821
+ function eatInner(str, listObjects) {
822
+ str = String(str);
823
+ const chars = Array.isArray(listObjects) ? listObjects : [listObjects];
824
+ // Keep removing from left while leftmost char is in the set
825
+ while (str.length > 0 && chars.includes(str[0])) {
826
+ str = str.slice(1);
827
+ }
828
+ return str;
829
+ }
830
+ /** Python-equivalent eatOuter */
831
+ function eatOuter(str, listObjects) {
832
+ str = String(str);
833
+ const chars = Array.isArray(listObjects) ? listObjects : [listObjects];
834
+ if (!str || chars.length === 0)
835
+ return str;
836
+ for (let i = 0; i < str.length; i++) {
837
+ if (!str)
838
+ return str;
839
+ const last = str[str.length - 1];
840
+ if (!chars.includes(last)) {
841
+ return str;
842
+ }
843
+ str = str.slice(0, -1);
844
+ }
845
+ return str;
846
+ }
847
+ /** Python-equivalent eatAll */
848
+ function eatAll(str, listObjects) {
849
+ str = String(str);
850
+ const chars = Array.isArray(listObjects) ? listObjects : [listObjects];
851
+ str = eatInner(str, chars);
852
+ str = eatOuter(str, chars);
853
+ return str;
854
+ }
855
+ // Plug in the actual version from your project
856
+ function get_alpha_ints(opts) {
857
+ // REPLACE WITH YOUR REAL IMPLEMENTATION
858
+ return [];
859
+ }
860
+ /** Python-equivalent eatElse */
861
+ function eatElse(stringObj, chars, ints = true, alpha = true, lower = true, capitalize = true, string = true, listObj = true) {
862
+ stringObj = String(stringObj);
863
+ const alphaInts = get_alpha_ints();
864
+ const ls = ensure_list(chars || []).concat(alphaInts);
865
+ while (true) {
866
+ if (!stringObj)
867
+ return stringObj;
868
+ const startOk = !ls.includes(stringObj[0]);
869
+ const endOk = !ls.includes(stringObj[stringObj.length - 1]);
870
+ const shouldEat = startOk || endOk;
871
+ if (!shouldEat)
872
+ return stringObj;
873
+ if (stringObj && startOk) {
874
+ stringObj = stringObj.length === 1 ? "" : stringObj.slice(1);
875
+ }
876
+ if (stringObj && endOk) {
877
+ stringObj = stringObj.length === 1 ? "" : stringObj.slice(0, -1);
878
+ }
879
+ }
880
+ }
881
+ function tryParse(obj) {
882
+ try {
883
+ obj = JSON.stringify(obj);
884
+ }
885
+ catch (err) {
886
+ try {
887
+ obj = JSON.parse(obj);
888
+ }
889
+ catch (err) {
890
+ }
891
+ }
892
+ return obj;
893
+ }
894
+ function create_list_string(array_obj) {
895
+ let string = '';
896
+ for (const obj in array_obj) {
897
+ const array_value = array_obj[obj];
898
+ const parsed_value = tryParse(array_value);
899
+ string += `${obj} == ${parsed_value}\n`;
900
+ }
901
+ return string;
902
+ }
903
+ function eatall(str, listObjects) {
904
+ return eatAll(str, listObjects);
905
+ }
906
+ function eatinner(str, listObjects) {
907
+ return eatInner(str, listObjects);
908
+ }
909
+ function eatouter(str, listObjects) {
910
+ return eatOuter(str, listObjects);
911
+ }
912
+
913
+ /**
914
+ * Checks if a value is enclosed in quotes.
915
+ */
916
+ function ends_in_quotes(value) {
917
+ if (typeof value === 'string') {
918
+ if ((value.startsWith('"') && value.endsWith('"')) || (value.startsWith("'") && value.endsWith("'"))) {
919
+ return true;
920
+ }
921
+ }
922
+ return false;
923
+ }
924
+ function stripQuotes(value) {
925
+ if (ends_in_quotes(value)) {
926
+ return value.slice(1, -1); // Remove the first and last characters
927
+ }
928
+ return value; // Return the input unchanged for all other cases
929
+ }
930
+
931
+ /**
932
+ * In the browser we already have a WHATWG URL constructor on window.
933
+ * Here we re-export it as “url” so other modules can import it.
934
+ */
935
+ /**
936
+ * Minimal fileURLToPath implementation for browser-side code.
937
+ * If you only ever need to strip off “file://” in development, this is enough.
938
+ */
939
+ function fileURLToPath(fileUrl) {
940
+ // e.g. fileUrl = "file:///Users/foo/bar.txt"
941
+ try {
942
+ const u = new URL(fileUrl);
943
+ return u.pathname;
944
+ }
945
+ catch {
946
+ // fallback: just strip file://
947
+ return fileUrl.replace(/^file:\/\//, '');
948
+ }
949
+ }
950
+ function getAbsolutePath() {
951
+ return fileURLToPath(import.meta.url);
952
+ }
953
+
954
+ function get_dirname(filePath) {
955
+ if (!filePath)
956
+ return '';
957
+ return path$1.dirname(filePath);
958
+ }
959
+ function get_basename(filePath) {
960
+ if (!filePath)
961
+ return '';
962
+ return path$1.basename(filePath);
963
+ }
964
+ function get_filename(filePath) {
965
+ if (!filePath)
966
+ return '';
967
+ const ext = path$1.extname(filePath);
968
+ return path$1.basename(filePath, ext);
969
+ }
970
+ function get_extname(filePath) {
971
+ if (!filePath)
972
+ return '';
973
+ return path$1.extname(filePath);
974
+ }
975
+ function get_splitext(filePath) {
976
+ if (!filePath)
977
+ return { filename: '', extname: '' };
978
+ const ext = path$1.extname(filePath);
979
+ // Get the basename without the extension
980
+ const filename = path$1.basename(filePath, ext);
981
+ return { filename, ext };
982
+ }
983
+ /**
984
+ * Returns the path of `targetPath` relative to `basePath`.
985
+ * Normalizes separators for consistent web and server environments.
986
+ *
987
+ * @param basePath - The base directory you want to compare from.
988
+ * @param targetPath - The full path of the file/directory.
989
+ * @returns A normalized relative path (e.g., "subdir/file.txt").
990
+ */
991
+ function get_relative_path(basePath, targetPath) {
992
+ try {
993
+ // Compute the relative path using Node's native path.relative
994
+ let rel = path$1.relative(basePath, targetPath);
995
+ // Normalize to POSIX-style slashes for consistency (especially on Windows)
996
+ rel = rel.split(path$1.sep).join('/');
997
+ // Avoid empty string (happens if both paths are identical)
998
+ return rel || '.';
999
+ }
1000
+ catch (err) {
1001
+ console.error(`[get_relative_path] Error computing relative path`, err);
1002
+ return targetPath;
1003
+ }
1004
+ }
1005
+ /**
1006
+ * Join multiple path segments — clean, predictable, bulletproof.
1007
+ *
1008
+ * Accepts ANYTHING that ensure_list can handle:
1009
+ * • 'a,b,c'
1010
+ * • ['a', 'b,c']
1011
+ * • 'a/b/c'
1012
+ * • '/a/', 'b//c'
1013
+ * • mixed arrays, comma strings, whatever
1014
+ *
1015
+ * Always returns a clean POSIX path string. Never a list.
1016
+ */
1017
+ function make_path(...parts) {
1018
+ // Normalize incoming segments into a flat list
1019
+ const segments = ensure_list(parts).map(x => String(x));
1020
+ let out = "";
1021
+ for (let i = 0; i < segments.length; i++) {
1022
+ const seg = segments[i];
1023
+ // Normalize a segment:
1024
+ let cleaned = eatOuter(seg, "/"); // trim trailing slashes
1025
+ if (!cleaned)
1026
+ continue;
1027
+ if (out === "") {
1028
+ out = cleaned;
1029
+ }
1030
+ else {
1031
+ cleaned = eatInner(cleaned, "/"); // trim leading slashes
1032
+ out = `${out}/${cleaned}`;
1033
+ }
1034
+ }
1035
+ return out;
1036
+ }
1037
+ function sanitizeFilename(filename) {
1038
+ return filename
1039
+ .toLowerCase()
1040
+ .replace(/\s+|-/g, '-') // Replace spaces and hyphens with single hyphen
1041
+ .replace(/_/g, '-') // Replace underscores with hyphens
1042
+ .replace(/[^a-z0-9-.]/g, '') // Remove all non-alphanumeric chars except hyphen and dot
1043
+ .replace(/-+/g, '-') // Collapse multiple hyphens into one
1044
+ .replace(/^-|-$/, ''); // Remove leading/trailing hyphens
1045
+ }
1046
+ function make_sanitized_path(...paths) {
1047
+ let real_path = '';
1048
+ for (let i = 0; i < paths.length; i++) {
1049
+ const sanitized = sanitizeFilename(eatOuter(paths[i], '/'));
1050
+ if (i === 0) {
1051
+ real_path = sanitized;
1052
+ }
1053
+ else if (sanitized) { // Only append if there's a non-empty segment
1054
+ real_path = `${real_path}/${sanitized}`;
1055
+ }
1056
+ }
1057
+ return real_path || '';
1058
+ }
1059
+ function normalizeUrl(base, p) {
1060
+ if (!p)
1061
+ return base;
1062
+ const cleanBase = base.replace(/\/+$/, ''); // regex literal
1063
+ const cleanPath = p.replace(/^\/+/, '');
1064
+ // collapse multiple “//” into one, but keep the “://” after protocol
1065
+ return `${cleanBase}/${cleanPath}`.replace(/([^:])\/{2,}/g, '$1/');
1066
+ }
1067
+ function pathjoin(...parts) {
1068
+ return make_path(...parts);
1069
+ }
1070
+ function pathJoin(...parts) {
1071
+ return make_path(...parts);
1072
+ }
1073
+ function makepath(...parts) {
1074
+ return make_path(...parts);
1075
+ }
1076
+ function makePath(...parts) {
1077
+ return make_path(...parts);
1078
+ }
1079
+ function path_join(...parts) {
1080
+ return make_path(...parts);
1081
+ }
1082
+ function getSplitext(filePath) {
1083
+ return get_splitext(filePath);
1084
+ }
1085
+ function getsplitext(filePath) {
1086
+ return get_splitext(filePath);
1087
+ }
1088
+ function getextname(filePath) {
1089
+ return get_extname(filePath);
1090
+ }
1091
+ function getExtname(filePath) {
1092
+ return get_extname(filePath);
1093
+ }
1094
+ function getfilename(filePath) {
1095
+ return get_filename(filePath);
1096
+ }
1097
+ function getFilename(filePath) {
1098
+ return get_filename(filePath);
1099
+ }
1100
+ function getbasename(filePath) {
1101
+ return get_basename(filePath);
1102
+ }
1103
+ function getBasename(filePath) {
1104
+ return get_basename(filePath);
1105
+ }
1106
+ function getdirname(filePath) {
1107
+ return get_dirname(filePath);
1108
+ }
1109
+ function getDirname(filePath) {
1110
+ return get_dirname(filePath);
1111
+ }
1112
+
1113
+ /**
1114
+ * Returns the absolute path of the current file.
1115
+ */
1116
+ function getAbsDir() {
1117
+ return get_dirname(getAbsolutePath());
1118
+ }
1119
+ function getAbsPath(subPath) {
1120
+ return make_path(getAbsDir(), subPath);
1121
+ }
1122
+
1123
+ function getFunctionsDir() {
1124
+ return get_dirname(getAbsDir());
1125
+ }
1126
+ function geAuthsUtilsDirectory() {
1127
+ return make_path(getFunctionsDir(), 'auths');
1128
+ }
1129
+ function geBackupsUtilsDirectory() {
1130
+ return make_path(getFunctionsDir(), 'backups');
1131
+ }
1132
+ function geConstantsUtilsDirectory() {
1133
+ return make_path(getFunctionsDir(), 'constants');
1134
+ }
1135
+ function geEnvUtilsDirectory() {
1136
+ return make_path(getFunctionsDir(), 'env_utils');
1137
+ }
1138
+ function geFetchUtilsDirectory() {
1139
+ return make_path(getFunctionsDir(), 'fetch_utils');
1140
+ }
1141
+ function geFileUtilsDirectory() {
1142
+ return make_path(getFunctionsDir(), 'file_utils');
1143
+ }
1144
+ function gePathUtilsDirectory() {
1145
+ return make_path(getFunctionsDir(), 'path_utils');
1146
+ }
1147
+ function geStringUtilsDirectory() {
1148
+ return make_path(getFunctionsDir(), 'string_utils');
1149
+ }
1150
+ function geTypeUtilsDirectory() {
1151
+ return make_path(getFunctionsDir(), 'type_utils');
1152
+ }
1153
+
1154
+ function getSrcDir() {
1155
+ return get_dirname(getFunctionsDir());
1156
+ }
1157
+ function geStaticDirectory() {
1158
+ return make_path(getSrcDir(), 'static');
1159
+ }
1160
+ function getLibUtilsDirectory() {
1161
+ return make_path(getSrcDir(), 'lib');
1162
+ }
1163
+ function getHooksUtilsDirectory() {
1164
+ return make_path(getSrcDir(), 'hooks');
1165
+ }
1166
+ function getFunctionsUtilsDirectory() {
1167
+ return make_path(getSrcDir(), 'functions');
1168
+ }
1169
+ function getComponentsUtilsDirectory() {
1170
+ return make_path(getSrcDir(), 'components');
1171
+ }
1172
+
1173
+ function getBaseDir() {
1174
+ return get_dirname(getSrcDir());
1175
+ }
1176
+ function getPublicDir() {
1177
+ return make_path(getBaseDir(), 'public');
1178
+ }
1179
+ function getDistDir() {
1180
+ return make_path(getBaseDir(), 'dist');
1181
+ }
1182
+ function getEnvDir() {
1183
+ return make_path(getBaseDir(), '.env');
1184
+ }
1185
+
1186
+ function getEnvPath(string = '.env') {
1187
+ return make_path(getEnvDir(), string);
1188
+ }
1189
+ function getDbConfigsPath() {
1190
+ return make_path(getBaseDir(), 'dbConfigs');
1191
+ }
1192
+ function getSchemasPath() {
1193
+ return make_path(getDbConfigsPath(), 'schemas');
1194
+ }
1195
+ function getSchemasDirPath(subPath) {
1196
+ return make_path(getSchemasPath(), subPath);
1197
+ }
1198
+
1199
+ // src/functions/rndm_utils/utils.ts
1200
+ function alertit(obj = null) {
1201
+ let msg;
1202
+ try {
1203
+ msg = JSON.stringify(obj);
1204
+ }
1205
+ catch {
1206
+ // If JSON.stringify fails (circular refs, etc.), fall back to a simple string
1207
+ msg = String(obj);
1208
+ }
1209
+ alert(msg);
1210
+ }
1211
+
1212
+ // take N args and coerce them all to numbers
1213
+ function safeNums(...args) {
1214
+ return args.map(ensure_number);
1215
+ }
1216
+ // divide the first value by each of the following
1217
+ function safeAdd(...args) {
1218
+ const [head, ...rest] = safeNums(...args);
1219
+ // if we don’t have a head or any divisor is zero, bail
1220
+ return rest.reduce((acc, d) => acc + d, head);
1221
+ }
1222
+ // divide the first value by each of the following
1223
+ function safeSubtract(...args) {
1224
+ const [head, ...rest] = safeNums(...args);
1225
+ // if we don’t have a head or any divisor is zero, bail
1226
+ return rest.reduce((acc, d) => acc - d, head);
1227
+ }
1228
+ // divide the first value by each of the following
1229
+ function safeDivide(...args) {
1230
+ const [head, ...rest] = safeNums(...args);
1231
+ // if we don’t have a head or any divisor is zero, bail
1232
+ if (head === 0 || rest.some((d) => d === 0))
1233
+ return 0;
1234
+ return rest.reduce((acc, d) => acc / d, head);
1235
+ }
1236
+ // multiply all the values together
1237
+ function safeMultiply(...args) {
1238
+ const nums = safeNums(...args);
1239
+ // if any number is zero, result is zero
1240
+ if (nums.includes(0))
1241
+ return 0;
1242
+ return nums.reduce((acc, n) => acc * n, 1);
1243
+ }
1244
+ // round a value to two decimals by percent
1245
+ function roundPercentage(x) {
1246
+ const pct = safeMultiply(ensure_number(x), 100);
1247
+ return safeDivide(Math.round(pct), 100);
1248
+ }
1249
+ function exponential(i, k) {
1250
+ return i * (10 ** (k));
1251
+ }
1252
+ function isZero(obj) {
1253
+ if (obj == 0) {
1254
+ return true;
1255
+ }
1256
+ return false;
1257
+ }
1258
+
1259
+ const SECOND = 1;
1260
+ const ZEPTOSECOND = exponential(SECOND, -21);
1261
+ const ATTOSECOND = exponential(SECOND, -18);
1262
+ const FEMTOSECOND = exponential(SECOND, -15);
1263
+ const PICOSECOND = exponential(SECOND, -12);
1264
+ const NANOSECOND = exponential(SECOND, -9);
1265
+ const MICROSECOND = exponential(SECOND, -6);
1266
+ const MILISECOND = exponential(SECOND, -3);
1267
+ const CENTISECOND = exponential(SECOND, -2);
1268
+ const DECISECOND = exponential(SECOND, -1);
1269
+ const MINUTE = 60 * SECOND;
1270
+ const HOUR = 60 * MINUTE;
1271
+ const DAY = 24 * HOUR;
1272
+ const YEAR = 365 * DAY;
1273
+ const MONTH = YEAR / 12;
1274
+ // Derived: explicit names
1275
+ const SECONDS_PER_MINUTE = MINUTE;
1276
+ const SECONDS_PER_HOUR = HOUR;
1277
+ const SECONDS_PER_DAY = DAY;
1278
+ //math
1279
+ const PI = Math.PI;
1280
+ const PI2 = 2 * PI;
1281
+ // Distance
1282
+ const METERS_PER_KM = 1000;
1283
+ const METERS_PER_MILE = 1609.34;
1284
+ const METERS_PER_FOOT = 0.3048;
1285
+ const KMS_PER_METER = 1 / METERS_PER_KM;
1286
+ const MILES_PER_METER = 1 / METERS_PER_MILE;
1287
+ const FEET_PER_METER = 1 / METERS_PER_FOOT;
1288
+ const MIN_IN_S = 1 / MINUTE;
1289
+ const HOUR_IN_S = 1 / HOUR;
1290
+ const DAY_IN_S = 1 / DAY;
1291
+ const YEAR_IN_S = 1 / YEAR;
1292
+ const MONTH_IN_S = 1 / MONTH;
1293
+ const MiPerH_TO_MPerS = METERS_PER_MILE * HOUR_IN_S;
1294
+ const MPerS_TO_MiPerH = 1 / MiPerH_TO_MPerS;
1295
+
1296
+ // conversions.ts
1297
+ /*───────────────────────────────────────────────────────────────
1298
+ 🧭 CANONICAL MAPPINGS
1299
+ ───────────────────────────────────────────────────────────────*/
1300
+ const DIST_ALIASES = {
1301
+ m: "m", meter: "m", meters: "m",
1302
+ km: "km", kms: "km", kilometer: "km", kilometers: "km",
1303
+ mi: "mi", mile: "mi", miles: "mi",
1304
+ ft: "ft", f: "ft", foot: "ft", feet: "ft",
1305
+ };
1306
+ const TIME_ALIASES = {
1307
+ s: "s", sec: "s", second: "s", seconds: "s",
1308
+ min: "min", m: "min", minute: "min", minutes: "min",
1309
+ h: "h", hr: "h", hour: "h", hours: "h",
1310
+ day: "day", d: "day", days: "day",
1311
+ };
1312
+ const DIST_FACTORS = {
1313
+ m: 1,
1314
+ km: METERS_PER_KM,
1315
+ mi: METERS_PER_MILE,
1316
+ ft: METERS_PER_FOOT,
1317
+ };
1318
+ const TIME_FACTORS = {
1319
+ s: 1,
1320
+ min: MINUTE,
1321
+ h: HOUR,
1322
+ day: DAY,
1323
+ };
1324
+ /*───────────────────────────────────────────────────────────────
1325
+ 🔍 CANONICALIZATION HELPERS
1326
+ ───────────────────────────────────────────────────────────────*/
1327
+ function canonDist(u) {
1328
+ const key = (u ?? "m").toString().toLowerCase();
1329
+ const canon = DIST_ALIASES[key];
1330
+ if (!canon)
1331
+ throw new Error(`Unknown distance unit: ${u}`);
1332
+ return canon;
1333
+ }
1334
+ function canonTime(u) {
1335
+ const key = (u ?? "s").toString().toLowerCase();
1336
+ const canon = TIME_ALIASES[key];
1337
+ if (!canon)
1338
+ throw new Error(`Unknown time unit: ${u}`);
1339
+ return canon;
1340
+ }
1341
+ /*───────────────────────────────────────────────────────────────
1342
+ ⚖️ NORMALIZATION HELPERS
1343
+ ───────────────────────────────────────────────────────────────*/
1344
+ function distanceToMeters(d, unit) {
1345
+ const u = canonDist(unit);
1346
+ return safeMultiply(d, DIST_FACTORS[u]);
1347
+ }
1348
+ function metersToDistance(v, unit) {
1349
+ const u = canonDist(unit);
1350
+ return safeDivide(v, DIST_FACTORS[u]);
1351
+ }
1352
+ function timeToSeconds(t, unit) {
1353
+ const u = canonTime(unit);
1354
+ return safeMultiply(t, TIME_FACTORS[u]);
1355
+ }
1356
+ function secondsToTime(v, unit) {
1357
+ const u = canonTime(unit);
1358
+ return safeDivide(v, TIME_FACTORS[u]);
1359
+ }
1360
+ /*───────────────────────────────────────────────────────────────
1361
+ 🚀 SPEED CONVERSIONS (normalize / unnormalize)
1362
+ ───────────────────────────────────────────────────────────────*/
1363
+ function speedToMps(v, distUnit, timeUnit) {
1364
+ const du = canonDist(distUnit);
1365
+ const tu = canonTime(timeUnit);
1366
+ return v * (DIST_FACTORS[du] / TIME_FACTORS[tu]);
1367
+ }
1368
+ function mpsToSpeed(vMps, distUnit, timeUnit) {
1369
+ const du = canonDist(distUnit);
1370
+ const tu = canonTime(timeUnit);
1371
+ return vMps * (TIME_FACTORS[tu] / DIST_FACTORS[du]);
1372
+ }
1373
+ /*───────────────────────────────────────────────────────────────
1374
+ 🎯 UNIVERSAL CONVERTERS
1375
+ ───────────────────────────────────────────────────────────────*/
1376
+ function convertDistance({ d, fromDist, toDist, vOnly = true, }) {
1377
+ const m = distanceToMeters(d, fromDist);
1378
+ const D = canonDist(toDist ?? "m");
1379
+ const out = metersToDistance(m, D);
1380
+ return vOnly ? out : { d: out, D };
1381
+ }
1382
+ function convertTime({ t, fromTime, toTime, vOnly = true, }) {
1383
+ const sec = timeToSeconds(t, fromTime);
1384
+ const T = canonTime(toTime ?? "s");
1385
+ const out = secondsToTime(sec, T);
1386
+ return vOnly ? out : { t: out, T };
1387
+ }
1388
+ function convertSpeed({ v, fromDist, fromTime, toDist, toTime, vOnly = true, }) {
1389
+ const mps = speedToMps(v, fromDist, fromTime);
1390
+ const d = canonDist(toDist ?? "m");
1391
+ const t = canonTime(toTime ?? "s");
1392
+ const out = mpsToSpeed(mps, d, t);
1393
+ return vOnly ? out : { v: out, d, t };
1394
+ }
1395
+ const DistanceConverter = {
1396
+ normalize: distanceToMeters,
1397
+ unnormalize: metersToDistance,
1398
+ };
1399
+ const TimeConverter = {
1400
+ normalize: timeToSeconds,
1401
+ unnormalize: secondsToTime,
1402
+ };
1403
+ const SpeedConverter = {
1404
+ normalize: (v, [du, tu]) => speedToMps(v, du, tu),
1405
+ unnormalize: (v, [du, tu]) => mpsToSpeed(v, du, tu),
1406
+ };
1407
+ /*───────────────────────────────────────────────────────────────
1408
+ 🧩 COMPATIBILITY WRAPPERS (legacy aliases)
1409
+ ───────────────────────────────────────────────────────────────*/
1410
+ const toMeters = distanceToMeters;
1411
+ const fromMeters = metersToDistance;
1412
+ const toSeconds = timeToSeconds;
1413
+ const fromSeconds = secondsToTime;
1414
+ const velocityToMs = (value, unit) => speedToMps(value, unit, "s");
1415
+ const velocityFromMs = (value, unit) => mpsToSpeed(value, unit, "s");
1416
+ /** Non-canonical helper for arbitrary rate conversion, e.g. ft/day → m/s */
1417
+ const fromMps = (v, dist_unit, time_unit) => mpsToSpeed(v, dist_unit, time_unit);
1418
+ /*───────────────────────────────────────────────────────────────
1419
+ 📊 UTILITIES
1420
+ ───────────────────────────────────────────────────────────────*/
1421
+ const isFiniteNum = (x) => Number.isFinite(x);
1422
+ const fmt = (n, digits = 2) => isFiniteNum(n) ? n.toFixed(digits) : "N/A";
1423
+
1424
+ // Function to check time interval
1425
+ function isTimeInterval(timeObj, interval) {
1426
+ return (Date.now() / 1000 - timeObj) < (interval - 1);
1427
+ }
1428
+
1429
+ /**
1430
+ * Recursively traverse the object and convert BigInts to numbers or strings.
1431
+ *
1432
+ * @param {object|array} obj - The object to traverse
1433
+ * @param {boolean} convertToNumber - Whether to convert BigInt to Number (default is true)
1434
+ * @returns {object|array} - The transformed object
1435
+ */
1436
+ function convertBigInts(obj, convertToNumber = true) {
1437
+ if (obj === null || obj === undefined)
1438
+ return obj;
1439
+ try {
1440
+ if (typeof obj === 'bigint') {
1441
+ return convertToNumber ? Number(obj) : obj.toString();
1442
+ }
1443
+ if (typeof obj === 'object') {
1444
+ if (Array.isArray(obj)) {
1445
+ return obj.map((item) => convertBigInts(item, convertToNumber));
1446
+ }
1447
+ return Object.fromEntries(Object.entries(obj).map(([key, value]) => [key, convertBigInts(value, convertToNumber)]));
1448
+ }
1449
+ }
1450
+ catch (error) {
1451
+ }
1452
+ return obj;
1453
+ }
1454
+
1455
+ async function readJsonFileBrowser(url) {
1456
+ const fetchFn = safeGlobalProp("fetch");
1457
+ if (typeof fetchFn !== "function")
1458
+ return null;
1459
+ try {
1460
+ const res = await fetchFn(url);
1461
+ if (!res.ok)
1462
+ return null;
1463
+ return (await res.json());
1464
+ }
1465
+ catch {
1466
+ return null;
1467
+ }
1468
+ }
1469
+
1470
+ var readJsonFile_browser = /*#__PURE__*/Object.freeze({
1471
+ __proto__: null,
1472
+ readJsonFileBrowser: readJsonFileBrowser
1473
+ });
1474
+
1475
+ function readJsonFileNode(relativeOrAbsolutePath) {
1476
+ try {
1477
+ const filePath = isAbsolute(relativeOrAbsolutePath)
1478
+ ? relativeOrAbsolutePath
1479
+ : resolve(process.cwd(), relativeOrAbsolutePath);
1480
+ return JSON.parse(readFileSync(filePath, "utf8"));
1481
+ }
1482
+ catch {
1483
+ return null;
1484
+ }
1485
+ }
1486
+
1487
+ var readJsonFile_node = /*#__PURE__*/Object.freeze({
1488
+ __proto__: null,
1489
+ readJsonFileNode: readJsonFileNode
1490
+ });
1491
+
1492
+ async function readJsonFile(relativeOrAbsolutePath) {
1493
+ if (typeof process !== "undefined" && process.versions?.node) {
1494
+ const mod = await Promise.resolve().then(function () { return readJsonFile_node; });
1495
+ return mod.readJsonFileNode(relativeOrAbsolutePath);
1496
+ }
1497
+ else {
1498
+ const mod = await Promise.resolve().then(function () { return readJsonFile_browser; });
1499
+ return mod.readJsonFileBrowser(relativeOrAbsolutePath);
1500
+ }
1501
+ }
1502
+ async function getConfigContent() {
1503
+ try {
1504
+ // `readJsonFile` should throw if the file isn’t there or isn’t valid JSON
1505
+ const cfg = await readJsonFile('./config.json');
1506
+ return cfg;
1507
+ }
1508
+ catch {
1509
+ // swallow errors & return null so callers can detect “no config”
1510
+ return null;
1511
+ }
1512
+ }
1513
+
1514
+ // src/functions/config_utils/src/config_utils.ts
1515
+ let _cachedConfig = null;
1516
+ async function loadConfig(filePath = null) {
1517
+ if (_cachedConfig) {
1518
+ return _cachedConfig;
1519
+ }
1520
+ // 1) figure out where config.json lives
1521
+ let configUrl;
1522
+ if (filePath) {
1523
+ configUrl = filePath;
1524
+ }
1525
+ else if (typeof import.meta !== 'undefined' && typeof import.meta.url === 'string') {
1526
+ // ES module: resolve relative to this file
1527
+ try {
1528
+ const mod = await (new Function("return import('./config.json').catch(() => ({}))"))();
1529
+ _cachedConfig = mod.default ?? {};
1530
+ return _cachedConfig;
1531
+ }
1532
+ catch {
1533
+ configUrl = 'config.json';
1534
+ }
1535
+ }
1536
+ else {
1537
+ // browser fallback
1538
+ const baseURI = safeGlobalProp('document', 'baseURI');
1539
+ try {
1540
+ configUrl =
1541
+ typeof baseURI === 'string'
1542
+ ? new URL('config.json', baseURI).href
1543
+ : 'config.json';
1544
+ }
1545
+ catch {
1546
+ configUrl = 'config.json';
1547
+ }
1548
+ }
1549
+ // 2) if we have a fetch, try HTTP(S)
1550
+ const fetchFn = safeGlobalProp('fetch');
1551
+ if (typeof fetchFn === 'function') {
1552
+ try {
1553
+ const res = await fetchFn(configUrl);
1554
+ if (res.ok) {
1555
+ const json = await res.json();
1556
+ // cache & return
1557
+ _cachedConfig = json ?? {};
1558
+ return _cachedConfig;
1559
+ }
1560
+ }
1561
+ catch {
1562
+ /* swallow */
1563
+ }
1564
+ }
1565
+ // 3) Node fallback: try reading from disk (requires your readJsonFile util)
1566
+ try {
1567
+ const disk = await readJsonFile(configUrl);
1568
+ _cachedConfig = disk ?? {};
1569
+ return _cachedConfig;
1570
+ }
1571
+ catch {
1572
+ /* swallow */
1573
+ }
1574
+ // 4) if all else fails, return an empty config
1575
+ _cachedConfig = {};
1576
+ return _cachedConfig;
1577
+ }
1578
+ async function getConfig(key) {
1579
+ const cfg = await loadConfig();
1580
+ return key != null ? cfg[key] : cfg;
1581
+ }
1582
+
1583
+ /**
1584
+ * Processes keywords by checking if keywords is a string and splitting it.
1585
+ * Then cleans each keyword using `eatAll` with a set of characters to remove.
1586
+ *
1587
+ * @param keywords - The keywords as a comma-separated string or as an array.
1588
+ * @returns An array of cleaned keywords.
1589
+ */
1590
+ function processKeywords(keywords) {
1591
+ let keywordArray;
1592
+ // If keywords is a string, split it on commas
1593
+ if (typeof keywords === "string") {
1594
+ keywordArray = keywords.split(",");
1595
+ }
1596
+ else {
1597
+ keywordArray = keywords;
1598
+ }
1599
+ // Clean each keyword by removing unwanted characters
1600
+ return keywordArray.map(keyword => eatAll(keyword, [",", "\n", "\t", " ", "#"]));
1601
+ }
1602
+ /**
1603
+ * Constructs a keyword string where each keyword is prefixed with a hash (#).
1604
+ *
1605
+ * @param keywords - An array of keywords.
1606
+ * @returns A string with each keyword prefixed by '#'.
1607
+ */
1608
+ function get_keyword_string(keywords) {
1609
+ keywords = processKeywords(keywords);
1610
+ let allString = "";
1611
+ for (const keyword of keywords) {
1612
+ allString += ` #${keyword}`;
1613
+ }
1614
+ return allString;
1615
+ }
1616
+
1617
+ // Function to compare MB
1618
+ function exceedsMbLimit(limitMb, payloadMb) {
1619
+ return payloadMb > limitMb;
1620
+ }
1621
+ function safeJsonSizeInMb(value) {
1622
+ const seen = new WeakSet();
1623
+ const json = JSON.stringify(value, (_, v) => {
1624
+ if (typeof v === "bigint")
1625
+ return v.toString();
1626
+ if (typeof v === "object" && v !== null) {
1627
+ if (seen.has(v))
1628
+ return "[Circular]";
1629
+ seen.add(v);
1630
+ }
1631
+ return v;
1632
+ });
1633
+ return Buffer.byteLength(json, "utf8") / (1024 * 1024);
1634
+ }
1635
+ function dataSizeInMb(data) {
1636
+ const size = typeof data === "string"
1637
+ ? Buffer.byteLength(data, "utf8")
1638
+ : Buffer.byteLength(JSON.stringify(data), "utf8");
1639
+ return size / (1024 * 1024);
1640
+ }
1641
+ function getJsonSizeInMb(json) {
1642
+ return Buffer.byteLength(JSON.stringify(json), "utf8") / (1024 * 1024);
1643
+ }
1644
+ // Function to calculate data size in KB
1645
+ function dataSize(data) {
1646
+ let size = 0;
1647
+ if (typeof data === 'string') {
1648
+ size = Buffer.byteLength(data, 'utf8');
1649
+ }
1650
+ else if (Buffer.isBuffer(data)) {
1651
+ size = data.length;
1652
+ }
1653
+ else if (typeof data === 'object') {
1654
+ size = Buffer.byteLength(JSON.stringify(data), 'utf8');
1655
+ }
1656
+ else {
1657
+ size = Buffer.byteLength(String(data), 'utf8');
1658
+ }
1659
+ return size / 1000; // Convert to kilobytes
1660
+ }
1661
+
1662
+ function getLastCaller(skip = ["debugPrint"]) {
1663
+ const stack = new Error().stack;
1664
+ if (!stack)
1665
+ return null;
1666
+ const lines = stack
1667
+ .split("\n")
1668
+ .map(l => l.trim())
1669
+ .slice(1); // drop "Error"
1670
+ for (const line of lines) {
1671
+ // Example:
1672
+ // at processSingleAddress (/path/file.ts:142:7)
1673
+ const match = line.match(/at (.+?) \((.+?):(\d+):(\d+)\)/) ||
1674
+ line.match(/at (.+?):(\d+):(\d+)/);
1675
+ if (!match)
1676
+ continue;
1677
+ const functionName = match[1] ?? "anonymous";
1678
+ if (skip.includes(functionName))
1679
+ continue;
1680
+ return {
1681
+ functionName,
1682
+ file: match[2],
1683
+ line: Number(match[3]),
1684
+ column: Number(match[4]),
1685
+ };
1686
+ }
1687
+ return null;
1688
+ }
1689
+
1690
+ function debugPrint(value, label = null) {
1691
+ const caller = getLastCaller();
1692
+ const header = label ??
1693
+ (caller
1694
+ ? `${caller.functionName} @ ${caller.file}:${caller.line}`
1695
+ : "object");
1696
+ console.log(`\n🔍 ${header}`);
1697
+ console.log(inspect(value, {
1698
+ depth: null,
1699
+ colors: true,
1700
+ compact: false,
1701
+ maxArrayLength: null,
1702
+ }));
1703
+ }
1704
+
1705
+ export { getExtname as $, API_PREFIX as A, BASE_URL as B, get_full_path as C, DOMAIN_NAME as D, path_to_url as E, url_to_path as F, urljoin as G, get_dirname as H, get_basename as I, get_filename as J, get_extname as K, get_splitext as L, get_relative_path as M, make_path as N, sanitizeFilename as O, PROTOCOL as P, make_sanitized_path as Q, normalizeUrl as R, SUB_DIR as S, pathjoin as T, pathJoin as U, makepath as V, makePath as W, path_join as X, getSplitext as Y, getsplitext as Z, getextname as _, getAuthorizationHeader as a, canonDist as a$, getfilename as a0, getFilename as a1, getbasename as a2, getBasename as a3, getdirname as a4, getDirname as a5, getAbsDir as a6, getAbsPath as a7, getFunctionsDir as a8, geAuthsUtilsDirectory as a9, capitalize_str as aA, capitalize as aB, stripPrefixes as aC, tryEatPrefix as aD, eatInner as aE, eatOuter as aF, eatAll as aG, eatElse as aH, tryParse as aI, create_list_string as aJ, eatall as aK, eatinner as aL, eatouter as aM, ends_in_quotes as aN, stripQuotes as aO, safeNums as aP, safeAdd as aQ, safeSubtract as aR, safeDivide as aS, safeMultiply as aT, roundPercentage as aU, exponential as aV, isZero as aW, DIST_ALIASES as aX, TIME_ALIASES as aY, DIST_FACTORS as aZ, TIME_FACTORS as a_, geBackupsUtilsDirectory as aa, geConstantsUtilsDirectory as ab, geEnvUtilsDirectory as ac, geFetchUtilsDirectory as ad, geFileUtilsDirectory as ae, gePathUtilsDirectory as af, geStringUtilsDirectory as ag, geTypeUtilsDirectory as ah, getSrcDir as ai, geStaticDirectory as aj, getLibUtilsDirectory as ak, getHooksUtilsDirectory as al, getFunctionsUtilsDirectory as am, getComponentsUtilsDirectory as an, getBaseDir as ao, getPublicDir as ap, getDistDir as aq, getEnvDir as ar, getEnvPath as as, getDbConfigsPath as at, getSchemasPath as au, getSchemasDirPath as av, alertit as aw, getSubstring as ax, sanitizeString as ay, truncateString as az, currentUsernames as b, ensure_string as b$, canonTime as b0, distanceToMeters as b1, metersToDistance as b2, timeToSeconds as b3, secondsToTime as b4, speedToMps as b5, mpsToSpeed as b6, convertDistance as b7, convertTime as b8, convertSpeed as b9, MONTH as bA, SECONDS_PER_MINUTE as bB, SECONDS_PER_HOUR as bC, SECONDS_PER_DAY as bD, PI as bE, PI2 as bF, METERS_PER_KM as bG, METERS_PER_MILE as bH, METERS_PER_FOOT as bI, KMS_PER_METER as bJ, MILES_PER_METER as bK, FEET_PER_METER as bL, MIN_IN_S as bM, HOUR_IN_S as bN, DAY_IN_S as bO, YEAR_IN_S as bP, MONTH_IN_S as bQ, MiPerH_TO_MPerS as bR, MPerS_TO_MiPerH as bS, isTimeInterval as bT, convertBigInts as bU, cleanText as bV, cleanArray as bW, getCleanArray as bX, formatNumber as bY, ensure_list as bZ, ensure_number as b_, DistanceConverter as ba, TimeConverter as bb, SpeedConverter as bc, toMeters as bd, fromMeters as be, toSeconds as bf, fromSeconds as bg, velocityToMs as bh, velocityFromMs as bi, fromMps as bj, isFiniteNum as bk, fmt as bl, SECOND as bm, ZEPTOSECOND as bn, ATTOSECOND as bo, FEMTOSECOND as bp, PICOSECOND as bq, NANOSECOND as br, MICROSECOND as bs, MILISECOND as bt, CENTISECOND as bu, DECISECOND as bv, MINUTE as bw, HOUR as bx, DAY as by, YEAR as bz, currentUsername as c, ensurelist as c0, assureList as c1, assure_list as c2, ensureList as c3, assurelist as c4, ensurenumber as c5, assureNumber as c6, ensureNumber as c7, assurenumber as c8, assure_number as c9, emptyObjectToNull as cA, loadConfig as cB, getConfig as cC, readJsonFileBrowser as cD, readJsonFileNode as cE, readJsonFile as cF, getConfigContent as cG, getSafeDocument as cH, getDocumentProp as cI, getSafeWindow as cJ, callWindowMethod as cK, getWindowProp as cL, getWindowHost as cM, processKeywords as cN, get_keyword_string as cO, exceedsMbLimit as cP, safeJsonSizeInMb as cQ, dataSizeInMb as cR, getJsonSizeInMb as cS, dataSize as cT, debugPrint as cU, getLastCaller as cV, ensurestring as ca, ensureString as cb, assureString as cc, assurestring as cd, assure_string as ce, assurearray as cf, ensurearray as cg, ensure_array as ch, ensureArray as ci, assure_array as cj, assureArray as ck, get_key_value as cl, get as cm, findKeyValue as cn, omitKeys as co, extractInsertData as cp, loadInnerJson as cq, isType as cr, isStrInString as cs, getChar as ct, getAlphaNum as cu, getNums as cv, isNum as cw, getAlphas as cx, getIfNone as cy, mergeNotNullValues as cz, removeToken as d, PROD_PREFIX as e, DEV_PREFIX as f, getToken as g, get_window as h, isLoggedIn as i, get_window_location as j, get_window_pathname as k, get_window_parts as l, fetchIt as m, getHtmlDirectory as n, fetchIndexHtml as o, fetchIndexHtmlContainer as p, getResult as q, requireToken as r, getMethod as s, getHeaders as t, getBody as u, getFetchVars as v, parseResult as w, checkResponse as x, urlJoin as y, get_full_url as z };
1706
+ //# sourceMappingURL=print_utils-DlZVeNG9.js.map