@libs-ui/utils 0.2.348-8 → 0.2.350-0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,7 +1,6 @@
1
1
  import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
2
- import Quill from 'quill';
3
- import Quill2x from 'quill2x';
4
- import { Observable, Subject, fromEvent, filter, tap, takeUntil, mergeMap, startWith, finalize, lastValueFrom, timer } from 'rxjs';
2
+ import Bowser from 'bowser';
3
+ import { Observable, Subject, fromEvent, filter, tap, takeUntil, mergeMap, startWith, finalize } from 'rxjs';
5
4
  import { HttpParams } from '@angular/common/http';
6
5
  import { TemplateRef, ElementRef, isSignal, signal, InjectionToken } from '@angular/core';
7
6
  import dayjs from 'dayjs';
@@ -13,227 +12,6 @@ import timezone from 'dayjs/plugin/timezone';
13
12
  import updateLocale from 'dayjs/plugin/updateLocale';
14
13
  import utc from 'dayjs/plugin/utc';
15
14
  import CryptoES from 'crypto-es';
16
- import Bowser from 'bowser';
17
-
18
- const ERROR_MESSAGE_EMPTY_VALID = 'i18n_valid_empty_message';
19
- const ERROR_MESSAGE_PATTEN_VALID = 'i18n_valid_pattern_message';
20
- const ERROR_MESSAGE_MIN_VALID = 'i18n_message_error_input_min_value';
21
- const ERROR_MESSAGE_MAX_VALID = 'i18n_message_error_input_max_value';
22
- const ERROR_MESSAGE_MIN_LENGTH = 'i18n_message_error_input_min_length';
23
- const ERROR_MESSAGE_MAX_LENGTH = 'i18n_message_error_input_max_length';
24
- const CHARACTER_DATA_EMPTY = '__';
25
- const DEFAULT_START_PAGE_0 = 'defaultStartPage0';
26
- const COMMUNICATE_MICRO_PREFIX_TYPE = '3RD_INTEGRATE_MICRO_SITE_';
27
- const COMMUNICATE_MICRO_KEY_GET_ALL_MESSAGE = 'MICRO_SITES_ALL_MESSAGE';
28
-
29
- /* eslint-disable no-useless-escape */
30
- const patternEmail = () => {
31
- return /^[A-z0-9]+[A-z0-9\_\.\+\-]*[A-z0-9]@[A-z0-9]+[A-z0-9\_\.\+\-]*[A-z0-9]\.[A-z0-9]+[A-z0-9\_\.\+\-]*[A-z0-9]$/;
32
- };
33
- const patterProtocolUrl = () => {
34
- return /(http|https|ftp):/;
35
- };
36
- const patternUrl = () => {
37
- return /^(http|https|ftp):(\/){2}[^\s]+[.]{1}[^\s]+$/;
38
- };
39
- const patternHostUrl = () => {
40
- return /^((https|http|ftp):[/]{2}[^/\s]+)/;
41
- };
42
- const patternDomain = () => {
43
- return /^([a-zA-Z0-9])(([a-z0-9-]{1,61})?[a-z0-9]{1})?(\.[a-z0-9](([a-z0-9-]{1,61})?[a-z0-9]{1})?)?(\.[a-zA-Z]{2,4})+$/;
44
- };
45
- const patternMobilePhone = () => {
46
- return /^(\+?84|0|84)([0-9]{9})$/;
47
- };
48
- const patternPhone = () => {
49
- return /^(\+?84|[0-9]|84)([0-9]{2,9})$/;
50
- };
51
- const patternNumber = () => {
52
- return /\d+/g;
53
- };
54
- const patternEncodeUri = () => {
55
- return /%([0-9A-F]{2})/g;
56
- };
57
- const patternName = () => {
58
- return /^\w+[A-Za-z\s\d]+$/;
59
- };
60
- const patternNameUtf8 = () => {
61
- return /^[ àáảãạăắằẵặẳâầấậẫẩđèéẻẽẹêềếểễệìíỉĩịòóỏõọôồốổỗộơờớởỡợùúủũụưừứửữựỳýỷỹÀÁẢÃẠĂẮẰẴẶẲÂẦẤẬẪẨĐÈÉẺẼẸÊỀẾỂỄỆÌÍỈĨỊÒÓỎÕỌÔỒỐỔỖỘƠỜỚỞỠỢÙÚỦŨỤƯỪỨỬỮỰỲÝỶỸA-Za-z0-9]+$/;
62
- };
63
- const patternNameSpecial = () => {
64
- return /[~!@#$%^&*()-+=<>,?\/\\:;"']/;
65
- };
66
- const patternNameProfile = () => {
67
- return /([\w\W\d\s]+)+/;
68
- };
69
- const patternEmoji = () => {
70
- return /(\u00a9|\u00ae|[\u2000-\u3300]|\ud83c[\ud000-\udfff]|\ud83d[\ud000-\udfff]|\ud83e[\ud000-\udfff])/g;
71
- };
72
- const patternRuleFieldReplace = () => {
73
- return /[{]{2}[a-zA-Z_-]+[}]{2}/g;
74
- };
75
- const patternGetFieldByRuleFieldReplace = () => {
76
- return /[a-zA-Z_-]+/g;
77
- };
78
- const patternPem = () => {
79
- return /^(0|1):([0-9]{1,2}):(\{\{path-api\}\}):([a-zA-Z0-9\/]+)$/g;
80
- };
81
- const patternTax = () => {
82
- return /^([0-9]){10}(-[0-9]{3})?$/;
83
- };
84
- const patternKey = () => {
85
- return /^([0-9]){10}(-[0-9]{3})?$/;
86
- };
87
- const patternAccount = () => {
88
- return /^(?=.*@)[a-z0-9@._-]{2,63}$/;
89
- };
90
-
91
- const highlightByKeyword = (value, search, ignoreHighlight, classHightLight) => {
92
- if (!value) {
93
- return CHARACTER_DATA_EMPTY;
94
- }
95
- try {
96
- if (!search || ignoreHighlight) {
97
- return value;
98
- }
99
- const keysReplace = getValueReplace(search, value);
100
- if (!keysReplace || !keysReplace.length) {
101
- return value;
102
- }
103
- if (!classHightLight) {
104
- classHightLight = 'bg-[#19344a] text-white';
105
- }
106
- keysReplace.forEach((key) => {
107
- const regExp = new RegExp(key, 'gi');
108
- value = value?.replace(regExp, `<span class="${classHightLight}">$&</span>`);
109
- });
110
- }
111
- catch (error) {
112
- console.log(error);
113
- }
114
- finally {
115
- // eslint-disable-next-line no-unsafe-finally
116
- return value;
117
- }
118
- };
119
- const getValueReplace = (search, value) => {
120
- const searchConvert = deleteUnicode(search).toLowerCase();
121
- const valueConvert = deleteUnicode(value).toLowerCase();
122
- const keys = new Set();
123
- let i = 0;
124
- while ((i = valueConvert.indexOf(searchConvert, i)) >= 0) {
125
- const endIndex = i + search.length;
126
- keys.add(value.substring(i, endIndex));
127
- i += +valueConvert.length;
128
- }
129
- return Array.from(keys);
130
- };
131
- const formatTextCompare = (text, options) => {
132
- if (!text) {
133
- return text;
134
- }
135
- text = text.normalize('NFC');
136
- return formatByOptions(text, options);
137
- };
138
- const fullNameFormat = (value) => {
139
- if (!value) {
140
- return value;
141
- }
142
- return capitalize(value, { lowercaseOtherCharacter: true, trim: true, removeMultipleSpace: true, removeEmoji: true });
143
- };
144
- const capitalize = (text, options) => {
145
- if (!text) {
146
- return text;
147
- }
148
- text = formatByOptions(text, options);
149
- return text
150
- .split(' ')
151
- .map((word) => firstLetterToUpperCase(word))
152
- .join(' ');
153
- };
154
- const firstLetterToUpperCase = (text, options) => {
155
- if (!text) {
156
- return text;
157
- }
158
- return uppercaseByPosition(text, 0, options);
159
- };
160
- const uppercaseByPosition = (text, position, options) => {
161
- if (!text) {
162
- return text;
163
- }
164
- text = formatByOptions(text, options);
165
- return `${text.substring(0, position)}${text.charAt(position).toUpperCase()}${text.substring(position + 1)}`;
166
- };
167
- const formatByOptions = (text, options) => {
168
- if (!text || !options) {
169
- return text;
170
- }
171
- if (options?.uppercaseOtherCharacter) {
172
- text = text.toUpperCase();
173
- }
174
- if (options?.lowercaseOtherCharacter) {
175
- text = text.toLowerCase();
176
- }
177
- if (options?.removeMultipleSpace) {
178
- text = text.replace(/\u200B|\u00A0/g, '');
179
- text = text.replace(/\s+/g, ' ');
180
- }
181
- if (options?.removeEmoji) {
182
- text = removeEmoji(text);
183
- }
184
- if (options?.removeUnicode) {
185
- text = deleteUnicode(text);
186
- }
187
- if (options?.trim) {
188
- text = text.trim();
189
- }
190
- return text;
191
- };
192
- const escapeHtml = (str) => {
193
- if (!str || typeof str !== 'string') {
194
- return str;
195
- }
196
- return str.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;').replace(/'/g, '&#039;');
197
- };
198
- const decodeEscapeHtml = (str) => {
199
- const htmlTag = document.createElement('textarea');
200
- htmlTag.innerHTML = str;
201
- while (str) {
202
- if (str === htmlTag.value) {
203
- str = htmlTag.value;
204
- htmlTag.remove();
205
- break;
206
- }
207
- str = htmlTag.value;
208
- htmlTag.innerHTML = str;
209
- }
210
- return str;
211
- };
212
- const deleteUnicode = (str) => {
213
- str = str.replace(/à|á|ạ|ả|ã|â|ầ|ấ|ậ|ẩ|ẫ|ă|ằ|ắ|ặ|ẳ|ẵ/g, 'a');
214
- str = str.replace(/è|é|ẹ|ẻ|ẽ|ê|ề|ế|ệ|ể|ễ|ễ/g, 'e');
215
- str = str.replace(/ì|í|ị|ỉ|ĩ/g, 'i');
216
- str = str.replace(/ò|ó|ọ|ỏ|õ|ô|ồ|ố|ộ|ổ|ỗ|ơ|ờ|ớ|ợ|ở|ỡ/g, 'o');
217
- str = str.replace(/ù|ú|ụ|ủ|ũ|ư|ừ|ứ|ự|ử|ữ/g, 'u');
218
- str = str.replace(/ỳ|ý|ỵ|ỷ|ỹ/g, 'y');
219
- str = str.replace(/đ/g, 'd');
220
- str = str.replace(/À|Á|Ạ|Ả|Ã|Â|Ầ|Ấ|Ậ|Ẩ|Ẫ|Ă|Ằ|Ắ|Ặ|Ẳ|Ẵ/g, 'A');
221
- str = str.replace(/È|É|Ẹ|Ẻ|Ẽ|Ê|Ề|Ế|Ệ|Ể|Ễ/g, 'E');
222
- str = str.replace(/Ì|Í|Ị|Ỉ|Ĩ/g, 'I');
223
- str = str.replace(/Ò|Ó|Ọ|Ỏ|Õ|Ô|Ồ|Ố|Ộ|Ổ|Ỗ|Ơ|Ờ|Ớ|Ợ|Ở|Ỡ/g, 'O');
224
- str = str.replace(/Ù|Ú|Ụ|Ủ|Ũ|Ư|Ừ|Ứ|Ự|Ử|Ữ/g, 'U');
225
- str = str.replace(/Ỳ|Ý|Ỵ|Ỷ|Ỹ/g, 'Y');
226
- str = str.replace(/Đ/g, 'D');
227
- str = str.replace(/\u0300|\u0301|\u0303|\u0309|\u0323/g, ''); // ̀ ́ ̃ ̉ ̣ huyền, sắc, ngã, hỏi, nặng
228
- str = str.replace(/\u02C6|\u0306|\u031B/g, ''); // ˆ ̆ ̛ Â, Ê, Ă, Ơ, Ư
229
- return str.normalize('NFC');
230
- };
231
- const removeEmoji = (text) => {
232
- if (!text || !text.trim()) {
233
- return text;
234
- }
235
- return text.replace(patternEmoji(), '');
236
- };
237
15
 
238
16
  /* eslint-disable @typescript-eslint/no-explicit-any */
239
17
  /**
@@ -468,6 +246,17 @@ const isEmbedFrame = () => {
468
246
  return functionCheck();
469
247
  };
470
248
 
249
+ const ERROR_MESSAGE_EMPTY_VALID = 'i18n_valid_empty_message';
250
+ const ERROR_MESSAGE_PATTEN_VALID = 'i18n_valid_pattern_message';
251
+ const ERROR_MESSAGE_MIN_VALID = 'i18n_message_error_input_min_value';
252
+ const ERROR_MESSAGE_MAX_VALID = 'i18n_message_error_input_max_value';
253
+ const ERROR_MESSAGE_MIN_LENGTH = 'i18n_message_error_input_min_length';
254
+ const ERROR_MESSAGE_MAX_LENGTH = 'i18n_message_error_input_max_length';
255
+ const CHARACTER_DATA_EMPTY = '__';
256
+ const DEFAULT_START_PAGE_0 = 'defaultStartPage0';
257
+ const COMMUNICATE_MICRO_PREFIX_TYPE = '3RD_INTEGRATE_MICRO_SITE_';
258
+ const COMMUNICATE_MICRO_KEY_GET_ALL_MESSAGE = 'MICRO_SITES_ALL_MESSAGE';
259
+
471
260
  /* eslint-disable @typescript-eslint/no-explicit-any */
472
261
  class UtilsCommunicateMicroKeyGlobal {
473
262
  static KEY_MESSAGE_MODAL = 'LIBS_UI_MODEL_EVENT';
@@ -2127,8 +1916,6 @@ const generateInterface = (obj, interfaceName) => {
2127
1916
  };
2128
1917
 
2129
1918
  let parser = null;
2130
- let quill = null;
2131
- let quill2x = null;
2132
1919
  let bowserParser = null;
2133
1920
  const getDeviceInfo = () => {
2134
1921
  if (!bowserParser) {
@@ -2249,149 +2036,6 @@ const getDragEventByElement = (config) => {
2249
2036
  }), takeUntil(mouseup));
2250
2037
  return mouseDown.pipe(mergeMap((e) => (config.isStartWithMouseDownEvent ? mousemove.pipe(startWith(e)) : mousemove)), takeUntilDestroyed(config.destroyRef), finalize(removeClass));
2251
2038
  };
2252
- const getHTMLFromQuill = async (data, options) => {
2253
- if (!quill) {
2254
- quill = new Quill(document.createElement('div'));
2255
- }
2256
- const { replaceNewLineTo = '<br>', replaceTagBRTo, replaceTags, replaceBrToDiv } = options || {};
2257
- const delta = typeof data === 'string' ? await getDeltaFromHTML(data) : data;
2258
- if (options?.functionReplaceDelta) {
2259
- options.functionReplaceDelta(delta);
2260
- }
2261
- delta.ops.forEach((op) => {
2262
- if (op.insert) {
2263
- if (typeof op.insert === 'string') {
2264
- if (replaceNewLineTo) {
2265
- op.insert = op.insert.replace(/\n/g, replaceNewLineTo);
2266
- }
2267
- if (replaceTagBRTo) {
2268
- op.insert = op.insert.replace(/<br>/g, replaceTagBRTo);
2269
- }
2270
- if (replaceTags?.length) {
2271
- for (const tag of replaceTags) {
2272
- op.insert = op.insert.replace(new RegExp(`<${tag.tag}>`, 'g'), `<${tag.replaceTo}>`);
2273
- op.insert = op.insert.replace(new RegExp(`</${tag.tag}>`, 'g'), `</${tag.replaceTo}>`);
2274
- }
2275
- }
2276
- }
2277
- }
2278
- });
2279
- quill.setContents(delta);
2280
- let htmlText = options?.getRootHtml ? quill.root.innerHTML : quill.root.firstElementChild?.innerHTML;
2281
- if (replaceBrToDiv) {
2282
- htmlText = convertHtmlToDivBlocks(htmlText || '');
2283
- }
2284
- return decodeEscapeHtml(htmlText || '');
2285
- };
2286
- const convertHtmlToDivBlocks = (html) => {
2287
- const BREAK_TOKEN = '<<<BREAK>>>';
2288
- // Bước 1: thay <br> thành token tạm
2289
- const normalizedHtml = html.replace(/<br\s*\/?>/gi, BREAK_TOKEN);
2290
- // Bước 2: tách theo token
2291
- const parts = normalizedHtml.split(BREAK_TOKEN);
2292
- const parser = new DOMParser();
2293
- const divs = [];
2294
- for (const raw of parts) {
2295
- const trimmed = raw.trim();
2296
- if (!trimmed)
2297
- continue;
2298
- // parse mỗi phần nhỏ như một document riêng
2299
- const doc = parser.parseFromString(trimmed, 'text/html');
2300
- const body = doc.body;
2301
- // Lấy lại nội dung bên trong body
2302
- divs.push(`<div>${body.innerHTML}</div>`);
2303
- }
2304
- return divs.join('');
2305
- };
2306
- const getDeltaFromHTML = async (html) => {
2307
- if (!quill) {
2308
- quill = new Quill(document.createElement('div'));
2309
- }
2310
- quill.root.innerHTML = html;
2311
- await lastValueFrom(timer(1000));
2312
- return quill.getContents();
2313
- };
2314
- const processPasteData = async (e, config) => {
2315
- const element = config.element;
2316
- const files = e.clipboardData?.files;
2317
- if (files?.length) {
2318
- e.preventDefault();
2319
- config.handlerPasteFile?.(files);
2320
- config.callBack?.('file');
2321
- return;
2322
- }
2323
- // Lưu selection TRƯỚC khi prevent default
2324
- const selection = window.getSelection();
2325
- let savedRange = null;
2326
- if (selection && selection.rangeCount > 0) {
2327
- const range = selection.getRangeAt(0);
2328
- // Chỉ lưu nếu range nằm trong contentText element
2329
- const container = range.commonAncestorContainer;
2330
- const isInContentElement = element.contains(container.nodeType === Node.TEXT_NODE ? container.parentNode : container);
2331
- if (isInContentElement) {
2332
- savedRange = range.cloneRange();
2333
- }
2334
- }
2335
- // Prevent default để tự xử lý paste
2336
- e.preventDefault();
2337
- // Sử dụng Quill để clean HTML content
2338
- const htmlContent = e.clipboardData?.getData('text/html') || '';
2339
- const plainText = e.clipboardData?.getData('text/plain') || '';
2340
- let contentToInsert = (plainText || '').replace(/\n/g, '<br>');
2341
- if (htmlContent) {
2342
- contentToInsert = await getHTMLFromQuill(htmlContent);
2343
- }
2344
- if (!contentToInsert) {
2345
- config.callBack?.('no-content');
2346
- return;
2347
- }
2348
- if (savedRange) {
2349
- insertContentWithRange(contentToInsert, savedRange, element);
2350
- config.callBack?.('range');
2351
- return;
2352
- }
2353
- element.innerHTML += contentToInsert;
2354
- config.callBack?.('content');
2355
- };
2356
- const insertContentWithRange = (content, savedRange, element) => {
2357
- const selection = window.getSelection();
2358
- if (!selection) {
2359
- // Fallback: append vào cuối
2360
- element.innerHTML += content;
2361
- return;
2362
- }
2363
- // Restore selection
2364
- selection.removeAllRanges();
2365
- selection.addRange(savedRange);
2366
- // Xóa nội dung đã select (nếu có)
2367
- savedRange.deleteContents();
2368
- // Tạo document fragment từ HTML content
2369
- const tempDiv = document.createElement('div');
2370
- tempDiv.innerHTML = content;
2371
- const fragment = document.createDocumentFragment();
2372
- while (tempDiv.firstChild) {
2373
- fragment.appendChild(tempDiv.firstChild);
2374
- }
2375
- // Insert fragment tại vị trí range
2376
- savedRange.insertNode(fragment);
2377
- // Di chuyển cursor đến cuối nội dung vừa insert
2378
- if (fragment.lastChild) {
2379
- savedRange.setStartAfter(fragment.lastChild);
2380
- }
2381
- savedRange.collapse(true);
2382
- selection.removeAllRanges();
2383
- selection.addRange(savedRange);
2384
- };
2385
- const quill2xGetHtmlByDelta = (delta) => {
2386
- if (!quill2x) {
2387
- quill2x = new Quill2x(document.createElement('div'));
2388
- }
2389
- if (!delta || !delta.ops || !delta.ops.length) {
2390
- return '';
2391
- }
2392
- quill2x.setContents(delta);
2393
- return quill2x.root.innerHTML;
2394
- };
2395
2039
 
2396
2040
  class UtilsUrlSearchParams {
2397
2041
  static instance;
@@ -2911,6 +2555,68 @@ const viewDataNumberByLanguage = (value, acceptNegativeValue, parseFixed = 1, ig
2911
2555
  }
2912
2556
  };
2913
2557
 
2558
+ /* eslint-disable no-useless-escape */
2559
+ const patternEmail = () => {
2560
+ return /^[A-z0-9]+[A-z0-9\_\.\+\-]*[A-z0-9]@[A-z0-9]+[A-z0-9\_\.\+\-]*[A-z0-9]\.[A-z0-9]+[A-z0-9\_\.\+\-]*[A-z0-9]$/;
2561
+ };
2562
+ const patterProtocolUrl = () => {
2563
+ return /(http|https|ftp):/;
2564
+ };
2565
+ const patternUrl = () => {
2566
+ return /^(http|https|ftp):(\/){2}[^\s]+[.]{1}[^\s]+$/;
2567
+ };
2568
+ const patternHostUrl = () => {
2569
+ return /^((https|http|ftp):[/]{2}[^/\s]+)/;
2570
+ };
2571
+ const patternDomain = () => {
2572
+ return /^([a-zA-Z0-9])(([a-z0-9-]{1,61})?[a-z0-9]{1})?(\.[a-z0-9](([a-z0-9-]{1,61})?[a-z0-9]{1})?)?(\.[a-zA-Z]{2,4})+$/;
2573
+ };
2574
+ const patternMobilePhone = () => {
2575
+ return /^(\+?84|0|84)([0-9]{9})$/;
2576
+ };
2577
+ const patternPhone = () => {
2578
+ return /^(\+?84|[0-9]|84)([0-9]{2,9})$/;
2579
+ };
2580
+ const patternNumber = () => {
2581
+ return /\d+/g;
2582
+ };
2583
+ const patternEncodeUri = () => {
2584
+ return /%([0-9A-F]{2})/g;
2585
+ };
2586
+ const patternName = () => {
2587
+ return /^\w+[A-Za-z\s\d]+$/;
2588
+ };
2589
+ const patternNameUtf8 = () => {
2590
+ return /^[ àáảãạăắằẵặẳâầấậẫẩđèéẻẽẹêềếểễệìíỉĩịòóỏõọôồốổỗộơờớởỡợùúủũụưừứửữựỳýỷỹÀÁẢÃẠĂẮẰẴẶẲÂẦẤẬẪẨĐÈÉẺẼẸÊỀẾỂỄỆÌÍỈĨỊÒÓỎÕỌÔỒỐỔỖỘƠỜỚỞỠỢÙÚỦŨỤƯỪỨỬỮỰỲÝỶỸA-Za-z0-9]+$/;
2591
+ };
2592
+ const patternNameSpecial = () => {
2593
+ return /[~!@#$%^&*()-+=<>,?\/\\:;"']/;
2594
+ };
2595
+ const patternNameProfile = () => {
2596
+ return /([\w\W\d\s]+)+/;
2597
+ };
2598
+ const patternEmoji = () => {
2599
+ return /(\u00a9|\u00ae|[\u2000-\u3300]|\ud83c[\ud000-\udfff]|\ud83d[\ud000-\udfff]|\ud83e[\ud000-\udfff])/g;
2600
+ };
2601
+ const patternRuleFieldReplace = () => {
2602
+ return /[{]{2}[a-zA-Z_-]+[}]{2}/g;
2603
+ };
2604
+ const patternGetFieldByRuleFieldReplace = () => {
2605
+ return /[a-zA-Z_-]+/g;
2606
+ };
2607
+ const patternPem = () => {
2608
+ return /^(0|1):([0-9]{1,2}):(\{\{path-api\}\}):([a-zA-Z0-9\/]+)$/g;
2609
+ };
2610
+ const patternTax = () => {
2611
+ return /^([0-9]){10}(-[0-9]{3})?$/;
2612
+ };
2613
+ const patternKey = () => {
2614
+ return /^([0-9]){10}(-[0-9]{3})?$/;
2615
+ };
2616
+ const patternAccount = () => {
2617
+ return /^(?=.*@)[a-z0-9@._-]{2,63}$/;
2618
+ };
2619
+
2914
2620
  let functionXssFilter = async (value) => {
2915
2621
  return value;
2916
2622
  };
@@ -3118,6 +2824,153 @@ const convertUrlToFile = (url, fileName) => {
3118
2824
  });
3119
2825
  };
3120
2826
 
2827
+ const highlightByKeyword = (value, search, ignoreHighlight, classHightLight) => {
2828
+ if (!value) {
2829
+ return CHARACTER_DATA_EMPTY;
2830
+ }
2831
+ try {
2832
+ if (!search || ignoreHighlight) {
2833
+ return value;
2834
+ }
2835
+ const keysReplace = getValueReplace(search, value);
2836
+ if (!keysReplace || !keysReplace.length) {
2837
+ return value;
2838
+ }
2839
+ if (!classHightLight) {
2840
+ classHightLight = 'bg-[#19344a] text-white';
2841
+ }
2842
+ keysReplace.forEach((key) => {
2843
+ const regExp = new RegExp(key, 'gi');
2844
+ value = value?.replace(regExp, `<span class="${classHightLight}">$&</span>`);
2845
+ });
2846
+ }
2847
+ catch (error) {
2848
+ console.log(error);
2849
+ }
2850
+ finally {
2851
+ // eslint-disable-next-line no-unsafe-finally
2852
+ return value;
2853
+ }
2854
+ };
2855
+ const getValueReplace = (search, value) => {
2856
+ const searchConvert = deleteUnicode(search).toLowerCase();
2857
+ const valueConvert = deleteUnicode(value).toLowerCase();
2858
+ const keys = new Set();
2859
+ let i = 0;
2860
+ while ((i = valueConvert.indexOf(searchConvert, i)) >= 0) {
2861
+ const endIndex = i + search.length;
2862
+ keys.add(value.substring(i, endIndex));
2863
+ i += +valueConvert.length;
2864
+ }
2865
+ return Array.from(keys);
2866
+ };
2867
+ const formatTextCompare = (text, options) => {
2868
+ if (!text) {
2869
+ return text;
2870
+ }
2871
+ text = text.normalize('NFC');
2872
+ return formatByOptions(text, options);
2873
+ };
2874
+ const fullNameFormat = (value) => {
2875
+ if (!value) {
2876
+ return value;
2877
+ }
2878
+ return capitalize(value, { lowercaseOtherCharacter: true, trim: true, removeMultipleSpace: true, removeEmoji: true });
2879
+ };
2880
+ const capitalize = (text, options) => {
2881
+ if (!text) {
2882
+ return text;
2883
+ }
2884
+ text = formatByOptions(text, options);
2885
+ return text
2886
+ .split(' ')
2887
+ .map((word) => firstLetterToUpperCase(word))
2888
+ .join(' ');
2889
+ };
2890
+ const firstLetterToUpperCase = (text, options) => {
2891
+ if (!text) {
2892
+ return text;
2893
+ }
2894
+ return uppercaseByPosition(text, 0, options);
2895
+ };
2896
+ const uppercaseByPosition = (text, position, options) => {
2897
+ if (!text) {
2898
+ return text;
2899
+ }
2900
+ text = formatByOptions(text, options);
2901
+ return `${text.substring(0, position)}${text.charAt(position).toUpperCase()}${text.substring(position + 1)}`;
2902
+ };
2903
+ const formatByOptions = (text, options) => {
2904
+ if (!text || !options) {
2905
+ return text;
2906
+ }
2907
+ if (options?.uppercaseOtherCharacter) {
2908
+ text = text.toUpperCase();
2909
+ }
2910
+ if (options?.lowercaseOtherCharacter) {
2911
+ text = text.toLowerCase();
2912
+ }
2913
+ if (options?.removeMultipleSpace) {
2914
+ text = text.replace(/\u200B|\u00A0/g, '');
2915
+ text = text.replace(/\s+/g, ' ');
2916
+ }
2917
+ if (options?.removeEmoji) {
2918
+ text = removeEmoji(text);
2919
+ }
2920
+ if (options?.removeUnicode) {
2921
+ text = deleteUnicode(text);
2922
+ }
2923
+ if (options?.trim) {
2924
+ text = text.trim();
2925
+ }
2926
+ return text;
2927
+ };
2928
+ const escapeHtml = (str) => {
2929
+ if (!str || typeof str !== 'string') {
2930
+ return str;
2931
+ }
2932
+ return str.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;').replace(/'/g, '&#039;');
2933
+ };
2934
+ const decodeEscapeHtml = (str) => {
2935
+ const htmlTag = document.createElement('textarea');
2936
+ htmlTag.innerHTML = str;
2937
+ while (str) {
2938
+ if (str === htmlTag.value) {
2939
+ str = htmlTag.value;
2940
+ htmlTag.remove();
2941
+ break;
2942
+ }
2943
+ str = htmlTag.value;
2944
+ htmlTag.innerHTML = str;
2945
+ }
2946
+ return str;
2947
+ };
2948
+ const deleteUnicode = (str) => {
2949
+ str = str.replace(/à|á|ạ|ả|ã|â|ầ|ấ|ậ|ẩ|ẫ|ă|ằ|ắ|ặ|ẳ|ẵ/g, 'a');
2950
+ str = str.replace(/è|é|ẹ|ẻ|ẽ|ê|ề|ế|ệ|ể|ễ|ễ/g, 'e');
2951
+ str = str.replace(/ì|í|ị|ỉ|ĩ/g, 'i');
2952
+ str = str.replace(/ò|ó|ọ|ỏ|õ|ô|ồ|ố|ộ|ổ|ỗ|ơ|ờ|ớ|ợ|ở|ỡ/g, 'o');
2953
+ str = str.replace(/ù|ú|ụ|ủ|ũ|ư|ừ|ứ|ự|ử|ữ/g, 'u');
2954
+ str = str.replace(/ỳ|ý|ỵ|ỷ|ỹ/g, 'y');
2955
+ str = str.replace(/đ/g, 'd');
2956
+ str = str.replace(/À|Á|Ạ|Ả|Ã|Â|Ầ|Ấ|Ậ|Ẩ|Ẫ|Ă|Ằ|Ắ|Ặ|Ẳ|Ẵ/g, 'A');
2957
+ str = str.replace(/È|É|Ẹ|Ẻ|Ẽ|Ê|Ề|Ế|Ệ|Ể|Ễ/g, 'E');
2958
+ str = str.replace(/Ì|Í|Ị|Ỉ|Ĩ/g, 'I');
2959
+ str = str.replace(/Ò|Ó|Ọ|Ỏ|Õ|Ô|Ồ|Ố|Ộ|Ổ|Ỗ|Ơ|Ờ|Ớ|Ợ|Ở|Ỡ/g, 'O');
2960
+ str = str.replace(/Ù|Ú|Ụ|Ủ|Ũ|Ư|Ừ|Ứ|Ự|Ử|Ữ/g, 'U');
2961
+ str = str.replace(/Ỳ|Ý|Ỵ|Ỷ|Ỹ/g, 'Y');
2962
+ str = str.replace(/Đ/g, 'D');
2963
+ str = str.replace(/\u0300|\u0301|\u0303|\u0309|\u0323/g, ''); // ̀ ́ ̃ ̉ ̣ huyền, sắc, ngã, hỏi, nặng
2964
+ str = str.replace(/\u02C6|\u0306|\u031B/g, ''); // ˆ ̆ ̛ Â, Ê, Ă, Ơ, Ư
2965
+ return str.normalize('NFC');
2966
+ };
2967
+ const removeEmoji = (text) => {
2968
+ if (!text || !text.trim()) {
2969
+ return text;
2970
+ }
2971
+ return text.replace(patternEmoji(), '');
2972
+ };
2973
+
3121
2974
  const DEFAULT_MIN_TICK_COUNT = 5;
3122
2975
  const DEFAULT_MAX_TICK_COUNT = 10;
3123
2976
  const MIN_DISTANCE_TO_ZERO = 3;
@@ -3374,5 +3227,5 @@ const getObjectSize = (obj) => {
3374
3227
  * Generated bundle index. Do not edit.
3375
3228
  */
3376
3229
 
3377
- 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, addArrayToSet, base64Decode, base64Encode, capitalize, checkMouseOverInContainer, checkViewInScreen, cloneDeep, cloneIBoundingClientRect, colorContrastFromOrigin, colorStepContrastFromOrigin, convertBase64ToBlob, convertBlobToFile, convertFileToBase64, convertFileToBase64_ObjectUrl, convertHtmlToDivBlocks, convertObjectToSignal, convertSetToArray, convertSignalToObject, convertUrlToFile, createUniqueRandomIntGenerator, decodeEscapeHtml, decodeURI, decrypt, decrypt3rd, deleteUnicode, detectAndCleanNearWhiteColors, 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, getObjectSize, getSmartAxisScale, getViewport, groupBy, hasDangerousConstructorName, highlightByKeyword, insertContentWithRange, isArray, isAsyncObject, isBrowserAPIObject, isBrowserGlobalObject, isBuiltInObject, isDOMObject, isDangerousObject, isDayjsObject, isDifferenceDay, isDifferenceMonth, isDifferenceYear, isEmbedFrame, isEmpty, isEqual, isFalsy, isFile, isFrameworkObject, isIncludeAudioExtList, isIncludeDocumentExtList, isIncludeImageExtList, isIncludeVideoExtList, isMap, isNearWhite, isNil, isRegExp, isReturnAsIsObject, isSafeToProcess, isSet, isSkippableObject, isSpecialObject, isTouchDevice, isTruthy, isTypeAudio, isTypeFile, isTypeImage, isTypeVideo, keyBy, listColorDefine, md5, omitBy, patterProtocolUrl, patternAccount, patternDomain, patternEmail, patternEmoji, patternEncodeUri, patternGetFieldByRuleFieldReplace, patternHostUrl, patternKey, patternMobilePhone, patternName, patternNameProfile, patternNameSpecial, patternNameUtf8, patternNumber, patternPem, patternPhone, patternRuleFieldReplace, patternTax, patternUrl, processPasteData, protectString, quill2xGetHtmlByDelta, range, removeEmoji, revealString, rgbToHex, set, setCaretPosition, setDefaultTimeZone, setKeyCrypto, setKeyCrypto3rd, setPatternCheckTimeUTC, setStylesElement, uniqBy, unwrapSignal, updateFunctionCheckEmbedFrame, updateFunctionFormatDate, updateFunctionXssFilter, uppercaseByPosition, uuid, viewDataNumberByLanguage, xssFilter };
3230
+ 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, addArrayToSet, base64Decode, base64Encode, capitalize, checkMouseOverInContainer, checkViewInScreen, cloneDeep, cloneIBoundingClientRect, colorContrastFromOrigin, colorStepContrastFromOrigin, convertBase64ToBlob, convertBlobToFile, convertFileToBase64, convertFileToBase64_ObjectUrl, convertObjectToSignal, convertSetToArray, convertSignalToObject, convertUrlToFile, createUniqueRandomIntGenerator, decodeEscapeHtml, decodeURI, decrypt, decrypt3rd, deleteUnicode, detectAndCleanNearWhiteColors, downloadFileByUrl, downloadFileByUrlUseXmlRequest, downloadImageFromELement, encodeURI, encrypt, encrypt3rd, endCodeUrl, escapeHtml, firstLetterToUpperCase, formatDate, formatNumber, formatTextCompare, fullNameFormat, generateInterface, get, getColorById, getDayjs, getDeviceInfo, getDocumentByString, getDragEventByElement, getEventNameHandleClick, getFileExtension, getKeyCacheByArrayObject, getLabelBySizeFile, getObjectSize, getSmartAxisScale, getViewport, groupBy, hasDangerousConstructorName, highlightByKeyword, isArray, isAsyncObject, isBrowserAPIObject, isBrowserGlobalObject, isBuiltInObject, isDOMObject, isDangerousObject, isDayjsObject, isDifferenceDay, isDifferenceMonth, isDifferenceYear, isEmbedFrame, isEmpty, isEqual, isFalsy, isFile, isFrameworkObject, isIncludeAudioExtList, isIncludeDocumentExtList, isIncludeImageExtList, isIncludeVideoExtList, isMap, isNearWhite, isNil, isRegExp, isReturnAsIsObject, isSafeToProcess, isSet, isSkippableObject, isSpecialObject, isTouchDevice, isTruthy, isTypeAudio, isTypeFile, isTypeImage, isTypeVideo, keyBy, listColorDefine, md5, omitBy, patterProtocolUrl, patternAccount, patternDomain, patternEmail, patternEmoji, patternEncodeUri, patternGetFieldByRuleFieldReplace, patternHostUrl, patternKey, patternMobilePhone, patternName, patternNameProfile, patternNameSpecial, patternNameUtf8, patternNumber, patternPem, patternPhone, patternRuleFieldReplace, patternTax, patternUrl, protectString, range, removeEmoji, revealString, rgbToHex, set, setCaretPosition, setDefaultTimeZone, setKeyCrypto, setKeyCrypto3rd, setPatternCheckTimeUTC, setStylesElement, uniqBy, unwrapSignal, updateFunctionCheckEmbedFrame, updateFunctionFormatDate, updateFunctionXssFilter, uppercaseByPosition, uuid, viewDataNumberByLanguage, xssFilter };
3378
3231
  //# sourceMappingURL=libs-ui-utils.mjs.map