function clone(object, options = null) {
    // manually coalesced instead of default parameters for performance
    const isStrict = !!(options && options.isStrict);
    const realm = options && options.realm || GLOBAL_THIS;
    const getObjectClone = isStrict ? getObjectCloneStrict : getObjectCloneLoose;
    /**
     * @function handleCopy
     *
     * @description
     * copy the object recursively based on its type
     *
     * @param object the object to copy
     * @returns the copied object
     */

    const handleCopy = (object, cache) => {
      if (!object || typeof object !== 'object' || cache.has(object)) {
        return object;
      } // DOM objects


      if (typeof HTMLElement !== 'undefined' && object instanceof HTMLElement) {
        return object.cloneNode(false);
      }

      const Constructor = object.constructor; // plain objects

      if (Constructor === realm.Object) {
        cache.add(object);
        return getObjectClone(object, realm, handleCopy, cache);
      }

      let clone; // arrays

      if (isArray(object)) {
        cache.add(object); // if strict, include non-standard properties

        if (isStrict) {
          return getObjectCloneStrict(object, realm, handleCopy, cache);
        }

        clone = new Constructor();

        for (let index = 0; index < object.length; index++) {
          clone[index] = handleCopy(object[index], cache);
        }

        return clone;
      } // dates


      if (object instanceof realm.Date) {
        return new Constructor(object.getTime());
      } // regexps


      if (object instanceof realm.RegExp) {
        clone = new Constructor(object.source, object.flags || getRegExpFlags(object));
        clone.lastIndex = object.lastIndex;
        return clone;
      } // maps


      if (realm.Map && object instanceof realm.Map) {
        cache.add(object);
        clone = new Constructor();
        object.forEach((value, key) => {
          clone.set(key, handleCopy(value, cache));
        });
        return clone;
      } // sets


      if (realm.Set && object instanceof realm.Set) {
        cache.add(object);
        clone = new Constructor();
        object.forEach(value => {
          clone.add(handleCopy(value, cache));
        });
        return clone;
      } // buffers (node-only)


      if (realm.Buffer && realm.Buffer.isBuffer(object)) {
        clone = realm.Buffer.allocUnsafe ? realm.Buffer.allocUnsafe(object.length) : new Constructor(object.length);
        object.copy(clone);
        return clone;
      } // arraybuffers / dataviews


      if (realm.ArrayBuffer) {
        // dataviews
        if (realm.ArrayBuffer.isView(object)) {
          return new Constructor(object.buffer.slice(0));
        } // arraybuffers


        if (object instanceof realm.ArrayBuffer) {
          return object.slice(0);
        }
      } // if the object cannot / should not be cloned, don't


      if ( // promise-like
      hasOwnProperty.call(object, 'then') && typeof object.then === 'function' || // errors
      object instanceof Error || // weakmaps
      realm.WeakMap && object instanceof realm.WeakMap || // weaksets
      realm.WeakSet && object instanceof realm.WeakSet) {
        return object;
      }

      cache.add(object); // assume anything left is a custom constructor

      return getObjectClone(object, realm, handleCopy, cache);
    };

    return handleCopy(object, createCache());
  }
@function clone

@description
copy an object deeply as much as possible

If `strict` is applied, then all properties (including non-enumerable ones)
are copied with their original property descriptors on both objects and arrays.

The object is compared to the global constructors in the `realm` provided,
and the native constructor is always used to ensure that extensions of native
objects (allows in ES2015+) are maintained.

@param object the object to copy
@param [options] the options for copying with
@param [options.isStrict] should the copy be strict
@param [options.realm] the realm (this) object the object is copied from
@returns the copied object