js-cool
Version:
Collection of common JavaScript / TypeScript utilities
1,613 lines (1,560 loc) • 122 kB
JavaScript
/*!
* js-cool v5.23.1
* Collection of common JavaScript / TypeScript utilities
* (c) 2021-2025 saqqdy
* Released under the MIT License.
*/
var jsCool = (function () {
'use strict';
/**
* Save the file
*
* @private
* @param data - file data
* @param filename - the name of the file
*/
function saveFile(data, filename) {
var urlObject = window.URL || window.webkitURL || window;
var blob = new Blob([data]);
var link = document.createElementNS('http://www.w3.org/1999/xhtml', 'a');
link.href = urlObject.createObjectURL(blob);
link.download = filename;
link.click();
}
/**
* Download secondary system documents
*
* @private
* @param url - link
* @param filename - the name of the file
*/
function downloadUrlFile(url, filename) {
var xhr = window.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject('Microsoft.XMLHTTP');
xhr.open('GET', url, true);
xhr.responseType = 'blob';
xhr.onload = function () {
if (xhr.status === 200) {
saveFile(xhr.response, filename);
}
};
xhr.send();
}
/**
* New tab to download files
*
* @private
* @param url - link
* @param filename - the name of the file
*/
function openFile(url, filename, fileType) {
var dom = document.createElement('a');
// if (['pdf', 'txt'].includes(fileType)) console.log('is pdf')
dom.style.display = 'none';
dom.download = filename;
dom.href = url;
document.body.appendChild(dom);
dom.click();
document.body.removeChild(dom);
}
/**
* Several ways of file downloading:
* 1. For file formats that some browsers do not recognize. Enter the file URL in the address bar, window.location.href = URL, window.open(URL);
* 2. using a tag download attribute (or js create a tag);
* 3. browser-recognizable pdf, txt files, back-end compatible with handling attachment;
* 4. add token in the header for authenticated download, use XmlHttpRequest to want to backend to launch the request
*
* @param url - link
* @param filename - filename
* @param type - download type 'href','open','download','request'
*/
function download(url, filename, type) {
var _a, _b;
if (type === undefined) {
type = 'download';
}
var name = ((_a = /[^\/]+$/.exec(url)) === null || _a === undefined ? undefined : _a[0]) || '';
(_b = /[^\.]+$/.exec(name)) === null || _b === undefined ? undefined : _b[0].toLowerCase();
if (type === 'open') {
window.open(url);
} else if (type === 'href') {
window.location.href = url;
} else if (type === 'request') {
downloadUrlFile(url, filename || name);
} else {
openFile(url, filename || name);
}
}
/**
* The client method returns a browser judgment result: `{ ANDROID: true, GECKO: true, GLSH_APP: false, IE: false, IOS: false, IPAD: false, IPHONE: false, MOBILE: true, MOBILEDEVICE. true, OPERA: false, QQ: false, QQBROWSER: false, TRIDENT: false, WEBKIT: true, WEIXIN: false }`
*
* @deprecated Will be refactored for the next major release
* @since 1.0.1
* @param name - optional, e.g. pass in MicroMessenger to return whether it is the built-in browser of Weixin
* @param userAgent - optional, pass in a custom ua, default takes the browser's navigator.userAgent
* @returns - the common ua match table, if name is passed, then returns whether the terminal matches true/false
*/
var client = function client(name, userAgent) {
if (name === undefined) {
name = '';
}
if (userAgent === undefined) {
userAgent = navigator.userAgent;
}
var userAgentL = userAgent.toLowerCase();
if (name) {
return userAgent.includes(name);
} else {
return {
IE: userAgentL.includes('msie') && !userAgentL.includes('opera'),
GECKO: userAgentL.includes('gecko') && !userAgentL.includes('khtml'),
// firefox
WEBKIT: userAgentL.includes('applewebkit'),
// safari/chrome
OPERA: userAgentL.includes('opera') && userAgentL.includes('presto'),
// opera
TRIDENT: userAgentL.includes('trident'),
// IE
MOBILE: !!userAgent.match(/AppleWebKit.*Mobile.*/),
// MOBILEDEVICE: !!userAgentL.match(/iphone|android|phone|mobile|wap|netfront|x11|java|opera mobi|opera mini|ucweb|windows ce|symbian|symbianos|series|webos|sony|blackberry|dopod|nokia|samsung|palmsource|xda|pieplus|meizu|midp|cldc|motorola|foma|docomo|up.browser|up.link|blazer|helio|hosin|huawei|novarra|coolpad|webos|techfaith|palmsource|alcatel|amoi|ktouch|nexian|ericsson|philips|sagem|wellcom|bunjalloo|maui|smartphone|iemobile|spice|bird|zte-|longcos|pantech|gionee|portalmmm|jig browser|hiptop|benq|haier|^lct|320x320|240x320|176x220/i),
IOS: !!userAgent.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/),
// ios
ANDROID: userAgent.includes('Android') || userAgent.includes('Adr'),
// android or uc browser
IPHONE: userAgent.includes('iPhone'),
// iPhone or QQ HD browser
IPAD: userAgent.includes('iPad'),
// iPad
// WEBAPP: !userAgent.indexOf('Safari') > -1, // webapp
QQBROWSER: userAgent.includes('QQBrowser'),
// QQ browser
WEIXIN: userAgent.includes('MicroMessenger'),
// weixin
QQ: userAgent.match(/\sQQ/i) // QQ
};
}
};
/**
* Collection of common regular expressions
*
* @deprecated It will be refactored and renamed patterns in the next major release.
* @since 1.0.1
* @returns - object
*/
var pattern = {
any: /[\w\W]+/,
number: /^(\-|\+)?(0|[1-9]\d*)(\.\d+)?$/,
string: /^[\u4E00-\u9FA5\uF900-\uFA2D\w\.\s]+$/,
postcode: /^[0-9]{6}$/,
url: /^(\w+:\/\/)?\w+(\.\w+)+.*$/,
username: /^[a-zA-Z0-9\_\-\.]{3,15}$/,
float: /^[0-9]+\.{0,1}[0-9]{0,2}$/,
email: /^([a-zA-Z0-9]+[_|\_|\.]?)*[a-zA-Z0-9]+@([a-zA-Z0-9]+[_|\_|\.]?)*[a-zA-Z0-9]+\.[a-zA-Z]{2,3}$/,
// mobile:/^(13[0-9]|14[5|7]|15[0|1|2|3|5|6|7|8|9]|17[6|7|8]|18[0-9])\d{8}$/,
// mobile:/^13[0-9]{9}$|14[0-9]{9}|15[0-9]{9}$|18[0-9]{9}$/,
mobile: /^1[3|4|5|7|8][0-9]\d{8,8}$/,
chinese: /^[\u4E00-\u9FA5\uF900-\uFA2D]$/,
tel: /^(([0\+]\d{2,3}-)?(0\d{2,3})-)?(\d{7,8})(-(\d{3,}))?$/,
qq: /^[1-9][0-9]{5,13}$/,
pass: /^(?![0-9\W\_]+$)(?![a-zA-Z\W\_]+$)[0-9a-zA-Z\W\_]{6,16}$/,
json: /^\{[\s\S]*\}$/,
arrjson: /^\[\{[\s\S]*\}\]$/,
array: /^\[[\s\S]*\]$/,
isjson: /[\s\S]*(\{[\s\S]*\})[\s\S]*/,
textarea: /[\u4E00-\u9FA5_a-zA-Z0-9\,\.\/\?\;\:\'\"\[\]\-\*\(\)\(\)\%\$\@\\\!\,\《\》\。\、\?\;\:\‘\’\“\”\…\¥\!]/,
mac: /^((([a-f0-9]{2}:){5})|(([a-f0-9]{2}-){5}))[a-f0-9]{2}$/i,
ip4: /^(([1-9]?\d|1\d{2}|2[0-4]\d|25[0-5]).){3}([1-9]?\d|1\d{2}|2[0-4]\d|25[0-5])$/,
ip4_pri: /^1(((0|27)(.(([1-9]?|1[0-9])[0-9]|2([0-4][0-9]|5[0-5])))|(72.(1[6-9]|2[0-9]|3[01])|92.168))(.(([1-9]?|1[0-9])[0-9]|2([0-4][0-9]|5[0-5]))){2})$/
};
/**
* Remove leading and trailing spaces from strings
*
* @deprecated will be removed in the next major release.
* @since 1.0.1
* @param string - pass in the string
* @returns - the new string
*/
function trim(string) {
return string.replace(/(^\s+)|(\s+$)/g, '');
}
/**
* Remove all attributes of HTML tags
*
* @since 1.0.1
* @param string - pass in the string
* @returns newString
*/
function clearAttr(string) {
return string.replace(/<([a-zA-Z1-7]+)\s*[^><]*>/g, '<$1>');
}
/**
* Removing HTML tags
*
* @since 1.0.1
* @param string - string with html tags
* @returns newString
*/
function clearHtml(string) {
return string.replace(/<\/?.+?>/g, '').replace(/[\r\n]/g, '');
}
/**
* Escaping HTML Special Characters
*
* @example
* ```js
* escape('<div>test<br />string</div>')
* // '<div>test<br />string</div>'
* ```
* @since 5.5.0
* @param string - string with html tags
* @returns - newString
*/
function escape(string) {
var map = {
'&': '&',
'<': '<',
'>': '>',
'"': '"',
"'": '''
};
return string.replace(/[&<>"']/g, function (m) {
return map[m];
});
}
/**
* Restore HTML Special Characters
*
* @example
* ```js
* unescape('<div>test<br />string</div>')
* // '<div>test<br />string</div>'
* ```
* @since 5.5.0
* @param string - string
* @returns - newString
*/
function unescape(string) {
var map = {
'&': '&',
'<': '<',
'>': '>',
'"': '"',
''': "'"
};
return string.replace(/&|<|>|"|'/g, function (m) {
return map[m];
});
}
/**
* Get the number in the string
*
* @example
* ```js
* getNumber('Chrome123.33')
* // '123.33'.
*
* getNumber('234test.88')
* // '234.88'.
* ```
* @since 1.0.1
* @param string - pass in a string with a number
* @returns - a pure numeric string
*/
function getNumber(string) {
return string.replace(/[^0-9.]/gi, '');
}
/**
* Converts humped strings to -spaced and all lowercase Dash pattern
*
* @since 1.0.1
* @param string - the string to be converted
* @returns - the converted string
*/
function camel2Dash(string) {
return string.replace(/([A-Z]{1,1})/g, '-$1').replace(/^-/, '').toLocaleLowerCase();
}
/**
* Converts -spaced and all lowercase Dash patterns to humped strings
*
* @since 1.0.1
* @param string - the string to be converted
* @returns - the converted string
*/
function dash2Camel(string) {
return string.replace(/[\-]{1,1}([a-z]{1,1})/g, function () {
// eslint-disable-next-line prefer-rest-params
return arguments[1].toLocaleUpperCase();
});
}
/**
* First letter capitalized
*
* @example
* ```js
* upperFirst('saqqdy') // Saqqdy
* ```
* @since 1.0.1
* @param string - the string to be converted
* @returns - the converted string
*/
function upperFirst(string) {
return string.slice(0, 1).toLocaleUpperCase() + string.slice(1);
}
function _typeof(o) {
"@babel/helpers - typeof";
return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) {
return typeof o;
} : function (o) {
return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o;
}, _typeof(o);
}
var _assign = function __assign() {
_assign = Object.assign || function __assign(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
}
return t;
};
return _assign.apply(this, arguments);
};
function __values(o) {
var s = typeof Symbol === "function" && Symbol.iterator,
m = s && o[s],
i = 0;
if (m) return m.call(o);
if (o && typeof o.length === "number") return {
next: function next() {
if (o && i >= o.length) o = undefined;
return {
value: o && o[i++],
done: !o
};
}
};
throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
}
function __read(o, n) {
var m = typeof Symbol === "function" && o[Symbol.iterator];
if (!m) return o;
var i = m.call(o),
r,
ar = [],
e;
try {
while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
} catch (error) {
e = {
error: error
};
} finally {
try {
if (r && !r.done && (m = i["return"])) m.call(i);
} finally {
if (e) throw e.error;
}
}
return ar;
}
function __spreadArray(to, from, pack) {
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
if (ar || !(i in from)) {
if (!ar) ar = Array.prototype.slice.call(from, 0, i);
ar[i] = from[i];
}
}
return to.concat(ar || Array.prototype.slice.call(from));
}
typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
var e = new Error(message);
return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
};
/**
* Get a random integer
*
* @example
* ```js
* randomNumber()
* // 8
*
* randomNumber(0.1, 0.9)
* // 0.8
* ```
* @since 5.0.0
* @param min - the minimum value of the random number
* @param max - the maximum value of the random number
* @returns - random number
*/
function randomNumber(min, max) {
if (min === undefined) {
min = 1;
}
if (max === undefined) {
max = 10;
}
return min + Math.round(Math.random() * (max - min));
}
/**
* Generate random hexadecimal colors
*
* @example
* ```js
* randomColor()
* // #bf444b
*
* randomColor(200)
* // #d6e9d7
*
* randomColor(200, 255)
* // #d3f9e4
*
* randomColor([0, 0, 0], [255, 255, 255])
* // #d6e9d7
* ```
* @since 5.5.0
* @param min - the minimum value of the random numbers, eg: [10, 10, 10]
* @param max - the maximum value of the random number, eg: [255, 255, 255]
* @returns - result
*/
function randomColor(min, max) {
var _a, _b;
if (!max && !min && min !== 0) return "#".concat(Math.random().toString(16).slice(2, 8).padEnd(6, '0'));
var min1, min2, min3, max1, max2, max3;
if (!min) min1 = min2 = min3 = 0;else if (typeof min === 'number') min1 = min2 = min3 = min;else _a = __read(min, 3), min1 = _a[0], min2 = _a[1], min3 = _a[2];
if (!max) max1 = max2 = max3 = 255;else if (typeof max === 'number') max1 = max2 = max3 = max;else _b = __read(max, 3), max1 = _b[0], max2 = _b[1], max3 = _b[2];
return "#".concat(randomNumber(min1, max1).toString(16).padStart(2, '0')).concat(randomNumber(min2, max2).toString(16).padStart(2, '0')).concat(randomNumber(min3, max3).toString(16).padStart(2, '0'));
}
function shuffle(value, size) {
var index = -1,
isString = false;
if (typeof value === 'string') {
value = value.split('');
isString = true;
}
// value = value.sort(() => 0.5 - Math.random())
var length = value.length;
var lastIndex = length - 1;
size = size === undefined ? length : size;
while (++index < size) {
var rand = index + Math.floor(Math.random() * (lastIndex - index + 1));
var _val = value[rand];
value[rand] = value[index];
value[index] = _val;
}
value.length = size;
return isString ? value.join('') : value;
}
/**
* Generate n random integers that sum to a fixed sum
*
* @example
* ```js
* randomNumbers()
* // [8]
*
* randomNumbers(4, 5)
* // [1, 1, 2, 1]
*
* randomNumbers(4, 5, false)
* // [0, 1, 2, 2]
* ```
* @since 5.4.0
* @param n - Number of generated integers, default: 1
* @param sum - Sum of generated integers, default: 100
* @param max - Generate integers that are not zero, default: true
* @returns - numbers
*/
function randomNumbers(n, sum, noZero) {
n !== null && n !== undefined ? n : n = 1;
sum !== null && sum !== undefined ? sum : sum = 100;
noZero !== null && noZero !== undefined ? noZero : noZero = true;
if (noZero && sum < n) throw new Error('When "noZero" is true, "sum" cannot be less than "n"');
var _reached = 0;
// const _max = noZero ? Math.round(sum / n) : Math.ceil(sum / n)
var _max = Math.round(sum / n);
var numbers = [];
while (--n > 0) {
var num = randomNumber(noZero ? 1 : 0, _max);
_reached += num;
numbers.push(num);
}
numbers.push(sum - _reached);
return shuffle(numbers);
}
function randomString(len, options) {
var _a, _b, _c;
var charTypes = ['uppercase', 'lowercase', 'number'],
noConfuse = false,
strict = false,
result = '';
if (typeof len !== 'number') {
options = len;
len = _typeof(options) === 'object' ? (_a = options.length) !== null && _a !== undefined ? _a : 32 : 32; // default
}
if (typeof options === 'boolean') {
if (options) charTypes.push('special');
} else if (options) {
options.charTypes && options.charTypes.length && (charTypes = [].concat(options.charTypes));
noConfuse = (_b = options.noConfuse) !== null && _b !== undefined ? _b : noConfuse;
strict = (_c = options.strict) !== null && _c !== undefined ? _c : strict;
}
var chars = {
uppercase: noConfuse ? 'ABCDEFGHJKMNPQRSTWXYZ' : 'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
lowercase: noConfuse ? 'abcdefghjkmnpqrstwxyz' : 'abcdefghijklmnopqrstuvwxyz',
number: noConfuse ? '2345678' : '0123456789',
special: '~!@#$%^&*_+|:-=[];,.' // '~!@#$%^&*()_+{}|:"<>?`-=[]\\;\',./'
};
if (!strict) return generateString(len, charTypes.map(function (charType) {
return chars[charType];
}).join(''));
var charLengths = randomNumbers(charTypes.length, len);
charTypes.forEach(function (charType, index) {
result += generateString(charLengths[index], chars[charType]);
});
return shuffle(result);
}
/**
* generate string
*
* @param len - string length
* @param chars - chars
* @returns - result
*/
function generateString(len, chars) {
var str = '';
var _maxPos = chars.length;
for (var i = 0; i < len; i++) {
str += chars.charAt(Math.floor(Math.random() * _maxPos));
}
return str;
}
/**
* Determine if it is running on the browser side
*
* @since 4.5.0
* @returns boolean
*/
var inBrowser = typeof window !== 'undefined';
/**
* Generating Browser Fingerprints
*
* @since 5.2.0
* @param domain - key string, default: location.host
* @returns - fingerprint
*/
function fingerprint(domain) {
if (!inBrowser) return null;
if (!domain) domain = location.host;
function bin2hex(s) {
var i,
l,
n,
o = '';
s += '';
for (i = 0, l = s.length; i < l; i++) {
n = s.charCodeAt(i).toString(16);
o += n.length < 2 ? '0' + n : n;
}
return o;
}
var canvas = document.createElement('canvas');
var ctx = canvas.getContext('2d');
ctx.textBaseline = 'top';
ctx.font = "14px 'Arial'";
ctx.fillStyle = '#f60';
ctx.fillRect(125, 1, 62, 20);
ctx.fillStyle = '#069';
ctx.fillText(domain, 2, 15);
ctx.fillStyle = 'rgba(102, 204, 0, 0.7)';
ctx.fillText(domain, 4, 17);
var b64 = canvas.toDataURL().replace('data:image/png;base64,', '');
var bin = atob(b64);
var crc = bin2hex(bin.slice(-16, -12));
return crc;
}
/**
* Get the length of the text, Chinese counts as 2 bytes
*
* @example
* ```js
* getCHSLength('测试')
* // 2
* ```
* @since 1.0.1
* @param str - string
* @returns - length
*/
function getCHSLength(str) {
// eslint-disable-next-line no-control-regex
return str.replace(/[^\x00-\xFF]/g, '**').length;
}
/**
* Intercept string, Chinese counts as 2 bytes
*
* @since 1.0.1
* @param str - the string to be intercepted
* @param len -
* @param hasDot -
* @returns - the intercepted string
*/
function cutCHSString(str, len, hasDot) {
if (len === undefined) {
len = str.length;
}
if (hasDot === undefined) {
hasDot = false;
}
if (!str) return '';
var newLength = 0,
newStr = '',
singleChar = '';
// eslint-disable-next-line no-control-regex
var chineseRegex = /[^\x00-\xFF]/g;
var strLength = str.replace(chineseRegex, '**').length;
for (var i = 0; i < strLength; i++) {
singleChar = str.charAt(i).toString();
if (singleChar.match(chineseRegex) != null) {
newLength += 2;
} else {
newLength++;
}
if (newLength > len) {
break;
}
newStr += singleChar;
}
if (hasDot && strLength > len) {
newStr += '...';
}
return newStr;
}
/**
* Whether or not it is a string consisting of numbers
*
* @deprecated will be removed in the next major release.
* @since 1.0.1
* @param str - the string to be tested
* @returns - true/false
*/
function isDigitals(str) {
return /^[0-9]*$/.test(str);
}
/**
* eval alternative method
*
* return - Function | undefined
*/
function _eval(functionName) {
var Fn = Function;
try {
return new Fn('return ' + functionName)();
} catch (_a) {
return undefined;
}
}
/**
* The presence or absence of the specified function
*
* @example
* ```js
* isExitsFunction('test') // false
* isExitsFunction('console.log') // true
* ```
* @since 1.0.1
* @param name - incoming function name
* @returns - true/false
*/
function isExitsFunction(name) {
return typeof _eval(name) === 'function';
}
/**
* The presence or absence of the specified variable
*
* @example
* ```js
* isExitsVariable('test') // false
* isExitsVariable('window') // true
* ```
* @since 1.0.1
* @param name - variable name
* @returns - true/false
*/
function isExitsVariable(name) {
try {
if (typeof name === 'undefined') {
return false;
} else {
return true;
}
} catch (_a) {}
return false;
}
/**
* Determine if it is an array
*
* @example
* ```js
* isArray([]) // true
* ```
* @since 1.0.2
* @param target - any target
* @returns - target is Array
*/
function isArray(target) {
return Object.prototype.toString.call(target).includes('Array');
}
// @see https://underscorejs.org/#isEqual
// Internal recursive comparison function for `isEqual`.
var _eq = function eq(a, b, aStack, bStack) {
// Identical objects are equal. `0 === -0`, but they aren't identical.
// See the [Harmony `egal` proposal](http://wiki.ecmascript.org/doku.php?id=harmony:egal).
if (a === b) return a !== 0 || 1 / a === 1 / b;
// A strict comparison is necessary because `null == undefined`.
if (a == null || b == null) return a === b;
// Compare `[[Class]]` names.
var className = toString.call(a);
if (className !== toString.call(b)) return false;
switch (className) {
// Strings, numbers, regular expressions, dates, and booleans are compared by value.
case '[object RegExp]': // RegExps are coerced to strings for comparison (Note: '' + /a/i === '/a/i')
case '[object String]':
// Primitives and their corresponding object wrappers are equivalent; thus, `"5"` is
// equivalent to `new String("5")`.
return '' + a === '' + b;
case '[object Number]':
// `NaN`s are equivalent, but non-reflexive.
// Object(NaN) is equivalent to NaN
// eslint-disable-next-line no-self-compare
if (+a !== +a) return +b !== +b;
// An `egal` comparison is performed for other numeric values.
return +a === 0 ? 1 / +a === 1 / b : +a === +b;
case '[object Date]':
case '[object Boolean]':
// Coerce dates and booleans to numeric primitive values. Dates are compared by their
// millisecond representations. Note that invalid dates with millisecond representations
// of `NaN` are not equivalent.
return +a === +b;
}
var areArrays = isArray(a) && isArray(b);
if (!areArrays) {
if (_typeof(a) != 'object' || _typeof(b) != 'object') return false;
// Objects with different constructors are not equivalent, but `Object`s or `Array`s
// from different frames are.
var aCtor = a.constructor;
var bCtor = b.constructor;
if (aCtor !== bCtor && !(typeof aCtor === 'function' && aCtor instanceof aCtor && typeof bCtor === 'function' && bCtor instanceof bCtor) && 'constructor' in a && 'constructor' in b) {
return false;
}
}
// Assume equality for cyclic structures. The algorithm for detecting cyclic
// structures is adapted from ES 5.1 section 15.12.3, abstract operation `JO`.
// Initializing stack of traversed objects.
// It's done here since we only need them for objects and arrays comparison.
aStack = aStack || [];
bStack = bStack || [];
var length = aStack.length;
while (length--) {
// Linear search. Performance is inversely proportional to the number of
// unique nested structures.
if (aStack[length] === a) return bStack[length] === b;
}
// Add the first object to the stack of traversed objects.
aStack.push(a);
bStack.push(b);
// Recursively compare objects and arrays.
if (areArrays) {
// Compare array lengths to determine if a deep comparison is necessary.
length = a.length;
if (length !== b.length) return false;
// Deep compare the contents, ignoring non-numeric properties.
while (length--) {
if (!_eq(a[length], b[length], aStack, bStack)) return false;
}
} else {
// Deep compare objects.
var keys = Object.keys(a);
var key = undefined;
length = keys.length;
// Ensure that both objects contain the same number of properties before comparing deep equality.
if (Object.keys(b).length !== length) return false;
while (length--) {
// Deep compare each member
key = keys[length];
if (!(key in b && _eq(a[key], b[key], aStack, bStack))) return false;
}
}
// Remove the first object from the stack of traversed objects.
aStack.pop();
bStack.pop();
return true;
};
/**
* Determine if 2 objects are equal
*
* @example
* ```js
* isEqual({ a: 22, b: {} }, { b: {}, a: 22 })
* // true
*
* isEqual([1, 2], [2, 1])
* // false
*
* isEqual(NaN, NaN)
* // true
* ```
* @since 5.12.0
* @param a - source
* @param b - compare
* @returns - a equals to b
*/
function isEqual(a, b) {
return _eq(a, b);
}
/**
* Get the target type
*
* @since 1.0.2
* @param target - target
* @returns type
*/
function getType(target) {
var type = {
'[object Array]': 'array',
'[object Boolean]': 'boolean',
'[object Date]': 'date',
'[object Promise]': 'promise',
'[object Function]': 'function',
// Function | Class
'[object AsyncFunction]': 'function',
'[object GeneratorFunction]': 'function',
// Generator
'[object Math]': 'math',
// Math
'[object Window]': 'window',
// Window
'[object Navigator]': 'navigator',
// Navigator
'[object global]': 'global',
// global
'[object HTMLDocument]': 'document',
// document
'[object Symbol]': 'symbol',
'[object Number]': 'number',
'[object Object]': 'object',
// Object | Proxy
'[object RegExp]': 'regexp',
'[object String]': 'string',
'[object Undefined]': 'undefined',
'[object Null]': 'null',
'[object Error]': 'error'
};
if (target === null) return 'null';else if (_typeof(target) === 'object' || typeof target === 'function') return type[Object.prototype.toString.call(target)] || 'object';
return _typeof(target);
}
/**
* Determine if target is an object
*
* @example
* ```js
* isObject({}) // true
* ```
* @since 5.0.0
* @param target - any target
* @returns - target is Object
*/
function isObject(target) {
return target && getType(target) === 'object';
}
/**
* Determine if target is an window object
*
* @example
* ```js
* isWindow({}) // false
* isWindow(window) // true
* ```
* @since 5.0.0
* @param target - any
* @returns - target is Window
*/
function isWindow(target) {
return target && isObject(target) && target === target.window;
}
/**
* Determine if target is Date
*
* @example
* ```js
* const now = new Date()
*
* isDate(now)
* // true
* ```
* @since 5.15.0
* @param target - any target
* @returns - target is Date
*/
function isDate(target) {
return target && getType(target) === 'date';
}
/**
* Determine if target is RegExp
*
* @example
* ```js
* isRegExp(/\d/) // true
* ```
* @since 5.15.0
* @param target - any target
* @returns - target is RegExp
*/
function isRegExp(target) {
return target && getType(target) === 'regexp';
}
/**
* Determine if it is iterable
*
* @example
* ```js
* isIterable([]) // true
* ```
* @since 5.7.0
* @param target - any target
* @returns - target is Array
*/
function isIterable(target) {
if (target === null || target === undefined) return false;
// return typeof (target as Iterable<T>)[Symbol.iterator] === 'function'
return Symbol.iterator in target;
}
/**
* Determine if it is running on node.js
*
* @since 5.13.0
* @returns boolean
*/
var inNodeJs = typeof global !== 'undefined';
/**
* Detect if the client is a 360 browser
*
* @example
* ```js
* // 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.6261.95 Safari/537.36 QIHU 360EE'
* // true
*
* // 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.6261.95 Safari/537.36'
* // true
* ```
* @since 5.22.0
* @param userAgent - ua, allowed to be undefined, default takes navigator.userAgent
* @returns - result
*/
function isNumberBrowser(userAgent) {
if (!userAgent && !inBrowser) return false;
userAgent = userAgent || navigator.userAgent;
return isNumberBrowserByUserAgent(userAgent) || isNumberBrowserByDll('np-mswmp.dll') || isNumberBrowserByMimeTypes('type', 'application/vnd.chromium.remoting-viewer');
}
/**
* Detect if the client is a 360 browser by userAgent
*
* @since 5.22.0
* @param userAgent - ua, allowed to be undefined, default takes navigator.userAgent
* @returns - result
*/
function isNumberBrowserByUserAgent(userAgent) {
userAgent = userAgent || navigator.userAgent;
var ua = userAgent.toLowerCase();
if (ua.includes('360se') || ua.includes('360ee')) return true;else if (userAgent.includes('Safari') && ua.includes('wow64')) return true;
return false;
}
/**
* Detect if the client is a 360 browser by check dll file
*
* @since 5.22.0
* @param filename - file name
* @returns - result
*/
function isNumberBrowserByDll(filename) {
if (navigator.userAgent.includes('Safari')) {
for (var key in navigator.plugins) {
if (navigator.plugins[key].filename === filename) return true;
}
}
return false;
}
/**
* Detect if the client is a 360 browser by check mimeTypes
*
* @since 5.22.0
* @param option - mime option
* @param value - mime value
* @returns - result
*/
function isNumberBrowserByMimeTypes(option, value) {
var mimeTypes = navigator.mimeTypes;
for (var mt in mimeTypes) {
if (mimeTypes[mt][option] === value) return true;
}
return false;
}
/**
* windowSize to get the window size
*
* @example
* ```js
* windowSize() // { width: 1280, height: 800 }
* ```
* @since 1.0.1
* @returns - the width and height
*/
function windowSize() {
var s = {
width: 0,
height: 0
};
if (window.innerWidth) {
s.width = window.innerWidth;
s.height = window.innerHeight;
} else if (document.body && document.body.clientWidth) {
s.width = document.body.clientWidth;
s.height = document.body.clientHeight;
}
// Get the window size by going inside the Document to detect the body
if (document.documentElement && document.documentElement.clientWidth) {
s.width = document.documentElement.clientWidth;
s.height = document.documentElement.clientHeight;
}
return s;
}
/**
* Get the APP version number
*
* @deprecated please use 'appVersion' instead
* @since 1.0.1
* @param appName - app name
* @param withApp - whether to bring the name
* @param userAgent - ua, allowed to be undefined, default is navigator.userAgent
* @return null/true/false
*/
function getAppVersion(appName, withApp, userAgent) {
userAgent = userAgent || navigator.userAgent;
var reg = new RegExp(appName + '\\/([\\d\\.]+)', 'i');
var isApp = userAgent.includes(appName);
var ver = userAgent.match(reg);
// withApp = typeof(withApp) != "undefined" ? withApp : false;
if (ver) {
if (withApp) {
// Need to bring the app name, complete output
return ver ? ver[0] : '';
} else {
return ver ? ver[1] : '';
}
} else {
if (isApp) {
// is the specified client but the version number is unknown
return false;
} else {
// Not a designated client
return null;
}
}
}
function appVersion(appName, ua, ignoreCase) {
if (!appName || typeof appName !== 'string') {
console.info('appName is required');
return null;
} else if (typeof ua === 'boolean' || !ua) {
// us=undefined|true|false
if (!inBrowser) {
console.info('ua is required');
return null;
}
if (typeof ua === 'boolean') ignoreCase = ua;
ua = navigator.userAgent;
}
if (typeof ignoreCase !== 'boolean') ignoreCase = true;
var reg = new RegExp("".concat(appName, "/(\\d+(?:.\\d+)*(?:-\\w+.\\d+)*)"), ignoreCase ? 'i' : '');
var match = ua.match(reg);
return match ? match[1] : null;
}
/**
* Get the phone system version
*
* @example
* ```
* getOsVersion('iPhone')
* // '13.2.3'
*
* getOsVersion('iPhone', true)
* // 'iPhone/13.2.3'
* ```
* @deprecated please use 'osVersion' instead
* @since 1.0.1
* @param osName - system type string Android, iPod, iWatch or iPhone
* @param withOS - whether to bring the name
* @param userAgent - ua, allowed to be undefined, default takes navigator.userAgent
* @return - null/true/false
*/
function getOsVersion(osName, withOS, userAgent) {
userAgent = userAgent || navigator.userAgent;
var d = ['iPhone', 'iPad', 'iPod', 'iWatch', 'Mac', 'iMac', 'iOS'];
var name = osName,
ver;
var index = d.indexOf(osName);
if (index > -1 && userAgent.includes('like Mac OS X')) {
name = 'OS';
}
var reg = new RegExp(name + '\\s[\\d\\_]+', 'ig');
ver = (userAgent.match(reg) + '').replace(/\s/gi, '/').replace(/_/gi, '.');
if (index > -1) {
ver = ver.replace(/OS\//gi, osName + '/');
}
return getAppVersion(osName, withOS, ver);
}
/**
* Get the system name and version
*
* @example
* ```
* // ipad => 'Mozilla/5.0 (iPad; CPU OS 13_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) CriOS/87.0.4280.77 Mobile/15E148 Safari/604.1'
* osVersion() // \{ name: 'iOS', version: '13.3' \}
*
* // iphone => 'Mozilla/5.0 (iPhone; CPU iPhone OS 13_2_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0.3 Mobile/15E148 Safari/604.1'
* osVersion() // \{ name: 'iOS', version: '13.2.3' \}
*
* // mac os => 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36'
* osVersion() // \{ name: 'MacOS', version: '10.15.7' \}
*
* // windows => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36'
* osVersion() // \{ name: 'Windows', version: '10.0' \}
*
* // windows xp => 'Mozilla/5.0 (Windows NT 5.2; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36'
* osVersion() // \{ name: 'Windows', version: 'XP' \}
*
* // windows phone => 'Mozilla/5.0 (Windows Phone OS 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.82 Safari/537.36'
* osVersion() // \{ name: 'WindowsPhone', version: '10.0' \}
*
* ```
* @since 5.1.0
* @param ua - ua or any ua like string, allowed to be undefined, default is navigator.userAgent
* @return OsVersion|null
*/
function osVersion(ua) {
if (!ua) {
if (!inBrowser) {
console.info('url is required');
return null;
}
ua = navigator.userAgent;
}
ua = ua.toLowerCase();
var OS_REG_MAP = {
Windows: /windows nt\s+([\w.]+)/,
MacOS: /mac os x\s+([\w_]+)/,
Android: /android\s+([\d.]+)/,
iOS: /i(?:pad|phone|pod)(?:.*)cpu(?: i(?:pad|phone|pod))? os (\d+(?:[\.|_]\d+)+) like/,
WindowsPhone: /Windows Phone(?: OS)? ([\d.]+);/,
Debian: /Debian\/([\d.]+)/,
WebOS: /hpwOS\/([\d.]+);/,
Harmony: /openharmony\s+([\d.]+)/
};
var key;
for (key in OS_REG_MAP) {
var match = ua.match(OS_REG_MAP[key]);
if (!match) continue;else {
var version = (match[1] || '').replace(/_/g, '.');
if (key === 'Windows') {
var VERSION_MAP = {
'10': '10 || 11',
'6.3': '8.1',
'6.2': '8',
'6.1': '7',
'6.0': 'Vista',
'5.2': 'XP 64-Bit',
'5.1': 'XP',
'5.0': '2000',
'4.0': 'NT 4.0',
'3.5.1': 'NT 3.5.1',
'3.5': 'NT 3.5',
'3.1': 'NT 3.1'
};
version = VERSION_MAP[version] || version;
}
return {
name: key,
version: version
};
}
}
return null;
}
/**
* Get the browser name and version
*
* @example
* ```
* // Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) Ap…KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36
* browserVersion() // \{ name: 'Chrome', version: '114.0.0.0' \}
* ```
* @since 5.2.0
* @param ua - ua or any ua like string, allowed to be undefined, default is navigator.userAgent
* @return BrowserVersion|null
*/
function browserVersion(ua) {
if (!ua) {
if (!inBrowser) {
console.info('url is required');
return null;
}
ua = navigator.userAgent;
}
var BROWSER_REG_MAP = {
Safari: /Version\/([\d.]+)/,
Chrome: /(?:Chrome|CriOS)\/([\d.]+)/,
IE: /(?:MSIE |rv:)([\d.]+)/,
Edge: /Edge\/([\d.]+)/,
Firefox: /(?:Firefox|FxiOS)\/([\d.]+)/,
'Firefox Focus': /Focus\/([\d.]+)/,
Chromium: /Chromium\/([\d.]+)/,
Opera: /(?:Opera|OPR)\/([\d.]+)/,
Vivaldi: /Vivaldi\/([\d.]+)/,
Yandex: /YaBrowser\/([\d.]+)/,
Arora: /Arora\/([\d.]+)/,
Lunascape: /Lunascape[\/\s]([\d.]+)/,
QupZilla: /QupZilla[\/\s]([\d.]+)/,
'Coc Coc': /coc_coc_browser\/([\d.]+)/,
Kindle: /Version\/([\d.]+)/,
Iceweasel: /Iceweasel\/([\d.]+)/,
Konqueror: /Konqueror\/([\d.]+)/,
Iceape: /Iceape\/([\d.]+)/,
SeaMonkey: /SeaMonkey\/([\d.]+)/,
Epiphany: /Epiphany\/([\d.]+)/,
'360': /QihooBrowser\/([\d.]+)/,
'360SE': /Chrome\/([\d.]+)/,
'360EE': /Chrome\/([\d.]+)/,
Maxthon: /Maxthon\/([\d.]+)/,
QQBrowser: /QQBrowser\/([\d.]+)/,
QQ: /QQ\/([\d.]+)/,
Baidu: /BIDUBrowser[\s\/]([\d.]+)/,
UC: /UC?Browser\/([\d.]+)/,
Sogou: /(?:SE |SogouMobileBrowser\/)([\d.X]+)/,
Liebao: /(?:LieBaoFast|Chrome)\/([\d.]+)/,
LBBROWSER: /(?:LieBaoFast|Chrome)\/([\d.]+)/,
'2345Explorer': /2345Explorer\/([\d.]+)/,
'115Browser': /115Browser\/([\d.]+)/,
TheWorld: /TheWorld ([\d.]+)/,
XiaoMi: /MiuiBrowser\/([\d.]+)/,
Vivo: /VivoBrowser\/([\d.]+)/,
Quark: /Quark\/([\d.]+)/,
Qiyu: /Qiyu\/([\d.]+)/,
Wechat: /MicroMessenger\/([\d.]+)/,
WechatWork: /wxwork\/([\d.]+)/,
Taobao: /AliApp\(TB\/([\d.]+)/,
Alipay: /AliApp\(AP\/([\d.]+)/,
Weibo: /weibo__([\d.]+)/,
Douban: /com.douban.frodo\/([\d.]+)/,
Suning: /SNEBUY-APP([\d.]+)/,
iQiYi: /IqiyiVersion\/([\d.]+)/,
DingTalk: /DingTalk\/([\d.]+)/,
Huawei: /(?:Version|HuaweiBrowser|HBPC)\/([\d.]+)/
};
var key;
for (key in BROWSER_REG_MAP) {
var match = ua.match(BROWSER_REG_MAP[key]);
if (!match) continue;else {
var version = (match[1] || '').replace(/_/g, '.');
if (key === '360SE') {
var VERSION_MAP = {
'63': '10.0',
'55': '9.1',
'45': '8.1',
'42': '8.0',
'31': '7.0',
'21': '6.3'
};
version = VERSION_MAP[version] || version;
} else if (key === '360EE') {
var VERSION_MAP = {
'69': '11.0',
'63': '9.5',
'55': '9.0',
'50': '8.7',
'30': '7.5'
};
version = VERSION_MAP[version] || version;
} else if (['Liebao', 'LBBROWSER'].includes(key)) {
var VERSION_MAP = {
'57': '6.5',
'49': '6.0',
'46': '5.9',
'42': '5.3',
'39': '5.2',
'34': '5.0',
'29': '4.5',
'21': '4.0'
};
version = VERSION_MAP[version] || version;
}
return {
name: key,
version: version
};
}
}
return null;
}
/**
* Version number size comparison, tag version: rc \> beta \> alpha \> other
*
* @example
* ```js
* compareVersion('1.11.0', '1.9.9')
* // => 1: 1=Version 1.11.0 is newer than 1.9.9
*
* compareVersion('1.11.0', '1.11.0')
* // => 0: 0=Versions 1.11.0 and 1.11.0 are the same
*
* compareVersion('1.11.0', '1.99.0')
* // => -1: -1=Version 1.11.0 is older than 1.99.0
*
* compareVersion('1.0.0.0.0.10', '1.0')
* // => -1
*
* // compare tag version: rc > beta > alpha > other
* compareVersion('1.11.0', '1.11.0-beta.1')
* // => -1
*
* compareVersion('1.11.0-beta.1', '1.11.0')
* // => -1
*
* compareVersion('1.11.0-beta.10', '1.11.0-beta.10')
* // => 0
*
* compareVersion('1.11.0-alpha.10', '1.11.0-beta.1')
* // => -1
*
* compareVersion('1.11.0-alpha.10', '1.11.0-rc.1')
* // => -1
*
* compareVersion('1.11.0-tag.10', '1.11.0-alpha.1')
* // => -1
*
* compareVersion('1.11.0-tag.10', '1.11.0-tag.1')
* // => 1
*
* compareVersion('1.11.0-release.10', '1.11.0-tag.1')
* // => 1
* ```
* @since 4.7.0
* @param input - input version
* @param compare - compare version
* @return 1/0/-1
*/
function compareVersion(input, compare) {
var VER_TYPES = ['alpha', 'beta', 'rc'];
var _a = __read(input.split('-'), 2),
inputVer = _a[0],
_b = _a[1],
inputSubVer = _b === undefined ? '' : _b;
var _c = __read(compare.split('-'), 2),
compareVer = _c[0],
_d = _c[1],
compareSubVer = _d === undefined ? '' : _d;
var v1 = inputVer.split('.');
var v2 = compareVer.split('.');
var len = Math.max(v1.length, v2.length);
while (v1.length < len) {
v1.push('0');
}
while (v2.length < len) {
v2.push('0');
}
for (var i = 0; i < len; i++) {
var num1 = parseInt(v1[i]);
var num2 = parseInt(v2[i]);
if (num1 > num2) return 1;else if (num1 < num2) return -1;
}
if (!inputSubVer && !compareSubVer) return 0;else if (!compareSubVer) return -1;else if (!inputSubVer) return 1;
var inputSubArr = inputSubVer.split('.');
var compareSubArr = compareSubVer.split('.');
inputSubArr[0] = VER_TYPES.indexOf(inputSubArr[0]) + 1 + '';
compareSubArr[0] = VER_TYPES.indexOf(compareSubArr[0]) + 1 + '';
return compareVersion(inputSubArr.join('.'), compareSubArr.join('.'));
}
/**
* parse url params
*
* @example
* ```js
* parseUrlParam('?key1=100&key2=true&key3=null&key4=undefined&key5=NaN&key6=10.888&key7=Infinity&key8=test')
* // \{"key1":"100","key2":"true","key3":"null","key4":"undefined","key5":"NaN","key6":"10.888","key7":"Infinity","key8":"test"\}
*
* parseUrlParam('?key1=100&key2=true&key3=null&key4=undefined&key5=NaN&key6=10.888&key7=Infinity&key8=test', true)
* // \{"key1":100,"key2":true,"key3":null,"key5":NaN,"key6":10.888,"key7":Infinity,"key8":"test"\}
* ```
* @since 5.0.0
* @param url - url string (like: ?key1=value1&key2=value2)
* @param covert - Converts a specific string to a corresponding value (Scientific notation, binary, octal and hexadecimal types of data are not converted, like: 0b111, 0o13, 0xFF, 1e3, -1e-2)
* @returns object
*/
function parseUrlParam(url, covert) {
if (covert === undefined) {
covert = false;
}
if (!url) {
console.info('url is required');
return {};
}
url = url.substring(url.lastIndexOf('?') + 1); // delete string before "?"
var VALUE_MAP = {
null: null,
undefined: undefined,
true: true,
false: false,
NaN: NaN,
Infinity: Infinity,
'-Infinity': -Infinity
};
var result = {};
url.replace(/([^?&=]+)=([^?&=]*)/g, function (rs, $1, $2) {
var key = decodeURIComponent($1);
$2 = decodeURIComponent($2);
result[key] = $2;
if (covert) {
if ($2 in VALUE_MAP) result[key] = VALUE_MAP[$2];else if (pattern.number.test($2)) result[key] = Number($2);
}
return rs;
});
if (covert) return result;
return result;
}
/**
* splice url params
*
* @example
* ```js
* spliceUrlParam(\{"key1":"100","key2":true,"key3":null,"key4":undefined,"key5":"测试"\})
* // ?key1=100&key2=true&key3=null&key4=undefined&key5=测试
*
* spliceUrlParam(\{"key1":"100","key2":true,"key3":null,"key4":undefined,"key5":"测试"\}, \{ encode: true \})
* // ?key1=100&key2=true&key3=null&key4=undefined&key5=%E6%B5%8B%E8%AF%95
*
* spliceUrlParam(\{"key1":"100","key2":true,"key3":null,"key4":undefined\}, true)
* // ?key1=100&key2=true&key3=&key4=
*
* spliceUrlParam(\{"key1":"100","key2":true,"key3":null,"key4":undefined\}, \{ covert: true, withQuestionsMark: false \})
* // key1=100&key2=true&key3=&key4=
* ```
* @since 5.3.0
* @param params - json object
* @param covert - Convert a null value type (null/undefined/) to an empty string, default: false
* @returns - result
*/
function spliceUrlParam(params, covert) {
var _a, _b, _c, _d;
if (covert === undefined) {
covert = false;
}
if (!params) {
console.info('params is required');
return '';
}
var encode = false,
withQuestionsMark = true,
key;
if (_typeof(covert) === 'object') {
encode = (_a = covert.encode) !== null && _a !== undefined ? _a : false;
withQuestionsMark = (_b = covert.withQuestionsMark) !== null && _b !== undefined ? _b : true;
covert = (_c = covert.covert) !== null && _c !== undefined ? _c : false;
}
var result = [];
for (key in params) {
if (typeof key === 'string') {
var val = '' + (covert ? (_d = params[key]) !== null && _d !== undefined ? _d : '' : params[key]);
result.push("".concat(key, "=").concat(encode ? encodeURIComponent(val) : val));
}
}
if (withQuestionsMark) return '?' + result.join('&');
return result.join('&');
}
/**
* Secure parsing of JSON strings
*
* @example
* ```js
* safeParse('100')
* // 100
*
* safeParse('{"a":"undefined","b":"NaN","c":"Infinity","d":"9007199254740993"}')
* // { b: NaN, c: Infinity, d: 9007199254740993n }
* ```
* @param data - JSON string
* @param covert - Whether to convert data, default: true
* @returns - JSON Object
*/
function safeParse(data, covert) {
if (covert === undefined) {
covert = true;
}
var VALUE_MAP = {
undefined: undefined,
NaN: NaN,
Infinity: Infinity,
'-Infinity': -Infinity
};
return JSON.parse(data, function (key, val) {
if (covert && ['Infinity', '-Infinity', 'undefined', 'NaN'].includes(val)) return VALUE_MAP[val];else if (typeof val === 'string' && /^(\-|\+)?\d+(\.\d+)?$/.test(val) && !Number.isSafeInteger(+val)) return BigInt(val);
return val;
});
}
/**
* Secure stringify of JSON Object
*
* @example
* ```js
* safeStringify(100)
* // "100"
*
* safeStringify(undefined)
* // "undefined"
*
* safeStringify(NaN)
* // "NaN"
*
* safeStringify(Infinity)
* // "Infinity"
*
* safeStringify({ a: undefined, b: NaN, c: Infinity, d: BigInt(Number.MAX_SAFE_INTEGER) + 2n })
* // {"a":"undefined","b":"NaN","c":"Infinity","d":"9007199254740993"}
* ```
* @param data - JSON Object
* @param covert - Whether to convert data, default: true
* @returns - JSON String
*/
function safeStringify(data, covert) {
if (covert === undefined) {
covert = true;
}
return JSON.stringify(data, function (key, val) {
if (covert) {
if ([Infinity, -Infinity, undefined, NaN].includes(val)) return String(val);else if (typeof val === 'number' && !Number.isSafeInteger(val)) return String(BigInt(val));
} else if (typeof val === 'bigint') return String(val);
return val;
});
}
/**
* Get directory form URL parameters
*
* @deprecated It will be refactored and renamed getDirParams in the next major release.
* @since 1.0.1
* @param url - pass in the url address
* @returns - parameter object
*/
function getDirParam(url) {
var urlStr = url !== '' && typeof url !== 'undefined' ? url.replace(/^http[s]?:\/\/[^\/]+([\s\S]*)/, '$1') : location.pathname; // Get the string after the domain name in the url:/post/0703/a1.html
urlStr = urlStr.replace(/^\//, '');
var dirParam = {
path: [],
host: ''
};
// Get the domain name, including http://
if (url !== '' && typeof url !== 'un