# Path: deluca/core.py
# class Env(Obj):
# 
#   @abstractmethod
#   def init(self):
#     """Return an initialized state"""
# 
#   @abstractmethod
#   def __call__(self, state, action, *args, **kwargs):
#     """Return an updated state"""
# 
# Path: deluca/core.py
# def field(default=None, jaxed=True, **kwargs):
#   if "default_factory" not in kwargs:
#     kwargs["default"] = default
#   kwargs["pytree_node"] = jaxed
#   return flax.struct.field(**kwargs)
# 
# Path: deluca/core.py
# class Obj:
# 
#   def freeze(self):
#     object.__setattr__(self, "__frozen__", True)
# 
#   def unfreeze(self):
#     object.__setattr__(self, "__frozen__", False)
# 
#   def is_frozen(self):
#     return not hasattr(self, "__frozen__") or getattr(self, "__frozen__")
# 
#   def __new__(cls, *args, **kwargs):
#     """A true bastardization of __new__..."""
# 
#     def __setattr__(self, name, value):
#       if self.is_frozen():
#         raise dataclasses.FrozenInstanceError
#       object.__setattr__(self, name, value)
# 
#     def replace(self, **updates):
#       obj = dataclasses.replace(self, **updates)
#       obj.freeze()
#       return obj
# 
#     cls.__setattr__ = __setattr__
#     cls.replace = replace
# 
#     obj = object.__new__(cls)
#     obj.unfreeze()
# 
#     return obj
# 
#   @classmethod
#   def __init_subclass__(cls, *args, **kwargs):
#     flax.struct.dataclass(cls)
# 
#   @classmethod
#   def create(cls, *args, **kwargs):
#     # NOTE: Oh boy, this is so janky
#     obj = cls(*args, **kwargs)
#     obj.setup()
#     obj.freeze()
# 
#     return obj
# 
#   @classmethod
#   def unflatten(cls, treedef, leaves):
#     """Expost a default unflatten method"""
#     return jax.tree_util.tree_unflatten(treedef, leaves)
# 
#   def setup(self):
#     """Used in place of __init__"""
# 
#   def flatten(self):
#     """Expose a default flatten method"""
#     return jax.tree_util.tree_flatten(self)[0]


from deluca.core import Env
from deluca.core import field
from deluca.core import Obj
import jax.numpy as jnp
    arr:
    h:
  """
  arr: jnp.ndarray = field(jaxed=True)
  h: float = field(0.0, jaxed=True)

  def flatten(self):
    """flatten.

    Returns:

    """
    return self.arr

  # TODO(dsuo): this should be a classmethod.
  def unflatten(self, arr):
    """unflatten.

    Args:
      arr:

    Returns:

    """
    return ReacherState(arr=arr, h=self.h)


class Reacher(Env):
  """Reacher."""
  m1: float = field(1.0, jaxed=False)

# Path: deluca/core.py
# class Env(Obj):
# 
#   @abstractmethod
#   def init(self):
#     """Return an initialized state"""
# 
#   @abstractmethod
#   def __call__(self, state, action, *args, **kwargs):
#     """Return an updated state"""
# 
# Path: deluca/core.py
# def field(default=None, jaxed=True, **kwargs):
#   if "default_factory" not in kwargs:
#     kwargs["default"] = default
#   kwargs["pytree_node"] = jaxed
#   return flax.struct.field(**kwargs)
# 
# Path: deluca/core.py
# class Obj:
# 
#   def freeze(self):
#     object.__setattr__(self, "__frozen__", True)
# 
#   def unfreeze(self):
#     object.__setattr__(self, "__frozen__", False)
# 
#   def is_frozen(self):
#     return not hasattr(self, "__frozen__") or getattr(self, "__frozen__")
# 
#   def __new__(cls, *args, **kwargs):
#     """A true bastardization of __new__..."""
# 
#     def __setattr__(self, name, value):
#       if self.is_frozen():
#         raise dataclasses.FrozenInstanceError
#       object.__setattr__(self, name, value)
# 
#     def replace(self, **updates):
#       obj = dataclasses.replace(self, **updates)
#       obj.freeze()
#       return obj
# 
#     cls.__setattr__ = __setattr__
#     cls.replace = replace
# 
#     obj = object.__new__(cls)
#     obj.unfreeze()
# 
#     return obj
# 
#   @classmethod
#   def __init_subclass__(cls, *args, **kwargs):
#     flax.struct.dataclass(cls)
# 
#   @classmethod
#   def create(cls, *args, **kwargs):
#     # NOTE: Oh boy, this is so janky
#     obj = cls(*args, **kwargs)
#     obj.setup()
#     obj.freeze()
# 
#     return obj
# 
#   @classmethod
#   def unflatten(cls, treedef, leaves):
#     """Expost a default unflatten method"""
#     return jax.tree_util.tree_unflatten(treedef, leaves)
# 
#   def setup(self):
#     """Used in place of __init__"""
# 
#   def flatten(self):
#     """Expose a default flatten method"""
#     return jax.tree_util.tree_flatten(self)[0]


# Path: deluca/envs/classic/_reacher.py
from deluca.core import Env
from deluca.core import field
from deluca.core import Obj
import jax.numpy as jnp

    arr:
    h:
  """
  arr: jnp.ndarray = field(jaxed=True)
  h: float = field(0.0, jaxed=True)

  def flatten(self):
    """flatten.

    Returns:

    """
    return self.arr

  # TODO(dsuo): this should be a classmethod.
  def unflatten(self, arr):
    """unflatten.

    Args:
      arr:

    Returns:

    """
    return ReacherState(arr=arr, h=self.h)


class Reacher(Env):
  """Reacher."""
  m1: float = field(1.0, jaxed=False)

  m2: float = field(1.0, jaxed=False)