@jhqn/utils-core 0.1.0 → 0.3.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.
package/dist/index.mjs DELETED
@@ -1,484 +0,0 @@
1
- export { detect } from 'detect-browser';
2
- import dayjs from 'dayjs';
3
- export { default as dayjs } from 'dayjs';
4
- import zhCN from 'dayjs/locale/zh-cn';
5
- import customParseFormat from 'dayjs/plugin/customParseFormat';
6
- import duration from 'dayjs/plugin/duration';
7
- import localeData from 'dayjs/plugin/localeData';
8
- import objectSupport from 'dayjs/plugin/objectSupport';
9
- import relativeTime from 'dayjs/plugin/relativeTime';
10
-
11
- const snake2Kebab = (str) => str.replace(/_([a-z])/g, (_, letter) => `-${letter.toLowerCase()}`);
12
- const snake2Pascal = (str) => str.replace(/_([a-z])/g, (_, letter) => letter.toUpperCase()).replace(/^[a-z]/, (letter) => letter.toUpperCase());
13
- const snake2Camel = (str) => str.replace(/(_([a-z]))/g, (match) => match[1].toUpperCase());
14
- const snake2Title = (str) => str.replace(/_([a-z])/g, (_, letter) => ` ${letter.toUpperCase()}`).replace(/^[a-z]/, (letter) => letter.toUpperCase());
15
- const kebab2Snake = (str) => str.replace(/-([a-z])/g, (_, letter) => `_${letter.toLowerCase()}`);
16
- const kebab2Pascal = (str) => str.replace(/-([a-z])/g, (_, letter) => letter.toUpperCase()).replace(/^[a-z]/, (letter) => letter.toUpperCase());
17
- const kebab2Camel = (str) => {
18
- const [first, ...rest] = str.split("-");
19
- return [first, ...rest.map((s) => s.replace(/^[a-z]/, s[0].toUpperCase()))].join("");
20
- };
21
- const kebab2Title = (str) => str.replace(/-([a-z])/g, (_, letter) => ` ${letter.toUpperCase()}`).replace(/^[a-z]/, (letter) => letter.toUpperCase());
22
- const pascal2Snake = (str) => str.replace(/([A-Z])/g, (_, letter) => `_${letter.toLowerCase()}`).replace(/^_/, "");
23
- const pascal2Kebab = (str) => str.replace(/([A-Z])/g, (_, letter) => `-${letter.toLowerCase()}`).replace(/^-/, "");
24
- const pascal2Camel = (str) => str.replace(/^[A-Z]/, (letter) => letter.toLowerCase());
25
- const pascal2Title = (str) => str.replace(/([A-Z])/g, (_, letter) => ` ${letter}`).replace(/^ /, "");
26
- const camel2Snake = (str) => str.replace(/([A-Z])/g, (_, letter) => `_${letter.toLowerCase()}`);
27
- const camel2Kebab = (str) => str.replace(/([A-Z])/g, (_, letter) => `-${letter.toLowerCase()}`);
28
- const camel2Pascal = (str) => str.replace(/(^[a-z])|(\s+[a-z])/g, (match) => match.toUpperCase());
29
- const camel2Title = (str) => str.replace(/([A-Z])/g, (_, letter) => ` ${letter}`).replace(/^[a-z]/, (match) => match.toUpperCase());
30
- const title2Snake = (str) => str.replace(/([A-Z])/g, (match) => match.toLowerCase()).replace(/ /g, "_");
31
- const title2Kebab = (str) => str.replace(/([A-Z])/g, (match) => match.toLowerCase()).replace(/ /g, "-");
32
- const title2Pascal = (str) => str.replace(/ /g, "");
33
- const title2Camel = (str) => str.replace(/ /g, "").replace(/^[A-Z]/, (match) => match.toLowerCase());
34
-
35
- const sharedStyle = "color: white; padding: 1px 2px;";
36
- const jLog = (...args) => __DEV__ ? console.log.bind(
37
- console,
38
- `%c[${args.length === 1 ? "LOG" : "%s"}]`,
39
- `${sharedStyle} background: seagreen;`
40
- )(...args) : () => {
41
- };
42
- const jDebug = (...args) => console.log.bind(
43
- console,
44
- `%c[${args.length === 1 ? "DEBUG" : "%s"}]`,
45
- `${sharedStyle} background: linear-gradient(LightSalmon, Tomato); border-radius: 2px; font-weight: bold; border-top: 2px solid Crimson; border-bottom: 2px solid Crimson;`
46
- )(...args);
47
- const jWarn = (...args) => console.warn.bind(console, `%c[${args.length === 1 ? "WARN" : "%s"}]`, `${sharedStyle} background: tomato;`)(...args);
48
- const jError = (...args) => console.error.bind(
49
- console,
50
- `%c[${args.length === 1 ? "ERROR" : "%s"}]`,
51
- `${sharedStyle} background: crimson;`
52
- )(...args);
53
- const jInfo = (...args) => console.info.bind(
54
- console,
55
- `%c[${args.length === 1 ? "INFO" : "%s"}]`,
56
- `${sharedStyle} background: dodgerblue;`
57
- )(...args);
58
- const jGroup = console.group.bind(console, "%c[%s]", `${sharedStyle} background: slateblue;`);
59
- const jGroupC = console.groupCollapsed.bind(console, "%c[%s]", `${sharedStyle} background: slateblue;`);
60
- const jGroupE = console.groupEnd.bind(console);
61
- const jTime = (str) => console.time(`[${str}]`);
62
- const jTimeEnd = (str) => console.timeEnd(`[${str}]`);
63
- const jClear = console.clear.bind(console);
64
-
65
- let prevValue;
66
- const jLogDedupe = (...args) => {
67
- if (args.length === 0) return;
68
- if (args.length > 0 && prevValue && JSON.stringify(args) === JSON.stringify(prevValue)) return;
69
- jLog(...args);
70
- prevValue = args;
71
- };
72
-
73
- let logged = false;
74
- const jLogOnce = (...args) => {
75
- if (logged) return;
76
- jLog(...args);
77
- logged = true;
78
- };
79
-
80
- const getVariableType = (val) => {
81
- const value = Object.prototype.toString.call(val);
82
- const result = value.match(/\[object (\S*)\]/)?.[1];
83
- return result?.toLocaleLowerCase();
84
- };
85
- const isNumber = (val) => getVariableType(val) === "number";
86
- const isBigInt = (val) => getVariableType(val) === "bigint";
87
- const isString = (val) => getVariableType(val) === "string";
88
- const isBoolean = (val) => getVariableType(val) === "boolean";
89
- const isNull = (val) => getVariableType(val) === "null";
90
- const isUndefined = (val) => getVariableType(val) === "undefined";
91
- const isSymbol = (val) => getVariableType(val) === "symbol";
92
- const isObject = (val) => getVariableType(val) === "object";
93
- const isArray = (val) => getVariableType(val) === "array";
94
- const isFunction = (val) => getVariableType(val) === "function";
95
- const isDate = (val) => getVariableType(val) === "date";
96
- const isRegExp = (val) => getVariableType(val) === "regexp";
97
- const isPromise = (val) => getVariableType(val) === "promise";
98
- const isSet = (val) => getVariableType(val) === "set";
99
- const isMap = (val) => getVariableType(val) === "map";
100
- const isWeakSet = (val) => getVariableType(val) === "weakset";
101
- const isWeakMap = (val) => getVariableType(val) === "weakmap";
102
- const isFile = (val) => getVariableType(val) === "file";
103
- const isBlob = (val) => getVariableType(val) === "blob";
104
- const isURL = (val) => getVariableType(val) === "url";
105
- const isError = (val) => getVariableType(val) === "error";
106
- const isDef = (val) => !isNull(val) && !isUndefined(val);
107
- const isJSONStr = (str) => {
108
- if (isDef(str)) {
109
- try {
110
- JSON.parse(str);
111
- return true;
112
- } catch (e) {
113
- jWarn("Failed to parse invalid string", e);
114
- return false;
115
- }
116
- }
117
- return false;
118
- };
119
- const isArrStr = (str) => {
120
- if (isDef(str)) {
121
- try {
122
- return Array.isArray(JSON.parse(str));
123
- } catch (e) {
124
- jWarn("Failed to parse invalid string", e);
125
- return false;
126
- }
127
- }
128
- return false;
129
- };
130
- const isValidKey = (key, object) => key in object;
131
- const isEmpty = (val) => {
132
- return !isDef(val) || val === "" || isArray(val) && val.length === 0 || isObject(val) && Object.keys(val).length === 0 || isMap(val) && val.size === 0 || isSet(val) && val.size === 0;
133
- };
134
-
135
- const cnPhoneRE = /^1[3-9]\d{9}$/;
136
- const cnTelRE = /^0\d{2,3}-?\d{7,8}$/;
137
- const cnTelRE2 = /^\(0\d{2,3}\)\d{7,8}$/;
138
- const cnUSCIRE = /^[0-9A-HJ-NPQRTUWXY]{2}\d{6}[0-9A-HJ-NPQRTUWXY]{10}$/;
139
- const cnIdCard15Re = /^[1-9]\d{7}(?:0[1-9]|10|11|12)(?:[0-2][1-9]|10|20|30|31)\d{2}[\dX]$/i;
140
- const cnIdCard18Re = /^[1-9]\d{5}(?:18|19|20)\d{2}(?:0[1-9]|1[0-2])(?:[0-2][1-9]|10|20|30|31)\d{3}[\dX]$/i;
141
- const emailRE = /^[a-z\d](?:\w|-)+@[a-z\d]+\.[a-z]{2,5}$/i;
142
- const isUSCI = (val) => {
143
- if (!isDef(val)) return false;
144
- return cnUSCIRE.test(val);
145
- };
146
- const isPhone = (val) => {
147
- if (!isDef(val)) return false;
148
- return cnPhoneRE.test(val.toString());
149
- };
150
- const isTel = (val) => {
151
- if (!isDef(val)) return false;
152
- const valStr = val.toString().replaceAll(" ", "");
153
- return cnTelRE.test(valStr) || cnTelRE2.test(valStr);
154
- };
155
- const isEmail = (val) => {
156
- if (!isDef(val)) return false;
157
- return emailRE.test(val);
158
- };
159
- const isIdCard = (val, compatible = true) => {
160
- if (!isDef(val)) return false;
161
- return cnIdCard18Re.test(val) || (compatible ? cnIdCard15Re.test(val) : false);
162
- };
163
- const isNumeric = (val) => {
164
- if (isDef(val)) return typeof val === "number" || /^\d+(?:\.\d+)?$/.test(val);
165
- return false;
166
- };
167
- const checkImg = (ext) => {
168
- return /\.(?:jpg|jpeg|png|gif)$/.test((ext || "").toLowerCase());
169
- };
170
- const nonASCII = (text) => /[^\x20-\x7E]/.test(text);
171
- const isValidFileType = (file, type) => {
172
- if (type === "*") return true;
173
- const fileType = file.type;
174
- const fileName = file.name;
175
- function validate(item) {
176
- if (item.startsWith(".")) {
177
- return fileName.endsWith(item);
178
- }
179
- if (item.endsWith("/*")) {
180
- return fileType.startsWith(item.replace("/*", ""));
181
- }
182
- if (item.includes("/")) {
183
- return fileType === item;
184
- }
185
- return false;
186
- }
187
- const typeArrStr = type.split(",").map((item) => item.trim());
188
- if (typeArrStr.length > 1) {
189
- return typeArrStr.some(validate);
190
- }
191
- return validate(type);
192
- };
193
-
194
- const isValidResCode = (res, code = 200) => res.code === code;
195
- const isValidRes = (res, code) => isValidResCode(res, code) && isDef(res.data);
196
- const isValidArrRes = (res, code) => isValidResCode(res, code) && Array.isArray(res.data);
197
- const isValidPageRes = (res, code) => isValidResCode(res, code) && isDef(res.data) && Array.isArray(res.data.list || res.data.records);
198
-
199
- const hideMiddle = (str) => {
200
- if (!isDef(str)) return "";
201
- const len = str.length;
202
- if (len <= 2) return "*".repeat(len);
203
- return str[0] + "*".repeat(len - 2) + str[len - 1];
204
- };
205
- const hideThird = (str) => {
206
- if (!isDef(str)) return "";
207
- const len = str.length;
208
- if (len <= 2) return "*".repeat(len);
209
- const partLen = Math.round(len / 3);
210
- return str.slice(0, partLen) + "*".repeat(len - 2 * partLen) + str.slice(len - partLen);
211
- };
212
- const hideHead = (str, count) => {
213
- if (!isDef(str)) return "";
214
- const len = str.length;
215
- if (len <= 1) return "*".repeat(len);
216
- const cnt = count !== void 0 ? Math.max(Math.min(len, count), 0) : len - 1;
217
- return "*".repeat(cnt) + str.substring(cnt);
218
- };
219
- const hideTail = (str, count) => {
220
- if (!isDef(str)) return "";
221
- const len = str.length;
222
- if (len <= 1) return "*".repeat(len);
223
- const cnt = count !== void 0 ? Math.max(Math.min(len, count), 0) : len - 1;
224
- return str.substring(0, len - cnt) + "*".repeat(cnt);
225
- };
226
- const hidePhone = (phone) => {
227
- if (phone) {
228
- const phoneStr = phone.replaceAll(" ", "");
229
- if (isPhone(phoneStr)) {
230
- return phoneStr.replace(/^(\d{3})\d{4}(\d{4})$/, "$1****$2");
231
- }
232
- if (cnTelRE.test(phoneStr)) {
233
- return phoneStr.replace(/^(0\d{2,3})-?\d{3,4}(\d{4})$/, "$1****$2");
234
- }
235
- if (cnTelRE2.test(phoneStr)) {
236
- return phoneStr.replace(/^\((0\d{2,3})\)\d{3,4}(\d{4})$/, "$1****$2");
237
- }
238
- return phone;
239
- }
240
- return "";
241
- };
242
- const hideCardNo = (cardNo, strong = true) => {
243
- if (cardNo) {
244
- if (isIdCard(cardNo, false)) {
245
- return strong ? hideMiddle(cardNo) : cardNo.replace(/^(.)\d{3}(.{8})\d{5}(.)$/, "$1***$2*****$3");
246
- }
247
- return cardNo;
248
- }
249
- return "";
250
- };
251
- const hideSurname = (name) => {
252
- return hideHead(name, 1);
253
- };
254
- const hideFirstName = (name) => {
255
- return hideTail(name);
256
- };
257
- const hideEmail = (email) => {
258
- if (email) {
259
- if (!email.includes("@")) return email;
260
- const arr = email.split("@");
261
- const name = arr[0];
262
- const domain = arr[1];
263
- if (!name || !domain) return email;
264
- const len = name.length;
265
- let newName;
266
- if (len <= 3) {
267
- newName = `${name}***`;
268
- } else {
269
- newName = hideTail(name, 3);
270
- }
271
- return `${newName}@${domain}`;
272
- }
273
- return "";
274
- };
275
- const hideBankCard = (bankCard) => {
276
- if (bankCard) {
277
- const len = bankCard.length;
278
- if (len <= 10) return bankCard;
279
- return bankCard.substring(0, 6) + "*".repeat(len - 10) + bankCard.substring(len - 4, len);
280
- }
281
- return "";
282
- };
283
-
284
- let __BASE_ATTACH_URL__;
285
- function setBaseAttachUrl(baseUrl) {
286
- __BASE_ATTACH_URL__ = baseUrl;
287
- }
288
- function getBaseAttachUrl() {
289
- return __BASE_ATTACH_URL__;
290
- }
291
-
292
- function parseToJSON(str, reviverFn) {
293
- return isJSONStr(str) ? JSON.parse(str, reviverFn) : null;
294
- }
295
- function parseJSON(str, reviverFn = reviver) {
296
- return isJSONStr(str) ? JSON.parse(str, reviverFn) : null;
297
- }
298
- function stringifyJSON(value, replacerFn = replacer) {
299
- return JSON.stringify(value, replacerFn);
300
- }
301
- function replacer(_key, value) {
302
- if (isMap(value)) {
303
- return {
304
- dataType: "Map",
305
- value: [...value]
306
- };
307
- }
308
- if (isSet(value)) {
309
- return {
310
- dataType: "Set",
311
- value: [...value]
312
- };
313
- }
314
- if (isDate(value)) {
315
- return {
316
- dataType: "Date",
317
- value: value.toISOString()
318
- };
319
- }
320
- return value;
321
- }
322
- function reviver(_key, value) {
323
- if (typeof value === "object" && value !== null) {
324
- if (value.dataType === "Map") {
325
- return new Map(value.value);
326
- }
327
- if (value.dataType === "Set") {
328
- return new Set(value.value);
329
- }
330
- if (value.dataType === "Date") {
331
- return new Date(value.value);
332
- }
333
- }
334
- return value;
335
- }
336
- const filterObj = (obj, keys, reverse = false) => Object.fromEntries(Object.entries(obj).filter(([key]) => reverse ? !keys.includes(key) : keys.includes(key)));
337
-
338
- const toThousands = (num) => {
339
- const arr = num.toString().split(".");
340
- const integer = arr[0]?.replace(/(\d)(?=(?:\d{3})+$)/g, "$1,");
341
- if (arr.length > 1) return `${integer}.${arr[1]}`;
342
- return integer;
343
- };
344
- const currencyFmt = (currency, maximumFractionDigits = 2) => {
345
- if (!isDef(currency)) return "";
346
- const num = Number(currency);
347
- if (Number.isNaN(num)) return "";
348
- return new Intl.NumberFormat("zh-CN", { style: "currency", currency: "CNY", maximumFractionDigits }).format(num);
349
- };
350
-
351
- dayjs.extend(localeData).locale("zh-cn", zhCN);
352
- dayjs.extend(duration);
353
- dayjs.extend(relativeTime);
354
- dayjs.extend(customParseFormat);
355
- dayjs.extend(objectSupport);
356
- const dateFmt = (date, format = "YYYY-MM-DD HH:mm:ss") => {
357
- const dd = dayjs(date);
358
- let fmt = format;
359
- if (!isDef(date) || !dd.isValid()) return "";
360
- if (format === "date") fmt = "YYYY-MM-DD";
361
- if (format === "datetime") fmt = "YYYY-MM-DD HH:mm:ss";
362
- return dd.format(fmt);
363
- };
364
- const dateDuration = (start, end) => {
365
- const startDay = dayjs(start);
366
- const endDay = dayjs(end);
367
- if (!isDef(start) || !startDay.isValid() || !isDef(end) || !endDay.isValid()) return "";
368
- const dd = dayjs.duration(endDay.diff(startDay));
369
- const year = dd.years();
370
- const month = dd.months();
371
- const day = dd.days();
372
- const format = [
373
- year === 0 ? "" : "Y\u5E74",
374
- month === 0 ? "" : "M\u4E2A\u6708",
375
- day === 0 ? "" : `${day < 10 && (year !== 0 || month !== 0) ? "\u96F6" : ""}D\u5929`
376
- ].join("");
377
- return dd.format(format);
378
- };
379
-
380
- const resUrl = (url) => {
381
- if (!isDef(url)) return void 0;
382
- if (/^https?:\/\//.test(url) || url.startsWith("blob:") || url.startsWith("data:")) {
383
- return url;
384
- }
385
- const baseUrl = getBaseAttachUrl();
386
- if (!isDef(baseUrl)) {
387
- throw new Error("\u8BF7\u5148\u4F7F\u7528 setBaseAttachUrl \u8BBE\u7F6E\u6587\u4EF6\u57FA\u672C\u8DEF\u5F84");
388
- }
389
- return `${baseUrl}/${url}`.replace(/([^:]\/)\/+/g, "$1");
390
- };
391
- const recoverFile = (resource) => {
392
- const { uri, url, ...item } = resource;
393
- const validUrl = uri || url;
394
- return {
395
- ...item,
396
- url: resUrl(validUrl),
397
- content: resUrl(validUrl),
398
- uri: validUrl || "",
399
- status: "done",
400
- percent: 100
401
- };
402
- };
403
- const attachFmt = (data) => {
404
- let attachList = [];
405
- const prototype = Object.prototype.toString.call(data);
406
- if (!data) {
407
- attachList = [];
408
- } else if (Array.isArray(data)) {
409
- attachList = data.filter(Boolean);
410
- } else if (typeof data === "string") {
411
- if (isArrStr(data)) {
412
- attachList = (parseJSON(data) || []).filter(Boolean);
413
- } else {
414
- const jsonData = parseJSON(data);
415
- const prototypeJson = Object.prototype.toString.call(jsonData);
416
- if (prototypeJson === "[object Object]") attachList = [jsonData].filter(Boolean);
417
- else attachList = [{ id: data, name: "name", uri: data, group: "default" }];
418
- }
419
- } else if (prototype === "[object Object]") {
420
- attachList = [data];
421
- }
422
- return attachList.map(recoverFile);
423
- };
424
-
425
- const isNumberArray = (arr) => arr.every((item) => typeof item === "number");
426
- const isStringArray = (arr) => arr.every((item) => typeof item === "string");
427
- const naturalSort = (arr) => {
428
- if (isNumberArray(arr)) return [...arr].sort((a, b) => a - b);
429
- if (isStringArray(arr)) {
430
- return [...arr].sort((a, b) => a.localeCompare(b, "zh-CN")).sort((a, b) => a.length - b.length);
431
- }
432
- const newArr = [...arr].sort();
433
- const validArr = newArr.filter((a) => isDef(a));
434
- const invalidArr = newArr.filter((a) => !isDef(a));
435
- return naturalSort(validArr).concat(invalidArr);
436
- };
437
- const naturalSortBy = (arr, key) => {
438
- return [...arr].sort((a, b) => naturalSort([a[key], b[key]])[0] === a[key] ? -1 : 1);
439
- };
440
-
441
- const inBrowser = typeof window !== "undefined";
442
- const waitTime = (time = 100) => {
443
- return new Promise((resolve) => {
444
- setTimeout(() => {
445
- resolve(true);
446
- }, time);
447
- });
448
- };
449
- const fixiOSInputAutoZoomIn = () => {
450
- if (CSS.supports("(font:-apple-system-body) and (-webkit-touch-callout:none) and (-webkit-tap-highlight-color:hotpink)")) {
451
- const viewport = document.querySelector('meta[name="viewport"]');
452
- if (viewport !== null) {
453
- viewport.content = `${viewport.content}, user-scalable=no`;
454
- }
455
- }
456
- };
457
- const userAgent = inBrowser ? window.navigator.userAgent : "";
458
- const getHostEnv = () => {
459
- const ua = userAgent.toLowerCase();
460
- const zlb = ua.includes("@zlb");
461
- const zyd = ua.includes("saas");
462
- const zzd = ua.includes("zhejiang") || ua.includes("tauruszjd") || ua.includes("dingtalk-win");
463
- const dd = ua.includes("taurusapp");
464
- const wx = ua.includes("micromessenger");
465
- const zfb = ua.includes("alipay");
466
- const mini = ua.includes("miniprogram");
467
- const info = {
468
- zlb,
469
- zyd,
470
- zzd,
471
- dd,
472
- wx,
473
- zfb,
474
- mini
475
- };
476
- return info;
477
- };
478
- const XOR_VAL = 1111;
479
- const getCodeOfTime = (time) => Math.abs(new Date(time).getTime() ^ XOR_VAL);
480
- const getCodeOfHour = () => getCodeOfTime(`${dateFmt(/* @__PURE__ */ new Date(), "YYYY-MM-DD HH")}:00:00`);
481
- const getCodeOfDate = () => getCodeOfTime(dateFmt(/* @__PURE__ */ new Date(), "date"));
482
- const getCodeOfMonth = () => getCodeOfTime(dateFmt(dayjs().endOf("month"), "date"));
483
-
484
- export { attachFmt, camel2Kebab, camel2Pascal, camel2Snake, camel2Title, checkImg, cnIdCard15Re, cnIdCard18Re, cnPhoneRE, cnTelRE, cnTelRE2, cnUSCIRE, currencyFmt, dateDuration, dateFmt, emailRE, filterObj, fixiOSInputAutoZoomIn, getBaseAttachUrl, getCodeOfDate, getCodeOfHour, getCodeOfMonth, getHostEnv, getVariableType, hideBankCard, hideCardNo, hideEmail, hideFirstName, hideHead, hideMiddle, hidePhone, hideSurname, hideTail, hideThird, inBrowser, isArrStr, isArray, isBigInt, isBlob, isBoolean, isDate, isDef, isEmail, isEmpty, isError, isFile, isFunction, isIdCard, isJSONStr, isMap, isNull, isNumber, isNumeric, isObject, isPhone, isPromise, isRegExp, isSet, isString, isSymbol, isTel, isURL, isUSCI, isUndefined, isValidArrRes, isValidFileType, isValidKey, isValidPageRes, isValidRes, isValidResCode, isWeakMap, isWeakSet, jClear, jDebug, jError, jGroup, jGroupC, jGroupE, jInfo, jLog, jLogDedupe, jLogOnce, jTime, jTimeEnd, jWarn, kebab2Camel, kebab2Pascal, kebab2Snake, kebab2Title, naturalSort, naturalSortBy, nonASCII, parseJSON, parseToJSON, pascal2Camel, pascal2Kebab, pascal2Snake, pascal2Title, recoverFile, replacer, resUrl, reviver, setBaseAttachUrl, snake2Camel, snake2Kebab, snake2Pascal, snake2Title, stringifyJSON, title2Camel, title2Kebab, title2Pascal, title2Snake, toThousands, userAgent, waitTime };