js-cool
Version:
Collection of common JavaScript / TypeScript utilities
4,218 lines • 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 !== 'undefined') {
var match = url.match(/^http[s]?:\/\/[^\/]+/);
if (match) dirParam.host = match[0];
} else dirParam.host = location.host;
if (urlStr.includes('/')) {
// dirParam = unescape(urlStr).split("/");
dirParam.path = decodeURI(urlStr).split('/');
}
return dirParam; // {"host":"http://192.168.2.243:7004","path":["media","video","chidaoyan.mp4"]}
}
function getQueryParam(key, url) {
if (!key) {
console.info('key is required');
return undefined;
} else if (!url) {
if (!inBrowser) {
console.info('url is required');
return undefined;
}
url = location.href;
}
var _a = __read(url.split('#'), 2),
before = _a[0],
after = _a[1];
url = after || before;
url = url.slice(url.lastIndexOf('?'));
return parseUrlParam(url)[key];
}
function getQueryParams(url, covert) {
if (!url || typeof url === 'boolean') {
if (!inBrowser) {
console.info('url is required');
return null;
}
typeof url === 'boolean' && (covert = url);
url = location.href;
}
var _a = __read(url.split('#'), 2),
before = _a[0],
after = _a[1];
url = after || before;
url = url.slice(url.lastIndexOf('?'));
return parseUrlParam(url, covert);
}
function getUrlParam(key, url) {
if (!key) {
console.info('key is required');
return undefined;
} else if (!url) {
if (!inBrowser) {
console.info('url is required');
return undefined;
}
url = location.search;
} else {
url = url.slice(url.indexOf('?')).split('#')[0];
}
return parseUrlParam(url)[key];
}
function getUrlParams(url, covert) {
if (!url || typeof url === 'boolean') {
if (!inBrowser) {
console.info('url is required');
return null;
}
typeof url === 'boolean' && (covert = url);
url = location.search;
} else {
url = url.slice(url.indexOf('?')).split('#')[0];
}
return parseUrlParam(url, covert);
}
/**
* Get the cache, if the deposited is Object, the retrieved is also Object, no need to convert again
*
* @example
* ```js
* const data1 = 100
* const data2 = { a: 10 }
* const data3 = null
*
* setCache('data1', data1)
* setCache('data2', data2)
* setCache('data3', data3)
*
* getCache('data1') // 100
* getCache('data2') // {a:10}
* getCache('data3') // null
*
* getCache('data4') // null
* ```
* @since 1.0.2
* @param name - cache name
* @returns - data, if it's an object, it's also an object
*/
function getCache(name) {
var data = localStorage.getItem(name);
if (!data) return null;
try {
var exp = new Date();
var obj = JSON.parse(data);
if ('value' in obj || 'expires' in obj) {
if (!obj.expires || obj.expires > exp.getTime()) return obj.value;
sessionStorage.removeItem(name);
return null;
}
} catch (_a) {
return data;
}
}
/**
* Get the cache, if the deposited is Object, the retrieved is also Object, no need to convert again
*
* @example
* ```js
* // set boolean
* setCache('boolean', true)
*
* // set object
* setCache('object', { name: 'saqqdy' })
*
* // set number, expires in 20 seconds
* setCache('number', 666, 20)
* ```
* @since 1.0.2
* @param name - cache name
* @param value - cache data, can be passed directly into Object
* @param seconds - cache time (seconds)
*/
function setCache(name, value, seconds) {
if (typeof seconds === 'string') seconds = parseInt(seconds);
var expires = seconds ? new Date().getTime() + seconds * 1000 : undefined;
var data = {
value: value,
expires: expires
};
localStorage.setItem(name, JSON.stringify(data));
}
/**
* Delete localStorage
*
* @since 1.0.2
* @param name - name
*/
function delCache(name) {
localStorage.removeItem(name);
}
/**
* Read sessionStorage
*
* @example
* ```js
* const data1 = 100
* const data2 = { a: 10 }
* const data3 = null
*
* setSession('data1', data1)
* setSession('data2', data2)
* setSession('data3', data3)
*
* getSession('data1') // 100
* getSession('data2') // {a:10}
* getSession('data3') // null
*
* getSession('data4') // null
* ```
* @since 1.0.2
* @param name - name
* @returns - sessionStorage
*/
function getSession(name) {
var data = sessionStorage.getItem(name);
if (!data) return null;
try {
var exp = new Date();
var obj = JSON.parse(data);
if ('value' in obj || 'expires' in obj) {
if (!obj.expires || obj.expires > exp.getTime()) return obj.value;
sessionStorage.removeItem(name);
return null;
}
} catch (_a) {
return data;
}
}
/**
* Write sessionStorage
*
* @example
* ```js
* // set boolean
* setSession('boolean', true)
*
* // set object
* setSession('object', { name: 'saqqdy' })
*
* // set number, expires in 20 seconds
* setSession('number', 666, 20)
* ```
* @since 1.0.2
* @param name - name
* @param value - Set the value to be stored, either as an object or as a string
* @param seconds - the valid time
*/
function setSession(name, value, seconds) {
if (typeof seconds === 'string') seconds = parseInt(seconds);
var expires = seconds ? new Date().getTime() + seconds * 1000 : undefined;
var data = {
value: value,
expires: expires
};
sessionStorage.setItem(name, JSON.stringify(data));
}
/**
* Delete sessionStorage
*
* @since 1.0.2
* @param name - name
*/
function delSession(name) {
sessionStorage.removeItem(name);
}
/**
* Read cookie by name
*
* @example
* ```js
* getCookie('data1')
* // 100
* ```
* @since 1.0.2
* @param name - cookie name
* @returns - the cookie string
*/
function getCookie(name) {
var reg = new RegExp('(^| )' + name + '=([^;]*)(;|$)');
var arr = document.cookie.match(reg);
if (arr) {
return decodeURIComponent(arr[2]);
} else {
return null;
}
}
/**
* Read all cookies
*
* @example
* ```js
* getCookies()
* // \{ token: 'xxx', name: 'saqqdy' \}
* ```
* @since 5.6.0
* @returns - the cookie values
*/
function getCookies() {
var cookies = {};
var cookieArr = decodeURIComponent(document.cookie).split('; ');
for (var i = cookieArr.length - 1; i >= 0; i--) {
var valPair = cookieArr[i].split('=');
if (['null', 'undefined', 'NaN'].includes(valPair[1])) valPair[1] = '';
cookies[valPair[0]] = valPair[1];
}
return cookies;
}
/**
* setCookie method for writing cookies
*
* @example
* ```js
* // expires in 86400 seconds
* setCookie('token', 'xxxxxx')
*
* // set to path
* setCookie('token', 'xxxxxx', 20, '/app')
*
* // enable samesite
* setCookie('number', 666, 20, '/', false)
* ```
* @since 1.0.2
* @param name - cookie name
* @param value - Set the value to be stored, either as an object or as a string
* @param seconds - cookie validity default 1 day
* @param path - path, default '/'
* @param samesite - SameSite, default true
*/
function setCookie(name, value, seconds, path, samesite) {
if (path === undefined) {
path = '/';
}
if (samesite === undefined) {
samesite = true;
}
if (typeof seconds === 'string') seconds = parseInt(seconds);
var _t = new Date();
seconds || (seconds = 86400);
_t.setTime(_t.getTime() + seconds * 1000);
var cookieStr = "".concat(name, "=").concat(encodeURIComponent(value), ";expires=").concat(_t.toUTCString(), ";path=").concat(path);
if (samesite && location.protocol === 'https:') cookieStr += ';SameSite=None;Secure';
document.cookie = cookieStr;
}
/**
* Delete cookie
*
* @since 1.0.2
* @param name - cookie name
*/
function delCookie(name) {
var e = new Date();
e.setTime(e.getTime() - 1);
var cval = getCookie(name);
if (cval !== null) {
document.cookie = name + '=' + cval + ';expires=' + e.toUTCString() + ';path=/';
}
}
/**
* Encoding Utf8
*
* @since 1.0.1
* @param input - the string to be encoded
* @returns - the UTF-8 encoding
*/
function encodeUtf8(string) {
string = string.replace(/\r\n/g, '\n');
var utftext = '';
for (var n = 0; n < string.length; n++) {
var c = string.charCodeAt(n);
if (c < 128) {
utftext += String.fromCharCode(c);
} else if (c > 127 && c < 2048) {
utftext += String.fromCharCode(c >> 6 | 192);
utftext += String.fromCharCode(c & 63 | 128);
} else {
utftext += String.fromCharCode(c >> 12 | 224);
utftext += String.fromCharCode(c >> 6 & 63 | 128);
utftext += String.fromCharCode(c & 63 | 128);
}
}
return utftext;
}
var _keyStr$1 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
/**
* String, number to base64
*
* @since 1.0.1
* @param input - the string to be encoded
* @returns - the BASE64 encoding
*/
function encodeBase64(input) {
var output = '',
chr1,
chr2,
chr3,
enc1,
enc2,
enc3,
enc4,
i = 0;
input = encodeUtf8(input);
while (i < input.length) {
chr1 = input.charCodeAt(i++);
chr2 = input.charCodeAt(i++);
chr3 = input.charCodeAt(i++);
enc1 = chr1 >> 2;
enc2 = (chr1 & 3) << 4 | chr2 >> 4;
enc3 = (chr2 & 15) << 2 | chr3 >> 6;
enc4 = chr3 & 63;
if (isNaN(chr2)) {
enc3 = enc4 = 64;
} else if (isNaN(chr3)) {
enc4 = 64;
}
output = output + _keyStr$1.charAt(enc1) + _keyStr$1.charAt(enc2) + _keyStr$1.charAt(enc3) + _keyStr$1.charAt(enc4);
}
return output;
}
/**
* Decoding Utf8
*
* @since 1.0.1
* @param input - the string to be decoded
* @returns decoded string
*/
function decodeUtf8(utftext) {
var string = '',
i = 0,
c = 0,
// c1 = 0,
c2 = 0,
c3 = 0;
while (i < utftext.length) {
c = utftext.charCodeAt(i);
if (c < 128) {
string += String.fromCharCode(c);
i++;
} else if (c > 191 && c < 224) {
c2 = utftext.charCodeAt(i + 1);
string += String.fromCharCode((c & 31) << 6 | c2 & 63);
i += 2;
} else {
c2 = utftext.charCodeAt(i + 1);
c3 = utftext.charCodeAt(i + 2);
string += String.fromCharCode((c & 15) << 12 | (c2 & 63) << 6 | c3 & 63);
i += 3;
}
}
return string;
}
var _keyStr = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
/**
* base64 decoding
*
* @since 1.0.1
* @param input - the string to be decoded
* @returns decoded string
*/
function decodeBase64(input) {
var output = '',
chr1,
chr2,
chr3,
enc1,
enc2,
enc3,
enc4,
i = 0;
input = input.replace(/[^A-Za-z0-9\+\/\=]/g, '');
while (i < input.length) {
enc1 = _keyStr.indexOf(input.charAt(i++));
enc2 = _keyStr.indexOf(input.charAt(i++));
enc3 = _keyStr.indexOf(input.charAt(i++));
enc4 = _keyStr.indexOf(input.charAt(i++));
chr1 = enc1 << 2 | enc2 >> 4;
chr2 = (enc2 & 15) << 4 | enc3 >> 2;
chr3 = (enc3 & 3) << 6 | enc4;
output = output + String.fromCharCode(chr1);
if (enc3 !== 64) {
output = output + String.fromCharCode(chr2);
}
if (enc4 !== 64) {
output = output + String.fromCharCode(chr3);
}
}
output = decodeUtf8(output);
return output;
}
/**
* Block bubbling
*
* @since 1.0.2
* @param e - dom's event object
* @returns - false
*/
function stopBubble(e) {
if (e && e.stopPropagation) {
// Firefox
e.stopPropagation(); // e.preventDefault();
} else {
// IE
e.cancelBubble = true; // e.returnValue = false;
}
return false;
}
/**
* Block default events
*
* @since 1.0.2
* @param e - dom's event object
* @returns - false
*/
function stopDefault(e) {
if (e && e.preventDefault) {
e.preventDefault();
} else {
window.event.returnValue = false;
}
return false;
}
/**
* addEvent() event delegate, supports multiple delegates
*
* @since 1.0.2
* @param element - js dom object
* @param type - The event type. No need to add on
* @param handler - callback method
*/
function addEvent(element, type, handler) {
if (element.addEventListener) {
element.addEventListener(type, handler, false);
} else {
// Assign a unique ID to each event handler
if (!handler.$$guid) handler.$$guid = addEvent.guid++;
// Create a hash table for the event type of the element
if (!element.events) element.events = {};
// Create a hash table of event handlers for each "element/event" pair
var handlers = element.events[type];
if (!handlers) {
handlers = element.events[type] = {};
// Store the event handler functions that exist (if any)
if (element['on' + type]) {
handlers[0] = element['on' + type];
}
}
// Store event handling functions in a hash table
handlers[handler.$$guid] = handler;
// Assign a global event handler to do all the work
element['on' + type] = handleEvent;
}
}
// a counter used to create unique IDs
addEvent.guid = 1;
/**
* handleEvent() to execute the event
*
* @private
* @param event - event type
* @returns returnValue
*/
function handleEvent(event) {
var returnValue = true;
// @ts-expect-error
var that = this;
// Capturing event objects (IE uses global event objects)
event = event || fixEvent(((that.ownerDocument || that.document || that).parentWindow || window).event);
// Get a reference to the hash table of the event handling function
// @ts-expect-error
var handlers = this.events[event.type];
// Execute each handler function
for (var i in handlers) {
this.$$handleEvent = handlers[i];
// @ts-expect-error
if (this.$$handleEvent(event) === false) {
returnValue = false;
}
}
return returnValue;
}
/**
* Add some "missing" functions to IE's event objects
*
* @private
* @param event - event type
* @returns event returns the event that completes the missing method
*/
function fixEvent(event) {
// Adding standard W3C methods
event.preventDefault = fixEvent.preventDefault;
event.stopPropagation = fixEvent.stopPropagation;
return event;
}
fixEvent.preventDefault = function () {
this.returnValue = false;
};
fixEvent.stopPropagation = function () {
this.cancelBubble = true;
};
/**
* removeEvent removes the event delegate created by addEvent
*
* @since 1.0.2
* @param element - js dom object
* @param type - The type of the event. No need to add on
* @param handler - Callback method.
*/
function removeEvent(element, type, handler) {
if (element.removeEventListener) {
element.removeEventListener(type, handler, false);
} else {
// Removing event handler functions from a hash table
if (element.events && element.events[type]) {
delete element.events[type][handler.$$guid];
}
}
}
/**
* Get slide to top and bottom return 'top' 'bottom', recommend using limit flow
*
* @deprecated will be removed in the next major release.
* @since 1.0.2
* @returns - position
*/
function getScrollPosition() {
var innerH = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight;
var docScrollTop = document.documentElement.scrollTop;
var bodyScrollTop = document.body.scrollTop;
var docScrollHeight = document.documentElement.scrollHeight;
var bodyScrollHeight = document.body.scrollHeight;
var scrollT = 0,
scrollH = 0;
if (docScrollTop === 0) {
scrollT = bodyScrollTop;
scrollH = bodyScrollHeight;
if (bodyScrollTop === 0) {
return 'top';
}
} else {
scrollT = docScrollTop;
scrollH = docScrollHeight;
}
// if(bodyScrollTop === 0 && docScrollTop === 0){
// return 'top';
// }
if (innerH + Math.floor(scrollT) === scrollH || innerH + Math.ceil(scrollT) === scrollH) {
return 'bottom';
}
}
/**
* Return the next zIndex value
*
* @example
* ```js
* nextIndex()
* // 1
*
* nextIndex(1000)
* // 1001
*
* nextIndex(10, 100)
* // 100
* ```
* @since 1.0.2
* @param min - optional, minimum value
* @param max - optional, maximum value
* @returns - number
*/
// function nextIndex(min = 0, max?: number): number {
// const doms = [min]
// Array.prototype.forEach.call(document.querySelectorAll('body > *'), e => {
// const n = ['SCRIPT', 'META', 'STYLE', 'LINK'].includes(e.tagName)
// ? 0
// : +window.getComputedStyle(e).zIndex || 0
// n > min && doms.push(n)
// })
// // doms.sort((a, b) => b - a)
// const index = Math.max(...doms) + 1
// return !max || index < max ? index : max
// }
function nextIndex(min, max) {
if (min === undefined) {
min = 5000;
}
if (max === undefined) {
max = 10000;
}
var doms = [min];
Array.prototype.forEach.call(document.querySelectorAll('body > *'), function (e) {
var n = ['SCRIPT', 'META', 'STYLE', 'LINK'].includes(e.tagName) ? 0 : +window.getComputedStyle(e).zIndex || 0;
n > min && n < max && doms.push(n);
});
doms.sort(function (a, b) {
return b - a;
});
return doms[0] + 1;
}
/**
* return the next version, Only version types with no more than 3 digits are supported. (Follow the npm version rules)
*
* @example
* ```js
* nextVersion('1.2.33') // 1.2.34
*
* nextVersion('1.2.33', 'major') // 2.0.0
*
* nextVersion('1.2.33', 'premajor', 'alpha') // 2.0.0-alpha.1
* ```
* @since 5.10.0
* @param version - version(like: 1.0.0)
* @param type - optional, version type
* @param preid - optional, prerelease id
* @returns - new version
*/
function nextVersion(version, type, preid) {
if (preid === undefined) {
preid = '';
}
var ver = parseVersion(version);
switch (type) {
case 'major':
if (ver.minor || ver.patch || !ver.preid) ver.major++;
ver.minor = 0;
ver.patch = 0;
ver.preid = '';
ver.release = undefined;
break;
case 'minor':
if (ver.patch || !ver.preid) ver.minor++;
ver.patch = 0;
ver.preid = '';
ver.release = undefined;
break;
case 'premajor':
ver.major++;
ver.minor = 0;
ver.patch = 0;
ver.preid = preid;
ver.release = 0;
break;
case 'preminor':
ver.minor++;
ver.patch = 0;
ver.preid = preid;
ver.release = 0;
break;
case 'prepatch':
ver.patch++;
ver.preid = preid;
ver.release = 0;
break;
case 'prerelease':
if (preid && ver.preid !== preid) {
if (ver.release === undefined) ver.patch++;
ver.preid = preid;
ver.release = 0;
} else if (ver.release === undefined) {
ver.patch++;
ver.release = 0;
} else ver.release++;
break;
case 'patch':
default:
if (ver.release === undefined) ver.patch++;
ver.preid = '';
ver.release = undefined;
}
return stringifyVersion(ver);
}
function parseVersion(version) {
var _a, _b, _c, _d, _e;
var ver = {
major: 0,
minor: 0,
patch: 0,
preid: '',
release: undefined
};
var _f = __read(version.split('-'), 2),
mainVer = _f[0],
_g = _f[1],
subVer = _g === undefined ? '' : _g;
_a = __read(mainVer.split('.').map(function (el) {
return +el;
}), 3), _b = _a[0], ver.major = _b === undefined ? 0 : _b, _c = _a[1], ver.minor = _c === undefined ? 0 : _c, _d = _a[2], ver.patch = _d === undefined ? 0 : _d;
if (subVer.includes('.')) _e = __read(subVer.split('.').map(function (el, i) {
return i > 0 ? +el : el;
}), 2), ver.preid = _e[0], ver.release = _e[1];else if (subVer) ver.release = +subVer;
return ver;
}
function stringifyVersion(ver) {
var _a;
var mainVer = [ver.major, ver.minor, ver.patch].join('.');
var subVer = "".concat(ver.preid ? ver.preid + '.' : '').concat((_a = ver.release) !== null && _a !== undefined ? _a : '');
return "".concat(mainVer).concat(subVer ? '-' + subVer : '');
}
function punctualTimer(handler, delay) {
var args = [];
for (var _i = 2; _i < arguments.length; _i++) {
args[_i - 2] = arguments[_i];
}
handler();
var _this = {
count: 1,
timer: null,
clear: function clear() {
if (this.timer) {
clearTimeout(this.timer);
this.timer = null;
}
_this = null;
return _this;
}
};
var start = new Date().getTime();
var _instance = function instance() {
handler();
var ideal = _this.count * delay;
var real = new Date().getTime() - start;
_this.count++;
var diff = real - ideal;
_this.timer = setTimeout.apply(undefined, __spreadArray([_instance, delay - diff], __read(args), false)); // Repair by system time
};
_this.timer = setTimeout.apply(undefined, __spreadArray([_instance, delay], __read(args), false));
return _this;
}
/**
* Convert an object to a promise like api
*
* @example
* ```js
* import { promiseFactory, waiting } from 'js-cool'
*
* function promise() {
* const stats = {
* value: 100
* }
*
* const resolver = () =>
* new Promise(resolve =>
* waiting(2000).then(() => {
* stats.value = 200
* resolve(stats)
* })
* )
*
* return promiseFactory(stats, resolver)
* }
*
* const res = promise() // res => 100
* const res = await promise() // res => 200
* ```
* @since 5.10.0
* @param original - original object
* @param resolver - resolver function
* @returns - result
*/
function promiseFactory(original, resolver) {
return _assign(_assign({}, original), {
then: function then(onFulfilled, onRejected) {
return resolver().then(onFulfilled, onRejected);
}
});
}
/**
* Intercept the decimal places, do not fill in the missing 0
*
* @example
* ```js
* fixNumber('100.888')
* // 100.88
*
* fixNumber('100.8', 2)
* // 100.8
*
* fixNumber('100.8888', 3)
* // 100.888
* ```
* @since 1.0.2
* @param number - the number of digits to be processed, required
* @param n - the number of decimal places to keep, default is 2
* @returns - the new number
*/
function fixNumber(number, n) {
if (n === undefined) {
n = 2;
}
var reg = new RegExp('^(.*\\..{' + n + '}).*$');
number = '' + number;
if (!pattern.number.test(number)) throw new Error('"number" is not a number');
return parseFloat(number.replace(reg, '$1'));
}
/**
* Replacing specific data in a template string, support `${xxxx}` `{{xxxx}}` and `{xxxx}`
*
* @example
* ```ts
* const tmp = "My name is ${name}, I'm ${age} years old."
* mapTemplate(tmp, {
* name: 'saqqdy',
* age: 18
* })
* // My name is saqqdy, I'm 18 years old.
*
* mapTemplate(tmp, key => ({ name: 'saqqdy', age: 28 }[key]))
* // My name is saqqdy, I'm 28 years old.
*
* const tmp = "My name is {{name}}, I'm {{age}} years old."
* mapTemplate(tmp, {
* name: 'saqqdy',
* age: 18
* })
* // My name is saqqdy, I'm 18 years old.
* ```
* @since 5.9.0
* @param tmp - Template string
* @param data - Template data of map function
* @returns - result
*/
function mapTemplate(tmp, data) {
if (!tmp || !data) throw new Error('"tmp" & "data" is required');
var regexp = tmp.match(/\$\{(\w+)\}/g) ? /\$\{(\w+)\}/g : /\{?\{(\w+)\}\}?/g;
return '' + tmp.replace(regexp, function (string, replaceValue) {
if (typeof data === 'function') return '' + data(replaceValue);
for (var key in data) {
if (replaceValue === key) return '' + data[key];
}
return string;
});
}
/**
* Determine if target is an plain object
*
* @example
* ```js
* isPlainObject({}) // true
* isPlainObject(window) // false
* ```
* @since 5.0.0
* @param target - any target
* @returns - target is plain Object
*/
function isPlainObject(target) {
return Object.prototype.toString.call(target) === '[object Object]' && !isWindow(target) && Object.getPrototypeOf(target) === Object.prototype;
}
function extendObject(target, source, deep) {
var key;
for (key in source) if (source.hasOwnProperty(key)) {
if (deep && (isPlainObject(source[key]) || isArray(source[key]))) {
if (isPlainObject(source[key]) && !isPlainObject(target[key])) target[key] = {};
if (isArray(source[key]) && !isArray(target[key])) target[key] = [];
extendObject(target[key], source[key], deep);
} else if (source[key] !== undefined) target[key] = source[key];
}
}
function extend(target) {
var args = [];
for (var _i = 1; _i < arguments.length; _i++) {
args[_i - 1] = arguments[_i];
}
var deep = false;
if (typeof target === 'boolean') {
deep = target;
target = args.shift();
}
args.forEach(function (arg) {
extendObject(target, arg, deep);
});
return target;
}
/**
* deep clone (Buffer, Promise, Set, Map are not supported)
*
* @example
* ```js
* const source = { a: 100, reg: /\d+/g, arr: [1, 2] }
* const res = clone(source)
* // { a: 100, reg: /\d+/g, arr: [1, 2] }
* ```
* @since 5.15.0
* @param parent - source object
* @returns - new object
*/
function clone(parent) {
// handle regexp
var getRegExp = function getRegExp(reg) {
var flags = '';
if (reg.global) flags += 'g';
if (reg.ignoreCase) flags += 'i';
if (reg.multiline) flags += 'm';
return flags;
};
// Maintain two arrays of circular references
var parents = [];
var children = [];
var _clone2 = function _clone(parent) {
if (parent === null || _typeof(parent) !== 'object') return parent;
var child, proto;
if (isArray(parent)) {
child = [];
} else if (isRegExp(parent)) {
child = new RegExp(parent.source, getRegExp(parent));
if (parent.lastIndex) child.lastIndex = parent.lastIndex;
} else if (isDate(parent)) {
child = new Date(parent.getTime());
} else {
proto = Object.getPrototypeOf(parent);
child = Object.create(proto);
}
// Handling circular references
var index = parents.indexOf(parent);
// If this object exists in the parent array, it has already been referenced, so return it directly.
if (index !== -1) return children[index];
parents.push(parent);
children.push(child);
for (var i in parent) {
// recursive
child[i] = _clone2(parent[i]);
}
return child;
};
return _clone2(parent);
}
/**
* debounce & throttle
*
* @since 1.0.2
* @returns class
*/
function delay() {
return {
map: {},
register: function register(id, fn, time, boo) {
var _this = this;
if (boo) {
// debounce, only the first trigger for a certain period of time
if (!this.map[id]) {
// Non-existent first execution fn
fn();
}
this.map[id] = {
id: id,
fn: fn,
time: time,
boo: boo,
timeout: setTimeout(function () {
_this.destroy(id);
}, time)
};
} else {
// Throttling, delayed execution for a certain period of time
if (this.map[id]) {
// Existing ones are destroyed first
this.destroy(id);
}
this.map[id] = {
id: id,
fn: fn,
time: time,
boo: boo,
timeout: setTimeout(fn, time)
};
}
},
destroy: function destroy(id) {
if (!this.map[id]) {
return;
}
clearTimeout(this.map[id].timeout);
delete this.map[id];
}
};
}
/**
* Determine file type based on link suffix
*
* @example
* ```js
* getFileType('/name.png')
* // { "suffix": "png", "type": "image" }
*
* getFileType('/name.PDF')
* // { "suffix": "pdf", "type": "pdf" }
*
* getFileType('/name.xyz')
* // { "suffix": "xyz", "type": "other" }
* ```
* @since 5.11.0
* @param url - file url
* @returns result
*/
function getFileType(url) {
if (!url) throw new Error('"url" is required');
var _arr = url.split('.');
var suffix = _arr[_arr.length - 1].toLocaleLowerCase();
var type = 'other';
if (['png', 'jpg', 'jpeg', 'bmp', 'gif', 'webp', 'tiff', 'tif'].includes(suffix)) type = 'image';else if (['txt'].includes(suffix)) type = 'txt';else if (['xls', 'xlsx'].includes(suffix)) type = 'excel';else if (['doc', 'docx'].includes(suffix)) type = 'word';else if (['pdf'].includes(suffix)) type = 'pdf';else if (['ppt', 'pptx'].includes(suffix)) type = 'ppt';else if (['rar', 'zip', '7z'].includes(suffix)) type = 'zip';else if (['mp4', 'm2v', 'mkv', 'rmvb', 'wmv', 'avi', 'flv', 'mov', 'm4v'].includes(suffix)) type = 'video';else if (['mp3', 'wav', 'wmv'].includes(suffix)) type = 'audio';
return {
suffix: suffix,
type: type
};
}
/**
* Sorter factory function
*
* @example
* ```js
* const items = ['啊我', '波拉', 'abc', 0, 3, '10', ',11', 13, null, '阿吧', 'ABB', 'BDD', 'ACD', 'ä']
*
* items.sort(
* sorter('zh-Hans-CN', {
* ignorePunctuation: true,
* sensitivity: 'variant',
* numeric: true
* })
* )
* // [ 0, 3, "10", ",11", 13, "ä", "ABB", "abc", "ACD", "BDD", null, "阿吧", "啊我", "波拉" ]
* ```
* @since 5.14.0
* @param locales - A string with a BCP 47 language tag, or an array of such strings.
* @param options - An object adjusting the output format.
* @returns - compare function
*/
function sorter(locales, options) {
return function (a, b) {
var canUse = canUseLocales();
return canUse ? String(a).localeCompare(String(b), locales, options) : String(a).localeCompare(String(b));
};
}
/**
* Check browser support for extended arguments
*
* @returns - result
*/
function canUseLocales() {
try {
''.localeCompare('', 'i');
} catch (err) {
return err.name === 'RangeError';
}
return false;
}
/**
* Sort Chinese by Chinese phonetic alphabet
*
* @example
* ```js
* const items = ['啊我', '波拉', 'abc', 0, 3, '10', ',11', 13, null, '阿吧', 'ABB', 'BDD', 'ACD', 'ä']
*
* items.sort(sortPinyin)
* // [ ",11", 0, "10", 13, 3, "ä", "ABB", "abc", "ACD", "BDD", null, "阿吧", "啊我", "波拉" ]
*
* items.sort((a, b) => sortPinyin(a, b, { ignorePunctuation: true, numeric:true }))
* // [ 0, 3, "10", ",11", 13, "ä", "ABB", "abc", "ACD", "BDD", null, "阿吧", "啊我", "波拉" ]
* ```
* @since 5.14.0
* @param a - The first element for comparison.
* @param b - The second element for comparison.
* @param options - An object adjusting the output format.
* @returns - number
*/
function sortPinyin(a, b, options) {
// const aIsNumber = !isNaN(+a)
// const bIsNumber = !isNaN(+b)
if (options === undefined) {
options = {};
}
// if (aIsNumber && bIsNumber) return +a - +b
// else if (aIsNumber) return -1
// else if (bIsNumber) return 1
var aIsHans = /[^\x00-\xFF]+/g.test(String(a)); // eslint-disable-line no-control-regex
var bIsHans = /[^\x00-\xFF]+/g.test(String(b)); // eslint-disable-line no-control-regex
if (aIsHans && !bIsHans) return 1;
if (!aIsHans && bIsHans) return -1;
return sorter(['zh-Hans-CN', 'en-u-kn-true', 'de-DE-u-co-phonebk'], _assign({
ignorePunctuation: true,
sensitivity: 'variant',
numeric: true,
collation: 'pinyin',
caseFirst: 'false'
}, options))(a, b);
}
/**
* Determine if dark color mode
*
* @example
* ```js
* isDarkMode() // true
* ```
* @since 5.5.0
* @returns - result
*/
function isDarkMode() {
return window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches;
}
/**
* Data cleaning methods
*
* @since 1.0.2
* @param data - the object to be cleaned, must be passed
* @param map - the data queue to be cleaned, can be passed as array or object
* @param map -
* @param nullFix -
* @param map -
* @param nullFix -
* @param nullFix - optional, the value returned if there is no corresponding property, the default does not return the property
* @returns - the cleaned object
*/
function cleanData(data, map, nullFix) {
var result = {};
if (!data) return;
if (!map) return data;
if (isArray(map)) {
map.forEach(function (key) {
if (data.hasOwnProperty(key)) {
result[key] = data[key];
} else if (typeof nullFix !== 'undefined') {
result[key] = nullFix;
}
});
} else if (_typeof(map) === 'object') {
for (var key in map) {
if (typeof map[key] === 'function') {
result[key] = map[key](data);
} else {
if (!map[key]) map[key] = key;
if (data.hasOwnProperty(map[key])) {
result[key] = data[map[key]];
} else if (typeof nullFix !== 'undefined') {
result[key] = nullFix;
}
}
}
}
return result;
}
/**
* tree object depth lookup
*
* @since 5.0.0
* @param tree - tree object
* @param expression - required Query method
* @param keySet - optional Default subclass name, query name
* @param number - optional Number of lookups, if not passed, query all
* @returns - the queried array
*/
function searchObject(tree, expression, keySet, number) {
if (number === undefined) {
number = 0;
}
var retNode = [];
var isLimit = number > 0;
if (!keySet || _typeof(keySet) !== 'object') {
keySet = {
childName: 'child',
keyName: 'name'
};
}
if (Object.prototype.toString.call(tree) === '[object Object]') tree = [tree];
/**
* Recursive lookup
*
* @private
* @param tree - object
* @param expression - expression
* @returns Nodes
*/
function deepSearch(tree, expression) {
var e_1, _a;
for (var i = 0; i < tree.length; i++) {
if (tree[i][keySet.childName] && tree[i][keySet.childName].length > 0) {
deepSearch(tree[i][keySet.childName], expression);
}
var result = true;
if (_typeof(expression) === 'object') {
var keys = Object.keys(expression);
try {
for (var keys_1 = (e_1 = void 0, __values(keys)), keys_1_1 = keys_1.next(); !keys_1_1.done; keys_1_1 = keys_1.next()) {
var key = keys_1_1.value;
if (expression[key] !== tree[i][key]) {
result = false;
break;
}
}
} catch (e_1_1) {
e_1 = {
error: e_1_1
};
} finally {
try {
if (keys_1_1 && !keys_1_1.done && (_a = keys_1.return)) _a.call(keys_1);
} finally {
if (e_1) throw e_1.error;
}
}
} else if (typeof expression === 'function') {
result = expression.call(tree[i], tree[i]);
} else {
result = tree[i][keySet.keyName] === expression;
}
if (isLimit) {
// Limit the number of queries
if (number > 0) {
if (result) {
var treeNode = _assign({}, tree[i]);
delete treeNode[keySet.childName];
retNode.push(treeNode);
number--;
}
} else {
break;
}
} else {
if (result) {
var treeNode = _assign({}, tree[i]);
delete treeNode[keySet.childName];
retNode.push(treeNode);
}
}
}
}
deepSearch(tree, expression);
return retNode;
}
/**
* Open link in new tab (file jump download if browser can't parse)
*
* @since 1.0.6
* @param url - link
*/
function openUrl(url) {
var dom = document.createElement('a');
dom.style.display = 'none';
dom.href = url;
dom.setAttribute('target', '_blank');
document.body.appendChild(dom);
dom.click();
document.body.removeChild(dom);
}
/**
* copy to clipboard
*
* @since 5.0.0
* @param value - any target
* @returns - target is Object
*/
function copy(value) {
if (!inBrowser) return;
var textarea = document.createElement('textarea');
textarea.style.position = 'absolute';
textarea.style.opacity = '0';
textarea.innerText = value;
document.body.appendChild(textarea);
textarea.select();
var status = document.execCommand('copy');
document.body.removeChild(textarea);
return status;
}
/**
* Digital thousandths division
*
* @example
* ```js
* toThousands(10000000222)
* // 10,000,000,222
*
* toThousands(100.2232323)
* // 100.2232323
*
* toThousands(null)
* // ''
* ```
* @since 3.0.0
* @param num - input number
* @returns - the split string
*/
function toThousands(num) {
if (!num) return num === 0 || num === '0' ? '0' : '';
num = num.toString();
if (num.split('.').length === 1) return num.toString().replace(/(\d)(?=(?:\d{3})+$)/g, '$1,');
return num.split('.')[0].replace(/(\d)(?=(?:\d{3})+$)/g, '$&,') + '.' + num.split('.')[1];
}
/**
* Returns true if the provided predicate function returns true for all elements in a set, otherwise it returns false.
*
* @example
* ```js
* all([4, 2, 3], x => x > 1)
* // true
* ```
* @since 1.0.9
* @param arr - the target array
* @param fn - the judgment method
* @returns - the result of the judgment
*/
var all = function all(arr, fn) {
return arr.every(fn);
};
/**
* Returns true if the provided predicate function returns true for at least one element of a set, otherwise it returns false.
*
* @example
* ```js
* any([0, 1, 2, 0], x => x >= 2)
* // true
* ```
* @since 1.0.9
* @param arr - the target array
* @param fn - the judgment method
* @returns - the result of the judgment
*/
var any = function any(arr, fn) {
return arr.some(fn);
};
/**
* Browser-side generation of uuid, using v4 method
*
* @example
* ```js
* uuid() // '4222fcfe-5721-4632-bede-6043885be57d'
* ```
* @since 1.0.9
* @returns - uuid
*/
var uuid = function uuid() {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-expect-error
return ([1e7] + -1e3 + -4e3 + -8e3 + -1e11).replace(/[018]/g, function (c) {
return (c ^ crypto.getRandomValues(new Uint8Array(1))[0] & 15 >> c / 4).toString(16);
});
};
/**
* Converts a comma-separated string of values (CSV) to a 2D array.
*
* @example
* ```js
* CSVToArray('a,b\\nc,d')
* // `[['a','b'],['c','d']]`.
*
* CSVToArray('a;b\\\nc;d', ';')
* // `[['a','b'],['c','d']]`.
*
* CSVToArray('col1,col2\\\na,b\\\nc,d', ',', true)
* // `[['a','b'],['c','d']]`.
* ```
* @since 1.0.9
* @param data - csv data
* @param delimiter - separator, default ','
* @param omitFirstRow - the first row is the table header data, default false
* @returns array
*/
var CSVToArray = function CSVToArray(data, delimiter, omitFirstRow) {
if (delimiter === undefined) {
delimiter = ',';
}
if (omitFirstRow === undefined) {
omitFirstRow = false;
}
return data.slice(omitFirstRow ? data.indexOf('\n') + 1 : 0).split('\n').map(function (v) {
return v.split(delimiter);
});
};
/**
* Converts a two-dimensional array to a comma-separated string of values (CSV).
*
* @example
* ```js
* arrayToCSV([['a', 'b'], ['c', 'd']])
* // '"a", "b" \n "c", "d"'
*
* arrayToCSV([['a', 'b'], ['c', 'd']], ';')
* // '"a"; "b"\n "c"; "d"'
*
* arrayToCSV([['a', '"b" great'], ['c', 3.1415]])
* // '"a", """b"" great"\n "c",3.1415'
* ```
* @since 1.0.9
* @param data - json data
* @param delimiter - delimiter, default ','
* @returns CSV data
*/
var arrayToCSV = function arrayToCSV(arr, delimiter) {
if (delimiter === undefined) {
delimiter = ',';
}
return arr.map(function (v) {
return v.map(function (x) {
return isNaN(x) ? "\"".concat(x.replace(/"/g, '""'), "\"") : x;
}).join(delimiter);
}).join('\n');
};
/**
* Converts a comma-separated string of values (CSV) to an array of 2D objects. The first line of the string is used as the header line.
*
* @example
* ```js
* CSVToJSON('col1,col2\\na,b\\\nc,d')
* // `[{'col1': 'a', 'col2': 'b'}, {'col1': 'c', 'col2': 'd'}]`.
*
* CSVToJSON('col1;col2\\\na;b\\\nc;d', ';')
* // `[{'col1': 'a', 'col2': 'b'}, {'col1': 'c', 'col2': 'd'}]`.
* ```
* @since 1.0.9
* @param data - csv data
* @param delimiter - delimiter, default ','
* @returns - json
*/
function CSVToJSON(data, delimiter) {
if (delimiter === undefined) {
delimiter = ',';
}
var titles = data.slice(0, data.indexOf('\n')).split(delimiter);
return data.slice(data.indexOf('\n') + 1).split('\n').map(function (v) {
var values = v.split(delimiter);
return titles.reduce(
// eslint-disable-next-line no-sequences
function (obj, title, index) {
return obj[title] = values[index], obj;
}, {});
});
}
/**
* Converts an array of objects to a comma-separated value (CSV) string containing only the specified columns.
*
* @example
* ```js
* JSONToCSV([{ a: 1, b: 2 }, { a: 3, b: 4, c: 5 }, { a: 6 }, { b: 7 }], ['a', 'b'])
* // 'a,b\n "1", "2"\n "3", "4"\n "6",""\n"", "7"'
*
* JSONToCSV([{ a: 1, b: 2 }, { a: 3, b: 4, c: 5 }, { a: 6 }, { b: 7 }], ['a', 'b'], ';')
* // 'a;b\n "1"; "2"\n "3"; "4"\n "6";""\n""; "7"'
* ```
* @since 1.0.9
* @param data - json data
* @param columns - the specified columns
* @param delimiter - delimiter, default ','
* @returns - CSV data
*/
var JSONToCSV = function JSONToCSV(arr, columns, delimiter) {
if (delimiter === undefined) {
delimiter = ',';
}
return __spreadArray([columns.join(delimiter)], __read(arr.map(function (obj) {
return columns.reduce(function (acc, key) {
return "".concat(acc).concat(!acc.length ? '' : delimiter, "\"").concat(!obj[key] ? '' : obj[key], "\"");
}, '');
})), false).join('\n');
};
/**
* Converts RGB component values to color codes.
*
* @example
* ```js
* RGBToHex(255, 165, 1)
* // 'ffa501'
* ```
* @since 1.0.9
* @param r - the 1st value of RGB
* @param g - RGB's 2nd value
* @param b - RGB's 3rd value
* @returns - hex value
*/
var RGBToHex = function RGBToHex(r, g, b) {
return ((r << 16) + (g << 8) + b).toString(16).padStart(6, '0');
};
/**
* Whether the array contains the specified element
*
* @example
* ```js
* contains([1, 2], 2) // true
* contains([1, 2], 3) // false
* ```
* @since 2.2.1
* @param arr - the target array
* @param item - the target to find
* @returns boolean
*/
function contains(arr, item) {
var e_1, _a;
try {
for (var arr_1 = __values(arr), arr_1_1 = arr_1.next(); !arr_1_1.done; arr_1_1 = arr_1.next()) {
var el = arr_1_1.value;
if (el === item) return true;
}
} catch (e_1_1) {
e_1 = {
error: e_1_1
};
} finally {
try {
if (arr_1_1 && !arr_1_1.done && (_a = arr_1.return)) _a.call(arr_1);
} finally {
if (e_1) throw e_1.error;
}
}
return false;
}
/**
* Find the intersection of multiple arrays
*
* @example
* ```js
* intersect([1, 2], [2, 3, 4], [2, 8], [2, '33']) // [2]
* ```
* @since 2.2.1
* @param args - arguments
* @returns - new array
*/
function intersect() {
var args = [];
for (var _i = 0; _i < arguments.length; _i++) {
args[_i] = arguments[_i];
}
return args.reduce(function (pre, cur) {
return pre.filter(function (item) {
return contains(cur, item);
});
});
}
/**
* Array de-duplication
*
* @example
* ```js
* unique([1, 2, 2, '33']) // [1, 2, '33']
* ```
* @since 2.2.1
* @param arr - array data
* @returns - new array
*/
function unique(arr) {
var e_1, _a;
var newArray = [];
try {
for (var arr_1 = __values(arr), arr_1_1 = arr_1.next(); !arr_1_1.done; arr_1_1 = arr_1.next()) {
var el = arr_1_1.value;
!contains(newArray, el) && newArray.push(el);
}
} catch (e_1_1) {
e_1 = {
error: e_1_1
};
} finally {
try {
if (arr_1_1 && !arr_1_1.done && (_a = arr_1.return)) _a.call(arr_1);
} finally {
if (e_1) throw e_1.error;
}
}
return newArray;
}
/**
* Find the concatenation of multiple arrays
*
* @example
* ```js
* union([1, 2], [2, '33'])
* // [1, 2, '33']
*
* union([1, 2], [2, '33'], [1, 11, 2, '2'])
* // [ 1, 2, '33', 11, '2' ]
* ```
* @since 2.2.1
* @param args - arguments
* @returns - new array
*/
function union() {
var args = [];
for (var _i = 0; _i < arguments.length; _i++) {
args[_i] = arguments[_i];
}
return unique(args.reduce(function (pre, cur) {
return pre.concat(cur.filter(function (item) {
return !contains(pre, item);
}));
}));
}
/**
* Find the set of differences of multiple arrays that belong to A but not to B/C/D... of the elements of
*
* @example
* ```js
* minus([1, 2], [2, '33'], [2, 4]) // [1]
* ```
* @since 2.2.1
* @param args - arguments
* @returns - new array
*/
function minus() {
var args = [];
for (var _i = 0; _i < arguments.length; _i++) {
args[_i] = arguments[_i];
}
return args.reduce(function (pre, cur, index) {
index === 1 && (pre = unique(pre));
return pre.filter(function (item) {
return !contains(cur, item);
});
});
}
/**
* Find the complement of multiple arrays
*
* @example
* ```js
* complement([1, 2], [2, '33'], [2]) // [1, '33']
* ```
* @since 2.2.1
* @param args - arguments
* @returns array
*/
function complement() {
var args = [];
for (var _i = 0; _i < arguments.length; _i++) {
args[_i] = arguments[_i];
}
var intersectArray = intersect.apply(undefined, __spreadArray([], __read(args), false)); // Intersection set
var unionArray = union.apply(undefined, __spreadArray([], __read(args), false)); // Complementary set
return unionArray.filter(function (item) {
return !contains(intersectArray, item);
});
}
/**
* Read full IPv6
*
* @example
* ```js
* fillIPv6('2409:8005:800::2')
* // '2409:8005:0800:0000:0000:0000:0000:0002'
*
* fillIPv6('2409:8005:800::1c')
* // '2409:8005:0800:0000:0000:0000:0000:001c'
* ```
* @since 2.2.2
* @returns - string
*/
function fillIPv6(ip) {
return ip.replace(/\w+/g, function (a) {
return ('000' + a).substr(-4);
}).replace(/(\w*)::(\w*)/, function (a, b, c) {
var dotLen = 8 - ip.match(/:/g).length,
str = ':';
while (dotLen--) {
str += '0000:';
}
return (b || '0000') + str + (c || '0000');
});
}
function getProperty(target, prop, defaultValue) {
var e_1, _a;
if (!target) throw new Error('target is required');
if (!prop) return target;
if (prop instanceof Function) prop = prop();
var arr = prop.split('.');
var _loop_1 = function _loop_1(p) {
var index = -1;
// eslint-disable-next-line no-sequences
p = p.replace(/\[(\d+)\]$/, function (str, num) {
return index = parseInt(num), '';
});
if (p) target = target === null || target === undefined ? undefined : target[p];
if (index !== -1 && target) target = target === null || target === undefined ? undefined : target[index];
};
try {
for (var arr_1 = __values(arr), arr_1_1 = arr_1.next(); !arr_1_1.done; arr_1_1 = arr_1.next()) {
var p = arr_1_1.value;
_loop_1(p);
}
} catch (e_1_1) {
e_1 = {
error: e_1_1
};
} finally {
try {
if (arr_1_1 && !arr_1_1.done && (_a = arr_1.return)) _a.call(arr_1);
} finally {
if (e_1) throw e_1.error;
}
}
if (defaultValue === undefined) return target;
// undefined | null | NaN => defaultValue
// eslint-disable-next-line eqeqeq
return target || target == false ? target : defaultValue;
}
/**
* Set array, object property values based on path strings
*
* @example
* ```js
* const target = {
* a: 1,
* b: [{
* c: 2
* }]
* }
*
* setProperty(target, 'a', 2)
*
* setProperty(target, 'b[0].c', 3)
*
* setProperty(target, () => 'a', 100)
* ```
* @since 2.7.0
* @param target - target array, object
* @param prop - set target, support function, 'a' | 'a[1].c'
* @returns - the corresponding value
*/
function setProperty(target, prop, value) {
if (!target) throw new Error('target is required');
if (!prop) throw new Error('prop is required');
if (prop instanceof Function) prop = prop();
var arr = prop.split('.');
var _target = target;
arr.forEach(function (p, i) {
var _a, _b, _c;
var index = -1;
// p = p.replace(/\[(\d+)\]$/, (str, num) => ((index = parseInt(num)), ''))
p = p.replace(/\[(\d+)\]$/, function (str, num) {
index = parseInt(num);
return '';
});
if (i !== arr.length - 1) {
if (p) {
(_a = _target[p]) !== null && _a !== undefined ? _a : _target[p] = {};
_target = _target[p];
}
if (index !== -1 && _target) {
(_b = _target[index]) !== null && _b !== undefined ? _b : _target[index] = [];
_target = _target[index];
}
} else {
if (index !== -1) {
if (p) {
(_c = _target[p]) !== null && _c !== undefined ? _c : _target[p] = [];
_target = _target[p];
}
_target[index] = value;
} else if (p) {
_target[p] = value;
}
}
});
return target;
}
function preloader(images) {
var e_1, _a;
var isString = false;
if (!images) throw new Error('"images" is required');else if (typeof images === 'string') {
isString = true;
images = [].concat(images);
}
var imageObj = {};
try {
for (var images_1 = __values(images), images_1_1 = images_1.next(); !images_1_1.done; images_1_1 = images_1.next()) {
var image = images_1_1.value;
imageObj[image] = new Image();
imageObj[image].src = image;
}
} catch (e_1_1) {
e_1 = {
error: e_1_1
};
} finally {
try {
if (images_1_1 && !images_1_1.done && (_a = images_1.return)) _a.call(images_1);
} finally {
if (e_1) throw e_1.error;
}
}
return isString ? imageObj[images[0]] : imageObj;
}
/**
* waiting for a while
*
* @since 5.5.0
* @param milliseconds - waiting time (milliseconds)
* @param throwOnTimeout - throw on timeout
*/
var waiting = function waiting(milliseconds, throwOnTimeout) {
if (throwOnTimeout === undefined) {
throwOnTimeout = false;
}
return new Promise(function (resolve, reject) {
return setTimeout(throwOnTimeout ? reject : resolve, milliseconds);
});
};
/**
* arrayBuffer to base64
*
* @example
* ```js
* arrayBufferToBase64(arrayBuffer, 'image/png')
* // data:image/png;base64,xxxxxxxxxxxx
*
* arrayBufferToBase64(arrayBuffer)
* // xxxxxxxxxxxx
* ```
* @since 5.13.0
* @param input - arrayBuffer
* @param mime - image mime, eq: image/png
* @returns - base64
*/
function arrayBufferToBase64(input, mime) {
var u8Array = String.fromCharCode.apply(String, __spreadArray([], __read(new Uint8Array(input)), false));
return mime ? "data:".concat(mime, ";base64,").concat(btoa(u8Array)) : btoa(u8Array);
}
/**
* arrayBuffer to blob
*
* @since 5.13.0
* @param input - arrayBuffer
* @param mime - image mime, default: image/png
* @returns - blob
*/
function arrayBufferToBlob(input, mime) {
if (mime === undefined) {
mime = 'image/png';
}
return new Blob([input], {
type: mime
});
}
/**
* base64 to arrayBuffer
*
* @since 5.13.0
* @param input - base64 string
* @returns - arrayBuffer
*/
function base64ToArrayBuffer(input) {
var _a = __read(input.split(','), 2),
pre = _a[0],
data = _a[1];
if (!pre) throw new Error('Not a valid base64');else if (!data) {
data = pre;
pre = '';
}
if (inBrowser) {
var bstr = atob(data);
var len = bstr.length;
var u8Array = new Uint8Array(len);
while (len--) {
u8Array[len] = bstr.charCodeAt(len);
}
return u8Array;
}
return Buffer.from(data, 'base64');
}
/**
* base64 to blob
*
* @since 5.13.0
* @param input - base64 string
* @returns - blob
*/
function base64ToBlob(input) {
var _a;
var _b = __read(input.split(','), 1),
pre = _b[0];
if (!pre) throw new Error('Not a valid base64');
var mime = (_a = pre.match(/:(.*?);/)) === null || _a === undefined ? undefined : _a[1];
var arrayBuffer = base64ToArrayBuffer(input);
return new Blob([arrayBuffer], {
type: mime
});
}
/**
* base64 to file
*
* @since 5.13.0
* @param input - base64 string
* @param fileName - file name
* @returns - the BASE64 encoding
*/
function base64ToFile(input, fileName) {
var _a;
var _b = __read(input.split(','), 1),
pre = _b[0];
if (!pre) throw new Error('Not a valid base64');
var mime = (_a = pre.match(/:(.*?);/)) === null || _a === undefined ? undefined : _a[1];
var arrayBuffer = base64ToArrayBuffer(input);
return new File([arrayBuffer], fileName, {
type: mime
});
}
/**
* blob to arrayBuffer
*
* @since 5.13.0
* @param input - blob data
* @returns - arrayBuffer
*/
function blobToArrayBuffer(input) {
return new Promise(function (resolve, reject) {
var reader = new FileReader();
reader.onload = function () {
return resolve(reader.result);
};
reader.onerror = reject;
reader.readAsArrayBuffer(input);
});
}
/**
* blob to base64
*
* @since 5.13.0
* @param input - blob data
* @returns - base64 string
*/
function blobToBase64(input) {
return new Promise(function (resolve, reject) {
var reader = new FileReader();
reader.onload = function () {
return resolve(reader.result);
};
reader.onerror = reject;
reader.readAsDataURL(input);
});
}
/**
* blob to blobUrl
*
* @since 5.13.0
* @param input - blob data
* @returns - blobUrl
*/
function blobToUrl(input) {
return URL.createObjectURL(input);
}
/**
* file to base64
*
* @since 5.13.0
* @param input - file data
* @returns - base64 string
*/
function fileToBase64(input) {
return blobToBase64(input);
}
/**
* svg to blob
*
* @since 5.13.0
* @param input - svg string
* @returns - blob
*/
function svgToBlob(input) {
return new Blob([input], {
type: 'image/svg+xml'
});
}
/**
* url to blob
*
* @since 5.13.0
* @param input - url
* @returns - blob
*/
function urlToBlob(input) {
return new Promise(function (resolve, reject) {
if (!fetch) {
var xhr_1 = new XMLHttpRequest();
xhr_1.open('get', input, true);
xhr_1.responseType = 'blob';
xhr_1.onload = function () {
if (xhr_1.status === 200) {
resolve(xhr_1.response);
}
};
xhr_1.onerror = reject;
xhr_1.send();
} else {
fetch(input).then(function (res) {
resolve(res.blob());
}).catch(reject);
}
});
}
/**
* Dynamic loading of css link resources
*
* @param src - resource address
* @param option - parameters: attrs, props, force
* @returns - result
*/
function mountCss(src, option) {
if (option === undefined) {
option = {};
}
if (!src) throw new Error('[mountCss]: url is required');
var attrs = option.attrs,
props = option.props,
_a = option.force,
force = _a === undefined ? false : _a;
return new Promise(function (resolve, reject) {
if (!force && document.querySelector("link[href=\"".concat(src, "\"]"))) {
resolve(true);
return;
}
var dom = document.createElement('link');
var attr, prop;
if (attrs) {
for (attr in attrs) {
dom[attr] = attrs[attr];
}
}
if (props) {
for (prop in props) {
dom[prop] = props[prop];
}
}
dom.rel = 'stylesheet';
dom.type = 'text/css';
dom.href = src;
document.getElementsByTagName('head')[0].appendChild(dom);
dom.onload = dom.onreadystatechange = function () {
if (!dom.readyState || ['loaded', 'complete'].includes(dom.readyState)) {
dom.onload = dom.onreadystatechange = null;
resolve(true);
}
};
dom.onerror = reject;
});
}
/**
* Dynamic loading of image resources
*
* @param src - resource address
* @param option - parameters: attrs, props, force
* @returns - result
*/
function mountImage(src, option) {
if (option === undefined) {
option = {};
}
if (!src) throw new Error('[mountImage]: url is required');
var attrs = option.attrs,
props = option.props,
_a = option.force,
force = _a === undefined ? false : _a;
return new Promise(function (resolve, reject) {
if (!force && document.querySelector("img[src=\"".concat(src, "\"]"))) {
resolve(true);
return;
}
var dom = document.createElement('img');
var attr, prop;
if (attrs) {
for (attr in attrs) {
dom[attr] = attrs[attr];
}
}
if (props) {
for (prop in props) {
dom[prop] = props[prop];
}
}
dom.src = src;
document.body.appendChild(dom);
dom.onload = dom.onreadystatechange = function () {
if (!dom.readyState || ['loaded', 'complete'].includes(dom.readyState)) {
dom.onload = dom.onreadystatechange = null;
resolve(true);
}
};
dom.onerror = reject;
});
}
/**
* Dynamic loading of js linked resources
*
* @param src - resource address
* @param option - parameters: attrs, props, force
* @returns - result
*/
function mountScript(src, option) {
if (option === undefined) {
option = {};
}
if (!src) throw new Error('[mountScript]: url is required');
var attrs = option.attrs,
props = option.props,
_a = option.force,
force = _a === undefined ? false : _a;
return new Promise(function (resolve, reject) {
if (!force && document.querySelector("script[src=\"".concat(src, "\"]"))) {
resolve(true);
return;
}
var dom = document.createElement('script');
var attr, prop;
if (attrs) {
for (attr in attrs) {
dom[attr] = attrs[attr];
}
}
if (props) {
for (prop in props) {
dom[prop] = props[prop];
}
}
dom.src = src;
document.body.appendChild(dom);
dom.onload = dom.onreadystatechange = function () {
if (!dom.readyState || ['loaded', 'complete'].includes(dom.readyState)) {
dom.onload = dom.onreadystatechange = null;
resolve(true);
}
};
dom.onerror = reject;
});
}
/**
* Dynamic loading of css styles
*
* @param src - css string
* @param option - parameters: attrs, props
* @returns - results
*/
function mountStyle(css, option) {
if (option === undefined) {
option = {};
}
if (!css) throw new Error('[mountStyle]: css string is required');
var attrs = option.attrs,
props = option.props;
return new Promise(function (resolve) {
var dom = document.createElement('style');
var attr, prop;
if (attrs) {
for (attr in attrs) {
dom[attr] = attrs[attr];
}
}
if (props) {
for (prop in props) {
dom[prop] = props[prop];
}
}
dom.type = 'text/css';
try {
dom.appendChild(document.createTextNode(css));
} catch (ex) {
dom.textContent = css;
}
document.getElementsByTagName('head')[0].appendChild(dom);
resolve(true);
});
}
function __awaiter(thisArg, _arguments, P, generator) {
function adopt(value) {
return value instanceof P ? value : new P(function (resolve) {
resolve(value);
});
}
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) {
try {
step(generator.next(value));
} catch (e) {
reject(e);
}
}
function rejected(value) {
try {
step(generator["throw"](value));
} catch (e) {
reject(e);
}
}
function step(result) {
result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected);
}
step((generator = generator.apply(thisArg, [])).next());
});
}
function __generator(thisArg, body) {
var _ = {
label: 0,
sent: function sent() {
if (t[0] & 1) throw t[1];
return t[1];
},
trys: [],
ops: []
},
f,
y,
t,
g;
return g = {
next: verb(0),
"throw": verb(1),
"return": verb(2)
}, typeof Symbol === "function" && (g[Symbol.iterator] = function () {
return this;
}), g;
function verb(n) {
return function (v) {
return step([n, v]);
};
}
function step(op) {
if (f) throw new TypeError("Generator is already executing.");
while (g && (g = 0, op[0] && (_ = 0)), _) try {
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
if (y = 0, t) op = [op[0] & 2, t.value];
switch (op[0]) {
case 0:
case 1:
t = op;
break;
case 4:
_.label++;
return {
value: op[1],
done: false
};
case 5:
_.label++;
y = op[1];
op = [0];
continue;
case 7:
op = _.ops.pop();
_.trys.pop();
continue;
default:
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) {
_ = 0;
continue;
}
if (op[0] === 3 && (!t || op[1] > t[0] && op[1] < t[3])) {
_.label = op[1];
break;
}
if (op[0] === 6 && _.label < t[1]) {
_.label = t[1];
t = op;
break;
}
if (t && _.label < t[2]) {
_.label = t[2];
_.ops.push(op);
break;
}
if (t[2]) _.ops.pop();
_.trys.pop();
continue;
}
op = body.call(thisArg, _);
} catch (e) {
op = [6, e];
y = 0;
} finally {
f = t = 0;
}
if (op[0] & 5) throw op[1];
return {
value: op[0] ? op[1] : undefined,
done: true
};
}
}
/**
* Dynamic loading of resources, support js, images, css links, css style strings
*
* @param url - link to the resource, type must be passed when passing in styleString
* @param option - parameters: attrs, props, force
* @returns - true|false|imgUrl
*/
function loadSource(url, option) {
var _a, _b;
return __awaiter(this, undefined, undefined, function () {
var match, func;
return __generator(this, function (_c) {
switch (_c.label) {
case 0:
if (!url) throw new Error('url is required');
if (!option) option = {};
if (typeof option === 'string') {
option = {
type: option
};
} else if (!option.type) {
match = /\.(\w+)$/.exec(url);
if (!match || !match[1]) throw new Error('The url is not support');
option.type = match[1];
}
(_a = option.force) !== null && _a !== undefined ? _a : option.force = false;
option.type && (option.type = option.type.toLowerCase());
if (!['js', 'img', 'css', 'style'].includes(option.type)) throw new Error("Not support type: ".concat(option.type));
func = {
js: function js(src) {
return mountScript(src, option);
},
img: function img(src) {
return mountImage(src, option);
},
css: function css(src) {
return mountCss(src, option);
},
style: function style(css) {
return mountStyle(css, option);
}
};
return [4 /*yield*/, (_b = func[option.type]) === null || _b === undefined ? undefined : _b.call(func, url)];
case 1:
return [2 /*return*/, _c.sent()];
}
});
});
}
function awaitToDone(promise) {
var promises = [];
for (var _i = 1; _i < arguments.length; _i++) {
promises[_i - 1] = arguments[_i];
}
if (Array.isArray(promise)) {
return Promise.all(promise).then(function (data) {
return [null, data];
}).catch(function (err) {
return [err, undefined];
});
} else if (promises.length === 0) {
return promise.then(function (data) {
return [null, data];
}).catch(function (err) {
return [err, undefined];
});
}
return Promise.all(__spreadArray([promise], __read(promises), false)).then(function (data) {
return [null, data];
}).catch(function (err) {
return [err, undefined];
});
}
var index_default = {
version: '5.23.1',
download: download,
RGBToHex: RGBToHex,
addEvent: addEvent,
all: all,
any: any,
getCache: getCache,
setCache: setCache,
delCache: delCache,
getSession: getSession,
setSession: setSession,
delSession: delSession,
getCookie: getCookie,
getCookies: getCookies,
setCookie: setCookie,
delCookie: delCookie,
camel2Dash: camel2Dash,
cleanData: cleanData,
clearAttr: clearAttr,
clearHtml: clearHtml,
escape: escape,
unescape: unescape,
client: client,
complement: complement,
contains: contains,
CSVToArray: CSVToArray,
arrayToCSV: arrayToCSV,
CSVToJSON: CSVToJSON,
JSONToCSV: JSONToCSV,
cutCHSString: cutCHSString,
dash2Camel: dash2Camel,
decodeBase64: decodeBase64,
decodeUtf8: decodeUtf8,
delay: delay,
encodeBase64: encodeBase64,
encodeUtf8: encodeUtf8,
extend: extend,
clone: clone,
fillIPv6: fillIPv6,
fixNumber: fixNumber,
mapTemplate: mapTemplate,
getAppVersion: getAppVersion,
appVersion: appVersion,
getCHSLength: getCHSLength,
getDirParam: getDirParam,
compareVersion: compareVersion,
getNumber: getNumber,
getOsVersion: getOsVersion,
osVersion: osVersion,
browserVersion: browserVersion,
getQueryParam: getQueryParam,
getQueryParams: getQueryParams,
getProperty: getProperty,
randomColor: randomColor,
randomNumber: randomNumber,
randomNumbers: randomNumbers,
randomString: randomString,
shuffle: shuffle,
fingerprint: fingerprint,
getScrollPosition: getScrollPosition,
getType: getType,
getFileType: getFileType,
sorter: sorter,
sortPinyin: sortPinyin,
parseUrlParam: parseUrlParam,
spliceUrlParam: spliceUrlParam,
safeParse: safeParse,
safeStringify: safeStringify,
getUrlParam: getUrlParam,
getUrlParams: getUrlParams,
intersect: intersect,
isDigitals: isDigitals,
isExitsFunction: isExitsFunction,
isExitsVariable: isExitsVariable,
isEqual: isEqual,
isWindow: isWindow,
isObject: isObject,
isDate: isDate,
isRegExp: isRegExp,
isArray: isArray,
isIterable: isIterable,
isPlainObject: isPlainObject,
isDarkMode: isDarkMode,
inBrowser: inBrowser,
inNodeJs: inNodeJs,
isNumberBrowser: isNumberBrowser,
minus: minus,
nextIndex: nextIndex,
nextVersion: nextVersion,
punctualTimer: punctualTimer,
promiseFactory: promiseFactory,
waiting: waiting,
awaitTo: awaitToDone,
arrayBufferToBase64: arrayBufferToBase64,
arrayBufferToBlob: arrayBufferToBlob,
base64ToArrayBuffer: base64ToArrayBuffer,
base64ToBlob: base64ToBlob,
base64ToFile: base64ToFile,
blobToArrayBuffer: blobToArrayBuffer,
blobToBase64: blobToBase64,
blobToUrl: blobToUrl,
fileToBase64: fileToBase64,
svgToBlob: svgToBlob,
urlToBlob: urlToBlob,
openUrl: openUrl,
copy: copy,
pattern: pattern,
removeEvent: removeEvent,
searchObject: searchObject,
setProperty: setProperty,
stopBubble: stopBubble,
stopDefault: stopDefault,
toThousands: toThousands,
trim: trim,
union: union,
unique: unique,
upperFirst: upperFirst,
uuid: uuid,
windowSize: windowSize,
loadSource: loadSource,
mountCss: mountCss,
mountImg: mountImage,
mountJs: mountScript,
mountStyle: mountStyle,
preloader: preloader
};
return index_default;
})();