@knime/utils 1.12.1 → 2.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,755 +1,957 @@
1
- import { isValid, set, getDate, getMonth, getYear, isAfter, isBefore } from 'date-fns';
2
- import prettyBytes from 'pretty-bytes';
3
- import DomPurify from 'dompurify';
4
-
5
- const capitalize = (input) => input.charAt(0).toUpperCase() + input.substring(1);
6
- const formats = {
7
- customFormat: (input, delimiter) => capitalize(input.replace(delimiter, " ").toLowerCase()),
8
- kebabFormat: (input) => formats.customFormat(input, "-"),
9
- snakeFormat: (input) => formats.customFormat(input, "_"),
10
- camelPascalCase: (input) => capitalize(
11
- (input.match(/([A-Z]?[^A-Z]*)/g) ?? []).slice(0, -1).join(" ").toLowerCase()
12
- )
13
- };
14
- const caseFormatter = ({
15
- string,
16
- delimiter,
17
- format
18
- }) => {
19
- if (delimiter) {
20
- return formats.customFormat(string, delimiter);
21
- }
22
- if (format) {
23
- return formats[format](string, delimiter ?? "");
24
- }
25
- return capitalize(string);
26
- };
27
-
28
- const updateDate = (base, date) => {
29
- if (date) {
30
- base = isValid(base) ? base : new Date(Date.UTC(0, 0));
31
- return set(base, {
32
- year: getYear(date),
33
- month: getMonth(date),
34
- date: getDate(date)
35
- });
36
- }
37
- return base;
38
- };
39
-
40
- const updateTime = (base, date) => {
41
- const d = new Date(base);
42
- if (date) {
43
- d.setHours(date.getHours());
44
- d.setMinutes(date.getMinutes());
45
- d.setSeconds(date.getSeconds());
46
- d.setMilliseconds(date.getMilliseconds());
47
- }
48
- return d;
49
- };
50
-
51
- const isBeforeMinDate = (date, min, checkDate, checkTime) => {
52
- if (min) {
53
- if (checkTime && checkDate) {
54
- return isBefore(date, min);
55
- }
56
- if (checkTime) {
57
- const base = /* @__PURE__ */ new Date(0);
58
- return isBefore(updateTime(base, date), updateTime(base, min));
59
- }
60
- if (checkDate) {
61
- const base = /* @__PURE__ */ new Date(0);
62
- return isBefore(updateDate(base, date), updateDate(base, min));
63
- }
64
- }
65
- return false;
66
- };
67
- const isAfterMaxDate = (date, max, checkDate, checkTime) => {
68
- if (max) {
69
- if (checkTime && checkDate) {
70
- return isAfter(date, max);
71
- }
72
- if (checkTime) {
73
- const base = /* @__PURE__ */ new Date(0);
74
- return isAfter(updateTime(base, date), updateTime(base, max));
75
- }
76
- if (checkDate) {
77
- const base = /* @__PURE__ */ new Date(0);
78
- return isAfter(updateDate(base, date), updateDate(base, max));
79
- }
80
- }
81
- return false;
82
- };
83
-
84
- const debounce = (callback, wait) => {
85
- let timer;
86
- let lastCall = 0;
87
- return (...args) => {
88
- const [value, index] = args;
89
- clearTimeout(timer);
90
- const now = Date.now();
91
- const timeFromLastCall = now - lastCall;
92
- if (timeFromLastCall > wait) {
93
- lastCall = now;
94
- callback(value, index);
95
- } else {
96
- timer = setTimeout(() => {
97
- lastCall = now;
98
- callback(value, index);
99
- }, wait);
100
- }
101
- };
102
- };
103
-
104
- const modeDefinitions = [
105
- {
106
- id: "search",
107
- normalize(searchTerm, caseSensitiveSearch) {
108
- return caseSensitiveSearch ? searchTerm : searchTerm.toLowerCase();
109
- },
110
- test(text, normalizedSearchTerm, caseSensitiveSearch, inverseSearch) {
111
- const testText = caseSensitiveSearch ? text : text.toLowerCase();
112
- const matches = testText.includes(normalizedSearchTerm);
113
- return inverseSearch ? !matches : matches;
114
- }
115
- },
116
- {
117
- id: "wildcard",
118
- normalize(searchTerm, caseSensitiveSearch) {
119
- if (searchTerm.length > 0) {
120
- const escapedSearchTerm = searchTerm.replace(
121
- /[-[\]{}()+.,\\^$|#\s]/g,
122
- "\\$&"
123
- );
124
- const wildcardSearchTerm = escapedSearchTerm.replace(/\*/g, ".*").replace(/\?/g, ".?");
125
- searchTerm = `^${wildcardSearchTerm}$`;
126
- } else {
127
- return { test: () => false };
128
- }
129
- try {
130
- const flags = caseSensitiveSearch ? "" : "i";
131
- return new RegExp(searchTerm, flags);
132
- } catch (_error) {
133
- return /$^/;
134
- }
135
- },
136
- test(text, normalizedSearchTerm, caseSensitiveSearch, inverseSearch) {
137
- const matches = normalizedSearchTerm.test(text);
138
- return inverseSearch ? !matches : matches;
139
- }
140
- },
141
- {
142
- id: "regex",
143
- normalize(searchTerm, caseSensitiveSearch) {
144
- try {
145
- const flags = caseSensitiveSearch ? "" : "i";
146
- return new RegExp(`^(${searchTerm})$`, flags);
147
- } catch (_error) {
148
- return /$^/;
149
- }
150
- },
151
- test(text, normalizedSearchTerm, caseSensitiveSearch, inverseSearch) {
152
- const matches = normalizedSearchTerm.test(text);
153
- return inverseSearch ? !matches : matches;
154
- }
155
- },
156
- {
157
- id: "type",
158
- normalize(selectedTypes) {
159
- return { test: (type) => selectedTypes.includes(type) };
160
- },
161
- test(type, normalizedSearchTerm) {
162
- if (typeof type === "undefined") {
163
- return false;
164
- }
165
- return normalizedSearchTerm.test(type);
166
- }
167
- }
168
- ];
169
- const filters = Object.assign({}, ...modeDefinitions.map((obj) => ({ [obj.id]: obj })));
170
-
171
- const getLocalTimeZone = () => Intl.DateTimeFormat().resolvedOptions().timeZone;
172
-
173
- const formatDateString = (dateString, useTimeZone = false) => {
174
- const date = new Date(dateString);
175
- if (isNaN(date)) {
176
- throw Error("Invalid Date format");
177
- }
178
- const baseDateOptions = {
179
- day: "numeric",
180
- month: "short",
181
- year: "numeric"
182
- };
183
- const dateOptions = useTimeZone ? { ...baseDateOptions, timeZone: getLocalTimeZone() } : baseDateOptions;
184
- return date.toLocaleDateString("en-US", dateOptions);
185
- };
186
- const formatTimeString = (timeString, useTimeZone = false) => {
187
- const time = new Date(timeString);
188
- if (isNaN(time)) {
189
- throw Error("Invalid Date format");
190
- }
191
- const baseTimeOptions = {
192
- hour: "numeric",
193
- minute: "2-digit"
194
- };
195
- const timeOptions = useTimeZone ? { ...baseTimeOptions, timeZone: getLocalTimeZone() } : baseTimeOptions;
196
- return time.toLocaleTimeString("en-US", timeOptions);
197
- };
198
- const formatDateTimeString = (dateTimeString, useTimeZone = false) => {
199
- return `${formatDateString(dateTimeString, useTimeZone)} ${formatTimeString(
200
- dateTimeString,
201
- useTimeZone
202
- )}`;
203
- };
204
- const formatLocalDateTimeString = (date, showTime) => showTime ? formatDateTimeString(date, true) : formatDateString(date, true);
205
- const formatFileSize = (bytes) => {
206
- const safeBytes = Number.isFinite(bytes) && bytes >= 0 ? bytes : 0;
207
- return prettyBytes(safeBytes);
208
- };
209
-
210
- const getDeepActiveElement = () => {
211
- let element = document?.activeElement;
212
- while (element?.shadowRoot) {
213
- element = element?.shadowRoot?.activeElement;
214
- }
215
- return element;
216
- };
217
-
218
- const getWrappedAroundIndex = (index, length) => (index % length + length) % length;
219
-
220
- const extractPeriodFromRegexMatch = (negative, match) => {
221
- return {
222
- negative,
223
- years: parseInt(match[1] ?? "0", 10),
224
- months: parseInt(match[2] ?? "0", 10),
225
- weeks: parseInt(match[3] ?? "0", 10),
226
- days: parseInt(match[4] ?? "0", 10)
227
- };
228
- };
229
- const extractDurationFromRegexMatch = (negative, match) => {
230
- const milliseconds = parseInt(match[4]?.padEnd(3, "0") ?? "0", 10);
231
- return {
232
- negative,
233
- hours: parseInt(match[1] ?? "0", 10),
234
- minutes: parseInt(match[2] ?? "0", 10),
235
- seconds: parseInt(match[3] ?? "0", 10),
236
- milliseconds
237
- };
238
- };
239
- const isZero = (interval) => {
240
- if (interval.type === "DATE") {
241
- return interval.interval.years === 0 && interval.interval.months === 0 && interval.interval.weeks === 0 && interval.interval.days === 0;
242
- } else {
243
- return interval.interval.hours === 0 && interval.interval.minutes === 0 && interval.interval.seconds === 0 && interval.interval.milliseconds === 0;
244
- }
245
- };
246
- const formatIntervalToISOIntervalString = (toFormat) => {
247
- let output = "P";
248
- if (toFormat.type === "DATE") {
249
- output += `${toFormat.interval.years}Y${toFormat.interval.months}M${toFormat.interval.weeks}W${toFormat.interval.days}D`;
250
- } else {
251
- output += `T${toFormat.interval.hours}H${toFormat.interval.minutes}M${toFormat.interval.seconds}.${toFormat.interval.milliseconds.toString().padStart(3, "0")}S`;
252
- }
253
- if (toFormat.interval.negative) {
254
- output = `-${output}`;
255
- }
256
- return output;
257
- };
258
- const formatIntervalToHumanReadableIntervalString = (toFormat) => {
259
- const formatPart = (value, unit) => {
260
- if (value === 0) {
261
- return "";
262
- } else if (value === 1) {
263
- return `${value} ${unit} `;
264
- } else {
265
- return `${value} ${unit}s `;
266
- }
267
- };
268
- let output = "";
269
- if (toFormat.type === "DATE") {
270
- if (isZero(toFormat)) {
271
- return "0 days";
272
- }
273
- output += formatPart(toFormat.interval.years, "year");
274
- output += formatPart(toFormat.interval.months, "month");
275
- output += formatPart(toFormat.interval.weeks, "week");
276
- output += formatPart(toFormat.interval.days, "day");
277
- } else {
278
- if (isZero(toFormat)) {
279
- return "0 seconds";
280
- }
281
- output += formatPart(toFormat.interval.hours, "hour");
282
- output += formatPart(toFormat.interval.minutes, "minute");
283
- const milliSecondsZero = toFormat.interval.milliseconds === 0;
284
- if (toFormat.interval.seconds !== 0 || !milliSecondsZero) {
285
- if (milliSecondsZero) {
286
- output += formatPart(toFormat.interval.seconds, "second");
287
- } else {
288
- output += `${toFormat.interval.seconds}.${toFormat.interval.milliseconds.toString().padStart(3, "0")} seconds `;
289
- }
290
- }
291
- }
292
- if (toFormat.interval.negative) {
293
- output = `-(${output.trim()})`;
294
- }
295
- return output.trim();
296
- };
297
- const yearsPart = "(\\d+)\\s*y(?:ears?)?";
298
- const monthsPart = "(\\d+)\\s*m(?:o(?:nths?)?)?";
299
- const weeksPart = "(\\d+)\\s*w(?:eeks?)?";
300
- const daysPart = "(\\d+)\\s*d(?:ays?)?";
301
- const hoursPart = "(\\d+)\\s*h(?:ours?)?";
302
- const minutesPart = "(\\d+)\\s*m(?:in(?:s|utes?)?)?";
303
- const secondsPart = "(\\d+)(?:[,.](\\d{1,3}))?\\s*s(?:ec(?:s|onds?)?)?";
304
- const humanReadablePeriodRegex = new RegExp(
305
- `^(?:${yearsPart})?\\s*(?:${monthsPart})?\\s*(?:${weeksPart})?\\s*(?:${daysPart})?\\s*$`,
306
- "i"
307
- );
308
- const humanReadableDurationRegex = new RegExp(
309
- `^(?:${hoursPart})?\\s*(?:${minutesPart})?\\s*(?:${secondsPart})?$`,
310
- "i"
311
- );
312
- const negativeHumanReadablePeriodRegex = new RegExp(
313
- `^\\s*-\\s*\\(\\s*${humanReadablePeriodRegex.source.replace(/[$^]/g, "")}\\s*\\)\\s*$`,
314
- "i"
315
- );
316
- const negativeHumanReadablePeriodRegexWithSingleField = new RegExp(
317
- `^\\s*-\\s*(?:\\s*${yearsPart}|${monthsPart}|${weeksPart}|${daysPart})\\s*$`,
318
- "i"
319
- );
320
- const negativeHumanReadableDurationRegex = new RegExp(
321
- `^\\s*-\\s*\\(\\s*${humanReadableDurationRegex.source.replace(/[$^]/g, "")}\\s*\\)\\s*$`,
322
- "i"
323
- );
324
- const negativeHumanReadableDurationRegexWithSingleField = new RegExp(
325
- `^\\s*-\\s*(?:\\s*${hoursPart}|${minutesPart}|${secondsPart})\\s*$`,
326
- "i"
327
- );
328
- const parseHumanReadableIntervalString = (intervalString) => {
329
- intervalString = intervalString?.trim();
330
- if (!intervalString) {
331
- throw new Error("Empty interval string");
332
- }
333
- const matchPositivePeriod = humanReadablePeriodRegex.exec(intervalString);
334
- const matchNegativePeriod = negativeHumanReadablePeriodRegex.exec(intervalString) ?? negativeHumanReadablePeriodRegexWithSingleField.exec(intervalString);
335
- const matchPositiveDuration = humanReadableDurationRegex.exec(intervalString);
336
- const matchNegativeDuration = negativeHumanReadableDurationRegex.exec(intervalString) ?? negativeHumanReadableDurationRegexWithSingleField.exec(intervalString);
337
- const matchPeriod = matchPositivePeriod ?? matchNegativePeriod;
338
- const matchDuration = matchPositiveDuration ?? matchNegativeDuration;
339
- const negative = (matchNegativePeriod ?? matchNegativeDuration) !== null;
340
- if (matchDuration && matchPeriod) {
341
- throw new Error("Ambiguous time format");
342
- }
343
- if (matchPeriod) {
344
- return {
345
- type: "DATE",
346
- interval: extractPeriodFromRegexMatch(negative, matchPeriod)
347
- };
348
- } else if (matchDuration) {
349
- return {
350
- type: "TIME",
351
- interval: extractDurationFromRegexMatch(negative, matchDuration)
352
- };
353
- } else {
354
- throw new Error(`Invalid human readable time: ${intervalString}`);
355
- }
356
- };
357
- const isValidHumanReadableIntervalString = (time, expectedType) => {
358
- try {
359
- const validationResult = parseHumanReadableIntervalString(time);
360
- const actualType = validationResult.type;
361
- const negative = validationResult.interval.negative;
362
- if (actualType === expectedType || expectedType === "DATE_OR_TIME") {
363
- return {
364
- valid: true,
365
- type: actualType,
366
- negative
367
- };
368
- } else {
369
- return { valid: false };
370
- }
371
- } catch (_e) {
372
- return { valid: false };
373
- }
374
- };
375
- const parseISOIntervalString = (isoString) => {
376
- isoString = isoString?.trim();
377
- if (["", "P", "PT", "-", "-P", "-PT"].includes(isoString)) {
378
- throw new Error("Empty ISO duration");
379
- }
380
- const periodRegex = /^-?P(?:(\d+)Y)?(?:(\d+)M)?(?:(\d+)W)?(?:(\d+)D)?$/;
381
- const durationRegex = /^-?PT(?:(\d+)H)?(?:(\d+)M)?(?:(\d+)(?:[,.](\d{1,3}))?S)?$/;
382
- const matchPeriod = periodRegex.exec(isoString);
383
- const matchDuration = durationRegex.exec(isoString);
384
- if (matchPeriod) {
385
- return {
386
- type: "DATE",
387
- interval: extractPeriodFromRegexMatch(
388
- isoString.startsWith("-"),
389
- matchPeriod
390
- )
391
- };
392
- } else if (matchDuration) {
393
- return {
394
- type: "TIME",
395
- interval: extractDurationFromRegexMatch(
396
- isoString.startsWith("-"),
397
- matchDuration
398
- )
399
- };
400
- } else {
401
- throw new Error(`Invalid ISO duration: ${isoString}`);
402
- }
403
- };
404
- const isValidISOIntervalString = (isoString, type) => {
405
- try {
406
- const validationResult = parseISOIntervalString(isoString);
407
- const actualType = validationResult.type;
408
- const negative = validationResult.interval.negative;
409
- if (actualType === type || type === "DATE_OR_TIME") {
410
- return {
411
- valid: true,
412
- type: actualType,
413
- negative
414
- };
415
- } else {
416
- return { valid: false };
417
- }
418
- } catch (_e) {
419
- return { valid: false };
420
- }
421
- };
422
- const parseGenericIntervalString = (time) => {
423
- const validISO = isValidISOIntervalString(time, "DATE_OR_TIME");
424
- const validHumanReadable = isValidHumanReadableIntervalString(
425
- time,
426
- "DATE_OR_TIME"
427
- );
428
- if (validISO.valid) {
429
- return parseISOIntervalString(time);
430
- } else if (validHumanReadable.valid) {
431
- return parseHumanReadableIntervalString(time);
432
- } else {
433
- throw new Error(`Invalid interval string: ${time}`);
434
- }
435
- };
436
- const isValidIntervalString = (time, type) => {
437
- const validISO = isValidISOIntervalString(time, type);
438
- const validHumanReadable = isValidHumanReadableIntervalString(time, type);
439
- if (validISO.valid) {
440
- return validISO;
441
- } else if (validHumanReadable.valid) {
442
- return validHumanReadable;
443
- } else {
444
- return { valid: false };
445
- }
446
- };
447
-
448
- const intervalUtils = /*#__PURE__*/Object.freeze(/*#__PURE__*/Object.defineProperty({
449
- __proto__: null,
450
- formatIntervalToHumanReadableIntervalString,
451
- formatIntervalToISOIntervalString,
452
- isValidHumanReadableIntervalString,
453
- isValidISOIntervalString,
454
- isValidIntervalString,
455
- isZero,
456
- parseGenericIntervalString,
457
- parseHumanReadableIntervalString,
458
- parseISOIntervalString
459
- }, Symbol.toStringTag, { value: 'Module' }));
460
-
461
- const numIntegerDigits = (input) => Math.max(Math.floor(Math.log10(Math.abs(input))), 0) + 1;
462
-
463
- class AbortError extends Error {
464
- }
465
- const createAbortablePromise = () => {
466
- const abortController = new AbortController();
467
- const runAbortablePromise = (request) => {
468
- return new Promise((resolve, reject) => {
469
- const abortListener = ({ target }) => {
470
- abortController.signal.removeEventListener("abort", abortListener);
471
- const reason = target.reason;
472
- reject(reason instanceof AbortError ? reason : new AbortError(reason));
473
- };
474
- request().then(resolve).catch((error) => {
475
- if (error instanceof AbortError) {
476
- return;
477
- }
478
- reject(error);
479
- });
480
- abortController.signal.addEventListener("abort", abortListener);
481
- });
482
- };
483
- return { abortController, runAbortablePromise };
484
- };
485
-
486
- const createUnwrappedPromise = () => {
487
- let resolve = () => {
488
- };
489
- let reject = () => {
490
- };
491
- const promise = new Promise((res, rej) => {
492
- resolve = res;
493
- reject = rej;
494
- });
495
- return { resolve, reject, promise };
496
- };
497
-
1
+ import { getDate, getMonth, getYear, isAfter, isBefore, isValid, set } from "date-fns";
2
+ import prettyBytes from "pretty-bytes";
3
+ import DomPurify from "dompurify";
4
+ //#region \0rolldown/runtime.js
5
+ var __defProp = Object.defineProperty;
6
+ var __exportAll = (all, no_symbols) => {
7
+ let target = {};
8
+ for (var name in all) __defProp(target, name, {
9
+ get: all[name],
10
+ enumerable: true
11
+ });
12
+ if (!no_symbols) __defProp(target, Symbol.toStringTag, { value: "Module" });
13
+ return target;
14
+ };
15
+ //#endregion
16
+ //#region src/capitalize.ts
17
+ /**
18
+ * Uppercases first letter of string
19
+ * @param string to be capitalized first string, e.g. "workflow"
20
+ * @return Capitalized String, e.g. "Workflow"
21
+ */
22
+ var capitalize = (input) => input.charAt(0).toUpperCase() + input.substring(1);
23
+ var formats = {
24
+ customFormat: (input, delimiter) => capitalize(input.replace(delimiter, " ").toLowerCase()),
25
+ kebabFormat: (input) => formats.customFormat(input, "-"),
26
+ snakeFormat: (input) => formats.customFormat(input, "_"),
27
+ camelPascalCase: (input) => capitalize((input.match(/([A-Z]?[^A-Z]*)/g) ?? []).slice(0, -1).join(" ").toLowerCase())
28
+ };
29
+ var caseFormatter = ({ string, delimiter, format }) => {
30
+ if (delimiter) return formats.customFormat(string, delimiter);
31
+ if (format) return formats[format](string, delimiter ?? "");
32
+ return capitalize(string);
33
+ };
34
+ //#endregion
35
+ //#region src/updateDate.ts
36
+ /**
37
+ * Updates the date part (year, day and month) of a date object (base)
38
+ * time, offset (timezone) and so on will be left untouched.
39
+ *
40
+ * @param base - Date which will be used (copied) to set day, month and year.
41
+ * @param date - Extract day, month and year from this date object.
42
+ * @returns Copy of base with day, month and year of date.
43
+ */
44
+ var updateDate_default = (base, date) => {
45
+ if (date) {
46
+ base = isValid(base) ? base : new Date(Date.UTC(0, 0));
47
+ return set(base, {
48
+ year: getYear(date),
49
+ month: getMonth(date),
50
+ date: getDate(date)
51
+ });
52
+ }
53
+ return base;
54
+ };
55
+ //#endregion
56
+ //#region src/updateTime.ts
57
+ /**
58
+ * Updates the time part (hour, minute, second and millisecond) of a date object (base)
59
+ * date, offset (timezone) and so on will be left untouched.
60
+ *
61
+ * @param base - Date which will be used (copied) to set day, month and year.
62
+ * @param date - Extract hour, minute, second and millisecond from this date object.
63
+ * @returns Copy of base with hour, minute, second and millisecond changed.
64
+ */
65
+ var updateTime_default = (base, date) => {
66
+ const d = new Date(base);
67
+ if (date) {
68
+ d.setHours(date.getHours());
69
+ d.setMinutes(date.getMinutes());
70
+ d.setSeconds(date.getSeconds());
71
+ d.setMilliseconds(date.getMilliseconds());
72
+ }
73
+ return d;
74
+ };
75
+ //#endregion
76
+ //#region src/dateMinMaxCheck.ts
77
+ /**
78
+ * Check if date is before min.
79
+ * @param date
80
+ * @param min
81
+ * @param checkDate - check date part (year, day, month).
82
+ * @param checkTime - check time part (hour, minutes etc.).
83
+ * @returns whether limit is kept or not.
84
+ */
85
+ var isBeforeMinDate = (date, min, checkDate, checkTime) => {
86
+ if (min) {
87
+ if (checkTime && checkDate) return isBefore(date, min);
88
+ if (checkTime) {
89
+ const base = /* @__PURE__ */ new Date(0);
90
+ return isBefore(updateTime_default(base, date), updateTime_default(base, min));
91
+ }
92
+ if (checkDate) {
93
+ const base = /* @__PURE__ */ new Date(0);
94
+ return isBefore(updateDate_default(base, date), updateDate_default(base, min));
95
+ }
96
+ }
97
+ return false;
98
+ };
99
+ /**
100
+ * Check
101
+ * @param date - date to check.
102
+ * @param max - maximum date.
103
+ * @param checkDate - check date part (year, day, month).
104
+ * @param checkTime - check time part (hour, minutes etc.).
105
+ * @returns whether limit is kept or not.
106
+ */
107
+ var isAfterMaxDate = (date, max, checkDate, checkTime) => {
108
+ if (max) {
109
+ if (checkTime && checkDate) return isAfter(date, max);
110
+ if (checkTime) {
111
+ const base = /* @__PURE__ */ new Date(0);
112
+ return isAfter(updateTime_default(base, date), updateTime_default(base, max));
113
+ }
114
+ if (checkDate) {
115
+ const base = /* @__PURE__ */ new Date(0);
116
+ return isAfter(updateDate_default(base, date), updateDate_default(base, max));
117
+ }
118
+ }
119
+ return false;
120
+ };
121
+ //#endregion
122
+ //#region src/debounce.ts
123
+ var debounce = (callback, wait) => {
124
+ let timer;
125
+ let lastCall = 0;
126
+ return (...args) => {
127
+ const [value, index] = args;
128
+ clearTimeout(timer);
129
+ const now = Date.now();
130
+ if (now - lastCall > wait) {
131
+ lastCall = now;
132
+ callback(value, index);
133
+ } else timer = setTimeout(() => {
134
+ lastCall = now;
135
+ callback(value, index);
136
+ }, wait);
137
+ };
138
+ };
139
+ var filters = Object.assign({}, ...[
140
+ {
141
+ id: "search",
142
+ normalize(searchTerm, caseSensitiveSearch) {
143
+ return caseSensitiveSearch ? searchTerm : searchTerm.toLowerCase();
144
+ },
145
+ test(text, normalizedSearchTerm, caseSensitiveSearch, inverseSearch) {
146
+ const matches = (caseSensitiveSearch ? text : text.toLowerCase()).includes(normalizedSearchTerm);
147
+ return inverseSearch ? !matches : matches;
148
+ }
149
+ },
150
+ {
151
+ id: "wildcard",
152
+ normalize(searchTerm, caseSensitiveSearch) {
153
+ if (searchTerm.length > 0) searchTerm = `^${searchTerm.replace(/[-[\]{}()+.,\\^$|#\s]/g, "\\$&").replace(/\*/g, ".*").replace(/\?/g, ".?")}$`;
154
+ else return { test: () => false };
155
+ try {
156
+ return new RegExp(searchTerm, caseSensitiveSearch ? "" : "i");
157
+ } catch (_error) {
158
+ return /$^/;
159
+ }
160
+ },
161
+ test(text, normalizedSearchTerm, caseSensitiveSearch, inverseSearch) {
162
+ const matches = normalizedSearchTerm.test(text);
163
+ return inverseSearch ? !matches : matches;
164
+ }
165
+ },
166
+ {
167
+ id: "regex",
168
+ normalize(searchTerm, caseSensitiveSearch) {
169
+ try {
170
+ const flags = caseSensitiveSearch ? "" : "i";
171
+ return new RegExp(`^(${searchTerm})$`, flags);
172
+ } catch (_error) {
173
+ return /$^/;
174
+ }
175
+ },
176
+ test(text, normalizedSearchTerm, caseSensitiveSearch, inverseSearch) {
177
+ const matches = normalizedSearchTerm.test(text);
178
+ return inverseSearch ? !matches : matches;
179
+ }
180
+ },
181
+ {
182
+ id: "type",
183
+ normalize(selectedTypes) {
184
+ return { test: (type) => selectedTypes.includes(type) };
185
+ },
186
+ test(type, normalizedSearchTerm) {
187
+ if (typeof type === "undefined") return false;
188
+ return normalizedSearchTerm.test(type);
189
+ }
190
+ }
191
+ ].map((obj) => ({ [obj.id]: obj })));
192
+ //#endregion
193
+ //#region src/localTimezone.ts
194
+ /**
195
+ * Get the users local timezone.
196
+ *
197
+ * @returns current users timezone (browser based) tz db string (e. g. Europe/Berlin).
198
+ */
199
+ var localTimezone_default = () => Intl.DateTimeFormat().resolvedOptions().timeZone;
200
+ //#endregion
201
+ //#region src/format.ts
202
+ /**
203
+ * Converts the specified date String to human readable text containing the day, month, and year.
204
+ * Example: '2018-07-31T09:44:31+00:00' => 'Jul 31, 2018'
205
+ *
206
+ * @param dateString String representation of the Date to format
207
+ * @param useTimeZone to set the timeZone where the user is located, and display local date and time
208
+ * @returns human readable date String
209
+ */
210
+ var formatDateString = (dateString, useTimeZone = false) => {
211
+ const date = new Date(dateString);
212
+ if (isNaN(date)) throw Error("Invalid Date format");
213
+ const baseDateOptions = {
214
+ day: "numeric",
215
+ month: "short",
216
+ year: "numeric"
217
+ };
218
+ const dateOptions = useTimeZone ? {
219
+ ...baseDateOptions,
220
+ timeZone: localTimezone_default()
221
+ } : baseDateOptions;
222
+ return date.toLocaleDateString("en-US", dateOptions);
223
+ };
224
+ /**
225
+ * Converts the specified time String to human readable text containing the hour (12-hour) and minute.
226
+ * Example: '2018-07-31T09:44:31+00:00' => '9:44 AM'
227
+ *
228
+ * @param timeString String representation of the Date (including time) to format
229
+ * @param useTimeZone to set the timeZone where the user is located, and display local date and time
230
+ * @returns human readable time String
231
+ */
232
+ var formatTimeString = (timeString, useTimeZone = false) => {
233
+ const time = new Date(timeString);
234
+ if (isNaN(time)) throw Error("Invalid Date format");
235
+ const baseTimeOptions = {
236
+ hour: "numeric",
237
+ minute: "2-digit"
238
+ };
239
+ const timeOptions = useTimeZone ? {
240
+ ...baseTimeOptions,
241
+ timeZone: localTimezone_default()
242
+ } : baseTimeOptions;
243
+ return time.toLocaleTimeString("en-US", timeOptions);
244
+ };
245
+ /**
246
+ * Converts the specified time String to human readable text containing the date (day, month, year) and time (hour,
247
+ * minute; 12-hour).
248
+ * Example: '2018-07-31T09:44:31+00:00' => 'Jul 31, 2018 9:44 AM'
249
+ *
250
+ * @param dateTimeString String representation of the Date (including time and date) to format
251
+ * @param useTimeZone to set the timeZone where the user is located, and display local date and time
252
+ * @returns human readable date/time String
253
+ */
254
+ var formatDateTimeString = (dateTimeString, useTimeZone = false) => {
255
+ return `${formatDateString(dateTimeString, useTimeZone)} ${formatTimeString(dateTimeString, useTimeZone)}`;
256
+ };
257
+ /**
258
+ * Converts the specified date and time to the user time zone with option to display (day, month, year) only or with time (hour,
259
+ * minute; 12-hour).
260
+ *
261
+ * @param showTime String representation of the Date to convert and format
262
+ * @param String | number} date String representation of the Date to convert and format
263
+ * @returns human readable date/time String converted to user time zone
264
+ */
265
+ var formatLocalDateTimeString = (date, showTime) => showTime ? formatDateTimeString(date, true) : formatDateString(date, true);
266
+ var formatFileSize = (bytes) => {
267
+ return prettyBytes(Number.isFinite(bytes) && bytes >= 0 ? bytes : 0);
268
+ };
269
+ //#endregion
270
+ //#region src/getDeepActiveElement.ts
271
+ var getDeepActiveElement = () => {
272
+ let element = document?.activeElement;
273
+ while (element?.shadowRoot) element = element?.shadowRoot?.activeElement;
274
+ return element;
275
+ };
276
+ //#endregion
277
+ //#region src/getWrappedAroundIndex.ts
278
+ /**
279
+ * Since (a % b) yields a negative outcome for negative a, we need this method in order
280
+ * to correctly compute wrapped around indices in lists
281
+ * @param {number} index an arbitrary integer
282
+ * @param {number} length a positive integer
283
+ * @returns {number} the non-negative modulo outcome
284
+ */
285
+ var getWrappedAroundIndex_default = (index, length) => (index % length + length) % length;
286
+ //#endregion
287
+ //#region src/intervalUtils.ts
288
+ var intervalUtils_exports = /* @__PURE__ */ __exportAll({
289
+ formatIntervalToHumanReadableIntervalString: () => formatIntervalToHumanReadableIntervalString,
290
+ formatIntervalToISOIntervalString: () => formatIntervalToISOIntervalString,
291
+ isValidHumanReadableIntervalString: () => isValidHumanReadableIntervalString,
292
+ isValidISOIntervalString: () => isValidISOIntervalString,
293
+ isValidIntervalString: () => isValidIntervalString,
294
+ isZero: () => isZero,
295
+ parseGenericIntervalString: () => parseGenericIntervalString,
296
+ parseHumanReadableIntervalString: () => parseHumanReadableIntervalString,
297
+ parseISOIntervalString: () => parseISOIntervalString
298
+ });
299
+ var extractPeriodFromRegexMatch = (negative, match) => {
300
+ return {
301
+ negative,
302
+ years: parseInt(match[1] ?? "0", 10),
303
+ months: parseInt(match[2] ?? "0", 10),
304
+ weeks: parseInt(match[3] ?? "0", 10),
305
+ days: parseInt(match[4] ?? "0", 10)
306
+ };
307
+ };
308
+ var extractDurationFromRegexMatch = (negative, match) => {
309
+ const milliseconds = parseInt(match[4]?.padEnd(3, "0") ?? "0", 10);
310
+ return {
311
+ negative,
312
+ hours: parseInt(match[1] ?? "0", 10),
313
+ minutes: parseInt(match[2] ?? "0", 10),
314
+ seconds: parseInt(match[3] ?? "0", 10),
315
+ milliseconds
316
+ };
317
+ };
318
+ var isZero = (interval) => {
319
+ if (interval.type === "DATE") return interval.interval.years === 0 && interval.interval.months === 0 && interval.interval.weeks === 0 && interval.interval.days === 0;
320
+ else return interval.interval.hours === 0 && interval.interval.minutes === 0 && interval.interval.seconds === 0 && interval.interval.milliseconds === 0;
321
+ };
322
+ /**
323
+ * Take an interval object and convert it to an ISO duration or period string. All parts of the
324
+ * relevant part of the Interval object are included in the output, even if they are zero.
325
+ *
326
+ * Technically the ISO standard allows to mix period and duration parts, but we don't support that
327
+ * here because it's incredibly hard to deal with all the edge cases. Maybe in a future ticket.
328
+ *
329
+ * The output here is allowed to be negative, in which case the minus sign is prepended to the
330
+ * output.
331
+ *
332
+ * @param toFormat The PeriodOrDuration object to format
333
+ */
334
+ var formatIntervalToISOIntervalString = (toFormat) => {
335
+ let output = "P";
336
+ if (toFormat.type === "DATE") output += `${toFormat.interval.years}Y${toFormat.interval.months}M${toFormat.interval.weeks}W${toFormat.interval.days}D`;
337
+ else output += `T${toFormat.interval.hours}H${toFormat.interval.minutes}M${toFormat.interval.seconds}.${toFormat.interval.milliseconds.toString().padStart(3, "0")}S`;
338
+ if (toFormat.interval.negative) output = `-${output}`;
339
+ return output;
340
+ };
341
+ /**
342
+ * Take an interval object and convert it to a human readable string. Only non-zero parts are
343
+ * included in the output (unless all parts are 0).
344
+ *
345
+ * The output here is allowed to be negative, in which case the minus sign is prepended to the
346
+ * output and we wrap the whole thing in brackets e.g. -(1 year 2 days).
347
+ *
348
+ * @param toFormat The PeriodOrDuration object to format
349
+ */
350
+ var formatIntervalToHumanReadableIntervalString = (toFormat) => {
351
+ const formatPart = (value, unit) => {
352
+ if (value === 0) return "";
353
+ else if (value === 1) return `${value} ${unit} `;
354
+ else return `${value} ${unit}s `;
355
+ };
356
+ let output = "";
357
+ if (toFormat.type === "DATE") {
358
+ if (isZero(toFormat)) return "0 days";
359
+ output += formatPart(toFormat.interval.years, "year");
360
+ output += formatPart(toFormat.interval.months, "month");
361
+ output += formatPart(toFormat.interval.weeks, "week");
362
+ output += formatPart(toFormat.interval.days, "day");
363
+ } else {
364
+ if (isZero(toFormat)) return "0 seconds";
365
+ output += formatPart(toFormat.interval.hours, "hour");
366
+ output += formatPart(toFormat.interval.minutes, "minute");
367
+ const milliSecondsZero = toFormat.interval.milliseconds === 0;
368
+ if (toFormat.interval.seconds !== 0 || !milliSecondsZero) if (milliSecondsZero) output += formatPart(toFormat.interval.seconds, "second");
369
+ else output += `${toFormat.interval.seconds}.${toFormat.interval.milliseconds.toString().padStart(3, "0")} seconds `;
370
+ }
371
+ if (toFormat.interval.negative) output = `-(${output.trim()})`;
372
+ return output.trim();
373
+ };
374
+ var yearsPart = "(\\d+)\\s*y(?:ears?)?";
375
+ var monthsPart = "(\\d+)\\s*m(?:o(?:nths?)?)?";
376
+ var weeksPart = "(\\d+)\\s*w(?:eeks?)?";
377
+ var daysPart = "(\\d+)\\s*d(?:ays?)?";
378
+ var hoursPart = "(\\d+)\\s*h(?:ours?)?";
379
+ var minutesPart = "(\\d+)\\s*m(?:in(?:s|utes?)?)?";
380
+ var secondsPart = "(\\d+)(?:[,.](\\d{1,3}))?\\s*s(?:ec(?:s|onds?)?)?";
381
+ /**
382
+ * Matches a human readable period string, e.g. "1y 2mo 3weeks 4day" (each part is optional)
383
+ */
384
+ var humanReadablePeriodRegex = new RegExp(`^(?:${yearsPart})?\\s*(?:${monthsPart})?\\s*(?:${weeksPart})?\\s*(?:${daysPart})?\\s*$`, "i");
385
+ /**
386
+ * Matches a human readable duration string, e.g. "1h 2m 3.456s" (each part is optional)
387
+ */
388
+ var humanReadableDurationRegex = new RegExp(`^(?:${hoursPart})?\\s*(?:${minutesPart})?\\s*(?:${secondsPart})?$`, "i");
389
+ /**
390
+ * Matches a negative human readable period string, e.g. "-(1y 2mo 3weeks 4day)" (each part is optional)
391
+ */
392
+ var negativeHumanReadablePeriodRegex = new RegExp(`^\\s*-\\s*\\(\\s*${humanReadablePeriodRegex.source.replace(/[$^]/g, "")}\\s*\\)\\s*$`, "i");
393
+ /**
394
+ * Matches a negative human readable period string with one field like "-1y" or "-1w"
395
+ */
396
+ var negativeHumanReadablePeriodRegexWithSingleField = new RegExp(`^\\s*-\\s*(?:\\s*${yearsPart}|${monthsPart}|${weeksPart}|${daysPart})\\s*$`, "i");
397
+ /**
398
+ * Matches a negative human readable duration string, e.g. "-(1h 2m 3.456s)" (each part is optional)
399
+ */
400
+ var negativeHumanReadableDurationRegex = new RegExp(`^\\s*-\\s*\\(\\s*${humanReadableDurationRegex.source.replace(/[$^]/g, "")}\\s*\\)\\s*$`, "i");
401
+ /**
402
+ * Matches a negative human readable duration string with one field like "-1h" or "-1.5s"
403
+ */
404
+ var negativeHumanReadableDurationRegexWithSingleField = new RegExp(`^\\s*-\\s*(?:\\s*${hoursPart}|${minutesPart}|${secondsPart})\\s*$`, "i");
405
+ /**
406
+ * Try to parse a human readable interval string into an Interval object. Any parts not specified
407
+ * are assumed to be zero. Note that the string must be either a period or a duration, not a mix of
408
+ * both. So for example, "1y 2mo 3weeks 4day" is fine, as is "1h 2m 3.456s". However, "1y 2mo 1sec"
409
+ * is not, since it's a mix of both.
410
+ *
411
+ * Negative intervals are allowed, although if multiple fields are provided the string must include
412
+ * brackets, so "-(1y 2mo)" is also valid, as is "-5 seconds".
413
+ *
414
+ * The string is required to have at least some content, any string that is blank will throw an error.
415
+ *
416
+ * @param intervalString The human readable time string
417
+ */
418
+ var parseHumanReadableIntervalString = (intervalString) => {
419
+ intervalString = intervalString?.trim();
420
+ if (!intervalString) throw new Error("Empty interval string");
421
+ const matchPositivePeriod = humanReadablePeriodRegex.exec(intervalString);
422
+ const matchNegativePeriod = negativeHumanReadablePeriodRegex.exec(intervalString) ?? negativeHumanReadablePeriodRegexWithSingleField.exec(intervalString);
423
+ const matchPositiveDuration = humanReadableDurationRegex.exec(intervalString);
424
+ const matchNegativeDuration = negativeHumanReadableDurationRegex.exec(intervalString) ?? negativeHumanReadableDurationRegexWithSingleField.exec(intervalString);
425
+ const matchPeriod = matchPositivePeriod ?? matchNegativePeriod;
426
+ const matchDuration = matchPositiveDuration ?? matchNegativeDuration;
427
+ const negative = (matchNegativePeriod ?? matchNegativeDuration) !== null;
428
+ if (matchDuration && matchPeriod) throw new Error("Ambiguous time format");
429
+ if (matchPeriod) return {
430
+ type: "DATE",
431
+ interval: extractPeriodFromRegexMatch(negative, matchPeriod)
432
+ };
433
+ else if (matchDuration) return {
434
+ type: "TIME",
435
+ interval: extractDurationFromRegexMatch(negative, matchDuration)
436
+ };
437
+ else throw new Error(`Invalid human readable time: ${intervalString}`);
438
+ };
439
+ /**
440
+ * Check if the given string can be understood as a human readable duration or period string. The
441
+ * type parameter specifies whether the string should be a date, time, or either.
442
+ *
443
+ * @param time the string to check
444
+ * @param expectedType the type of the string - either "DATE", "TIME", or "ANY"
445
+ */
446
+ var isValidHumanReadableIntervalString = (time, expectedType) => {
447
+ try {
448
+ const validationResult = parseHumanReadableIntervalString(time);
449
+ const actualType = validationResult.type;
450
+ const negative = validationResult.interval.negative;
451
+ if (actualType === expectedType || expectedType === "DATE_OR_TIME") return {
452
+ valid: true,
453
+ type: actualType,
454
+ negative
455
+ };
456
+ else return { valid: false };
457
+ } catch (_e) {
458
+ return { valid: false };
459
+ }
460
+ };
461
+ /**
462
+ * Convert an ISO duration OR period string to an Interval object. So for example,
463
+ * "P1Y2M3W4D" is fine, as is "PT1H2M3.456S". However, "P1Y2M3W4D1H2M3.456S" is not, since
464
+ * it's a mix of both. We're more forgiving than the ISO standard, so we allow for missing parts.
465
+ * Also, the string is allowed to be negative, so "-P1Y2M3W4D" is also valid.
466
+ *
467
+ * The string is required to have at least some content, so the strings "", "P", and "PT" are
468
+ * considered invalid (also if they start with a -).
469
+ *
470
+ * @param isoString The ISO duration or period string.
471
+ */
472
+ var parseISOIntervalString = (isoString) => {
473
+ isoString = isoString?.trim();
474
+ if ([
475
+ "",
476
+ "P",
477
+ "PT",
478
+ "-",
479
+ "-P",
480
+ "-PT"
481
+ ].includes(isoString)) throw new Error("Empty ISO duration");
482
+ const periodRegex = /^-?P(?:(\d+)Y)?(?:(\d+)M)?(?:(\d+)W)?(?:(\d+)D)?$/;
483
+ const durationRegex = /^-?PT(?:(\d+)H)?(?:(\d+)M)?(?:(\d+)(?:[,.](\d{1,3}))?S)?$/;
484
+ const matchPeriod = periodRegex.exec(isoString);
485
+ const matchDuration = durationRegex.exec(isoString);
486
+ if (matchPeriod) return {
487
+ type: "DATE",
488
+ interval: extractPeriodFromRegexMatch(isoString.startsWith("-"), matchPeriod)
489
+ };
490
+ else if (matchDuration) return {
491
+ type: "TIME",
492
+ interval: extractDurationFromRegexMatch(isoString.startsWith("-"), matchDuration)
493
+ };
494
+ else throw new Error(`Invalid ISO duration: ${isoString}`);
495
+ };
496
+ /**
497
+ * Check if the given string is a valid duration or period ISO string. The type parameter
498
+ * specifies whether the string should be a date, time, or either.
499
+ *
500
+ * @param isoString the string to check
501
+ * @param type the type of the string - either "DATE", "TIME", or "ANY"
502
+ */
503
+ var isValidISOIntervalString = (isoString, type) => {
504
+ try {
505
+ const validationResult = parseISOIntervalString(isoString);
506
+ const actualType = validationResult.type;
507
+ const negative = validationResult.interval.negative;
508
+ if (actualType === type || type === "DATE_OR_TIME") return {
509
+ valid: true,
510
+ type: actualType,
511
+ negative
512
+ };
513
+ else return { valid: false };
514
+ } catch (_e) {
515
+ return { valid: false };
516
+ }
517
+ };
518
+ /**
519
+ * Try to convert an interval string to an Interval object. The string can be either an ISO
520
+ * duration/period string or a human readable string. If the string is not valid, an error is
521
+ * thrown.
522
+ *
523
+ * @param time the time string, either ISO or human readable
524
+ */
525
+ var parseGenericIntervalString = (time) => {
526
+ const validISO = isValidISOIntervalString(time, "DATE_OR_TIME");
527
+ const validHumanReadable = isValidHumanReadableIntervalString(time, "DATE_OR_TIME");
528
+ if (validISO.valid) return parseISOIntervalString(time);
529
+ else if (validHumanReadable.valid) return parseHumanReadableIntervalString(time);
530
+ else throw new Error(`Invalid interval string: ${time}`);
531
+ };
532
+ /**
533
+ * Check if the given string is a valid interval string, either human readable or ISO. The type parameter
534
+ * specifies whether the string should be a period, duration, or either.
535
+ *
536
+ * @param time the time string to check
537
+ * @param type the type of the string - either "DATE", "TIME", or "ANY"
538
+ */
539
+ var isValidIntervalString = (time, type) => {
540
+ const validISO = isValidISOIntervalString(time, type);
541
+ const validHumanReadable = isValidHumanReadableIntervalString(time, type);
542
+ if (validISO.valid) return validISO;
543
+ else if (validHumanReadable.valid) return validHumanReadable;
544
+ else return { valid: false };
545
+ };
546
+ //#endregion
547
+ //#region src/numIntegerDigits.ts
548
+ /**
549
+ * Count the number of integer digits for a given number.
550
+ *
551
+ * @param input number.
552
+ * @returns number of integer digits x has. 1234 = 4 but 1234.44 is also 4.
553
+ */
554
+ var numIntegerDigits_default = (input) => Math.max(Math.floor(Math.log10(Math.abs(input))), 0) + 1;
555
+ //#endregion
556
+ //#region src/promise/createAbortablePromise.ts
557
+ var AbortError = class extends Error {};
558
+ /**
559
+ * Helper to create an abortable promise. Returns an AbortController and a Function
560
+ * that you can pass your async handler to. Whenever the AbortController signal is
561
+ * aborted then the async handler's promise will reject with an AbortError
562
+ *
563
+ * Example:
564
+ * ```
565
+ * import { abortUtils } from "@knime/utils"
566
+ * const myFetchCall = async (params...) => {...};
567
+ *
568
+ * try {
569
+ * const { runAbortablePromise, abortController } = createAbortablePromise(() =>
570
+ * myFetchCall(params...),
571
+ * );
572
+ * } catch (e) {
573
+ * if (e instanceof abortUtils.AbortError) {
574
+ * console.info('ignore due to abort');
575
+ * return;
576
+ * }
577
+ * }
578
+ *
579
+ * // somewhere else (while request is in-flight)
580
+ * abortController.abort(new abortUtils.AbortError('reason here'))
581
+ * ```
582
+ */
583
+ var createAbortablePromise = () => {
584
+ const abortController = new AbortController();
585
+ const runAbortablePromise = (request) => {
586
+ return new Promise((resolve, reject) => {
587
+ const abortListener = ({ target }) => {
588
+ abortController.signal.removeEventListener("abort", abortListener);
589
+ const reason = target.reason;
590
+ reject(reason instanceof AbortError ? reason : new AbortError(reason));
591
+ };
592
+ request().then(resolve).catch((error) => {
593
+ if (error instanceof AbortError) return;
594
+ reject(error);
595
+ });
596
+ abortController.signal.addEventListener("abort", abortListener);
597
+ });
598
+ };
599
+ return {
600
+ abortController,
601
+ runAbortablePromise
602
+ };
603
+ };
604
+ //#endregion
605
+ //#region src/promise/createUnwrappedPromise.ts
606
+ var createUnwrappedPromise = () => {
607
+ let resolve = () => {};
608
+ let reject = () => {};
609
+ const promise = new Promise((res, rej) => {
610
+ resolve = res;
611
+ reject = rej;
612
+ });
613
+ return {
614
+ resolve,
615
+ reject,
616
+ promise
617
+ };
618
+ };
619
+ //#endregion
620
+ //#region src/sleep.ts
621
+ /**
622
+ * Returns promise that resolves after ms.
623
+ */
498
624
  function sleep(ms) {
499
- return new Promise((resolve) => setTimeout(resolve, ms));
625
+ return new Promise((resolve) => setTimeout(resolve, ms));
500
626
  }
501
-
502
- const DEFAULT_RETRY_DELAY_MS = 0;
503
- const DEFAULT_RETRY_COUNT = 5;
504
- async function retryPromise({
505
- fn,
506
- retryCount = DEFAULT_RETRY_COUNT,
507
- retryDelayMS = DEFAULT_RETRY_DELAY_MS,
508
- excludeError
509
- }) {
510
- try {
511
- return await fn();
512
- } catch (error) {
513
- if (excludeError?.(error)) {
514
- throw error;
515
- }
516
- if (retryCount > 0) {
517
- await sleep(retryDelayMS);
518
- return await retryPromise({
519
- fn,
520
- retryCount: retryCount - 1,
521
- retryDelayMS,
522
- excludeError
523
- });
524
- }
525
- throw error;
526
- }
627
+ /**
628
+ * Helper to add retry capability to an async function
629
+ * @param fn async function
630
+ * @param retryCount max number of retries. defaults to 5
631
+ * @param retryDelayMS delay in-between retries in millisecs. defaults to 0
632
+ * @param excludeError predicate fn to exclude specific errors from causing a retry
633
+ */
634
+ async function retryPromise({ fn, retryCount = 5, retryDelayMS = 0, excludeError }) {
635
+ try {
636
+ return await fn();
637
+ } catch (error) {
638
+ if (excludeError?.(error)) throw error;
639
+ if (retryCount > 0) {
640
+ await sleep(retryDelayMS);
641
+ return await retryPromise({
642
+ fn,
643
+ retryCount: retryCount - 1,
644
+ retryDelayMS,
645
+ excludeError
646
+ });
647
+ }
648
+ throw error;
649
+ }
527
650
  }
528
-
529
- const index = /*#__PURE__*/Object.freeze(/*#__PURE__*/Object.defineProperty({
530
- __proto__: null,
531
- AbortError,
532
- DEFAULT_RETRY_COUNT,
533
- DEFAULT_RETRY_DELAY_MS,
534
- createAbortablePromise,
535
- createUnwrappedPromise,
536
- retryPromise
537
- }, Symbol.toStringTag, { value: 'Module' }));
538
-
539
- const ALLOWED_TAGS = [
540
- "p",
541
- "div",
542
- "h1",
543
- "h2",
544
- "h3",
545
- "h4",
546
- "h5",
547
- "h6",
548
- "ul",
549
- "ol",
550
- "li",
551
- "blockquote",
552
- "b",
553
- "i",
554
- "s",
555
- "u",
556
- "sup",
557
- "sub",
558
- "ins",
559
- "del",
560
- "strong",
561
- "strike",
562
- "tt",
563
- "code",
564
- "big",
565
- "small",
566
- "br",
567
- "span",
568
- "em"
651
+ //#endregion
652
+ //#region src/promise/index.ts
653
+ var promise_exports = /* @__PURE__ */ __exportAll({
654
+ AbortError: () => AbortError,
655
+ DEFAULT_RETRY_COUNT: () => 5,
656
+ DEFAULT_RETRY_DELAY_MS: () => 0,
657
+ createAbortablePromise: () => createAbortablePromise,
658
+ createUnwrappedPromise: () => createUnwrappedPromise,
659
+ retryPromise: () => retryPromise
660
+ });
661
+ //#endregion
662
+ //#region src/sanitization.ts
663
+ var ALLOWED_TAGS = [
664
+ "p",
665
+ "div",
666
+ "h1",
667
+ "h2",
668
+ "h3",
669
+ "h4",
670
+ "h5",
671
+ "h6",
672
+ "ul",
673
+ "ol",
674
+ "li",
675
+ "blockquote",
676
+ "b",
677
+ "i",
678
+ "s",
679
+ "u",
680
+ "sup",
681
+ "sub",
682
+ "ins",
683
+ "del",
684
+ "strong",
685
+ "strike",
686
+ "tt",
687
+ "code",
688
+ "big",
689
+ "small",
690
+ "br",
691
+ "span",
692
+ "em"
569
693
  ];
570
- const sanitizeHTML = (rawHTML, options = {
571
- allowStyleAttribute: false,
572
- allowHyperlinks: false
694
+ /**
695
+ * Sanitizes Raw HTML and only allow specific tags to be used, as per OWASP standards.
696
+ * @param rawHTML
697
+ * @param options.allowStyleAttribute - Allow the style attribute on elements
698
+ * @param options.allowHyperlinks - Allow anchor tags with href attribute
699
+ * @returns sanitized html
700
+ */
701
+ var sanitizeHTML = (rawHTML, options = {
702
+ allowStyleAttribute: false,
703
+ allowHyperlinks: false
573
704
  }) => {
574
- const { allowStyleAttribute, allowHyperlinks } = options;
575
- const ALLOWED_ATTR = [
576
- ...allowStyleAttribute ? ["style"] : [],
577
- ...allowHyperlinks ? ["href"] : []
578
- ];
579
- const allowedTags = allowHyperlinks ? [...ALLOWED_TAGS, "a"] : ALLOWED_TAGS;
580
- return DomPurify.sanitize(rawHTML, {
581
- ALLOWED_TAGS: allowedTags,
582
- ALLOWED_ATTR
583
- });
584
- };
585
- const stripHTML = (rawHTML) => {
586
- return DomPurify.sanitize(rawHTML, { ALLOWED_TAGS: [], ALLOWED_ATTR: [] });
587
- };
588
- const sanitization = { sanitizeHTML, stripHTML };
589
-
590
- const defaultMaxLength = 160;
591
- const truncateString = (string = "", maxLength = defaultMaxLength) => {
592
- const dots = string.length > maxLength ? "…" : "";
593
- return `${string.substring(0, maxLength - 1)}${dots}`;
594
- };
595
-
596
- const getFileExtension = (nameOrPath) => {
597
- const basename = nameOrPath.split(/[\\/]/).pop() ?? "";
598
- const parts = basename.split(".");
599
- if (basename === "" || parts.length === 1) {
600
- return "";
601
- }
602
- return parts.at(-1) ?? "";
603
- };
604
- const KNAR = Object.freeze({
605
- extension: "knar",
606
- mimeType: "application/vnd.knime.workflow-group+zip",
607
- matches(file) {
608
- const extension = getFileExtension(file.name);
609
- return extension === this.extension;
610
- }
705
+ const { allowStyleAttribute, allowHyperlinks } = options;
706
+ const ALLOWED_ATTR = [...allowStyleAttribute ? ["style"] : [], ...allowHyperlinks ? ["href"] : []];
707
+ const allowedTags = allowHyperlinks ? [...ALLOWED_TAGS, "a"] : ALLOWED_TAGS;
708
+ return DomPurify.sanitize(rawHTML, {
709
+ ALLOWED_TAGS: allowedTags,
710
+ ALLOWED_ATTR
711
+ });
712
+ };
713
+ /**
714
+ * Removes any HTML tag from the input string. Keeps HTML entities
715
+ * (e.g   because these can be considered plain text)
716
+ * @param rawHTML
717
+ * @returns plain text
718
+ */
719
+ var stripHTML = (rawHTML) => {
720
+ return DomPurify.sanitize(rawHTML, {
721
+ ALLOWED_TAGS: [],
722
+ ALLOWED_ATTR: []
723
+ });
724
+ };
725
+ var sanitization = {
726
+ sanitizeHTML,
727
+ stripHTML
728
+ };
729
+ //#endregion
730
+ //#region src/truncateString.ts
731
+ var defaultMaxLength = 160;
732
+ var truncateString_default = (string = "", maxLength = defaultMaxLength) => {
733
+ const dots = string.length > maxLength ? "…" : "";
734
+ return `${string.substring(0, maxLength - 1)}${dots}`;
735
+ };
736
+ //#endregion
737
+ //#region src/fileExtensions.ts
738
+ /**
739
+ * Gets the file extension
740
+ * @param nameOrPath can take a full file name (e.g "file.txt") or a path to a file
741
+ * (e.g "file://path/to/file.txt" OR "/path/to/file.txt")
742
+ * @returns just the file extension (e.g "txt")
743
+ */
744
+ var getFileExtension = (nameOrPath) => {
745
+ const basename = nameOrPath.split(/[\\/]/).pop() ?? "";
746
+ const parts = basename.split(".");
747
+ if (basename === "" || parts.length === 1) return "";
748
+ return parts.at(-1) ?? "";
749
+ };
750
+ /**
751
+ * Metadata for .knar files, which corresponds to exported KNIME Workflow Groups
752
+ * or Components
753
+ */
754
+ var KNAR = Object.freeze({
755
+ extension: "knar",
756
+ mimeType: "application/vnd.knime.workflow-group+zip",
757
+ matches(file) {
758
+ return getFileExtension(file.name) === this.extension;
759
+ }
611
760
  });
612
- const KNWF = Object.freeze({
613
- extension: "knwf",
614
- mimeType: "application/vnd.knime.workflow+zip",
615
- matches(file) {
616
- const extension = getFileExtension(file.name);
617
- return extension === this.extension;
618
- },
619
- /**
620
- * Gets the name of a .knwf file without the extension. If the file is not
621
- * matched as a .knwf file then this function will return the default value,
622
- * which is empty string ("") if param is not provided
623
- */
624
- getNameOrDefault(file, defaultValue = "") {
625
- if (!this.matches(file)) {
626
- return defaultValue;
627
- }
628
- return file.name.replace(`.${this.extension}`, "");
629
- }
761
+ /**
762
+ * Metadata for .knwf files, which corresponds to exported KNIME Workflows
763
+ */
764
+ var KNWF = Object.freeze({
765
+ extension: "knwf",
766
+ mimeType: "application/vnd.knime.workflow+zip",
767
+ matches(file) {
768
+ return getFileExtension(file.name) === this.extension;
769
+ },
770
+ /**
771
+ * Gets the name of a .knwf file without the extension. If the file is not
772
+ * matched as a .knwf file then this function will return the default value,
773
+ * which is empty string ("") if param is not provided
774
+ */
775
+ getNameOrDefault(file, defaultValue = "") {
776
+ if (!this.matches(file)) return defaultValue;
777
+ return file.name.replace(`.${this.extension}`, "");
778
+ }
630
779
  });
631
- const knimeFileFormats = { KNAR, KNWF };
632
- const getFileMimeType = (file) => {
633
- const DEFAULT_MIMETYPE = "application/octet-stream";
634
- const extension = getFileExtension(file.name);
635
- if (!extension) {
636
- return DEFAULT_MIMETYPE;
637
- }
638
- if (KNWF.matches(file)) {
639
- return KNWF.mimeType;
640
- }
641
- if (KNAR.matches(file)) {
642
- return KNAR.mimeType;
643
- }
644
- if (!file.type) {
645
- return DEFAULT_MIMETYPE;
646
- }
647
- return file.type;
648
- };
649
-
650
- const hotkeyPlatform = {
651
- MAC_OS: "macOS",
652
- OTHER: "other"
780
+ var knimeFileFormats = {
781
+ KNAR,
782
+ KNWF
783
+ };
784
+ /**
785
+ * Gets the mime type from a given file. Defaults to `application/octet-stream`
786
+ * if mimeType cannot be detected
787
+ * @param file File
788
+ * @returns mimeType
789
+ */
790
+ var getFileMimeType = (file) => {
791
+ const DEFAULT_MIMETYPE = "application/octet-stream";
792
+ if (!getFileExtension(file.name)) return DEFAULT_MIMETYPE;
793
+ if (KNWF.matches(file)) return KNWF.mimeType;
794
+ if (KNAR.matches(file)) return KNAR.mimeType;
795
+ if (!file.type) return DEFAULT_MIMETYPE;
796
+ return file.type;
797
+ };
798
+ //#endregion
799
+ //#region src/hotkeys/enums.ts
800
+ /**
801
+ * Platforms that influence how modifier keys are rendered. macOS substitutes
802
+ * dedicated glyphs (`⌘`, `⌥`, `⇧`, …), every other platform uses the textual
803
+ * rendering (`Ctrl`, `Alt`, `Shift`, …).
804
+ */
805
+ var hotkeyPlatform = {
806
+ MAC_OS: "macOS",
807
+ OTHER: "other"
653
808
  };
654
809
  Object.values(hotkeyPlatform);
810
+ //#endregion
811
+ //#region src/platform/navigator.ts
812
+ var navigator_exports = /* @__PURE__ */ __exportAll({
813
+ isMac: () => isMac,
814
+ isWindows: () => isWindows
815
+ });
816
+ /**
817
+ *
818
+ * @returns true if the platform of the user is Mac
819
+ */
820
+ var isMac = () => navigator?.userAgent?.toLowerCase()?.includes("mac");
821
+ /**
822
+ *
823
+ * @returns true if the platform of the user is Windows
824
+ */
825
+ var isWindows = () => navigator?.userAgent?.toLowerCase()?.includes("windows");
826
+ //#endregion
827
+ //#region src/hotkeys/format.ts
828
+ var globalKeyMap = {
829
+ ArrowUp: "↑",
830
+ ArrowDown: "↓",
831
+ ArrowLeft: "←",
832
+ ArrowRight: "→",
833
+ Enter: "↵",
834
+ " ": "Space",
835
+ CtrlOrCmd: "Ctrl"
836
+ };
837
+ var MacOSkeyMap = {
838
+ Shift: "⇧",
839
+ Delete: "⌫",
840
+ CtrlOrCmd: "⌘",
841
+ Ctrl: "⌃",
842
+ Alt: "⌥",
843
+ Enter: "↩"
844
+ };
845
+ /**
846
+ * Returns a string representation of a single hotkey. Replaces some special key names with symbols.
847
+ *
848
+ * By default the platform is auto-detected from the user agent via `isMac()`.
849
+ * Pass `platform` to force a specific platform's glyphs — useful for SSR,
850
+ * tests, or rendering multiple platforms on the same page.
851
+ */
852
+ var formatHotkey = (hotkey, platform) => {
853
+ /**
854
+ * Returns the symbol corresponding to the `key` based on the given
855
+ * `formatMap`. Otherwise, if not found, returns the same `key` value given
856
+ */
857
+ const mapSymbols = (formatMap) => (key) => formatMap[key] ?? key;
858
+ /**
859
+ * Pipe function implementation. Receives a list of functions to execute in order
860
+ * and will pipe the parameter passed at the end to each function returning the final output
861
+ */
862
+ const pipe = (...fns) => fns.reduce((f, g) => (arg) => g(f(arg)), (arg) => arg);
863
+ const macKeyFormatter = pipe(mapSymbols(MacOSkeyMap), mapSymbols(globalKeyMap));
864
+ const generalKeyFormatter = mapSymbols(globalKeyMap);
865
+ return (platform === void 0 ? isMac() : platform === hotkeyPlatform.MAC_OS) ? macKeyFormatter(hotkey) : generalKeyFormatter(hotkey);
866
+ };
867
+ var getDefaultSeparator = () => isMac() ? " " : "+";
868
+ /**
869
+ * Returns a string representation of a list of hotkeys. Replaces some special key names with symbols
870
+ */
871
+ var formatHotkeys = (hotkeys, getSeparator = getDefaultSeparator) => hotkeys.map((hotkey) => formatHotkey(hotkey)).join(getSeparator());
872
+ /**
873
+ * Appends a formatted hotkey shortcut to the given string. Useful for tooltips
874
+ */
875
+ var textWithHotkeys = (text, hotkeys) => {
876
+ return `${text} – ${formatHotkeys(hotkeys)}`;
877
+ };
878
+ //#endregion
879
+ //#region src/hotkeys/match.ts
880
+ /**
881
+ * Checks whether a pressed `Digit` key falls within a numeric hotkey range such
882
+ * as `1-9`.
883
+ * @param keyCode - The `KeyboardEvent.code` to check (e.g. `Digit5`).
884
+ * @param hotkey - The hotkey token, expected to be a single-digit range like `1-9`.
885
+ * @returns True if the pressed digit lies within the inclusive range.
886
+ */
887
+ var isDigitKeyInRange = (keyCode, hotkey) => {
888
+ if (hotkey.length !== 3 || !keyCode?.startsWith("Digit")) return false;
889
+ const keyNumber = Number(keyCode.slice(5));
890
+ const [lower, upper] = hotkey.split("-");
891
+ return Boolean(lower) && Boolean(upper) && Number.parseInt(lower, 10) <= keyNumber && keyNumber <= Number.parseInt(upper, 10);
892
+ };
893
+ /**
894
+ * Checks whether a keyboard event matches a hotkey definition. The last token is
895
+ * treated as the character; any preceding tokens are modifiers. The special
896
+ * `CtrlOrCmd` modifier resolves to the platform's primary modifier (Meta/`⌘` on
897
+ * macOS, Ctrl elsewhere).
898
+ * @param event - The keyboard event to check.
899
+ * @param hotkeys - The ordered hotkey tokens (modifiers followed by the character).
900
+ * @returns True if the event matches the given hotkey, otherwise false.
901
+ */
902
+ var match = (event, hotkeys) => {
903
+ const { key, code, metaKey, ctrlKey, shiftKey, altKey } = event;
904
+ const modifiers = hotkeys.slice();
905
+ const character = modifiers.pop() ?? "";
906
+ const ctrlOrMeta = isMac() ? "Meta" : "Ctrl";
907
+ const platformModifiers = new Set(modifiers.map((modifier) => modifier === "CtrlOrCmd" ? ctrlOrMeta : modifier));
908
+ const metaMatches = Boolean(metaKey) === platformModifiers.has("Meta");
909
+ const ctrlMatches = Boolean(ctrlKey) === platformModifiers.has("Ctrl");
910
+ const shiftMatches = Boolean(shiftKey) === platformModifiers.has("Shift");
911
+ const altMatches = Boolean(altKey) === platformModifiers.has("Alt");
912
+ const keysMatch = key.toUpperCase() === character.toUpperCase() || character.includes("-") && isDigitKeyInRange(code, character) || isMac() && character === "Delete" && key === "Backspace";
913
+ return metaMatches && ctrlMatches && shiftMatches && altMatches && keysMatch;
914
+ };
915
+ //#endregion
916
+ //#region src/hotkeys/modifiers.ts
917
+ /**
918
+ * Checks if any modifier key (Ctrl, Meta, Alt, or Shift) is pressed.
919
+ * @param event - The keyboard event to check.
920
+ * @returns True if a modifier key is pressed, otherwise false.
921
+ */
922
+ var isModifierKeyPressed = (event) => {
923
+ return event.ctrlKey || event.metaKey || event.altKey || event.shiftKey;
924
+ };
925
+ /**
926
+ * Checks if a specific key (or keys) were pressed without any modifier keys.
927
+ * @param event - The keyboard event to check.
928
+ * @param keys - The key or keys to check for.
929
+ * @returns True if the specified key(s) were pressed without modifiers, otherwise false.
930
+ */
931
+ var isKeyWithoutModifiers = (event, keys) => {
932
+ return (Array.isArray(keys) ? keys : [keys]).includes(event.key) && !isModifierKeyPressed(event);
933
+ };
934
+ /**
935
+ * Returns the name of the primary modifier key for the current platform.
936
+ */
937
+ var getMetaOrCtrlKey = () => {
938
+ return isMac() ? "metaKey" : "ctrlKey";
939
+ };
940
+ //#endregion
941
+ //#region src/hotkeys/index.ts
942
+ /**
943
+ * Grouped keyboard-shortcut helpers, exposed as a single namespace for
944
+ * ergonomic access (e.g. `hotkeys.formatHotkey`).
945
+ */
946
+ var hotkeys = {
947
+ formatHotkeys,
948
+ formatHotkey,
949
+ getDefaultSeparator,
950
+ hotkeyPlatform,
951
+ textWithHotkeys,
952
+ match
953
+ };
954
+ //#endregion
955
+ export { capitalize, caseFormatter, debounce, filters, formatDateString, formatDateTimeString, formatFileSize, formatLocalDateTimeString, formatTimeString, getDeepActiveElement, getFileExtension, getFileMimeType, localTimezone_default as getLocalTimeZone, getMetaOrCtrlKey, getWrappedAroundIndex_default as getWrappedAroundIndex, hotkeys, intervalUtils_exports as intervalUtils, isAfterMaxDate, isBeforeMinDate, isKeyWithoutModifiers, isModifierKeyPressed, knimeFileFormats, match, navigator_exports as navigatorUtils, numIntegerDigits_default as numIntegerDigits, promise_exports as promise, sanitization, sleep, truncateString_default as truncateString, updateDate_default as updateDate, updateTime_default as updateTime };
655
956
 
656
- const isMac = () => navigator?.userAgent?.toLowerCase()?.includes("mac");
657
- const isWindows = () => navigator?.userAgent?.toLowerCase()?.includes("windows");
658
-
659
- const navigator$1 = /*#__PURE__*/Object.freeze(/*#__PURE__*/Object.defineProperty({
660
- __proto__: null,
661
- isMac,
662
- isWindows
663
- }, Symbol.toStringTag, { value: 'Module' }));
664
-
665
- const globalKeyMap = {
666
- ArrowUp: "↑",
667
- ArrowDown: "↓",
668
- ArrowLeft: "←",
669
- ArrowRight: "→",
670
- Enter: "↵",
671
- " ": "Space",
672
- // we use event.key and there space is an actual space not the code "Space"
673
- CtrlOrCmd: "Ctrl"
674
- };
675
- const MacOSkeyMap = {
676
- Shift: "⇧",
677
- Delete: "⌫",
678
- CtrlOrCmd: "⌘",
679
- Ctrl: "⌃",
680
- Alt: "⌥",
681
- Enter: "↩"
682
- };
683
- const formatHotkey = (hotkey, platform) => {
684
- const mapSymbols = (formatMap) => (key) => formatMap[key] ?? key;
685
- const pipe = (...fns) => fns.reduce(
686
- (f, g) => (arg) => g(f(arg)),
687
- (arg) => arg
688
- );
689
- const macKeyFormatter = pipe(
690
- mapSymbols(MacOSkeyMap),
691
- mapSymbols(globalKeyMap)
692
- );
693
- const generalKeyFormatter = mapSymbols(globalKeyMap);
694
- const useMacFormatter = platform === void 0 ? isMac() : platform === hotkeyPlatform.MAC_OS;
695
- return useMacFormatter ? macKeyFormatter(hotkey) : generalKeyFormatter(hotkey);
696
- };
697
- const getDefaultSeparator = () => isMac() ? " " : "+";
698
- const formatHotkeys = (hotkeys, getSeparator = getDefaultSeparator) => hotkeys.map((hotkey) => formatHotkey(hotkey)).join(getSeparator());
699
- const textWithHotkeys = (text, hotkeys) => {
700
- return `${text} – ${formatHotkeys(hotkeys)}`;
701
- };
702
-
703
- const isDigitKeyInRange = (keyCode, hotkey) => {
704
- const digitRangeLength = 3;
705
- if (hotkey.length !== digitRangeLength || !keyCode?.startsWith("Digit")) {
706
- return false;
707
- }
708
- const keyNumber = Number(keyCode.slice("Digit".length));
709
- const [lower, upper] = hotkey.split("-");
710
- return Boolean(lower) && Boolean(upper) && Number.parseInt(lower, 10) <= keyNumber && keyNumber <= Number.parseInt(upper, 10);
711
- };
712
- const match = (event, hotkeys) => {
713
- const { key, code, metaKey, ctrlKey, shiftKey, altKey } = event;
714
- const modifiers = hotkeys.slice();
715
- const character = modifiers.pop() ?? "";
716
- const ctrlOrMeta = isMac() ? "Meta" : "Ctrl";
717
- const platformModifiers = new Set(
718
- modifiers.map(
719
- (modifier) => modifier === "CtrlOrCmd" ? ctrlOrMeta : modifier
720
- )
721
- );
722
- const metaMatches = Boolean(metaKey) === platformModifiers.has("Meta");
723
- const ctrlMatches = Boolean(ctrlKey) === platformModifiers.has("Ctrl");
724
- const shiftMatches = Boolean(shiftKey) === platformModifiers.has("Shift");
725
- const altMatches = Boolean(altKey) === platformModifiers.has("Alt");
726
- const keysMatch = (
727
- // keys are matched case insensitively
728
- key.toUpperCase() === character.toUpperCase() || character.includes("-") && isDigitKeyInRange(code, character) || // on mac 'backspace' can be used instead of delete
729
- isMac() && character === "Delete" && key === "Backspace"
730
- );
731
- return metaMatches && ctrlMatches && shiftMatches && altMatches && keysMatch;
732
- };
733
-
734
- const isModifierKeyPressed = (event) => {
735
- return event.ctrlKey || event.metaKey || event.altKey || event.shiftKey;
736
- };
737
- const isKeyWithoutModifiers = (event, keys) => {
738
- const keyList = Array.isArray(keys) ? keys : [keys];
739
- return keyList.includes(event.key) && !isModifierKeyPressed(event);
740
- };
741
- const getMetaOrCtrlKey = () => {
742
- return isMac() ? "metaKey" : "ctrlKey";
743
- };
744
-
745
- const hotkeys = {
746
- formatHotkeys,
747
- formatHotkey,
748
- getDefaultSeparator,
749
- hotkeyPlatform,
750
- textWithHotkeys,
751
- match
752
- };
753
-
754
- export { capitalize, caseFormatter, debounce, filters, formatDateString, formatDateTimeString, formatFileSize, formatLocalDateTimeString, formatTimeString, getDeepActiveElement, getFileExtension, getFileMimeType, getLocalTimeZone, getMetaOrCtrlKey, getWrappedAroundIndex, hotkeys, intervalUtils, isAfterMaxDate, isBeforeMinDate, isKeyWithoutModifiers, isModifierKeyPressed, knimeFileFormats, match, navigator$1 as navigatorUtils, numIntegerDigits, index as promise, sanitization, sleep, truncateString, updateDate, updateTime };
755
- //# sourceMappingURL=index.js.map
957
+ //# sourceMappingURL=index.js.map