docs: function equals(value1, value2, traversedValues) {
    if (!(value1 instanceof Object)) {
      return value1 === value2
    }
    
    for (let wrappedType of WRAPPED_TYPES) {
      if (value1 instanceof wrappedType) {
        return (value2 instanceof wrappedType) &&
            (value1.valueOf() === value2.valueOf())
      }
    }
    
    if (value1 instanceof RegExp) {
      return (value2 instanceof RegExp) &&
          (value1.source === value2.source) &&
          (value2.flags === value2.flags)
    }
    
    for (let uninspectableType of UNINSPECTABLE_TYPES) {
      if (value1 instanceof uninspectableType) {
        return (value2 instanceof uninspectableType) &&
            (value1 === value2)
      }
    }
    
    if ((typeof ArrayBuffer === "function") && (value1 instanceof ArrayBuffer)) {
      return (value2 instanceof ArrayBuffer) &&
          equals(new Int8Array(value1), new Int8Array(value2), traversedValues)
    }
  
    if ((typeof DataView === "function") && (value1 instanceof DataView)) {
      return (value2 instanceof DataView) &&
          equals(
            new Int8Array(value1.buffer, value1.byteOffset, value1.byteLength),
            new Int8Array(value2.buffer, value2.byteOffset, value2.byteLength),
            traversedValues
          )
    }
    
    for (let arrayType of TYPED_ARRAY_TYPES) {
      if (value1 instanceof arrayType) {
        return (value2 instanceof arrayType) &&
            arrayEquals(value1, value2, traversedValues)
      }
    }
    
    if ((typeof ImageData === "function") && (value1 instanceof ImageData)) {
      return (value2 instanceof ImageData) &&
          (value1.width === value2.width) &&
          (value1.height === value2.height) &&
          equals(value1.data, value2.data, traversedValues)
    }
    
    if (value1 instanceof Array) {
      return (value2 instanceof Array) &&
          arrayEquals(value1, value2, traversedValues)
    }
    
    if (value1 instanceof Map) {
      return mapEquals(value1, value2, traversedValues)
    }
    
    if (value1 instanceof Set) {
      return setEquals(value1, value2, traversedValues)
    }
  
    if (isPlainObjectOrEntity(value1) && isPlainObjectOrEntity(value2)) {
      return objectEquals(value1, value2, traversedValues)
    }
  
    throw new Error(`Unsupported argument types: ${value1}, ${value2}`)
  }