{"ScriptPreparationCode":"const Tag = Object.freeze({\r\n ARGUMENTS: \u0027[object Arguments]\u0027,\r\n ARRAY: \u0027[object Array]\u0027,\r\n BOOLEAN: \u0027[object Boolean]\u0027,\r\n DATE: \u0027[object Date]\u0027,\r\n ERROR: \u0027[object Error]\u0027,\r\n MAP: \u0027[object Map]\u0027,\r\n NUMBER: \u0027[object Number]\u0027,\r\n OBJECT: \u0027[object Object]\u0027,\r\n REGEXP: \u0027[object RegExp]\u0027,\r\n SET: \u0027[object Set]\u0027,\r\n STRING: \u0027[object String]\u0027,\r\n SYMBOL: \u0027[object Symbol]\u0027,\r\n WEAKMAP: \u0027[object WeakMap]\u0027,\r\n WEAKSET: \u0022[object WeakSet]\u0022,\r\n ARRAYBUFFER: \u0027[object ArrayBuffer]\u0027,\r\n DATAVIEW: \u0027[object DataView]\u0027,\r\n FLOAT32: \u0027[object Float32Array]\u0027,\r\n FLOAT64: \u0027[object Float64Array]\u0027,\r\n INT8: \u0027[object Int8Array]\u0027,\r\n INT16: \u0027[object Int16Array]\u0027,\r\n INT32: \u0027[object Int32Array]\u0027,\r\n UINT8: \u0027[object Uint8Array]\u0027,\r\n UINT8CLAMPED: \u0027[object Uint8ClampedArray]\u0027,\r\n UINT16: \u0027[object Uint16Array]\u0027,\r\n UINT32: \u0027[object Uint32Array]\u0027,\r\n BIGINT64: \u0022[object BigInt64Array]\u0022,\r\n BIGUINT64: \u0022[object BigUint64Array]\u0022\r\n});\r\n\r\nfunction cloneInternalNoRecursion(_value, customizer, log, doThrow) {\r\n \r\n if (typeof log !== \u0022function\u0022) log = console.warn;\r\n\r\n let result;\r\n\r\n // Will be used to store cloned values so that we don\u0027t loop infinitely on \r\n // circular references.\r\n const cloneStore = new Map();\r\n\r\n // This symbol is used to indicate that the cloned value is the top-level \r\n // object that will be returned by the function.\r\n const TOP_LEVEL = Symbol(\u0022TOP_LEVEL\u0022);\r\n\r\n // A queue so we can avoid recursion.\r\n const queue = [{ value: _value, parentOrAssigner: TOP_LEVEL }]; \r\n \r\n // We will do a second pass through everything to check Object.isExtensible, \r\n // Object.isSealed and Object.isFrozen. We do it last so we don\u0027t run into \r\n // issues where we append properties on a frozen object, etc\r\n const isExtensibleSealFrozen = [];\r\n \r\n function warn(message, cause) {\r\n class CloneDeepWarning extends Error {\r\n constructor(message, cause) {\r\n super(message, cause);\r\n this.name = CloneDeepWarning.name;\r\n }\r\n }\r\n\r\n return new CloneDeepWarning(message, cause);\r\n }\r\n\r\n function assign(cloned, parentOrAssigner, prop, metadata) {\r\n if (parentOrAssigner === TOP_LEVEL) \r\n result = cloned;\r\n else if (typeof parentOrAssigner === \u0022function\u0022) \r\n parentOrAssigner(cloned, prop, metadata);\r\n else if (typeof metadata === \u0022object\u0022) {\r\n const hasAccessor = [\u0022get\u0022, \u0022set\u0022].some(key =\u003E \r\n typeof metadata[key] === \u0022function\u0022);\r\n \r\n // \u0060cloned\u0060 or getAccessor will determine the value\r\n delete metadata.value;\r\n\r\n // defineProperty throws if property with accessors is writeable\r\n if (hasAccessor) {\r\n delete metadata.writable;\r\n log(warn(\u0022Cloning value whose property descriptor is a get \u0022 \u002B \r\n \u0022or set accessor.\u0022));\r\n }\r\n\r\n Object.defineProperty(parentOrAssigner, prop, Object.assign(\r\n // defineProperty throws if value and set/get accessor coexist\r\n hasAccessor ? {} : { value: cloned },\r\n metadata,\r\n ));\r\n }\r\n else \r\n parentOrAssigner[prop] = cloned;\r\n return cloned;\r\n }\r\n \r\n function tagOf(value) {\r\n return Object.prototype.toString.call(value);\r\n }\r\n\r\n for (let obj = queue.shift(); obj !== undefined; obj = queue.shift()) {\r\n // \u0060value\u0060 is the value to deeply clone\r\n // \u0060parentOrAssigner\u0060 is either\r\n // - TOP_LEVEL - this value is the top-level object that will be \r\n // returned by the function\r\n // - object - a parent object this value is nested under\r\n // - function - an \u0022assigner\u0022 that has the responsiblity of \r\n // assigning the cloned value to something\r\n // \u0060prop\u0060 is used with \u0060parentOrAssigner\u0060 if it is an object so that the \r\n // cloned object will be assigned to \u0060parentOrAssigner[prop]\u0060.\r\n // \u0060metadata\u0060 contains the property descriptor(s) for the value. It may \r\n // be undefined.\r\n const { value, parentOrAssigner, prop, metadata } = obj;\r\n \r\n // Will contain the cloned object.\r\n let cloned;\r\n\r\n // Check for circular references.\r\n const seen = cloneStore.get(value);\r\n if (seen !== undefined) {\r\n assign(seen, parentOrAssigner, prop, metadata);\r\n continue;\r\n }\r\n\r\n // If true, do not not clone the properties of value.\r\n let ignoreProps;\r\n\r\n // If true, do not have \u0060cloned\u0060 share the prototype of \u0060value\u0060.\r\n let ignoreProto;\r\n\r\n // Is true if the customizer determines the value of \u0060cloned\u0060.\r\n let useCustomizerClone;\r\n\r\n // Perform user-injected logic if applicable.\r\n if (typeof customizer === \u0022function\u0022) {\r\n\r\n let clone, additionalValues, ignore;\r\n\r\n try {\r\n const customResult = customizer(value);\r\n \r\n if (typeof customResult === \u0022object\u0022) {\r\n useCustomizerClone = true;\r\n\r\n // Must wrap destructure in () if not variable declaration\r\n ({ clone, \r\n additionalValues,\r\n ignore,\r\n ignoreProps,\r\n ignoreProto\r\n } = customResult);\r\n\r\n if (ignore === true) continue;\r\n\r\n cloned = assign(clone, \r\n parentOrAssigner, \r\n prop, \r\n metadata);\r\n\r\n if (Array.isArray(additionalValues))\r\n additionalValues.forEach(object =\u003E {\r\n if (typeof object === \u0022object\u0022) {\r\n queue.push({\r\n value: object.value,\r\n parentOrAssigner: object.assigner\r\n });\r\n }\r\n });\r\n }\r\n }\r\n catch(error) {\r\n if (doThrow === true) throw error;\r\n\r\n clone = undefined;\r\n useCustomizerClone = false;\r\n \r\n error.message = \u0022customizer encountered error. Its results \u0022 \u002B \r\n \u0022will be ignored for the current value, and \u0022 \u002B \r\n \u0022the algorithm will proceed with default \u0022 \u002B \r\n \u0022behavior. Error encountered: \u0022 \u002B error.message;\r\n log(warn(error.message, error.cause));\r\n }\r\n }\r\n\r\n try {\r\n // skip the following \u0022else if\u0022 branches\r\n if (useCustomizerClone === true) {}\r\n\r\n // If value is primitive, just assign it directly.\r\n else if (value === null || ![\u0022object\u0022, \u0022function\u0022]\r\n .includes(typeof value)) {\r\n assign(value, parentOrAssigner, prop, metadata);\r\n continue;\r\n }\r\n\r\n // We won\u0027t clone weakmaps or weaksets.\r\n else if ([Tag.WEAKMAP, Tag.WEAKSET].includes(tagOf(value)))\r\n throw warn(\u0060Attempted to clone unsupported type${\r\n typeof value.constructor === \u0022function\u0022 \u0026\u0026 \r\n typeof value.constructor.name === \u0022string\u0022\r\n ? \u0060 ${value.constructor.name}\u0060\r\n : \u0022\u0022\r\n }.\u0060);\r\n\r\n // We only copy functions if they are methods.\r\n else if (typeof value === \u0022function\u0022) {\r\n cloned = assign(parentOrAssigner !== TOP_LEVEL \r\n ? value \r\n : {}, \r\n parentOrAssigner, \r\n prop, \r\n metadata);\r\n log(warn(\u0060Attempted to clone function${typeof prop === \u0022string\u0022\r\n ? \u0060 with name ${prop}\u0060\r\n : \u0022\u0022 }. \u0060 \u002B \r\n \u0022JavaScript functions cannot be cloned. If this \u0022 \u002B \r\n \u0022function is a method, then it will be copied \u0022\u002B \r\n \u0022directly.\u0022));\r\n if (parentOrAssigner === TOP_LEVEL) continue;\r\n }\r\n\r\n // If value is a Node Buffer, just use Buffer\u0027s subarray method.\r\n else if (typeof global === \u0022object\u0022\r\n \u0026\u0026 global.Buffer\r\n \u0026\u0026 typeof Buffer === \u0022function\u0022\r\n \u0026\u0026 typeof Buffer.isBuffer === \u0022function\u0022\r\n \u0026\u0026 Buffer.isBuffer(value))\r\n cloned = assign(value.subarray(), \r\n parentOrAssigner, \r\n prop, \r\n metadata);\r\n \r\n else if (Array.isArray(value))\r\n cloned = assign(new Array(value.length), \r\n parentOrAssigner, \r\n prop, \r\n metadata);\r\n\r\n // Ordinary objects, or the rare \u0060arguments\u0060 clone\r\n else if ([Tag.OBJECT, Tag.ARGUMENTS].includes(tagOf(value)))\r\n cloned = assign(Object.create(Object.getPrototypeOf(value)), \r\n parentOrAssigner, \r\n prop,\r\n metadata);\r\n \r\n // values that will be called using contructor\r\n else {\r\n const Value = value.constructor;\r\n\r\n // Booleans, Number, String or Symbols which used \u0060new\u0060 syntax \r\n // so JavaScript thinks they are objects\r\n // We also handle Date here because it is convenient\r\n if ([Tag.BOOLEAN, Tag.DATE].includes(tagOf(value)))\r\n cloned = assign(new Value(Number(value)), \r\n parentOrAssigner, \r\n prop,\r\n metadata);\r\n else if ([Tag.NUMBER, Tag.STRING].includes(tagOf(value)))\r\n cloned = assign(new Value(value), \r\n parentOrAssigner, \r\n prop, \r\n metadata);\r\n else if (Tag.SYMBOL === tagOf(value)) {\r\n cloned = assign(\r\n Object(Symbol.prototype.valueOf.call(value)), \r\n parentOrAssigner, \r\n prop,\r\n metadata);\r\n }\r\n\r\n else if (Tag.REGEXP === tagOf(value)) {\r\n const regExp = new Value(value.source, /\\w*$/.exec(value));\r\n regExp.lastIndex = value.lastIndex;\r\n cloned = assign(regExp, parentOrAssigner, prop, metadata);\r\n }\r\n\r\n else if (Tag.ERROR === tagOf(value)) {\r\n const cause = value.cause;\r\n cloned = assign(cause === undefined\r\n ? new Value(value.message)\r\n : new Value(value.message, { cause }),\r\n parentOrAssigner,\r\n prop,\r\n metadata);\r\n }\r\n\r\n else if (Tag.ARRAYBUFFER === tagOf(value)) {\r\n // copy data over to clone\r\n const arrayBuffer = new Value(value.byteLength);\r\n new Uint8Array(arrayBuffer).set(new Uint8Array(value));\r\n \r\n cloned = assign(arrayBuffer, \r\n parentOrAssigner, \r\n prop, \r\n metadata);\r\n }\r\n \r\n // TypeArrays\r\n else if ([ \r\n Tag.DATAVIEW, \r\n Tag.FLOAT32,\r\n Tag.FLOAT64,\r\n Tag.INT8,\r\n Tag.INT16,\r\n Tag.INT32,\r\n Tag.UINT8,\r\n Tag.UINT8CLAMPED,\r\n Tag.UINT16,\r\n Tag.UINT32,\r\n Tag.BIGINT64,\r\n Tag.BIGUINT64\r\n ].includes(tagOf(value))) {\r\n // copy data over to clone\r\n const buffer = new value.buffer.constructor(\r\n value.buffer.byteLength);\r\n new Uint8Array(buffer).set(new Uint8Array(value.buffer));\r\n \r\n cloned = assign(\r\n new Value(buffer, value.byteOffset, value.length),\r\n parentOrAssigner,\r\n prop,\r\n metadata);\r\n }\r\n\r\n else if (Tag.MAP === tagOf(value)) {\r\n const map = new Value;\r\n cloned = assign(map, parentOrAssigner, prop, metadata);\r\n value.forEach((subValue, key) =\u003E {\r\n queue.push({ \r\n value: subValue, \r\n parentOrAssigner: cloned =\u003E {\r\n isExtensibleSealFrozen.push([subValue, cloned]);\r\n map.set(key, cloned)\r\n }\r\n });\r\n });\r\n }\r\n\r\n else if (Tag.SET === tagOf(value)) {\r\n const set = new Value;\r\n cloned = assign(set, parentOrAssigner, prop, metadata);\r\n value.forEach(subValue =\u003E {\r\n queue.push({ \r\n value: subValue, \r\n parentOrAssigner: cloned =\u003E {\r\n isExtensibleSealFrozen.push([subValue, cloned]);\r\n map.set(key, cloned)\r\n }\r\n });\r\n });\r\n }\r\n\r\n else\r\n throw warn(\u0022Attempted to clone unsupported type.\u0022);\r\n }\r\n }\r\n catch(error) {\r\n error.message = \u0022Encountered error while attempting to clone \u0022 \u002B \r\n \u0022specific value. The value will be \\\u0022cloned\\\u0022 \u0022 \u002B \r\n \u0022into an empty object. Error encountered: \u0022 \u002B \r\n error.message\r\n log(warn(error.message, error.cause));\r\n cloned = assign({}, parentOrAssigner, prop, metadata);\r\n\r\n // We don\u0027t want the prototype if we failed and set the value to an \r\n // empty object.\r\n ignoreProto = true;\r\n }\r\n\r\n cloneStore.set(value, cloned);\r\n\r\n isExtensibleSealFrozen.push([value, cloned]);\r\n\r\n // Ensure clone has prototype of value\r\n if (ignoreProto !== true\r\n \u0026\u0026 Object.getPrototypeOf(cloned) !== Object.getPrototypeOf(value))\r\n Object.setPrototypeOf(cloned, Object.getPrototypeOf(value));\r\n\r\n if (ignoreProps === true) continue;\r\n\r\n // Now copy all enumerable and non-enumerable properties.\r\n [Object.getOwnPropertyNames(value), Object.getOwnPropertySymbols(value)]\r\n .flat()\r\n .forEach(key =\u003E {\r\n queue.push({ \r\n value: value[key], \r\n parentOrAssigner: cloned,\r\n prop: key,\r\n metadata: Object.getOwnPropertyDescriptor(value, key)\r\n });\r\n });\r\n }\r\n\r\n // Check extensible, seal, and frozen statuses.\r\n isExtensibleSealFrozen.forEach(([value, cloned]) =\u003E {\r\n if (!Object.isExtensible(value)) Object.preventExtensions(cloned);\r\n if (Object.isSealed(value)) Object.seal(cloned);\r\n if (Object.isFrozen(value)) Object.freeze(cloned);\r\n });\r\n\r\n return result;\r\n}\r\n\r\nfunction cloneDeep(value, options) {\r\n if (typeof options === \u0022function\u0022) options = { customizer: options };\r\n else if (typeof options !== \u0022object\u0022) options = {};\r\n \r\n let { customizer, log, logMode, letCustomizerThrow } = options;\r\n\r\n if (logMode !== \u0022string\u0022 || typeof log === \u0022function\u0022);\r\n else if (logMode.toLowerCase() === \u0022silent\u0022) \r\n log = () =\u003E { /* no-op */ };\r\n else if (logMode.toLowerCase() === \u0022quiet\u0022)\r\n log = error =\u003E console.warn(error.message);\r\n\r\n return cloneInternalNoRecursion(value, customizer, log, letCustomizerThrow);\r\n}\r\n\r\nvar myObject = {};\r\nlet next = myObject;\r\nfor (let i = 0; i \u003C 1000; i\u002B\u002B) {\r\n\tnext.b = {};\r\n\tnext = next.b;\r\n}\r\n\r\nlet myCopy;","TestCases":[{"Name":"Lodash cloneDeep","Code":"myCopy = _.cloneDeep(myObject);","IsDeferred":false},{"Name":"Native structuredClone","Code":"myCopy = structuredClone(myObject);","IsDeferred":false},{"Name":"mt cloneDeep","Code":"myCopy = cloneDeep(myObject);","IsDeferred":false}]}