var SdenvExtend = (function () { /** * Removes all key-value entries from the list cache. * * @private * @name clear * @memberOf ListCache */ function listCacheClear() { this.__data__ = []; this.size = 0; } /** * Performs a * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) * comparison between two values to determine if they are equivalent. * * @static * @memberOf _ * @since 4.0.0 * @category Lang * @param {*} value The value to compare. * @param {*} other The other value to compare. * @returns {boolean} Returns `true` if the values are equivalent, else `false`. * @example * * var object = { 'a': 1 }; * var other = { 'a': 1 }; * * _.eq(object, object); * // => true * * _.eq(object, other); * // => false * * _.eq('a', 'a'); * // => true * * _.eq('a', Object('a')); * // => false * * _.eq(NaN, NaN); * // => true */ function eq(value, other) { return value === other || (value !== value && other !== other); } /** * Gets the index at which the `key` is found in `array` of key-value pairs. * * @private * @param {Array} array The array to inspect. * @param {*} key The key to search for. * @returns {number} Returns the index of the matched value, else `-1`. */ function assocIndexOf(array, key) { var length = array.length; while (length--) { if (eq(array[length][0], key)) { return length; } } return -1; } /** Used for built-in method references. */ var arrayProto = Array.prototype; /** Built-in value references. */ var splice = arrayProto.splice; /** * Removes `key` and its value from the list cache. * * @private * @name delete * @memberOf ListCache * @param {string} key The key of the value to remove. * @returns {boolean} Returns `true` if the entry was removed, else `false`. */ function listCacheDelete(key) { var data = this.__data__, index = assocIndexOf(data, key); if (index < 0) { return false; } var lastIndex = data.length - 1; if (index == lastIndex) { data.pop(); } else { splice.call(data, index, 1); } --this.size; return true; } /** * Gets the list cache value for `key`. * * @private * @name get * @memberOf ListCache * @param {string} key The key of the value to get. * @returns {*} Returns the entry value. */ function listCacheGet(key) { var data = this.__data__, index = assocIndexOf(data, key); return index < 0 ? undefined : data[index][1]; } /** * Checks if a list cache value for `key` exists. * * @private * @name has * @memberOf ListCache * @param {string} key The key of the entry to check. * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. */ function listCacheHas(key) { return assocIndexOf(this.__data__, key) > -1; } /** * Sets the list cache `key` to `value`. * * @private * @name set * @memberOf ListCache * @param {string} key The key of the value to set. * @param {*} value The value to set. * @returns {Object} Returns the list cache instance. */ function listCacheSet(key, value) { var data = this.__data__, index = assocIndexOf(data, key); if (index < 0) { ++this.size; data.push([key, value]); } else { data[index][1] = value; } return this; } /** * Creates an list cache object. * * @private * @constructor * @param {Array} [entries] The key-value pairs to cache. */ function ListCache(entries) { var index = -1, length = entries == null ? 0 : entries.length; this.clear(); while (++index < length) { var entry = entries[index]; this.set(entry[0], entry[1]); } } // Add methods to `ListCache`. ListCache.prototype.clear = listCacheClear; ListCache.prototype['delete'] = listCacheDelete; ListCache.prototype.get = listCacheGet; ListCache.prototype.has = listCacheHas; ListCache.prototype.set = listCacheSet; /** * Removes all key-value entries from the stack. * * @private * @name clear * @memberOf Stack */ function stackClear() { this.__data__ = new ListCache; this.size = 0; } /** * Removes `key` and its value from the stack. * * @private * @name delete * @memberOf Stack * @param {string} key The key of the value to remove. * @returns {boolean} Returns `true` if the entry was removed, else `false`. */ function stackDelete(key) { var data = this.__data__, result = data['delete'](key); this.size = data.size; return result; } /** * Gets the stack value for `key`. * * @private * @name get * @memberOf Stack * @param {string} key The key of the value to get. * @returns {*} Returns the entry value. */ function stackGet(key) { return this.__data__.get(key); } /** * Checks if a stack value for `key` exists. * * @private * @name has * @memberOf Stack * @param {string} key The key of the entry to check. * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. */ function stackHas(key) { return this.__data__.has(key); } /** Detect free variable `global` from Node.js. */ var freeGlobal = typeof global == 'object' && global && global.Object === Object && global; /** Detect free variable `self`. */ var freeSelf = typeof self == 'object' && self && self.Object === Object && self; /** Used as a reference to the global object. */ var root = freeGlobal || freeSelf || Function('return this')(); /** Built-in value references. */ var Symbol$1 = root.Symbol; /** Used for built-in method references. */ var objectProto$e = Object.prototype; /** Used to check objects for own properties. */ var hasOwnProperty$b = objectProto$e.hasOwnProperty; /** * Used to resolve the * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring) * of values. */ var nativeObjectToString$1 = objectProto$e.toString; /** Built-in value references. */ var symToStringTag$1 = Symbol$1 ? Symbol$1.toStringTag : undefined; /** * A specialized version of `baseGetTag` which ignores `Symbol.toStringTag` values. * * @private * @param {*} value The value to query. * @returns {string} Returns the raw `toStringTag`. */ function getRawTag(value) { var isOwn = hasOwnProperty$b.call(value, symToStringTag$1), tag = value[symToStringTag$1]; try { value[symToStringTag$1] = undefined; var unmasked = true; } catch (e) {} var result = nativeObjectToString$1.call(value); if (unmasked) { if (isOwn) { value[symToStringTag$1] = tag; } else { delete value[symToStringTag$1]; } } return result; } /** Used for built-in method references. */ var objectProto$d = Object.prototype; /** * Used to resolve the * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring) * of values. */ var nativeObjectToString = objectProto$d.toString; /** * Converts `value` to a string using `Object.prototype.toString`. * * @private * @param {*} value The value to convert. * @returns {string} Returns the converted string. */ function objectToString(value) { return nativeObjectToString.call(value); } /** `Object#toString` result references. */ var nullTag = '[object Null]', undefinedTag = '[object Undefined]'; /** Built-in value references. */ var symToStringTag = Symbol$1 ? Symbol$1.toStringTag : undefined; /** * The base implementation of `getTag` without fallbacks for buggy environments. * * @private * @param {*} value The value to query. * @returns {string} Returns the `toStringTag`. */ function baseGetTag(value) { if (value == null) { return value === undefined ? undefinedTag : nullTag; } return (symToStringTag && symToStringTag in Object(value)) ? getRawTag(value) : objectToString(value); } /** * Checks if `value` is the * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types) * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) * * @static * @memberOf _ * @since 0.1.0 * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is an object, else `false`. * @example * * _.isObject({}); * // => true * * _.isObject([1, 2, 3]); * // => true * * _.isObject(_.noop); * // => true * * _.isObject(null); * // => false */ function isObject(value) { var type = typeof value; return value != null && (type == 'object' || type == 'function'); } /** `Object#toString` result references. */ var asyncTag = '[object AsyncFunction]', funcTag$1 = '[object Function]', genTag = '[object GeneratorFunction]', proxyTag = '[object Proxy]'; /** * Checks if `value` is classified as a `Function` object. * * @static * @memberOf _ * @since 0.1.0 * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is a function, else `false`. * @example * * _.isFunction(_); * // => true * * _.isFunction(/abc/); * // => false */ function isFunction(value) { if (!isObject(value)) { return false; } // The use of `Object#toString` avoids issues with the `typeof` operator // in Safari 9 which returns 'object' for typed arrays and other constructors. var tag = baseGetTag(value); return tag == funcTag$1 || tag == genTag || tag == asyncTag || tag == proxyTag; } /** Used to detect overreaching core-js shims. */ var coreJsData = root['__core-js_shared__']; /** Used to detect methods masquerading as native. */ var maskSrcKey = (function() { var uid = /[^.]+$/.exec(coreJsData && coreJsData.keys && coreJsData.keys.IE_PROTO || ''); return uid ? ('Symbol(src)_1.' + uid) : ''; }()); /** * Checks if `func` has its source masked. * * @private * @param {Function} func The function to check. * @returns {boolean} Returns `true` if `func` is masked, else `false`. */ function isMasked(func) { return !!maskSrcKey && (maskSrcKey in func); } /** Used for built-in method references. */ var funcProto$2 = Function.prototype; /** Used to resolve the decompiled source of functions. */ var funcToString$2 = funcProto$2.toString; /** * Converts `func` to its source code. * * @private * @param {Function} func The function to convert. * @returns {string} Returns the source code. */ function toSource(func) { if (func != null) { try { return funcToString$2.call(func); } catch (e) {} try { return (func + ''); } catch (e) {} } return ''; } /** * Used to match `RegExp` * [syntax characters](http://ecma-international.org/ecma-262/7.0/#sec-patterns). */ var reRegExpChar = /[\\^$.*+?()[\]{}|]/g; /** Used to detect host constructors (Safari). */ var reIsHostCtor = /^\[object .+?Constructor\]$/; /** Used for built-in method references. */ var funcProto$1 = Function.prototype, objectProto$c = Object.prototype; /** Used to resolve the decompiled source of functions. */ var funcToString$1 = funcProto$1.toString; /** Used to check objects for own properties. */ var hasOwnProperty$a = objectProto$c.hasOwnProperty; /** Used to detect if a method is native. */ var reIsNative = RegExp('^' + funcToString$1.call(hasOwnProperty$a).replace(reRegExpChar, '\\$&') .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$' ); /** * The base implementation of `_.isNative` without bad shim checks. * * @private * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is a native function, * else `false`. */ function baseIsNative(value) { if (!isObject(value) || isMasked(value)) { return false; } var pattern = isFunction(value) ? reIsNative : reIsHostCtor; return pattern.test(toSource(value)); } /** * Gets the value at `key` of `object`. * * @private * @param {Object} [object] The object to query. * @param {string} key The key of the property to get. * @returns {*} Returns the property value. */ function getValue(object, key) { return object == null ? undefined : object[key]; } /** * Gets the native function at `key` of `object`. * * @private * @param {Object} object The object to query. * @param {string} key The key of the method to get. * @returns {*} Returns the function if it's native, else `undefined`. */ function getNative(object, key) { var value = getValue(object, key); return baseIsNative(value) ? value : undefined; } /* Built-in method references that are verified to be native. */ var Map = getNative(root, 'Map'); /* Built-in method references that are verified to be native. */ var nativeCreate = getNative(Object, 'create'); /** * Removes all key-value entries from the hash. * * @private * @name clear * @memberOf Hash */ function hashClear() { this.__data__ = nativeCreate ? nativeCreate(null) : {}; this.size = 0; } /** * Removes `key` and its value from the hash. * * @private * @name delete * @memberOf Hash * @param {Object} hash The hash to modify. * @param {string} key The key of the value to remove. * @returns {boolean} Returns `true` if the entry was removed, else `false`. */ function hashDelete(key) { var result = this.has(key) && delete this.__data__[key]; this.size -= result ? 1 : 0; return result; } /** Used to stand-in for `undefined` hash values. */ var HASH_UNDEFINED$2 = '__lodash_hash_undefined__'; /** Used for built-in method references. */ var objectProto$b = Object.prototype; /** Used to check objects for own properties. */ var hasOwnProperty$9 = objectProto$b.hasOwnProperty; /** * Gets the hash value for `key`. * * @private * @name get * @memberOf Hash * @param {string} key The key of the value to get. * @returns {*} Returns the entry value. */ function hashGet(key) { var data = this.__data__; if (nativeCreate) { var result = data[key]; return result === HASH_UNDEFINED$2 ? undefined : result; } return hasOwnProperty$9.call(data, key) ? data[key] : undefined; } /** Used for built-in method references. */ var objectProto$a = Object.prototype; /** Used to check objects for own properties. */ var hasOwnProperty$8 = objectProto$a.hasOwnProperty; /** * Checks if a hash value for `key` exists. * * @private * @name has * @memberOf Hash * @param {string} key The key of the entry to check. * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. */ function hashHas(key) { var data = this.__data__; return nativeCreate ? (data[key] !== undefined) : hasOwnProperty$8.call(data, key); } /** Used to stand-in for `undefined` hash values. */ var HASH_UNDEFINED$1 = '__lodash_hash_undefined__'; /** * Sets the hash `key` to `value`. * * @private * @name set * @memberOf Hash * @param {string} key The key of the value to set. * @param {*} value The value to set. * @returns {Object} Returns the hash instance. */ function hashSet(key, value) { var data = this.__data__; this.size += this.has(key) ? 0 : 1; data[key] = (nativeCreate && value === undefined) ? HASH_UNDEFINED$1 : value; return this; } /** * Creates a hash object. * * @private * @constructor * @param {Array} [entries] The key-value pairs to cache. */ function Hash(entries) { var index = -1, length = entries == null ? 0 : entries.length; this.clear(); while (++index < length) { var entry = entries[index]; this.set(entry[0], entry[1]); } } // Add methods to `Hash`. Hash.prototype.clear = hashClear; Hash.prototype['delete'] = hashDelete; Hash.prototype.get = hashGet; Hash.prototype.has = hashHas; Hash.prototype.set = hashSet; /** * Removes all key-value entries from the map. * * @private * @name clear * @memberOf MapCache */ function mapCacheClear() { this.size = 0; this.__data__ = { 'hash': new Hash, 'map': new (Map || ListCache), 'string': new Hash }; } /** * Checks if `value` is suitable for use as unique object key. * * @private * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is suitable, else `false`. */ function isKeyable(value) { var type = typeof value; return (type == 'string' || type == 'number' || type == 'symbol' || type == 'boolean') ? (value !== '__proto__') : (value === null); } /** * Gets the data for `map`. * * @private * @param {Object} map The map to query. * @param {string} key The reference key. * @returns {*} Returns the map data. */ function getMapData(map, key) { var data = map.__data__; return isKeyable(key) ? data[typeof key == 'string' ? 'string' : 'hash'] : data.map; } /** * Removes `key` and its value from the map. * * @private * @name delete * @memberOf MapCache * @param {string} key The key of the value to remove. * @returns {boolean} Returns `true` if the entry was removed, else `false`. */ function mapCacheDelete(key) { var result = getMapData(this, key)['delete'](key); this.size -= result ? 1 : 0; return result; } /** * Gets the map value for `key`. * * @private * @name get * @memberOf MapCache * @param {string} key The key of the value to get. * @returns {*} Returns the entry value. */ function mapCacheGet(key) { return getMapData(this, key).get(key); } /** * Checks if a map value for `key` exists. * * @private * @name has * @memberOf MapCache * @param {string} key The key of the entry to check. * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. */ function mapCacheHas(key) { return getMapData(this, key).has(key); } /** * Sets the map `key` to `value`. * * @private * @name set * @memberOf MapCache * @param {string} key The key of the value to set. * @param {*} value The value to set. * @returns {Object} Returns the map cache instance. */ function mapCacheSet(key, value) { var data = getMapData(this, key), size = data.size; data.set(key, value); this.size += data.size == size ? 0 : 1; return this; } /** * Creates a map cache object to store key-value pairs. * * @private * @constructor * @param {Array} [entries] The key-value pairs to cache. */ function MapCache(entries) { var index = -1, length = entries == null ? 0 : entries.length; this.clear(); while (++index < length) { var entry = entries[index]; this.set(entry[0], entry[1]); } } // Add methods to `MapCache`. MapCache.prototype.clear = mapCacheClear; MapCache.prototype['delete'] = mapCacheDelete; MapCache.prototype.get = mapCacheGet; MapCache.prototype.has = mapCacheHas; MapCache.prototype.set = mapCacheSet; /** Used as the size to enable large array optimizations. */ var LARGE_ARRAY_SIZE = 200; /** * Sets the stack `key` to `value`. * * @private * @name set * @memberOf Stack * @param {string} key The key of the value to set. * @param {*} value The value to set. * @returns {Object} Returns the stack cache instance. */ function stackSet(key, value) { var data = this.__data__; if (data instanceof ListCache) { var pairs = data.__data__; if (!Map || (pairs.length < LARGE_ARRAY_SIZE - 1)) { pairs.push([key, value]); this.size = ++data.size; return this; } data = this.__data__ = new MapCache(pairs); } data.set(key, value); this.size = data.size; return this; } /** * Creates a stack cache object to store key-value pairs. * * @private * @constructor * @param {Array} [entries] The key-value pairs to cache. */ function Stack(entries) { var data = this.__data__ = new ListCache(entries); this.size = data.size; } // Add methods to `Stack`. Stack.prototype.clear = stackClear; Stack.prototype['delete'] = stackDelete; Stack.prototype.get = stackGet; Stack.prototype.has = stackHas; Stack.prototype.set = stackSet; var defineProperty = (function() { try { var func = getNative(Object, 'defineProperty'); func({}, '', {}); return func; } catch (e) {} }()); /** * The base implementation of `assignValue` and `assignMergeValue` without * value checks. * * @private * @param {Object} object The object to modify. * @param {string} key The key of the property to assign. * @param {*} value The value to assign. */ function baseAssignValue(object, key, value) { if (key == '__proto__' && defineProperty) { defineProperty(object, key, { 'configurable': true, 'enumerable': true, 'value': value, 'writable': true }); } else { object[key] = value; } } /** * This function is like `assignValue` except that it doesn't assign * `undefined` values. * * @private * @param {Object} object The object to modify. * @param {string} key The key of the property to assign. * @param {*} value The value to assign. */ function assignMergeValue(object, key, value) { if ((value !== undefined && !eq(object[key], value)) || (value === undefined && !(key in object))) { baseAssignValue(object, key, value); } } /** * Creates a base function for methods like `_.forIn` and `_.forOwn`. * * @private * @param {boolean} [fromRight] Specify iterating from right to left. * @returns {Function} Returns the new base function. */ function createBaseFor(fromRight) { return function(object, iteratee, keysFunc) { var index = -1, iterable = Object(object), props = keysFunc(object), length = props.length; while (length--) { var key = props[fromRight ? length : ++index]; if (iteratee(iterable[key], key, iterable) === false) { break; } } return object; }; } /** * The base implementation of `baseForOwn` which iterates over `object` * properties returned by `keysFunc` and invokes `iteratee` for each property. * Iteratee functions may exit iteration early by explicitly returning `false`. * * @private * @param {Object} object The object to iterate over. * @param {Function} iteratee The function invoked per iteration. * @param {Function} keysFunc The function to get the keys of `object`. * @returns {Object} Returns `object`. */ var baseFor = createBaseFor(); /** Detect free variable `exports`. */ var freeExports$2 = typeof exports == 'object' && exports && !exports.nodeType && exports; /** Detect free variable `module`. */ var freeModule$2 = freeExports$2 && typeof module == 'object' && module && !module.nodeType && module; /** Detect the popular CommonJS extension `module.exports`. */ var moduleExports$2 = freeModule$2 && freeModule$2.exports === freeExports$2; /** Built-in value references. */ var Buffer$1 = moduleExports$2 ? root.Buffer : undefined, allocUnsafe = Buffer$1 ? Buffer$1.allocUnsafe : undefined; /** * Creates a clone of `buffer`. * * @private * @param {Buffer} buffer The buffer to clone. * @param {boolean} [isDeep] Specify a deep clone. * @returns {Buffer} Returns the cloned buffer. */ function cloneBuffer(buffer, isDeep) { if (isDeep) { return buffer.slice(); } var length = buffer.length, result = allocUnsafe ? allocUnsafe(length) : new buffer.constructor(length); buffer.copy(result); return result; } /** Built-in value references. */ var Uint8Array = root.Uint8Array; /** * Creates a clone of `arrayBuffer`. * * @private * @param {ArrayBuffer} arrayBuffer The array buffer to clone. * @returns {ArrayBuffer} Returns the cloned array buffer. */ function cloneArrayBuffer(arrayBuffer) { var result = new arrayBuffer.constructor(arrayBuffer.byteLength); new Uint8Array(result).set(new Uint8Array(arrayBuffer)); return result; } /** * Creates a clone of `typedArray`. * * @private * @param {Object} typedArray The typed array to clone. * @param {boolean} [isDeep] Specify a deep clone. * @returns {Object} Returns the cloned typed array. */ function cloneTypedArray(typedArray, isDeep) { var buffer = isDeep ? cloneArrayBuffer(typedArray.buffer) : typedArray.buffer; return new typedArray.constructor(buffer, typedArray.byteOffset, typedArray.length); } /** * Copies the values of `source` to `array`. * * @private * @param {Array} source The array to copy values from. * @param {Array} [array=[]] The array to copy values to. * @returns {Array} Returns `array`. */ function copyArray(source, array) { var index = -1, length = source.length; array || (array = Array(length)); while (++index < length) { array[index] = source[index]; } return array; } /** Built-in value references. */ var objectCreate = Object.create; /** * The base implementation of `_.create` without support for assigning * properties to the created object. * * @private * @param {Object} proto The object to inherit from. * @returns {Object} Returns the new object. */ var baseCreate = (function() { function object() {} return function(proto) { if (!isObject(proto)) { return {}; } if (objectCreate) { return objectCreate(proto); } object.prototype = proto; var result = new object; object.prototype = undefined; return result; }; }()); /** * Creates a unary function that invokes `func` with its argument transformed. * * @private * @param {Function} func The function to wrap. * @param {Function} transform The argument transform. * @returns {Function} Returns the new function. */ function overArg(func, transform) { return function(arg) { return func(transform(arg)); }; } /** Built-in value references. */ var getPrototype = overArg(Object.getPrototypeOf, Object); var getPrototype$1 = getPrototype; /** Used for built-in method references. */ var objectProto$9 = Object.prototype; /** * Checks if `value` is likely a prototype object. * * @private * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is a prototype, else `false`. */ function isPrototype(value) { var Ctor = value && value.constructor, proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto$9; return value === proto; } /** * Initializes an object clone. * * @private * @param {Object} object The object to clone. * @returns {Object} Returns the initialized clone. */ function initCloneObject(object) { return (typeof object.constructor == 'function' && !isPrototype(object)) ? baseCreate(getPrototype$1(object)) : {}; } /** * Checks if `value` is object-like. A value is object-like if it's not `null` * and has a `typeof` result of "object". * * @static * @memberOf _ * @since 4.0.0 * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is object-like, else `false`. * @example * * _.isObjectLike({}); * // => true * * _.isObjectLike([1, 2, 3]); * // => true * * _.isObjectLike(_.noop); * // => false * * _.isObjectLike(null); * // => false */ function isObjectLike(value) { return value != null && typeof value == 'object'; } /** `Object#toString` result references. */ var argsTag$2 = '[object Arguments]'; /** * The base implementation of `_.isArguments`. * * @private * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is an `arguments` object, */ function baseIsArguments(value) { return isObjectLike(value) && baseGetTag(value) == argsTag$2; } /** Used for built-in method references. */ var objectProto$8 = Object.prototype; /** Used to check objects for own properties. */ var hasOwnProperty$7 = objectProto$8.hasOwnProperty; /** Built-in value references. */ var propertyIsEnumerable$1 = objectProto$8.propertyIsEnumerable; /** * Checks if `value` is likely an `arguments` object. * * @static * @memberOf _ * @since 0.1.0 * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is an `arguments` object, * else `false`. * @example * * _.isArguments(function() { return arguments; }()); * // => true * * _.isArguments([1, 2, 3]); * // => false */ var isArguments = baseIsArguments(function() { return arguments; }()) ? baseIsArguments : function(value) { return isObjectLike(value) && hasOwnProperty$7.call(value, 'callee') && !propertyIsEnumerable$1.call(value, 'callee'); }; /** * Checks if `value` is classified as an `Array` object. * * @static * @memberOf _ * @since 0.1.0 * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is an array, else `false`. * @example * * _.isArray([1, 2, 3]); * // => true * * _.isArray(document.body.children); * // => false * * _.isArray('abc'); * // => false * * _.isArray(_.noop); * // => false */ var isArray = Array.isArray; /** Used as references for various `Number` constants. */ var MAX_SAFE_INTEGER$1 = 9007199254740991; /** * Checks if `value` is a valid array-like length. * * **Note:** This method is loosely based on * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength). * * @static * @memberOf _ * @since 4.0.0 * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is a valid length, else `false`. * @example * * _.isLength(3); * // => true * * _.isLength(Number.MIN_VALUE); * // => false * * _.isLength(Infinity); * // => false * * _.isLength('3'); * // => false */ function isLength(value) { return typeof value == 'number' && value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER$1; } /** * Checks if `value` is array-like. A value is considered array-like if it's * not a function and has a `value.length` that's an integer greater than or * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`. * * @static * @memberOf _ * @since 4.0.0 * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is array-like, else `false`. * @example * * _.isArrayLike([1, 2, 3]); * // => true * * _.isArrayLike(document.body.children); * // => true * * _.isArrayLike('abc'); * // => true * * _.isArrayLike(_.noop); * // => false */ function isArrayLike(value) { return value != null && isLength(value.length) && !isFunction(value); } /** * This method is like `_.isArrayLike` except that it also checks if `value` * is an object. * * @static * @memberOf _ * @since 4.0.0 * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is an array-like object, * else `false`. * @example * * _.isArrayLikeObject([1, 2, 3]); * // => true * * _.isArrayLikeObject(document.body.children); * // => true * * _.isArrayLikeObject('abc'); * // => false * * _.isArrayLikeObject(_.noop); * // => false */ function isArrayLikeObject(value) { return isObjectLike(value) && isArrayLike(value); } /** * This method returns `false`. * * @static * @memberOf _ * @since 4.13.0 * @category Util * @returns {boolean} Returns `false`. * @example * * _.times(2, _.stubFalse); * // => [false, false] */ function stubFalse() { return false; } /** Detect free variable `exports`. */ var freeExports$1 = typeof exports == 'object' && exports && !exports.nodeType && exports; /** Detect free variable `module`. */ var freeModule$1 = freeExports$1 && typeof module == 'object' && module && !module.nodeType && module; /** Detect the popular CommonJS extension `module.exports`. */ var moduleExports$1 = freeModule$1 && freeModule$1.exports === freeExports$1; /** Built-in value references. */ var Buffer = moduleExports$1 ? root.Buffer : undefined; /* Built-in method references for those with the same name as other `lodash` methods. */ var nativeIsBuffer = Buffer ? Buffer.isBuffer : undefined; /** * Checks if `value` is a buffer. * * @static * @memberOf _ * @since 4.3.0 * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is a buffer, else `false`. * @example * * _.isBuffer(new Buffer(2)); * // => true * * _.isBuffer(new Uint8Array(2)); * // => false */ var isBuffer = nativeIsBuffer || stubFalse; /** `Object#toString` result references. */ var objectTag$3 = '[object Object]'; /** Used for built-in method references. */ var funcProto = Function.prototype, objectProto$7 = Object.prototype; /** Used to resolve the decompiled source of functions. */ var funcToString = funcProto.toString; /** Used to check objects for own properties. */ var hasOwnProperty$6 = objectProto$7.hasOwnProperty; /** Used to infer the `Object` constructor. */ var objectCtorString = funcToString.call(Object); /** * Checks if `value` is a plain object, that is, an object created by the * `Object` constructor or one with a `[[Prototype]]` of `null`. * * @static * @memberOf _ * @since 0.8.0 * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is a plain object, else `false`. * @example * * function Foo() { * this.a = 1; * } * * _.isPlainObject(new Foo); * // => false * * _.isPlainObject([1, 2, 3]); * // => false * * _.isPlainObject({ 'x': 0, 'y': 0 }); * // => true * * _.isPlainObject(Object.create(null)); * // => true */ function isPlainObject(value) { if (!isObjectLike(value) || baseGetTag(value) != objectTag$3) { return false; } var proto = getPrototype$1(value); if (proto === null) { return true; } var Ctor = hasOwnProperty$6.call(proto, 'constructor') && proto.constructor; return typeof Ctor == 'function' && Ctor instanceof Ctor && funcToString.call(Ctor) == objectCtorString; } /** `Object#toString` result references. */ var argsTag$1 = '[object Arguments]', arrayTag$1 = '[object Array]', boolTag$1 = '[object Boolean]', dateTag$1 = '[object Date]', errorTag$1 = '[object Error]', funcTag = '[object Function]', mapTag$2 = '[object Map]', numberTag$1 = '[object Number]', objectTag$2 = '[object Object]', regexpTag$1 = '[object RegExp]', setTag$2 = '[object Set]', stringTag$1 = '[object String]', weakMapTag$1 = '[object WeakMap]'; var arrayBufferTag$1 = '[object ArrayBuffer]', dataViewTag$2 = '[object DataView]', float32Tag = '[object Float32Array]', float64Tag = '[object Float64Array]', int8Tag = '[object Int8Array]', int16Tag = '[object Int16Array]', int32Tag = '[object Int32Array]', uint8Tag = '[object Uint8Array]', uint8ClampedTag = '[object Uint8ClampedArray]', uint16Tag = '[object Uint16Array]', uint32Tag = '[object Uint32Array]'; /** Used to identify `toStringTag` values of typed arrays. */ var typedArrayTags = {}; typedArrayTags[float32Tag] = typedArrayTags[float64Tag] = typedArrayTags[int8Tag] = typedArrayTags[int16Tag] = typedArrayTags[int32Tag] = typedArrayTags[uint8Tag] = typedArrayTags[uint8ClampedTag] = typedArrayTags[uint16Tag] = typedArrayTags[uint32Tag] = true; typedArrayTags[argsTag$1] = typedArrayTags[arrayTag$1] = typedArrayTags[arrayBufferTag$1] = typedArrayTags[boolTag$1] = typedArrayTags[dataViewTag$2] = typedArrayTags[dateTag$1] = typedArrayTags[errorTag$1] = typedArrayTags[funcTag] = typedArrayTags[mapTag$2] = typedArrayTags[numberTag$1] = typedArrayTags[objectTag$2] = typedArrayTags[regexpTag$1] = typedArrayTags[setTag$2] = typedArrayTags[stringTag$1] = typedArrayTags[weakMapTag$1] = false; /** * The base implementation of `_.isTypedArray` without Node.js optimizations. * * @private * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is a typed array, else `false`. */ function baseIsTypedArray(value) { return isObjectLike(value) && isLength(value.length) && !!typedArrayTags[baseGetTag(value)]; } /** * The base implementation of `_.unary` without support for storing metadata. * * @private * @param {Function} func The function to cap arguments for. * @returns {Function} Returns the new capped function. */ function baseUnary(func) { return function(value) { return func(value); }; } /** Detect free variable `exports`. */ var freeExports = typeof exports == 'object' && exports && !exports.nodeType && exports; /** Detect free variable `module`. */ var freeModule = freeExports && typeof module == 'object' && module && !module.nodeType && module; /** Detect the popular CommonJS extension `module.exports`. */ var moduleExports = freeModule && freeModule.exports === freeExports; /** Detect free variable `process` from Node.js. */ var freeProcess = moduleExports && freeGlobal.process; /** Used to access faster Node.js helpers. */ var nodeUtil = (function() { try { // Use `util.types` for Node.js 10+. var types = freeModule && freeModule.require && freeModule.require('util').types; if (types) { return types; } // Legacy `process.binding('util')` for Node.js < 10. return freeProcess && freeProcess.binding && freeProcess.binding('util'); } catch (e) {} }()); /* Node.js helper references. */ var nodeIsTypedArray = nodeUtil && nodeUtil.isTypedArray; /** * Checks if `value` is classified as a typed array. * * @static * @memberOf _ * @since 3.0.0 * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is a typed array, else `false`. * @example * * _.isTypedArray(new Uint8Array); * // => true * * _.isTypedArray([]); * // => false */ var isTypedArray = nodeIsTypedArray ? baseUnary(nodeIsTypedArray) : baseIsTypedArray; /** * Gets the value at `key`, unless `key` is "__proto__" or "constructor". * * @private * @param {Object} object The object to query. * @param {string} key The key of the property to get. * @returns {*} Returns the property value. */ function safeGet(object, key) { if (key === 'constructor' && typeof object[key] === 'function') { return; } if (key == '__proto__') { return; } return object[key]; } /** Used for built-in method references. */ var objectProto$6 = Object.prototype; /** Used to check objects for own properties. */ var hasOwnProperty$5 = objectProto$6.hasOwnProperty; /** * Assigns `value` to `key` of `object` if the existing value is not equivalent * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) * for equality comparisons. * * @private * @param {Object} object The object to modify. * @param {string} key The key of the property to assign. * @param {*} value The value to assign. */ function assignValue(object, key, value) { var objValue = object[key]; if (!(hasOwnProperty$5.call(object, key) && eq(objValue, value)) || (value === undefined && !(key in object))) { baseAssignValue(object, key, value); } } /** * Copies properties of `source` to `object`. * * @private * @param {Object} source The object to copy properties from. * @param {Array} props The property identifiers to copy. * @param {Object} [object={}] The object to copy properties to. * @param {Function} [customizer] The function to customize copied values. * @returns {Object} Returns `object`. */ function copyObject(source, props, object, customizer) { var isNew = !object; object || (object = {}); var index = -1, length = props.length; while (++index < length) { var key = props[index]; var newValue = customizer ? customizer(object[key], source[key], key, object, source) : undefined; if (newValue === undefined) { newValue = source[key]; } if (isNew) { baseAssignValue(object, key, newValue); } else { assignValue(object, key, newValue); } } return object; } /** * The base implementation of `_.times` without support for iteratee shorthands * or max array length checks. * * @private * @param {number} n The number of times to invoke `iteratee`. * @param {Function} iteratee The function invoked per iteration. * @returns {Array} Returns the array of results. */ function baseTimes(n, iteratee) { var index = -1, result = Array(n); while (++index < n) { result[index] = iteratee(index); } return result; } /** Used as references for various `Number` constants. */ var MAX_SAFE_INTEGER = 9007199254740991; /** Used to detect unsigned integer values. */ var reIsUint = /^(?:0|[1-9]\d*)$/; /** * Checks if `value` is a valid array-like index. * * @private * @param {*} value The value to check. * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index. * @returns {boolean} Returns `true` if `value` is a valid index, else `false`. */ function isIndex(value, length) { var type = typeof value; length = length == null ? MAX_SAFE_INTEGER : length; return !!length && (type == 'number' || (type != 'symbol' && reIsUint.test(value))) && (value > -1 && value % 1 == 0 && value < length); } /** Used for built-in method references. */ var objectProto$5 = Object.prototype; /** Used to check objects for own properties. */ var hasOwnProperty$4 = objectProto$5.hasOwnProperty; /** * Creates an array of the enumerable property names of the array-like `value`. * * @private * @param {*} value The value to query. * @param {boolean} inherited Specify returning inherited property names. * @returns {Array} Returns the array of property names. */ function arrayLikeKeys(value, inherited) { var isArr = isArray(value), isArg = !isArr && isArguments(value), isBuff = !isArr && !isArg && isBuffer(value), isType = !isArr && !isArg && !isBuff && isTypedArray(value), skipIndexes = isArr || isArg || isBuff || isType, result = skipIndexes ? baseTimes(value.length, String) : [], length = result.length; for (var key in value) { if ((inherited || hasOwnProperty$4.call(value, key)) && !(skipIndexes && ( // Safari 9 has enumerable `arguments.length` in strict mode. key == 'length' || // Node.js 0.10 has enumerable non-index properties on buffers. (isBuff && (key == 'offset' || key == 'parent')) || // PhantomJS 2 has enumerable non-index properties on typed arrays. (isType && (key == 'buffer' || key == 'byteLength' || key == 'byteOffset')) || // Skip index properties. isIndex(key, length) ))) { result.push(key); } } return result; } /** * This function is like * [`Object.keys`](http://ecma-international.org/ecma-262/7.0/#sec-object.keys) * except that it includes inherited enumerable properties. * * @private * @param {Object} object The object to query. * @returns {Array} Returns the array of property names. */ function nativeKeysIn(object) { var result = []; if (object != null) { for (var key in Object(object)) { result.push(key); } } return result; } /** Used for built-in method references. */ var objectProto$4 = Object.prototype; /** Used to check objects for own properties. */ var hasOwnProperty$3 = objectProto$4.hasOwnProperty; /** * The base implementation of `_.keysIn` which doesn't treat sparse arrays as dense. * * @private * @param {Object} object The object to query. * @returns {Array} Returns the array of property names. */ function baseKeysIn(object) { if (!isObject(object)) { return nativeKeysIn(object); } var isProto = isPrototype(object), result = []; for (var key in object) { if (!(key == 'constructor' && (isProto || !hasOwnProperty$3.call(object, key)))) { result.push(key); } } return result; } /** * Creates an array of the own and inherited enumerable property names of `object`. * * **Note:** Non-object values are coerced to objects. * * @static * @memberOf _ * @since 3.0.0 * @category Object * @param {Object} object The object to query. * @returns {Array} Returns the array of property names. * @example * * function Foo() { * this.a = 1; * this.b = 2; * } * * Foo.prototype.c = 3; * * _.keysIn(new Foo); * // => ['a', 'b', 'c'] (iteration order is not guaranteed) */ function keysIn(object) { return isArrayLike(object) ? arrayLikeKeys(object, true) : baseKeysIn(object); } /** * Converts `value` to a plain object flattening inherited enumerable string * keyed properties of `value` to own properties of the plain object. * * @static * @memberOf _ * @since 3.0.0 * @category Lang * @param {*} value The value to convert. * @returns {Object} Returns the converted plain object. * @example * * function Foo() { * this.b = 2; * } * * Foo.prototype.c = 3; * * _.assign({ 'a': 1 }, new Foo); * // => { 'a': 1, 'b': 2 } * * _.assign({ 'a': 1 }, _.toPlainObject(new Foo)); * // => { 'a': 1, 'b': 2, 'c': 3 } */ function toPlainObject(value) { return copyObject(value, keysIn(value)); } /** * A specialized version of `baseMerge` for arrays and objects which performs * deep merges and tracks traversed objects enabling objects with circular * references to be merged. * * @private * @param {Object} object The destination object. * @param {Object} source The source object. * @param {string} key The key of the value to merge. * @param {number} srcIndex The index of `source`. * @param {Function} mergeFunc The function to merge values. * @param {Function} [customizer] The function to customize assigned values. * @param {Object} [stack] Tracks traversed source values and their merged * counterparts. */ function baseMergeDeep(object, source, key, srcIndex, mergeFunc, customizer, stack) { var objValue = safeGet(object, key), srcValue = safeGet(source, key), stacked = stack.get(srcValue); if (stacked) { assignMergeValue(object, key, stacked); return; } var newValue = customizer ? customizer(objValue, srcValue, (key + ''), object, source, stack) : undefined; var isCommon = newValue === undefined; if (isCommon) { var isArr = isArray(srcValue), isBuff = !isArr && isBuffer(srcValue), isTyped = !isArr && !isBuff && isTypedArray(srcValue); newValue = srcValue; if (isArr || isBuff || isTyped) { if (isArray(objValue)) { newValue = objValue; } else if (isArrayLikeObject(objValue)) { newValue = copyArray(objValue); } else if (isBuff) { isCommon = false; newValue = cloneBuffer(srcValue, true); } else if (isTyped) { isCommon = false; newValue = cloneTypedArray(srcValue, true); } else { newValue = []; } } else if (isPlainObject(srcValue) || isArguments(srcValue)) { newValue = objValue; if (isArguments(objValue)) { newValue = toPlainObject(objValue); } else if (!isObject(objValue) || isFunction(objValue)) { newValue = initCloneObject(srcValue); } } else { isCommon = false; } } if (isCommon) { // Recursively merge objects and arrays (susceptible to call stack limits). stack.set(srcValue, newValue); mergeFunc(newValue, srcValue, srcIndex, customizer, stack); stack['delete'](srcValue); } assignMergeValue(object, key, newValue); } /** * The base implementation of `_.merge` without support for multiple sources. * * @private * @param {Object} object The destination object. * @param {Object} source The source object. * @param {number} srcIndex The index of `source`. * @param {Function} [customizer] The function to customize merged values. * @param {Object} [stack] Tracks traversed source values and their merged * counterparts. */ function baseMerge(object, source, srcIndex, customizer, stack) { if (object === source) { return; } baseFor(source, function(srcValue, key) { stack || (stack = new Stack); if (isObject(srcValue)) { baseMergeDeep(object, source, key, srcIndex, baseMerge, customizer, stack); } else { var newValue = customizer ? customizer(safeGet(object, key), srcValue, (key + ''), object, source, stack) : undefined; if (newValue === undefined) { newValue = srcValue; } assignMergeValue(object, key, newValue); } }, keysIn); } /** * This method returns the first argument it receives. * * @static * @since 0.1.0 * @memberOf _ * @category Util * @param {*} value Any value. * @returns {*} Returns `value`. * @example * * var object = { 'a': 1 }; * * console.log(_.identity(object) === object); * // => true */ function identity(value) { return value; } /** * A faster alternative to `Function#apply`, this function invokes `func` * with the `this` binding of `thisArg` and the arguments of `args`. * * @private * @param {Function} func The function to invoke. * @param {*} thisArg The `this` binding of `func`. * @param {Array} args The arguments to invoke `func` with. * @returns {*} Returns the result of `func`. */ function apply(func, thisArg, args) { switch (args.length) { case 0: return func.call(thisArg); case 1: return func.call(thisArg, args[0]); case 2: return func.call(thisArg, args[0], args[1]); case 3: return func.call(thisArg, args[0], args[1], args[2]); } return func.apply(thisArg, args); } /* Built-in method references for those with the same name as other `lodash` methods. */ var nativeMax = Math.max; /** * A specialized version of `baseRest` which transforms the rest array. * * @private * @param {Function} func The function to apply a rest parameter to. * @param {number} [start=func.length-1] The start position of the rest parameter. * @param {Function} transform The rest array transform. * @returns {Function} Returns the new function. */ function overRest(func, start, transform) { start = nativeMax(start === undefined ? (func.length - 1) : start, 0); return function() { var args = arguments, index = -1, length = nativeMax(args.length - start, 0), array = Array(length); while (++index < length) { array[index] = args[start + index]; } index = -1; var otherArgs = Array(start + 1); while (++index < start) { otherArgs[index] = args[index]; } otherArgs[start] = transform(array); return apply(func, this, otherArgs); }; } /** * Creates a function that returns `value`. * * @static * @memberOf _ * @since 2.4.0 * @category Util * @param {*} value The value to return from the new function. * @returns {Function} Returns the new constant function. * @example * * var objects = _.times(2, _.constant({ 'a': 1 })); * * console.log(objects); * // => [{ 'a': 1 }, { 'a': 1 }] * * console.log(objects[0] === objects[1]); * // => true */ function constant(value) { return function() { return value; }; } /** * The base implementation of `setToString` without support for hot loop shorting. * * @private * @param {Function} func The function to modify. * @param {Function} string The `toString` result. * @returns {Function} Returns `func`. */ var baseSetToString = !defineProperty ? identity : function(func, string) { return defineProperty(func, 'toString', { 'configurable': true, 'enumerable': false, 'value': constant(string), 'writable': true }); }; var baseSetToString$1 = baseSetToString; /** Used to detect hot functions by number of calls within a span of milliseconds. */ var HOT_COUNT = 800, HOT_SPAN = 16; /* Built-in method references for those with the same name as other `lodash` methods. */ var nativeNow = Date.now; /** * Creates a function that'll short out and invoke `identity` instead * of `func` when it's called `HOT_COUNT` or more times in `HOT_SPAN` * milliseconds. * * @private * @param {Function} func The function to restrict. * @returns {Function} Returns the new shortable function. */ function shortOut(func) { var count = 0, lastCalled = 0; return function() { var stamp = nativeNow(), remaining = HOT_SPAN - (stamp - lastCalled); lastCalled = stamp; if (remaining > 0) { if (++count >= HOT_COUNT) { return arguments[0]; } } else { count = 0; } return func.apply(undefined, arguments); }; } /** * Sets the `toString` method of `func` to return `string`. * * @private * @param {Function} func The function to modify. * @param {Function} string The `toString` result. * @returns {Function} Returns `func`. */ var setToString = shortOut(baseSetToString$1); /** * The base implementation of `_.rest` which doesn't validate or coerce arguments. * * @private * @param {Function} func The function to apply a rest parameter to. * @param {number} [start=func.length-1] The start position of the rest parameter. * @returns {Function} Returns the new function. */ function baseRest(func, start) { return setToString(overRest(func, start, identity), func + ''); } /** * Checks if the given arguments are from an iteratee call. * * @private * @param {*} value The potential iteratee value argument. * @param {*} index The potential iteratee index or key argument. * @param {*} object The potential iteratee object argument. * @returns {boolean} Returns `true` if the arguments are from an iteratee call, * else `false`. */ function isIterateeCall(value, index, object) { if (!isObject(object)) { return false; } var type = typeof index; if (type == 'number' ? (isArrayLike(object) && isIndex(index, object.length)) : (type == 'string' && index in object) ) { return eq(object[index], value); } return false; } /** * Creates a function like `_.assign`. * * @private * @param {Function} assigner The function to assign values. * @returns {Function} Returns the new assigner function. */ function createAssigner(assigner) { return baseRest(function(object, sources) { var index = -1, length = sources.length, customizer = length > 1 ? sources[length - 1] : undefined, guard = length > 2 ? sources[2] : undefined; customizer = (assigner.length > 3 && typeof customizer == 'function') ? (length--, customizer) : undefined; if (guard && isIterateeCall(sources[0], sources[1], guard)) { customizer = length < 3 ? undefined : customizer; length = 1; } object = Object(object); while (++index < length) { var source = sources[index]; if (source) { assigner(object, source, index, customizer); } } return object; }); } /** * This method is like `_.assign` except that it recursively merges own and * inherited enumerable string keyed properties of source objects into the * destination object. Source properties that resolve to `undefined` are * skipped if a destination value exists. Array and plain object properties * are merged recursively. Other objects and value types are overridden by * assignment. Source objects are applied from left to right. Subsequent * sources overwrite property assignments of previous sources. * * **Note:** This method mutates `object`. * * @static * @memberOf _ * @since 0.5.0 * @category Object * @param {Object} object The destination object. * @param {...Object} [sources] The source objects. * @returns {Object} Returns `object`. * @example * * var object = { * 'a': [{ 'b': 2 }, { 'd': 4 }] * }; * * var other = { * 'a': [{ 'c': 3 }, { 'e': 5 }] * }; * * _.merge(object, other); * // => { 'a': [{ 'b': 2, 'c': 3 }, { 'd': 4, 'e': 5 }] } */ var merge = createAssigner(function(object, source, srcIndex) { baseMerge(object, source, srcIndex); }); const sdenv = { adapt: {}, // 适配专用网站方法 tools: {}, // 内部工具 utils: {}, // 外部方法 config: { proxyOpen: false, // 是否允许开启代理 randomReturn: undefined, // 随机数值固定 randomFixed: false, // 固定日期与随机数,文件:@/config/dateAndRandom.json // 强制setInterval的时间设置,如设置的足够大让执行函数不运行,其中:undefined表示通过框架拦截并计算运行时间,0表示不拦截且使用原时间 timeInterval: undefined, timeTimeout: undefined, // 与timeInterval功能类似,区别是控制setTimeout isNode: typeof window === 'undefined', // node环境标识 }, memory: { runinfo: { // 程序运行时间节点 start: new Date().getTime(), // 代码开始运行 isDied: false, // 窗口生命是否已经结束 }, timeout: null, // 存放处理setTimeout/setInterval的类 sdEval: eval, // node内置eval sdWindow: typeof window !== 'undefined' ? window : global, sdFunction: Function, sdDate: Date, sdMath: Math, SdenvExtend: null, // node环境缓存sdenv-extend插件,用于浏览器环境使用 }, cache: { dynamicCode: [], // 缓存动态生成代码 runloop: {}, // 缓存循环代码运行时 /* 缓存循环执行顺序 sdenv.cache.runsArr .map((it, num) => ({idx: it.idx, num, ...it.val})) .reduce((ans, it) => ( ans[it.idx] === undefined ? ans[it.idx] = [it] : ans[it.idx].push(it), ans ), {}) */ runsArr: [], runsObj: [], // 缓存循环递归树 runtime: {}, // 存放运行时数据的代理 monitor: {}, // 监控变量对象 }, // 存储缓存数据 datas: { dateAndRandom: {}, // 随机数相关数据 }, }; /** * A specialized version of `_.map` for arrays without support for iteratee * shorthands. * * @private * @param {Array} [array] The array to iterate over. * @param {Function} iteratee The function invoked per iteration. * @returns {Array} Returns the new mapped array. */ function arrayMap(array, iteratee) { var index = -1, length = array == null ? 0 : array.length, result = Array(length); while (++index < length) { result[index] = iteratee(array[index], index, array); } return result; } /** `Object#toString` result references. */ var symbolTag$1 = '[object Symbol]'; /** * Checks if `value` is classified as a `Symbol` primitive or object. * * @static * @memberOf _ * @since 4.0.0 * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is a symbol, else `false`. * @example * * _.isSymbol(Symbol.iterator); * // => true * * _.isSymbol('abc'); * // => false */ function isSymbol(value) { return typeof value == 'symbol' || (isObjectLike(value) && baseGetTag(value) == symbolTag$1); } /** Used to match property names within property paths. */ var reIsDeepProp = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/, reIsPlainProp = /^\w*$/; /** * Checks if `value` is a property name and not a property path. * * @private * @param {*} value The value to check. * @param {Object} [object] The object to query keys on. * @returns {boolean} Returns `true` if `value` is a property name, else `false`. */ function isKey(value, object) { if (isArray(value)) { return false; } var type = typeof value; if (type == 'number' || type == 'symbol' || type == 'boolean' || value == null || isSymbol(value)) { return true; } return reIsPlainProp.test(value) || !reIsDeepProp.test(value) || (object != null && value in Object(object)); } /** Error message constants. */ var FUNC_ERROR_TEXT = 'Expected a function'; /** * Creates a function that memoizes the result of `func`. If `resolver` is * provided, it determines the cache key for storing the result based on the * arguments provided to the memoized function. By default, the first argument * provided to the memoized function is used as the map cache key. The `func` * is invoked with the `this` binding of the memoized function. * * **Note:** The cache is exposed as the `cache` property on the memoized * function. Its creation may be customized by replacing the `_.memoize.Cache` * constructor with one whose instances implement the * [`Map`](http://ecma-international.org/ecma-262/7.0/#sec-properties-of-the-map-prototype-object) * method interface of `clear`, `delete`, `get`, `has`, and `set`. * * @static * @memberOf _ * @since 0.1.0 * @category Function * @param {Function} func The function to have its output memoized. * @param {Function} [resolver] The function to resolve the cache key. * @returns {Function} Returns the new memoized function. * @example * * var object = { 'a': 1, 'b': 2 }; * var other = { 'c': 3, 'd': 4 }; * * var values = _.memoize(_.values); * values(object); * // => [1, 2] * * values(other); * // => [3, 4] * * object.a = 2; * values(object); * // => [1, 2] * * // Modify the result cache. * values.cache.set(object, ['a', 'b']); * values(object); * // => ['a', 'b'] * * // Replace `_.memoize.Cache`. * _.memoize.Cache = WeakMap; */ function memoize(func, resolver) { if (typeof func != 'function' || (resolver != null && typeof resolver != 'function')) { throw new TypeError(FUNC_ERROR_TEXT); } var memoized = function() { var args = arguments, key = resolver ? resolver.apply(this, args) : args[0], cache = memoized.cache; if (cache.has(key)) { return cache.get(key); } var result = func.apply(this, args); memoized.cache = cache.set(key, result) || cache; return result; }; memoized.cache = new (memoize.Cache || MapCache); return memoized; } // Expose `MapCache`. memoize.Cache = MapCache; /** Used as the maximum memoize cache size. */ var MAX_MEMOIZE_SIZE = 500; /** * A specialized version of `_.memoize` which clears the memoized function's * cache when it exceeds `MAX_MEMOIZE_SIZE`. * * @private * @param {Function} func The function to have its output memoized. * @returns {Function} Returns the new memoized function. */ function memoizeCapped(func) { var result = memoize(func, function(key) { if (cache.size === MAX_MEMOIZE_SIZE) { cache.clear(); } return key; }); var cache = result.cache; return result; } /** Used to match property names within property paths. */ var rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g; /** Used to match backslashes in property paths. */ var reEscapeChar = /\\(\\)?/g; /** * Converts `string` to a property path array. * * @private * @param {string} string The string to convert. * @returns {Array} Returns the property path array. */ var stringToPath = memoizeCapped(function(string) { var result = []; if (string.charCodeAt(0) === 46 /* . */) { result.push(''); } string.replace(rePropName, function(match, number, quote, subString) { result.push(quote ? subString.replace(reEscapeChar, '$1') : (number || match)); }); return result; }); /** Used as references for various `Number` constants. */ var INFINITY$2 = 1 / 0; /** Used to convert symbols to primitives and strings. */ var symbolProto$1 = Symbol$1 ? Symbol$1.prototype : undefined, symbolToString = symbolProto$1 ? symbolProto$1.toString : undefined; /** * The base implementation of `_.toString` which doesn't convert nullish * values to empty strings. * * @private * @param {*} value The value to process. * @returns {string} Returns the string. */ function baseToString(value) { // Exit early for strings to avoid a performance hit in some environments. if (typeof value == 'string') { return value; } if (isArray(value)) { // Recursively convert values (susceptible to call stack limits). return arrayMap(value, baseToString) + ''; } if (isSymbol(value)) { return symbolToString ? symbolToString.call(value) : ''; } var result = (value + ''); return (result == '0' && (1 / value) == -INFINITY$2) ? '-0' : result; } /** * Converts `value` to a string. An empty string is returned for `null` * and `undefined` values. The sign of `-0` is preserved. * * @static * @memberOf _ * @since 4.0.0 * @category Lang * @param {*} value The value to convert. * @returns {string} Returns the converted string. * @example * * _.toString(null); * // => '' * * _.toString(-0); * // => '-0' * * _.toString([1, 2, 3]); * // => '1,2,3' */ function toString$1(value) { return value == null ? '' : baseToString(value); } /** * Casts `value` to a path array if it's not one. * * @private * @param {*} value The value to inspect. * @param {Object} [object] The object to query keys on. * @returns {Array} Returns the cast property path array. */ function castPath(value, object) { if (isArray(value)) { return value; } return isKey(value, object) ? [value] : stringToPath(toString$1(value)); } /** Used as references for various `Number` constants. */ var INFINITY$1 = 1 / 0; /** * Converts `value` to a string key if it's not a string or symbol. * * @private * @param {*} value The value to inspect. * @returns {string|symbol} Returns the key. */ function toKey(value) { if (typeof value == 'string' || isSymbol(value)) { return value; } var result = (value + ''); return (result == '0' && (1 / value) == -INFINITY$1) ? '-0' : result; } /** * The base implementation of `_.get` without support for default values. * * @private * @param {Object} object The object to query. * @param {Array|string} path The path of the property to get. * @returns {*} Returns the resolved value. */ function baseGet(object, path) { path = castPath(path, object); var index = 0, length = path.length; while (object != null && index < length) { object = object[toKey(path[index++])]; } return (index && index == length) ? object : undefined; } /** Used to stand-in for `undefined` hash values. */ var HASH_UNDEFINED = '__lodash_hash_undefined__'; /** * Adds `value` to the array cache. * * @private * @name add * @memberOf SetCache * @alias push * @param {*} value The value to cache. * @returns {Object} Returns the cache instance. */ function setCacheAdd(value) { this.__data__.set(value, HASH_UNDEFINED); return this; } /** * Checks if `value` is in the array cache. * * @private * @name has * @memberOf SetCache * @param {*} value The value to search for. * @returns {number} Returns `true` if `value` is found, else `false`. */ function setCacheHas(value) { return this.__data__.has(value); } /** * * Creates an array cache object to store unique values. * * @private * @constructor * @param {Array} [values] The values to cache. */ function SetCache(values) { var index = -1, length = values == null ? 0 : values.length; this.__data__ = new MapCache; while (++index < length) { this.add(values[index]); } } // Add methods to `SetCache`. SetCache.prototype.add = SetCache.prototype.push = setCacheAdd; SetCache.prototype.has = setCacheHas; /** * A specialized version of `_.some` for arrays without support for iteratee * shorthands. * * @private * @param {Array} [array] The array to iterate over. * @param {Function} predicate The function invoked per iteration. * @returns {boolean} Returns `true` if any element passes the predicate check, * else `false`. */ function arraySome(array, predicate) { var index = -1, length = array == null ? 0 : array.length; while (++index < length) { if (predicate(array[index], index, array)) { return true; } } return false; } /** * Checks if a `cache` value for `key` exists. * * @private * @param {Object} cache The cache to query. * @param {string} key The key of the entry to check. * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. */ function cacheHas(cache, key) { return cache.has(key); } /** Used to compose bitmasks for value comparisons. */ var COMPARE_PARTIAL_FLAG$5 = 1, COMPARE_UNORDERED_FLAG$3 = 2; /** * A specialized version of `baseIsEqualDeep` for arrays with support for * partial deep comparisons. * * @private * @param {Array} array The array to compare. * @param {Array} other The other array to compare. * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details. * @param {Function} customizer The function to customize comparisons. * @param {Function} equalFunc The function to determine equivalents of values. * @param {Object} stack Tracks traversed `array` and `other` objects. * @returns {boolean} Returns `true` if the arrays are equivalent, else `false`. */ function equalArrays(array, other, bitmask, customizer, equalFunc, stack) { var isPartial = bitmask & COMPARE_PARTIAL_FLAG$5, arrLength = array.length, othLength = other.length; if (arrLength != othLength && !(isPartial && othLength > arrLength)) { return false; } // Check that cyclic values are equal. var arrStacked = stack.get(array); var othStacked = stack.get(other); if (arrStacked && othStacked) { return arrStacked == other && othStacked == array; } var index = -1, result = true, seen = (bitmask & COMPARE_UNORDERED_FLAG$3) ? new SetCache : undefined; stack.set(array, other); stack.set(other, array); // Ignore non-index properties. while (++index < arrLength) { var arrValue = array[index], othValue = other[index]; if (customizer) { var compared = isPartial ? customizer(othValue, arrValue, index, other, array, stack) : customizer(arrValue, othValue, index, array, other, stack); } if (compared !== undefined) { if (compared) { continue; } result = false; break; } // Recursively compare arrays (susceptible to call stack limits). if (seen) { if (!arraySome(other, function(othValue, othIndex) { if (!cacheHas(seen, othIndex) && (arrValue === othValue || equalFunc(arrValue, othValue, bitmask, customizer, stack))) { return seen.push(othIndex); } })) { result = false; break; } } else if (!( arrValue === othValue || equalFunc(arrValue, othValue, bitmask, customizer, stack) )) { result = false; break; } } stack['delete'](array); stack['delete'](other); return result; } /** * Converts `map` to its key-value pairs. * * @private * @param {Object} map The map to convert. * @returns {Array} Returns the key-value pairs. */ function mapToArray(map) { var index = -1, result = Array(map.size); map.forEach(function(value, key) { result[++index] = [key, value]; }); return result; } /** * Converts `set` to an array of its values. * * @private * @param {Object} set The set to convert. * @returns {Array} Returns the values. */ function setToArray(set) { var index = -1, result = Array(set.size); set.forEach(function(value) { result[++index] = value; }); return result; } /** Used to compose bitmasks for value comparisons. */ var COMPARE_PARTIAL_FLAG$4 = 1, COMPARE_UNORDERED_FLAG$2 = 2; /** `Object#toString` result references. */ var boolTag = '[object Boolean]', dateTag = '[object Date]', errorTag = '[object Error]', mapTag$1 = '[object Map]', numberTag = '[object Number]', regexpTag = '[object RegExp]', setTag$1 = '[object Set]', stringTag = '[object String]', symbolTag = '[object Symbol]'; var arrayBufferTag = '[object ArrayBuffer]', dataViewTag$1 = '[object DataView]'; /** Used to convert symbols to primitives and strings. */ var symbolProto = Symbol$1 ? Symbol$1.prototype : undefined, symbolValueOf = symbolProto ? symbolProto.valueOf : undefined; /** * A specialized version of `baseIsEqualDeep` for comparing objects of * the same `toStringTag`. * * **Note:** This function only supports comparing values with tags of * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`. * * @private * @param {Object} object The object to compare. * @param {Object} other The other object to compare. * @param {string} tag The `toStringTag` of the objects to compare. * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details. * @param {Function} customizer The function to customize comparisons. * @param {Function} equalFunc The function to determine equivalents of values. * @param {Object} stack Tracks traversed `object` and `other` objects. * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. */ function equalByTag(object, other, tag, bitmask, customizer, equalFunc, stack) { switch (tag) { case dataViewTag$1: if ((object.byteLength != other.byteLength) || (object.byteOffset != other.byteOffset)) { return false; } object = object.buffer; other = other.buffer; case arrayBufferTag: if ((object.byteLength != other.byteLength) || !equalFunc(new Uint8Array(object), new Uint8Array(other))) { return false; } return true; case boolTag: case dateTag: case numberTag: // Coerce booleans to `1` or `0` and dates to milliseconds. // Invalid dates are coerced to `NaN`. return eq(+object, +other); case errorTag: return object.name == other.name && object.message == other.message; case regexpTag: case stringTag: // Coerce regexes to strings and treat strings, primitives and objects, // as equal. See http://www.ecma-international.org/ecma-262/7.0/#sec-regexp.prototype.tostring // for more details. return object == (other + ''); case mapTag$1: var convert = mapToArray; case setTag$1: var isPartial = bitmask & COMPARE_PARTIAL_FLAG$4; convert || (convert = setToArray); if (object.size != other.size && !isPartial) { return false; } // Assume cyclic values are equal. var stacked = stack.get(object); if (stacked) { return stacked == other; } bitmask |= COMPARE_UNORDERED_FLAG$2; // Recursively compare objects (susceptible to call stack limits). stack.set(object, other); var result = equalArrays(convert(object), convert(other), bitmask, customizer, equalFunc, stack); stack['delete'](object); return result; case symbolTag: if (symbolValueOf) { return symbolValueOf.call(object) == symbolValueOf.call(other); } } return false; } /** * Appends the elements of `values` to `array`. * * @private * @param {Array} array The array to modify. * @param {Array} values The values to append. * @returns {Array} Returns `array`. */ function arrayPush(array, values) { var index = -1, length = values.length, offset = array.length; while (++index < length) { array[offset + index] = values[index]; } return array; } /** * The base implementation of `getAllKeys` and `getAllKeysIn` which uses * `keysFunc` and `symbolsFunc` to get the enumerable property names and * symbols of `object`. * * @private * @param {Object} object The object to query. * @param {Function} keysFunc The function to get the keys of `object`. * @param {Function} symbolsFunc The function to get the symbols of `object`. * @returns {Array} Returns the array of property names and symbols. */ function baseGetAllKeys(object, keysFunc, symbolsFunc) { var result = keysFunc(object); return isArray(object) ? result : arrayPush(result, symbolsFunc(object)); } /** * A specialized version of `_.filter` for arrays without support for * iteratee shorthands. * * @private * @param {Array} [array] The array to iterate over. * @param {Function} predicate The function invoked per iteration. * @returns {Array} Returns the new filtered array. */ function arrayFilter(array, predicate) { var index = -1, length = array == null ? 0 : array.length, resIndex = 0, result = []; while (++index < length) { var value = array[index]; if (predicate(value, index, array)) { result[resIndex++] = value; } } return result; } /** * This method returns a new empty array. * * @static * @memberOf _ * @since 4.13.0 * @category Util * @returns {Array} Returns the new empty array. * @example * * var arrays = _.times(2, _.stubArray); * * console.log(arrays); * // => [[], []] * * console.log(arrays[0] === arrays[1]); * // => false */ function stubArray() { return []; } /** Used for built-in method references. */ var objectProto$3 = Object.prototype; /** Built-in value references. */ var propertyIsEnumerable = objectProto$3.propertyIsEnumerable; /* Built-in method references for those with the same name as other `lodash` methods. */ var nativeGetSymbols = Object.getOwnPropertySymbols; /** * Creates an array of the own enumerable symbols of `object`. * * @private * @param {Object} object The object to query. * @returns {Array} Returns the array of symbols. */ var getSymbols = !nativeGetSymbols ? stubArray : function(object) { if (object == null) { return []; } object = Object(object); return arrayFilter(nativeGetSymbols(object), function(symbol) { return propertyIsEnumerable.call(object, symbol); }); }; var getSymbols$1 = getSymbols; /* Built-in method references for those with the same name as other `lodash` methods. */ var nativeKeys = overArg(Object.keys, Object); /** Used for built-in method references. */ var objectProto$2 = Object.prototype; /** Used to check objects for own properties. */ var hasOwnProperty$2 = objectProto$2.hasOwnProperty; /** * The base implementation of `_.keys` which doesn't treat sparse arrays as dense. * * @private * @param {Object} object The object to query. * @returns {Array} Returns the array of property names. */ function baseKeys(object) { if (!isPrototype(object)) { return nativeKeys(object); } var result = []; for (var key in Object(object)) { if (hasOwnProperty$2.call(object, key) && key != 'constructor') { result.push(key); } } return result; } /** * Creates an array of the own enumerable property names of `object`. * * **Note:** Non-object values are coerced to objects. See the * [ES spec](http://ecma-international.org/ecma-262/7.0/#sec-object.keys) * for more details. * * @static * @since 0.1.0 * @memberOf _ * @category Object * @param {Object} object The object to query. * @returns {Array} Returns the array of property names. * @example * * function Foo() { * this.a = 1; * this.b = 2; * } * * Foo.prototype.c = 3; * * _.keys(new Foo); * // => ['a', 'b'] (iteration order is not guaranteed) * * _.keys('hi'); * // => ['0', '1'] */ function keys(object) { return isArrayLike(object) ? arrayLikeKeys(object) : baseKeys(object); } /** * Creates an array of own enumerable property names and symbols of `object`. * * @private * @param {Object} object The object to query. * @returns {Array} Returns the array of property names and symbols. */ function getAllKeys(object) { return baseGetAllKeys(object, keys, getSymbols$1); } /** Used to compose bitmasks for value comparisons. */ var COMPARE_PARTIAL_FLAG$3 = 1; /** Used for built-in method references. */ var objectProto$1 = Object.prototype; /** Used to check objects for own properties. */ var hasOwnProperty$1 = objectProto$1.hasOwnProperty; /** * A specialized version of `baseIsEqualDeep` for objects with support for * partial deep comparisons. * * @private * @param {Object} object The object to compare. * @param {Object} other The other object to compare. * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details. * @param {Function} customizer The function to customize comparisons. * @param {Function} equalFunc The function to determine equivalents of values. * @param {Object} stack Tracks traversed `object` and `other` objects. * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. */ function equalObjects(object, other, bitmask, customizer, equalFunc, stack) { var isPartial = bitmask & COMPARE_PARTIAL_FLAG$3, objProps = getAllKeys(object), objLength = objProps.length, othProps = getAllKeys(other), othLength = othProps.length; if (objLength != othLength && !isPartial) { return false; } var index = objLength; while (index--) { var key = objProps[index]; if (!(isPartial ? key in other : hasOwnProperty$1.call(other, key))) { return false; } } // Check that cyclic values are equal. var objStacked = stack.get(object); var othStacked = stack.get(other); if (objStacked && othStacked) { return objStacked == other && othStacked == object; } var result = true; stack.set(object, other); stack.set(other, object); var skipCtor = isPartial; while (++index < objLength) { key = objProps[index]; var objValue = object[key], othValue = other[key]; if (customizer) { var compared = isPartial ? customizer(othValue, objValue, key, other, object, stack) : customizer(objValue, othValue, key, object, other, stack); } // Recursively compare objects (susceptible to call stack limits). if (!(compared === undefined ? (objValue === othValue || equalFunc(objValue, othValue, bitmask, customizer, stack)) : compared )) { result = false; break; } skipCtor || (skipCtor = key == 'constructor'); } if (result && !skipCtor) { var objCtor = object.constructor, othCtor = other.constructor; // Non `Object` object instances with different constructors are not equal. if (objCtor != othCtor && ('constructor' in object && 'constructor' in other) && !(typeof objCtor == 'function' && objCtor instanceof objCtor && typeof othCtor == 'function' && othCtor instanceof othCtor)) { result = false; } } stack['delete'](object); stack['delete'](other); return result; } /* Built-in method references that are verified to be native. */ var DataView = getNative(root, 'DataView'); var DataView$1 = DataView; /* Built-in method references that are verified to be native. */ var Promise$1 = getNative(root, 'Promise'); var Promise$2 = Promise$1; /* Built-in method references that are verified to be native. */ var Set = getNative(root, 'Set'); var Set$1 = Set; /* Built-in method references that are verified to be native. */ var WeakMap = getNative(root, 'WeakMap'); var WeakMap$1 = WeakMap; /** `Object#toString` result references. */ var mapTag = '[object Map]', objectTag$1 = '[object Object]', promiseTag = '[object Promise]', setTag = '[object Set]', weakMapTag = '[object WeakMap]'; var dataViewTag = '[object DataView]'; /** Used to detect maps, sets, and weakmaps. */ var dataViewCtorString = toSource(DataView$1), mapCtorString = toSource(Map), promiseCtorString = toSource(Promise$2), setCtorString = toSource(Set$1), weakMapCtorString = toSource(WeakMap$1); /** * Gets the `toStringTag` of `value`. * * @private * @param {*} value The value to query. * @returns {string} Returns the `toStringTag`. */ var getTag = baseGetTag; // Fallback for data views, maps, sets, and weak maps in IE 11 and promises in Node.js < 6. if ((DataView$1 && getTag(new DataView$1(new ArrayBuffer(1))) != dataViewTag) || (Map && getTag(new Map) != mapTag) || (Promise$2 && getTag(Promise$2.resolve()) != promiseTag) || (Set$1 && getTag(new Set$1) != setTag) || (WeakMap$1 && getTag(new WeakMap$1) != weakMapTag)) { getTag = function(value) { var result = baseGetTag(value), Ctor = result == objectTag$1 ? value.constructor : undefined, ctorString = Ctor ? toSource(Ctor) : ''; if (ctorString) { switch (ctorString) { case dataViewCtorString: return dataViewTag; case mapCtorString: return mapTag; case promiseCtorString: return promiseTag; case setCtorString: return setTag; case weakMapCtorString: return weakMapTag; } } return result; }; } var getTag$1 = getTag; /** Used to compose bitmasks for value comparisons. */ var COMPARE_PARTIAL_FLAG$2 = 1; /** `Object#toString` result references. */ var argsTag = '[object Arguments]', arrayTag = '[object Array]', objectTag = '[object Object]'; /** Used for built-in method references. */ var objectProto = Object.prototype; /** Used to check objects for own properties. */ var hasOwnProperty = objectProto.hasOwnProperty; /** * A specialized version of `baseIsEqual` for arrays and objects which performs * deep comparisons and tracks traversed objects enabling objects with circular * references to be compared. * * @private * @param {Object} object The object to compare. * @param {Object} other The other object to compare. * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details. * @param {Function} customizer The function to customize comparisons. * @param {Function} equalFunc The function to determine equivalents of values. * @param {Object} [stack] Tracks traversed `object` and `other` objects. * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. */ function baseIsEqualDeep(object, other, bitmask, customizer, equalFunc, stack) { var objIsArr = isArray(object), othIsArr = isArray(other), objTag = objIsArr ? arrayTag : getTag$1(object), othTag = othIsArr ? arrayTag : getTag$1(other); objTag = objTag == argsTag ? objectTag : objTag; othTag = othTag == argsTag ? objectTag : othTag; var objIsObj = objTag == objectTag, othIsObj = othTag == objectTag, isSameTag = objTag == othTag; if (isSameTag && isBuffer(object)) { if (!isBuffer(other)) { return false; } objIsArr = true; objIsObj = false; } if (isSameTag && !objIsObj) { stack || (stack = new Stack); return (objIsArr || isTypedArray(object)) ? equalArrays(object, other, bitmask, customizer, equalFunc, stack) : equalByTag(object, other, objTag, bitmask, customizer, equalFunc, stack); } if (!(bitmask & COMPARE_PARTIAL_FLAG$2)) { var objIsWrapped = objIsObj && hasOwnProperty.call(object, '__wrapped__'), othIsWrapped = othIsObj && hasOwnProperty.call(other, '__wrapped__'); if (objIsWrapped || othIsWrapped) { var objUnwrapped = objIsWrapped ? object.value() : object, othUnwrapped = othIsWrapped ? other.value() : other; stack || (stack = new Stack); return equalFunc(objUnwrapped, othUnwrapped, bitmask, customizer, stack); } } if (!isSameTag) { return false; } stack || (stack = new Stack); return equalObjects(object, other, bitmask, customizer, equalFunc, stack); } /** * The base implementation of `_.isEqual` which supports partial comparisons * and tracks traversed objects. * * @private * @param {*} value The value to compare. * @param {*} other The other value to compare. * @param {boolean} bitmask The bitmask flags. * 1 - Unordered comparison * 2 - Partial comparison * @param {Function} [customizer] The function to customize comparisons. * @param {Object} [stack] Tracks traversed `value` and `other` objects. * @returns {boolean} Returns `true` if the values are equivalent, else `false`. */ function baseIsEqual(value, other, bitmask, customizer, stack) { if (value === other) { return true; } if (value == null || other == null || (!isObjectLike(value) && !isObjectLike(other))) { return value !== value && other !== other; } return baseIsEqualDeep(value, other, bitmask, customizer, baseIsEqual, stack); } /** Used to compose bitmasks for value comparisons. */ var COMPARE_PARTIAL_FLAG$1 = 1, COMPARE_UNORDERED_FLAG$1 = 2; /** * The base implementation of `_.isMatch` without support for iteratee shorthands. * * @private * @param {Object} object The object to inspect. * @param {Object} source The object of property values to match. * @param {Array} matchData The property names, values, and compare flags to match. * @param {Function} [customizer] The function to customize comparisons. * @returns {boolean} Returns `true` if `object` is a match, else `false`. */ function baseIsMatch(object, source, matchData, customizer) { var index = matchData.length, length = index, noCustomizer = !customizer; if (object == null) { return !length; } object = Object(object); while (index--) { var data = matchData[index]; if ((noCustomizer && data[2]) ? data[1] !== object[data[0]] : !(data[0] in object) ) { return false; } } while (++index < length) { data = matchData[index]; var key = data[0], objValue = object[key], srcValue = data[1]; if (noCustomizer && data[2]) { if (objValue === undefined && !(key in object)) { return false; } } else { var stack = new Stack; if (customizer) { var result = customizer(objValue, srcValue, key, object, source, stack); } if (!(result === undefined ? baseIsEqual(srcValue, objValue, COMPARE_PARTIAL_FLAG$1 | COMPARE_UNORDERED_FLAG$1, customizer, stack) : result )) { return false; } } } return true; } /** * Checks if `value` is suitable for strict equality comparisons, i.e. `===`. * * @private * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` if suitable for strict * equality comparisons, else `false`. */ function isStrictComparable(value) { return value === value && !isObject(value); } /** * Gets the property names, values, and compare flags of `object`. * * @private * @param {Object} object The object to query. * @returns {Array} Returns the match data of `object`. */ function getMatchData(object) { var result = keys(object), length = result.length; while (length--) { var key = result[length], value = object[key]; result[length] = [key, value, isStrictComparable(value)]; } return result; } /** * A specialized version of `matchesProperty` for source values suitable * for strict equality comparisons, i.e. `===`. * * @private * @param {string} key The key of the property to get. * @param {*} srcValue The value to match. * @returns {Function} Returns the new spec function. */ function matchesStrictComparable(key, srcValue) { return function(object) { if (object == null) { return false; } return object[key] === srcValue && (srcValue !== undefined || (key in Object(object))); }; } /** * The base implementation of `_.matches` which doesn't clone `source`. * * @private * @param {Object} source The object of property values to match. * @returns {Function} Returns the new spec function. */ function baseMatches(source) { var matchData = getMatchData(source); if (matchData.length == 1 && matchData[0][2]) { return matchesStrictComparable(matchData[0][0], matchData[0][1]); } return function(object) { return object === source || baseIsMatch(object, source, matchData); }; } /** * Gets the value at `path` of `object`. If the resolved value is * `undefined`, the `defaultValue` is returned in its place. * * @static * @memberOf _ * @since 3.7.0 * @category Object * @param {Object} object The object to query. * @param {Array|string} path The path of the property to get. * @param {*} [defaultValue] The value returned for `undefined` resolved values. * @returns {*} Returns the resolved value. * @example * * var object = { 'a': [{ 'b': { 'c': 3 } }] }; * * _.get(object, 'a[0].b.c'); * // => 3 * * _.get(object, ['a', '0', 'b', 'c']); * // => 3 * * _.get(object, 'a.b.c', 'default'); * // => 'default' */ function get(object, path, defaultValue) { var result = object == null ? undefined : baseGet(object, path); return result === undefined ? defaultValue : result; } /** * The base implementation of `_.hasIn` without support for deep paths. * * @private * @param {Object} [object] The object to query. * @param {Array|string} key The key to check. * @returns {boolean} Returns `true` if `key` exists, else `false`. */ function baseHasIn(object, key) { return object != null && key in Object(object); } /** * Checks if `path` exists on `object`. * * @private * @param {Object} object The object to query. * @param {Array|string} path The path to check. * @param {Function} hasFunc The function to check properties. * @returns {boolean} Returns `true` if `path` exists, else `false`. */ function hasPath(object, path, hasFunc) { path = castPath(path, object); var index = -1, length = path.length, result = false; while (++index < length) { var key = toKey(path[index]); if (!(result = object != null && hasFunc(object, key))) { break; } object = object[key]; } if (result || ++index != length) { return result; } length = object == null ? 0 : object.length; return !!length && isLength(length) && isIndex(key, length) && (isArray(object) || isArguments(object)); } /** * Checks if `path` is a direct or inherited property of `object`. * * @static * @memberOf _ * @since 4.0.0 * @category Object * @param {Object} object The object to query. * @param {Array|string} path The path to check. * @returns {boolean} Returns `true` if `path` exists, else `false`. * @example * * var object = _.create({ 'a': _.create({ 'b': 2 }) }); * * _.hasIn(object, 'a'); * // => true * * _.hasIn(object, 'a.b'); * // => true * * _.hasIn(object, ['a', 'b']); * // => true * * _.hasIn(object, 'b'); * // => false */ function hasIn(object, path) { return object != null && hasPath(object, path, baseHasIn); } /** Used to compose bitmasks for value comparisons. */ var COMPARE_PARTIAL_FLAG = 1, COMPARE_UNORDERED_FLAG = 2; /** * The base implementation of `_.matchesProperty` which doesn't clone `srcValue`. * * @private * @param {string} path The path of the property to get. * @param {*} srcValue The value to match. * @returns {Function} Returns the new spec function. */ function baseMatchesProperty(path, srcValue) { if (isKey(path) && isStrictComparable(srcValue)) { return matchesStrictComparable(toKey(path), srcValue); } return function(object) { var objValue = get(object, path); return (objValue === undefined && objValue === srcValue) ? hasIn(object, path) : baseIsEqual(srcValue, objValue, COMPARE_PARTIAL_FLAG | COMPARE_UNORDERED_FLAG); }; } /** * The base implementation of `_.property` without support for deep paths. * * @private * @param {string} key The key of the property to get. * @returns {Function} Returns the new accessor function. */ function baseProperty(key) { return function(object) { return object == null ? undefined : object[key]; }; } /** * A specialized version of `baseProperty` which supports deep paths. * * @private * @param {Array|string} path The path of the property to get. * @returns {Function} Returns the new accessor function. */ function basePropertyDeep(path) { return function(object) { return baseGet(object, path); }; } /** * Creates a function that returns the value at `path` of a given object. * * @static * @memberOf _ * @since 2.4.0 * @category Util * @param {Array|string} path The path of the property to get. * @returns {Function} Returns the new accessor function. * @example * * var objects = [ * { 'a': { 'b': 2 } }, * { 'a': { 'b': 1 } } * ]; * * _.map(objects, _.property('a.b')); * // => [2, 1] * * _.map(_.sortBy(objects, _.property(['a', 'b'])), 'a.b'); * // => [1, 2] */ function property(path) { return isKey(path) ? baseProperty(toKey(path)) : basePropertyDeep(path); } /** * The base implementation of `_.iteratee`. * * @private * @param {*} [value=_.identity] The value to convert to an iteratee. * @returns {Function} Returns the iteratee. */ function baseIteratee(value) { // Don't store the `typeof` result in a variable to avoid a JIT bug in Safari 9. // See https://bugs.webkit.org/show_bug.cgi?id=156034 for more details. if (typeof value == 'function') { return value; } if (value == null) { return identity; } if (typeof value == 'object') { return isArray(value) ? baseMatchesProperty(value[0], value[1]) : baseMatches(value); } return property(value); } /** * The base implementation of `_.forOwn` without support for iteratee shorthands. * * @private * @param {Object} object The object to iterate over. * @param {Function} iteratee The function invoked per iteration. * @returns {Object} Returns `object`. */ function baseForOwn(object, iteratee) { return object && baseFor(object, iteratee, keys); } /** * Creates a `baseEach` or `baseEachRight` function. * * @private * @param {Function} eachFunc The function to iterate over a collection. * @param {boolean} [fromRight] Specify iterating from right to left. * @returns {Function} Returns the new base function. */ function createBaseEach(eachFunc, fromRight) { return function(collection, iteratee) { if (collection == null) { return collection; } if (!isArrayLike(collection)) { return eachFunc(collection, iteratee); } var length = collection.length, index = fromRight ? length : -1, iterable = Object(collection); while ((fromRight ? index-- : ++index < length)) { if (iteratee(iterable[index], index, iterable) === false) { break; } } return collection; }; } /** * The base implementation of `_.forEach` without support for iteratee shorthands. * * @private * @param {Array|Object} collection The collection to iterate over. * @param {Function} iteratee The function invoked per iteration. * @returns {Array|Object} Returns `collection`. */ var baseEach = createBaseEach(baseForOwn); /** * The base implementation of `_.map` without support for iteratee shorthands. * * @private * @param {Array|Object} collection The collection to iterate over. * @param {Function} iteratee The function invoked per iteration. * @returns {Array} Returns the new mapped array. */ function baseMap(collection, iteratee) { var index = -1, result = isArrayLike(collection) ? Array(collection.length) : []; baseEach(collection, function(value, key, collection) { result[++index] = iteratee(value, key, collection); }); return result; } /** * The base implementation of `_.sortBy` which uses `comparer` to define the * sort order of `array` and replaces criteria objects with their corresponding * values. * * @private * @param {Array} array The array to sort. * @param {Function} comparer The function to define sort order. * @returns {Array} Returns `array`. */ function baseSortBy(array, comparer) { var length = array.length; array.sort(comparer); while (length--) { array[length] = array[length].value; } return array; } /** * Compares values to sort them in ascending order. * * @private * @param {*} value The value to compare. * @param {*} other The other value to compare. * @returns {number} Returns the sort order indicator for `value`. */ function compareAscending(value, other) { if (value !== other) { var valIsDefined = value !== undefined, valIsNull = value === null, valIsReflexive = value === value, valIsSymbol = isSymbol(value); var othIsDefined = other !== undefined, othIsNull = other === null, othIsReflexive = other === other, othIsSymbol = isSymbol(other); if ((!othIsNull && !othIsSymbol && !valIsSymbol && value > other) || (valIsSymbol && othIsDefined && othIsReflexive && !othIsNull && !othIsSymbol) || (valIsNull && othIsDefined && othIsReflexive) || (!valIsDefined && othIsReflexive) || !valIsReflexive) { return 1; } if ((!valIsNull && !valIsSymbol && !othIsSymbol && value < other) || (othIsSymbol && valIsDefined && valIsReflexive && !valIsNull && !valIsSymbol) || (othIsNull && valIsDefined && valIsReflexive) || (!othIsDefined && valIsReflexive) || !othIsReflexive) { return -1; } } return 0; } /** * Used by `_.orderBy` to compare multiple properties of a value to another * and stable sort them. * * If `orders` is unspecified, all values are sorted in ascending order. Otherwise, * specify an order of "desc" for descending or "asc" for ascending sort order * of corresponding values. * * @private * @param {Object} object The object to compare. * @param {Object} other The other object to compare. * @param {boolean[]|string[]} orders The order to sort by for each property. * @returns {number} Returns the sort order indicator for `object`. */ function compareMultiple(object, other, orders) { var index = -1, objCriteria = object.criteria, othCriteria = other.criteria, length = objCriteria.length, ordersLength = orders.length; while (++index < length) { var result = compareAscending(objCriteria[index], othCriteria[index]); if (result) { if (index >= ordersLength) { return result; } var order = orders[index]; return result * (order == 'desc' ? -1 : 1); } } // Fixes an `Array#sort` bug in the JS engine embedded in Adobe applications // that causes it, under certain circumstances, to provide the same value for // `object` and `other`. See https://github.com/jashkenas/underscore/pull/1247 // for more details. // // This also ensures a stable sort in V8 and other engines. // See https://bugs.chromium.org/p/v8/issues/detail?id=90 for more details. return object.index - other.index; } /** * The base implementation of `_.orderBy` without param guards. * * @private * @param {Array|Object} collection The collection to iterate over. * @param {Function[]|Object[]|string[]} iteratees The iteratees to sort by. * @param {string[]} orders The sort orders of `iteratees`. * @returns {Array} Returns the new sorted array. */ function baseOrderBy(collection, iteratees, orders) { if (iteratees.length) { iteratees = arrayMap(iteratees, function(iteratee) { if (isArray(iteratee)) { return function(value) { return baseGet(value, iteratee.length === 1 ? iteratee[0] : iteratee); } } return iteratee; }); } else { iteratees = [identity]; } var index = -1; iteratees = arrayMap(iteratees, baseUnary(baseIteratee)); var result = baseMap(collection, function(value, key, collection) { var criteria = arrayMap(iteratees, function(iteratee) { return iteratee(value); }); return { 'criteria': criteria, 'index': ++index, 'value': value }; }); return baseSortBy(result, function(object, other) { return compareMultiple(object, other, orders); }); } /** * This method is like `_.sortBy` except that it allows specifying the sort * orders of the iteratees to sort by. If `orders` is unspecified, all values * are sorted in ascending order. Otherwise, specify an order of "desc" for * descending or "asc" for ascending sort order of corresponding values. * * @static * @memberOf _ * @since 4.0.0 * @category Collection * @param {Array|Object} collection The collection to iterate over. * @param {Array[]|Function[]|Object[]|string[]} [iteratees=[_.identity]] * The iteratees to sort by. * @param {string[]} [orders] The sort orders of `iteratees`. * @param- {Object} [guard] Enables use as an iteratee for methods like `_.reduce`. * @returns {Array} Returns the new sorted array. * @example * * var users = [ * { 'user': 'fred', 'age': 48 }, * { 'user': 'barney', 'age': 34 }, * { 'user': 'fred', 'age': 40 }, * { 'user': 'barney', 'age': 36 } * ]; * * // Sort by `user` in ascending order and by `age` in descending order. * _.orderBy(users, ['user', 'age'], ['asc', 'desc']); * // => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 40]] */ function orderBy(collection, iteratees, orders, guard) { if (collection == null) { return []; } if (!isArray(iteratees)) { iteratees = iteratees == null ? [] : [iteratees]; } orders = guard ? undefined : orders; if (!isArray(orders)) { orders = orders == null ? [] : [orders]; } return baseOrderBy(collection, iteratees, orders); } function addConstant(object, property, value) { Object.defineProperty(object, property, { configurable: false, enumerable: true, writable: false, value }); } function addConstants(Constructor, propertyMap) { for (const property in propertyMap) { const value = propertyMap[property]; addConstant(Constructor, property, value); } } function mixin(target, source, allowKeys = []) { const keys = Reflect.ownKeys(source); for (let i = 0; i < keys.length; ++i) { if (keys[i] in target && !allowKeys.includes(keys[i])) { continue; } Object.defineProperty(target, keys[i], Object.getOwnPropertyDescriptor(source, keys[i])); } } function addRuntimeData(name, key, val) { // 添加运行时数据 if (!sdenv.cache.runtime[name]) sdenv.cache.runtime[name] = {}; const runtimeData = sdenv.cache.runtime[name]; if (!runtimeData[key]) runtimeData[key] = []; runtimeData[key].push(val); return val; } function getRuntimeData(name, key) { return get(sdenv, ['cache.runtime', name, key] .filter((it) => it !== undefined) .join('.')); } function compressText(text, max = 100) { if (text.length <= max) { return text; } const truncatedText = text.replace(/[\r\n]+/g, ' ').replace(/\s+/g, ' '); return `${truncatedText.slice(0, max)}......`; } const isAlive = () => { // 窗口是否还活跃 return !sdenv.memory.runinfo.isDied; }; const isDied = () => { // 窗口是否还活跃 return sdenv.memory.runinfo.isDied; }; const setDied = () => { // 设置窗口为死亡状态 sdenv.memory.runinfo.isDied = true; }; const exit = (params) => { const win = sdenv.memory.sdWindow; setDied(); if (params.url) win.onbeforeunload?.(params.url); }; let originToString = Function.toString; const canToStrigArr = []; const toString = function() { if (canToStrigArr.includes(this.name)) { return `function ${this.name || ''}() { [native code] }`; } return originToString.apply(this); }; const setFuncNative = function(func, name) { // 修改函数的toString方法返回native code标识 if (!func) return undefined; func.name = name || func.name || ''; canToStrigArr.push(func.name); Object.defineProperty(func, 'toString', { enumerable: false, configurable: true, writable: true, value: toString, }); return func; }; const setFuncName = function(func, name) { // 修改方法的name属性值 Object.defineProperty(func, 'name', { configurable: true, enumerable: false, writable: false, value: name }); return func; }; const setNativeFuncName = function(func, name) { setFuncName(func, name); setFuncNative(func, name); return func; }; setNativeFuncName(toString, 'toString'); const _setFuncInit = function() { // 修改Function指向与toString原型链指向 const win = sdenv.memory.sdWindow; originToString = win.Function.toString; toString.__proto__ = win.Function.prototype; }; const setObjNative = function(obj, name) { // 修改函数的toString方法返回native code标识 Object.defineProperty(obj, 'toString', { enumerable: false, configurable: true, writable: true, value() { return `[object ${name}]`; } }); return obj; }; const setObjName = function(obj, name) { /* 修改toString的显示,如: window.navigator.webkitPersistentStorage.toString() === '[object DeprecatedStorageQuota]' */ Object.defineProperty(obj, Symbol.toStringTag, { configurable: true, enumerable: false, writable: false, value: name }); return obj; }; const setNativeObjName = function(obj, name) { setObjName(obj, name); setObjNative(obj, name); return obj; }; function getNativeProto(funcname, objname, attrs = {}) { // 自动生成原型函数并返回基于原始数据与该原型函数的实例化对象 const func = setNativeFuncName(() => { throw new TypeError('Illegal constructor'); }, funcname); const obj = setNativeObjName({ __proto__: func, ...attrs, }, funcname); return [func, obj]; } function addUtil(func, name) { sdenv.utils[name || func.name] = func; return func; } function getUtil(name) { return sdenv.utils[name]; } /* eslint-disable no-debugger */ function monitor(tar, name, config = {}) { const win = sdenv.memory.sdWindow; const { getLog, // 开启get日志 setLog, // 开启set日志 getKeys = [], // 触发get的debugger的键集合 setKeys = [], // 触发set的debugger的键集合 keys = [], // 触发debugger的键集合 getCb, // get的回调,设置的debugger更友好 setCb, // set的回调,设置的debugger更友好 cb, // 回调,设置的debugger更友好 parse = (key, val) => val, } = config; if (!sdenv.cache.monitor[name]) sdenv.cache.monitor[name] = []; const newTar = new win.Proxy(tar, { get(target, property, receiver) { if (getLog) win.console.log(`${name} Getting ${property}`); if (getKeys.includes(property) || keys.includes(property)) debugger; (getCb || cb)?.(property, name); return Reflect.get(target, property, receiver); }, set(target, property, value, receiver) { const show = [ win, win.Math, win.navigation ].includes(value) && value.toString ? value.toString() : value; if (setLog) win.console.log(`${name} Setting ${property} to ${show}`); if (setKeys.includes(property) || keys.includes(property)) debugger; (setCb || cb)?.(property, value, name); return Reflect.set(target, property, parse(property, value), receiver); } }); sdenv.cache.monitor[name].push(newTar); return newTar; } function monitorFunction(tar, name, config = {}) { const win = sdenv.memory.sdWindow; const { log, // 开启日志 isDebugger, // 是否在调用时触发debugger cb, // 回调,设置的debugger更友好 } = config; if (!sdenv.cache.monitor[name]) sdenv.cache.monitor[name] = []; const newTar = new win.Proxy(tar, { apply(target, thisArg, argArray) { const result = Reflect.apply(target, thisArg, argArray); if (log) win.console.log(`${name} Apply ${argArray}`); if (isDebugger) debugger; cb?.(argArray, result, name); return result; } }); sdenv.cache.monitor[name].push(newTar); return newTar; } function getMonitor(name) { if (name) return sdenv.cache.monitor[name]; return sdenv.cache.monitor } const proxy = function (obj, objname) { function get_attribute_type(value) { return Object.prototype.toString.call(value); } function get_method_handler(watchName) { return { apply(target, thisArg, argArray) { const result = Reflect.apply(target, thisArg, argArray); if (thisArg === console && target.name === 'log') { return result; } if (target.name === 'toString') { return result; } console.log(`[${watchName}] apply function name is [${target.name}], argArray is [${argArray}], result is [${result}].`); return result }, construct(target, argArray, newTarget) { const result = Reflect.construct(target, argArray, newTarget); console.log(`[${watchName}] construct function name is [${target.name}], argArray is [${argArray}], result is [${(result)}].`); return result; } } } function get_obj_handler(WatchName) { return { get(target, propKey) { try { if (sdenv.config.proxy_proto === false && propKey === '__proto__') { console.log(`getting propKey-> ${WatchName}.${propKey} value-> ${(target[propKey])}`); return target[propKey] } const result = Reflect.get(target, propKey, target); const result_type = get_attribute_type(result); if (result instanceof Object) { if (Object.getOwnPropertyDescriptor(target, propKey)?.writable === false) { console.log(`【getting】${WatchName}.${propKey.toString()} it is non-writable`); } else { if (typeof result === 'function') { console.log(`【getting】${WatchName}.${propKey} value-> ${sdenv.tools.compressText(String(result))} typeof-> ${result_type}`); return new Proxy(result, get_method_handler(WatchName)) } console.log(`\n【getting】${WatchName}.${propKey} value-> ${sdenv.tools.compressText(String(result))} typeof-> ${result_type}`); return new Proxy(result, get_obj_handler(`${WatchName}.${propKey}`)) } } console.log(`\n【getting】${WatchName}.${propKey.description ?? propKey} result-> ${result} typeof-> ${result_type}`); return result; } catch (e) { console.error(`[${WatchName}] getting error`); console.error(e.stack); } }, set(target, propKey, value, receiver) { const value_type = get_attribute_type(value); if (value instanceof Object) { console.log(`\n【setting】${WatchName}.${propKey} value-> ${sdenv.tools.compressText(String(value))} typeof-> ${value_type}`); } else { console.log(`\n【setting】${WatchName}.${propKey} value-> ${sdenv.tools.compressText(String(value))} typeof-> ${value_type}`); } return Reflect.set(target, propKey, value, receiver); }, has(target, propKey) { const result = Reflect.has(target, propKey); console.log(`【has】${WatchName}.${propKey}, result-> ${result}`); return result; }, deleteProperty(target, propKey) { const result = Reflect.deleteProperty(target, propKey); console.log(`【delete】${WatchName}.${propKey}, result-> ${result}`); return result; }, getOwnPropertyDescriptor(target, propKey) { const result = Reflect.getOwnPropertyDescriptor(target, propKey); try { console.log(`【getOwnPropertyDescriptor】${WatchName}.${propKey.toString()} result-> ${(String(result))}`); } catch (e) { console.error(e.stack); } return result; }, defineProperty(target, propKey, attributes) { const result = Reflect.defineProperty(target, propKey, attributes); try { console.log(`【defineProperty】${WatchName}.${propKey} attributes is [${(attributes)}], result is [${result}]`); } catch (e) { console.error(`[${WatchName}] defineProperty error`); console.error(e.stack); } return result; }, getPrototypeOf(target) { const result = Reflect.getPrototypeOf(target); console.log(`[${WatchName}] getPrototypeOf result is [${(result)}]`); return result; }, setPrototypeOf(target, proto) { const result = Reflect.setPrototypeOf(target, proto); console.log(`[${WatchName}] setPrototypeOf proto is [${(proto)}], result is [${result}]`); return result; }, preventExtensions(target) { const result = Reflect.preventExtensions(target); console.log(`[${WatchName}] preventExtensions, result is [${result}]`); return result; }, isExtensible(target) { const result = Reflect.isExtensible(target); console.log(`[${WatchName}] isExtensible, result is [${result}]`); return result; }, ownKeys(target) { const result = Reflect.ownKeys(target); try { console.log(`[${WatchName}] invoke ownkeys, result is [${String((result))}]`); } catch (e) { console.error(e.stack); } return result } } } if (sdenv.config.proxyOpen === false) { return obj } if (typeof obj === 'function') { return new Proxy(obj, get_method_handler(objname)); } return new Proxy(obj, get_obj_handler(objname)); }; let cache$8 = undefined; function timeoutHandle(config) { if (typeof config !== 'object') config = {}; const win = sdenv.memory.sdWindow; if (!cache$8) { cache$8 = win.setTimeout; } const { log, cb, time, filter = () => true } = config; win.setTimeout = sdenv.tools.setNativeFuncName(new Proxy(cache$8, { apply: function (target, thisArg, params) { if (!filter || !filter(...params)) return; const [func, timeout] = params; const funcStr = func.param ? JSON.stringify(func.param) : sdenv.tools.compressText(func.toString()); if (log) win.console.log(`【TIMEOUT APPLY】增加setTimeout事件,时间:${timeout}, 方法: ${funcStr}`); if (time !== undefined) { if (typeof time !== 'number') throw new Error(`time配置如果存在值则必须是数字`); return Reflect.apply(target, thisArg, [ () => { if (log) win.console.log(`【TIMEOUT RUN】setTimeout执行,时间:${timeout},方法:${funcStr}`); func(); if (log) win.console.log(`【TIMEOUT RUNED】setTimeout执行,时间:${timeout},方法:${funcStr}`); }, time || timeout, ]); } return sdenv.tools.addTimeout(func, timeout); }, }), 'setTimeout'); win.document.addEventListener('readystatechange', function() { if (log) win.console.log(`【READY STATE】${win.document.readyState}`); }); } const getTimeout = () => cache$8; const currentTask = function () { this.cache = null; this.add = (item) => { if (!this.cache) return false; if (this.cache.task.includes(item)) return this.cache.task.push(item); }; this.set = (task) => this.cache = task; this.get = () => this.cache; this.getTime = () => { if (!this.cache) return false; return this.cache.time; }; this.getTask = (idx) => { if (!this.cache) return false; if (typeof idx === 'number') return this.cache.task[idx] return this.cache.task; }; this.clear = () => this.cache = null; }; class Timeout { constructor() { this.index = []; this.timeouts = {}; this.lastOp = sdenv.memory.runinfo.start; this.isLock = false; this.id = 0; this.currentTask = new currentTask(); } addTimeout(func, time, type = 'timeout', idx = this.index.length) { let timekey = new sdenv.memory.sdDate().getTime() - sdenv.memory.runinfo.start + time; const obj = { func, // 方法 type, // 类型: timeout interval flag: 0, // 执行状态: -1(取消执行)0(未执行)1(执行中)2(已执行) time, // 延时时间 expect_time: timekey, // 预期执行时间 real_time: null, // 实际执行时间 index: idx, // 编号 id: this.id++, }; if (this.index[idx]) { this.index[idx] = obj; } else { this.index.push(obj); } if (time === 0 && this.currentTask.get()) { timekey = this.currentTask.getTime(); this.timeouts[timekey].push(obj); this.currentTask.add(obj); } else { if (this.timeouts[timekey] === undefined) this.timeouts[timekey] = []; this.timeouts[timekey].push(obj); if (isAlive()) this.exec(); } // const win = sdenv.memory.sdWindow; // win.console.log(`程序时间${timekey}处${type}回调添加成功`); return idx; } addInterval(func, time, idx = undefined) { const self = this; const newFunc = function() { try { func(); } catch (err) { console.error(err); } finally { if (self.index[idx].flag !== -1) self.addInterval(func, time, idx); } }; idx = this.addTimeout(newFunc, time, 'interval', idx); return idx; } remove(idx) { if (typeof idx !== 'number' || !this.index[idx]) return false; if (this.index[idx].flag === 0) { this.index[idx].flag = -1; } else if ([-1, 2].includes(this.index[idx].flag)) { return undefined; } else if (this.index[idx].flag === 1) { return false; } return undefined } exec() { if (this.isLock) return; this.isLock = true; getTimeout()(() => { this.isLock = false; this.run(); }, 0); } run() { const win = sdenv.memory.sdWindow; const times = Object.keys(this.timeouts).filter((key) => { if (Number(key) + sdenv.memory.runinfo.start <= this.lastOp) return false; return true; }); if (times.length === 0) return false; this.lastOp = Number(times[0]) + sdenv.memory.runinfo.start; this.currentTask.set({ task: this.timeouts[times[0]], time: times[0], }); for(let i = 0; this.currentTask.getTask(i); i++) { const cfg = this.currentTask.getTask(i); if (isDied() || cfg.flag === -1) return; const funcStr = cfg.func.param ? JSON.stringify(cfg.func.param) : sdenv.tools.compressText(cfg.func.toString()); win.console.log(`【TIMEOUT RUN】执行程序时间${times[0]}处${cfg.type}回调,延时:${cfg.time},编号:${cfg.id},方法:${funcStr}`); cfg.flag = 1; cfg.real_time = new sdenv.memory.sdDate().getTime() - sdenv.memory.runinfo.start; try { cfg.func(); win.console.log(`【TIMEOUT RUNED】执行程序时间${times[0]}处${cfg.type}回调,延时:${cfg.time},编号:${cfg.id},方法:${funcStr}`); } catch (e) { console.error(e); } cfg.flag = 2; } this.currentTask.clear(); if (isDied()) return undefined; if (times.length > 1) { this.run(); } else { this.exec(); } return undefined; } } sdenv.memory.timeout = new Timeout(); const addTimeout = function(func, time) { return sdenv.memory.timeout.addTimeout(func, Number(time || 0), 'timeout') }; const addInterval = function(func, time) { return sdenv.memory.timeout.addInterval(func, time); }; const removeTimeout = function(idx) { return sdenv.memory.timeout.remove(idx); }; const removeInterval = function(idx) { return sdenv.memory.timeout.remove(idx); }; var tools = /*#__PURE__*/Object.freeze({ __proto__: null, _setFuncInit: _setFuncInit, addConstant: addConstant, addConstants: addConstants, addInterval: addInterval, addRuntimeData: addRuntimeData, addTimeout: addTimeout, addUtil: addUtil, compressText: compressText, exit: exit, getMonitor: getMonitor, getNativeProto: getNativeProto, getRuntimeData: getRuntimeData, getUtil: getUtil, isAlive: isAlive, isDied: isDied, mixin: mixin, monitor: monitor, monitorFunction: monitorFunction, proxy: proxy, removeInterval: removeInterval, removeTimeout: removeTimeout, setDied: setDied, setFuncName: setFuncName, setFuncNative: setFuncNative, setNativeFuncName: setNativeFuncName, setNativeObjName: setNativeObjName, setObjName: setObjName, setObjNative: setObjNative }); // 循环体执行监控 const preLoop = {}; function loopRunInit() { const win = sdenv.memory.sdWindow; const runloop = sdenv.cache.runloop = { current: 1 }; let log = false; addUtil((key, idx, name, runlist = '', lens = 0) => { /* * 初始化一个循环 * key: 循环体的case的变量名 * idx: 初始化下标 * name: 循环方法名称 * runlist: 循环任务名或者循环任务队列 * lens: 任务队列长度 * */ const arr = []; const current = runloop.current++; if (!runloop[key]) { runloop[key] = []; } const loopobj = { idx, // 启动的下标 name, // 函数名 data: arr, // 实际运行队列 current, // 启动编号 idxs: [], // 实际运行下标队列 list: Array.isArray(runlist) ? runlist.join() : runlist, // 预期运行队列 lens: lens || (Array.isArray(runlist) ? runlist.length : -1), // 预期运行队列长度 pre: { // 上一次循环信息 current: preLoop.cur, curloop: preLoop.num, }, param: {}, // 需要记录的关键数据 }; if (preLoop.loop) { preLoop.loop.param[preLoop.loop.data.length - 1] = { next: current // 档次编号记录到父循环中 }; } runloop[key].push(loopobj); if (log) win.console.log(`【RUN TASK】current:${current}`); return { addLoop: (id, it, _key) => { loopobj.data.push(it); loopobj.idxs.push(id); Object.assign(preLoop, { key: _key, cur: current, num: arr.length, loop: loopobj, }); }, curLoop: () => arr.length, current, loopobj, openLog: () => (log = true), closeLog: () => (log = false), isLog: () => log, } }, 'initLoop'); // 上一个循环的信息 addUtil(() => ({ ...preLoop }), 'getPreLoop'); addUtil((copy) => { // 返回循环体运行数据,copy为复制方法,非浏览器环境需要手动传入 const data = JSON.parse(JSON.stringify(runloop)); const ascii = {}; Object.entries(data).forEach(([key, item]) => { if (!Array.isArray(item)) return; ascii[key] = {}; item.forEach((each) => { each.data.forEach((it) => { if (ascii[key][it] === undefined) ascii[key][it] = 0; ascii[key][it]++; }); each.data = each.data.join(); each.idxs = each.idxs.join(); }); ascii[key] = orderBy(Object.entries(ascii[key]).map(([code, num]) => ({ code, num })), 'num', 'desc'); }); if (copy) { copy(JSON.stringify(data)); console.log('运行时数据复制成功'); } return { ascii, ...data }; }, 'getLoopData'); } // 修改任务树增加任务名称等信息 function parse(val, keyMap = {}, deep = 0, deeps = [0]) { // 任务列表、主要子树、次要子树、监控值变化的配置 if (keyMap._count === undefined) keyMap._count = 0; const { taskKey, oneKey, twoKey, monitor = {} } = keyMap; const str = val[taskKey]; val.str = str; val.val = {}; if (!str) { val.arr = []; val[taskKey] = []; } else { val.arr = str.split('').map((it) => it.charCodeAt()); if (keyMap._count > 0) val[taskKey] = [...val.arr]; // 最外层让瑞数自己处理 } val.idx = `${deeps.join('>')}-${keyMap._count++}`; val[oneKey] = val[oneKey].map((it, idx) => { if (it) { parse(it, keyMap, deep + 1, [...deeps, 'one', idx]); return sdenv.tools.monitor(it, it.idx, { setLog: true, ...monitor }); } return it; }); val[twoKey] = val[twoKey].map((it, idx) => { if (it) { parse(it, keyMap, deep + 1, [...deeps, 'two', idx]); return sdenv.tools.monitor(it, it.idx, { setLog: true, ...monitor }); } return it; }); return val; } const parseTaskTree = function(...params) { sdenv.cache.runsObj = parse(...params); // 任务树 sdenv.cache.runsArr = []; // 任务运行时队列 }; var index$1 = /*#__PURE__*/Object.freeze({ __proto__: null, parseTaskTree: parseTaskTree }); var adapt = /*#__PURE__*/Object.freeze({ __proto__: null, rs: index$1 }); let cache$7 = undefined; const evalmap = { '!new function(){eval("this.a=1")}().a': 'false', }; function evalHandle(config) { if (typeof config !== 'object') config = {}; const win = sdenv.memory.sdWindow; if (!cache$7) { cache$7 = win.eval; } const { cb, log } = config; win.eval = sdenv.tools.setNativeFuncName(new Proxy(cache$7, { apply(target, thisArg, params) { if (log) win.console.log(`【EVAL APPLY】参数:${params.map(it => sdenv.tools.compressText(JSON.stringify(it)))}`); const new_params = params.map((param) => { if (typeof evalmap[param] === 'string') return evalmap[param]; if (param.includes('debugger')) { param = param.replace(/debugger/g, ''); } if (param.includes('sdDebugger')) { param = param.replace(/sdDebugger/g, 'debugger'); } return param }); const dynamicCode = { type: 'eval', params, tar_params: new_params, }; cb?.(dynamicCode); sdenv.cache.dynamicCode.push({ ...dynamicCode }); return Reflect.apply(target, thisArg, new_params); }, }), 'eval'); } let cache$6 = undefined; function funcHandle(config) { if (typeof config !== 'object') config = {}; const win = sdenv.memory.sdWindow; if (!cache$6) { cache$6 = win.Function; } const { log, cb } = config; win.Function = sdenv.tools.setNativeFuncName(new Proxy(cache$6, { apply(target, thisArg, params) { const new_params = params.map((param) => { if (param.includes('debugger')) { param = param.replace(/debugger/g, ''); } if (param.includes('sdDebugger')) { param = param.replace(/sdDebugger/g, 'debugger'); } return param }); if (log) win.console.log(`【FUNCTION APPLY】参数:${params.map(it => sdenv.tools.compressText(JSON.stringify(it)))}`); const dynamicCode = { type: 'Function', params, tar_params: new_params, }; cb?.(dynamicCode); sdenv.cache.dynamicCode.push({ ...dynamicCode }); return Reflect.apply(target, thisArg, new_params); } }), 'Function'); win.Function.prototype.constructor = win.Function; sdenv.tools.setNativeFuncName(win.Function.prototype, ''); } const delay$1 = (ms) => new Promise(resolve => sdenv.memory.sdWindow.setTimeout(resolve, ms)); let cache$5 = undefined; function eventHandle(config) { if (typeof config !== 'object') config = {}; const win = sdenv.memory.sdWindow; if (!cache$5) { cache$5 = win.addEventListener; } const { addLog, runLog, log, addCb, runCb, cb, filter = () => true } = config; win.addEventListener = sdenv.tools.setNativeFuncName(new Proxy(cache$5, { apply: function (target, thisArg, params) { if (!filter || !filter(...params)) return; const [type, callback] = params; const funcStr = callback.param ? JSON.stringify(callback.param) : sdenv.tools.compressText(callback.toString()); if (addLog || log) win.console.log(`【ADD EVENT】事件名:${type}, 方法:${funcStr}`); (addCb || cb)?.(...params); return Reflect.apply(target, thisArg, [ type, async () => { // load事件需要等下一次事件循环时执行: 延时为0的定时任务先执行 if (type === 'load') await delay$1(0); (runCb || cb)?.(...params); if (runLog || log) win.console.log(`【RUN EVENT】事件名:${type}, 方法:${funcStr}`); callback(); }, ]); }, }), 'addEventListener'); } let cache$4 = undefined; function cookieHandle(config) { if (typeof config !== 'object') config = {}; const win = sdenv.memory.sdWindow; if (!cache$4) { cache$4 = { cookieGet: Object.getOwnPropertyDescriptor(win.Document.prototype, 'cookie').get, cookieSet: Object.getOwnPropertyDescriptor(win.Document.prototype, 'cookie').set, }; } const { getLog, // 开启get日志 setLog, // 开启set日志 log, getCb, // get的回调,设置的debugger更友好 setCb, // set的回调,设置的debugger更友好 cb, // 回调,设置的debugger更友好 parse = (val) => val, } = config; Object.defineProperty(win.document, 'cookie', { configurable: false, enumerable: false, get() { const cookie = cache$4.cookieGet.call(win.document); if (getLog || log) win.console.log(`【GET COOKIE】长:${cookie.length} 值:${cookie}`); (getCb || cb)?.(cookie); return cookie; }, set(val) { if (setLog || log) win.console.log(`【SET COOKIE】长:${val.length} 值:${val}`); (setCb || cb)?.(val); cache$4.cookieSet.call(win.document, parse(val)); } }); } /** Used to match a single whitespace character. */ var reWhitespace = /\s/; /** * Used by `_.trim` and `_.trimEnd` to get the index of the last non-whitespace * character of `string`. * * @private * @param {string} string The string to inspect. * @returns {number} Returns the index of the last non-whitespace character. */ function trimmedEndIndex(string) { var index = string.length; while (index-- && reWhitespace.test(string.charAt(index))) {} return index; } /** Used to match leading whitespace. */ var reTrimStart = /^\s+/; /** * The base implementation of `_.trim`. * * @private * @param {string} string The string to trim. * @returns {string} Returns the trimmed string. */ function baseTrim(string) { return string ? string.slice(0, trimmedEndIndex(string) + 1).replace(reTrimStart, '') : string; } /** Used as references for various `Number` constants. */ var NAN = 0 / 0; /** Used to detect bad signed hexadecimal string values. */ var reIsBadHex = /^[-+]0x[0-9a-f]+$/i; /** Used to detect binary string values. */ var reIsBinary = /^0b[01]+$/i; /** Used to detect octal string values. */ var reIsOctal = /^0o[0-7]+$/i; /** Built-in method references without a dependency on `root`. */ var freeParseInt = parseInt; /** * Converts `value` to a number. * * @static * @memberOf _ * @since 4.0.0 * @category Lang * @param {*} value The value to process. * @returns {number} Returns the number. * @example * * _.toNumber(3.2); * // => 3.2 * * _.toNumber(Number.MIN_VALUE); * // => 5e-324 * * _.toNumber(Infinity); * // => Infinity * * _.toNumber('3.2'); * // => 3.2 */ function toNumber(value) { if (typeof value == 'number') { return value; } if (isSymbol(value)) { return NAN; } if (isObject(value)) { var other = typeof value.valueOf == 'function' ? value.valueOf() : value; value = isObject(other) ? (other + '') : other; } if (typeof value != 'string') { return value === 0 ? value : +value; } value = baseTrim(value); var isBinary = reIsBinary.test(value); return (isBinary || reIsOctal.test(value)) ? freeParseInt(value.slice(2), isBinary ? 2 : 8) : (reIsBadHex.test(value) ? NAN : +value); } /** Used as references for various `Number` constants. */ var INFINITY = 1 / 0, MAX_INTEGER = 1.7976931348623157e+308; /** * Converts `value` to a finite number. * * @static * @memberOf _ * @since 4.12.0 * @category Lang * @param {*} value The value to convert. * @returns {number} Returns the converted number. * @example * * _.toFinite(3.2); * // => 3.2 * * _.toFinite(Number.MIN_VALUE); * // => 5e-324 * * _.toFinite(Infinity); * // => 1.7976931348623157e+308 * * _.toFinite('3.2'); * // => 3.2 */ function toFinite(value) { if (!value) { return value === 0 ? value : 0; } value = toNumber(value); if (value === INFINITY || value === -INFINITY) { var sign = (value < 0 ? -1 : 1); return sign * MAX_INTEGER; } return value === value ? value : 0; } /** * Converts `value` to an integer. * * **Note:** This method is loosely based on * [`ToInteger`](http://www.ecma-international.org/ecma-262/7.0/#sec-tointeger). * * @static * @memberOf _ * @since 4.0.0 * @category Lang * @param {*} value The value to convert. * @returns {number} Returns the converted integer. * @example * * _.toInteger(3.2); * // => 3 * * _.toInteger(Number.MIN_VALUE); * // => 0 * * _.toInteger(Infinity); * // => 1.7976931348623157e+308 * * _.toInteger('3.2'); * // => 3 */ function toInteger(value) { var result = toFinite(value), remainder = result % 1; return result === result ? (remainder ? result - remainder : result) : 0; } /* Built-in method references for those with the same name as other `lodash` methods. */ var nativeIsFinite = root.isFinite, nativeMin = Math.min; /** * Creates a function like `_.round`. * * @private * @param {string} methodName The name of the `Math` method to use when rounding. * @returns {Function} Returns the new round function. */ function createRound(methodName) { var func = Math[methodName]; return function(number, precision) { number = toNumber(number); precision = precision == null ? 0 : nativeMin(toInteger(precision), 292); if (precision && nativeIsFinite(number)) { // Shift with exponential notation to avoid floating-point issues. // See [MDN](https://mdn.io/round#Examples) for more details. var pair = (toString$1(number) + 'e').split('e'), value = func(pair[0] + 'e' + (+pair[1] + precision)); pair = (toString$1(value) + 'e').split('e'); return +(pair[0] + 'e' + (+pair[1] - precision)); } return func(number); }; } /** * Computes `number` rounded to `precision`. * * @static * @memberOf _ * @since 3.10.0 * @category Math * @param {number} number The number to round. * @param {number} [precision=0] The precision to round to. * @returns {number} Returns the rounded number. * @example * * _.round(4.006); * // => 4 * * _.round(4.006, 2); * // => 4.01 * * _.round(4060, -2); * // => 4100 */ var round = createRound('round'); /* charging: 是否正在充电, true表示正在充电 chargingTime: 充满需要多久时间, 0表示已经充满,未充电总是为Infinity dischargingTime: 可以用多久,正在充电时总为Infinity level: 电量,1表示100%电量 */ const level = round(Math.random(), 2); // 电量 const chargingTime = (1 - level) * 100 * 300; // 充满时间 const dischargingTime = level * 100 * 443; // 可用时间 const charging = { charging_success: { // 正在充电,电量100% charging: true, chargingTime: 0, dischargingTime: Infinity, level: 1, }, discharging_success: { // 未充电,电量100% charging: false, chargingTime: Infinity, dischargingTime: Infinity, level: 1, }, charging_ing: { // 正在充电 charging: true, chargingTime, dischargingTime: Infinity, level, }, discharging_ing: { // 未充电 charging: false, chargingTime: Infinity, dischargingTime: dischargingTime, level, } }; function batteryHandle(config) { if (typeof config === 'string') { config = charging[config] || {}; } else if (typeof config !== 'object') { config = {}; } const win = sdenv.memory.sdWindow; win.navigator.getBattery = sdenv.tools.setNativeFuncName(() => { return new Promise((resolve, reject) => { resolve({ onchargingchange: null, onchargingtimechange: null, ondischargingtimechange: null, onlevelchange: null, ...charging.charging_success, ...config, }); }); }, 'getBattery'); } /* downlink:设备下行速速,单位兆 effectiveType:网络类型,如:"slow-2g"、"2g"、"3g"、"4g" rrt:设备的往返延时,单位毫秒 saveData:是否为节流模式 type:网络连接类型,有些浏览器有有些没有,如:"bluetooth"(蓝牙1)、"cellular"(蜂窝网络2)、"ethernet"(以太网3)、"none"(无网络连接)、"wifi"(wifi连接4)、"wimax5" */ function connectionHandle(config) { const win = sdenv.memory.sdWindow; if (typeof config !== 'object') { config = {}; } sdenv.tools.addConstants(win.navigator.connection, { downlink: 6.66, effectiveType: "4g", onchange: null, rtt: 0, saveData: false, ...config, }); } let cache$3 = undefined; function DateAndRandom({ datas }) { sdenv.memory.sdWindow; this.data = datas || {}; if (this.data?.firstMap && Object.values(this.data.firstMap).some((it) => !it)) { throw new Error('日期首位配置错误请检查'); } this.runs = []; Object.assign(this, cache$3); } DateAndRandom.prototype.shift = function (name) { const { firstMap } = this.data; let val = this.data[name].shift(); if (typeof firstMap[name] === 'number') { val += firstMap[name]; } this.runs.push(val); return val; }; DateAndRandom.prototype.wrapFun = function (funcName, def) { const name = `_${funcName}`; if (!this[name]) return undefined; if (def === undefined && !Array.isArray(this.data[name])) this.data[name] = []; const self = this; return setNativeFuncName(function() { if (def !== undefined) return def; if (self.data.firstMap?.[name]) { if (!self.data[name].length) { throw new Error(`DateAndRandom的${name}数据不够`); } return self.shift(name); } const val = self[name].call(this); self.data[name].push(val); return val }, funcName); }; DateAndRandom.prototype.wrapClass = function (className, cla) { const win = sdenv.memory.sdWindow; const name = `_${className}`; if (!Array.isArray(this.data[name])) this.data[name] = []; const self = this; return setNativeFuncName(new Proxy(cla, { construct(target, argumentsList, newTarget) { if (self.data.firstMap?.[name]) { if (!self.data[name].length) { throw new Error(`DateAndRandom的${name}数据不够`); } return new cla(self.shift(name)); } const val = Reflect.construct(target, argumentsList, newTarget); self.data[name].push(win.Date.prototype.valueOf.call(val)); return val; }, apply(target, argumentsList, newTarget) { const val = Reflect.apply(target, argumentsList, newTarget); return val; } }), cla.name || className); }; DateAndRandom.prototype.getData = function (copy) { const ret = Object.entries(this.data).reduce((ans, [key, val]) => { if (key === 'firstMap' || !val.length) return ans; if (key === '_random') { ans[key] = val; ans.firstMap[key] = true; return ans; } const first = val[0]; ans.firstMap[key] = first; ans[key] = val.map((it) => it - first); return ans; }, { firstMap: {} }); if (copy) { copy(JSON.stringify(ret)); console.log('日期与随机数数据复制成功'); } return ret; }; function dateAndRandomHandle(config) { if (typeof config !== 'object') config = {}; const win = sdenv.memory.sdWindow; if (!cache$3) { cache$3 = { _now: win.Date.now, _parse: win.Date.parse, _valueOf: win.Date.prototype.valueOf, _getTime: win.Date.prototype.getTime, _toString: win.Date.prototype.toString, _random: win.Math.random, }; } const { randomReturn = sdenv.config.randomReturn } = config; const dateAndRandom = new DateAndRandom(config); sdenv.tools.addUtil(dateAndRandom.getData.bind(dateAndRandom), 'getDateData'); win.Date = dateAndRandom.wrapClass('newdate', win.Date); win.Date.now = dateAndRandom.wrapFun('now'); win.Date.parse = dateAndRandom.wrapFun('parse'); win.Math.random = dateAndRandom.wrapFun('random', randomReturn); } const delay = (ms) => new Promise(resolve => sdenv.memory.sdWindow.setTimeout(resolve, ms)); let cache$2 = undefined; function ovserverHandle(config) { if (typeof config !== 'object') config = {}; const win = sdenv.memory.sdWindow; if (!cache$2) { cache$2 = win.MutationObserver; } const { newLog, addLog, runLog, log, addCb, runCb, newCb, cb, filter = () => true } = config; win.MutationObserver = sdenv.tools.setNativeFuncName(new Proxy(cache$2, { construct: function (target, argArray, newTarget) { const [func] = argArray; const funcStr = func.param ? JSON.stringify(func.param) : sdenv.tools.compressText(func.toString()); if (newLog || log) win.console.log(`【NEW OVSERVER】方法:${funcStr}`); (newCb || cb)?.(...argArray); const result = Reflect.construct(target, [async (...params) => { if (!filter || !filter(...argArray)) return; if (runLog || log) win.console.log(`【RUN OVSERVER】方法:${funcStr}`); (runCb || cb)?.(...params[0]); await delay(0); func(...params); }], newTarget); result.observe = new Proxy(result.observe, { apply: function (target, thisArg, params) { if (addLog || log) win.console.log(`【ADD OVSERVER】方法:${funcStr}`); (addCb || cb)?.(...params); return Reflect.apply(target, thisArg, params); } }); return result; }, }), 'MutationObserver'); } let cache$1 = undefined; function intervalHandle(config) { if (typeof config !== 'object') config = {}; const win = sdenv.memory.sdWindow; if (!cache$1) { cache$1 = win.setInterval; } const { log, cb, time, filter = () => true } = config; win.setInterval = sdenv.tools.setNativeFuncName(new Proxy(cache$1, { apply: function (target, thisArg, params) { if (!filter || !filter(...params)) return; const [func, timeout] = params; const funcStr = func.param ? JSON.stringify(func.param) : sdenv.tools.compressText(func.toString()); if (log) win.console.log(`【INTERVAL APPLY】增加setInterval事件,时间:${timeout}, 方法:${funcStr}`); if (time !== undefined) { if (typeof time !== 'number') throw new Error(`time配置如果存在值则必须是数字`); return Reflect.apply(target, thisArg, [ () => { if (log) win.console.log(`【INTERVAL RUN】setInterval执行,时间:${timeout},方法:${funcStr}`); func(); if (log) win.console.log(`【INTERVAL RUNED】setInterval执行,时间:${timeout},方法:${funcStr}`); }, time || timeout, ]); } return sdenv.tools.addInterval(func, timeout); }, }), 'setInterval'); } const getInterval = () => cache$1; var handles = /*#__PURE__*/Object.freeze({ __proto__: null, batteryHandle: batteryHandle, connectionHandle: connectionHandle, cookieHandle: cookieHandle, dateAndRandomHandle: dateAndRandomHandle, evalHandle: evalHandle, eventHandle: eventHandle, funcHandle: funcHandle, getInterval: getInterval, getTimeout: getTimeout, intervalHandle: intervalHandle, ovserverHandle: ovserverHandle, timeoutHandle: timeoutHandle }); function setWindow(win) { if (!win) return; Object.assign(sdenv.memory, { sdWindow: win, sdEval: win.eval, sdFunction: win.Function, sdDate: win.Date, sdMath: win.Math, }); if (sdenv.config.isNode) { // 修改setFunc工具中的Function指向到window.Function _setFuncInit(); Object.setPrototypeOf(win.window, win.Window.prototype); } } let cache = undefined; class index { constructor(config, win = undefined) { const obj = win ? win.Object : Object; if (!cache) cache = obj; if (!obj.sdenv) { merge(sdenv, config || {}); obj.prototype.sdenv = () => sdenv; setWindow(win); merge(sdenv.tools, tools); merge(sdenv.adapt, adapt); // 会用到前面tools的方法 loopRunInit(); } Object.assign(this, obj.sdenv()); } static sdenv() { if (cache) return cache.sdenv(); console.error('sdenv还未被初始化!'); } getHandle(name) { const handleName = `${name}Handle`; if (!handles[handleName]) return; return (...params) => { handles[handleName](...params); return this; } } getTools(name) { if (!sdenv.tools[name]) return; return (...params) => { sdenv.tools[name](...params); return this; } } getUtils(name) { if (!sdenv.utils[name]) return; return (...params) => { sdenv.utils[name](...params); return this; } } } return index; })(); SdenvExtend.version = 'V1.2.1'