@libs-ui/utils 0.2.304 → 0.2.306-10
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/communicate-micro.d.ts +1 -1
- package/dangerous-object.d.ts +75 -0
- package/date.d.ts +14 -19
- package/dom.d.ts +21 -3
- package/esm2022/base64.mjs +2 -2
- package/esm2022/cache.mjs +20 -16
- package/esm2022/color.mjs +66 -14
- package/esm2022/communicate-micro.mjs +20 -16
- package/esm2022/constants.mjs +1 -1
- package/esm2022/crypto-3rd.mjs +3 -3
- package/esm2022/crypto.mjs +3 -3
- package/esm2022/dangerous-object.mjs +143 -0
- package/esm2022/date.mjs +24 -22
- package/esm2022/dom.mjs +127 -17
- package/esm2022/download.mjs +3 -3
- package/esm2022/file.mjs +23 -11
- package/esm2022/format-number.mjs +9 -6
- package/esm2022/format-text.mjs +13 -15
- package/esm2022/function-check-embed-frame.mjs +1 -1
- package/esm2022/get-smart-axis-scale.mjs +10 -10
- package/esm2022/helpers.mjs +136 -48
- package/esm2022/http-params.mjs +2 -2
- package/esm2022/index.mjs +2 -1
- package/esm2022/inject-token.mjs +2 -2
- package/esm2022/key-cache.mjs +6 -6
- package/esm2022/key-code.mjs +1 -1
- package/esm2022/language.mjs +28 -28
- package/esm2022/pattern.mjs +1 -1
- package/esm2022/random.mjs +2 -2
- package/esm2022/two-way-signal-object.mjs +32 -20
- package/esm2022/uri.mjs +9 -6
- package/esm2022/url-search-params.mjs +13 -11
- package/esm2022/uuid.mjs +2 -2
- package/esm2022/xss-filter.mjs +1 -1
- package/fesm2022/libs-ui-utils.mjs +797 -368
- package/fesm2022/libs-ui-utils.mjs.map +1 -1
- package/file.d.ts +2 -2
- package/format-text.d.ts +1 -1
- package/helpers.d.ts +54 -5
- package/http-params.d.ts +1 -1
- package/index.d.ts +1 -0
- package/inject-token.d.ts +1 -1
- package/package.json +2 -2
- package/uri.d.ts +1 -1
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { fromEvent, tap, takeUntil, mergeMap, startWith, finalize, Subject, filter, Observable } from 'rxjs';
|
|
2
|
-
import Quill from 'quill';
|
|
3
1
|
import DeviceDetector from 'device-detector-js';
|
|
2
|
+
import Quill from 'quill';
|
|
3
|
+
import { fromEvent, tap, takeUntil, mergeMap, startWith, finalize, lastValueFrom, timer, Observable, Subject, filter } from 'rxjs';
|
|
4
4
|
import CryptoES from 'crypto-es';
|
|
5
5
|
import { HttpParams } from '@angular/common/http';
|
|
6
|
-
import {
|
|
6
|
+
import { TemplateRef, ElementRef, isSignal, signal, InjectionToken } from '@angular/core';
|
|
7
7
|
import dayjs from 'dayjs';
|
|
8
8
|
import 'dayjs/locale/en';
|
|
9
9
|
import 'dayjs/locale/vi';
|
|
@@ -90,7 +90,7 @@ const highlightByKeyword = (value, search, ignoreHighlight, classHightLight) =>
|
|
|
90
90
|
if (!classHightLight) {
|
|
91
91
|
classHightLight = 'bg-[#19344a] text-white';
|
|
92
92
|
}
|
|
93
|
-
keysReplace.forEach(key => {
|
|
93
|
+
keysReplace.forEach((key) => {
|
|
94
94
|
const regExp = new RegExp(key, 'gi');
|
|
95
95
|
value = value?.replace(regExp, `<span class="${classHightLight}">$&</span>`);
|
|
96
96
|
});
|
|
@@ -119,7 +119,7 @@ const formatTextCompare = (text, options) => {
|
|
|
119
119
|
if (!text) {
|
|
120
120
|
return text;
|
|
121
121
|
}
|
|
122
|
-
text = text.normalize(
|
|
122
|
+
text = text.normalize('NFC');
|
|
123
123
|
return formatByOptions(text, options);
|
|
124
124
|
};
|
|
125
125
|
const fullNameFormat = (value) => {
|
|
@@ -133,7 +133,10 @@ const capitalize = (text, options) => {
|
|
|
133
133
|
return text;
|
|
134
134
|
}
|
|
135
135
|
text = formatByOptions(text, options);
|
|
136
|
-
return text
|
|
136
|
+
return text
|
|
137
|
+
.split(' ')
|
|
138
|
+
.map((word) => firstLetterToUpperCase(word))
|
|
139
|
+
.join(' ');
|
|
137
140
|
};
|
|
138
141
|
const firstLetterToUpperCase = (text, options) => {
|
|
139
142
|
if (!text) {
|
|
@@ -159,7 +162,7 @@ const formatByOptions = (text, options) => {
|
|
|
159
162
|
text = text.toLowerCase();
|
|
160
163
|
}
|
|
161
164
|
if (options?.removeMultipleSpace) {
|
|
162
|
-
text = text.replace(/\u200B|\u00A0/g,
|
|
165
|
+
text = text.replace(/\u200B|\u00A0/g, '');
|
|
163
166
|
text = text.replace(/\s+/g, ' ');
|
|
164
167
|
}
|
|
165
168
|
if (options?.removeEmoji) {
|
|
@@ -177,12 +180,7 @@ const escapeHtml = (str) => {
|
|
|
177
180
|
if (!str || typeof str !== 'string') {
|
|
178
181
|
return str;
|
|
179
182
|
}
|
|
180
|
-
return str
|
|
181
|
-
.replace(/&/g, "&")
|
|
182
|
-
.replace(/</g, "<")
|
|
183
|
-
.replace(/>/g, ">")
|
|
184
|
-
.replace(/"/g, """)
|
|
185
|
-
.replace(/'/g, "'");
|
|
183
|
+
return str.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/"/g, '"').replace(/'/g, ''');
|
|
186
184
|
};
|
|
187
185
|
const decodeEscapeHtml = (str) => {
|
|
188
186
|
const htmlTag = document.createElement('textarea');
|
|
@@ -213,9 +211,9 @@ const deleteUnicode = (str) => {
|
|
|
213
211
|
str = str.replace(/Ù|Ú|Ụ|Ủ|Ũ|Ư|Ừ|Ứ|Ự|Ử|Ữ/g, 'U');
|
|
214
212
|
str = str.replace(/Ỳ|Ý|Ỵ|Ỷ|Ỹ/g, 'Y');
|
|
215
213
|
str = str.replace(/Đ/g, 'D');
|
|
216
|
-
str = str.replace(/\u0300|\u0301|\u0303|\u0309|\u0323/g,
|
|
217
|
-
str = str.replace(/\u02C6|\u0306|\u031B/g,
|
|
218
|
-
return str.normalize(
|
|
214
|
+
str = str.replace(/\u0300|\u0301|\u0303|\u0309|\u0323/g, ''); // ̀ ́ ̃ ̉ ̣ huyền, sắc, ngã, hỏi, nặng
|
|
215
|
+
str = str.replace(/\u02C6|\u0306|\u031B/g, ''); // ˆ ̆ ̛ Â, Ê, Ă, Ơ, Ư
|
|
216
|
+
return str.normalize('NFC');
|
|
219
217
|
};
|
|
220
218
|
const removeEmoji = (text) => {
|
|
221
219
|
if (!text || !text.trim()) {
|
|
@@ -290,10 +288,7 @@ const checkViewInScreen = (container, element, elementScroll, maxTopLeft) => {
|
|
|
290
288
|
const limitLeft = leftContainer + scrollLeftContainer + widthContainer;
|
|
291
289
|
const maxTopItem = top + (maxTopLeft?.top || 0);
|
|
292
290
|
const maxLeftItem = left + (maxTopLeft?.left || 0);
|
|
293
|
-
if (topContainer <= maxTopItem &&
|
|
294
|
-
maxTopItem <= limitTop &&
|
|
295
|
-
leftContainer <= maxLeftItem &&
|
|
296
|
-
maxLeftItem <= limitLeft) {
|
|
291
|
+
if (topContainer <= maxTopItem && maxTopItem <= limitTop && leftContainer <= maxLeftItem && maxLeftItem <= limitLeft) {
|
|
297
292
|
return true;
|
|
298
293
|
}
|
|
299
294
|
return false;
|
|
@@ -307,10 +302,7 @@ const checkMouseOverInContainer = (mousePosition, element, rect) => {
|
|
|
307
302
|
const limitLeft = left + width;
|
|
308
303
|
const limitTop = top + height;
|
|
309
304
|
const { clientX, clientY } = mousePosition;
|
|
310
|
-
if (left <= clientX &&
|
|
311
|
-
clientX <= limitLeft &&
|
|
312
|
-
top <= clientY &&
|
|
313
|
-
clientY <= limitTop) {
|
|
305
|
+
if (left <= clientX && clientX <= limitLeft && top <= clientY && clientY <= limitTop) {
|
|
314
306
|
return true;
|
|
315
307
|
}
|
|
316
308
|
return false;
|
|
@@ -348,22 +340,138 @@ const getDragEventByElement = (config) => {
|
|
|
348
340
|
e.stopPropagation();
|
|
349
341
|
config.functionMouseMove?.(e);
|
|
350
342
|
}), takeUntil(mouseup));
|
|
351
|
-
return mouseDown.pipe(mergeMap((e) => config.isStartWithMouseDownEvent
|
|
352
|
-
? mousemove.pipe(startWith(e))
|
|
353
|
-
: mousemove), takeUntil(config.onDestroy), finalize(removeClass));
|
|
343
|
+
return mouseDown.pipe(mergeMap((e) => (config.isStartWithMouseDownEvent ? mousemove.pipe(startWith(e)) : mousemove)), takeUntil(config.onDestroy), finalize(removeClass));
|
|
354
344
|
};
|
|
355
|
-
const getHTMLFromQuill = (
|
|
345
|
+
const getHTMLFromQuill = async (data, options) => {
|
|
346
|
+
const { replaceNewLineTo = '<br>', replaceTagBRTo, replaceTags, replaceBrToDiv } = options || {};
|
|
347
|
+
const delta = typeof data === 'string' ? await getDeltaFromHTML(data) : data;
|
|
348
|
+
if (options?.functionReplaceDelta) {
|
|
349
|
+
options.functionReplaceDelta(delta);
|
|
350
|
+
}
|
|
356
351
|
delta.ops.forEach((op) => {
|
|
357
352
|
if (op.insert) {
|
|
358
353
|
if (typeof op.insert === 'string') {
|
|
359
|
-
|
|
354
|
+
if (replaceNewLineTo) {
|
|
355
|
+
op.insert = op.insert.replace(/\n/g, replaceNewLineTo);
|
|
356
|
+
}
|
|
357
|
+
if (replaceTagBRTo) {
|
|
358
|
+
op.insert = op.insert.replace(/<br>/g, replaceTagBRTo);
|
|
359
|
+
}
|
|
360
|
+
if (replaceTags?.length) {
|
|
361
|
+
for (const tag of replaceTags) {
|
|
362
|
+
op.insert = op.insert.replace(new RegExp(`<${tag.tag}>`, 'g'), `<${tag.replaceTo}>`);
|
|
363
|
+
op.insert = op.insert.replace(new RegExp(`</${tag.tag}>`, 'g'), `</${tag.replaceTo}>`);
|
|
364
|
+
}
|
|
365
|
+
}
|
|
360
366
|
}
|
|
361
367
|
}
|
|
362
368
|
});
|
|
363
369
|
quill.setContents(delta);
|
|
364
|
-
|
|
370
|
+
let htmlText = options?.getRootHtml ? quill.root.innerHTML : quill.root.firstElementChild?.innerHTML;
|
|
371
|
+
if (replaceBrToDiv) {
|
|
372
|
+
htmlText = convertHtmlToDivBlocks(htmlText || '');
|
|
373
|
+
}
|
|
365
374
|
return decodeEscapeHtml(htmlText || '');
|
|
366
375
|
};
|
|
376
|
+
const convertHtmlToDivBlocks = (html) => {
|
|
377
|
+
const BREAK_TOKEN = '<<<BREAK>>>';
|
|
378
|
+
// Bước 1: thay <br> thành token tạm
|
|
379
|
+
const normalizedHtml = html.replace(/<br\s*\/?>/gi, BREAK_TOKEN);
|
|
380
|
+
// Bước 2: tách theo token
|
|
381
|
+
const parts = normalizedHtml.split(BREAK_TOKEN);
|
|
382
|
+
const parser = new DOMParser();
|
|
383
|
+
const divs = [];
|
|
384
|
+
for (const raw of parts) {
|
|
385
|
+
const trimmed = raw.trim();
|
|
386
|
+
if (!trimmed)
|
|
387
|
+
continue;
|
|
388
|
+
// parse mỗi phần nhỏ như một document riêng
|
|
389
|
+
const doc = parser.parseFromString(trimmed, 'text/html');
|
|
390
|
+
const body = doc.body;
|
|
391
|
+
// Lấy lại nội dung bên trong body
|
|
392
|
+
divs.push(`<div>${body.innerHTML}</div>`);
|
|
393
|
+
}
|
|
394
|
+
return divs.join('');
|
|
395
|
+
};
|
|
396
|
+
const getDeltaFromHTML = async (html) => {
|
|
397
|
+
quill.root.innerHTML = html;
|
|
398
|
+
setTimeout(() => {
|
|
399
|
+
console.log(quill.getContents());
|
|
400
|
+
}, 1000);
|
|
401
|
+
await lastValueFrom(timer(1000));
|
|
402
|
+
return quill.getContents();
|
|
403
|
+
};
|
|
404
|
+
const processPasteData = async (e, config) => {
|
|
405
|
+
const element = config.element;
|
|
406
|
+
const files = e.clipboardData?.files;
|
|
407
|
+
if (files?.length) {
|
|
408
|
+
e.preventDefault();
|
|
409
|
+
config.handlerPasteFile?.(files);
|
|
410
|
+
config.callBack?.('file');
|
|
411
|
+
return;
|
|
412
|
+
}
|
|
413
|
+
// Lưu selection TRƯỚC khi prevent default
|
|
414
|
+
const selection = window.getSelection();
|
|
415
|
+
let savedRange = null;
|
|
416
|
+
if (selection && selection.rangeCount > 0) {
|
|
417
|
+
const range = selection.getRangeAt(0);
|
|
418
|
+
// Chỉ lưu nếu range nằm trong contentText element
|
|
419
|
+
const container = range.commonAncestorContainer;
|
|
420
|
+
const isInContentElement = element.contains(container.nodeType === Node.TEXT_NODE ? container.parentNode : container);
|
|
421
|
+
if (isInContentElement) {
|
|
422
|
+
savedRange = range.cloneRange();
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
// Prevent default để tự xử lý paste
|
|
426
|
+
e.preventDefault();
|
|
427
|
+
// Sử dụng Quill để clean HTML content
|
|
428
|
+
const htmlContent = e.clipboardData?.getData('text/html') || '';
|
|
429
|
+
const plainText = e.clipboardData?.getData('text/plain') || '';
|
|
430
|
+
let contentToInsert = (plainText || '').replace(/\n/g, '<br>');
|
|
431
|
+
if (htmlContent) {
|
|
432
|
+
contentToInsert = await getHTMLFromQuill(htmlContent);
|
|
433
|
+
}
|
|
434
|
+
if (!contentToInsert) {
|
|
435
|
+
config.callBack?.('no-content');
|
|
436
|
+
return;
|
|
437
|
+
}
|
|
438
|
+
if (savedRange) {
|
|
439
|
+
insertContentWithRange(contentToInsert, savedRange, element);
|
|
440
|
+
config.callBack?.('range');
|
|
441
|
+
return;
|
|
442
|
+
}
|
|
443
|
+
element.innerHTML += contentToInsert;
|
|
444
|
+
config.callBack?.('content');
|
|
445
|
+
};
|
|
446
|
+
const insertContentWithRange = (content, savedRange, element) => {
|
|
447
|
+
const selection = window.getSelection();
|
|
448
|
+
if (!selection) {
|
|
449
|
+
// Fallback: append vào cuối
|
|
450
|
+
element.innerHTML += content;
|
|
451
|
+
return;
|
|
452
|
+
}
|
|
453
|
+
// Restore selection
|
|
454
|
+
selection.removeAllRanges();
|
|
455
|
+
selection.addRange(savedRange);
|
|
456
|
+
// Xóa nội dung đã select (nếu có)
|
|
457
|
+
savedRange.deleteContents();
|
|
458
|
+
// Tạo document fragment từ HTML content
|
|
459
|
+
const tempDiv = document.createElement('div');
|
|
460
|
+
tempDiv.innerHTML = content;
|
|
461
|
+
const fragment = document.createDocumentFragment();
|
|
462
|
+
while (tempDiv.firstChild) {
|
|
463
|
+
fragment.appendChild(tempDiv.firstChild);
|
|
464
|
+
}
|
|
465
|
+
// Insert fragment tại vị trí range
|
|
466
|
+
savedRange.insertNode(fragment);
|
|
467
|
+
// Di chuyển cursor đến cuối nội dung vừa insert
|
|
468
|
+
if (fragment.lastChild) {
|
|
469
|
+
savedRange.setStartAfter(fragment.lastChild);
|
|
470
|
+
}
|
|
471
|
+
savedRange.collapse(true);
|
|
472
|
+
selection.removeAllRanges();
|
|
473
|
+
selection.addRange(savedRange);
|
|
474
|
+
};
|
|
367
475
|
|
|
368
476
|
class UtilsUrlSearchParams {
|
|
369
477
|
static instance;
|
|
@@ -380,17 +488,19 @@ class UtilsUrlSearchParams {
|
|
|
380
488
|
return this.instance;
|
|
381
489
|
}
|
|
382
490
|
static toStringParamObject(params) {
|
|
383
|
-
const paramsArr = Object.keys(params).map(key => {
|
|
491
|
+
const paramsArr = Object.keys(params).map((key) => {
|
|
384
492
|
return {
|
|
385
493
|
key,
|
|
386
|
-
value: params[key]
|
|
494
|
+
value: params[key],
|
|
387
495
|
};
|
|
388
496
|
});
|
|
389
497
|
return UtilsUrlSearchParams.ToString(paramsArr);
|
|
390
498
|
}
|
|
391
499
|
static ToString(params) {
|
|
392
500
|
let paramsStr = '';
|
|
393
|
-
params
|
|
501
|
+
params
|
|
502
|
+
.sort((item1, item2) => item1.key.localeCompare(item2.key))
|
|
503
|
+
.forEach((item) => {
|
|
394
504
|
const { key, value } = item;
|
|
395
505
|
paramsStr = `${paramsStr}${paramsStr ? '&' : ''}${key}=${value}`;
|
|
396
506
|
});
|
|
@@ -407,14 +517,14 @@ class UtilsUrlSearchParams {
|
|
|
407
517
|
}
|
|
408
518
|
const params = paramString.replace(/\S+[?]/g, '').split('&');
|
|
409
519
|
if (params) {
|
|
410
|
-
params.forEach(param => {
|
|
520
|
+
params.forEach((param) => {
|
|
411
521
|
if (param.indexOf('=') < 0) {
|
|
412
522
|
return;
|
|
413
523
|
}
|
|
414
524
|
let [key, value] = param.split('=');
|
|
415
525
|
key = key.replace(/[?&]+/g, '');
|
|
416
526
|
value = decodeURIComponent(value.replace(/\+/g, ' '));
|
|
417
|
-
if (!paramsBuild.some(param => param.key === key)) {
|
|
527
|
+
if (!paramsBuild.some((param) => param.key === key)) {
|
|
418
528
|
paramsBuild.push({ key, value });
|
|
419
529
|
}
|
|
420
530
|
});
|
|
@@ -422,7 +532,7 @@ class UtilsUrlSearchParams {
|
|
|
422
532
|
return paramsBuild;
|
|
423
533
|
}
|
|
424
534
|
set(key, value) {
|
|
425
|
-
const paramByKey = this.params.find(param => param.key === key);
|
|
535
|
+
const paramByKey = this.params.find((param) => param.key === key);
|
|
426
536
|
if (!paramByKey) {
|
|
427
537
|
this.params.push({ key, value: decodeURIComponent(value.replace(/\+/g, ' ')) });
|
|
428
538
|
return;
|
|
@@ -430,13 +540,13 @@ class UtilsUrlSearchParams {
|
|
|
430
540
|
paramByKey['value'] = value;
|
|
431
541
|
}
|
|
432
542
|
get(key) {
|
|
433
|
-
return this.params.find(param => param.key === key)?.value;
|
|
543
|
+
return this.params.find((param) => param.key === key)?.value;
|
|
434
544
|
}
|
|
435
545
|
has(key) {
|
|
436
|
-
return this.params.some(param => param.key === key);
|
|
546
|
+
return this.params.some((param) => param.key === key);
|
|
437
547
|
}
|
|
438
548
|
delete(key) {
|
|
439
|
-
const index = this.params.findIndex(param => param.key === key);
|
|
549
|
+
const index = this.params.findIndex((param) => param.key === key);
|
|
440
550
|
if (index >= 0) {
|
|
441
551
|
this.params.splice(index, 1);
|
|
442
552
|
}
|
|
@@ -450,7 +560,7 @@ class UtilsUrlSearchParams {
|
|
|
450
560
|
}
|
|
451
561
|
getParamObject() {
|
|
452
562
|
const params = {};
|
|
453
|
-
this.params.forEach(item => {
|
|
563
|
+
this.params.forEach((item) => {
|
|
454
564
|
params[item.key] = item.value;
|
|
455
565
|
});
|
|
456
566
|
return params;
|
|
@@ -478,7 +588,7 @@ const keyStore$1 = () => {
|
|
|
478
588
|
};
|
|
479
589
|
const encrypt = (plainData) => {
|
|
480
590
|
if (!keyStore$1()) {
|
|
481
|
-
throw Error(
|
|
591
|
+
throw Error('lỗi chưa setup key mã hóa');
|
|
482
592
|
}
|
|
483
593
|
const key = CryptoES.enc.Hex.parse(keyStore$1());
|
|
484
594
|
const iv = CryptoES.enc.Hex.parse(keyStore$1());
|
|
@@ -489,7 +599,7 @@ const encrypt = (plainData) => {
|
|
|
489
599
|
};
|
|
490
600
|
const decrypt = (encryptedData) => {
|
|
491
601
|
if (!keyStore$1()) {
|
|
492
|
-
throw Error(
|
|
602
|
+
throw Error('lỗi chưa setup key mã hóa');
|
|
493
603
|
}
|
|
494
604
|
const key = CryptoES.enc.Hex.parse(keyStore$1());
|
|
495
605
|
const iv = CryptoES.enc.Hex.parse(keyStore$1());
|
|
@@ -520,83 +630,143 @@ const uuid = () => {
|
|
|
520
630
|
};
|
|
521
631
|
|
|
522
632
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
}
|
|
534
|
-
if (instance instanceof UtilsHttpParamsRequest) {
|
|
535
|
-
this.params = instance.getInstance();
|
|
536
|
-
return;
|
|
537
|
-
}
|
|
538
|
-
if (instance instanceof HttpParams) {
|
|
539
|
-
this.params = instance;
|
|
540
|
-
return;
|
|
541
|
-
}
|
|
542
|
-
}
|
|
543
|
-
getInstance() {
|
|
544
|
-
return this.params;
|
|
545
|
-
}
|
|
546
|
-
setInstance(instance) {
|
|
547
|
-
if (instance instanceof UtilsHttpParamsRequest) {
|
|
548
|
-
this.params = instance.getInstance();
|
|
549
|
-
return;
|
|
550
|
-
}
|
|
551
|
-
if (instance instanceof HttpParams) {
|
|
552
|
-
this.params = instance;
|
|
553
|
-
return;
|
|
554
|
-
}
|
|
555
|
-
}
|
|
556
|
-
set(param, value) {
|
|
557
|
-
this.params = this.params.set(param, value);
|
|
558
|
-
return this;
|
|
633
|
+
/**
|
|
634
|
+
* Danh sách các constructor name nguy hiểm
|
|
635
|
+
*/
|
|
636
|
+
const DANGEROUS_CONSTRUCTOR_NAMES = ['Window', 'Document', 'HTMLDocument', 'HTMLElement', 'Element', 'Node', 'Location', 'Navigator', 'Screen', 'History', 'Storage', 'Console', 'Performance'];
|
|
637
|
+
/**
|
|
638
|
+
* Kiểm tra xem đối tượng có phải là browser global object không
|
|
639
|
+
*/
|
|
640
|
+
const isBrowserGlobalObject = (obj) => {
|
|
641
|
+
if (obj === null || typeof obj !== 'object') {
|
|
642
|
+
return false;
|
|
559
643
|
}
|
|
560
|
-
|
|
561
|
-
|
|
644
|
+
return obj instanceof Window || obj instanceof Document || obj === window || obj === document || obj === globalThis;
|
|
645
|
+
};
|
|
646
|
+
/**
|
|
647
|
+
* Kiểm tra xem đối tượng có phải là DOM object không
|
|
648
|
+
*/
|
|
649
|
+
const isDOMObject = (obj) => {
|
|
650
|
+
if (obj === null || typeof obj !== 'object') {
|
|
651
|
+
return false;
|
|
562
652
|
}
|
|
563
|
-
|
|
564
|
-
|
|
653
|
+
return obj instanceof HTMLElement || obj instanceof Node || obj instanceof Element;
|
|
654
|
+
};
|
|
655
|
+
/**
|
|
656
|
+
* Kiểm tra xem đối tượng có phải là browser API object không
|
|
657
|
+
*/
|
|
658
|
+
const isBrowserAPIObject = (obj) => {
|
|
659
|
+
if (obj === null || typeof obj !== 'object' || typeof window === 'undefined') {
|
|
660
|
+
return false;
|
|
565
661
|
}
|
|
566
|
-
|
|
567
|
-
|
|
662
|
+
return obj === window.location || obj === window.navigator || obj === window.screen || obj === window.history || obj === window.localStorage || obj === window.sessionStorage || obj === window.console || obj === window.performance;
|
|
663
|
+
};
|
|
664
|
+
/**
|
|
665
|
+
* Kiểm tra constructor name có nằm trong danh sách nguy hiểm không
|
|
666
|
+
*/
|
|
667
|
+
const hasDangerousConstructorName = (obj) => {
|
|
668
|
+
if (obj === null || typeof obj !== 'object') {
|
|
669
|
+
return false;
|
|
568
670
|
}
|
|
569
|
-
|
|
570
|
-
|
|
671
|
+
const constructorName = obj.constructor?.name;
|
|
672
|
+
return constructorName && DANGEROUS_CONSTRUCTOR_NAMES.includes(constructorName);
|
|
673
|
+
};
|
|
674
|
+
/**
|
|
675
|
+
* Kiểm tra xem đối tượng có phải là DOM object hoặc browser object nguy hiểm không
|
|
676
|
+
* Những đối tượng này có thể gây ra circular reference và maximum call stack
|
|
677
|
+
*/
|
|
678
|
+
const isDangerousObject = (obj) => {
|
|
679
|
+
if (obj === null || typeof obj !== 'object') {
|
|
680
|
+
return false;
|
|
571
681
|
}
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
682
|
+
return isBrowserGlobalObject(obj) || isDOMObject(obj) || isBrowserAPIObject(obj) || hasDangerousConstructorName(obj);
|
|
683
|
+
};
|
|
684
|
+
/**
|
|
685
|
+
* Kiểm tra đối tượng có phải là Angular/Framework object không
|
|
686
|
+
*/
|
|
687
|
+
const isFrameworkObject = (obj) => {
|
|
688
|
+
if (obj === null || typeof obj !== 'object') {
|
|
689
|
+
return false;
|
|
575
690
|
}
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
691
|
+
return obj instanceof TemplateRef || obj instanceof ElementRef;
|
|
692
|
+
};
|
|
693
|
+
/**
|
|
694
|
+
* Kiểm tra đối tượng có phải là File/Blob object không
|
|
695
|
+
*/
|
|
696
|
+
const isFileObject = (obj) => {
|
|
697
|
+
if (obj === null || typeof obj !== 'object') {
|
|
698
|
+
return false;
|
|
579
699
|
}
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
700
|
+
return obj instanceof File || obj instanceof Blob || Object.prototype.toString.call(obj) === '[object File]';
|
|
701
|
+
};
|
|
702
|
+
/**
|
|
703
|
+
* Kiểm tra đối tượng có phải là Built-in object không
|
|
704
|
+
*/
|
|
705
|
+
const isBuiltInObject = (obj) => {
|
|
706
|
+
if (obj === null || typeof obj !== 'object') {
|
|
707
|
+
return false;
|
|
583
708
|
}
|
|
584
|
-
|
|
585
|
-
|
|
709
|
+
return obj instanceof Date || obj instanceof RegExp || obj instanceof HttpParams;
|
|
710
|
+
};
|
|
711
|
+
/**
|
|
712
|
+
* Kiểm tra đối tượng có phải là Async object không
|
|
713
|
+
*/
|
|
714
|
+
const isAsyncObject = (obj) => {
|
|
715
|
+
if (obj === null || typeof obj !== 'object') {
|
|
716
|
+
return false;
|
|
586
717
|
}
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
718
|
+
return obj instanceof Promise || obj instanceof Observable;
|
|
719
|
+
};
|
|
720
|
+
/**
|
|
721
|
+
* Kiểm tra đối tượng có phải là Special object cần bỏ qua không
|
|
722
|
+
* Bao gồm: Framework objects, File objects, Built-in objects, Async objects
|
|
723
|
+
*/
|
|
724
|
+
const isSpecialObject = (obj) => {
|
|
725
|
+
return isFrameworkObject(obj) || isFileObject(obj) || isBuiltInObject(obj) || isAsyncObject(obj);
|
|
726
|
+
};
|
|
727
|
+
/**
|
|
728
|
+
* Kiểm tra đối tượng có phải là dayjs object không
|
|
729
|
+
*/
|
|
730
|
+
const isDayjsObject = (obj) => {
|
|
731
|
+
return dayjs.isDayjs(obj);
|
|
732
|
+
};
|
|
733
|
+
/**
|
|
734
|
+
* Kiểm tra đối tượng có phải là object cần bỏ qua trong quá trình convert không
|
|
735
|
+
*/
|
|
736
|
+
const isSkippableObject = (obj) => {
|
|
737
|
+
return isDangerousObject(obj) || isSpecialObject(obj);
|
|
738
|
+
};
|
|
739
|
+
/**
|
|
740
|
+
* Kiểm tra đối tượng có phải là Map object không
|
|
741
|
+
*/
|
|
742
|
+
const isMapObject = (obj) => {
|
|
743
|
+
return obj instanceof Map;
|
|
744
|
+
};
|
|
745
|
+
/**
|
|
746
|
+
* Kiểm tra đối tượng có phải là Set object không
|
|
747
|
+
*/
|
|
748
|
+
const isSetObject = (obj) => {
|
|
749
|
+
return obj instanceof Set;
|
|
750
|
+
};
|
|
751
|
+
/**
|
|
752
|
+
* Kiểm tra đối tượng có phải là Array object không
|
|
753
|
+
*/
|
|
754
|
+
const isArrayObject = (obj) => {
|
|
755
|
+
return Array.isArray(obj);
|
|
756
|
+
};
|
|
757
|
+
/**
|
|
758
|
+
* Kiểm tra đối tượng có phải là object cần trả về nguyên trạng không
|
|
759
|
+
* Bao gồm: dangerous objects, special objects, dayjs objects
|
|
760
|
+
*/
|
|
761
|
+
const isReturnAsIsObject = (obj) => {
|
|
762
|
+
return isSkippableObject(obj) || isDayjsObject(obj);
|
|
763
|
+
};
|
|
764
|
+
/**
|
|
765
|
+
* Kiểm tra xem đối tượng có an toàn để clone/convert không
|
|
766
|
+
*/
|
|
767
|
+
const isSafeToProcess = (obj) => {
|
|
768
|
+
return !isDangerousObject(obj);
|
|
769
|
+
};
|
|
600
770
|
|
|
601
771
|
let key = '12~@#loqwsxacva(3rdhaq12';
|
|
602
772
|
/**
|
|
@@ -614,7 +784,7 @@ const keyStore = () => {
|
|
|
614
784
|
};
|
|
615
785
|
const encrypt3rd = (plainData) => {
|
|
616
786
|
if (!keyStore()) {
|
|
617
|
-
throw Error(
|
|
787
|
+
throw Error('lỗi chưa setup key mã hóa');
|
|
618
788
|
}
|
|
619
789
|
const key = CryptoES.enc.Hex.parse(keyStore());
|
|
620
790
|
const iv = CryptoES.enc.Hex.parse(keyStore());
|
|
@@ -625,7 +795,7 @@ const encrypt3rd = (plainData) => {
|
|
|
625
795
|
};
|
|
626
796
|
const decrypt3rd = (encryptedData) => {
|
|
627
797
|
if (!keyStore()) {
|
|
628
|
-
throw Error(
|
|
798
|
+
throw Error('lỗi chưa setup key mã hóa');
|
|
629
799
|
}
|
|
630
800
|
const key = CryptoES.enc.Hex.parse(keyStore());
|
|
631
801
|
const iv = CryptoES.enc.Hex.parse(keyStore());
|
|
@@ -672,7 +842,9 @@ class UtilsCommunicateMicro {
|
|
|
672
842
|
if (!this.subs.get(COMMUNICATE_MICRO_KEY_GET_ALL_MESSAGE)) {
|
|
673
843
|
this.subs.set(COMMUNICATE_MICRO_KEY_GET_ALL_MESSAGE, UtilsCommunicateMicro.allMessageSub);
|
|
674
844
|
}
|
|
675
|
-
fromEvent(currentWindow, 'message')
|
|
845
|
+
fromEvent(currentWindow, 'message')
|
|
846
|
+
.pipe(takeUntil(onDestroy))
|
|
847
|
+
.subscribe((e) => {
|
|
676
848
|
const event = { data: { ...e.data } };
|
|
677
849
|
const data = event.data;
|
|
678
850
|
const type = data.type;
|
|
@@ -700,7 +872,9 @@ class UtilsCommunicateMicro {
|
|
|
700
872
|
this.allMessageSub.next(event);
|
|
701
873
|
}
|
|
702
874
|
});
|
|
703
|
-
UtilsCommunicateMicro.GetMessage(UtilsCache.typeKeyClearLocalStorage)
|
|
875
|
+
UtilsCommunicateMicro.GetMessage(UtilsCache.typeKeyClearLocalStorage)
|
|
876
|
+
.pipe(filter((e) => e.data.response !== UtilsCache.idService), takeUntil(onDestroy))
|
|
877
|
+
.subscribe(() => {
|
|
704
878
|
console.log('clear all cache by event');
|
|
705
879
|
UtilsCache.ClearAll();
|
|
706
880
|
});
|
|
@@ -709,10 +883,10 @@ class UtilsCommunicateMicro {
|
|
|
709
883
|
data = this.convertData(data);
|
|
710
884
|
try {
|
|
711
885
|
if (isEmbedFrame()) {
|
|
712
|
-
window?.parent?.postMessage(data,
|
|
886
|
+
window?.parent?.postMessage(data, '*');
|
|
713
887
|
return;
|
|
714
888
|
}
|
|
715
|
-
window?.top?.postMessage(data,
|
|
889
|
+
window?.top?.postMessage(data, '*');
|
|
716
890
|
}
|
|
717
891
|
catch (error) {
|
|
718
892
|
console.log(error);
|
|
@@ -720,8 +894,8 @@ class UtilsCommunicateMicro {
|
|
|
720
894
|
}
|
|
721
895
|
static PostMessageToChildren(data) {
|
|
722
896
|
data = this.convertData(data);
|
|
723
|
-
const iframes = document.querySelectorAll(
|
|
724
|
-
Array.from(iframes).forEach(iframe => {
|
|
897
|
+
const iframes = document.querySelectorAll('iframe');
|
|
898
|
+
Array.from(iframes).forEach((iframe) => {
|
|
725
899
|
iframe?.contentWindow?.postMessage(data, '*');
|
|
726
900
|
});
|
|
727
901
|
}
|
|
@@ -759,7 +933,7 @@ class UtilsCommunicateMicro {
|
|
|
759
933
|
}
|
|
760
934
|
static GetMessage(messageType) {
|
|
761
935
|
if (!this.initdEvent) {
|
|
762
|
-
throw Error(
|
|
936
|
+
throw Error('chưa khơi tạo hàm lắng nghe sự kiện, gọi UtilsCommunicateMicro.initEvent(window) tại root component');
|
|
763
937
|
}
|
|
764
938
|
if (typeof messageType === 'string') {
|
|
765
939
|
let sub = this.subs.get(messageType);
|
|
@@ -787,8 +961,8 @@ class UtilsCommunicateMicro {
|
|
|
787
961
|
return sub;
|
|
788
962
|
}
|
|
789
963
|
static initSubject(subRoot, messageType) {
|
|
790
|
-
messageType.forEach(key => {
|
|
791
|
-
this.GetMessage(key).subscribe(e => {
|
|
964
|
+
messageType.forEach((key) => {
|
|
965
|
+
this.GetMessage(key).subscribe((e) => {
|
|
792
966
|
subRoot.next(e);
|
|
793
967
|
});
|
|
794
968
|
});
|
|
@@ -796,33 +970,33 @@ class UtilsCommunicateMicro {
|
|
|
796
970
|
}
|
|
797
971
|
|
|
798
972
|
class UtilsLanguageConstants {
|
|
799
|
-
static VI =
|
|
800
|
-
static EN =
|
|
801
|
-
static FR =
|
|
802
|
-
static DE =
|
|
803
|
-
static ES =
|
|
804
|
-
static ZH =
|
|
805
|
-
static ZH_TW =
|
|
806
|
-
static JA =
|
|
807
|
-
static KO =
|
|
808
|
-
static RU =
|
|
809
|
-
static IT =
|
|
810
|
-
static PT =
|
|
811
|
-
static TH =
|
|
812
|
-
static ID =
|
|
813
|
-
static MS =
|
|
814
|
-
static AR =
|
|
815
|
-
static HI =
|
|
816
|
-
static BN =
|
|
817
|
-
static TR =
|
|
818
|
-
static NL =
|
|
819
|
-
static KM =
|
|
820
|
-
static LO =
|
|
821
|
-
static MY =
|
|
822
|
-
static TL =
|
|
823
|
-
static CEB =
|
|
824
|
-
static JV =
|
|
825
|
-
static SU =
|
|
973
|
+
static VI = 'vi'; // Tiếng Việt
|
|
974
|
+
static EN = 'en'; // Tiếng Anh
|
|
975
|
+
static FR = 'fr'; // Tiếng Pháp
|
|
976
|
+
static DE = 'de'; // Tiếng Đức
|
|
977
|
+
static ES = 'es'; // Tiếng Tây Ban Nha
|
|
978
|
+
static ZH = 'zh'; // Tiếng Trung (Giản thể)
|
|
979
|
+
static ZH_TW = 'zh-TW'; // Tiếng Trung (Phồn thể)
|
|
980
|
+
static JA = 'ja'; // Tiếng Nhật
|
|
981
|
+
static KO = 'ko'; // Tiếng Hàn
|
|
982
|
+
static RU = 'ru'; // Tiếng Nga
|
|
983
|
+
static IT = 'it'; // Tiếng Ý
|
|
984
|
+
static PT = 'pt'; // Tiếng Bồ Đào Nha
|
|
985
|
+
static TH = 'th'; // Tiếng Thái
|
|
986
|
+
static ID = 'id'; // Tiếng Indonesia
|
|
987
|
+
static MS = 'ms'; // Tiếng Malaysia
|
|
988
|
+
static AR = 'ar'; // Tiếng Ả Rập
|
|
989
|
+
static HI = 'hi'; // Tiếng Hindi
|
|
990
|
+
static BN = 'bn'; // Tiếng Bengal
|
|
991
|
+
static TR = 'tr'; // Tiếng Thổ Nhĩ Kỳ
|
|
992
|
+
static NL = 'nl'; // Tiếng Hà Lan
|
|
993
|
+
static KM = 'km'; // Tiếng Khmer (Campuchia)
|
|
994
|
+
static LO = 'lo'; // Tiếng Lào
|
|
995
|
+
static MY = 'my'; // Tiếng Miến Điện (Myanmar)
|
|
996
|
+
static TL = 'tl'; // Tiếng Tagalog (Philippines)
|
|
997
|
+
static CEB = 'ceb'; // Tiếng Cebuano (Philippines)
|
|
998
|
+
static JV = 'jv'; // Tiếng Java (Indonesia)
|
|
999
|
+
static SU = 'su'; // Tiếng Sundanese (Indonesia)
|
|
826
1000
|
// Ngôn ngữ mặc định
|
|
827
1001
|
static defaultLang = UtilsLanguageConstants.VI;
|
|
828
1002
|
// Danh sách các ngôn ngữ được hỗ trợ
|
|
@@ -908,7 +1082,7 @@ class UtilsCache {
|
|
|
908
1082
|
return this.Get(this.languageKeyCache, UtilsLanguageConstants.defaultLang);
|
|
909
1083
|
}
|
|
910
1084
|
static openDB() {
|
|
911
|
-
return new Promise(resolve => {
|
|
1085
|
+
return new Promise((resolve) => {
|
|
912
1086
|
const request = indexedDB.open(this.dbName, this.dbVersion);
|
|
913
1087
|
request.onupgradeneeded = (event) => {
|
|
914
1088
|
const db = event.target.result;
|
|
@@ -980,7 +1154,7 @@ class UtilsCache {
|
|
|
980
1154
|
clear: () => {
|
|
981
1155
|
this.storage = {};
|
|
982
1156
|
localStorage.clear();
|
|
983
|
-
}
|
|
1157
|
+
},
|
|
984
1158
|
};
|
|
985
1159
|
}
|
|
986
1160
|
static getLocalStorageFake() {
|
|
@@ -999,7 +1173,7 @@ class UtilsCache {
|
|
|
999
1173
|
},
|
|
1000
1174
|
clear: () => {
|
|
1001
1175
|
this.storage = {};
|
|
1002
|
-
}
|
|
1176
|
+
},
|
|
1003
1177
|
};
|
|
1004
1178
|
}
|
|
1005
1179
|
static async GetAsync(key, default_value, isKeyMD5 = false) {
|
|
@@ -1018,7 +1192,7 @@ class UtilsCache {
|
|
|
1018
1192
|
if (data.expire === this.CACHE_EXPIRE_NONE) {
|
|
1019
1193
|
return resolve(data.json);
|
|
1020
1194
|
}
|
|
1021
|
-
const currentMillisecond =
|
|
1195
|
+
const currentMillisecond = new Date().valueOf() / 1000;
|
|
1022
1196
|
if (data.expire < currentMillisecond) {
|
|
1023
1197
|
return resolve(default_value);
|
|
1024
1198
|
}
|
|
@@ -1031,6 +1205,7 @@ class UtilsCache {
|
|
|
1031
1205
|
});
|
|
1032
1206
|
}
|
|
1033
1207
|
static Get(key, default_value) {
|
|
1208
|
+
// support cho những file không thể inject UtilsCache
|
|
1034
1209
|
if (!key) {
|
|
1035
1210
|
return this.GetDefaultValueBySpecificKey(key, default_value);
|
|
1036
1211
|
}
|
|
@@ -1043,7 +1218,7 @@ class UtilsCache {
|
|
|
1043
1218
|
if (data.expire === this.CACHE_EXPIRE_NONE) {
|
|
1044
1219
|
return data.value ?? default_value;
|
|
1045
1220
|
}
|
|
1046
|
-
const currentMillisecond =
|
|
1221
|
+
const currentMillisecond = new Date().valueOf() / 1000;
|
|
1047
1222
|
if (data.expire < currentMillisecond) {
|
|
1048
1223
|
return this.GetDefaultValueBySpecificKey(key, default_value);
|
|
1049
1224
|
}
|
|
@@ -1058,11 +1233,12 @@ class UtilsCache {
|
|
|
1058
1233
|
return default_value;
|
|
1059
1234
|
}
|
|
1060
1235
|
static async SetAsync(key, value, expireTimeBySecond = this.CACHE_EXPIRE_TIME_DEFAULT, isKeyMD5 = false) {
|
|
1236
|
+
// support inject UtilsCache
|
|
1061
1237
|
return new Promise(async (resolve) => {
|
|
1062
1238
|
const objectStore = await this.getObjectStore();
|
|
1063
1239
|
key = isKeyMD5 ? key : md5(key);
|
|
1064
1240
|
try {
|
|
1065
|
-
const currentMillisecond = expireTimeBySecond === this.CACHE_EXPIRE_NONE ? this.CACHE_EXPIRE_NONE :
|
|
1241
|
+
const currentMillisecond = expireTimeBySecond === this.CACHE_EXPIRE_NONE ? this.CACHE_EXPIRE_NONE : new Date().valueOf() / 1000 + expireTimeBySecond;
|
|
1066
1242
|
const data = {
|
|
1067
1243
|
value: encrypt(JSON.stringify({ json: value, expire: currentMillisecond })),
|
|
1068
1244
|
};
|
|
@@ -1088,10 +1264,11 @@ class UtilsCache {
|
|
|
1088
1264
|
});
|
|
1089
1265
|
}
|
|
1090
1266
|
static Set(key, value, expireTimeBySecond = this.CACHE_EXPIRE_TIME_DEFAULT) {
|
|
1091
|
-
|
|
1267
|
+
// support cho những file không inject UtilsCache
|
|
1268
|
+
const currentMillisecond = expireTimeBySecond === this.CACHE_EXPIRE_NONE ? this.CACHE_EXPIRE_NONE : new Date().valueOf() / 1000 + expireTimeBySecond;
|
|
1092
1269
|
const data = {
|
|
1093
1270
|
value: value,
|
|
1094
|
-
expire: currentMillisecond
|
|
1271
|
+
expire: currentMillisecond,
|
|
1095
1272
|
};
|
|
1096
1273
|
try {
|
|
1097
1274
|
this.LocalStorage.setItem(key, encrypt(JSON.stringify(data)));
|
|
@@ -1146,13 +1323,13 @@ class UtilsCache {
|
|
|
1146
1323
|
const data = {
|
|
1147
1324
|
type: this.typeKeyClearLocalStorage,
|
|
1148
1325
|
response: {
|
|
1149
|
-
idEvent: this.idService
|
|
1150
|
-
}
|
|
1326
|
+
idEvent: this.idService,
|
|
1327
|
+
},
|
|
1151
1328
|
};
|
|
1152
1329
|
UtilsCommunicateMicro.PostMessageToParent(data);
|
|
1153
1330
|
}
|
|
1154
1331
|
const keys = [...this.listKeyKeepWhenClearALll];
|
|
1155
|
-
Object.keys(this.LocalStorage).forEach(key => {
|
|
1332
|
+
Object.keys(this.LocalStorage).forEach((key) => {
|
|
1156
1333
|
if (key.includes('kc-callback-')) {
|
|
1157
1334
|
keys.push(key);
|
|
1158
1335
|
}
|
|
@@ -1198,7 +1375,7 @@ class UtilsCache {
|
|
|
1198
1375
|
if (!Array.isArray(data)) {
|
|
1199
1376
|
return resolve({});
|
|
1200
1377
|
}
|
|
1201
|
-
data.forEach(obj => {
|
|
1378
|
+
data.forEach((obj) => {
|
|
1202
1379
|
if (obj[this.itemIndexByKey].startsWith(keyCacheStartWith)) {
|
|
1203
1380
|
this.ClearAsync(obj[this.itemIndexByKey], true);
|
|
1204
1381
|
}
|
|
@@ -1216,7 +1393,7 @@ class UtilsCache {
|
|
|
1216
1393
|
if (!keys || !keys.length) {
|
|
1217
1394
|
return;
|
|
1218
1395
|
}
|
|
1219
|
-
keys.forEach(key => {
|
|
1396
|
+
keys.forEach((key) => {
|
|
1220
1397
|
if (key.startsWith(keyCache)) {
|
|
1221
1398
|
this.Clear(key);
|
|
1222
1399
|
}
|
|
@@ -1231,8 +1408,9 @@ class UtilsCache {
|
|
|
1231
1408
|
resolve({ deleteSuccess: true });
|
|
1232
1409
|
};
|
|
1233
1410
|
request.onerror = (event) => {
|
|
1234
|
-
|
|
1235
|
-
|
|
1411
|
+
const error = event.target.error;
|
|
1412
|
+
console.trace('Error deleting database:', error);
|
|
1413
|
+
resolve({ messageError: get(error || {}, 'message'), deleteSuccess: false });
|
|
1236
1414
|
};
|
|
1237
1415
|
request.onblocked = () => {
|
|
1238
1416
|
console.trace('Delete request is blocked');
|
|
@@ -1247,7 +1425,7 @@ dayjs.extend(updateLocale);
|
|
|
1247
1425
|
dayjs.extend(utc);
|
|
1248
1426
|
dayjs.extend(timezone);
|
|
1249
1427
|
dayjs.extend(customParseFormat);
|
|
1250
|
-
let timeZoneSetup =
|
|
1428
|
+
let timeZoneSetup = 'Asia/Ho_Chi_Minh';
|
|
1251
1429
|
const setDefaultTimeZone = (localeZone = timeZoneSetup) => {
|
|
1252
1430
|
timeZoneSetup = localeZone;
|
|
1253
1431
|
dayjs.tz.setDefault(localeZone);
|
|
@@ -1257,23 +1435,25 @@ const updateFunctionFormatDate = (functionCustom) => {
|
|
|
1257
1435
|
functionFormatDate = functionCustom;
|
|
1258
1436
|
};
|
|
1259
1437
|
/**
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
*/
|
|
1438
|
+
* @description Lấy đối tượng dayjs theo config
|
|
1439
|
+
* @param config nếu không có config sẽ trả về đối tượng dayjs là thời gian hiện tại
|
|
1440
|
+
* @param config.date thời gian cần lấy
|
|
1441
|
+
* @param config.returnDayjsIfConfigDateNotExist true nếu muốn trả về đối tượng dayjs nếu config.date không có
|
|
1442
|
+
* @param config.utc true nếu muốn lấy thời gian UTC
|
|
1443
|
+
* @param config.formatOfDate định dạng thời gian đang được truyền vào
|
|
1444
|
+
*/
|
|
1267
1445
|
const getDayjs = (config) => {
|
|
1446
|
+
// helper cast để tránh lặp lại kiểu điều kiện ở các return
|
|
1447
|
+
const out = (v) => v;
|
|
1268
1448
|
if (!config) {
|
|
1269
|
-
return dayjs().tz();
|
|
1449
|
+
return out(dayjs().tz());
|
|
1270
1450
|
}
|
|
1271
1451
|
config.date = !config.date && config.returnDayjsIfConfigDateNotExist ? dayjs().tz() : config.date;
|
|
1272
1452
|
if (typeof config.date === 'number') {
|
|
1273
1453
|
config.date = dayjs.unix(config.date);
|
|
1274
1454
|
}
|
|
1275
1455
|
if (!config.date) {
|
|
1276
|
-
return undefined;
|
|
1456
|
+
return out(undefined);
|
|
1277
1457
|
}
|
|
1278
1458
|
let { date, utc, formatOfDate } = config;
|
|
1279
1459
|
while (isSignal(date)) {
|
|
@@ -1287,18 +1467,18 @@ const getDayjs = (config) => {
|
|
|
1287
1467
|
}
|
|
1288
1468
|
if (utc) {
|
|
1289
1469
|
if (formatOfDate) {
|
|
1290
|
-
return dayjs(date, formatOfDate).utc();
|
|
1470
|
+
return out(dayjs(date, formatOfDate).utc());
|
|
1291
1471
|
}
|
|
1292
1472
|
const dateInputIsUTC = (dayjs.isDayjs(date) && date.isUTC()) || (typeof date === 'string' && date.includes('Z'));
|
|
1293
1473
|
if (dateInputIsUTC) {
|
|
1294
|
-
return dayjs(date);
|
|
1474
|
+
return out(dayjs(date));
|
|
1295
1475
|
}
|
|
1296
|
-
return dayjs(date).utc();
|
|
1476
|
+
return out(dayjs(date).utc());
|
|
1297
1477
|
}
|
|
1298
1478
|
if (typeof date === 'string' && !date.includes('Z') && !date.includes('+')) {
|
|
1299
|
-
return (formatOfDate ? dayjs.tz(date, formatOfDate, config.localeZone || timeZoneSetup) : dayjs.tz(date, config.localeZone || timeZoneSetup));
|
|
1479
|
+
return out(formatOfDate ? dayjs.tz(date, formatOfDate, config.localeZone || timeZoneSetup) : dayjs.tz(date, config.localeZone || timeZoneSetup));
|
|
1300
1480
|
}
|
|
1301
|
-
return (formatOfDate ? dayjs(date, formatOfDate) : dayjs(date)).tz();
|
|
1481
|
+
return out((formatOfDate ? dayjs(date, formatOfDate) : dayjs(date)).tz());
|
|
1302
1482
|
};
|
|
1303
1483
|
/**
|
|
1304
1484
|
* @description Kiểm tra xem hai ngày có khác nhau không (khác ngày trong tuần)
|
|
@@ -1356,7 +1536,7 @@ const formatDate = (date, formatOutput = 'YYYY/MM/DD HH:mm', lang, formatInput)
|
|
|
1356
1536
|
date = getDayjs({ date, formatOfDate: formatInput }).locale(lang);
|
|
1357
1537
|
if (lang === 'vi') {
|
|
1358
1538
|
dayjs.updateLocale('vi', {
|
|
1359
|
-
monthsShort: 'Thg 1_Thg 2_Thg 3_Thg 4_Thg 5_Thg 6_Thg 7_Thg 8_Thg 9_Thg 10_Thg 11_Thg 12'.split('_')
|
|
1539
|
+
monthsShort: 'Thg 1_Thg 2_Thg 3_Thg 4_Thg 5_Thg 6_Thg 7_Thg 8_Thg 9_Thg 10_Thg 11_Thg 12'.split('_'),
|
|
1360
1540
|
});
|
|
1361
1541
|
}
|
|
1362
1542
|
return date.format(getFormatData(getTypeByFormat(formatOutput), lang)) || '';
|
|
@@ -1421,6 +1601,207 @@ const getFormatData = (type, lang) => {
|
|
|
1421
1601
|
}
|
|
1422
1602
|
};
|
|
1423
1603
|
|
|
1604
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
1605
|
+
const UtilsHttpParamsRequestInstance = (options, instance) => {
|
|
1606
|
+
return new UtilsHttpParamsRequest(options, instance);
|
|
1607
|
+
};
|
|
1608
|
+
class UtilsHttpParamsRequest extends HttpParams {
|
|
1609
|
+
params = new HttpParams();
|
|
1610
|
+
constructor(options, instance) {
|
|
1611
|
+
super(options);
|
|
1612
|
+
if (!instance) {
|
|
1613
|
+
this.params = new HttpParams(options);
|
|
1614
|
+
return;
|
|
1615
|
+
}
|
|
1616
|
+
if (instance instanceof UtilsHttpParamsRequest) {
|
|
1617
|
+
this.params = instance.getInstance();
|
|
1618
|
+
return;
|
|
1619
|
+
}
|
|
1620
|
+
if (instance instanceof HttpParams) {
|
|
1621
|
+
this.params = instance;
|
|
1622
|
+
return;
|
|
1623
|
+
}
|
|
1624
|
+
}
|
|
1625
|
+
getInstance() {
|
|
1626
|
+
return this.params;
|
|
1627
|
+
}
|
|
1628
|
+
setInstance(instance) {
|
|
1629
|
+
if (instance instanceof UtilsHttpParamsRequest) {
|
|
1630
|
+
this.params = instance.getInstance();
|
|
1631
|
+
return;
|
|
1632
|
+
}
|
|
1633
|
+
if (instance instanceof HttpParams) {
|
|
1634
|
+
this.params = instance;
|
|
1635
|
+
return;
|
|
1636
|
+
}
|
|
1637
|
+
}
|
|
1638
|
+
set(param, value) {
|
|
1639
|
+
this.params = this.params.set(param, value);
|
|
1640
|
+
return this;
|
|
1641
|
+
}
|
|
1642
|
+
has(param) {
|
|
1643
|
+
return this.params.has(param);
|
|
1644
|
+
}
|
|
1645
|
+
get(param) {
|
|
1646
|
+
return this.params.get(param);
|
|
1647
|
+
}
|
|
1648
|
+
getAll(param) {
|
|
1649
|
+
return this.params.getAll(param);
|
|
1650
|
+
}
|
|
1651
|
+
keys() {
|
|
1652
|
+
return this.params.keys();
|
|
1653
|
+
}
|
|
1654
|
+
append(param, value) {
|
|
1655
|
+
this.params = this.params.append(param, value);
|
|
1656
|
+
return this;
|
|
1657
|
+
}
|
|
1658
|
+
appendAll(params) {
|
|
1659
|
+
this.params = this.params.appendAll(params);
|
|
1660
|
+
return this;
|
|
1661
|
+
}
|
|
1662
|
+
delete(param, value) {
|
|
1663
|
+
this.params = this.params.delete(param, value);
|
|
1664
|
+
return this;
|
|
1665
|
+
}
|
|
1666
|
+
toString() {
|
|
1667
|
+
return this.params.toString();
|
|
1668
|
+
}
|
|
1669
|
+
}
|
|
1670
|
+
// Demo su dung GET_PATH_VARIABLE
|
|
1671
|
+
// interface Person {
|
|
1672
|
+
// name: string;
|
|
1673
|
+
// age: number;
|
|
1674
|
+
// location: string;
|
|
1675
|
+
// }
|
|
1676
|
+
// type c = GET_PATH_VARIABLE<Person, unknown>;
|
|
1677
|
+
// const a: c = {
|
|
1678
|
+
// "pathVariable-age": 1,
|
|
1679
|
+
// "pathVariable-location": '12',
|
|
1680
|
+
// "pathVariable-name": '124',
|
|
1681
|
+
// };
|
|
1682
|
+
|
|
1683
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
1684
|
+
/**
|
|
1685
|
+
* Chuyển đổi một đối tượng hoặc giá trị thành signal
|
|
1686
|
+
* @param data Dữ liệu cần chuyển đổi thành signal
|
|
1687
|
+
* @param cloneDeepIfNotSignal Có thực hiện sao chép sâu dữ liệu trước khi chuyển đổi hay không nếu data không phải signal. Mặc định là true.
|
|
1688
|
+
* Đặt false nếu muốn giữ nguyên tham chiếu đến dữ liệu gốc.
|
|
1689
|
+
* Nếu muốn sao chép sâu đối tượng signal thì đặt cloneDeepIfNotSignal là true và acceptConvertObjectInnerWritableSignal là true.
|
|
1690
|
+
* @param isSignalPrimitiveType Có chuyển đổi các giá trị nguyên thủy (string, number, boolean) thành signal hay không. Mặc định là false.
|
|
1691
|
+
* Đặt true nếu muốn bọc các giá trị nguyên thủy trong signal.
|
|
1692
|
+
* @param acceptConvertObjectInnerWritableSignal Có tiếp tục tìm kiếm và chuyển đổi các đối tượng bên trong signal hay không. Mặc định là false.
|
|
1693
|
+
* Đặt true nếu muốn tìm và chuyển đổi các đối tượng bên trong signal hoặc chính nó thành signal mới.
|
|
1694
|
+
* @returns Dữ liệu đã được chuyển đổi theo kiểu T
|
|
1695
|
+
*/
|
|
1696
|
+
const convertObjectToSignal = (data, cloneDeepIfNotSignal = true, isSignalPrimitiveType = false, acceptConvertObjectInnerWritableSignal = false, seen = new WeakMap()) => {
|
|
1697
|
+
if ((data === null || typeof data !== 'object') && !isSignal(data)) {
|
|
1698
|
+
return (isSignalPrimitiveType ? signal(data) : data);
|
|
1699
|
+
}
|
|
1700
|
+
if (seen.has(data)) {
|
|
1701
|
+
return seen.get(data);
|
|
1702
|
+
}
|
|
1703
|
+
if (isSignal(data)) {
|
|
1704
|
+
if (!acceptConvertObjectInnerWritableSignal) {
|
|
1705
|
+
return data;
|
|
1706
|
+
}
|
|
1707
|
+
seen.set(data, convertObjectToSignal(data(), cloneDeepIfNotSignal, isSignalPrimitiveType, acceptConvertObjectInnerWritableSignal, seen));
|
|
1708
|
+
return seen.get(data);
|
|
1709
|
+
}
|
|
1710
|
+
if (isArrayObject(data)) {
|
|
1711
|
+
seen.set(data, signal(data.map((item) => convertObjectToSignal(item, cloneDeepIfNotSignal, isSignalPrimitiveType, acceptConvertObjectInnerWritableSignal, seen))));
|
|
1712
|
+
return seen.get(data);
|
|
1713
|
+
}
|
|
1714
|
+
if (isMapObject(data)) {
|
|
1715
|
+
const mapCopy = new Map();
|
|
1716
|
+
Array.from(data.keys()).forEach((key) => {
|
|
1717
|
+
mapCopy.set(key, convertObjectToSignal(data.get(key), cloneDeepIfNotSignal, isSignalPrimitiveType, acceptConvertObjectInnerWritableSignal));
|
|
1718
|
+
});
|
|
1719
|
+
seen.set(data, signal(mapCopy));
|
|
1720
|
+
return seen.get(data);
|
|
1721
|
+
}
|
|
1722
|
+
// Bỏ qua các đối tượng async
|
|
1723
|
+
if (isAsyncObject(data)) {
|
|
1724
|
+
return data;
|
|
1725
|
+
}
|
|
1726
|
+
data = signal(cloneDeepIfNotSignal ? { ...data } : data);
|
|
1727
|
+
seen.set(data, data);
|
|
1728
|
+
for (const key in data()) {
|
|
1729
|
+
const value = data()[key];
|
|
1730
|
+
// Bỏ qua các đối tượng nguy hiểm và đặc biệt
|
|
1731
|
+
if (isReturnAsIsObject(value)) {
|
|
1732
|
+
continue;
|
|
1733
|
+
}
|
|
1734
|
+
if (Object.prototype.hasOwnProperty.call(data(), key)) {
|
|
1735
|
+
data()[key] = convertObjectToSignal(value, cloneDeepIfNotSignal, isSignalPrimitiveType, acceptConvertObjectInnerWritableSignal);
|
|
1736
|
+
}
|
|
1737
|
+
}
|
|
1738
|
+
return data;
|
|
1739
|
+
};
|
|
1740
|
+
const convertSignalToObject = (data, isCloneDeep = true, seen = new WeakMap()) => {
|
|
1741
|
+
let ignoreCheckSeenHasDataAfterWhile = false;
|
|
1742
|
+
while (isSignal(data) && !seen.has(data)) {
|
|
1743
|
+
const dataConvert = data();
|
|
1744
|
+
if (typeof dataConvert === 'object') {
|
|
1745
|
+
if (dataConvert === null || isReturnAsIsObject(dataConvert)) {
|
|
1746
|
+
return dataConvert;
|
|
1747
|
+
}
|
|
1748
|
+
seen.set(dataConvert, dataConvert);
|
|
1749
|
+
data = dataConvert;
|
|
1750
|
+
ignoreCheckSeenHasDataAfterWhile = true;
|
|
1751
|
+
break;
|
|
1752
|
+
}
|
|
1753
|
+
seen.set(data, dataConvert);
|
|
1754
|
+
data = dataConvert;
|
|
1755
|
+
}
|
|
1756
|
+
if (data === null || typeof data === 'function' || typeof data !== 'object' || isReturnAsIsObject(data)) {
|
|
1757
|
+
return data;
|
|
1758
|
+
}
|
|
1759
|
+
if (!ignoreCheckSeenHasDataAfterWhile && seen.has(data)) {
|
|
1760
|
+
return seen.get(data);
|
|
1761
|
+
}
|
|
1762
|
+
if (isArrayObject(data)) {
|
|
1763
|
+
if (!isSignal(data[0])) {
|
|
1764
|
+
return data;
|
|
1765
|
+
}
|
|
1766
|
+
seen.set(data, data.map((item) => convertSignalToObject(isCloneDeep ? cloneDeep(item) : item, isCloneDeep, seen)));
|
|
1767
|
+
return seen.get(data);
|
|
1768
|
+
}
|
|
1769
|
+
if (isMapObject(data)) {
|
|
1770
|
+
const mapCopy = new Map();
|
|
1771
|
+
Array.from(data.keys()).forEach((key) => {
|
|
1772
|
+
mapCopy.set(key, convertSignalToObject(isCloneDeep ? cloneDeep(data.get(key)) : data.get(key), isCloneDeep));
|
|
1773
|
+
});
|
|
1774
|
+
seen.set(data, mapCopy);
|
|
1775
|
+
return seen.get(data);
|
|
1776
|
+
}
|
|
1777
|
+
if (isSetObject(data)) {
|
|
1778
|
+
const setCopy = new Set();
|
|
1779
|
+
Array.from(data.values()).forEach((value) => {
|
|
1780
|
+
setCopy.add(convertSignalToObject(isCloneDeep ? cloneDeep(value) : value, isCloneDeep));
|
|
1781
|
+
});
|
|
1782
|
+
seen.set(data, setCopy);
|
|
1783
|
+
return seen.get(data);
|
|
1784
|
+
}
|
|
1785
|
+
// Bỏ qua các đối tượng nguy hiểm và đặc biệt
|
|
1786
|
+
if (isReturnAsIsObject(data)) {
|
|
1787
|
+
return data;
|
|
1788
|
+
}
|
|
1789
|
+
const result = isCloneDeep ? {} : data;
|
|
1790
|
+
seen.set(data, result);
|
|
1791
|
+
for (const key in data) {
|
|
1792
|
+
const value = data[key];
|
|
1793
|
+
if (Object.prototype.hasOwnProperty.call(data, key)) {
|
|
1794
|
+
// Bỏ qua các đối tượng nguy hiểm để tránh maximum call stack
|
|
1795
|
+
if (isReturnAsIsObject(value)) {
|
|
1796
|
+
result[key] = value;
|
|
1797
|
+
continue;
|
|
1798
|
+
}
|
|
1799
|
+
result[key] = convertSignalToObject(isCloneDeep ? cloneDeep(value) : value, isCloneDeep);
|
|
1800
|
+
}
|
|
1801
|
+
}
|
|
1802
|
+
return result;
|
|
1803
|
+
};
|
|
1804
|
+
|
|
1424
1805
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
1425
1806
|
/**Các hàm tương tự thư viện lodash */
|
|
1426
1807
|
/**
|
|
@@ -1433,7 +1814,10 @@ const getFormatData = (type, lang) => {
|
|
|
1433
1814
|
* isNil(0); // false
|
|
1434
1815
|
* isNil('hello'); // false
|
|
1435
1816
|
*/
|
|
1436
|
-
const isNil = (value) => {
|
|
1817
|
+
const isNil = (value, options) => {
|
|
1818
|
+
if (!options?.ignoreUnWrapSignal) {
|
|
1819
|
+
value = convertSignalToObject(value);
|
|
1820
|
+
}
|
|
1437
1821
|
return value === null || value === undefined;
|
|
1438
1822
|
};
|
|
1439
1823
|
/**
|
|
@@ -1449,11 +1833,78 @@ const isNil = (value) => {
|
|
|
1449
1833
|
* isEmpty([1, 2, 3]); // false
|
|
1450
1834
|
* isEmpty({ a: 1 }); // false
|
|
1451
1835
|
*/
|
|
1452
|
-
const isEmpty = (value) => {
|
|
1453
|
-
|
|
1454
|
-
value = value
|
|
1836
|
+
const isEmpty = (value, options) => {
|
|
1837
|
+
if (!options?.ignoreUnWrapSignal) {
|
|
1838
|
+
value = convertSignalToObject(value);
|
|
1839
|
+
}
|
|
1840
|
+
if (options?.ignoreCheckTypePrimitive) {
|
|
1841
|
+
return isEmptyTypeObject(value);
|
|
1842
|
+
}
|
|
1843
|
+
return isEmptyTypePrimitive(value, { ignoreCheckString: options?.ignoreCheckString }) || isEmptyTypeObject(value);
|
|
1844
|
+
};
|
|
1845
|
+
/**
|
|
1846
|
+
* Kiểm tra xem một giá trị có phải là object rỗng hay không
|
|
1847
|
+
* @param value Giá trị cần kiểm tra
|
|
1848
|
+
* @returns true nếu giá trị là object rỗng, false nếu không
|
|
1849
|
+
* @example
|
|
1850
|
+
* isEmptyTypeObject({}); // true
|
|
1851
|
+
* isEmptyTypeObject({ a: 1 }); // false
|
|
1852
|
+
*/
|
|
1853
|
+
const isEmptyTypeObject = (value) => {
|
|
1854
|
+
return typeof value === 'object' && (JSON.stringify(value) === '{}' || JSON.stringify(value) === '[]');
|
|
1855
|
+
};
|
|
1856
|
+
const isEmptyTypePrimitive = (value, options) => {
|
|
1857
|
+
if (options?.ignoreCheckString && value === '') {
|
|
1858
|
+
return false;
|
|
1859
|
+
}
|
|
1860
|
+
return value === '' || isNil(value, { ignoreUnWrapSignal: true });
|
|
1861
|
+
};
|
|
1862
|
+
/**
|
|
1863
|
+
* Kiểm tra xem một giá trị có phải là null, rỗng, undefined hoặc 0 hay không
|
|
1864
|
+
* @param value Giá trị cần kiểm tra
|
|
1865
|
+
* @param options Cấu hình tùy chọn
|
|
1866
|
+
* @param options.ignoreZero Nếu true, sẽ không kiểm tra giá trị 0
|
|
1867
|
+
* @returns true nếu giá trị là null, rỗng, undefined hoặc 0, false nếu không
|
|
1868
|
+
* @example
|
|
1869
|
+
* isTruthy(null); // false
|
|
1870
|
+
* isTruthy(''); // false
|
|
1871
|
+
* isTruthy(undefined); // false
|
|
1872
|
+
* isTruthy(0); // false
|
|
1873
|
+
* isTruthy({}); // true
|
|
1874
|
+
* isTruthy(0, { ignoreZero: true }); // true
|
|
1875
|
+
*/
|
|
1876
|
+
const isTruthy = (value, options) => {
|
|
1877
|
+
return !isFalsy(value, options);
|
|
1878
|
+
};
|
|
1879
|
+
/**
|
|
1880
|
+
* Kiểm tra xem một giá trị có phải là null, rỗng, undefined hoặc 0 hay không
|
|
1881
|
+
* @param value Giá trị cần kiểm tra
|
|
1882
|
+
* @param options Cấu hình tùy chọn
|
|
1883
|
+
* @param options.ignoreZero Nếu true, sẽ không kiểm tra giá trị 0
|
|
1884
|
+
* @returns true nếu giá trị là null, rỗng, undefined hoặc 0, false nếu không
|
|
1885
|
+
* @example
|
|
1886
|
+
* isFalsy(null); // true
|
|
1887
|
+
* isFalsy(''); // true
|
|
1888
|
+
* isFalsy(undefined); // true
|
|
1889
|
+
* isFalsy(0); // true
|
|
1890
|
+
* isFalsy({}); // false
|
|
1891
|
+
* isFalsy(0, { ignoreZero: true }); // false
|
|
1892
|
+
*/
|
|
1893
|
+
const isFalsy = (value, options) => {
|
|
1894
|
+
if (!options?.ignoreUnWrapSignal) {
|
|
1895
|
+
value = convertSignalToObject(value);
|
|
1455
1896
|
}
|
|
1456
|
-
|
|
1897
|
+
const isFalse = !value;
|
|
1898
|
+
if (!isFalse) {
|
|
1899
|
+
return false;
|
|
1900
|
+
}
|
|
1901
|
+
if (options?.ignoreZero && value === 0) {
|
|
1902
|
+
return false;
|
|
1903
|
+
}
|
|
1904
|
+
if (options?.ignoreCheckString && value === '') {
|
|
1905
|
+
return false;
|
|
1906
|
+
}
|
|
1907
|
+
return isFalse;
|
|
1457
1908
|
};
|
|
1458
1909
|
/**
|
|
1459
1910
|
* Loại bỏ các thuộc tính của đối tượng dựa trên một hàm điều kiện
|
|
@@ -1469,7 +1920,7 @@ const omitBy = (objData, predicate) => {
|
|
|
1469
1920
|
return objData;
|
|
1470
1921
|
}
|
|
1471
1922
|
const newObj = {};
|
|
1472
|
-
Object.keys(objData).forEach(key => {
|
|
1923
|
+
Object.keys(objData).forEach((key) => {
|
|
1473
1924
|
const valueOfKey = get(objData, key);
|
|
1474
1925
|
if (!predicate(valueOfKey)) {
|
|
1475
1926
|
set(newObj, key, valueOfKey);
|
|
@@ -1540,23 +1991,30 @@ const omitBy = (objData, predicate) => {
|
|
|
1540
1991
|
* get(null, 'any.path'); // undefined
|
|
1541
1992
|
* get(undefined, 'any.path', 'fallback'); // 'fallback'
|
|
1542
1993
|
*/
|
|
1543
|
-
const get = (obj, path, defaultValue
|
|
1994
|
+
const get = (obj, path, defaultValue, keepLastValueIfSignal) => {
|
|
1995
|
+
// helper cast để tránh lặp lại kiểu điều kiện ở các return
|
|
1996
|
+
const out = (v) => v;
|
|
1544
1997
|
if (isNil(obj)) {
|
|
1545
|
-
return defaultValue;
|
|
1998
|
+
return out(defaultValue);
|
|
1546
1999
|
}
|
|
1547
2000
|
while (isSignal(obj)) {
|
|
1548
2001
|
obj = obj();
|
|
1549
2002
|
}
|
|
1550
2003
|
if (path === '') {
|
|
1551
|
-
return obj;
|
|
2004
|
+
return out(obj);
|
|
1552
2005
|
}
|
|
1553
2006
|
if (obj instanceof HttpParams) {
|
|
1554
|
-
return obj.get(`${path}`);
|
|
2007
|
+
return out(obj.get(`${path}`) ?? defaultValue);
|
|
1555
2008
|
}
|
|
1556
2009
|
if (obj instanceof DOMRect) {
|
|
1557
|
-
return obj[path];
|
|
1558
|
-
}
|
|
1559
|
-
const paths = Array.isArray(path)
|
|
2010
|
+
return out(obj[path]);
|
|
2011
|
+
}
|
|
2012
|
+
const paths = Array.isArray(path)
|
|
2013
|
+
? path
|
|
2014
|
+
: path
|
|
2015
|
+
.replace(/\[(\d+)]/g, '.$1')
|
|
2016
|
+
.split('.')
|
|
2017
|
+
.filter((key) => key);
|
|
1560
2018
|
for (const index in paths) {
|
|
1561
2019
|
const key = paths[index];
|
|
1562
2020
|
if (obj instanceof CSSStyleDeclaration) {
|
|
@@ -1568,12 +2026,12 @@ const get = (obj, path, defaultValue = undefined, keepLastValueIfSignal) => {
|
|
|
1568
2026
|
continue;
|
|
1569
2027
|
}
|
|
1570
2028
|
if (isNil(obj) || !Object.prototype.hasOwnProperty.call(obj, key)) {
|
|
1571
|
-
return defaultValue;
|
|
2029
|
+
return out(defaultValue);
|
|
1572
2030
|
}
|
|
1573
2031
|
const val = isSignal(obj[key]) && !keepLastValueIfSignal ? obj[key]() : obj[key];
|
|
1574
2032
|
obj = val;
|
|
1575
2033
|
}
|
|
1576
|
-
return obj;
|
|
2034
|
+
return out(obj ?? defaultValue);
|
|
1577
2035
|
};
|
|
1578
2036
|
/**
|
|
1579
2037
|
* Thiết lập giá trị cho một thuộc tính trong đối tượng theo đường dẫn chỉ định
|
|
@@ -1586,29 +2044,36 @@ const get = (obj, path, defaultValue = undefined, keepLastValueIfSignal) => {
|
|
|
1586
2044
|
* const obj = { a: { b: 1 } };
|
|
1587
2045
|
* set(obj, 'a.b', 2); // { a: { b: 2 } }
|
|
1588
2046
|
*/
|
|
1589
|
-
const set = (obj, path, value) => {
|
|
1590
|
-
if (!obj || (typeof obj !==
|
|
1591
|
-
throw new Error(
|
|
2047
|
+
const set = (obj, path, value, options) => {
|
|
2048
|
+
if (!obj || (typeof obj !== 'object' && !isSignal(obj)) || (isSignal(obj) && typeof obj() !== 'object')) {
|
|
2049
|
+
throw new Error('The first argument must be an object');
|
|
1592
2050
|
}
|
|
1593
2051
|
if (obj instanceof HttpParams) {
|
|
1594
2052
|
return obj.set(`${path}`, value);
|
|
1595
2053
|
}
|
|
1596
|
-
const pathArray = Array.isArray(path)
|
|
2054
|
+
const pathArray = Array.isArray(path)
|
|
2055
|
+
? path
|
|
2056
|
+
: path
|
|
2057
|
+
.replace(/\[(\d+)]/g, '.[$1]')
|
|
2058
|
+
.split('.')
|
|
2059
|
+
.filter((key) => key);
|
|
1597
2060
|
let currentObjectByKey = isSignal(obj) ? obj() : obj;
|
|
1598
2061
|
let preObjectByKey = obj;
|
|
1599
2062
|
pathArray.forEach((key, index) => {
|
|
1600
2063
|
if (index < pathArray.length - 1) {
|
|
1601
|
-
if (!(key in currentObjectByKey) || (typeof currentObjectByKey[key] !==
|
|
2064
|
+
if (!(key in currentObjectByKey) || (typeof currentObjectByKey[key] !== 'object' && !isSignal(currentObjectByKey[key]))) {
|
|
1602
2065
|
const nextKey = pathArray[index + 1];
|
|
1603
2066
|
key = key.replace(/\[(\d+)]/g, '$1');
|
|
1604
|
-
currentObjectByKey[key]
|
|
2067
|
+
if (isNil(currentObjectByKey[key])) {
|
|
2068
|
+
currentObjectByKey[key] = /\[(\d+)]/g.test(nextKey) ? (options?.valueDefaultPathArrayUndefined ?? []) : (options?.valueDefaultPathObjectUndefined ?? {});
|
|
2069
|
+
}
|
|
1605
2070
|
}
|
|
1606
2071
|
currentObjectByKey = key ? currentObjectByKey[key] : currentObjectByKey;
|
|
1607
2072
|
preObjectByKey = currentObjectByKey;
|
|
1608
2073
|
currentObjectByKey = isSignal(currentObjectByKey) ? currentObjectByKey() : currentObjectByKey;
|
|
1609
2074
|
return;
|
|
1610
2075
|
}
|
|
1611
|
-
if (typeof currentObjectByKey !==
|
|
2076
|
+
if (typeof currentObjectByKey !== 'object') {
|
|
1612
2077
|
return;
|
|
1613
2078
|
}
|
|
1614
2079
|
// Gán giá trị ở cuối đường dẫn
|
|
@@ -1660,7 +2125,7 @@ const set = (obj, path, value) => {
|
|
|
1660
2125
|
* // clone là một bản sao hoàn toàn độc lập của obj
|
|
1661
2126
|
*/
|
|
1662
2127
|
const cloneDeep = (data, options = { ignoreSignal: false }, seen = new WeakMap()) => {
|
|
1663
|
-
if (data === null || (typeof data !== 'object' && !isSignal(data))) {
|
|
2128
|
+
if (data === null || (typeof data !== 'object' && !isSignal(data)) || isDangerousObject(data)) {
|
|
1664
2129
|
return data;
|
|
1665
2130
|
}
|
|
1666
2131
|
if (seen.has(data)) {
|
|
@@ -1689,19 +2154,16 @@ const cloneDeep = (data, options = { ignoreSignal: false }, seen = new WeakMap()
|
|
|
1689
2154
|
if (data instanceof Set) {
|
|
1690
2155
|
const setCopy = new Set();
|
|
1691
2156
|
seen.set(data, setCopy);
|
|
1692
|
-
data.forEach(val => {
|
|
2157
|
+
data.forEach((val) => {
|
|
1693
2158
|
setCopy.add(cloneDeep(val, options, seen));
|
|
1694
2159
|
});
|
|
1695
2160
|
return setCopy;
|
|
1696
2161
|
}
|
|
1697
2162
|
if (Array.isArray(data)) {
|
|
1698
|
-
seen.set(data, data.map(item => cloneDeep(item, options, seen)));
|
|
2163
|
+
seen.set(data, data.map((item) => cloneDeep(item, options, seen)));
|
|
1699
2164
|
return seen.get(data);
|
|
1700
2165
|
}
|
|
1701
|
-
if (
|
|
1702
|
-
return data;
|
|
1703
|
-
}
|
|
1704
|
-
if (data instanceof TemplateRef || data instanceof ElementRef || data instanceof Element || data instanceof Promise || data instanceof Observable) {
|
|
2166
|
+
if (isReturnAsIsObject(data)) {
|
|
1705
2167
|
return data;
|
|
1706
2168
|
}
|
|
1707
2169
|
if (isSignal(data)) {
|
|
@@ -1719,11 +2181,19 @@ const cloneDeep = (data, options = { ignoreSignal: false }, seen = new WeakMap()
|
|
|
1719
2181
|
result[key] = new UtilsHttpParamsRequest(undefined, value);
|
|
1720
2182
|
continue;
|
|
1721
2183
|
}
|
|
2184
|
+
if (value instanceof Date) {
|
|
2185
|
+
result[key] = new Date(value.getTime());
|
|
2186
|
+
continue;
|
|
2187
|
+
}
|
|
1722
2188
|
if (dayjs.isDayjs(value)) {
|
|
1723
2189
|
result[key] = getDayjs({ date: value.valueOf() });
|
|
1724
2190
|
continue;
|
|
1725
2191
|
}
|
|
1726
|
-
if (value instanceof
|
|
2192
|
+
if (value instanceof RegExp) {
|
|
2193
|
+
result[key] = new RegExp(value.source, value.flags);
|
|
2194
|
+
continue;
|
|
2195
|
+
}
|
|
2196
|
+
if (isReturnAsIsObject(data)) {
|
|
1727
2197
|
result[key] = value;
|
|
1728
2198
|
continue;
|
|
1729
2199
|
}
|
|
@@ -1786,7 +2256,7 @@ const keyBy = (data, key) => {
|
|
|
1786
2256
|
* // }
|
|
1787
2257
|
*/
|
|
1788
2258
|
const groupBy = (data, key) => {
|
|
1789
|
-
if (!data || !data.length || !Object.keys(get(data, '0')).length || !key) {
|
|
2259
|
+
if (!data || !data.length || !Object.keys(get(data, '[0]')).length || !key) {
|
|
1790
2260
|
return {};
|
|
1791
2261
|
}
|
|
1792
2262
|
return data.reduce((dir, nextItem) => {
|
|
@@ -1855,6 +2325,11 @@ const range = (start, end, step) => {
|
|
|
1855
2325
|
* isEqual({a:1}, {a:1}); // true
|
|
1856
2326
|
*/
|
|
1857
2327
|
const isEqual = (value1, value2, options) => {
|
|
2328
|
+
// Handle signals
|
|
2329
|
+
if (!options?.ignoreUnWrapSignal) {
|
|
2330
|
+
value1 = convertSignalToObject(value1);
|
|
2331
|
+
value2 = convertSignalToObject(value2);
|
|
2332
|
+
}
|
|
1858
2333
|
const { exactlyPosition = false, ignoreExactlyDataType = false } = options || {};
|
|
1859
2334
|
if (value1 === value2 || (value1 === null && value2 === null) || (value1 === undefined && value2 === undefined)) {
|
|
1860
2335
|
return true;
|
|
@@ -1862,13 +2337,6 @@ const isEqual = (value1, value2, options) => {
|
|
|
1862
2337
|
if (ignoreExactlyDataType) {
|
|
1863
2338
|
return isEqual(isNil(value1) ? undefined : `${value1}`, isNil(value2) ? undefined : `${value2}`);
|
|
1864
2339
|
}
|
|
1865
|
-
// Handle signals
|
|
1866
|
-
while (isSignal(value1)) {
|
|
1867
|
-
value1 = value1();
|
|
1868
|
-
}
|
|
1869
|
-
while (isSignal(value2)) {
|
|
1870
|
-
value2 = value2();
|
|
1871
|
-
}
|
|
1872
2340
|
if (typeof value1 !== 'object' || typeof value2 !== 'object' || (Array.isArray(value1) && !Array.isArray(value2)) || (!Array.isArray(value1) && Array.isArray(value2))) {
|
|
1873
2341
|
return false;
|
|
1874
2342
|
}
|
|
@@ -1877,7 +2345,7 @@ const isEqual = (value1, value2, options) => {
|
|
|
1877
2345
|
return false;
|
|
1878
2346
|
}
|
|
1879
2347
|
if (!exactlyPosition) {
|
|
1880
|
-
return !value1.some(item => !value2.includes(item));
|
|
2348
|
+
return !value1.some((item) => !value2.includes(item));
|
|
1881
2349
|
}
|
|
1882
2350
|
return !value1.some((item, index) => !isEqual(item, value2[index], options));
|
|
1883
2351
|
}
|
|
@@ -1906,11 +2374,11 @@ const isEqual = (value1, value2, options) => {
|
|
|
1906
2374
|
* uniqBy(numbersSignal); // [signal(1), signal(2), signal(3), signal(5), signal(4), signal(6), signal(7)]
|
|
1907
2375
|
*/
|
|
1908
2376
|
const uniqBy = (data, key) => {
|
|
1909
|
-
if (!key || !data?.length || typeof get(data, '0') !== 'object') {
|
|
2377
|
+
if (!key || !data?.length || typeof get(data, '[0]') !== 'object') {
|
|
1910
2378
|
// Xử lý mảng chứa signal values
|
|
1911
2379
|
if (data[0] && isSignal(data[0])) {
|
|
1912
2380
|
const seen = new Set();
|
|
1913
|
-
return data.filter(item => {
|
|
2381
|
+
return data.filter((item) => {
|
|
1914
2382
|
const value = `${get(item, '')}`;
|
|
1915
2383
|
if (seen.has(value)) {
|
|
1916
2384
|
return false;
|
|
@@ -1923,7 +2391,7 @@ const uniqBy = (data, key) => {
|
|
|
1923
2391
|
return Array.from(new Set(data));
|
|
1924
2392
|
}
|
|
1925
2393
|
const dataUnique = keyBy(data, key);
|
|
1926
|
-
return Object.keys(dataUnique).map(key => dataUnique[key]);
|
|
2394
|
+
return Object.keys(dataUnique).map((key) => dataUnique[key]);
|
|
1927
2395
|
};
|
|
1928
2396
|
const generateInterface = (obj, interfaceName) => {
|
|
1929
2397
|
const generateType = (value) => {
|
|
@@ -1972,11 +2440,10 @@ const generateInterface = (obj, interfaceName) => {
|
|
|
1972
2440
|
return interfaceStr;
|
|
1973
2441
|
};
|
|
1974
2442
|
|
|
1975
|
-
;
|
|
1976
2443
|
const step = 20;
|
|
1977
2444
|
const percent = 0.05;
|
|
1978
2445
|
const colorStepContrastFromOrigin = (color, stepNumber) => {
|
|
1979
|
-
return colorContrastFromOrigin(color).find(item => item.step === stepNumber);
|
|
2446
|
+
return colorContrastFromOrigin(color).find((item) => item.step === stepNumber);
|
|
1980
2447
|
};
|
|
1981
2448
|
const colorContrastFromOrigin = (color) => {
|
|
1982
2449
|
const parsedColorsArray = parseColorValues(color);
|
|
@@ -2011,10 +2478,10 @@ const parseColorValues = (colorValues) => {
|
|
|
2011
2478
|
return colorValuesArray;
|
|
2012
2479
|
};
|
|
2013
2480
|
const calculateShades = (colorValue) => {
|
|
2014
|
-
return calculate(colorValue, rgbShade).concat(
|
|
2481
|
+
return calculate(colorValue, rgbShade).concat('000000');
|
|
2015
2482
|
};
|
|
2016
2483
|
const calculateTints = (colorValue) => {
|
|
2017
|
-
return calculate(colorValue, rgbTint).concat(
|
|
2484
|
+
return calculate(colorValue, rgbTint).concat('ffffff');
|
|
2018
2485
|
};
|
|
2019
2486
|
const calculate = (colorValue, shadeOrTint) => {
|
|
2020
2487
|
const color = hexToRGB(colorValue);
|
|
@@ -2024,11 +2491,21 @@ const calculate = (colorValue, shadeOrTint) => {
|
|
|
2024
2491
|
}
|
|
2025
2492
|
return shadeValues;
|
|
2026
2493
|
};
|
|
2027
|
-
const rgbShade = (rgb, i) => {
|
|
2028
|
-
|
|
2029
|
-
|
|
2030
|
-
const
|
|
2031
|
-
|
|
2494
|
+
const rgbShade = (rgb, i) => {
|
|
2495
|
+
return { red: rgb.red * (1 - percent * i), green: rgb.green * (1 - percent * i), blue: rgb.blue * (1 - percent * i) };
|
|
2496
|
+
};
|
|
2497
|
+
const rgbTint = (rgb, i) => {
|
|
2498
|
+
return { red: rgb.red + (255 - rgb.red) * i * percent, green: rgb.green + (255 - rgb.green) * i * percent, blue: rgb.blue + (255 - rgb.blue) * i * percent };
|
|
2499
|
+
};
|
|
2500
|
+
const rgbToHex = (rgb) => {
|
|
2501
|
+
return intToHex(rgb.red) + intToHex(rgb.green) + intToHex(rgb.blue);
|
|
2502
|
+
};
|
|
2503
|
+
const hexToRGB = (colorValue) => {
|
|
2504
|
+
return { red: parseInt(colorValue.substr(0, 2), 16), green: parseInt(colorValue.substr(2, 2), 16), blue: parseInt(colorValue.substr(4, 2), 16) };
|
|
2505
|
+
};
|
|
2506
|
+
const intToHex = (rgbint) => {
|
|
2507
|
+
return pad(Math.min(Math.max(Math.round(rgbint), 0), 255).toString(16), 2);
|
|
2508
|
+
};
|
|
2032
2509
|
const pad = (number, length) => {
|
|
2033
2510
|
let str = '' + number;
|
|
2034
2511
|
while (str.length < length) {
|
|
@@ -2036,9 +2513,52 @@ const pad = (number, length) => {
|
|
|
2036
2513
|
}
|
|
2037
2514
|
return str;
|
|
2038
2515
|
};
|
|
2039
|
-
const listColorDefine = [
|
|
2040
|
-
'#
|
|
2041
|
-
'#
|
|
2516
|
+
const listColorDefine = [
|
|
2517
|
+
'#E62222',
|
|
2518
|
+
'#B81B1B',
|
|
2519
|
+
'#EB4E4E',
|
|
2520
|
+
'#F97316',
|
|
2521
|
+
'#C75C12',
|
|
2522
|
+
'#FA8F45',
|
|
2523
|
+
'#FFB700',
|
|
2524
|
+
'#CC9200',
|
|
2525
|
+
'#FFC533',
|
|
2526
|
+
'#84CC16',
|
|
2527
|
+
'#6AA312',
|
|
2528
|
+
'#9dd645',
|
|
2529
|
+
'#00BC62',
|
|
2530
|
+
'#00A757',
|
|
2531
|
+
'#33DA8A',
|
|
2532
|
+
'#06B6D4',
|
|
2533
|
+
'#1B59C4',
|
|
2534
|
+
'#4E8CF7',
|
|
2535
|
+
'#0EA5E9',
|
|
2536
|
+
'#1B59C4',
|
|
2537
|
+
'#4E8CF7',
|
|
2538
|
+
'#226FF5',
|
|
2539
|
+
'#1B59C4',
|
|
2540
|
+
'#4E8CF7',
|
|
2541
|
+
'#6366F1',
|
|
2542
|
+
'#4F52C1',
|
|
2543
|
+
'#8285F4',
|
|
2544
|
+
'#5B04B3',
|
|
2545
|
+
'#49038F',
|
|
2546
|
+
'#7C36C2',
|
|
2547
|
+
'#D946EF',
|
|
2548
|
+
'#AE38BF',
|
|
2549
|
+
'#E16BF2',
|
|
2550
|
+
'#EC4899',
|
|
2551
|
+
'#BD3A7A',
|
|
2552
|
+
'#F06DAD',
|
|
2553
|
+
'#F43F5E',
|
|
2554
|
+
'#C3324B',
|
|
2555
|
+
'#F6657E',
|
|
2556
|
+
'#757380',
|
|
2557
|
+
'#5E5C66',
|
|
2558
|
+
'#918F99',
|
|
2559
|
+
'#202020',
|
|
2560
|
+
'#1A1A1A',
|
|
2561
|
+
'#4D4D4D',
|
|
2042
2562
|
];
|
|
2043
2563
|
const getColorById = (str) => {
|
|
2044
2564
|
let hashString = 0;
|
|
@@ -2047,7 +2567,7 @@ const getColorById = (str) => {
|
|
|
2047
2567
|
}
|
|
2048
2568
|
for (let i = 0; i < str.length; i++) {
|
|
2049
2569
|
const char = str.charCodeAt(i);
|
|
2050
|
-
hashString = (
|
|
2570
|
+
hashString = (hashString << 5) - hashString + char;
|
|
2051
2571
|
hashString = hashString & hashString;
|
|
2052
2572
|
}
|
|
2053
2573
|
return listColorDefine[Math.abs(hashString) % listColorDefine.length];
|
|
@@ -2187,8 +2707,8 @@ const getKeyCacheByArrayObject = (keyCache, argumentsValue) => {
|
|
|
2187
2707
|
keyBuild = `${keyBuild}${JSON.stringify(item)}`;
|
|
2188
2708
|
return;
|
|
2189
2709
|
}
|
|
2190
|
-
const keys = (item instanceof HttpParams ? item.keys() : Object.keys(item)).sort((
|
|
2191
|
-
keys.forEach(key => {
|
|
2710
|
+
const keys = (item instanceof HttpParams ? item.keys() : Object.keys(item)).sort((str1, str2) => str1.localeCompare(str2));
|
|
2711
|
+
keys.forEach((key) => {
|
|
2192
2712
|
if (key.toLocaleLowerCase() === 'pem') {
|
|
2193
2713
|
return;
|
|
2194
2714
|
}
|
|
@@ -2232,7 +2752,7 @@ const viewDataNumberByLanguage = (value, acceptNegativeValue, parseFixed = 1, ig
|
|
|
2232
2752
|
return Math.round(value * fixed) / fixed;
|
|
2233
2753
|
};
|
|
2234
2754
|
if (parseFixed > (floatStr?.length || 0)) {
|
|
2235
|
-
const maxParseFixed =
|
|
2755
|
+
const maxParseFixed = acceptNegativeValue && +value < 0 ? 17 : 16;
|
|
2236
2756
|
const fixed = maxParseFixed - (intStr?.length || 0);
|
|
2237
2757
|
parseFixed = parseFixed < fixed ? parseFixed : fixed;
|
|
2238
2758
|
}
|
|
@@ -2259,7 +2779,10 @@ const viewDataNumberByLanguage = (value, acceptNegativeValue, parseFixed = 1, ig
|
|
|
2259
2779
|
if (lang === UtilsLanguageConstants.EN) {
|
|
2260
2780
|
return value.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',');
|
|
2261
2781
|
}
|
|
2262
|
-
return value
|
|
2782
|
+
return value
|
|
2783
|
+
.toString()
|
|
2784
|
+
.replace('.', ',')
|
|
2785
|
+
.replace(/\B(?=(\d{3})+(?!\d))/g, '.');
|
|
2263
2786
|
}
|
|
2264
2787
|
};
|
|
2265
2788
|
|
|
@@ -2273,120 +2796,14 @@ const xssFilter = async (data) => {
|
|
|
2273
2796
|
return await functionXssFilter(data);
|
|
2274
2797
|
};
|
|
2275
2798
|
|
|
2276
|
-
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
2277
|
-
/**
|
|
2278
|
-
* Chuyển đổi một đối tượng hoặc giá trị thành signal
|
|
2279
|
-
* @param data Dữ liệu cần chuyển đổi thành signal
|
|
2280
|
-
* @param cloneDeepIfNotSignal Có thực hiện sao chép sâu dữ liệu trước khi chuyển đổi hay không nếu data không phải signal. Mặc định là true.
|
|
2281
|
-
* Đặt false nếu muốn giữ nguyên tham chiếu đến dữ liệu gốc.
|
|
2282
|
-
* Nếu muốn sao chép sâu đối tượng signal thì đặt cloneDeepIfNotSignal là true và acceptConvertObjectInnerWritableSignal là true.
|
|
2283
|
-
* @param isSignalPrimitiveType Có chuyển đổi các giá trị nguyên thủy (string, number, boolean) thành signal hay không. Mặc định là false.
|
|
2284
|
-
* Đặt true nếu muốn bọc các giá trị nguyên thủy trong signal.
|
|
2285
|
-
* @param acceptConvertObjectInnerWritableSignal Có tiếp tục tìm kiếm và chuyển đổi các đối tượng bên trong signal hay không. Mặc định là false.
|
|
2286
|
-
* Đặt true nếu muốn tìm và chuyển đổi các đối tượng bên trong signal hoặc chính nó thành signal mới.
|
|
2287
|
-
* @returns Dữ liệu đã được chuyển đổi theo kiểu T
|
|
2288
|
-
*/
|
|
2289
|
-
const convertObjectToSignal = (data, cloneDeepIfNotSignal = true, isSignalPrimitiveType = false, acceptConvertObjectInnerWritableSignal = false, seen = new WeakMap()) => {
|
|
2290
|
-
if ((data === null || typeof data !== 'object') && !isSignal(data)) {
|
|
2291
|
-
return (isSignalPrimitiveType ? signal(data) : data);
|
|
2292
|
-
}
|
|
2293
|
-
if (seen.has(data)) {
|
|
2294
|
-
return seen.get(data);
|
|
2295
|
-
}
|
|
2296
|
-
if (isSignal(data)) {
|
|
2297
|
-
if (!acceptConvertObjectInnerWritableSignal) {
|
|
2298
|
-
return data;
|
|
2299
|
-
}
|
|
2300
|
-
seen.set(data, convertObjectToSignal(data(), cloneDeepIfNotSignal, isSignalPrimitiveType, acceptConvertObjectInnerWritableSignal, seen));
|
|
2301
|
-
return seen.get(data);
|
|
2302
|
-
}
|
|
2303
|
-
if (Array.isArray(data)) {
|
|
2304
|
-
seen.set(data, signal(data.map(item => convertObjectToSignal(item, cloneDeepIfNotSignal, isSignalPrimitiveType, acceptConvertObjectInnerWritableSignal, seen))));
|
|
2305
|
-
return seen.get(data);
|
|
2306
|
-
}
|
|
2307
|
-
if (data instanceof Map) {
|
|
2308
|
-
const mapCopy = new Map();
|
|
2309
|
-
Array.from(data.keys()).forEach(key => {
|
|
2310
|
-
mapCopy.set(key, convertObjectToSignal(data.get(key), cloneDeepIfNotSignal, isSignalPrimitiveType, acceptConvertObjectInnerWritableSignal));
|
|
2311
|
-
});
|
|
2312
|
-
seen.set(data, signal(mapCopy));
|
|
2313
|
-
return seen.get(data);
|
|
2314
|
-
}
|
|
2315
|
-
if (data instanceof Promise || data instanceof Observable) {
|
|
2316
|
-
return data;
|
|
2317
|
-
}
|
|
2318
|
-
data = signal(cloneDeepIfNotSignal ? { ...data } : data);
|
|
2319
|
-
seen.set(data, data);
|
|
2320
|
-
for (const key in data()) {
|
|
2321
|
-
const value = data()[key];
|
|
2322
|
-
if (value instanceof TemplateRef || value instanceof File || value instanceof Blob || Object.prototype.toString.call(value) === '[object File]' || value instanceof ElementRef || value instanceof Element || value instanceof Date || value instanceof RegExp || value instanceof Set || value instanceof Map || value instanceof Promise || value instanceof Observable || value instanceof HttpParams) {
|
|
2323
|
-
continue;
|
|
2324
|
-
}
|
|
2325
|
-
if (Object.prototype.hasOwnProperty.call(data(), key)) {
|
|
2326
|
-
data()[key] = convertObjectToSignal(value, cloneDeepIfNotSignal, isSignalPrimitiveType, acceptConvertObjectInnerWritableSignal);
|
|
2327
|
-
}
|
|
2328
|
-
}
|
|
2329
|
-
return data;
|
|
2330
|
-
};
|
|
2331
|
-
const convertSignalToObject = (data, isCloneDeep = true, seen = new WeakMap()) => {
|
|
2332
|
-
let ignoreCheckSeenHasDataAfterWhile = false;
|
|
2333
|
-
while (isSignal(data) && !seen.has(data)) {
|
|
2334
|
-
const dataConvert = data();
|
|
2335
|
-
if (typeof dataConvert === 'object') {
|
|
2336
|
-
if (dataConvert === null) {
|
|
2337
|
-
return dataConvert;
|
|
2338
|
-
}
|
|
2339
|
-
seen.set(dataConvert, dataConvert);
|
|
2340
|
-
data = dataConvert;
|
|
2341
|
-
ignoreCheckSeenHasDataAfterWhile = true;
|
|
2342
|
-
break;
|
|
2343
|
-
}
|
|
2344
|
-
seen.set(data, dataConvert);
|
|
2345
|
-
data = dataConvert;
|
|
2346
|
-
}
|
|
2347
|
-
if (data === null || typeof data === 'function' || typeof data !== 'object') {
|
|
2348
|
-
return data;
|
|
2349
|
-
}
|
|
2350
|
-
if (!ignoreCheckSeenHasDataAfterWhile && seen.has(data)) {
|
|
2351
|
-
return seen.get(data);
|
|
2352
|
-
}
|
|
2353
|
-
if (Array.isArray(data)) {
|
|
2354
|
-
if (!isSignal(data[0])) {
|
|
2355
|
-
return data;
|
|
2356
|
-
}
|
|
2357
|
-
seen.set(data, data.map(item => convertSignalToObject((isCloneDeep ? cloneDeep(item) : item), isCloneDeep, seen)));
|
|
2358
|
-
return seen.get(data);
|
|
2359
|
-
}
|
|
2360
|
-
if (data instanceof Map) {
|
|
2361
|
-
const mapCopy = new Map();
|
|
2362
|
-
Array.from(data.keys()).forEach(key => {
|
|
2363
|
-
mapCopy.set(key, convertSignalToObject(isCloneDeep ? cloneDeep(data.get(key)) : data.get(key), isCloneDeep));
|
|
2364
|
-
});
|
|
2365
|
-
seen.set(data, mapCopy);
|
|
2366
|
-
return seen.get(data);
|
|
2367
|
-
}
|
|
2368
|
-
if (data instanceof File || data instanceof Blob || Object.prototype.toString.call(data) === '[object File]') {
|
|
2369
|
-
return data;
|
|
2370
|
-
}
|
|
2371
|
-
if (data instanceof TemplateRef || data instanceof ElementRef || data instanceof Element || data instanceof Promise || data instanceof Observable || data instanceof HttpParams) {
|
|
2372
|
-
return data;
|
|
2373
|
-
}
|
|
2374
|
-
const result = isCloneDeep ? {} : data;
|
|
2375
|
-
seen.set(data, result);
|
|
2376
|
-
for (const key in data) {
|
|
2377
|
-
const value = data[key];
|
|
2378
|
-
if (Object.prototype.hasOwnProperty.call(data, key)) {
|
|
2379
|
-
result[key] = convertSignalToObject(isCloneDeep ? cloneDeep(value) : value, isCloneDeep);
|
|
2380
|
-
}
|
|
2381
|
-
}
|
|
2382
|
-
return result;
|
|
2383
|
-
};
|
|
2384
|
-
|
|
2385
2799
|
const ENCODE_URI_PATTERN = /%([0-9A-F]{2})/g;
|
|
2386
2800
|
const decodeURI = (value) => {
|
|
2387
|
-
return decodeURIComponent(value
|
|
2801
|
+
return decodeURIComponent(value
|
|
2802
|
+
.split('')
|
|
2803
|
+
.map((c) => {
|
|
2388
2804
|
return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2);
|
|
2389
|
-
})
|
|
2805
|
+
})
|
|
2806
|
+
.join(''));
|
|
2390
2807
|
};
|
|
2391
2808
|
const encodeURI = (value) => {
|
|
2392
2809
|
return encodeURIComponent(value).replace(ENCODE_URI_PATTERN, (match, p1) => {
|
|
@@ -2394,7 +2811,7 @@ const encodeURI = (value) => {
|
|
|
2394
2811
|
});
|
|
2395
2812
|
};
|
|
2396
2813
|
const endCodeUrl = (params, isBody) => {
|
|
2397
|
-
params = omitBy(params, param => param === '' || isNil(param));
|
|
2814
|
+
params = omitBy(params, (param) => param === '' || isNil(param));
|
|
2398
2815
|
let res = '';
|
|
2399
2816
|
for (const p in params) {
|
|
2400
2817
|
res += `&${p}=${encodeURIComponent(params[p])}`;
|
|
@@ -2472,7 +2889,7 @@ const downloadFileByUrl = async (fileUrl, filename, onlyOpen) => {
|
|
|
2472
2889
|
const downloadImageFromELement = (imageElement, typeFileDownload, nameFile) => {
|
|
2473
2890
|
const parentElement = imageElement?.src;
|
|
2474
2891
|
const blobData = convertBase64ToBlob(parentElement);
|
|
2475
|
-
const blob = new Blob([blobData], { type: typeFileDownload ||
|
|
2892
|
+
const blob = new Blob([blobData], { type: typeFileDownload || 'image/png' });
|
|
2476
2893
|
const url = window.URL.createObjectURL(blob);
|
|
2477
2894
|
const link = document.createElement('a');
|
|
2478
2895
|
link.href = url;
|
|
@@ -2484,12 +2901,22 @@ const LINK_IMAGE_ERROR_TOKEN_INJECT = new InjectionToken('LINK_IMAGE_ERROR_TOKEN
|
|
|
2484
2901
|
const PROCESS_BAR_STANDARD_CONFIG_DEFAULT_TOKEN_INJECT = new InjectionToken('PROCESS_BAR_STANDARD_CONFIG_DEFAULT_TOKEN_INJECT');
|
|
2485
2902
|
const PROCESS_BAR_STEPS_CONFIG_DEFAULT_TOKEN_INJECT = new InjectionToken('PROCESS_BAR_STEPS_CONFIG_DEFAULT_TOKEN_INJECT');
|
|
2486
2903
|
|
|
2487
|
-
const isTypeImage = (file) => file.type.match(/image.*/) ? true : false;
|
|
2488
|
-
const isTypeVideo = (file) => file.type.match(/video.*/) ? true : false;
|
|
2489
|
-
const isTypeAudio = (file) => file.type.match(/audio.*/) ? true : false;
|
|
2490
|
-
const isTypeFile = (file) => file instanceof File || Object.prototype.toString.call(file) === '[object File]' ? true : false;
|
|
2904
|
+
const isTypeImage = (file) => (file.type.match(/image.*/) ? true : false);
|
|
2905
|
+
const isTypeVideo = (file) => (file.type.match(/video.*/) ? true : false);
|
|
2906
|
+
const isTypeAudio = (file) => (file.type.match(/audio.*/) ? true : false);
|
|
2907
|
+
const isTypeFile = (file) => (file instanceof File || Object.prototype.toString.call(file) === '[object File]' ? true : false);
|
|
2491
2908
|
const ExcelExtList = ['xls', 'xlsx', 'application/vnd.ms-excel', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'];
|
|
2492
|
-
const DocumentExtList = [
|
|
2909
|
+
const DocumentExtList = [
|
|
2910
|
+
'doc',
|
|
2911
|
+
'docx',
|
|
2912
|
+
'xls',
|
|
2913
|
+
'xlsx',
|
|
2914
|
+
'ppt',
|
|
2915
|
+
'pptx',
|
|
2916
|
+
'pdf',
|
|
2917
|
+
'json',
|
|
2918
|
+
'xml',
|
|
2919
|
+
'application/msword',
|
|
2493
2920
|
'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
|
|
2494
2921
|
'application/vnd.ms-excel',
|
|
2495
2922
|
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
|
|
@@ -2497,7 +2924,8 @@ const DocumentExtList = ['doc', 'docx', 'xls', 'xlsx', 'ppt', 'pptx', 'pdf', 'js
|
|
|
2497
2924
|
'application/vnd.openxmlformats-officedocument.presentationml.presentation',
|
|
2498
2925
|
'application/pdf',
|
|
2499
2926
|
'application/json',
|
|
2500
|
-
'application/xml'
|
|
2927
|
+
'application/xml',
|
|
2928
|
+
];
|
|
2501
2929
|
const isIncludeDocumentExtList = (ext, listExt = DocumentExtList) => listExt.includes(ext) || listExt.includes(`application/${ext}`);
|
|
2502
2930
|
const ImageExtList = ['gif', 'jpg', 'jpeg', 'png', 'image/gif', 'image/jpeg', 'image/jpeg', 'image/png'];
|
|
2503
2931
|
const isIncludeImageExtList = (ext, listExt = ImageExtList) => listExt.includes(ext);
|
|
@@ -2522,7 +2950,7 @@ const getFileExtension = (file) => {
|
|
|
2522
2950
|
fileName = url.split('/').pop() || '';
|
|
2523
2951
|
set(file, 'name', fileName);
|
|
2524
2952
|
}
|
|
2525
|
-
const dots = fileName.split(
|
|
2953
|
+
const dots = fileName.split('.');
|
|
2526
2954
|
if (!dots) {
|
|
2527
2955
|
return;
|
|
2528
2956
|
}
|
|
@@ -2548,6 +2976,7 @@ const convertUrlToFile = (url, fileName) => {
|
|
|
2548
2976
|
const file = convertBase64ToBlob(reader.result);
|
|
2549
2977
|
resolve(convertBlobToFile(file, fileName || Date.now().toLocaleString()));
|
|
2550
2978
|
};
|
|
2979
|
+
reader.onerror = () => resolve(undefined);
|
|
2551
2980
|
reader.readAsDataURL(xhr.response);
|
|
2552
2981
|
};
|
|
2553
2982
|
xhr.onerror = (err) => {
|
|
@@ -2625,12 +3054,12 @@ const getSmartAxisScale = (originalMaxData, options) => {
|
|
|
2625
3054
|
}
|
|
2626
3055
|
const maxValuePositive = maxValue - Math.abs(minValue);
|
|
2627
3056
|
tickCount = maxValuePositive - originalMaxData > Math.abs(step) && tickCount - 1 >= minTickCount ? tickCount - 1 : tickCount;
|
|
2628
|
-
maxValue =
|
|
3057
|
+
maxValue = step * tickCount * scaleDirection - minValue * scaleDirection;
|
|
2629
3058
|
return {
|
|
2630
3059
|
stepSize: Math.abs(step),
|
|
2631
3060
|
max: maxValue,
|
|
2632
3061
|
min: minValue,
|
|
2633
|
-
tickAmount: tickCount
|
|
3062
|
+
tickAmount: tickCount,
|
|
2634
3063
|
};
|
|
2635
3064
|
}
|
|
2636
3065
|
}
|
|
@@ -2645,7 +3074,7 @@ const getSmartAxisScale = (originalMaxData, options) => {
|
|
|
2645
3074
|
stepSize: Math.abs(step),
|
|
2646
3075
|
max: maxValue,
|
|
2647
3076
|
min: 0,
|
|
2648
|
-
tickAmount: minTickCount
|
|
3077
|
+
tickAmount: minTickCount,
|
|
2649
3078
|
};
|
|
2650
3079
|
};
|
|
2651
3080
|
// Cache cho các giá trị lũy thừa 10 để tối ưu hiệu suất
|
|
@@ -2701,7 +3130,7 @@ const getStepCandidates = (maxData, minStep, minNegative, acceptStepIsTypeFloat
|
|
|
2701
3130
|
const checkAndSetNegativeSteps = (stepCandidates, acceptNegative, minNegative) => {
|
|
2702
3131
|
if (acceptNegative && minNegative < 0) {
|
|
2703
3132
|
// Tạo các step âm và thêm vào đầu danh sách
|
|
2704
|
-
const negativeSteps = [...stepCandidates].map(step => -step);
|
|
3133
|
+
const negativeSteps = [...stepCandidates].map((step) => -step);
|
|
2705
3134
|
stepCandidates.unshift(...negativeSteps);
|
|
2706
3135
|
}
|
|
2707
3136
|
};
|
|
@@ -2714,20 +3143,20 @@ const checkAndSetNegativeSteps = (stepCandidates, acceptNegative, minNegative) =
|
|
|
2714
3143
|
const validateInputs = (maxData, options) => {
|
|
2715
3144
|
// Kiểm tra maxData âm khi không chấp nhận giá trị âm
|
|
2716
3145
|
if (maxData < 0 && !options?.acceptNegative) {
|
|
2717
|
-
throw new Error(
|
|
3146
|
+
throw new Error('maxData is less than 0 and acceptNegative is false');
|
|
2718
3147
|
}
|
|
2719
3148
|
if (options?.acceptNegative) {
|
|
2720
3149
|
// Kiểm tra minNegative có được cung cấp không
|
|
2721
3150
|
if (isNil(options.minNegative)) {
|
|
2722
|
-
throw new Error(
|
|
3151
|
+
throw new Error('minNegative is required when acceptNegative is true');
|
|
2723
3152
|
}
|
|
2724
3153
|
// Kiểm tra maxData phải >= minNegative
|
|
2725
3154
|
if (maxData < options.minNegative) {
|
|
2726
|
-
throw new Error(
|
|
3155
|
+
throw new Error('maxData is less than minNegative');
|
|
2727
3156
|
}
|
|
2728
3157
|
// Kiểm tra minNegative phải là số âm
|
|
2729
3158
|
if (options.minNegative >= 0) {
|
|
2730
|
-
throw new Error(
|
|
3159
|
+
throw new Error('minNegative must be negative');
|
|
2731
3160
|
}
|
|
2732
3161
|
}
|
|
2733
3162
|
};
|
|
@@ -2747,7 +3176,7 @@ const revealString = (encoded) => {
|
|
|
2747
3176
|
const decoded = base
|
|
2748
3177
|
.split('')
|
|
2749
3178
|
.reverse()
|
|
2750
|
-
.map(c => String.fromCharCode(c.charCodeAt(0) ^ xorKey))
|
|
3179
|
+
.map((c) => String.fromCharCode(c.charCodeAt(0) ^ xorKey))
|
|
2751
3180
|
.join('');
|
|
2752
3181
|
return decoded;
|
|
2753
3182
|
};
|
|
@@ -2778,5 +3207,5 @@ const createUniqueRandomIntGenerator = (min, max) => {
|
|
|
2778
3207
|
* Generated bundle index. Do not edit.
|
|
2779
3208
|
*/
|
|
2780
3209
|
|
|
2781
|
-
export { AudioExtList, CHARACTER_DATA_EMPTY, COMMUNICATE_MICRO_KEY_GET_ALL_MESSAGE, COMMUNICATE_MICRO_PREFIX_TYPE, DEFAULT_START_PAGE_0, DocumentExtList, ENCODE_URI_PATTERN, ERROR_MESSAGE_EMPTY_VALID, ERROR_MESSAGE_MAX_LENGTH, ERROR_MESSAGE_MAX_VALID, ERROR_MESSAGE_MIN_LENGTH, ERROR_MESSAGE_MIN_VALID, ERROR_MESSAGE_PATTEN_VALID, ExcelExtList, ImageExtList, LINK_IMAGE_ERROR_TOKEN_INJECT, PROCESS_BAR_STANDARD_CONFIG_DEFAULT_TOKEN_INJECT, PROCESS_BAR_STEPS_CONFIG_DEFAULT_TOKEN_INJECT, UtilsCache, UtilsCommunicateMicro, UtilsCommunicateMicroKeyGlobal, UtilsHttpParamsRequest, UtilsHttpParamsRequestInstance, UtilsKeyCodeConstant, UtilsLanguageConstants, UtilsUrlSearchParams, VideoExtList, base64Decode, base64Encode, capitalize, checkMouseOverInContainer, checkViewInScreen, cloneDeep, cloneIBoundingClientRect, colorContrastFromOrigin, colorStepContrastFromOrigin, convertBase64ToBlob, convertBlobToFile, convertFileToBase64, convertFileToBase64_ObjectUrl, convertObjectToSignal, convertSignalToObject, convertUrlToFile, createUniqueRandomIntGenerator, decodeEscapeHtml, decodeURI, decrypt, decrypt3rd, deleteUnicode, downloadFileByUrl, downloadFileByUrlUseXmlRequest, downloadImageFromELement, encodeURI, encrypt, encrypt3rd, endCodeUrl, escapeHtml, firstLetterToUpperCase, formatDate, formatNumber, formatTextCompare, fullNameFormat, generateInterface, get, getColorById, getDayjs, getDeviceInfo, getDocumentByString, getDragEventByElement, getEventNameHandleClick, getFileExtension, getHTMLFromQuill, getKeyCacheByArrayObject, getLabelBySizeFile, getPlatFromBrowser, getSmartAxisScale, getViewport, groupBy, highlightByKeyword, isDifferenceDay, isDifferenceMonth, isDifferenceYear, isEmbedFrame, isEmpty, isEqual, isIncludeAudioExtList, isIncludeDocumentExtList, isIncludeImageExtList, isIncludeVideoExtList, isNil, isTypeAudio, isTypeFile, isTypeImage, isTypeVideo, keyBy, listColorDefine, md5, omitBy, patternAccount, patternDomain, patternEmail, patternEmoji, patternEncodeUri, patternGetFieldByRuleFieldReplace, patternHostUrl, patternKey, patternMobilePhone, patternName, patternNameProfile, patternNameSpecial, patternNameUtf8, patternNumber, patternPem, patternPhone, patternPhoneNormal, patternRuleFieldReplace, patternTax, patternUrl, protectString, range, removeEmoji, revealString, rgbToHex, set, setCaretPosition, setDefaultTimeZone, setKeyCrypto, setKeyCrypto3rd, setStylesElement, uniqBy, updateFunctionCheckEmbedFrame, updateFunctionFormatDate, updateFunctionXssFilter, uppercaseByPosition, uuid, viewDataNumberByLanguage, xssFilter };
|
|
3210
|
+
export { AudioExtList, CHARACTER_DATA_EMPTY, COMMUNICATE_MICRO_KEY_GET_ALL_MESSAGE, COMMUNICATE_MICRO_PREFIX_TYPE, DEFAULT_START_PAGE_0, DocumentExtList, ENCODE_URI_PATTERN, ERROR_MESSAGE_EMPTY_VALID, ERROR_MESSAGE_MAX_LENGTH, ERROR_MESSAGE_MAX_VALID, ERROR_MESSAGE_MIN_LENGTH, ERROR_MESSAGE_MIN_VALID, ERROR_MESSAGE_PATTEN_VALID, ExcelExtList, ImageExtList, LINK_IMAGE_ERROR_TOKEN_INJECT, PROCESS_BAR_STANDARD_CONFIG_DEFAULT_TOKEN_INJECT, PROCESS_BAR_STEPS_CONFIG_DEFAULT_TOKEN_INJECT, UtilsCache, UtilsCommunicateMicro, UtilsCommunicateMicroKeyGlobal, UtilsHttpParamsRequest, UtilsHttpParamsRequestInstance, UtilsKeyCodeConstant, UtilsLanguageConstants, UtilsUrlSearchParams, VideoExtList, base64Decode, base64Encode, capitalize, checkMouseOverInContainer, checkViewInScreen, cloneDeep, cloneIBoundingClientRect, colorContrastFromOrigin, colorStepContrastFromOrigin, convertBase64ToBlob, convertBlobToFile, convertFileToBase64, convertFileToBase64_ObjectUrl, convertHtmlToDivBlocks, convertObjectToSignal, convertSignalToObject, convertUrlToFile, createUniqueRandomIntGenerator, decodeEscapeHtml, decodeURI, decrypt, decrypt3rd, deleteUnicode, downloadFileByUrl, downloadFileByUrlUseXmlRequest, downloadImageFromELement, encodeURI, encrypt, encrypt3rd, endCodeUrl, escapeHtml, firstLetterToUpperCase, formatDate, formatNumber, formatTextCompare, fullNameFormat, generateInterface, get, getColorById, getDayjs, getDeltaFromHTML, getDeviceInfo, getDocumentByString, getDragEventByElement, getEventNameHandleClick, getFileExtension, getHTMLFromQuill, getKeyCacheByArrayObject, getLabelBySizeFile, getPlatFromBrowser, getSmartAxisScale, getViewport, groupBy, hasDangerousConstructorName, highlightByKeyword, insertContentWithRange, isArrayObject, isAsyncObject, isBrowserAPIObject, isBrowserGlobalObject, isBuiltInObject, isDOMObject, isDangerousObject, isDayjsObject, isDifferenceDay, isDifferenceMonth, isDifferenceYear, isEmbedFrame, isEmpty, isEqual, isFalsy, isFileObject, isFrameworkObject, isIncludeAudioExtList, isIncludeDocumentExtList, isIncludeImageExtList, isIncludeVideoExtList, isMapObject, isNil, isReturnAsIsObject, isSafeToProcess, isSetObject, isSkippableObject, isSpecialObject, isTruthy, isTypeAudio, isTypeFile, isTypeImage, isTypeVideo, keyBy, listColorDefine, md5, omitBy, patternAccount, patternDomain, patternEmail, patternEmoji, patternEncodeUri, patternGetFieldByRuleFieldReplace, patternHostUrl, patternKey, patternMobilePhone, patternName, patternNameProfile, patternNameSpecial, patternNameUtf8, patternNumber, patternPem, patternPhone, patternPhoneNormal, patternRuleFieldReplace, patternTax, patternUrl, processPasteData, protectString, range, removeEmoji, revealString, rgbToHex, set, setCaretPosition, setDefaultTimeZone, setKeyCrypto, setKeyCrypto3rd, setStylesElement, uniqBy, updateFunctionCheckEmbedFrame, updateFunctionFormatDate, updateFunctionXssFilter, uppercaseByPosition, uuid, viewDataNumberByLanguage, xssFilter };
|
|
2782
3211
|
//# sourceMappingURL=libs-ui-utils.mjs.map
|