@masterkeymaterial/ui 0.0.2 → 0.0.3

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.
Files changed (140) hide show
  1. package/fesm2022/masterkeymaterial-ui.mjs +6457 -0
  2. package/fesm2022/masterkeymaterial-ui.mjs.map +1 -0
  3. package/package.json +14 -5
  4. package/types/masterkeymaterial-ui.d.ts +928 -0
  5. package/ng-package.json +0 -10
  6. package/src/elements/ui-button/ui-button.css +0 -229
  7. package/src/elements/ui-button/ui-button.html +0 -12
  8. package/src/elements/ui-button/ui-button.ts +0 -133
  9. package/src/elements/ui-check-box/ui-check-box.css +0 -66
  10. package/src/elements/ui-check-box/ui-check-box.html +0 -5
  11. package/src/elements/ui-check-box/ui-check-box.ts +0 -65
  12. package/src/elements/ui-chip/ui-chip.css +0 -24
  13. package/src/elements/ui-chip/ui-chip.html +0 -3
  14. package/src/elements/ui-chip/ui-chip.ts +0 -25
  15. package/src/elements/ui-drop-zone/ui-drop-zone.css +0 -91
  16. package/src/elements/ui-drop-zone/ui-drop-zone.html +0 -8
  17. package/src/elements/ui-drop-zone/ui-drop-zone.ts +0 -153
  18. package/src/elements/ui-file-list/ui-file-list.css +0 -43
  19. package/src/elements/ui-file-list/ui-file-list.html +0 -17
  20. package/src/elements/ui-file-list/ui-file-list.ts +0 -22
  21. package/src/elements/ui-list-errors/ui-list-errors.css +0 -30
  22. package/src/elements/ui-list-errors/ui-list-errors.html +0 -10
  23. package/src/elements/ui-list-errors/ui-list-errors.ts +0 -14
  24. package/src/elements/ui-loading/ui-loading.css +0 -13
  25. package/src/elements/ui-loading/ui-loading.html +0 -1
  26. package/src/elements/ui-loading/ui-loading.ts +0 -10
  27. package/src/elements/ui-menu/ui-menu.css +0 -69
  28. package/src/elements/ui-menu/ui-menu.html +0 -20
  29. package/src/elements/ui-menu/ui-menu.ts +0 -267
  30. package/src/elements/ui-procurar/ui-procurar.css +0 -48
  31. package/src/elements/ui-procurar/ui-procurar.html +0 -14
  32. package/src/elements/ui-procurar/ui-procurar.ts +0 -82
  33. package/src/elements/ui-progress/ui-progress.css +0 -0
  34. package/src/elements/ui-progress/ui-progress.html +0 -1
  35. package/src/elements/ui-progress/ui-progress.ts +0 -15
  36. package/src/elements/ui-select/ui-select.css +0 -211
  37. package/src/elements/ui-select/ui-select.html +0 -46
  38. package/src/elements/ui-select/ui-select.ts +0 -482
  39. package/src/elements/ui-slide/ui-slide.css +0 -75
  40. package/src/elements/ui-slide/ui-slide.html +0 -7
  41. package/src/elements/ui-slide/ui-slide.ts +0 -61
  42. package/src/fields/Base/BaseFieldsForm/BaseFieldsForm.component.ts +0 -113
  43. package/src/fields/Base/BaseFieldsValues/BaseFieldsValues.ts +0 -112
  44. package/src/fields/Formulario/Formulario.ts +0 -1056
  45. package/src/fields/Formulario/form-action/form-action.css +0 -98
  46. package/src/fields/Formulario/form-action/form-action.html +0 -75
  47. package/src/fields/Formulario/form-action/form-action.ts +0 -187
  48. package/src/fields/Formulario/form-controls/form-controls.css +0 -108
  49. package/src/fields/Formulario/form-controls/form-controls.html +0 -105
  50. package/src/fields/Formulario/form-controls/form-controls.ts +0 -122
  51. package/src/fields/Formulario/form-fase/form-fase.css +0 -84
  52. package/src/fields/Formulario/form-fase/form-fase.html +0 -24
  53. package/src/fields/Formulario/form-fase/form-fase.ts +0 -157
  54. package/src/fields/Formulario/form-filter/form-filter.css +0 -50
  55. package/src/fields/Formulario/form-filter/form-filter.html +0 -25
  56. package/src/fields/Formulario/form-filter/form-filter.ts +0 -53
  57. package/src/fields/Formulario/form-no-action/form-no-action.css +0 -32
  58. package/src/fields/Formulario/form-no-action/form-no-action.html +0 -12
  59. package/src/fields/Formulario/form-no-action/form-no-action.ts +0 -21
  60. package/src/fields/Formulario/formated-values/formated-values.css +0 -104
  61. package/src/fields/Formulario/formated-values/formated-values.html +0 -15
  62. package/src/fields/Formulario/formated-values/formated-values.ts +0 -186
  63. package/src/fields/Formulario/single-values/single-values.css +0 -88
  64. package/src/fields/Formulario/single-values/single-values.html +0 -11
  65. package/src/fields/Formulario/single-values/single-values.ts +0 -65
  66. package/src/fields/autocomplete/autocomplete.css +0 -94
  67. package/src/fields/autocomplete/autocomplete.html +0 -38
  68. package/src/fields/autocomplete/autocomplete.ts +0 -294
  69. package/src/fields/button/button.css +0 -7
  70. package/src/fields/button/button.html +0 -19
  71. package/src/fields/button/button.ts +0 -38
  72. package/src/fields/checkbox/checkbox.css +0 -27
  73. package/src/fields/checkbox/checkbox.html +0 -20
  74. package/src/fields/checkbox/checkbox.ts +0 -44
  75. package/src/fields/color/CirculoColorido/circulocolorido.css +0 -50
  76. package/src/fields/color/CirculoColorido/circulocolorido.html +0 -8
  77. package/src/fields/color/CirculoColorido/circulocolorido.ts +0 -24
  78. package/src/fields/color/color.css +0 -15
  79. package/src/fields/color/color.html +0 -24
  80. package/src/fields/color/color.ts +0 -47
  81. package/src/fields/date/date.html +0 -19
  82. package/src/fields/date/date.ts +0 -29
  83. package/src/fields/datetime/datetime.html +0 -19
  84. package/src/fields/datetime/datetime.ts +0 -29
  85. package/src/fields/display/display.css +0 -7
  86. package/src/fields/display/display.html +0 -20
  87. package/src/fields/display/display.ts +0 -43
  88. package/src/fields/editor/editor.css +0 -51
  89. package/src/fields/editor/editor.html +0 -37
  90. package/src/fields/editor/editor.ts +0 -218
  91. package/src/fields/email/email.html +0 -19
  92. package/src/fields/email/email.ts +0 -29
  93. package/src/fields/fields.css +0 -180
  94. package/src/fields/generic/generic.html +0 -3
  95. package/src/fields/generic/generic.ts +0 -91
  96. package/src/fields/hidden/hidden.html +0 -3
  97. package/src/fields/hidden/hidden.ts +0 -20
  98. package/src/fields/icon/icon.css +0 -19
  99. package/src/fields/icon/icon.html +0 -27
  100. package/src/fields/icon/icon.ts +0 -31
  101. package/src/fields/multifactor/multifactor.css +0 -21
  102. package/src/fields/multifactor/multifactor.html +0 -39
  103. package/src/fields/multifactor/multifactor.ts +0 -106
  104. package/src/fields/multikv/multikv.css +0 -43
  105. package/src/fields/multikv/multikv.html +0 -47
  106. package/src/fields/multikv/multikv.ts +0 -88
  107. package/src/fields/multitext/multitext.css +0 -36
  108. package/src/fields/multitext/multitext.html +0 -38
  109. package/src/fields/multitext/multitext.ts +0 -75
  110. package/src/fields/number/number.html +0 -20
  111. package/src/fields/number/number.ts +0 -35
  112. package/src/fields/password/password.html +0 -23
  113. package/src/fields/password/password.ts +0 -37
  114. package/src/fields/search/search.css +0 -0
  115. package/src/fields/search/search.html +0 -19
  116. package/src/fields/search/search.ts +0 -54
  117. package/src/fields/select/select.css +0 -15
  118. package/src/fields/select/select.html +0 -18
  119. package/src/fields/select/select.ts +0 -52
  120. package/src/fields/slide/slide.css +0 -27
  121. package/src/fields/slide/slide.html +0 -20
  122. package/src/fields/slide/slide.ts +0 -45
  123. package/src/fields/text/text.html +0 -19
  124. package/src/fields/text/text.ts +0 -30
  125. package/src/fields/textarea/textarea.css +0 -4
  126. package/src/fields/textarea/textarea.html +0 -20
  127. package/src/fields/textarea/textarea.ts +0 -31
  128. package/src/fields/time/time.html +0 -19
  129. package/src/fields/time/time.ts +0 -29
  130. package/src/fields/upload/upload.css +0 -24
  131. package/src/fields/upload/upload.html +0 -41
  132. package/src/fields/upload/upload.ts +0 -137
  133. package/src/interfaces/interfaces.ts +0 -61
  134. package/src/public-api.ts +0 -38
  135. package/src/util/ClassOf.pipe.ts +0 -11
  136. package/src/util/JsonColorido.pipe.ts +0 -11
  137. package/src/util/util.ts +0 -2151
  138. package/tsconfig.lib.json +0 -16
  139. package/tsconfig.lib.prod.json +0 -9
  140. package/tsconfig.spec.json +0 -13
package/src/util/util.ts DELETED
@@ -1,2151 +0,0 @@
1
- import { WritableSignal } from "@angular/core";
2
- import { IFieldComponent } from "../fields/Formulario/Formulario";
3
-
4
- export class LibUtil {
5
-
6
- static loglevel = 0;
7
- static formConfigs: Partial<IFieldComponent<any>> = {};
8
-
9
- static classof = (o: any): IClassOf => {
10
- let nomeClasse = Object.prototype.toString.call(o).slice(8, -1).toLowerCase();
11
- if (nomeClasse == "number") {
12
- if (o.toString() == "NaN") {
13
- nomeClasse = "nan";
14
- }
15
- }
16
- return nomeClasse as IClassOf;
17
- };
18
-
19
- static wait = (ms: number) => {
20
- // Essa mecânica usa um setTimeout. A mecânica do Queue não foi implementada
21
- return new Promise(r => setTimeout(r, ms))
22
- };
23
-
24
- static clonar = (i: any) => {
25
- // Clona com a técnica de montar e desmontar string.
26
- // Não funciona para objetos com serviços (Date, File, Map, Set, etc)
27
- let parsed = null;
28
- try {
29
- let stringified = JSON.stringify(i);
30
- if (stringified == null) return null;
31
- if (stringified == "") return "";
32
- parsed = JSON.parse(stringified);
33
- if (parsed == null) return null;
34
- } catch (e) {
35
- return null;
36
- }
37
- return parsed;
38
- };
39
-
40
- static limparObject = (o: any) => {
41
- // Converte (Object) Limpar Nulos e Vazios
42
- if (LibUtil.classof(o) == "object") {
43
- for (let propName in o) {
44
- if (
45
- o[propName as keyof typeof o] === null ||
46
- o[propName as keyof typeof o] === undefined ||
47
- o[propName as keyof typeof o] === "" ||
48
- o[propName as keyof typeof o] === "undefined"
49
- ) {
50
- delete o[propName as keyof typeof o];
51
- }
52
- }
53
- }
54
- return o;
55
- };
56
-
57
- static mascarar = (texto: any, mascara: any): string | undefined => {
58
- // Informando uma máscara e um texto, retorna dado mascarado.
59
- // Mascaras: 0=Numero, A=Letra, Outros repete.
60
- if (LibUtil.classof(mascara) != "string") {
61
- // Se passar uma funcao para a mascara, Executa a função enviando o texto e deve retornar uma string da mascara para esse texto.
62
- if (LibUtil.classof(mascara) == "function") {
63
- mascara = mascara(texto); // Sobreextreve a mascara a ser executada pelo retorno da função.
64
- }
65
- }
66
- if (mascara) {
67
- if (texto) {
68
- if (LibUtil.classof(texto) != "string") texto = texto?.toString();
69
- if (LibUtil.classof(mascara) != "string") mascara = mascara?.toString(); // Se a chegar até aqui e ainda não for string
70
- let ms = [...LibUtil.clonar(mascara)];
71
- let ss = [...LibUtil.clonar(texto)];
72
- // this.l("ss: ", ss);
73
- let ts: any = [];
74
- let pm = 0;
75
- ss.forEach(s => {
76
- let t = null;
77
- if (/[0-9]/.test(s)) {
78
- t = "0";
79
- } else if (/[a-zA-Z]/.test(s)) {
80
- t = "A";
81
- } else {
82
- t = " ";
83
- }
84
- ts.push(t);
85
- pm++;
86
- });
87
- // this.l("ts: ", ts);
88
- // this.l("ms: ", ms);
89
- let r: any = [];
90
- for (let tp = 0, mp = 0; (tp < ts.length) && (mp < ms.length); tp++, mp++) {
91
- if (((ms[mp] === "0" || ms[mp] === "A") && (ms[mp] == ts[tp]))
92
- || (ms[mp] === "S" && (ts[tp] === "A" || ts[tp] === "0"))) {
93
- // FORMATO IGUAL.
94
- r.push(ss[tp]);
95
- } else {
96
- // MESMO CARACTER
97
- if (ss[tp] === ms[mp]) {
98
- r.push(ss[tp]);
99
- } else {
100
- // this.l("> ", ss[tp], " vs ", ms[mp])
101
- // Mágica: Coloca o especial que o usuário não colocou.
102
- if (ms[mp] != "0" && ms[mp] != "A" && ms[mp] != "S") {
103
- r.push(ms[mp]);
104
- tp--;
105
- } else {
106
- mp--;
107
- }
108
- }
109
- }
110
- }
111
- return r.join("");
112
- }
113
- } else {
114
- console.log("❌ Mascarar Requer Texto: ", texto, " e Mascara: ", mascara);
115
- }
116
- return undefined;
117
- };
118
-
119
- static tryParseJSON(val: any): any[] | null {
120
- try {
121
- return JSON.parse(val);
122
- } catch (e) {
123
- return null;
124
- }
125
- }
126
-
127
- static contem = (strMaior: string, strMenor: string): boolean => {
128
- // Comparardor de string CONTEM
129
- strMaior = LibUtil.removeAcentos(strMaior).toLowerCase();
130
- strMenor = LibUtil.removeAcentos(strMenor).toLowerCase();
131
- return (strMaior.includes(strMenor));
132
- };
133
-
134
- static removeAcentos = (s: string): string => {
135
- if (s == null) return "";
136
- // Remove acentos e depois chama Apenas Números e Letras.
137
- s = s.toString();
138
- let r = "";
139
- let sS = "áàãâäéèêëíìîïóòõôöúùûüçÁÀÃÂÄÉÈÊËÍÌÎÏÓÒÕÖÔÚÙÛÜÇ";
140
- let sN = "aaaaaeeeeiiiiooooouuuucAAAAAEEEEIIIIOOOOOUUUUC";
141
- for (let p = 0; p < s.length; p++) {
142
- let pSS = sS.indexOf(s.charAt(p)); // <= Procura
143
- if (pSS != -1) {
144
- r += sN.charAt(pSS); // Substitui mesma posicao
145
- } else {
146
- r += s.charAt(p);
147
- }
148
- }
149
- return r;
150
- };
151
-
152
- static fileReader = async (arquivo: File, eventos?: Function): Promise<string | null> => {
153
- return new Promise((r) => {
154
- let leitor = new FileReader();
155
- let gatilhos = (event: any) => {
156
- if (event.type == "error") {
157
- r(null);
158
- }
159
- else if (event.type == "loadend") {
160
- // Quando terminar, o result já é a string completa.
161
- let buffer = leitor.result as string;
162
- r(buffer);
163
- }
164
- if (eventos)
165
- eventos(event, Math.trunc((event.loaded / event.total) * 100));
166
- }
167
- if (arquivo) {
168
- if (arquivo.name != "") {
169
- leitor.addEventListener("loadstart", gatilhos);
170
- leitor.addEventListener("progress", gatilhos);
171
- leitor.addEventListener("error", gatilhos);
172
- leitor.addEventListener("abort", gatilhos);
173
- leitor.addEventListener("load", gatilhos);
174
- leitor.addEventListener("loadend", gatilhos);
175
- leitor.readAsDataURL(arquivo);
176
- }
177
- else {
178
- LOG(1, "⚠️ fileReader() - Nome do arquivo necessário: ", arquivo.name);
179
- r(null);
180
- }
181
- } else {
182
- LOG(1, "⚠️ fileReader() - Arquivo Nulo: ", arquivo);
183
- r(null);
184
- }
185
- });
186
- };
187
-
188
- static removeHtmlTags(texto: string): string {
189
- return texto.replace(/<\/?[^>]+(>|$)/g, "");
190
- }
191
-
192
- // Salva a posição do cursor
193
- static saveCursorPosition(element: any, plus: number = 0): { start: number; end: number, plus: number } | null {
194
- const selection = window.getSelection();
195
- if (!selection || selection.rangeCount === 0) return null;
196
- const range = selection.getRangeAt(0);
197
- const preCaretRange = range.cloneRange();
198
- if (!element) return null;
199
- preCaretRange.selectNodeContents(element);
200
- preCaretRange.setEnd(range.startContainer, range.startOffset);
201
- const start = preCaretRange.toString().length;
202
- return {
203
- start: start,
204
- end: start + range.toString().length,
205
- plus
206
- };
207
- }
208
-
209
- // Restaura a posição do cursor
210
- static restoreCursorPosition(element: any, position: { start: number; end: number, plus: number }) {
211
- if (!element) return;
212
- const selection = window.getSelection();
213
- if (!selection) return;
214
- let charIndex = 0;
215
- const range = document.createRange();
216
- range.setStart(element, 0);
217
- range.collapse(true);
218
- const nodeIterator = (node: Node): boolean => {
219
- if (node.nodeType === Node.TEXT_NODE) {
220
- const textNode = node as Text;
221
- const nextCharIndex = charIndex + (textNode.length || 0);
222
- if (position.start >= charIndex && position.start <= nextCharIndex) {
223
- range.setStart(textNode, position.start - charIndex);
224
- range.setEnd(textNode, position.start - charIndex);
225
- return true;
226
- }
227
- charIndex = nextCharIndex;
228
- } else {
229
- for (let i = 0; i < node.childNodes.length; i++) {
230
- if (nodeIterator(node.childNodes[i])) {
231
- return true;
232
- }
233
- }
234
- }
235
- return false;
236
- };
237
- nodeIterator(element);
238
- selection.removeAllRanges();
239
- selection.addRange(range);
240
- }
241
-
242
- static formatJson(texto: string, colorir: boolean = false): string {
243
- let retorno = "";
244
- try {
245
- retorno = JSON.stringify(texto, null, 2);
246
- } catch (e) {
247
- LOG(1, "⚠️ JSON Inválido: Não foi possível formatar o JSON.");
248
- return texto;
249
- }
250
-
251
- if (colorir) {
252
- let keyNameStart: string = '<span class="json-key">';
253
- let nullStart: string = '<span class="json-null">';
254
- let numberStart: string = '<span class="json-number">';
255
- let booleanStart: string = '<span class="json-boolean">';
256
- let stringStart: string = '<span class="json-string">';
257
- let spanEnd: string = '</span>';
258
- // Identificar a posição das chaves do json e adicionar as tags de span
259
- retorno = retorno.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
260
- retorno = retorno.replace(/("(\\u[a-zA-Z0-9]{4}|\\[^u]|[^\\"])*"(\s*:)?|\b(true|false|null)\b|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?)/g, function (match) {
261
- let cls = nullStart;
262
- if (/^"/.test(match)) {
263
- if (/:$/.test(match)) {
264
- cls = keyNameStart;
265
- } else {
266
- cls = stringStart;
267
- }
268
- } else if (/true|false/.test(match)) {
269
- cls = booleanStart;
270
- } else if (/null/.test(match)) {
271
- cls = nullStart;
272
- } else if (/undefined/.test(match)) {
273
- cls = nullStart;
274
- } else {
275
- cls = numberStart;
276
- }
277
- return cls + match + spanEnd;
278
- });
279
- }
280
-
281
- // Remove aspas duplas das chaves (mantém aspas dos valores string)
282
- retorno = retorno.replace(/"([^"]+)"(\s*):/g, '$1$2:');
283
-
284
- return retorno;
285
- }
286
-
287
- static async copy(content: string): Promise<void> {
288
- try {
289
- await this.copyHtml(content);
290
- } catch (erro) {
291
- LOG(1, "❌ %cFalha ao copiar como HTML, tentando como texto puro", "color:red;", erro);
292
- this.copyPlainText(content);
293
- }
294
- }
295
-
296
- private static copyPlainText(text: string) {
297
- const elemento = document.createElement('textarea');
298
- elemento.style.position = 'fixed';
299
- elemento.style.opacity = '0';
300
- elemento.style.whiteSpace = 'pre';
301
- elemento.value = text;
302
- document.body.appendChild(elemento);
303
- elemento.select();
304
- elemento.setSelectionRange(0, 99999);
305
- const result = document.execCommand('copy');
306
- if (!result) {
307
- LOG(1, "❌ Falha ao copiar via execCommand.");
308
- }
309
- LOG(1, "🫤! Cópia via execCommand: ", text);
310
- elemento.remove();
311
- }
312
-
313
- private static async copyHtml(html?: string) {
314
- if (!html) {
315
- html = "";
316
- LOG(1, "❌ %cNão foi possível copiar.", "color:red;");
317
- return;
318
- }
319
- try {
320
- // Remove tags HTML para gerar a versão texto puro
321
- const plainText = this.stripHtmlTags(html);
322
- if (navigator.clipboard && window.isSecureContext) {
323
- const clipboardItem = new ClipboardItem({
324
- 'text/plain': new Blob([plainText], { type: 'text/plain' }),
325
- 'text/html': new Blob([html], { type: 'text/html' })
326
- });
327
- await navigator.clipboard.write([clipboardItem]);
328
- console.groupCollapsed("✅ %cCopiado para a área de transferência.", "color:aquamarine;");
329
- LOG(1, plainText);
330
- console.groupEnd();
331
- return;
332
- }
333
-
334
- // Fallback: copia HTML usando execCommand
335
- const elemento = document.createElement('div');
336
- elemento.style.position = 'fixed';
337
- elemento.style.opacity = '0';
338
- elemento.innerHTML = html;
339
- document.body.appendChild(elemento);
340
-
341
- const range = document.createRange();
342
- range.selectNodeContents(elemento);
343
- const selection = window.getSelection();
344
- selection?.removeAllRanges();
345
- selection?.addRange(range);
346
-
347
- document.execCommand('copy');
348
- console.groupCollapsed("➡️ %cCopiado para a área de transferência. (execCommand)", "color:lightblue;");
349
- LOG(1, plainText);
350
- console.groupEnd();
351
- elemento.remove();
352
- } catch (erro) {
353
- LOG(1, "❌ Erro ao copiar:", erro);
354
- throw erro;
355
- }
356
- }
357
-
358
- private static stripHtmlTags(html: string): string {
359
- // Cria um elemento temporário para extrair texto puro
360
- const temp = document.createElement('div');
361
- temp.innerHTML = html;
362
- // Substitui <br> por quebras de linha antes de extrair o texto
363
- temp.innerHTML = temp.innerHTML.replace(/<br\s*\/?>/gi, '\n');
364
- return temp.textContent || temp.innerText || '';
365
- }
366
-
367
- static apenasNumeros = (s: string | number = ""): string => {
368
- if (s == null) return "";
369
- // Ignora qualquer outro caracter além de Numeros
370
- return s.toString().replace(/(?![0-9])./g, "");
371
- }
372
-
373
- static frequencia = (array: any): any => {
374
- // Retorna o total de encontro na array.
375
- // Quando é objeto converte pra string pra poder contar
376
- let f: any = {};
377
- for (let e of array) {
378
- let s = e;
379
- if (LibUtil.classof(e) == "object") s = JSON.stringify(e);
380
- f[s] ? f[s]++ : (f[s] = 1);
381
- }
382
- return f;
383
- }
384
-
385
- static formats: IUtilFormatters = {
386
- cpf: {
387
- mask: "000.000.000-00",
388
- regex: "^([0-9]{3}([\.]?[0-9]{3}){2}[-]?[0-9]{2})$",
389
- validate: (cpf: any) => {
390
- let m1 = [10, 9, 8, 7, 6, 5, 4, 3, 2];
391
- let m2 = [11, 10, 9, 8, 7, 6, 5, 4, 3, 2];
392
- if (!cpf) { return false; }
393
- cpf = LibUtil.apenasNumeros(cpf);
394
- if (cpf.length != 11) { return false; }
395
- let temp = cpf.slice(0, 9);
396
- let c = 0;
397
- for (let i = 0; i < 9; i++) { c += Number(temp.charAt(i)) * m1[i]; }
398
- let r = c % 11;
399
- (r < 2) ? r = 0 : r = 11 - r;
400
- temp += r.toString();
401
- c = 0;
402
- for (let i = 0; i < 10; i++) { c += Number(temp.charAt(i)) * m2[i]; }
403
- r = c % 11;
404
- (r < 2) ? r = 0 : r = 11 - r;
405
- if (cpf.charAt(10) != r.toString()) {
406
- return false;
407
- };
408
- let char0 = cpf.charAt(0);
409
- let repChar0 = LibUtil.frequencia(cpf)[char0];
410
- if (repChar0 >= 11) {
411
- return false;
412
- }
413
- return true;
414
- }
415
- },
416
- cnpj: {
417
- mask: "00.000.000/0000-00",
418
- regex: "^([0-9]{2}([\.]?[0-9]{3}){2}[\/]?[0-9]{4}[-]?[0-9]{2})$",
419
- validate: (cnpj: any) => {
420
- let m1 = [5, 4, 3, 2, 9, 8, 7, 6, 5, 4, 3, 2];
421
- let m2 = [6, 5, 4, 3, 2, 9, 8, 7, 6, 5, 4, 3, 2];
422
- if (!cnpj) { return false; }
423
- cnpj = LibUtil.apenasNumeros(cnpj);
424
- if (cnpj.length != 14) { return false; }
425
- let temp = cnpj.slice(0, 12);
426
- let c = 0;
427
- for (let i = 0; i < 12; i++) { c += Number(temp.charAt(i)) * m1[i]; }
428
- let r = (c % 11);
429
- (r < 2) ? r = 0 : r = 11 - r;
430
- temp += r.toString();
431
- c = 0;
432
- for (let i = 0; i < 13; i++) { c += Number(temp.charAt(i)) * m2[i]; }
433
- r = (c % 11);
434
- (r < 2) ? r = 0 : r = 11 - r;
435
- return cnpj.charAt(13) == r.toString();
436
- }
437
- },
438
- cpf_cnpj: {
439
- mask: (str: string) => {
440
- if (LibUtil.apenasNumeros(str).length <= 11) {
441
- return "000.000.000-00"
442
- } else {
443
- return "00.000.000/0000-00"
444
- };
445
- },
446
- regex: "^([0-9]{2}([\.]?[0-9]{3}){2}[\/]?[0-9]{4}[-]?[0-9]{2})|([0-9]{3}([\.]?[0-9]{3}){2}[-]?[0-9]{2})$",
447
- validate: (cpf_cnpj: any) => {
448
- if (LibUtil.apenasNumeros(cpf_cnpj).length <= 11) {
449
- return LibUtil.formats.cpf.validate?.(cpf_cnpj) ?? false;
450
- } else {
451
- return LibUtil.formats.cnpj.validate?.(cpf_cnpj) ?? false;
452
- };
453
- }
454
- },
455
- cnh: {
456
- mask: "00000000000",
457
- regex: "^([0-9]{11})$",
458
- validate: (cnh: any) => {
459
- if (!cnh) { return false; }
460
- cnh = LibUtil.apenasNumeros(cnh);
461
- if (cnh.length != 11) { return false; }
462
- return true;
463
- },
464
- },
465
- pis: {
466
- mask: "000.00000.00-0",
467
- regex: "^([0-9]{3}[\.]?[0-9]{5}[\.]?[0-9]{2}[-]?[0-9]{1})$",
468
- validate: (pis: any) => {
469
- if (!pis) { return false; }
470
- pis = LibUtil.apenasNumeros(pis);
471
- if (pis.length != 11) { return false; }
472
- return true;
473
- },
474
- },
475
- dia: {
476
- mask: "00",
477
- regex: "^(0[1-9]|[1-9]|[1-2][0-9]|3[0-1])$",
478
- validate: (dia: any) => {
479
- if (!dia) { return false; }
480
- dia = LibUtil.apenasNumeros(dia);
481
- let diaNum = Number(dia);
482
- return diaNum >= 1 && diaNum <= 31;
483
- },
484
- },
485
- mes: {
486
- mask: "00",
487
- regex: "^(0[1-9]|1[0-2])$",
488
- validate: (mes: any) => {
489
- if (!mes) { return false; }
490
- mes = LibUtil.apenasNumeros(mes);
491
- let mesNum = Number(mes);
492
- return mesNum >= 1 && mesNum <= 12;
493
- },
494
- },
495
- ano: {
496
- mask: "0000",
497
- regex: "^([0-2]?([0-9]){3})$",
498
- validate: (ano: any) => {
499
- if (!ano) { return false; }
500
- ano = LibUtil.apenasNumeros(ano);
501
- let anoNum = Number(ano);
502
- return anoNum >= 1000 && anoNum <= 2999;
503
- },
504
- },
505
- anoRecente: {
506
- mask: "0000",
507
- regex: "^(19([0-9]){2})|(20([0-9]){2})|(21([0-9]){2})$",
508
- validate: (anoRecente: any) => {
509
- if (!anoRecente) { return false; }
510
- anoRecente = LibUtil.apenasNumeros(anoRecente);
511
- let anoNum = Number(anoRecente);
512
- return anoNum >= 1900 && anoNum <= 2199;
513
- },
514
- },
515
- data: {
516
- mask: "0000-00-00",
517
- regex: "^([0-9]{4}(-[0-9]{2}){2})$",
518
- validate: (data: any) => {
519
- if (!data) { return false; }
520
- data = LibUtil.apenasNumeros(data);
521
- return new RegExp(LibUtil.formats.data.regex).test(data);
522
- },
523
- },
524
- dataIso: {
525
- mask: "0000-00-00T00:00:00.000Z",
526
- regex: "^([0-9]{4}(-[0-9]{2}){2}T[0-9]{2}(:[0-9]{2}){2}\.[0-9]{3}Z)$",
527
- validate: (dataIso: any) => {
528
- if (!dataIso) { return false; }
529
- dataIso = LibUtil.apenasNumeros(dataIso);
530
- return new RegExp(LibUtil.formats.dataIso.regex).test(dataIso);
531
- },
532
- },
533
- numero: {
534
- mask: "#0",
535
- regex: "^[0-9]*$",
536
- validate: (numero: any) => {
537
- if (!numero) { return false; }
538
- numero = LibUtil.apenasNumeros(numero);
539
- return numero.length > 0;
540
- },
541
- },
542
- decimal: {
543
- mask: "#0,00",
544
- regex: "^[0-9,]*$",
545
- validate: (decimal: any) => {
546
- if (!decimal) { return false; }
547
- return new RegExp(LibUtil.formats.decimal.regex).test(decimal);
548
- },
549
- },
550
- letra: {
551
- mask: "A",
552
- regex: "^[A-Za-z]*$",
553
- validate: (letra: any) => {
554
- if (!letra) { return false; }
555
- return new RegExp(LibUtil.formats.letra.regex).test(letra);
556
- },
557
- },
558
- numeroELetra: {
559
- mask: "S",
560
- regex: "^[A-Za-z0-9]*$",
561
- validate: (numeroELetra: any) => {
562
- if (!numeroELetra) { return false; }
563
- return new RegExp(LibUtil.formats.numeroELetra.regex).test(numeroELetra);
564
- }
565
- },
566
- ip: {
567
- mask: "000.000.000.000",
568
- regex: "^([0-2]?[0-9]?[0-9]([\.][0-2]?[0-9]?[0-9]){3})$",
569
- validate: (ip: any) => {
570
- if (!ip) { return false; }
571
- const regex = new RegExp(LibUtil.formats.ip.regex);
572
- if (!regex.test(ip)) { return false; }
573
- const parts = ip.split('.').map(Number);
574
- return parts.every((part: number) => part >= 0 && part <= 255);
575
- }
576
- },
577
- email: {
578
- mask: "S",
579
- regex: "^(([a-zA-Z0-9_+-\.]+)+)@([a-zA-Z0-9_+-\.]+\.[a-zA-Z]+)+$",
580
- validate: (email: any) => {
581
- if (!email) { return false; }
582
- return new RegExp(LibUtil.formats.email.regex).test(email);
583
- }
584
- },
585
- cep: {
586
- mask: "00000-000",
587
- regex: "^([0-9]{5}[-]?[0-9]{3})$",
588
- validate: (cep: any) => {
589
- if (!cep) { return false; }
590
- cep = LibUtil.apenasNumeros(cep);
591
- return new RegExp(LibUtil.formats.cep.regex).test(cep);
592
- }
593
- }
594
- }
595
-
596
- static stringToDataBR = (data: string | null | undefined): string | null => {
597
- let resultado = null;
598
- if (LibUtil.classof(data) == "null" || LibUtil.classof(data) == "undefined") {
599
- return null;
600
- } else if (LibUtil.classof(data) == "string") {
601
- // Quando a data é "YYYY-MM-DD", ascrescenta 1 espaço para UTC.
602
- if (new RegExp("^[12][0-9]{3}[-][0-1][0-9][-][0-3][0-9]$").test(data!)) {
603
- data += " ";
604
- }
605
- // Tentativa Direta:
606
- resultado = new Date(data!).toLocaleString().replace(",", "");
607
-
608
- // Falhando, tenta converter pra número.
609
- if (resultado.toUpperCase() == "INVALID DATE") {
610
- resultado = new Date(Number(data)).toLocaleString().replace(",", "");
611
-
612
- // Agora tenta ver se a data inicia no formato br já
613
- if (resultado.toUpperCase() == "INVALID DATE") {
614
- // DD/MM/YYYY ?
615
- if (new RegExp("^[0-3][0-9][/][0-1][0-9][/][0-2][0-9]{3}").test(data!)) {
616
- resultado = new Date(LibUtil.dataToIsoData(data!)).toLocaleString().replace(",", "");
617
- }
618
- }
619
- }
620
- } else {
621
- LOG(1, "❌ stringToDataBR(): A data precisa ser formato string: ", data, LibUtil.classof(data));
622
- }
623
- return resultado;
624
- }
625
-
626
- // ISO 8601 (Padrão Internacional)
627
- static dataToIsoData = (data: string): string => {
628
- // Converter de DD/MM/YYYY para YYYY-MM-DD
629
- if (new RegExp("^[0-3][0-9][/][0-1][0-9][/][0-2][0-9]{3}").test(data)) {
630
-
631
- }
632
- if (new RegExp("^[0-3][0-9][/][0-1][0-9][/][0-2][0-9]{3}").test(data)) {
633
- let novaData = data.slice(6, 10) + "-" + data.slice(3, 5) + "-" + data.slice(0, 2);
634
- let resto = data.slice(10, data.length);
635
- if (resto != "" && new RegExp("^ [0-2][0-9]:[0-5][0-9]:[0-5][0-9]").test(resto)) {
636
- novaData += resto;
637
- }
638
- return novaData;
639
- }
640
- return data; // < Se falhar
641
- };
642
-
643
-
644
-
645
-
646
-
647
-
648
-
649
-
650
-
651
-
652
-
653
-
654
-
655
-
656
-
657
-
658
-
659
-
660
-
661
-
662
- // ============================ SIGNALS DIRETO => CRUD E UTEIS ============================ \\
663
-
664
- // SET (SIGNAL)
665
- static sinalSet<T>(sinal: WritableSignal<any | undefined>, item: Partial<T>) {
666
- sinal.update(i => {
667
- if (!i) return item;
668
- return { ...i, ...item };
669
- });
670
- }
671
-
672
- // CREATE (SIGNAL)
673
- static sinalCreate<T>(sinal: WritableSignal<any[] | undefined>, item: T) {
674
- sinal.update(i => {
675
- if (!i) return [item];
676
- return [...i, item];
677
- });
678
- }
679
-
680
- // UPDATE (SIGNAL)
681
- static sinalUpdate<T>(sinal: WritableSignal<any[] | undefined>, item: Partial<T>, k: string, v?: string) {
682
- if (v != null && item) {
683
- sinal.update(i => {
684
- if (!i) return i;
685
- return i.map((o: T) => o[k as keyof T] === v ? { ...o, ...item } : o);
686
- });
687
- } else {
688
- if (v == null) {
689
- // PATCH UPDATE
690
- let value = item[k as keyof T];
691
- if (value != null) {
692
- sinal.update(i => {
693
- if (!i) return i;
694
- return i.map((o: T) => o[k as keyof T] === value ? { ...o, ...item } : o);
695
- });
696
- } else {
697
- LOG(1, `⚠️ sinalUpdate: A chave ${k} está nula. Passe o V desta chave para atualizar.`);
698
- }
699
- } else {
700
- LOG(1, `❌ Item ${k} chegou nulo para Update.`);
701
- }
702
- }
703
- }
704
-
705
- // DELETE (SIGNAL)
706
- static sinalDelete<T>(sinal: WritableSignal<any[] | undefined>, k: string, v?: string) {
707
- if (v != null) {
708
- sinal.update(i => {
709
- if (!i) return i;
710
- return i.filter((o: T) => o[k as keyof T] !== v);
711
- });
712
- } else {
713
- LOG(1, `⚠️ Chave ${k} chegou nula para Delete.`);
714
- }
715
- }
716
-
717
- // CLEAR (SIGNAL)
718
- static sinalClear<T>(sinal: WritableSignal<any[] | undefined>) {
719
- sinal.set(undefined);
720
- }
721
-
722
- // EXISTS (SIGNAL) - Verifica se um item existe na lista
723
- static sinalExists<T>(sinal: WritableSignal<any[] | undefined>, k: Extract<keyof T, string>, v: string): boolean {
724
- if (v != null) {
725
- const items = sinal();
726
- if (!items) return false;
727
- return items.some((o: T) => o[k] === v);
728
- } else {
729
- return false;
730
- }
731
- }
732
-
733
-
734
- // MOVE UP (SIGNAL) - Move um item uma posição para cima
735
- static sinalMoveUp<T>(sinal: WritableSignal<any[] | undefined>, k: Extract<keyof T, string>, v: string) {
736
- if (v != null) {
737
- sinal.update(i => {
738
- if (!i || i.length <= 1) return i;
739
- const index = i.findIndex((o: T) => o[k] === v);
740
- if (index <= 0) return i; // Já está no topo ou não encontrado
741
-
742
- const newArray = [...i];
743
- [newArray[index - 1], newArray[index]] = [newArray[index], newArray[index - 1]];
744
- return newArray;
745
- });
746
- } else {
747
- LOG(1, `⚠️ Chave ${k} chegou nula para MoveUp.`);
748
- }
749
- }
750
-
751
- // MOVE DOWN (SIGNAL) - Move um item uma posição para baixo
752
- static sinalMoveDown<T>(sinal: WritableSignal<any[] | undefined>, k: Extract<keyof T, string>, v: string) {
753
- if (v != null) {
754
- sinal.update(i => {
755
- if (!i || i.length <= 1) return i;
756
-
757
- const index = i.findIndex((o: T) => o[k] === v);
758
- if (index < 0 || index >= i.length - 1) return i; // Já está no final ou não encontrado
759
-
760
- const newArray = [...i];
761
- [newArray[index], newArray[index + 1]] = [newArray[index + 1], newArray[index]];
762
- return newArray;
763
- });
764
- } else {
765
- LOG(1, `⚠️ Chave ${k} chegou nula para MoveDown.`);
766
- }
767
- }
768
-
769
- // MOVE TO INDEX (SIGNAL) - Move um item para uma posição específica
770
- static sinalMoveToIndex<T>(sinal: WritableSignal<any[] | undefined>, k: Extract<keyof T, string>, v: string, targetIndex: number) {
771
- if (v != null) {
772
- sinal.update(i => {
773
- if (!i || i.length <= 1) return i;
774
- const currentIndex = i.findIndex((o: T) => o[k] === v);
775
- if (currentIndex < 0 || targetIndex < 0 || targetIndex >= i.length || currentIndex === targetIndex) {
776
- return i; // Item não encontrado, índice inválido ou já está na posição
777
- }
778
- const newArray = [...i];
779
- const [movedItem] = newArray.splice(currentIndex, 1);
780
- newArray.splice(targetIndex, 0, movedItem);
781
- return newArray;
782
- });
783
- } else {
784
- LOG(1, `⚠️ Chave ${k} chegou nula para MoveToIndex.`);
785
- }
786
- }
787
-
788
- static FlatRecursivo<T>(lista: T[], keyRecursive: keyof T): T[] {
789
- if (LibUtil.classof(lista) != "array") return [];
790
-
791
- let novaArray: T[] = [];
792
- lista.map(objeto => {
793
- if (LibUtil.classof(objeto) != "object") return;
794
- let novoObjeto: T = {} as T;
795
- for (let prop in objeto) {
796
- if (prop != keyRecursive) novoObjeto[prop] = objeto[prop];
797
- }
798
- novaArray = [...novaArray, novoObjeto];
799
- let children = objeto[keyRecursive] as T[];
800
- if (children != null) {
801
- novaArray = [...novaArray, ...LibUtil.FlatRecursivo(children, keyRecursive)];
802
- }
803
- })
804
- return novaArray;
805
- }
806
-
807
- // ============================ SIGNALS RECURSIVO => CRUD E UTEIS ============================ \\
808
-
809
- // Adiciona um novo item em uma estrutura hierárquica baseado na chave pai
810
- // CREATE RECURSIVE (SIGNAL)
811
- static sinalCreateRecursive<T>(sinal: WritableSignal<any[] | undefined>, item: T, keyRecursive: keyof T, keyPai: Extract<keyof T, string>, valuePai?: string) {
812
- sinal.update(i => {
813
- if (!i) return [item];
814
- if (valuePai != null) {
815
- return i.map((o: T) => {
816
- return LibUtil._recursiveCreate<T>(o, item, keyRecursive, keyPai, valuePai);
817
- });
818
- } else {
819
- // Sem Pai inserir direto na raiz
820
- return [...i, item];
821
- }
822
- });
823
- }
824
-
825
- // Encontra o item pai pela chave e adiciona o novo item no array de filhos
826
- static _recursiveCreate<T>(atual: T, novo: T, keyRecursive: keyof T, keyPai: Extract<keyof T, string>, valuePai: string): T {
827
- if (atual[keyPai] === valuePai) {
828
- // Encontrou o pai, adiciona o item no array recursivo
829
- if (atual[keyRecursive] == null) {
830
- (atual[keyRecursive] as T[]) = [novo];
831
- } else {
832
- (atual[keyRecursive] as T[]) = [...(atual[keyRecursive] as T[]), novo];
833
- }
834
- return atual;
835
- }
836
- if (atual[keyRecursive] == null || (atual[keyRecursive] as T[])?.length == 0) return atual;
837
- (atual[keyRecursive] as T[]) = [
838
- ...(atual[keyRecursive] as T[]).map(child => {
839
- return LibUtil._recursiveCreate(child, novo, keyRecursive, keyPai, valuePai);
840
- })
841
- ];
842
- return atual;
843
- }
844
-
845
- // Atualiza um item específico em uma estrutura hierárquica
846
- // UPDATE RECURSIVE (SIGNAL)
847
- static sinalUpdateRecursive<T>(sinal: WritableSignal<any[] | undefined>, item: Partial<T>, keyRecursive: keyof T, k: Extract<keyof T, string>, v: string) {
848
- if (v != null) {
849
- sinal.update(i => {
850
- if (!i) return i;
851
- return i.map((o: T) => {
852
- return LibUtil._recursiveUpdate<T>(o, item, keyRecursive, k, v);
853
- });
854
- });
855
- } else {
856
- LOG(1, `⚠️ Chave ${k} chegou nula para Update Recursivo.`);
857
- }
858
- }
859
-
860
- // Encontra o item pela chave e atualiza suas propriedades
861
- static _recursiveUpdate<T>(atual: T, novo: Partial<T>, keyRecursive: keyof T, k: Extract<keyof T, string>, v: string): T {
862
- if (atual[k] === v) {
863
- LOG(1, "Editado", { ...atual, ...novo })
864
- return { ...atual, ...novo };
865
- }
866
- if (atual[keyRecursive] == null || (atual[keyRecursive] as T[])?.length == 0) return atual;
867
- (atual[keyRecursive] as T[]) = [
868
- ...(atual[keyRecursive] as T[]).map(child => {
869
- return LibUtil._recursiveUpdate(child, novo, keyRecursive, k, v);
870
- })
871
- ];
872
- return atual;
873
- }
874
-
875
- // Remove um item específico de uma estrutura hierárquica
876
- // DELETE RECURSIVE (SIGNAL)
877
- static sinalDeleteRecursive<T>(sinal: WritableSignal<any[] | undefined>, keyRecursive: keyof T, k: Extract<keyof T, string>, v: string) {
878
- if (v != null) {
879
- sinal.update(i => {
880
- if (!i) return i;
881
- // Primeiro verifica se precisa deletar no nível raiz
882
- const filteredRoot = i.filter((o: T) => o[k] !== v);
883
- // Se encontrou e removeu no nível raiz, retorna o array filtrado
884
- if (filteredRoot.length !== i.length) {
885
- return filteredRoot;
886
- }
887
- // Se não encontrou no nível raiz, processa recursivamente
888
- return i.map((o: T) => {
889
- return LibUtil._recursiveDelete<T>(o, keyRecursive, k, v);
890
- });
891
- });
892
- } else {
893
- LOG(1, `⚠️ Chave ${k} chegou nula para Delete Recursivo.`);
894
- }
895
- }
896
- // Encontra e remove o item pela chave, filtrando do array de filhos
897
- static _recursiveDelete<T>(atual: T, keyRecursive: keyof T, k: Extract<keyof T, string>, v: string): T {
898
- // Se tem filhos, processa os filhos
899
- if (atual[keyRecursive] && (atual[keyRecursive] as T[])?.length > 0) {
900
- const children = atual[keyRecursive] as T[];
901
- // Remove o item dos filhos se existir e processa recursivamente os filhos restantes
902
- const filteredChildren = children
903
- .filter(child => child[k] !== v)
904
- .map(child => LibUtil._recursiveDelete(child, keyRecursive, k, v));
905
- return { ...atual, [keyRecursive]: filteredChildren };
906
- }
907
- return atual;
908
- }
909
-
910
- // EXISTS RECURSIVE (SIGNAL) - Verifica se um item existe em uma estrutura hierárquica
911
- static sinalExistsRecursive<T>(sinal: WritableSignal<any[] | undefined>, keyRecursive: keyof T, k: Extract<keyof T, string>, v: string): boolean {
912
- if (v != null) {
913
- const items = sinal();
914
- if (!items) return false;
915
- return items.some((o: T) => {
916
- return LibUtil._recursiveExists<T>(o, keyRecursive, k, v);
917
- });
918
- } else {
919
- return false;
920
- }
921
- }
922
-
923
- // Função auxiliar para busca recursiva
924
- static _recursiveExists<T>(atual: T, keyRecursive: keyof T, k: Extract<keyof T, string>, v: string): boolean {
925
- // Verifica se o item atual é o que estamos procurando
926
- if (atual[k] === v) return true;
927
- // Se tem filhos, procura recursivamente
928
- if (atual[keyRecursive] && (atual[keyRecursive] as T[])?.length > 0) {
929
- const children = atual[keyRecursive] as T[];
930
- return children.some(child => LibUtil._recursiveExists(child, keyRecursive, k, v));
931
- }
932
- return false;
933
- }
934
-
935
- // Move um item uma posição para cima na hierarquia
936
- // MOVE UP RECURSIVE (SIGNAL) - Para estruturas hierárquicas
937
- static sinalMoveUpRecursive<T>(sinal: WritableSignal<any[] | undefined>, keyRecursive: keyof T, k: Extract<keyof T, string>, v: string) {
938
- if (v != null) {
939
- sinal.update(i => {
940
- if (!i || i.length <= 1) return i;
941
- // Primeiro verifica se precisa mover no nível raiz
942
- const rootIndex = i.findIndex((o: T) => o[k] === v);
943
- if (rootIndex > 0) {
944
- const newArray = [...i];
945
- [newArray[rootIndex - 1], newArray[rootIndex]] = [newArray[rootIndex], newArray[rootIndex - 1]];
946
- return newArray;
947
- }
948
- // Se não encontrou no nível raiz, processa recursivamente
949
- return i.map((o: T) => {
950
- return LibUtil._recursiveMoveUp<T>(o, keyRecursive, k, v);
951
- });
952
- });
953
- } else {
954
- LOG(1, `⚠️ Chave ${k} chegou nula para MoveUp Recursivo.`);
955
- }
956
- }
957
-
958
- // Encontra o item e troca sua posição com o anterior no array
959
- static _recursiveMoveUp<T>(atual: T, keyRecursive: keyof T, k: Extract<keyof T, string>, v: string): T {
960
- // Se tem filhos, processa os filhos primeiro
961
- if (atual[keyRecursive] && (atual[keyRecursive] as T[])?.length > 0) {
962
- const children = atual[keyRecursive] as T[];
963
- // Verifica se precisa mover dentro dos filhos
964
- const targetIndex = children.findIndex(child => child[k] === v);
965
- if (targetIndex > 0) {
966
- const newChildren = [...children];
967
- [newChildren[targetIndex - 1], newChildren[targetIndex]] = [newChildren[targetIndex], newChildren[targetIndex - 1]];
968
- return { ...atual, [keyRecursive]: newChildren };
969
- }
970
- // Se não encontrou, processa recursivamente os filhos
971
- const processedChildren = children.map(child =>
972
- LibUtil._recursiveMoveUp(child, keyRecursive, k, v)
973
- );
974
- return { ...atual, [keyRecursive]: processedChildren };
975
- }
976
- return atual;
977
- }
978
-
979
- // Move um item uma posição para baixo na hierarquia
980
- // MOVE DOWN RECURSIVE (SIGNAL) - Para estruturas hierárquicas
981
- static sinalMoveDownRecursive<T>(sinal: WritableSignal<any[] | undefined>, keyRecursive: keyof T, k: Extract<keyof T, string>, v: string) {
982
- if (v != null) {
983
- sinal.update(i => {
984
- if (!i || i.length <= 1) return i;
985
- // Primeiro verifica se precisa mover no nível raiz
986
- const rootIndex = i.findIndex((o: T) => o[k] === v);
987
- if (rootIndex >= 0 && rootIndex < i.length - 1) {
988
- const newArray = [...i];
989
- [newArray[rootIndex], newArray[rootIndex + 1]] = [newArray[rootIndex + 1], newArray[rootIndex]];
990
- return newArray;
991
- }
992
- // Se não encontrou no nível raiz, processa recursivamente
993
- return i.map((o: T) => {
994
- return LibUtil._recursiveMoveDown<T>(o, keyRecursive, k, v);
995
- });
996
- });
997
- } else {
998
- LOG(1, `⚠️ Chave ${k} chegou nula para MoveDown Recursivo.`);
999
- }
1000
- }
1001
-
1002
- // Encontra o item e troca sua posição com o próximo no array
1003
- static _recursiveMoveDown<T>(atual: T, keyRecursive: keyof T, k: Extract<keyof T, string>, v: string): T {
1004
- if (atual[keyRecursive] && (atual[keyRecursive] as T[])?.length > 0) {
1005
- const children = atual[keyRecursive] as T[];
1006
- // Verifica se precisa mover dentro dos filhos
1007
- const targetIndex = children.findIndex(child => child[k] === v);
1008
- if (targetIndex >= 0 && targetIndex < children.length - 1) {
1009
- const newChildren = [...children];
1010
- [newChildren[targetIndex], newChildren[targetIndex + 1]] = [newChildren[targetIndex + 1], newChildren[targetIndex]];
1011
- return { ...atual, [keyRecursive]: newChildren };
1012
- }
1013
- // Se não encontrou, processa recursivamente os filhos
1014
- const processedChildren = children.map(child =>
1015
- LibUtil._recursiveMoveDown(child, keyRecursive, k, v)
1016
- );
1017
- return { ...atual, [keyRecursive]: processedChildren };
1018
- }
1019
- return atual;
1020
- }
1021
-
1022
- static sinalSetOrderRecursive<T>(sinal: WritableSignal<any[] | undefined>, keyRecursive: keyof T, k: Extract<keyof T, string>, propOrder: keyof T) {
1023
- sinal.update(i => {
1024
- if (!i) return i;
1025
- return i.map((o: T, i) => {
1026
- return LibUtil._recursiveSetOrder<T>(o, keyRecursive, k, propOrder, i);
1027
- });
1028
- });
1029
- }
1030
-
1031
- static _recursiveSetOrder<T>(atual: T, keyRecursive: keyof T, k: Extract<keyof T, string>, propOrder: keyof T, index: number): T {
1032
- atual = { ...atual, [propOrder]: index };
1033
- if (atual[keyRecursive] == null || (atual[keyRecursive] as T[])?.length == 0) return atual;
1034
- (atual[keyRecursive] as T[]) = [
1035
- ...(atual[keyRecursive] as T[]).map((child, i) => {
1036
- return LibUtil._recursiveSetOrder(child, keyRecursive, k, propOrder, i);
1037
- })
1038
- ];
1039
- return atual;
1040
- }
1041
-
1042
- // ============================ ATALHOS PERSONALIZADOS ============================ \\
1043
-
1044
- static Q = (query: any) => {
1045
- // Busca elemento único, podendo buscar ele mesmo. (Bifurcacado)
1046
- if (LibUtil.classof(query) == "string") return document.querySelector(query);
1047
- return query;
1048
- };
1049
-
1050
- static QAll = (query: any): any[] => {
1051
- // Sempre retorna uma array de encontrados. Inclusive uma array com um LibUtil.Q
1052
- if (LibUtil.classof(query) == "string") {
1053
- // Se buscando uma string, retorna a array do select encontrado
1054
- return Array.from(document.querySelectorAll(query));
1055
- } else if (LibUtil.classof(query).endsWith("Element")) {
1056
- // Quando buscar um único elemento, retorna o elemento em uma lista.
1057
- return [query];
1058
- } else if (LibUtil.classof(query) == "array") {
1059
- // Quando buscar uma array, retorna a propria array. (Bifurcado)
1060
- return query;
1061
- } else {
1062
- LOG(1, "⚠️ QAll() - Requer String / Elemento / Array. ClassOf: ", LibUtil.classof(query), " Query: ", query);
1063
- return [];
1064
- }
1065
- };
1066
-
1067
- static QverOff = (query: Element | HTMLElement | string | null = "body"): any[] => {
1068
- // Adiciona Classe Oculto em todos os elementos do Query
1069
- // Retorna uma array de elementos por causa do QAll
1070
- return LibUtil.aCadaElemento(query, (e: any) => {
1071
- e?.classList.add("oculto");
1072
- });
1073
- };
1074
-
1075
- static QverOn = (query: Element | HTMLElement | string | null = "body") => {
1076
- // Remove classe Oculto em todos os elementos do Query
1077
- // Retorna uma array de elementos por causa do QAll
1078
- return LibUtil.aCadaElemento(query, (e: any) => {
1079
- e?.classList.remove("oculto");
1080
- });
1081
- };
1082
-
1083
- static dataGetMs = (data: string | null = null): number => {
1084
- // Retorna Milisegundos da data no formato Javascript
1085
- if (data != null) {
1086
- if (data.length > 10) {
1087
- // Recomendado que os dados cheguem: 'YYYY-MM-DD HH:MM:SS'
1088
- return new Date(data).getTime(); // Recomendado que os dados
1089
- } else {
1090
- let dataCortada = data.split("-");
1091
- let oDia: number = Number(dataCortada[2]);
1092
- let oMes: number = Number(dataCortada[1]) - 1;
1093
- let oAno: number = Number(dataCortada[0]);
1094
- return new Date(oAno, oMes, oDia).getTime();
1095
- }
1096
- } else return new Date().getTime();
1097
- };
1098
-
1099
- static dataMsToSegundos = (num: number, reverse: boolean = false) => {
1100
- if (reverse) {
1101
- return num * 1000;
1102
- }
1103
- return Math.trunc(num / 1000); // 1000 ms == 1s
1104
- }
1105
-
1106
- static dataMsToDias = (num: number, reverse: boolean = false) => {
1107
- // 1000 * 3600 * 24 Considerando todo dia tiver 24 horas (~23h 56m 4.1s)
1108
- // (360º translacao / 86400000) = ~4.1
1109
- // Então o erro de 1 dia ocorre 1x ao ano (Dia represeta 1436min).
1110
- // Por isso, é melhor trabalhar com Dias em vez de outro formato maior.
1111
- if (reverse) {
1112
- return Math.trunc(num * 86400000);
1113
- }
1114
- return Math.trunc(num / 86400000);
1115
- };
1116
-
1117
- static dataGetSegundosDiferenca = (msDe: number, msAte: number | null = null): number => {
1118
- // Retorna a diferença de segundos entre dois MS
1119
- if (msAte == null) msAte = LibUtil.dataGetMs();
1120
- return LibUtil.dataMsToSegundos(msAte - msDe);
1121
- };
1122
-
1123
- static dataGetDiasDiferenca = (msDe: number, msAte: number | null = null): number => {
1124
- // Retorna a diferença de dias entre dois MS
1125
- if (msAte == null) msAte = LibUtil.dataGetMs();
1126
- return LibUtil.dataMsToDias(msAte - msDe);
1127
- };
1128
-
1129
- static dataShowTempoDiferenca = (msDe: number | string, msAte: number | string | null = null) => {
1130
- if (LibUtil.classof(msDe) == "string") msDe = LibUtil.dataGetMs(msDe as string);
1131
- if (LibUtil.classof(msAte) == "string") msAte = LibUtil.dataGetMs(msAte as string);
1132
- let dias = LibUtil.dataGetDiasDiferenca(msDe as number, msAte as number | null);
1133
- if (dias < 0) {
1134
- dias = dias * -1;
1135
- }
1136
- let strTempo = "";
1137
- if (dias > 29) { // Em Meses
1138
- if (dias < 60) {
1139
- strTempo = "1 mês";
1140
- } else {
1141
- if (dias > 365) { // Em Anos (+ Meses restantes)
1142
- let anos = Math.floor(dias / 365);
1143
- let diasRestoAno = dias % 365;
1144
- if (anos < 2) {
1145
- strTempo += anos + " ano ";
1146
- } else {
1147
- strTempo += anos + " anos ";
1148
- }
1149
- if (diasRestoAno > 30) {
1150
- if (diasRestoAno < 60) {
1151
- strTempo += "1 mês";
1152
- } else {
1153
- strTempo += Math.floor(diasRestoAno / 30) + " meses";
1154
- }
1155
- }
1156
- } else {
1157
- strTempo = Math.floor(dias / 30) + " meses";
1158
- }
1159
- }
1160
- } else {
1161
- if (dias < 1) {
1162
- let segundos = LibUtil.dataGetSegundosDiferenca(msDe as number, msAte as number);
1163
- if (segundos > 7199) { // Em Horas
1164
- strTempo = Math.floor(segundos / 3600) + " horas";
1165
- } else {
1166
- if (segundos > 3599) {
1167
- strTempo = "1 hora";
1168
- } else {
1169
- if (segundos > 119) { // Em Minutos
1170
- strTempo = Math.floor(segundos / 60) + " minutos";
1171
- } else {
1172
- if (segundos > 59) {
1173
- strTempo = "1 minuto";
1174
- } else {
1175
- strTempo = Math.floor(segundos) + " segundos";
1176
- }
1177
- }
1178
- }
1179
- }
1180
- } else { // Em Dias
1181
- strTempo = dias + " dias";
1182
- }
1183
- }
1184
- if (strTempo.includes("NaN")) return "";
1185
- return strTempo;
1186
- }
1187
-
1188
- static displayCelular = (area: string, numero: string, isoDDI?: string): string => {
1189
- if (numero == null) numero = ""
1190
- else numero = LibUtil.apenasNumeros(numero);
1191
- if (area == null) area = "";
1192
- else area = LibUtil.apenasEstes(area, "0-9\+");
1193
- if (numero == "" && area == "") return "";
1194
- let displayArea = area;
1195
- let displayNumero = numero;
1196
- let displayFlag = "";
1197
- if (numero != "" && displayArea == "") displayArea = "+55"
1198
- if (displayArea == "+55") {
1199
- numero = numero.slice(0, 11); // No brasil o limite é 9.
1200
- displayNumero = numero;
1201
- let apenasCelular = numero.slice(2, 11);
1202
- if (apenasCelular.length == 9) {
1203
- apenasCelular = apenasCelular.slice(0, 5) + "-" + apenasCelular.slice(5, 9);
1204
- }
1205
- displayNumero = "(" + numero.slice(0, 2) + ") " + apenasCelular;
1206
- }
1207
- if (isoDDI != null) {
1208
- displayFlag = LibUtil.displayFlag(isoDDI);
1209
- }
1210
- return `${displayFlag}<a href="tel:${area || ""}${numero || ""}">${displayArea} ${displayNumero}</a>`
1211
- }
1212
-
1213
- static displayFlag = (pais: string): string => {
1214
- if (pais != null) {
1215
- return `<img class="flagSizeIco" src="/images/Paises/${pais || "transparent"}.svg" alt="${pais || "transparent"}" onerror="base_imgonerror(this);"> `
1216
- }
1217
- return "";
1218
- }
1219
-
1220
- static diaEMes(data: string): string {
1221
- //Retorna: 01 de Abril
1222
- let arrData = LibUtil.stringToDataBR(data)?.split(" ")?.[0]?.split("/");
1223
- return arrData?.[0] + " de " + LibUtil.meses.get(Number(arrData?.[1] || 0))?.[0];
1224
- }
1225
-
1226
- // =============== Gerenciamento Monetário / Numérico / Locale =================== \\
1227
- static toNumber = (valor: any, casas: number = 2): number => {
1228
- // Informando String/Number, converte para o número de casas c.casas (padrão 2).
1229
- // LibUtil.toNumber("R$ 1.222,333") => 1222.33
1230
- if (valor != null) {
1231
- if (LibUtil.classof(valor) == "string") {
1232
- // Possiveis separadores
1233
- let us = [".", ","].reduce((x, y) => (valor.lastIndexOf(x) > valor.lastIndexOf(y)) ? x : y);
1234
- let posPonto = valor.lastIndexOf(us)
1235
- if (posPonto >= 0) {
1236
- let i = valor.slice(0, posPonto);
1237
- let d = valor.slice(posPonto + 1).slice(0, 2).padEnd(2, "0");
1238
- i = [...i.toString()].filter(a => { return new RegExp(LibUtil.formats.numero.regex).test(a) }).join("");
1239
- d = [...d.toString()].filter(a => { return new RegExp(LibUtil.formats.numero.regex).test(a) }).join("");
1240
- valor = i + "." + d;
1241
- } else {
1242
- valor = [...valor.toString()].filter(a => { return new RegExp(LibUtil.formats.numero.regex).test(a) }).join("").padStart(3, "0")
1243
- valor = valor.padStart(casas, "0");
1244
- valor = valor.slice(0, -(casas)) + (casas > 0 ? "." : "") + valor.slice(-(casas));
1245
- }
1246
- } else if (LibUtil.classof(valor) == "number") {
1247
- valor = valor.toFixed(casas); // <= Vira String, mas essa função apenas devolve Number
1248
- } else {
1249
- LOG(1, "❌ toNumber() - Formato de entrada não implementado: ", LibUtil.classof(valor));
1250
- }
1251
- return Number(valor); // <= OutPut Number
1252
- }
1253
- return 0; // <= OutPut Number
1254
- };
1255
-
1256
- // ============================= ARMAZENADORES ESTÁTICOS ============================ \\
1257
- static a: any = {
1258
- ALL: "*/*", // ContentType Blob
1259
- FORMDATA: "multipart/form-data", // ContentType FORM
1260
- GET: "GET", // Api Method GET
1261
- HTML: "text/html", // ContentType HTML
1262
- JSON: "application/json", // ContentType JSON
1263
- POST: "POST", // Api Method POST
1264
- DELETE: "DELETE", // Api Method DELETE
1265
- SVGINI: "<svg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='currentColor' viewBox='0 0 16 16'>",
1266
- SVGFIM: "</svg>",
1267
- timers: [] as any, // Array para guardar timers em andamento ou finalizados
1268
- wpool: null as any | null, // WorkerPool quando iniciado
1269
- }
1270
-
1271
- static meses = new Map([
1272
- [1, ["Janeiro", "JAN", "01"]],
1273
- [2, ["Fevereiro", "FEV", "02"]],
1274
- [3, ["Março", "MAR", "03"]],
1275
- [4, ["Abril", "ABR", "04"]],
1276
- [5, ["Maio", "MAI", "05"]],
1277
- [6, ["Junho", "JUN", "06"]],
1278
- [7, ["Julho", "JUL", "07"]],
1279
- [8, ["Agosto", "AGO", "08"]],
1280
- [9, ["Setembro", "SET", "09"]],
1281
- [10, ["Outubro", "OUT", "10"]],
1282
- [11, ["Novembro", "NOV", "11"]],
1283
- [12, ["Dezembro", "DEZ", "12"]],
1284
- ]);
1285
-
1286
- // ============================ TOOLS e JS HELPERS ================================ \\
1287
-
1288
- static isJson = (s: any): boolean => {
1289
- try {
1290
- JSON.parse(s);
1291
- } catch (e) {
1292
- return false;
1293
- }
1294
- return true;
1295
- };
1296
-
1297
- static stringify = (o: any): string => {
1298
- // Converte o Objeto em String JSON, e aproveita e já remove alguns caracteres de controle.
1299
- return JSON.stringify(o)
1300
- ?.replace(new RegExp("\n", 'g'), "")
1301
- ?.replace(new RegExp("\r", 'g'), "")
1302
- ?.replace(new RegExp("\t", 'g'), "")
1303
- ?.replace(new RegExp("\b", 'g'), "")
1304
- ?.replace(new RegExp("\f", 'g'), "")
1305
- };
1306
-
1307
- static parseJSON = (t: any) => {
1308
- // Se for um JSON válido. Retorna o objeto, se não null.
1309
- if (t === "") return "";
1310
- let resultado = null;
1311
- try {
1312
- resultado = JSON.parse(t);
1313
- } catch (e) {
1314
- LOG(1, "❌ JSON Inválido: Não foi possível converter o JSON.");
1315
- return null;
1316
- }
1317
- return resultado;
1318
- };
1319
-
1320
- // String qualquer em string com números
1321
- static convertToNumeric = (texto: string): Array<number> => {
1322
- let arrayDeNumeros = [];
1323
- for (const char of texto) {
1324
- arrayDeNumeros.push(char.codePointAt(0) || 0);
1325
- }
1326
- return arrayDeNumeros;
1327
- }
1328
-
1329
- // COnversor para Texto.
1330
- static convertToTexto = (arrayNumeros: Array<number>): string => {
1331
- return String.fromCodePoint(...arrayNumeros);
1332
- }
1333
-
1334
- // Conversor para Texto, separado por virgula
1335
- static convertToTexto2 = (stringNumeros: string): string => {
1336
- return String.fromCodePoint(...stringNumeros.split(",").map(i => Number(i)));
1337
- }
1338
-
1339
- static aCadaElemento = (query: any, fn: Function): any[] => {
1340
- // A cada elemento encontrado pelo QAll executa a funcao
1341
- let elementos = LibUtil.QAll(query);
1342
- elementos.forEach((e: any) => {
1343
- fn(e);
1344
- });
1345
- // Sempre retorna uma array por caus do QAll
1346
- return elementos;
1347
- };
1348
-
1349
- // Executa a FUNCAO em todas as propriedades deste OA. Inclusive Obj.Obj... (Matriz de Dados)
1350
- static aCadaSubPropriedade = (OA: any, funcao: Function | null = null, exceto: string = "Object") => {
1351
- let c = 0;
1352
- for (let a in OA) {
1353
- if (LibUtil.classof(OA[a]) != exceto) {
1354
- if (funcao) {
1355
- funcao(OA[a], a, OA);
1356
- }
1357
- }
1358
- c++;
1359
- // Se o atual é objeto, itera internamente
1360
- if (LibUtil.classof(OA[a]) == "object") {
1361
- c += LibUtil.aCadaSubPropriedade(OA[a], funcao, exceto);
1362
- }
1363
- // Se o atual é array, itera internamente
1364
- if (LibUtil.classof(OA[a]) == "array") {
1365
- c += LibUtil.aCadaSubPropriedade(OA[a], funcao, exceto);
1366
- }
1367
- }
1368
- return c;
1369
- };
1370
-
1371
- static apenasEstes = (s: string = "", regexPossiveis: string = "0-9\+"): string => {
1372
- if (s == null) return "";
1373
- let regex = new RegExp("(?![" + regexPossiveis + "]).");
1374
- return s.toString().replace(regex, "");
1375
- }
1376
-
1377
- static getV = (keys: string | string[], objeto: any): any => {
1378
- // Retorna o valor do chave informada, podendo ser obj.obj.chave
1379
- // LibUtil.getV("a.b.c",{a:{b:{c:"d"}}})
1380
- if (LibUtil.classof(objeto) == "object") {
1381
- if (LibUtil.classof(keys) == "string") {
1382
- if (keys.includes(".")) {
1383
- // Multi
1384
- let ks: string[] = (keys as string).split(".");
1385
- let lastObj = objeto;
1386
- let lastV = {};
1387
- // Iterar o Keys, Ver Obj atual e Setar Conteudo;
1388
- ks.forEach((k) => {
1389
- if (lastObj) { // Pode ficar nulo durante
1390
- lastV = lastObj[k];
1391
- if (typeof lastV == "object") {
1392
- lastObj = lastV;
1393
- } else {
1394
- lastObj = null;
1395
- }
1396
- }
1397
- });
1398
- return lastV;
1399
- } else {
1400
- // Simples
1401
- return objeto[(keys as string)];
1402
- }
1403
- } else if (LibUtil.classof(keys) == "array") {
1404
- // Array de Keys. Faz um loop e de forma recursiva tenta pegar o valor. Se o valor não for nulo, interrompe e retorna.
1405
- let lastV = null;
1406
- for (let k of (keys as string[])) {
1407
- lastV = LibUtil.getV(k, objeto);
1408
- if (lastV != null) {
1409
- return lastV;
1410
- }
1411
- }
1412
- } else {
1413
- LOG(1, "❌ getV() - Nome da propriedade precisa ser em String. (" + LibUtil.classof(keys) + "):", keys);
1414
- }
1415
- } else {
1416
- LOG(1, "❌ Para ver a chave, o parametro objeto precisa receber um objeto. (" + typeof objeto + ")");
1417
- }
1418
- return null;
1419
- };
1420
-
1421
- static setV = (keys: string, value: any, objeto: any) => {
1422
- // Retorna o valor do chave informada, podendo ser obj.obj.chave
1423
- // LibUtil.setV("a.b.c","mudei",{a:{b:{c:"d"}}})
1424
- if (typeof objeto == "object") {
1425
- if (LibUtil.classof(keys) == "string") {
1426
- if (keys.includes(".")) {
1427
- // Multi
1428
- let ks: string[] = keys.split(".");
1429
- let lastObj = objeto;
1430
- // Iterar o Keys, Ver Obj atual e Setar Conteudo;
1431
- ks.forEach((k) => {
1432
- if (ks.indexOf(k) == (ks.length - 1)) {
1433
- // Último
1434
- lastObj[k] = value;
1435
- } else {
1436
- if (LibUtil.classof(lastObj[k]) != "object") {
1437
- lastObj[k] = {};
1438
- }
1439
- }
1440
- lastObj = lastObj[k];
1441
- });
1442
- return objeto;
1443
- } else {
1444
- // Set direto, não tem ponto e é string
1445
- objeto[keys] = value;
1446
- return objeto;
1447
- }
1448
- } else {
1449
- LOG(1, "❌ setV() - Nome da propriedade precisa ser em string. (" + LibUtil.classof(keys) + "):", keys);
1450
- }
1451
- } else {
1452
- LOG(1, "❌ setV() - Objeto precisa receber um objeto. (" + typeof objeto + ")");
1453
- }
1454
- return null;
1455
- };
1456
-
1457
- static geraObjForm = (form: any) => {
1458
- // Gerar Objeto a partir de um Form Entries
1459
- if (LibUtil.classof(form) != "object") {
1460
- // Se vier o Elemento Form / o Query do Form
1461
- form = LibUtil.Q(form);
1462
- }
1463
- // Coleta apenas os campos com value.
1464
- let rObjeto: any = [...form.querySelectorAll(" *[name]")]
1465
- .map(o => { return { [o.name]: o.value } })
1466
- .reduce((a, o) => { a = { ...a, ...o }; return a; }, {});
1467
- if (form) {
1468
-
1469
- for (let [k, v] of Object.entries(rObjeto)) {
1470
- LibUtil.setV(k, v, rObjeto);
1471
- if (k.includes(".")) {
1472
- delete rObjeto[k];
1473
- }
1474
- }
1475
- Array.from(form.querySelectorAll("mk-sel")).forEach((e: any) => {
1476
- // rObjeto[mk.name] = mk.value;
1477
- LibUtil.setV(e.name, e.value, rObjeto);
1478
- });
1479
- // Aqui apenas coleta os mkBot que foram modificados pelo usuário.
1480
- Array.from(form.querySelectorAll("mk-bot.changed")).forEach((e: any) => {
1481
- // rObjeto[mk.name] = mk.value;
1482
- LibUtil.setV(e.name, e.value, rObjeto);
1483
- });
1484
- }
1485
- return rObjeto;
1486
- }
1487
-
1488
- static funcoesDinamicas = new Map<string, Function>();
1489
- static aCada1s = () => {
1490
- Array.from(LibUtil.funcoesDinamicas.values()).map((fn: Function) => { if (fn != null) fn() });
1491
- setTimeout(() => {
1492
- LibUtil.aCada1s();
1493
- }, 1000);
1494
- };
1495
-
1496
- static cortarString = (linha: string, regex: string, casas: any) => {
1497
- let resultado: any = "";
1498
- try {
1499
- resultado = new RegExp(regex).exec(linha)?.groups?.["ok"];
1500
- } catch (e) {
1501
- LOG(1, "Regex Inválido. ", e);
1502
- return "0";
1503
- }
1504
- if ((!casas) || (casas == "") || (casas <= 0)) casas = 0;
1505
- return `${LibUtil.toNumber(resultado, casas)}`;
1506
- }
1507
-
1508
- static uuid = () => {
1509
- // Padrão UUIDV4 - Gerador de identificador unico
1510
- return "10000000-1000-4000-8000-100000000000".replace(/[018]/g, (c: any) => { // c = String
1511
- return (c ^ crypto.getRandomValues(new Uint8Array(1))[0] & 15 >> c / 4).toString(16);
1512
- }).toString().toUpperCase();
1513
- }
1514
-
1515
- // mk.isRoute("/Pesagem$") // <= Rota termina com /Pesagem
1516
- static isRoute = (rotaRegex: string) => {
1517
- return new RegExp(rotaRegex).test(window.location.pathname);
1518
- }
1519
-
1520
- static verificarIgualdade(array: any[], propriedades: string[]) {
1521
- // Verifica se várias propriedades estão iguais em todos os objetos de um array.
1522
- if (array.length <= 1) return true;
1523
- const primeiro = array[0];
1524
- return array.every(objeto => {
1525
- return propriedades.every(propriedade => {
1526
- // Verifica se a propriedade existe em ambos os objetos antes da comparação
1527
- if (!(propriedade in objeto) || !(propriedade in primeiro)) {
1528
- LOG(1, `⚠️ Propriedade '${propriedade}' ausente em um ou mais objetos.`);
1529
- return false; // considera falso se a propriedade não existir
1530
- }
1531
- return objeto[propriedade] === primeiro[propriedade];
1532
- });
1533
- });
1534
- }
1535
-
1536
- static individualNoObjeto(array: any[], propriedade: string): any[] {
1537
- // Ignora os Objetos que esta Propriedade se repetir.
1538
- let novoSet = new Set(array.map((o) => { return o[propriedade] }));
1539
- return array.map((o) => {
1540
- if (novoSet.has(o[propriedade])) {
1541
- novoSet.delete(o[propriedade]);
1542
- return o;
1543
- } else return null;
1544
- }).filter(o => o);
1545
- }
1546
-
1547
- static hasFaltante(array: any[], propriedades: string[]) {
1548
- // Verifica as propriedades informadas estão disponíveis em todos os objetos do array.
1549
- if (array.length <= 0) return false;
1550
- return array.every(objeto => {
1551
- return propriedades.every(propriedade => {
1552
- if (!(propriedade in objeto)) {
1553
- return true;
1554
- }
1555
- return false;
1556
- });
1557
- });
1558
- }
1559
-
1560
- static somarEmObjeto(lista: any[], propriedade: string) {
1561
- // Soma uma determinada propriedade em uma lista
1562
- return lista.reduce((acc: number, val: any) => {
1563
- if (LibUtil.classof(val[propriedade]) == "number") {
1564
- return acc + val[propriedade];
1565
- }
1566
- return acc;
1567
- }, 0);
1568
- }
1569
-
1570
- static capitalize = (texto?: string | null): string => {
1571
- let arrayTexto = texto?.toString().split(" ");
1572
- return arrayTexto?.map(str => {
1573
- let str_low = str.toLowerCase();
1574
- if (["da", "de", "do", "das", "dos", "e"].includes(str_low)) {
1575
- return str_low;
1576
- } else {
1577
- return str_low.charAt(0).toUpperCase() + str_low.slice(1);
1578
- }
1579
- }).join(" ") || "";
1580
- };
1581
-
1582
- static GetParam = (name: string | null = null, url: string | null = null) => {
1583
- // Coleta o valor do parametro da url.
1584
- if (!url) url = document.location.toString();
1585
- if (name != null) {
1586
- return new URL(url).searchParams.get(name);
1587
- } else {
1588
- return new URL(url).searchParams.toString();
1589
- }
1590
- }
1591
-
1592
- static getParamObject = (url?: string) => {
1593
- if (!url) url = document.location.toString();
1594
- return url?.split("?")[1]?.split("&")?.reduce((acc: any, val: string) => {
1595
- const [key, value] = val.split("=");
1596
- acc[key] = value;
1597
- return acc;
1598
- }, {});
1599
- }
1600
-
1601
- static toQueryString(obj?: any, urlAtual: string = ""): string {
1602
- if (obj) {
1603
- // Quando é GET, modifica a URL e acrescenta os QUERYSTRING do objeto enviado por parametro.
1604
- if (obj != null) {
1605
- if (!urlAtual.includes("?")) {
1606
- urlAtual = urlAtual + "?"; // Cria o divisor entre os dados do query e o endereço destino.
1607
- }
1608
- let queryStrings = "";
1609
- if (LibUtil.classof(obj) == "object") {
1610
- for (let propriedade in obj) {
1611
- if (LibUtil.classof(obj[propriedade]) == "object") {
1612
- let propJson = JSON.stringify(obj[propriedade]);
1613
- queryStrings += `&${propriedade}=${propJson}`;
1614
- LOG(1, `⚠️ toQueryString() - Uma propriedade enviada: '${propriedade}' era um objeto. Url`, urlAtual);
1615
- } else {
1616
- if (obj[propriedade] != null) {
1617
- queryStrings += `&${propriedade}=${obj[propriedade]}`;
1618
- }
1619
- }
1620
- }
1621
- } else {
1622
- LOG(1, "❌ Dados enviados via GET precisam ser Object. Dados: ", LibUtil.classof(obj));
1623
- }
1624
- urlAtual = urlAtual + queryStrings;
1625
- }
1626
- }
1627
- if (urlAtual.endsWith("?")) urlAtual = urlAtual.slice(0, -1); // Remove o ? final se não tiver nada depois.
1628
- urlAtual = urlAtual.replaceAll("?&", "?");
1629
- return urlAtual;
1630
- }
1631
-
1632
- /**
1633
- * Mapeia uma EntidadeA para EntidadeB usando o TRANSFORMA
1634
- * É nescessário informar o DE/PARA/TRANSFORMA de cada propriedade.
1635
- */
1636
- static mapearEntidade<T, U>(
1637
- entidadeOrigem: T,
1638
- mapeamento: MapeamentoItem<T, U>[]
1639
- ): U {
1640
- const entidadeDestino: any = {};
1641
- mapeamento.forEach(item => {
1642
- const valor = entidadeOrigem[item.de];
1643
- if (valor !== undefined) {
1644
- entidadeDestino[item.para] = item.transforma(valor);
1645
- } else {
1646
- entidadeDestino[item.para] = null;
1647
- }
1648
- });
1649
- return entidadeDestino as U;
1650
-
1651
- }
1652
-
1653
- /**
1654
- * Faz uma tentativa de obter uma url, mas se falhar, retorna nulo
1655
- */
1656
- static getURL(urlQuery?: string) {
1657
- let url;
1658
- if (urlQuery) {
1659
- try {
1660
- url = new URL(urlQuery);
1661
- } catch (e) {
1662
- LOG(1, "❌ URL INVÁLIDA: ", urlQuery);
1663
- }
1664
- }
1665
- return url;
1666
- }
1667
-
1668
- static conversorCSS(texto: string): string[] {
1669
- const regex = /\.([a-z0-9-]+)\s*{.*?}/g;
1670
- let arrayTexto = texto.replace(/\s+/g, ' ').replace(/[\r\n]/g, '').replace(regex, (match, group1) => group1 + ",").trim().split(",");
1671
- return arrayTexto.map(i => i.trim()).filter(o => o != "");
1672
- }
1673
-
1674
- static sort<T, K extends keyof T>(array: T[], propriedade: K): T[] {
1675
- return array.sort((a, b) => (a[propriedade] < b[propriedade] ? -1 : 1));
1676
- }
1677
-
1678
- static converteEnterEmBr(texto: string): string {
1679
- return texto.replace(/\n/g, "<br>");
1680
- }
1681
-
1682
- static hasHtmlTags(texto: string): boolean {
1683
- const regex = /<\/?[a-z][\s\S]*>/i;
1684
- return regex.test(texto);
1685
- }
1686
-
1687
-
1688
- /**
1689
- * Une duas listas quando elas tem uma propriedade em comum
1690
- * @param listaA Lista a ser sobreescrita ou preenchida
1691
- * @param listaB Lista com os dados para preencher ou sobreescrever
1692
- * @param propEmComum Nome da propriedade que, se estiver em comum nas listas, será populado, do contrário não.
1693
- * @returns Lista Unida por um Filtro.
1694
- */
1695
- static Union(listaA: any[], listaB: any[], propEmComum?: string): any[] {
1696
- let resultado = listaA.map(itensA => ({
1697
- ...itensA,
1698
- ...listaB.filter(o => o[propEmComum as keyof typeof o]?.toString() == itensA[propEmComum as keyof typeof listaA]?.toString())[0],
1699
- }));
1700
- G_START(3, "Unindo Listas...")
1701
- LOG(3, "ListaA: ", listaA);
1702
- LOG(3, "ListaB: ", listaB);
1703
- LOG(3, "Resultado: ", resultado);
1704
- G_END(3);
1705
- return resultado;
1706
- }
1707
-
1708
- /**
1709
- * Gera uma string menor que a informada.
1710
- * @returns
1711
- */
1712
- static gerarHashCurto(texto: string, tamanho: number = 8): string {
1713
- let hash = 0;
1714
- for (let i = 0; i < texto.length; i++) {
1715
- hash = ((hash << 5) - hash) + texto.charCodeAt(i);
1716
- hash = hash & hash; // Converte para inteiro de 32 bits
1717
- }
1718
- // Converter para string hexadecimal positiva e pegar os primeiros caracteres
1719
- return Math.abs(hash).toString(16).substring(0, tamanho);
1720
- }
1721
-
1722
- static gerarNomeColection(nomeSistema: string, colecao: string): string {
1723
- return LibUtil.gerarHashCurto(nomeSistema) + "_" + colecao;
1724
- }
1725
-
1726
-
1727
- static apenasNumerosLetras = (s: string = ""): string => {
1728
- if (s == null) return "";
1729
- // Ignora qualquer outro caracter além de Numeros e Letras formato ocidental
1730
- return s.replace(/(?![a-zA-Z0-9])./g, "");
1731
- };
1732
-
1733
- static removeEspecias = (s: string): string => {
1734
- if (s == null) return "";
1735
- // Remove acentos e depois chama Apenas Números e Letras.
1736
- s = s.toString();
1737
- return LibUtil.apenasNumerosLetras(LibUtil.removeAcentos(s));
1738
- };
1739
-
1740
- static LerTexto = async (texto = "Teste som: 1, 2, 3.", locutor = 0) => {
1741
- let lerVoz = window.speechSynthesis;
1742
- let listaVozes = lerVoz.getVoices().filter(o => o.lang.toLowerCase() == "pt-br");
1743
- let locutorEncontrado = listaVozes[locutor] || listaVozes[0] || null;
1744
- return new Promise((r) => {
1745
- if (lerVoz.speaking) {
1746
- LOG(1, ">> Ainda está reproduzindo. Tente mais tarde.");
1747
- return;
1748
- }
1749
- if (texto != "") {
1750
- const ssu = new SpeechSynthesisUtterance(texto);
1751
- ssu.lang = "pt-BR";
1752
- ssu.voice = locutorEncontrado;
1753
- ssu.pitch = 0; // Tom de voz
1754
- ssu.rate = 1.5; // Velocidade
1755
- ssu.onend = (ev) => { r(true) };
1756
- ssu.onerror = (ev) => { LOG(1, "❌ Erro: ", ev.error); r(false) };
1757
- lerVoz.cancel();
1758
- lerVoz.speak(ssu);
1759
- }
1760
- });
1761
- }
1762
-
1763
- static async LerProximoERemover(playlist: string[]) {
1764
- if (await LibUtil.LerTexto(playlist[0]) == true) {
1765
- playlist.shift();
1766
- }
1767
- return playlist;
1768
- }
1769
-
1770
- static LeituraInterrompida() {
1771
- window.speechSynthesis.cancel();
1772
- }
1773
-
1774
- static gerarNumeroInteiro(min: number, max: number): any {
1775
- return Math.floor(Math.random() * (max - min + 1)) + min;
1776
- }
1777
-
1778
- static SelectInner(e: HTMLInputElement) {
1779
- // Seleciona texto do elemento
1780
- if (window.getSelection) {
1781
- const selection = window.getSelection();
1782
- const range = document.createRange();
1783
- range.selectNodeContents(e);
1784
- selection?.removeAllRanges();
1785
- selection?.addRange(range);
1786
- }
1787
- }
1788
-
1789
- static generatePrimaryKey(item: any, primarykey: string): any {
1790
- if (item == null) {
1791
- LOG(1, "❌ Não foi possível gerar uma chave, pois o objeto ainda não está preenchido.")
1792
- return item;
1793
- }
1794
-
1795
- if (LibUtil.classof(item) != "object") {
1796
- LOG(1, "⚠️ Não foi possível gerar uma chave neste tipo de variável: ", LibUtil.classof(item));
1797
- return item;
1798
- }
1799
-
1800
- if (item[primarykey] != null) {
1801
- LOG(5, "Chave não gerada no objeto, pois já estava preenchido com:", item[primarykey]);
1802
- return item;
1803
- }
1804
-
1805
- item[primarykey] = LibUtil.uuid();
1806
- return item;
1807
- }
1808
-
1809
- static hslToHex(h: number, s: number, l: number) {
1810
- // Normalize saturation and lightness to a 0-1 range
1811
- s /= 100;
1812
- l /= 100;
1813
-
1814
- let c = (1 - Math.abs(2 * l - 1)) * s,
1815
- x = c * (1 - Math.abs(((h / 60) % 2) - 1)),
1816
- m = l - c / 2,
1817
- r = 0,
1818
- g = 0,
1819
- b = 0;
1820
-
1821
- if (0 <= h && h < 60) {
1822
- r = c;
1823
- g = x;
1824
- b = 0;
1825
- } else if (60 <= h && h < 120) {
1826
- r = x;
1827
- g = c;
1828
- b = 0;
1829
- } else if (120 <= h && h < 180) {
1830
- r = 0;
1831
- g = c;
1832
- b = x;
1833
- } else if (180 <= h && h < 240) {
1834
- r = 0;
1835
- g = x;
1836
- b = c;
1837
- } else if (240 <= h && h < 300) {
1838
- r = x;
1839
- g = 0;
1840
- b = c;
1841
- } else if (300 <= h && h < 360) {
1842
- r = c;
1843
- g = 0;
1844
- b = x;
1845
- }
1846
-
1847
- // Convert RGB values to 0-255 range
1848
- r = Math.round((r + m) * 255);
1849
- g = Math.round((g + m) * 255);
1850
- b = Math.round((b + m) * 255);
1851
-
1852
- // Convert RGB components to hexadecimal and pad with leading zero if needed
1853
- const toHex = (c: any) => {
1854
- const hex = c.toString(16);
1855
- return hex.length === 1 ? '0' + hex : hex;
1856
- };
1857
-
1858
- return `#${toHex(r)}${toHex(g)}${toHex(b)}`;
1859
- }
1860
-
1861
- static isFilled(dados: any): boolean {
1862
- if (LibUtil.classof(dados) == "array") {
1863
- if ((dados as Array<any>).length && (dados as Array<any>).length > 0) {
1864
- return true;
1865
- }
1866
- }
1867
- return false;
1868
- }
1869
-
1870
- static replace(regex: string, valor: string | number): string {
1871
- if (typeof valor === "number") valor = valor.toString();
1872
- return valor.replace(new RegExp(regex, 'g'), '');
1873
- }
1874
-
1875
- // Mínimo 2 timestamps
1876
- static calculateJitter(timestamps: number[]): number {
1877
- if (timestamps.length < 2) return 0;
1878
-
1879
- const delays = [];
1880
- for (let i = 1; i < timestamps.length; i++) {
1881
- delays.push(timestamps[i] - timestamps[i - 1]);
1882
- }
1883
-
1884
- if (delays.length < 2) return 0;
1885
- let totalJitterDifference = 0;
1886
-
1887
- for (let i = 1; i < delays.length; i++) {
1888
- totalJitterDifference += Math.abs(delays[i] - delays[i - 1]);
1889
- }
1890
-
1891
- return totalJitterDifference / (delays.length - 1);
1892
- }
1893
-
1894
- // Soma os valores dos arrays por índice
1895
- static somarPorIndice = (arrays: number[][]): number[] => {
1896
- if (arrays.length === 0) return [];
1897
- return arrays.reduce((acc, arr) =>
1898
- arr.map((val, i) => (acc[i] || 0) + val)
1899
- );
1900
- }
1901
-
1902
- // Soma os valores dos arrays
1903
- static somarArrayInterna = (arrays: number[][]): number[] => {
1904
- if (arrays.length === 0) return [];
1905
- return arrays.map(a => a.reduce((acc, v) => acc + v, 0));
1906
- }
1907
-
1908
- // Faz o download de um Blob()
1909
- static downloadBlob = (blob: Blob, nomeArquivo: string) => {
1910
- const url = URL.createObjectURL(blob);
1911
- const a = document.createElement('a');
1912
- a.href = url;
1913
- a.download = nomeArquivo;
1914
- document.body.appendChild(a);
1915
- a.click();
1916
- document.body.removeChild(a);
1917
- URL.revokeObjectURL(url);
1918
- }
1919
-
1920
- static wordsToCamelCase(texto: string): string {
1921
- // Se houver espaços, traços, undercores, converte para camelCase
1922
- return texto.split(/[\s-_]+/)
1923
- .map((word, index) =>
1924
- index === 0 ? word : word.charAt(0).toUpperCase() + word.slice(1)
1925
- ).join('');
1926
- }
1927
-
1928
- static camelCase(texto: string): string {
1929
- return texto.charAt(0).toLowerCase() + texto.slice(1);
1930
- }
1931
-
1932
- static pascalCase(texto: string): string {
1933
- return texto.charAt(0).toUpperCase() + texto.slice(1);
1934
- }
1935
-
1936
- static dashedCase(texto: string): string {
1937
- // Converte camelCase ou PascalCase para dashed-case
1938
- return texto.replace(/([a-z])([A-Z])/g, '$1-$2').toLowerCase();
1939
- }
1940
-
1941
- static separaWordsCase(texto: string): string {
1942
- // Separa as palavras ao trocar de letra minúscula para maiúscula.
1943
- // CodigoIBGE => Codigo IBGE
1944
- let textoSeparado = texto.replace(/([a-z])([A-Z])/g, '$1 $2');
1945
- return textoSeparado;
1946
- }
1947
-
1948
- // Separa as palavras por espaço, traço ou underline, e retorna um array com as palavras.
1949
- static wordsArray(texto: string): string[] {
1950
- return texto.split(/[\s-_]+/).filter(word => word.length > 0);
1951
- }
1952
-
1953
- static tentaAcentuarTexto(s: string | string[]): string {
1954
- // Utiliza regras de acentuação de português para tentar acentuar a palavra informada.
1955
- if (LibUtil.classof(s) == "array") {
1956
- return (s as string[]).map((palavra) => LibUtil.tentaAcentuarTexto(palavra)).join(" ");
1957
- }
1958
- let texto = (s as string);
1959
- if (texto.endsWith("ao")) {
1960
- texto = texto.slice(0, -2) + "ão"; // Ex: mão
1961
- }
1962
- if (texto.endsWith("oes")) {
1963
- texto = texto.slice(0, -3) + "ões"; // Ex: permissões
1964
- }
1965
- if (texto.endsWith("cao") || texto.endsWith("çao") || (texto.endsWith("cão") && texto != "cão")) {
1966
- texto = texto.slice(0, -3) + "ção"; // Ex: ação
1967
- }
1968
- if (texto.endsWith("coes") || texto.endsWith("çoes") || texto.endsWith("cões")) {
1969
- texto = texto.slice(0, -4) + "ções"; // Ex: observações
1970
- }
1971
-
1972
- return texto;
1973
- }
1974
-
1975
- static pluralOf(word: string | string[]): string {
1976
- // Retorna o plural da palavra informada em português
1977
- if (LibUtil.classof(word) == "array") {
1978
- return (word as string[]).map((palavra) => LibUtil.pluralOf(palavra)).join(" ");
1979
- }
1980
-
1981
- let texto = (word as string);
1982
- if (texto.endsWith("ão")) {
1983
- return texto.slice(0, -2) + "ões";
1984
- } else if (texto.endsWith("ões")) {
1985
- return texto.slice(0, -3) + "ões";
1986
- } else if (texto.endsWith("r") || texto.endsWith("s") || texto.endsWith("z")) {
1987
- return texto + "es";
1988
- } else if (texto.endsWith("m")) {
1989
- return texto.slice(0, -1) + "ns";
1990
- } else if (texto.endsWith("l")) {
1991
- return texto.slice(0, -1) + "is";
1992
- } else {
1993
- return texto + "s";
1994
- }
1995
- }
1996
-
1997
- static setLogLevel(level: number): void {
1998
- LibUtil.loglevel = level;
1999
- }
2000
-
2001
- static setFormConfigs(configs: Partial<IFieldComponent<any>>): void {
2002
- LibUtil.formConfigs = configs;
2003
- }
2004
-
2005
- static paraPortugues(texto: string): string {
2006
- let acentuado = LibUtil.tentaAcentuarTexto(LibUtil.wordsArray(LibUtil.separaWordsCase(texto)))
2007
- return LibUtil.replaceDicionario(acentuado);
2008
- }
2009
-
2010
- static paraPortuguesPlural(texto: string): string {
2011
- let plural = LibUtil.pluralOf(LibUtil.paraPortugues(texto))
2012
- return plural;
2013
- }
2014
-
2015
- // Dicionário
2016
- static replaceDicionario(texto: string): string {
2017
- if (texto.startsWith("Is ")) {
2018
- texto = texto.replace(/^Is /, "É ");
2019
- }
2020
- texto = texto.replaceAll("Codigo", "Código");
2021
- texto = texto.replaceAll("Icone", "Ícone");
2022
- texto = texto.replaceAll("Enderec", "Endereç");
2023
- texto = texto.replaceAll("Balanc", "Balanç");
2024
- texto = texto.replaceAll("Usuari", "Usuári");
2025
- texto = texto.replaceAll("Lancamento", "Lançamento");
2026
- texto = texto.replaceAll("Referencia", "Referência");
2027
- texto = texto.replaceAll("Ultim", "Últim");
2028
- texto = texto.replaceAll("Numero", "Número");
2029
- texto = texto.replaceAll("Inicio", "Início");
2030
- texto = texto.replaceAll("Socio", "Sócio");
2031
- texto = texto.replaceAll("Socia", "Sócia");
2032
- texto = texto.replaceAll("Especie", "Espécie");
2033
- texto = texto.replaceAll("Cobranca", "Cobrança");
2034
- texto = texto.replaceAll("Modulo", "Módulo");
2035
- texto = texto.replaceAll("Servico", "Serviço");
2036
- texto = texto.replaceAll("Aliquota", "Alíquota");
2037
- texto = texto.replaceAll("Calculo", "Cálculo");
2038
- texto = texto.replaceAll("Unitario", "Unitário");
2039
- texto = texto.replaceAll("Procedencia", "Procedência");
2040
- texto = texto.replaceAll("Mudanca", "Mudança");
2041
- texto = texto.replaceAll("Pratica", "Prática");
2042
- texto = texto.replaceAll("Propria", "Própria");
2043
- texto = texto.replaceAll("Impropria", "Imprópria");
2044
- texto = texto.replaceAll("Responsavel", "Responsável");
2045
- texto = texto.replaceAll("Conjuge", "Cônjuge");
2046
- texto = texto.replaceAll("Cafe", "Café");
2047
- texto = texto.replaceAll("Transferencia", "Transferência");
2048
- texto = texto.replaceAll("Bancaria", "Bancária");
2049
- texto = texto.replaceAll("Agencia", "Agência");
2050
- texto = texto.replaceAll("Digito", "Dígito");
2051
-
2052
- if (texto.includes("Mes ")) texto = texto.replaceAll("Mes ", "Mês ");
2053
- if (texto.endsWith("Mes")) texto = texto.replace(/Mes$/, "Mês");
2054
- if (texto.includes("Ate ")) texto = texto.replaceAll("Ate ", "Até ");
2055
- if (texto.endsWith("Ate")) texto = texto.replace(/Ate$/, "Até");
2056
- if (texto.includes("Socio ")) texto = texto.replaceAll("Socio ", "Sócio ");
2057
- if (texto.endsWith("Socio")) texto = texto.replace(/Socio$/, "Sócio");
2058
- if (texto.includes("Socia ")) texto = texto.replaceAll("Socia ", "Sócia ");
2059
- if (texto.endsWith("Socia")) texto = texto.replace(/Socia$/, "Sócia");
2060
- return texto;
2061
- }
2062
-
2063
- }
2064
-
2065
-
2066
-
2067
-
2068
- ////////////////////////////////////
2069
- // CONSOLES: LOG - WARN - ERR ...
2070
- ////////////////////////////////////
2071
- // LibUtil.loglevel: 1,2,3 => Bigger will see more
2072
-
2073
- export const LOG = (level: number, ...attr: any) => {
2074
- if (LibUtil.loglevel >= level) {
2075
- return console.log(...attr);
2076
- }
2077
- }
2078
-
2079
- // export const WARN = (level: number, ...attr: any) => {
2080
- // if (LibUtil.loglevel >= level) {
2081
- // return console.warn(...attr);
2082
- // }
2083
- // }
2084
-
2085
- // export const ERR = (level: number, ...attr: any) => {
2086
- // if (LibUtil.loglevel >= level) {
2087
- // return console.error(...attr);
2088
- // }
2089
- // }
2090
-
2091
- export const G_START = (level: number, ...attr: any) => {
2092
- if (LibUtil.loglevel >= level) {
2093
- return console.groupCollapsed(...attr);
2094
- }
2095
- }
2096
-
2097
- export const G_START_OPEN = (level: number, ...attr: any) => {
2098
- if (LibUtil.loglevel >= level) {
2099
- return console.group(...attr);
2100
- }
2101
- }
2102
-
2103
- export const G_END = (level: number, ...attr: any) => {
2104
- if (LibUtil.loglevel >= level) {
2105
- return console.groupEnd();
2106
- }
2107
- }
2108
-
2109
- // LOG COLAPSADO
2110
- export const LOGC = (level: number, title: string, ...attr: any) => {
2111
- G_START(level, title);
2112
- LOG(level, ...attr);
2113
- G_END(level);
2114
- }
2115
-
2116
-
2117
-
2118
- export type IClassOf = "string" | "number" | "nan" | "object" | "array" | "boolean" | "undefined" | "null" | "function" | "date" | "regexp" | "error" | "symbol" | "bigint"
2119
-
2120
- export interface IFormatter {
2121
- mask: string | ((value: any) => string);
2122
- regex: string;
2123
- validate: (value: any) => boolean;
2124
- }
2125
-
2126
- export interface IUtilFormatters {
2127
- cpf: IFormatter;
2128
- cnpj: IFormatter;
2129
- cpf_cnpj: IFormatter;
2130
- cnh: IFormatter;
2131
- pis: IFormatter;
2132
- dia: IFormatter;
2133
- mes: IFormatter;
2134
- ano: IFormatter;
2135
- anoRecente: IFormatter;
2136
- data: IFormatter;
2137
- dataIso: IFormatter;
2138
- numero: IFormatter;
2139
- decimal: IFormatter;
2140
- letra: IFormatter;
2141
- numeroELetra: IFormatter;
2142
- ip: IFormatter;
2143
- email: IFormatter;
2144
- cep: IFormatter;
2145
- }
2146
-
2147
- export interface MapeamentoItem<T, U> {
2148
- de: keyof T;
2149
- para: keyof U;
2150
- transforma: (v: T[keyof T]) => U[keyof U];
2151
- }