@rt-tools/utils 0.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/README.md +99 -0
- package/fesm2022/rt-tools-utils.mjs +1567 -0
- package/fesm2022/rt-tools-utils.mjs.map +1 -0
- package/package.json +51 -0
- package/types/rt-tools-utils.d.ts +625 -0
|
@@ -0,0 +1,1567 @@
|
|
|
1
|
+
import * as i0 from '@angular/core';
|
|
2
|
+
import { input, HostBinding, Directive, effect, inject, booleanAttribute, InjectionToken, Injectable, Injector, signal, computed, HostListener, DestroyRef, output, Pipe } from '@angular/core';
|
|
3
|
+
import { isNil, WINDOW, PlatformService } from '@rt-tools/core';
|
|
4
|
+
export { MessageBus, PlatformService, WINDOW, isNil } from '@rt-tools/core';
|
|
5
|
+
import { Validators, FormControl } from '@angular/forms';
|
|
6
|
+
import { MatTooltip } from '@angular/material/tooltip';
|
|
7
|
+
import { Router, ActivatedRoute } from '@angular/router';
|
|
8
|
+
import { DOCUMENT } from '@angular/common';
|
|
9
|
+
import { BreakpointObserver } from '@angular/cdk/layout';
|
|
10
|
+
import { toSignal, toObservable, takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
|
11
|
+
import { distinctUntilChanged, switchMap, map, filter, take } from 'rxjs/operators';
|
|
12
|
+
import { DomSanitizer } from '@angular/platform-browser';
|
|
13
|
+
|
|
14
|
+
const OVERLAY_POSITIONS = Object.freeze([
|
|
15
|
+
{
|
|
16
|
+
originX: 'start',
|
|
17
|
+
originY: 'bottom',
|
|
18
|
+
overlayX: 'start',
|
|
19
|
+
overlayY: 'top',
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
originX: 'end',
|
|
23
|
+
originY: 'bottom',
|
|
24
|
+
overlayX: 'end',
|
|
25
|
+
overlayY: 'top',
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
originX: 'start',
|
|
29
|
+
originY: 'bottom',
|
|
30
|
+
overlayX: 'start',
|
|
31
|
+
overlayY: 'top',
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
originX: 'start',
|
|
35
|
+
originY: 'top',
|
|
36
|
+
overlayX: 'start',
|
|
37
|
+
overlayY: 'bottom',
|
|
38
|
+
},
|
|
39
|
+
]);
|
|
40
|
+
|
|
41
|
+
const DASH = '—';
|
|
42
|
+
|
|
43
|
+
class RtIconOutlinedDirective {
|
|
44
|
+
constructor() {
|
|
45
|
+
this.isOutlined = input(false, { ...(ngDevMode ? { debugName: "isOutlined" } : {}), alias: 'rtIconOutlined',
|
|
46
|
+
transform: (value) => {
|
|
47
|
+
return Boolean(value);
|
|
48
|
+
} });
|
|
49
|
+
}
|
|
50
|
+
get fontVariationSettings() {
|
|
51
|
+
// eslint-disable-next-line quotes
|
|
52
|
+
return this.isOutlined() ? "'FILL' 0, 'wght' 700, 'GRAD' 0, 'opsz' 48" : "'FILL' 1, 'wght' 700, 'GRAD' 0, 'opsz' 48";
|
|
53
|
+
}
|
|
54
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.1", ngImport: i0, type: RtIconOutlinedDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
55
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.0.1", type: RtIconOutlinedDirective, isStandalone: true, selector: "mat-icon[rtIconOutlined]", inputs: { isOutlined: { classPropertyName: "isOutlined", publicName: "rtIconOutlined", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "style.fontVariationSettings": "this.fontVariationSettings" } }, ngImport: i0 }); }
|
|
56
|
+
}
|
|
57
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.1", ngImport: i0, type: RtIconOutlinedDirective, decorators: [{
|
|
58
|
+
type: Directive,
|
|
59
|
+
args: [{
|
|
60
|
+
selector: 'mat-icon[rtIconOutlined]',
|
|
61
|
+
}]
|
|
62
|
+
}], propDecorators: { isOutlined: [{ type: i0.Input, args: [{ isSignal: true, alias: "rtIconOutlined", required: false }] }], fontVariationSettings: [{
|
|
63
|
+
type: HostBinding,
|
|
64
|
+
args: ['style.fontVariationSettings']
|
|
65
|
+
}] } });
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Date formatting and parsing utilities (replacement for date-fns)
|
|
69
|
+
*
|
|
70
|
+
* Supported format tokens:
|
|
71
|
+
* - yyyy: 4-digit year (2024)
|
|
72
|
+
* - yy: 2-digit year (24)
|
|
73
|
+
* - MM: 2-digit month (01-12)
|
|
74
|
+
* - M: month (1-12)
|
|
75
|
+
* - dd: 2-digit day (01-31)
|
|
76
|
+
* - d: day (1-31)
|
|
77
|
+
* - HH: 2-digit hour 24h (00-23)
|
|
78
|
+
* - H: hour 24h (0-23)
|
|
79
|
+
* - hh: 2-digit hour 12h (01-12)
|
|
80
|
+
* - h: hour 12h (1-12)
|
|
81
|
+
* - mm: 2-digit minutes (00-59)
|
|
82
|
+
* - m: minutes (0-59)
|
|
83
|
+
* - ss: 2-digit seconds (00-59)
|
|
84
|
+
* - s: seconds (0-59)
|
|
85
|
+
* - SSS: milliseconds (000-999)
|
|
86
|
+
* - a: AM/PM
|
|
87
|
+
* - EEEE: full weekday name (Monday)
|
|
88
|
+
* - EEE: short weekday name (Mon)
|
|
89
|
+
* - MMMM: full month name (January)
|
|
90
|
+
* - MMM: short month name (Jan)
|
|
91
|
+
*/
|
|
92
|
+
const WEEKDAYS_SHORT = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];
|
|
93
|
+
const WEEKDAYS_LONG = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'];
|
|
94
|
+
const MONTHS_SHORT = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
|
|
95
|
+
const MONTHS_LONG = [
|
|
96
|
+
'January',
|
|
97
|
+
'February',
|
|
98
|
+
'March',
|
|
99
|
+
'April',
|
|
100
|
+
'May',
|
|
101
|
+
'June',
|
|
102
|
+
'July',
|
|
103
|
+
'August',
|
|
104
|
+
'September',
|
|
105
|
+
'October',
|
|
106
|
+
'November',
|
|
107
|
+
'December',
|
|
108
|
+
];
|
|
109
|
+
/**
|
|
110
|
+
* Escapes special regex characters in a string
|
|
111
|
+
*/
|
|
112
|
+
function escapeRegExp(str) {
|
|
113
|
+
return str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Pads a number with leading zeros
|
|
117
|
+
*/
|
|
118
|
+
function padStart(value, length) {
|
|
119
|
+
return String(value).padStart(length, '0');
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Checks if a value is a valid Date object
|
|
123
|
+
*/
|
|
124
|
+
function isDate(value) {
|
|
125
|
+
return value instanceof Date && !isNaN(value.getTime());
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Formats a Date object according to the specified format string
|
|
129
|
+
*
|
|
130
|
+
* @param date - The date to format
|
|
131
|
+
* @param formatStr - The format string (e.g., 'dd.MM.yyyy', 'yyyy-MM-dd HH:mm:ss')
|
|
132
|
+
* @returns Formatted date string
|
|
133
|
+
*
|
|
134
|
+
* @example
|
|
135
|
+
* formatDate(new Date(2024, 0, 15), 'dd.MM.yyyy') // '15.01.2024'
|
|
136
|
+
* formatDate(new Date(2024, 0, 15, 14, 30), 'yyyy-MM-dd HH:mm') // '2024-01-15 14:30'
|
|
137
|
+
*/
|
|
138
|
+
function formatDate(date, formatStr) {
|
|
139
|
+
if (!isDate(date)) {
|
|
140
|
+
return '';
|
|
141
|
+
}
|
|
142
|
+
const year = date.getFullYear();
|
|
143
|
+
const month = date.getMonth();
|
|
144
|
+
const day = date.getDate();
|
|
145
|
+
const hours = date.getHours();
|
|
146
|
+
const minutes = date.getMinutes();
|
|
147
|
+
const seconds = date.getSeconds();
|
|
148
|
+
const milliseconds = date.getMilliseconds();
|
|
149
|
+
const dayOfWeek = date.getDay();
|
|
150
|
+
const hours12 = hours % 12 || 12;
|
|
151
|
+
const ampm = hours < 12 ? 'AM' : 'PM';
|
|
152
|
+
// Use placeholders to avoid partial replacements
|
|
153
|
+
const placeholders = new Map();
|
|
154
|
+
let placeholderIndex = 0;
|
|
155
|
+
const createPlaceholder = (value) => {
|
|
156
|
+
const placeholder = `\x00${placeholderIndex++}\x00`;
|
|
157
|
+
placeholders.set(placeholder, value);
|
|
158
|
+
return placeholder;
|
|
159
|
+
};
|
|
160
|
+
// Order matters: longer tokens must be replaced first
|
|
161
|
+
// Use exact token matching to prevent partial replacements
|
|
162
|
+
let result = formatStr;
|
|
163
|
+
// Replace tokens with placeholders (longest first)
|
|
164
|
+
result = result.replace(/yyyy/g, createPlaceholder(String(year)));
|
|
165
|
+
result = result.replace(/yy/g, createPlaceholder(String(year).slice(-2)));
|
|
166
|
+
result = result.replace(/MMMM/g, createPlaceholder(MONTHS_LONG[month]));
|
|
167
|
+
result = result.replace(/MMM/g, createPlaceholder(MONTHS_SHORT[month]));
|
|
168
|
+
result = result.replace(/MM/g, createPlaceholder(padStart(month + 1, 2)));
|
|
169
|
+
result = result.replace(/M/g, createPlaceholder(String(month + 1)));
|
|
170
|
+
result = result.replace(/EEEE/g, createPlaceholder(WEEKDAYS_LONG[dayOfWeek]));
|
|
171
|
+
result = result.replace(/EEE/g, createPlaceholder(WEEKDAYS_SHORT[dayOfWeek]));
|
|
172
|
+
result = result.replace(/dd/g, createPlaceholder(padStart(day, 2)));
|
|
173
|
+
result = result.replace(/d/g, createPlaceholder(String(day)));
|
|
174
|
+
result = result.replace(/HH/g, createPlaceholder(padStart(hours, 2)));
|
|
175
|
+
result = result.replace(/H/g, createPlaceholder(String(hours)));
|
|
176
|
+
result = result.replace(/hh/g, createPlaceholder(padStart(hours12, 2)));
|
|
177
|
+
result = result.replace(/h/g, createPlaceholder(String(hours12)));
|
|
178
|
+
result = result.replace(/mm/g, createPlaceholder(padStart(minutes, 2)));
|
|
179
|
+
result = result.replace(/m/g, createPlaceholder(String(minutes)));
|
|
180
|
+
result = result.replace(/SSS/g, createPlaceholder(padStart(milliseconds, 3)));
|
|
181
|
+
result = result.replace(/ss/g, createPlaceholder(padStart(seconds, 2)));
|
|
182
|
+
result = result.replace(/s/g, createPlaceholder(String(seconds)));
|
|
183
|
+
result = result.replace(/a/g, createPlaceholder(ampm));
|
|
184
|
+
// Replace placeholders with actual values
|
|
185
|
+
for (const [placeholder, value] of placeholders) {
|
|
186
|
+
result = result.replace(placeholder, value);
|
|
187
|
+
}
|
|
188
|
+
return result;
|
|
189
|
+
}
|
|
190
|
+
/**
|
|
191
|
+
* Parses an ISO 8601 date string into a Date object
|
|
192
|
+
*
|
|
193
|
+
* @param dateString - ISO date string (e.g., '2024-01-15', '2024-01-15T14:30:00.000Z')
|
|
194
|
+
* @returns Date object or Invalid Date if parsing fails
|
|
195
|
+
*
|
|
196
|
+
* @example
|
|
197
|
+
* parseISO('2024-01-15') // Date object for Jan 15, 2024
|
|
198
|
+
* parseISO('2024-01-15T14:30:00.000Z') // Date object with time
|
|
199
|
+
*/
|
|
200
|
+
function parseISO(dateString) {
|
|
201
|
+
if (!dateString || typeof dateString !== 'string') {
|
|
202
|
+
return new Date(NaN);
|
|
203
|
+
}
|
|
204
|
+
const date = new Date(dateString);
|
|
205
|
+
return date;
|
|
206
|
+
}
|
|
207
|
+
/**
|
|
208
|
+
* Parses a date string according to the specified format
|
|
209
|
+
*
|
|
210
|
+
* @param dateString - The date string to parse
|
|
211
|
+
* @param formatStr - The format string describing the input
|
|
212
|
+
* @param referenceDate - Reference date for missing parts (defaults to current date)
|
|
213
|
+
* @returns Date object or Invalid Date if parsing fails
|
|
214
|
+
*
|
|
215
|
+
* @example
|
|
216
|
+
* parseDate('15.01.2024', 'dd.MM.yyyy') // Date object for Jan 15, 2024
|
|
217
|
+
* parseDate('2024/01/15 14:30', 'yyyy/MM/dd HH:mm') // Date with time
|
|
218
|
+
*/
|
|
219
|
+
function parseDate(dateString, formatStr, referenceDate = new Date()) {
|
|
220
|
+
if (!dateString || typeof dateString !== 'string') {
|
|
221
|
+
return new Date(NaN);
|
|
222
|
+
}
|
|
223
|
+
let year = referenceDate.getFullYear();
|
|
224
|
+
let month = referenceDate.getMonth();
|
|
225
|
+
let day = referenceDate.getDate();
|
|
226
|
+
let hours = 0;
|
|
227
|
+
let minutes = 0;
|
|
228
|
+
let seconds = 0;
|
|
229
|
+
let milliseconds = 0;
|
|
230
|
+
let isPM = false;
|
|
231
|
+
let hasAMPM = false;
|
|
232
|
+
const tokenPatterns = [
|
|
233
|
+
{
|
|
234
|
+
token: 'yyyy',
|
|
235
|
+
pattern: '(\\d{4})',
|
|
236
|
+
handler: (val) => {
|
|
237
|
+
year = parseInt(val, 10);
|
|
238
|
+
},
|
|
239
|
+
},
|
|
240
|
+
{
|
|
241
|
+
token: 'yy',
|
|
242
|
+
pattern: '(\\d{2})',
|
|
243
|
+
handler: (val) => {
|
|
244
|
+
const parsed = parseInt(val, 10);
|
|
245
|
+
year = parsed >= 70 ? 1900 + parsed : 2000 + parsed;
|
|
246
|
+
},
|
|
247
|
+
},
|
|
248
|
+
{
|
|
249
|
+
token: 'MMMM',
|
|
250
|
+
pattern: `(${MONTHS_LONG.join('|')})`,
|
|
251
|
+
handler: (val) => {
|
|
252
|
+
month = MONTHS_LONG.findIndex((m) => m.toLowerCase() === val.toLowerCase());
|
|
253
|
+
},
|
|
254
|
+
},
|
|
255
|
+
{
|
|
256
|
+
token: 'MMM',
|
|
257
|
+
pattern: `(${MONTHS_SHORT.join('|')})`,
|
|
258
|
+
handler: (val) => {
|
|
259
|
+
month = MONTHS_SHORT.findIndex((m) => m.toLowerCase() === val.toLowerCase());
|
|
260
|
+
},
|
|
261
|
+
},
|
|
262
|
+
{
|
|
263
|
+
token: 'MM',
|
|
264
|
+
pattern: '(\\d{2})',
|
|
265
|
+
handler: (val) => {
|
|
266
|
+
month = parseInt(val, 10) - 1;
|
|
267
|
+
},
|
|
268
|
+
},
|
|
269
|
+
{
|
|
270
|
+
token: 'M',
|
|
271
|
+
pattern: '(\\d{1,2})',
|
|
272
|
+
handler: (val) => {
|
|
273
|
+
month = parseInt(val, 10) - 1;
|
|
274
|
+
},
|
|
275
|
+
},
|
|
276
|
+
{
|
|
277
|
+
token: 'dd',
|
|
278
|
+
pattern: '(\\d{2})',
|
|
279
|
+
handler: (val) => {
|
|
280
|
+
day = parseInt(val, 10);
|
|
281
|
+
},
|
|
282
|
+
},
|
|
283
|
+
{
|
|
284
|
+
token: 'd',
|
|
285
|
+
pattern: '(\\d{1,2})',
|
|
286
|
+
handler: (val) => {
|
|
287
|
+
day = parseInt(val, 10);
|
|
288
|
+
},
|
|
289
|
+
},
|
|
290
|
+
{
|
|
291
|
+
token: 'HH',
|
|
292
|
+
pattern: '(\\d{2})',
|
|
293
|
+
handler: (val) => {
|
|
294
|
+
hours = parseInt(val, 10);
|
|
295
|
+
},
|
|
296
|
+
},
|
|
297
|
+
{
|
|
298
|
+
token: 'H',
|
|
299
|
+
pattern: '(\\d{1,2})',
|
|
300
|
+
handler: (val) => {
|
|
301
|
+
hours = parseInt(val, 10);
|
|
302
|
+
},
|
|
303
|
+
},
|
|
304
|
+
{
|
|
305
|
+
token: 'hh',
|
|
306
|
+
pattern: '(\\d{2})',
|
|
307
|
+
handler: (val) => {
|
|
308
|
+
hours = parseInt(val, 10);
|
|
309
|
+
},
|
|
310
|
+
},
|
|
311
|
+
{
|
|
312
|
+
token: 'h',
|
|
313
|
+
pattern: '(\\d{1,2})',
|
|
314
|
+
handler: (val) => {
|
|
315
|
+
hours = parseInt(val, 10);
|
|
316
|
+
},
|
|
317
|
+
},
|
|
318
|
+
{
|
|
319
|
+
token: 'mm',
|
|
320
|
+
pattern: '(\\d{2})',
|
|
321
|
+
handler: (val) => {
|
|
322
|
+
minutes = parseInt(val, 10);
|
|
323
|
+
},
|
|
324
|
+
},
|
|
325
|
+
{
|
|
326
|
+
token: 'm',
|
|
327
|
+
pattern: '(\\d{1,2})',
|
|
328
|
+
handler: (val) => {
|
|
329
|
+
minutes = parseInt(val, 10);
|
|
330
|
+
},
|
|
331
|
+
},
|
|
332
|
+
{
|
|
333
|
+
token: 'SSS',
|
|
334
|
+
pattern: '(\\d{3})',
|
|
335
|
+
handler: (val) => {
|
|
336
|
+
milliseconds = parseInt(val, 10);
|
|
337
|
+
},
|
|
338
|
+
},
|
|
339
|
+
{
|
|
340
|
+
token: 'ss',
|
|
341
|
+
pattern: '(\\d{2})',
|
|
342
|
+
handler: (val) => {
|
|
343
|
+
seconds = parseInt(val, 10);
|
|
344
|
+
},
|
|
345
|
+
},
|
|
346
|
+
{
|
|
347
|
+
token: 's',
|
|
348
|
+
pattern: '(\\d{1,2})',
|
|
349
|
+
handler: (val) => {
|
|
350
|
+
seconds = parseInt(val, 10);
|
|
351
|
+
},
|
|
352
|
+
},
|
|
353
|
+
{
|
|
354
|
+
token: 'a',
|
|
355
|
+
pattern: '(AM|PM|am|pm)',
|
|
356
|
+
handler: (val) => {
|
|
357
|
+
hasAMPM = true;
|
|
358
|
+
isPM = val.toUpperCase() === 'PM';
|
|
359
|
+
},
|
|
360
|
+
},
|
|
361
|
+
];
|
|
362
|
+
// Sort by token length (longer first) to avoid partial matches
|
|
363
|
+
const sortedPatterns = [...tokenPatterns].sort((a, b) => b.token.length - a.token.length);
|
|
364
|
+
// Build regex from format string using placeholders to avoid double-replacement
|
|
365
|
+
// First, replace all tokens in the original format string with placeholders
|
|
366
|
+
let workingFormat = formatStr;
|
|
367
|
+
const placeholderList = [];
|
|
368
|
+
let placeholderIndex = 0;
|
|
369
|
+
for (const { token, pattern, handler } of sortedPatterns) {
|
|
370
|
+
if (workingFormat.includes(token)) {
|
|
371
|
+
const placeholder = `\x00${placeholderIndex++}\x00`;
|
|
372
|
+
workingFormat = workingFormat.split(token).join(placeholder);
|
|
373
|
+
placeholderList.push({ placeholder, pattern, handler });
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
// Now escape the remaining literal characters
|
|
377
|
+
let regexStr = escapeRegExp(workingFormat);
|
|
378
|
+
// Replace placeholders with actual regex patterns
|
|
379
|
+
for (const { placeholder, pattern } of placeholderList) {
|
|
380
|
+
regexStr = regexStr.replace(escapeRegExp(placeholder), pattern);
|
|
381
|
+
}
|
|
382
|
+
// Sort handlers by their placeholder position in the original working format
|
|
383
|
+
// to match capture group order (left-to-right in the regex)
|
|
384
|
+
const sortedByPosition = placeholderList
|
|
385
|
+
.map((item) => ({
|
|
386
|
+
placeholder: item.placeholder,
|
|
387
|
+
handler: item.handler,
|
|
388
|
+
position: escapeRegExp(workingFormat).indexOf(escapeRegExp(item.placeholder)),
|
|
389
|
+
}))
|
|
390
|
+
.sort((a, b) => a.position - b.position);
|
|
391
|
+
const handlers = sortedByPosition.map((item) => item.handler);
|
|
392
|
+
const regex = new RegExp(`^${regexStr}$`, 'i');
|
|
393
|
+
const match = dateString.match(regex);
|
|
394
|
+
if (!match) {
|
|
395
|
+
return new Date(NaN);
|
|
396
|
+
}
|
|
397
|
+
// Apply handlers in order
|
|
398
|
+
for (let i = 0; i < handlers.length; i++) {
|
|
399
|
+
if (match[i + 1]) {
|
|
400
|
+
handlers[i](match[i + 1]);
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
// Apply AM/PM adjustment after all handlers
|
|
404
|
+
if (hasAMPM) {
|
|
405
|
+
if (isPM && hours < 12) {
|
|
406
|
+
hours += 12;
|
|
407
|
+
}
|
|
408
|
+
else if (!isPM && hours === 12) {
|
|
409
|
+
hours = 0;
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
return new Date(year, month, day, hours, minutes, seconds, milliseconds);
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
const MAX_YEAR = 3000;
|
|
416
|
+
function dateStringToDate(date) {
|
|
417
|
+
if (date instanceof Date) {
|
|
418
|
+
return date;
|
|
419
|
+
}
|
|
420
|
+
const firstItem = 1;
|
|
421
|
+
const parsedDate = (date || '')
|
|
422
|
+
.replace(/^(\d)/, '0$1')
|
|
423
|
+
.replace(/\.(\d)\./, '.0$1.')
|
|
424
|
+
.replace('..', '.01.')
|
|
425
|
+
.replace(/^\./, '01.')
|
|
426
|
+
.replace(/(\d{3})\./g, (str) => str.slice(firstItem))
|
|
427
|
+
.replace(/(\d{2}).(\d{2}).(\d{4})/, '$2/$1/$3')
|
|
428
|
+
.replace(/00\//g, '01/');
|
|
429
|
+
const dateValue = new Date(parsedDate);
|
|
430
|
+
if (dateValue.getFullYear() > MAX_YEAR) {
|
|
431
|
+
return new Date();
|
|
432
|
+
}
|
|
433
|
+
return isNaN(dateValue.getTime()) ? new Date() : dateValue;
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
function isDateValid(date) {
|
|
437
|
+
return date instanceof Date && Boolean(date.getTime());
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
/**
|
|
441
|
+
* Indicates if the arguments are equal
|
|
442
|
+
*
|
|
443
|
+
* @param f first parameter to compare
|
|
444
|
+
* @param s second parameter to compare
|
|
445
|
+
*/
|
|
446
|
+
function isEqual(f, s) {
|
|
447
|
+
const s1 = JSON.stringify(f).split('').sort().join('');
|
|
448
|
+
const s2 = JSON.stringify(s).split('').sort().join('');
|
|
449
|
+
return s1 === s2;
|
|
450
|
+
}
|
|
451
|
+
/**
|
|
452
|
+
* Indicates if the content of two arrays is identical
|
|
453
|
+
*
|
|
454
|
+
* @param f first array
|
|
455
|
+
* @param s second array
|
|
456
|
+
*/
|
|
457
|
+
function areArraysEqual(f, s) {
|
|
458
|
+
if (!Array.isArray(f) || !Array.isArray(s)) {
|
|
459
|
+
return false;
|
|
460
|
+
}
|
|
461
|
+
if (f.length !== s.length) {
|
|
462
|
+
return false;
|
|
463
|
+
}
|
|
464
|
+
for (let i = 0; i < f.length; i++) {
|
|
465
|
+
const valueF = f[i];
|
|
466
|
+
const valueS = s[i];
|
|
467
|
+
if (Array.isArray(valueF) && Array.isArray(valueS)) {
|
|
468
|
+
if (!areArraysEqual(valueF, valueS)) {
|
|
469
|
+
return false;
|
|
470
|
+
}
|
|
471
|
+
}
|
|
472
|
+
if (typeof valueF === 'object' && valueF != null && typeof valueS === 'object' && valueS != null) {
|
|
473
|
+
// eslint-disable-next-line @typescript-eslint/no-use-before-define
|
|
474
|
+
if (!areObjectsEqual(valueF, valueS)) {
|
|
475
|
+
return false;
|
|
476
|
+
}
|
|
477
|
+
}
|
|
478
|
+
else if (valueF !== valueS) {
|
|
479
|
+
return false;
|
|
480
|
+
}
|
|
481
|
+
}
|
|
482
|
+
return true;
|
|
483
|
+
}
|
|
484
|
+
/**
|
|
485
|
+
* Indicates if the content of two objects is identical
|
|
486
|
+
*
|
|
487
|
+
* @param f first object
|
|
488
|
+
* @param s second object
|
|
489
|
+
*/
|
|
490
|
+
function areObjectsEqual(f, s) {
|
|
491
|
+
/** If it's just the same object - no need to compare */
|
|
492
|
+
if (f === s) {
|
|
493
|
+
return true;
|
|
494
|
+
}
|
|
495
|
+
if (Array.isArray(f) && Array.isArray(s)) {
|
|
496
|
+
return areArraysEqual(f, s);
|
|
497
|
+
}
|
|
498
|
+
/** If one of the objects is null or undefined - no need to compare */
|
|
499
|
+
if (typeof f === 'object' && f != null && typeof s === 'object' && s != null) {
|
|
500
|
+
const keysF = Object.keys(f);
|
|
501
|
+
const keysS = Object.keys(s);
|
|
502
|
+
if (keysF.length != keysS.length) {
|
|
503
|
+
return false;
|
|
504
|
+
}
|
|
505
|
+
for (const key in f) {
|
|
506
|
+
if (!areObjectsEqual(f[key], s[key])) {
|
|
507
|
+
return false;
|
|
508
|
+
}
|
|
509
|
+
}
|
|
510
|
+
return true;
|
|
511
|
+
}
|
|
512
|
+
return false;
|
|
513
|
+
}
|
|
514
|
+
/**
|
|
515
|
+
* Checks whether two arrays are equal regardless of the order of their elements.
|
|
516
|
+
* Supports deep comparison of nested arrays and objects.
|
|
517
|
+
*
|
|
518
|
+
* @template T The type of elements in the arrays
|
|
519
|
+
* @param f first array
|
|
520
|
+
* @param s second array
|
|
521
|
+
* @returns True if the arrays contain the same elements in any order, false otherwise
|
|
522
|
+
*/
|
|
523
|
+
function areArraysEqualUnordered(f, s) {
|
|
524
|
+
if (!Array.isArray(f) || !Array.isArray(s)) {
|
|
525
|
+
return false;
|
|
526
|
+
}
|
|
527
|
+
if (f.length !== s.length) {
|
|
528
|
+
return false;
|
|
529
|
+
}
|
|
530
|
+
const used = new Array(s.length).fill(false);
|
|
531
|
+
for (const valueF of f) {
|
|
532
|
+
let found = false;
|
|
533
|
+
for (let i = 0; i < s.length; i++) {
|
|
534
|
+
if (used[i]) {
|
|
535
|
+
continue;
|
|
536
|
+
}
|
|
537
|
+
const valueS = s[i];
|
|
538
|
+
if (Array.isArray(valueF) && Array.isArray(valueS)) {
|
|
539
|
+
if (areArraysEqualUnordered(valueF, valueS)) {
|
|
540
|
+
used[i] = true;
|
|
541
|
+
found = true;
|
|
542
|
+
break;
|
|
543
|
+
}
|
|
544
|
+
}
|
|
545
|
+
else if (typeof valueF === 'object' && valueF != null && typeof valueS === 'object' && valueS != null) {
|
|
546
|
+
if (areObjectsEqual(valueF, valueS)) {
|
|
547
|
+
used[i] = true;
|
|
548
|
+
found = true;
|
|
549
|
+
break;
|
|
550
|
+
}
|
|
551
|
+
}
|
|
552
|
+
else if (valueF === valueS) {
|
|
553
|
+
used[i] = true;
|
|
554
|
+
found = true;
|
|
555
|
+
break;
|
|
556
|
+
}
|
|
557
|
+
}
|
|
558
|
+
if (!found) {
|
|
559
|
+
return false;
|
|
560
|
+
}
|
|
561
|
+
}
|
|
562
|
+
return true;
|
|
563
|
+
}
|
|
564
|
+
|
|
565
|
+
function isNumber(value) {
|
|
566
|
+
return typeof value === 'number';
|
|
567
|
+
}
|
|
568
|
+
|
|
569
|
+
function isRecord(value) {
|
|
570
|
+
return value?.constructor === Object;
|
|
571
|
+
}
|
|
572
|
+
|
|
573
|
+
function isString(value) {
|
|
574
|
+
return typeof value === 'string';
|
|
575
|
+
}
|
|
576
|
+
|
|
577
|
+
function initToday() {
|
|
578
|
+
const today = new Date();
|
|
579
|
+
today.setHours(0, 0, 0, 0);
|
|
580
|
+
return today;
|
|
581
|
+
}
|
|
582
|
+
function isToday(date) {
|
|
583
|
+
const today = initToday();
|
|
584
|
+
return date.getDate() === today.getDate() && date.getMonth() === today.getMonth() && date.getFullYear() === today.getFullYear();
|
|
585
|
+
}
|
|
586
|
+
|
|
587
|
+
/** Makes shallow copy of passed object */
|
|
588
|
+
function removeFieldFromObject(obj, key) {
|
|
589
|
+
const result = { ...obj };
|
|
590
|
+
if (key in obj) {
|
|
591
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
592
|
+
delete result[key];
|
|
593
|
+
}
|
|
594
|
+
return result;
|
|
595
|
+
}
|
|
596
|
+
|
|
597
|
+
/**
|
|
598
|
+
* Allow to compare two values by provided comparator
|
|
599
|
+
*
|
|
600
|
+
* @param a - T
|
|
601
|
+
* @param b - T
|
|
602
|
+
* @param comparator - ComparatorType<T>
|
|
603
|
+
*/
|
|
604
|
+
function safeCompare(a, b, comparator) {
|
|
605
|
+
if (a == null) {
|
|
606
|
+
if (b == null) {
|
|
607
|
+
return 0;
|
|
608
|
+
}
|
|
609
|
+
else {
|
|
610
|
+
return 1;
|
|
611
|
+
}
|
|
612
|
+
}
|
|
613
|
+
else {
|
|
614
|
+
if (b == null) {
|
|
615
|
+
return -1;
|
|
616
|
+
}
|
|
617
|
+
else {
|
|
618
|
+
return comparator(a, b);
|
|
619
|
+
}
|
|
620
|
+
}
|
|
621
|
+
}
|
|
622
|
+
/**
|
|
623
|
+
* Allow to safely compare two string values
|
|
624
|
+
*
|
|
625
|
+
* @param a string
|
|
626
|
+
* @param b string
|
|
627
|
+
*/
|
|
628
|
+
function safeStrCompare(a, b) {
|
|
629
|
+
return safeCompare(a, b, () => a.localeCompare(b));
|
|
630
|
+
}
|
|
631
|
+
/**
|
|
632
|
+
* Allow to safely compare two number values
|
|
633
|
+
*
|
|
634
|
+
* @param a number
|
|
635
|
+
* @param b number
|
|
636
|
+
*/
|
|
637
|
+
function safeNumCompare(a, b) {
|
|
638
|
+
return safeCompare(a, b, () => a - b);
|
|
639
|
+
}
|
|
640
|
+
/**
|
|
641
|
+
* Allow composing comparison chain of several comparators
|
|
642
|
+
* that delegate comparison by the chain to the next comparators if current comparator returns 0
|
|
643
|
+
*
|
|
644
|
+
* @param comparators - Array<() => number>
|
|
645
|
+
*/
|
|
646
|
+
function safeComparatorPipe(...comparators) {
|
|
647
|
+
let result = 0;
|
|
648
|
+
for (let i = 0, len = comparators.length; i < len; i++) {
|
|
649
|
+
result = comparators[i]();
|
|
650
|
+
if (result !== 0) {
|
|
651
|
+
break;
|
|
652
|
+
}
|
|
653
|
+
}
|
|
654
|
+
return result;
|
|
655
|
+
}
|
|
656
|
+
|
|
657
|
+
const sortByAlphabet = (a, b, field) => {
|
|
658
|
+
if (a[field] && typeof a[field] === 'string' && b[field] && typeof b[field] === 'string') {
|
|
659
|
+
if (a[field].toLowerCase() < b[field].toLowerCase()) {
|
|
660
|
+
return -1;
|
|
661
|
+
}
|
|
662
|
+
if (a[field].toLowerCase() > b[field].toLowerCase()) {
|
|
663
|
+
return 1;
|
|
664
|
+
}
|
|
665
|
+
}
|
|
666
|
+
return 0;
|
|
667
|
+
};
|
|
668
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
669
|
+
const sortByDate = (
|
|
670
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
671
|
+
a,
|
|
672
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
673
|
+
b, field) => new Date(a[field]).getTime() - new Date(b[field]).getTime();
|
|
674
|
+
|
|
675
|
+
function stringifyHttpLikeParams(params) {
|
|
676
|
+
return Object.keys(params).reduce((stringParams, key) => ({
|
|
677
|
+
...stringParams,
|
|
678
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
679
|
+
[key]: encodeURI(params[key]),
|
|
680
|
+
}), {});
|
|
681
|
+
}
|
|
682
|
+
|
|
683
|
+
function transformArrayInput(array) {
|
|
684
|
+
if (Array.isArray(array) && array.length) {
|
|
685
|
+
return array;
|
|
686
|
+
}
|
|
687
|
+
else {
|
|
688
|
+
return [];
|
|
689
|
+
}
|
|
690
|
+
}
|
|
691
|
+
|
|
692
|
+
function transformStringInput(value) {
|
|
693
|
+
return isString(value) ? value : '';
|
|
694
|
+
}
|
|
695
|
+
|
|
696
|
+
function checkIsEntityInArrayByKey(selectedEntities, entity, keyExp) {
|
|
697
|
+
return !!selectedEntities.find((selectedEntity) => {
|
|
698
|
+
return (Object.prototype.hasOwnProperty.call(selectedEntity, keyExp) &&
|
|
699
|
+
Object.prototype.hasOwnProperty.call(entity, keyExp) &&
|
|
700
|
+
selectedEntity[keyExp] === entity[keyExp]);
|
|
701
|
+
});
|
|
702
|
+
}
|
|
703
|
+
|
|
704
|
+
function emptyToDash(value) {
|
|
705
|
+
return isNil(value) || value === '' ? DASH : value;
|
|
706
|
+
}
|
|
707
|
+
|
|
708
|
+
/**
|
|
709
|
+
* Check if the email is valid
|
|
710
|
+
* @param email
|
|
711
|
+
*/
|
|
712
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
713
|
+
function isEmail(email) {
|
|
714
|
+
return !Boolean(Validators.email(new FormControl(email)));
|
|
715
|
+
}
|
|
716
|
+
|
|
717
|
+
function isEmptyArray(value) {
|
|
718
|
+
return value.length === 0;
|
|
719
|
+
}
|
|
720
|
+
|
|
721
|
+
function isEmptyObject(value) {
|
|
722
|
+
return isEmptyArray(Object.keys(value));
|
|
723
|
+
}
|
|
724
|
+
|
|
725
|
+
function isEmptyString(value) {
|
|
726
|
+
return value.length === 0;
|
|
727
|
+
}
|
|
728
|
+
|
|
729
|
+
function isObject(value) {
|
|
730
|
+
return typeof value === 'object';
|
|
731
|
+
}
|
|
732
|
+
|
|
733
|
+
function isEmpty(value) {
|
|
734
|
+
if (isNil(value)) {
|
|
735
|
+
return true;
|
|
736
|
+
}
|
|
737
|
+
if (isObject(value)) {
|
|
738
|
+
if (Array.isArray(value)) {
|
|
739
|
+
return isEmptyArray(value);
|
|
740
|
+
}
|
|
741
|
+
if (!(value instanceof Date)) {
|
|
742
|
+
return isEmptyObject(value);
|
|
743
|
+
}
|
|
744
|
+
}
|
|
745
|
+
if (isString(value)) {
|
|
746
|
+
return isEmptyString(value);
|
|
747
|
+
}
|
|
748
|
+
return false;
|
|
749
|
+
}
|
|
750
|
+
|
|
751
|
+
function debounce(timeout = 300) {
|
|
752
|
+
return function (_target, _key, descriptor) {
|
|
753
|
+
const timeoutRefs = new WeakMap();
|
|
754
|
+
const { value } = descriptor;
|
|
755
|
+
descriptor.value = function (...args) {
|
|
756
|
+
const timeoutRef = timeoutRefs.get(this);
|
|
757
|
+
if (timeoutRef !== undefined) {
|
|
758
|
+
clearTimeout(timeoutRef);
|
|
759
|
+
}
|
|
760
|
+
timeoutRefs.set(this, setTimeout(() => value.apply(this, args), timeout));
|
|
761
|
+
};
|
|
762
|
+
return descriptor;
|
|
763
|
+
};
|
|
764
|
+
}
|
|
765
|
+
|
|
766
|
+
var HAS_OWN_SCOPE_ENUM;
|
|
767
|
+
(function (HAS_OWN_SCOPE_ENUM) {
|
|
768
|
+
HAS_OWN_SCOPE_ENUM["ANY"] = "any";
|
|
769
|
+
HAS_OWN_SCOPE_ENUM["OWN"] = "own";
|
|
770
|
+
HAS_OWN_SCOPE_ENUM["INHERITED"] = "inherited";
|
|
771
|
+
})(HAS_OWN_SCOPE_ENUM || (HAS_OWN_SCOPE_ENUM = {}));
|
|
772
|
+
const safetyHasOwn = (o, k) => {
|
|
773
|
+
const native = Object.hasOwn;
|
|
774
|
+
return typeof native === 'function' ? native(o, k) : Object.prototype.hasOwnProperty.call(o, k);
|
|
775
|
+
};
|
|
776
|
+
/**
|
|
777
|
+
* Safe property existence check with configurable scope.
|
|
778
|
+
*
|
|
779
|
+
* - Returns `false` for `null`/`undefined`.
|
|
780
|
+
* - Boxes primitives (e.g., strings, numbers) so prototype checks work.
|
|
781
|
+
* - Does **not** invoke getters; relies on `in` and an own-check helper.
|
|
782
|
+
* - Uses `Object.hasOwn` when available; **falls back** to
|
|
783
|
+
* `Object.prototype.hasOwnProperty.call` on older runtimes.
|
|
784
|
+
*
|
|
785
|
+
* @param obj {unknown} - Value to check. `null`/`undefined` short-circuit to `false`.
|
|
786
|
+
* @param key {PropertyKey} - Property key (string | number | symbol).
|
|
787
|
+
* @param scope {IHasScopeType} - Check mode: `'any'` (default), `'own'`, or `'inherited'`.
|
|
788
|
+
*
|
|
789
|
+
* @returns `true` if the property exists under the selected scope.
|
|
790
|
+
*
|
|
791
|
+
* @example
|
|
792
|
+
* hasPropertyInChain({ a: 1 }, 'a'); // true (ANY)
|
|
793
|
+
* hasPropertyInChain(Object.create({ a: 1 }), 'a', HAS_OWN_SCOPE_ENUM.INHERITED); // true
|
|
794
|
+
* hasPropertyInChain({ a: 1 }, 'b', HAS_OWN_SCOPE_ENUM.OWN); // false
|
|
795
|
+
*/
|
|
796
|
+
function hasPropertyInChain(obj, key, scope = HAS_OWN_SCOPE_ENUM.OWN) {
|
|
797
|
+
if (obj === undefined || obj === null) {
|
|
798
|
+
return false;
|
|
799
|
+
}
|
|
800
|
+
const o = Object(obj);
|
|
801
|
+
switch (scope) {
|
|
802
|
+
case HAS_OWN_SCOPE_ENUM.OWN:
|
|
803
|
+
return safetyHasOwn(o, key);
|
|
804
|
+
case HAS_OWN_SCOPE_ENUM.INHERITED:
|
|
805
|
+
return key in o && !safetyHasOwn(o, key);
|
|
806
|
+
default:
|
|
807
|
+
return key in o;
|
|
808
|
+
}
|
|
809
|
+
}
|
|
810
|
+
|
|
811
|
+
class RtScrollToElementDirective {
|
|
812
|
+
constructor() {
|
|
813
|
+
this.rtScrollToElement = input.required({ ...(ngDevMode ? { debugName: "rtScrollToElement" } : {}) });
|
|
814
|
+
this.elements = input.required({ ...(ngDevMode ? { debugName: "elements" } : {}), transform: (value) => transformArrayInput(value) });
|
|
815
|
+
effect(() => {
|
|
816
|
+
if (this.elements()?.length && this.rtScrollToElement()) {
|
|
817
|
+
this.#scrollToTarget();
|
|
818
|
+
}
|
|
819
|
+
});
|
|
820
|
+
}
|
|
821
|
+
#scrollToTarget() {
|
|
822
|
+
const targetId = this.rtScrollToElement();
|
|
823
|
+
const targetElement = document.getElementById(targetId.toString());
|
|
824
|
+
targetElement?.scrollIntoView({ behavior: 'smooth', block: 'start' });
|
|
825
|
+
}
|
|
826
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.1", ngImport: i0, type: RtScrollToElementDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
827
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.0.1", type: RtScrollToElementDirective, isStandalone: true, selector: "[rtScrollToElement]", inputs: { rtScrollToElement: { classPropertyName: "rtScrollToElement", publicName: "rtScrollToElement", isSignal: true, isRequired: true, transformFunction: null }, elements: { classPropertyName: "elements", publicName: "elements", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0 }); }
|
|
828
|
+
}
|
|
829
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.1", ngImport: i0, type: RtScrollToElementDirective, decorators: [{
|
|
830
|
+
type: Directive,
|
|
831
|
+
args: [{
|
|
832
|
+
selector: '[rtScrollToElement]',
|
|
833
|
+
}]
|
|
834
|
+
}], ctorParameters: () => [], propDecorators: { rtScrollToElement: [{ type: i0.Input, args: [{ isSignal: true, alias: "rtScrollToElement", required: true }] }], elements: [{ type: i0.Input, args: [{ isSignal: true, alias: "elements", required: true }] }] } });
|
|
835
|
+
|
|
836
|
+
class RtHideTooltipDirective {
|
|
837
|
+
#matTooltip;
|
|
838
|
+
/** Set tooltip state by 'isTooltipShown' */
|
|
839
|
+
constructor() {
|
|
840
|
+
this.#matTooltip = inject(MatTooltip);
|
|
841
|
+
/** Current HTMLElement */
|
|
842
|
+
this.element = input.required({ ...(ngDevMode ? { debugName: "element" } : {}), alias: 'rtHideTooltipDirective' });
|
|
843
|
+
/** Indicates is tooltip shown */
|
|
844
|
+
this.isTooltipShown = input.required({ ...(ngDevMode ? { debugName: "isTooltipShown" } : {}), transform: booleanAttribute });
|
|
845
|
+
effect(() => {
|
|
846
|
+
if (this.isTooltipShown()) {
|
|
847
|
+
this.#setTooltipState();
|
|
848
|
+
}
|
|
849
|
+
else {
|
|
850
|
+
this.#matTooltip.disabled = true;
|
|
851
|
+
}
|
|
852
|
+
});
|
|
853
|
+
}
|
|
854
|
+
ngAfterViewInit() {
|
|
855
|
+
const element = this.element();
|
|
856
|
+
/** Set tooltip state when HTMLElement changed */
|
|
857
|
+
if (element) {
|
|
858
|
+
const observer = new MutationObserver(() => {
|
|
859
|
+
if (this.isTooltipShown()) {
|
|
860
|
+
this.#setTooltipState();
|
|
861
|
+
}
|
|
862
|
+
});
|
|
863
|
+
observer.observe(element, {
|
|
864
|
+
childList: true,
|
|
865
|
+
characterData: true,
|
|
866
|
+
subtree: true,
|
|
867
|
+
});
|
|
868
|
+
if (this.isTooltipShown()) {
|
|
869
|
+
this.#setTooltipState();
|
|
870
|
+
}
|
|
871
|
+
}
|
|
872
|
+
}
|
|
873
|
+
/** Set tooltip state by container and content width */
|
|
874
|
+
#setTooltipState() {
|
|
875
|
+
this.#matTooltip.disabled = this.element()?.offsetWidth === this.element()?.scrollWidth;
|
|
876
|
+
}
|
|
877
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.1", ngImport: i0, type: RtHideTooltipDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
878
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.0.1", type: RtHideTooltipDirective, isStandalone: true, selector: "[rtHideTooltipDirective]", inputs: { element: { classPropertyName: "element", publicName: "rtHideTooltipDirective", isSignal: true, isRequired: true, transformFunction: null }, isTooltipShown: { classPropertyName: "isTooltipShown", publicName: "isTooltipShown", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0 }); }
|
|
879
|
+
}
|
|
880
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.1", ngImport: i0, type: RtHideTooltipDirective, decorators: [{
|
|
881
|
+
type: Directive,
|
|
882
|
+
args: [{
|
|
883
|
+
selector: '[rtHideTooltipDirective]',
|
|
884
|
+
}]
|
|
885
|
+
}], ctorParameters: () => [], propDecorators: { element: [{ type: i0.Input, args: [{ isSignal: true, alias: "rtHideTooltipDirective", required: true }] }], isTooltipShown: [{ type: i0.Input, args: [{ isSignal: true, alias: "isTooltipShown", required: true }] }] } });
|
|
886
|
+
|
|
887
|
+
class AsideRef {
|
|
888
|
+
constructor(answer, overlayRef, component, position, data) {
|
|
889
|
+
this.answer = answer;
|
|
890
|
+
this.overlayRef = overlayRef;
|
|
891
|
+
this.component = component;
|
|
892
|
+
this.position = position;
|
|
893
|
+
this.data = data;
|
|
894
|
+
}
|
|
895
|
+
close(answer) {
|
|
896
|
+
this.answer.next(answer ?? null);
|
|
897
|
+
}
|
|
898
|
+
}
|
|
899
|
+
const ASIDE_REF = new InjectionToken('ASIDE_REF');
|
|
900
|
+
const ddServices = [
|
|
901
|
+
{ provide: 'ddData', useValue: undefined },
|
|
902
|
+
{ provide: 'ddAnswer', useValue: undefined },
|
|
903
|
+
{ provide: 'ddOverlay', useValue: undefined },
|
|
904
|
+
];
|
|
905
|
+
|
|
906
|
+
const NAVIGATOR = new InjectionToken('An injection token for global navigator object', {
|
|
907
|
+
factory: () => {
|
|
908
|
+
const { defaultView } = inject(DOCUMENT);
|
|
909
|
+
if (!defaultView || !defaultView?.navigator) {
|
|
910
|
+
throw new Error('Navigator is not available');
|
|
911
|
+
}
|
|
912
|
+
return defaultView.navigator;
|
|
913
|
+
},
|
|
914
|
+
});
|
|
915
|
+
|
|
916
|
+
var OSTypes;
|
|
917
|
+
(function (OSTypes) {
|
|
918
|
+
OSTypes.WINDOWS = 'Windows';
|
|
919
|
+
OSTypes.MAC_OS = 'Mac OS';
|
|
920
|
+
OSTypes.LINUX = 'Linux';
|
|
921
|
+
OSTypes.ANDROID = 'Android';
|
|
922
|
+
OSTypes.IOS = 'iOS';
|
|
923
|
+
OSTypes.UNKNOWN = 'Unknown';
|
|
924
|
+
})(OSTypes || (OSTypes = {}));
|
|
925
|
+
class DeviceDetectorService {
|
|
926
|
+
#windowRef;
|
|
927
|
+
#navigatorRef;
|
|
928
|
+
#platformService;
|
|
929
|
+
constructor() {
|
|
930
|
+
this.#windowRef = inject(WINDOW);
|
|
931
|
+
this.#navigatorRef = inject(NAVIGATOR);
|
|
932
|
+
this.#platformService = inject(PlatformService);
|
|
933
|
+
this.userAgent = null;
|
|
934
|
+
if (this.#platformService.isPlatformBrowser &&
|
|
935
|
+
typeof this.#windowRef !== 'undefined' &&
|
|
936
|
+
typeof this.#navigatorRef !== 'undefined' &&
|
|
937
|
+
this.#navigatorRef?.userAgent) {
|
|
938
|
+
this.userAgent = this.#navigatorRef.userAgent;
|
|
939
|
+
}
|
|
940
|
+
}
|
|
941
|
+
isMobile() {
|
|
942
|
+
return this.userAgent ? /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(this.userAgent) : false;
|
|
943
|
+
}
|
|
944
|
+
isTablet() {
|
|
945
|
+
return this.userAgent ? /iPad|Android|Tablet/i.test(this.userAgent) : false;
|
|
946
|
+
}
|
|
947
|
+
isDesktop() {
|
|
948
|
+
return !this.isMobile() && !this.isTablet();
|
|
949
|
+
}
|
|
950
|
+
getOS() {
|
|
951
|
+
let os;
|
|
952
|
+
if (this.userAgent && /Windows/i.test(this.userAgent)) {
|
|
953
|
+
os = OSTypes.WINDOWS;
|
|
954
|
+
}
|
|
955
|
+
else if (this.userAgent && /Macintosh|Mac OS/i.test(this.userAgent)) {
|
|
956
|
+
os = OSTypes.MAC_OS;
|
|
957
|
+
}
|
|
958
|
+
else if (this.userAgent && /Linux/i.test(this.userAgent)) {
|
|
959
|
+
os = OSTypes.LINUX;
|
|
960
|
+
}
|
|
961
|
+
else if (this.userAgent && /Android/i.test(this.userAgent)) {
|
|
962
|
+
os = OSTypes.ANDROID;
|
|
963
|
+
}
|
|
964
|
+
else if (this.userAgent && /iOS/i.test(this.userAgent)) {
|
|
965
|
+
os = OSTypes.IOS;
|
|
966
|
+
}
|
|
967
|
+
else {
|
|
968
|
+
os = OSTypes.UNKNOWN;
|
|
969
|
+
}
|
|
970
|
+
return os;
|
|
971
|
+
}
|
|
972
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.1", ngImport: i0, type: DeviceDetectorService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
973
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.0.1", ngImport: i0, type: DeviceDetectorService }); }
|
|
974
|
+
}
|
|
975
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.1", ngImport: i0, type: DeviceDetectorService, decorators: [{
|
|
976
|
+
type: Injectable
|
|
977
|
+
}], ctorParameters: () => [] });
|
|
978
|
+
|
|
979
|
+
class Breakpoints {
|
|
980
|
+
constructor() {
|
|
981
|
+
this.xl = '1920px';
|
|
982
|
+
this.lg = '1280px';
|
|
983
|
+
this.md = '960px';
|
|
984
|
+
this.sm = '720px';
|
|
985
|
+
this.xs = '600px';
|
|
986
|
+
}
|
|
987
|
+
}
|
|
988
|
+
|
|
989
|
+
/**
|
|
990
|
+
* A service that manages responsive design breakpoints using Angular's `BreakpointObserver`.
|
|
991
|
+
* This service provides signals for different screen sizes and allows dynamic
|
|
992
|
+
* breakpoint management.
|
|
993
|
+
*
|
|
994
|
+
* @Injectable
|
|
995
|
+
*/
|
|
996
|
+
class BreakpointService {
|
|
997
|
+
constructor() {
|
|
998
|
+
/**
|
|
999
|
+
* Private instance of BreakpointObserver used to observe screen size changes.
|
|
1000
|
+
*/
|
|
1001
|
+
this.#breakpointObserver = inject(BreakpointObserver);
|
|
1002
|
+
/**
|
|
1003
|
+
* Private instance of Injector.
|
|
1004
|
+
*/
|
|
1005
|
+
this.#injector = inject(Injector);
|
|
1006
|
+
/**
|
|
1007
|
+
* Instance of a lass containing the breakpoint values for different screen sizes.
|
|
1008
|
+
*/
|
|
1009
|
+
this.#breakpoints = signal(new Breakpoints(), { ...(ngDevMode ? { debugName: "#breakpoints" } : {}) });
|
|
1010
|
+
this.#desktopQuery = computed(() => `(min-width: ${this.#breakpoints().xl})`, { ...(ngDevMode ? { debugName: "#desktopQuery" } : {}) });
|
|
1011
|
+
this.#smallDesktopQuery = computed(() => `(min-width: ${this.#breakpoints().lg})`, { ...(ngDevMode ? { debugName: "#smallDesktopQuery" } : {}) });
|
|
1012
|
+
this.#tabletQuery = computed(() => `(min-width: ${this.#breakpoints().md})`, { ...(ngDevMode ? { debugName: "#tabletQuery" } : {}) });
|
|
1013
|
+
this.#smallTabletQuery = computed(() => `(min-width: ${this.#breakpoints().sm})`, { ...(ngDevMode ? { debugName: "#smallTabletQuery" } : {}) });
|
|
1014
|
+
this.#mobileQuery = computed(() => `(max-width: ${this.decrementOnePixel(this.#breakpoints().xs)})`, { ...(ngDevMode ? { debugName: "#mobileQuery" } : {}) });
|
|
1015
|
+
this.isDesktop = toSignal(toObservable(this.#desktopQuery, { injector: this.#injector }).pipe(distinctUntilChanged(), switchMap((query) => this.#breakpointObserver.observe(query)), map(({ matches }) => matches)));
|
|
1016
|
+
this.isSmallDesktop = toSignal(toObservable(this.#smallDesktopQuery, { injector: this.#injector }).pipe(distinctUntilChanged(), switchMap((query) => this.#breakpointObserver.observe(query)), map(({ matches }) => matches)));
|
|
1017
|
+
this.isMobile = toSignal(toObservable(this.#mobileQuery, { injector: this.#injector }).pipe(distinctUntilChanged(), switchMap((query) => this.#breakpointObserver.observe(query)), map(({ matches }) => matches)));
|
|
1018
|
+
this.isTablet = toSignal(toObservable(this.#tabletQuery, { injector: this.#injector }).pipe(distinctUntilChanged(), switchMap((query) => this.#breakpointObserver.observe(query)), map(({ matches }) => !matches)));
|
|
1019
|
+
this.isSmallTablet = toSignal(toObservable(this.#smallTabletQuery, { injector: this.#injector }).pipe(distinctUntilChanged(), switchMap((query) => this.#breakpointObserver.observe(query)), map(({ matches }) => matches)));
|
|
1020
|
+
}
|
|
1021
|
+
/**
|
|
1022
|
+
* Private instance of BreakpointObserver used to observe screen size changes.
|
|
1023
|
+
*/
|
|
1024
|
+
#breakpointObserver;
|
|
1025
|
+
/**
|
|
1026
|
+
* Private instance of Injector.
|
|
1027
|
+
*/
|
|
1028
|
+
#injector;
|
|
1029
|
+
/**
|
|
1030
|
+
* Instance of a lass containing the breakpoint values for different screen sizes.
|
|
1031
|
+
*/
|
|
1032
|
+
#breakpoints;
|
|
1033
|
+
#desktopQuery;
|
|
1034
|
+
#smallDesktopQuery;
|
|
1035
|
+
#tabletQuery;
|
|
1036
|
+
#smallTabletQuery;
|
|
1037
|
+
#mobileQuery;
|
|
1038
|
+
/**
|
|
1039
|
+
* Allows setting custom breakpoints for different screen sizes.
|
|
1040
|
+
*
|
|
1041
|
+
* @param breakpoints - The custom breakpoints to apply.
|
|
1042
|
+
*/
|
|
1043
|
+
setBreakpoints(breakpoints) {
|
|
1044
|
+
this.#breakpoints.set(breakpoints);
|
|
1045
|
+
}
|
|
1046
|
+
/**
|
|
1047
|
+
* Helper function to decrement the pixel value by 1.
|
|
1048
|
+
* Used to exclude the exact pixel value in media queries.
|
|
1049
|
+
*
|
|
1050
|
+
* @usageNotes
|
|
1051
|
+
*
|
|
1052
|
+
* This function is useful for setting correct media queries.
|
|
1053
|
+
* E.g. for mobile devices: media query should be `(max-width: 599px)`,
|
|
1054
|
+
* and from `(min-width: 600px)` it should be considered as a tablet.
|
|
1055
|
+
*
|
|
1056
|
+
* @param value - The pixel value to decrement.
|
|
1057
|
+
* @returns The adjusted pixel value as a string.
|
|
1058
|
+
*/
|
|
1059
|
+
decrementOnePixel(value) {
|
|
1060
|
+
return Number(value.split('px')[0]) - 1 + 'px';
|
|
1061
|
+
}
|
|
1062
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.1", ngImport: i0, type: BreakpointService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
1063
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.0.1", ngImport: i0, type: BreakpointService }); }
|
|
1064
|
+
}
|
|
1065
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.1", ngImport: i0, type: BreakpointService, decorators: [{
|
|
1066
|
+
type: Injectable
|
|
1067
|
+
}] });
|
|
1068
|
+
|
|
1069
|
+
class RtNavigationDirective {
|
|
1070
|
+
constructor() {
|
|
1071
|
+
this.#router = inject(Router);
|
|
1072
|
+
this.#windowRef = inject(WINDOW);
|
|
1073
|
+
this.#platformService = inject(PlatformService);
|
|
1074
|
+
this.link = input.required({ ...(ngDevMode ? { debugName: "link" } : {}), alias: 'rtNavigationDirective' });
|
|
1075
|
+
}
|
|
1076
|
+
#router;
|
|
1077
|
+
#windowRef;
|
|
1078
|
+
#platformService;
|
|
1079
|
+
onClick(event) {
|
|
1080
|
+
if (this.link()) {
|
|
1081
|
+
if (this.#platformService.isPlatformBrowser && (event.ctrlKey || event.metaKey)) {
|
|
1082
|
+
this.#windowRef.open(this.link());
|
|
1083
|
+
}
|
|
1084
|
+
else {
|
|
1085
|
+
void this.#router.navigate([this.link()]);
|
|
1086
|
+
}
|
|
1087
|
+
}
|
|
1088
|
+
}
|
|
1089
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.1", ngImport: i0, type: RtNavigationDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
1090
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.0.1", type: RtNavigationDirective, isStandalone: true, selector: "[rtNavigationDirective]", inputs: { link: { classPropertyName: "link", publicName: "rtNavigationDirective", isSignal: true, isRequired: true, transformFunction: null } }, host: { listeners: { "click": "onClick($event)" } }, providers: [PlatformService], ngImport: i0 }); }
|
|
1091
|
+
}
|
|
1092
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.1", ngImport: i0, type: RtNavigationDirective, decorators: [{
|
|
1093
|
+
type: Directive,
|
|
1094
|
+
args: [{
|
|
1095
|
+
selector: '[rtNavigationDirective]',
|
|
1096
|
+
providers: [PlatformService],
|
|
1097
|
+
}]
|
|
1098
|
+
}], propDecorators: { link: [{ type: i0.Input, args: [{ isSignal: true, alias: "rtNavigationDirective", required: true }] }], onClick: [{
|
|
1099
|
+
type: HostListener,
|
|
1100
|
+
args: ['click', ['$event']]
|
|
1101
|
+
}] } });
|
|
1102
|
+
|
|
1103
|
+
class RtTabQueryParamDirective {
|
|
1104
|
+
constructor() {
|
|
1105
|
+
this.#router = inject(Router);
|
|
1106
|
+
this.#route = inject(ActivatedRoute);
|
|
1107
|
+
this.#destroyRef = inject(DestroyRef);
|
|
1108
|
+
this.#currentTabIndex = signal(0, { ...(ngDevMode ? { debugName: "#currentTabIndex" } : {}) });
|
|
1109
|
+
this.currentTabIndex = this.#currentTabIndex.asReadonly();
|
|
1110
|
+
}
|
|
1111
|
+
#router;
|
|
1112
|
+
#route;
|
|
1113
|
+
#destroyRef;
|
|
1114
|
+
#currentTabIndex;
|
|
1115
|
+
ngOnInit() {
|
|
1116
|
+
this.#route.queryParamMap
|
|
1117
|
+
.pipe(filter((params) => params.has('tab')), take(1), map((params) => Number(params.get('tab'))), takeUntilDestroyed(this.#destroyRef))
|
|
1118
|
+
.subscribe((tabIndex) => {
|
|
1119
|
+
this.#setTabIndex(tabIndex);
|
|
1120
|
+
});
|
|
1121
|
+
}
|
|
1122
|
+
setQueryTab(index) {
|
|
1123
|
+
void this.#router.navigate([], {
|
|
1124
|
+
relativeTo: this.#route,
|
|
1125
|
+
queryParams: {
|
|
1126
|
+
tab: index,
|
|
1127
|
+
},
|
|
1128
|
+
queryParamsHandling: 'merge',
|
|
1129
|
+
});
|
|
1130
|
+
this.#setTabIndex(index);
|
|
1131
|
+
}
|
|
1132
|
+
#setTabIndex(index) {
|
|
1133
|
+
this.#currentTabIndex.set(index);
|
|
1134
|
+
}
|
|
1135
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.1", ngImport: i0, type: RtTabQueryParamDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
1136
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.0.1", type: RtTabQueryParamDirective, isStandalone: true, ngImport: i0 }); }
|
|
1137
|
+
}
|
|
1138
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.1", ngImport: i0, type: RtTabQueryParamDirective, decorators: [{
|
|
1139
|
+
type: Directive
|
|
1140
|
+
}] });
|
|
1141
|
+
|
|
1142
|
+
class RtScrollDirective {
|
|
1143
|
+
constructor() {
|
|
1144
|
+
this.#windowRef = inject(WINDOW);
|
|
1145
|
+
this.#platformService = inject(PlatformService);
|
|
1146
|
+
this.active = input(true, { ...(ngDevMode ? { debugName: "active" } : {}) });
|
|
1147
|
+
this.multiplier = input(0.5, { ...(ngDevMode ? { debugName: "multiplier" } : {}) });
|
|
1148
|
+
this.scrollAction = output();
|
|
1149
|
+
this.scroll = (event) => {
|
|
1150
|
+
const target = event.target;
|
|
1151
|
+
if (this.active() && target.offsetHeight + target.scrollTop >= target.scrollHeight * this.multiplier()) {
|
|
1152
|
+
this.scrollAction.emit();
|
|
1153
|
+
}
|
|
1154
|
+
};
|
|
1155
|
+
}
|
|
1156
|
+
#windowRef;
|
|
1157
|
+
#platformService;
|
|
1158
|
+
ngOnInit() {
|
|
1159
|
+
if (this.#platformService.isPlatformBrowser) {
|
|
1160
|
+
this.#windowRef.addEventListener('scroll', this.scroll, true);
|
|
1161
|
+
}
|
|
1162
|
+
}
|
|
1163
|
+
ngOnDestroy() {
|
|
1164
|
+
this.#windowRef.removeEventListener('scroll', this.scroll, true);
|
|
1165
|
+
}
|
|
1166
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.1", ngImport: i0, type: RtScrollDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
1167
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.0.1", type: RtScrollDirective, isStandalone: true, selector: "[rtScrollDirective]", inputs: { active: { classPropertyName: "active", publicName: "active", isSignal: true, isRequired: false, transformFunction: null }, multiplier: { classPropertyName: "multiplier", publicName: "multiplier", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { scrollAction: "scrollAction" }, ngImport: i0 }); }
|
|
1168
|
+
}
|
|
1169
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.1", ngImport: i0, type: RtScrollDirective, decorators: [{
|
|
1170
|
+
type: Directive,
|
|
1171
|
+
args: [{
|
|
1172
|
+
selector: '[rtScrollDirective]',
|
|
1173
|
+
}]
|
|
1174
|
+
}], propDecorators: { active: [{ type: i0.Input, args: [{ isSignal: true, alias: "active", required: false }] }], multiplier: [{ type: i0.Input, args: [{ isSignal: true, alias: "multiplier", required: false }] }], scrollAction: [{ type: i0.Output, args: ["scrollAction"] }] } });
|
|
1175
|
+
|
|
1176
|
+
class RtEscapeKeyDirective {
|
|
1177
|
+
constructor() {
|
|
1178
|
+
this.escapeKeyAction = output();
|
|
1179
|
+
}
|
|
1180
|
+
handleKeyboardEvent(event) {
|
|
1181
|
+
if (event.key === 'Escape') {
|
|
1182
|
+
this.escapeKeyAction.emit();
|
|
1183
|
+
}
|
|
1184
|
+
}
|
|
1185
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.1", ngImport: i0, type: RtEscapeKeyDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
1186
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.0.1", type: RtEscapeKeyDirective, isStandalone: true, selector: "[rtEscapeKey]", outputs: { escapeKeyAction: "escapeKeyAction" }, host: { listeners: { "document:keydown": "handleKeyboardEvent($event)" } }, ngImport: i0 }); }
|
|
1187
|
+
}
|
|
1188
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.1", ngImport: i0, type: RtEscapeKeyDirective, decorators: [{
|
|
1189
|
+
type: Directive,
|
|
1190
|
+
args: [{
|
|
1191
|
+
selector: '[rtEscapeKey]',
|
|
1192
|
+
}]
|
|
1193
|
+
}], propDecorators: { escapeKeyAction: [{ type: i0.Output, args: ["escapeKeyAction"] }], handleKeyboardEvent: [{
|
|
1194
|
+
type: HostListener,
|
|
1195
|
+
args: ['document:keydown', ['$event']]
|
|
1196
|
+
}] } });
|
|
1197
|
+
|
|
1198
|
+
var MODAL_WINDOW_SIZE_ENUM;
|
|
1199
|
+
(function (MODAL_WINDOW_SIZE_ENUM) {
|
|
1200
|
+
MODAL_WINDOW_SIZE_ENUM["SM"] = "25rem";
|
|
1201
|
+
MODAL_WINDOW_SIZE_ENUM["MD"] = "45rem";
|
|
1202
|
+
MODAL_WINDOW_SIZE_ENUM["LG"] = "65rem";
|
|
1203
|
+
MODAL_WINDOW_SIZE_ENUM["FULL"] = "100%";
|
|
1204
|
+
})(MODAL_WINDOW_SIZE_ENUM || (MODAL_WINDOW_SIZE_ENUM = {}));
|
|
1205
|
+
|
|
1206
|
+
var ASIDE_BUTTONS_ENUM;
|
|
1207
|
+
(function (ASIDE_BUTTONS_ENUM) {
|
|
1208
|
+
ASIDE_BUTTONS_ENUM["USER_ACTIVE"] = "User active";
|
|
1209
|
+
ASIDE_BUTTONS_ENUM["USER_INACTIVE"] = "User inactive";
|
|
1210
|
+
ASIDE_BUTTONS_ENUM["DELETE"] = "Delete";
|
|
1211
|
+
ASIDE_BUTTONS_ENUM["RESET"] = "Reset";
|
|
1212
|
+
})(ASIDE_BUTTONS_ENUM || (ASIDE_BUTTONS_ENUM = {}));
|
|
1213
|
+
|
|
1214
|
+
var POSITION_ENUM;
|
|
1215
|
+
(function (POSITION_ENUM) {
|
|
1216
|
+
POSITION_ENUM["LEFT"] = "left";
|
|
1217
|
+
POSITION_ENUM["RIGHT"] = "right";
|
|
1218
|
+
POSITION_ENUM["TOP"] = "top";
|
|
1219
|
+
POSITION_ENUM["BOTTOM"] = "bottom";
|
|
1220
|
+
POSITION_ENUM["START"] = "start";
|
|
1221
|
+
POSITION_ENUM["END"] = "end";
|
|
1222
|
+
POSITION_ENUM["CENTER"] = "center";
|
|
1223
|
+
})(POSITION_ENUM || (POSITION_ENUM = {}));
|
|
1224
|
+
|
|
1225
|
+
class TypeCastHelper {
|
|
1226
|
+
getAsString(data, defaultValue = '') {
|
|
1227
|
+
return !isNil(data) && !Number.isNaN(data) ? String(data) : defaultValue;
|
|
1228
|
+
}
|
|
1229
|
+
getAsNumber(data, defaultValue) {
|
|
1230
|
+
const result = Number(data);
|
|
1231
|
+
return data === null || Number.isNaN(result) ? (defaultValue ?? NaN) : result;
|
|
1232
|
+
}
|
|
1233
|
+
getAsBoolean(data) {
|
|
1234
|
+
const stringExceptions = ['false', '0', 'null'];
|
|
1235
|
+
if (typeof data === 'string' && stringExceptions.includes(data)) {
|
|
1236
|
+
return false;
|
|
1237
|
+
}
|
|
1238
|
+
return Boolean(data);
|
|
1239
|
+
}
|
|
1240
|
+
getAsNull(data, handler) {
|
|
1241
|
+
if (!isNil(data) && !Number.isNaN(data)) {
|
|
1242
|
+
return handler ? handler(data) : data;
|
|
1243
|
+
}
|
|
1244
|
+
return null;
|
|
1245
|
+
}
|
|
1246
|
+
// eslint-disable-next-line
|
|
1247
|
+
getAsType(value, type) {
|
|
1248
|
+
if (!!value && !Object.values(type).includes(value)) {
|
|
1249
|
+
// eslint-disable-next-line no-console
|
|
1250
|
+
console.error(`getAsTyped: the value "${value}" was not found in the specified type`);
|
|
1251
|
+
return 'unknown';
|
|
1252
|
+
}
|
|
1253
|
+
return value;
|
|
1254
|
+
}
|
|
1255
|
+
getAsTypedArray(data, cb, showError = true) {
|
|
1256
|
+
if (!Array.isArray(data)) {
|
|
1257
|
+
if (showError) {
|
|
1258
|
+
// eslint-disable-next-line no-console
|
|
1259
|
+
console.error('getAsTypedArray: Given data must be an array (now it is ' +
|
|
1260
|
+
typeof data +
|
|
1261
|
+
'). Incorrect data will be defined as array of data (data => [data]).');
|
|
1262
|
+
}
|
|
1263
|
+
data = [data];
|
|
1264
|
+
}
|
|
1265
|
+
if (!data.length) {
|
|
1266
|
+
return [];
|
|
1267
|
+
}
|
|
1268
|
+
return data.map(cb);
|
|
1269
|
+
}
|
|
1270
|
+
getAsDate(date, asString, parseFormatOptions, formatOptions) {
|
|
1271
|
+
formatOptions = formatOptions ?? 'dd.MM.yyyy';
|
|
1272
|
+
asString = asString ?? true;
|
|
1273
|
+
const type = typeof date;
|
|
1274
|
+
switch (type) {
|
|
1275
|
+
case 'number':
|
|
1276
|
+
date = new Date(date);
|
|
1277
|
+
break;
|
|
1278
|
+
case 'string':
|
|
1279
|
+
date = !!parseFormatOptions ? parseDate(date, parseFormatOptions, new Date()) : parseISO(date);
|
|
1280
|
+
break;
|
|
1281
|
+
}
|
|
1282
|
+
if (!isDate(date)) {
|
|
1283
|
+
return '';
|
|
1284
|
+
}
|
|
1285
|
+
return asString ? formatDate(date, formatOptions) : date;
|
|
1286
|
+
}
|
|
1287
|
+
}
|
|
1288
|
+
|
|
1289
|
+
class BaseMapper {
|
|
1290
|
+
constructor() {
|
|
1291
|
+
this.typeCast = new TypeCastHelper();
|
|
1292
|
+
}
|
|
1293
|
+
// eslint-disable-next-line
|
|
1294
|
+
mapFrom(data, ...args) {
|
|
1295
|
+
return { ...data };
|
|
1296
|
+
}
|
|
1297
|
+
mapFromArray(data, ...args) {
|
|
1298
|
+
if (!Array.isArray(data)) {
|
|
1299
|
+
// eslint-disable-next-line no-console
|
|
1300
|
+
console.error('mapFromArray: Given data must be an array (now it is ' + typeof data + '). Incorrect data will be defined as empty array.');
|
|
1301
|
+
data = [];
|
|
1302
|
+
}
|
|
1303
|
+
return data.map((entry) => this.mapFrom(entry, ...args));
|
|
1304
|
+
}
|
|
1305
|
+
// eslint-disable-next-line
|
|
1306
|
+
mapTo(model, ...args) {
|
|
1307
|
+
return { ...model };
|
|
1308
|
+
}
|
|
1309
|
+
mapToArray(models, ...args) {
|
|
1310
|
+
if (!Array.isArray(models)) {
|
|
1311
|
+
// eslint-disable-next-line no-console
|
|
1312
|
+
console.error('mapToArray: Given data must be an array (now it is ' + typeof models + '). Incorrect data will be defined as empty array.');
|
|
1313
|
+
models = [];
|
|
1314
|
+
}
|
|
1315
|
+
return models.map((model) => this.mapTo(model, ...args));
|
|
1316
|
+
}
|
|
1317
|
+
}
|
|
1318
|
+
|
|
1319
|
+
class BreakStringPipe {
|
|
1320
|
+
transform(value) {
|
|
1321
|
+
if (isNil(value)) {
|
|
1322
|
+
return DASH;
|
|
1323
|
+
}
|
|
1324
|
+
if (value && isString(value)) {
|
|
1325
|
+
if (/\s/.test(value) || /^[A-Z0-9\s]+$/.test(value) || /\d/.test(value) || /[^\w\s]/.test(value)) {
|
|
1326
|
+
return value;
|
|
1327
|
+
}
|
|
1328
|
+
return value.split(/(?=[A-Z])/).join(' ');
|
|
1329
|
+
}
|
|
1330
|
+
return value.toString();
|
|
1331
|
+
}
|
|
1332
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.1", ngImport: i0, type: BreakStringPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe }); }
|
|
1333
|
+
static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "21.0.1", ngImport: i0, type: BreakStringPipe, isStandalone: true, name: "breakString" }); }
|
|
1334
|
+
}
|
|
1335
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.1", ngImport: i0, type: BreakStringPipe, decorators: [{
|
|
1336
|
+
type: Pipe,
|
|
1337
|
+
args: [{
|
|
1338
|
+
name: 'breakString',
|
|
1339
|
+
}]
|
|
1340
|
+
}] });
|
|
1341
|
+
|
|
1342
|
+
class SanitizePipe {
|
|
1343
|
+
#sanitizer = inject(DomSanitizer);
|
|
1344
|
+
transform(value) {
|
|
1345
|
+
return this.#sanitizer.bypassSecurityTrustHtml(value);
|
|
1346
|
+
}
|
|
1347
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.1", ngImport: i0, type: SanitizePipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe }); }
|
|
1348
|
+
static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "21.0.1", ngImport: i0, type: SanitizePipe, isStandalone: true, name: "sanitize" }); }
|
|
1349
|
+
}
|
|
1350
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.1", ngImport: i0, type: SanitizePipe, decorators: [{
|
|
1351
|
+
type: Pipe,
|
|
1352
|
+
args: [{
|
|
1353
|
+
name: 'sanitize',
|
|
1354
|
+
pure: true,
|
|
1355
|
+
}]
|
|
1356
|
+
}] });
|
|
1357
|
+
|
|
1358
|
+
class EntityToStringPipe {
|
|
1359
|
+
transform(value) {
|
|
1360
|
+
if (isString(value)) {
|
|
1361
|
+
return value;
|
|
1362
|
+
}
|
|
1363
|
+
if (isNumber(value)) {
|
|
1364
|
+
return value.toString();
|
|
1365
|
+
}
|
|
1366
|
+
return DASH;
|
|
1367
|
+
}
|
|
1368
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.1", ngImport: i0, type: EntityToStringPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe }); }
|
|
1369
|
+
static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "21.0.1", ngImport: i0, type: EntityToStringPipe, isStandalone: true, name: "entityToString" }); }
|
|
1370
|
+
}
|
|
1371
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.1", ngImport: i0, type: EntityToStringPipe, decorators: [{
|
|
1372
|
+
type: Pipe,
|
|
1373
|
+
args: [{
|
|
1374
|
+
name: 'entityToString',
|
|
1375
|
+
pure: true,
|
|
1376
|
+
}]
|
|
1377
|
+
}] });
|
|
1378
|
+
|
|
1379
|
+
class EmptyToDashPipe {
|
|
1380
|
+
transform(value) {
|
|
1381
|
+
return emptyToDash(value);
|
|
1382
|
+
}
|
|
1383
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.1", ngImport: i0, type: EmptyToDashPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe }); }
|
|
1384
|
+
static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "21.0.1", ngImport: i0, type: EmptyToDashPipe, isStandalone: true, name: "emptyToDash" }); }
|
|
1385
|
+
}
|
|
1386
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.1", ngImport: i0, type: EmptyToDashPipe, decorators: [{
|
|
1387
|
+
type: Pipe,
|
|
1388
|
+
args: [{
|
|
1389
|
+
name: 'emptyToDash',
|
|
1390
|
+
pure: true,
|
|
1391
|
+
}]
|
|
1392
|
+
}] });
|
|
1393
|
+
|
|
1394
|
+
/**
|
|
1395
|
+
* @description Use to compare equality to any of items with provided value
|
|
1396
|
+
* @example
|
|
1397
|
+
*
|
|
1398
|
+
* Direct usage
|
|
1399
|
+
* ```ts
|
|
1400
|
+
* equalPipe.transform(100, 1, 10, 100) // => true
|
|
1401
|
+
* ```
|
|
1402
|
+
*
|
|
1403
|
+
* Template usage
|
|
1404
|
+
*
|
|
1405
|
+
* ```html
|
|
1406
|
+
* <div *ngIf="100 | equal:1:10:100">Visible</div>
|
|
1407
|
+
* ```
|
|
1408
|
+
*/
|
|
1409
|
+
class EqualPipe {
|
|
1410
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
1411
|
+
transform(value, ...compares) {
|
|
1412
|
+
return compares.reduce((equal, compare) => equal || value === compare, false);
|
|
1413
|
+
}
|
|
1414
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.1", ngImport: i0, type: EqualPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe }); }
|
|
1415
|
+
static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "21.0.1", ngImport: i0, type: EqualPipe, isStandalone: true, name: "equal" }); }
|
|
1416
|
+
}
|
|
1417
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.1", ngImport: i0, type: EqualPipe, decorators: [{
|
|
1418
|
+
type: Pipe,
|
|
1419
|
+
args: [{
|
|
1420
|
+
name: 'equal',
|
|
1421
|
+
}]
|
|
1422
|
+
}] });
|
|
1423
|
+
|
|
1424
|
+
/**
|
|
1425
|
+
* @description Use to access to the deep object state for comparison
|
|
1426
|
+
* @example
|
|
1427
|
+
* {a: {b: true}} | equalChain:'a':'b':true => true
|
|
1428
|
+
*/
|
|
1429
|
+
class EqualChainPipe {
|
|
1430
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
1431
|
+
transform(obj, ...args) {
|
|
1432
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
1433
|
+
const compared = args.pop();
|
|
1434
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
1435
|
+
return Boolean(obj) && args.reduce((inner, arg) => inner[arg], obj) === compared;
|
|
1436
|
+
}
|
|
1437
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.1", ngImport: i0, type: EqualChainPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe }); }
|
|
1438
|
+
static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "21.0.1", ngImport: i0, type: EqualChainPipe, isStandalone: true, name: "equalChain" }); }
|
|
1439
|
+
}
|
|
1440
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.1", ngImport: i0, type: EqualChainPipe, decorators: [{
|
|
1441
|
+
type: Pipe,
|
|
1442
|
+
args: [{
|
|
1443
|
+
name: 'equalChain',
|
|
1444
|
+
}]
|
|
1445
|
+
}] });
|
|
1446
|
+
|
|
1447
|
+
/**
|
|
1448
|
+
* @description Use to compare not equality to all items with provided value
|
|
1449
|
+
* @example
|
|
1450
|
+
*
|
|
1451
|
+
* Direct usage
|
|
1452
|
+
* ```ts
|
|
1453
|
+
* notEqualPipe.transform(100, 1, 10, 100) // => false
|
|
1454
|
+
* ```
|
|
1455
|
+
*
|
|
1456
|
+
* Template usage
|
|
1457
|
+
*
|
|
1458
|
+
* ```html
|
|
1459
|
+
* <div *ngIf="100 | notEqual:1:10:100">Invisible</div>
|
|
1460
|
+
* ```
|
|
1461
|
+
*/
|
|
1462
|
+
class NotEqualPipe {
|
|
1463
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
1464
|
+
transform(value, ...compares) {
|
|
1465
|
+
return compares.reduce((notEqual, compare) => notEqual && value !== compare, true);
|
|
1466
|
+
}
|
|
1467
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.1", ngImport: i0, type: NotEqualPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe }); }
|
|
1468
|
+
static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "21.0.1", ngImport: i0, type: NotEqualPipe, isStandalone: true, name: "notEqual" }); }
|
|
1469
|
+
}
|
|
1470
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.1", ngImport: i0, type: NotEqualPipe, decorators: [{
|
|
1471
|
+
type: Pipe,
|
|
1472
|
+
args: [{
|
|
1473
|
+
name: 'notEqual',
|
|
1474
|
+
}]
|
|
1475
|
+
}] });
|
|
1476
|
+
|
|
1477
|
+
/**
|
|
1478
|
+
* @description Use to access to the deep object state for comparison
|
|
1479
|
+
* @example
|
|
1480
|
+
* {a: {b: true}} | equalChain:'a':'b':false => true
|
|
1481
|
+
*/
|
|
1482
|
+
class NotEqualChainPipe {
|
|
1483
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
1484
|
+
transform(obj, ...args) {
|
|
1485
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
1486
|
+
const compared = args.pop();
|
|
1487
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
1488
|
+
return Boolean(obj) && args.reduce((inner, arg) => inner[arg], obj) !== compared;
|
|
1489
|
+
}
|
|
1490
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.1", ngImport: i0, type: NotEqualChainPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe }); }
|
|
1491
|
+
static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "21.0.1", ngImport: i0, type: NotEqualChainPipe, isStandalone: true, name: "notEqualChain" }); }
|
|
1492
|
+
}
|
|
1493
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.1", ngImport: i0, type: NotEqualChainPipe, decorators: [{
|
|
1494
|
+
type: Pipe,
|
|
1495
|
+
args: [{
|
|
1496
|
+
name: 'notEqualChain',
|
|
1497
|
+
}]
|
|
1498
|
+
}] });
|
|
1499
|
+
|
|
1500
|
+
class TernaryPipe {
|
|
1501
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
1502
|
+
transform(value, option1, option2) {
|
|
1503
|
+
return Boolean(value) ? option1 : option2;
|
|
1504
|
+
}
|
|
1505
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.1", ngImport: i0, type: TernaryPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe }); }
|
|
1506
|
+
static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "21.0.1", ngImport: i0, type: TernaryPipe, isStandalone: true, name: "ternary" }); }
|
|
1507
|
+
}
|
|
1508
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.1", ngImport: i0, type: TernaryPipe, decorators: [{
|
|
1509
|
+
type: Pipe,
|
|
1510
|
+
args: [{
|
|
1511
|
+
name: 'ternary',
|
|
1512
|
+
}]
|
|
1513
|
+
}] });
|
|
1514
|
+
|
|
1515
|
+
function checkIsMatchingValues(sample) {
|
|
1516
|
+
return (control) => {
|
|
1517
|
+
return sample && control.value && control.value.localeCompare(sample) === 0 ? null : { notEquivalent: true };
|
|
1518
|
+
};
|
|
1519
|
+
}
|
|
1520
|
+
|
|
1521
|
+
function arraysNotEmptyValidator(control) {
|
|
1522
|
+
if (control.value instanceof Object) {
|
|
1523
|
+
const arrays = Object.values(control.value);
|
|
1524
|
+
const allArraysEmpty = arrays.every((array) => !array.length);
|
|
1525
|
+
return allArraysEmpty ? { allArraysEmpty: true } : null;
|
|
1526
|
+
}
|
|
1527
|
+
else if (Array.isArray(control.value)) {
|
|
1528
|
+
const array = control.value;
|
|
1529
|
+
return !array.length ? { arrayEmpty: true } : null;
|
|
1530
|
+
}
|
|
1531
|
+
else {
|
|
1532
|
+
return { invalidType: true };
|
|
1533
|
+
}
|
|
1534
|
+
}
|
|
1535
|
+
|
|
1536
|
+
/**
|
|
1537
|
+
* Returns a set of dependency injection providers for utility services.
|
|
1538
|
+
*
|
|
1539
|
+
* @usageNotes
|
|
1540
|
+
*
|
|
1541
|
+
* This function provides utility services that are commonly used across
|
|
1542
|
+
* an Angular application. Specifically, it provides the `BreakpointService`
|
|
1543
|
+
* for managing responsive design breakpoints and the `PlatformService` for
|
|
1544
|
+
* detecting the platform on which the application is running (e.g., browser or server).
|
|
1545
|
+
*
|
|
1546
|
+
* ```typescript
|
|
1547
|
+
* bootstrapApplication(RootComponent, {
|
|
1548
|
+
* providers: [
|
|
1549
|
+
* provideRtUtils()
|
|
1550
|
+
* ]
|
|
1551
|
+
* });
|
|
1552
|
+
* ```
|
|
1553
|
+
*
|
|
1554
|
+
* @publicApi
|
|
1555
|
+
*/
|
|
1556
|
+
function provideRtUtils() {
|
|
1557
|
+
return [BreakpointService, PlatformService];
|
|
1558
|
+
}
|
|
1559
|
+
|
|
1560
|
+
// constants
|
|
1561
|
+
|
|
1562
|
+
/**
|
|
1563
|
+
* Generated bundle index. Do not edit.
|
|
1564
|
+
*/
|
|
1565
|
+
|
|
1566
|
+
export { ASIDE_BUTTONS_ENUM, ASIDE_REF, AsideRef, BaseMapper, BreakStringPipe, BreakpointService, Breakpoints, DASH, DeviceDetectorService, EmptyToDashPipe, EntityToStringPipe, EqualChainPipe, EqualPipe, HAS_OWN_SCOPE_ENUM, MODAL_WINDOW_SIZE_ENUM, NAVIGATOR, NotEqualChainPipe, NotEqualPipe, OSTypes, OVERLAY_POSITIONS, POSITION_ENUM, RtEscapeKeyDirective, RtHideTooltipDirective, RtIconOutlinedDirective, RtNavigationDirective, RtScrollDirective, RtScrollToElementDirective, RtTabQueryParamDirective, SanitizePipe, TernaryPipe, TypeCastHelper, areArraysEqual, areArraysEqualUnordered, areObjectsEqual, arraysNotEmptyValidator, checkIsEntityInArrayByKey, checkIsMatchingValues, dateStringToDate, ddServices, debounce, emptyToDash, formatDate, hasPropertyInChain, initToday, isDate, isDateValid, isEmail, isEmpty, isEmptyArray, isEmptyObject, isEmptyString, isEqual, isNumber, isRecord, isString, isToday, parseDate, parseISO, provideRtUtils, removeFieldFromObject, safeComparatorPipe, safeCompare, safeNumCompare, safeStrCompare, sortByAlphabet, sortByDate, stringifyHttpLikeParams, transformArrayInput, transformStringInput };
|
|
1567
|
+
//# sourceMappingURL=rt-tools-utils.mjs.map
|