// @ts-nocheck
/**
 * Duplicate objects to prevent Cite changing values outside of own scope
 *
 * @access protected
 * @method deepCopy
 * @memberof module:@citation-js/core.util
 *
 * @param {Object} obj - Input object
 * @param {Set} [seen]
 *
 * @return {Object} Duplicated object
 * @throws {TypeError}
 */
export function deepCopy(value, seen = new Set()) {
    if (typeof value !== 'object' ||
        value === null ||
        (value.constructor !== Object && value.constructor !== Array)) {
        return value;
    }
    if (seen.has(value)) {
        throw new TypeError('Recursively copying circular structure');
    }
    seen.add(value);
    let copy;
    if (value.constructor === Array) {
        copy = value.map((value) => deepCopy(value, seen));
    }
    else {
        const object = {};
        for (const key in value) {
            object[key] = deepCopy(value[key], seen);
        }
        copy = object;
    }
    seen.delete(value);
    return copy;
}
// // Unfortunately too costly performance-wise, but the
// // proper way to clone any object (apart from arrays perhaps):
// const object = Object.create(Object.getPrototypeOf(value))
// const descriptors = Object.getOwnPropertyDescriptors(value)
// for (let key in descriptors) {
//   const descriptor = descriptors[key]
//   if (descriptor.value) { descriptor.value = deepCopy(descriptor.value) }
//   Object.defineProperty(object, key, descriptor)
// }
export default deepCopy;
