# Path: src/apscheduler/abc.py
# class Trigger(Iterator[datetime], metaclass=ABCMeta):
#     """Abstract base class that defines the interface that every trigger must implement."""
# 
#     __slots__ = ()
# 
#     @abstractmethod
#     def next(self) -> datetime | None:
#         """
#         Return the next datetime to fire on.
# 
#         If no such datetime can be calculated, ``None`` is returned.
#         :raises apscheduler.exceptions.MaxIterationsReached:
#         """
# 
#     @abstractmethod
#     def __getstate__(self):
#         """Return the (JSON compatible) serializable state of the trigger."""
# 
#     @abstractmethod
#     def __setstate__(self, state):
#         """Initialize an empty instance from an existing state."""
# 
#     def __iter__(self):
#         return self
# 
#     def __next__(self) -> datetime:
#         dateval = self.next()
#         if dateval is None:
#             raise StopIteration
#         else:
#             return dateval
# 
# Path: src/apscheduler/exceptions.py
# class MaxIterationsReached(Exception):
#     """
#     Raised when a trigger has reached its maximum number of allowed computation iterations when
#     trying to calculate the next fire time.
#     """
# 
# Path: src/apscheduler/marshalling.py
# def marshal_object(obj) -> tuple[str, Any]:
#     return f'{obj.__class__.__module__}:{obj.__class__.__qualname__}', obj.__getstate__()
# 
# def unmarshal_object(ref: str, state):
#     cls = callable_from_ref(ref)
#     instance = cls.__new__(cls)
#     instance.__setstate__(state)
#     return instance
# 
# Path: src/apscheduler/validators.py
# def as_timedelta(value: timedelta | float) -> timedelta:
#     if isinstance(value, (int, float)):
#         return timedelta(seconds=value)
#     elif isinstance(value, timedelta):
#         return value
# 
#     # raise TypeError(f'{attribute.name} must be a timedelta or number of seconds, got '
#     #                 f'{value.__class__.__name__} instead')
# 
# def require_state_version(trigger: Trigger, state: dict[str, Any], max_version: int) -> None:
#     try:
#         if state['version'] > max_version:
#             raise DeserializationError(
#                 f'{trigger.__class__.__name__} received a serialized state with version '
#                 f'{state["version"]}, but it only supports up to version {max_version}. '
#                 f'This can happen when an older version of APScheduler is being used with a data '
#                 f'store that was previously used with a newer APScheduler version.'
#             )
#     except KeyError as exc:
#         raise DeserializationError('Missing "version" key in the serialized state') from exc


from abc import abstractmethod
from datetime import datetime, timedelta
from typing import Any
from ..abc import Trigger
from ..exceptions import MaxIterationsReached
from ..marshalling import marshal_object, unmarshal_object
from ..validators import as_timedelta, require_state_version
import attrs
            'triggers': [marshal_object(trigger) for trigger in self.triggers],
            'next_fire_times': self._next_fire_times
        }

    @abstractmethod
    def __setstate__(self, state: dict[str, Any]) -> None:
        self.triggers = [unmarshal_object(*trigger_state) for trigger_state in state['triggers']]
        self._next_fire_times = state['next_fire_times']


@attrs.define
class AndTrigger(BaseCombiningTrigger):
    """
    Fires on times produced by the enclosed triggers whenever the fire times are within the given
    threshold.

    If the produced fire times are not within the given threshold of each other, the trigger(s)
    that produced the earliest fire time will be asked for their next fire time and the iteration
    is restarted. If instead all of the triggers agree on a fire time, all the triggers are asked
    for their next fire times and the earliest of the previously produced fire times will be
    returned.

    This trigger will be finished when any of the enclosed trigger has finished.

    :param triggers: triggers to combine
    :param threshold: maximum time difference between the next fire times of the triggers in order
        for the earliest of them to be returned from :meth:`next` (in seconds, or as timedelta)
    :param max_iterations: maximum number of iterations of fire time calculations before giving up
    """


# Path: src/apscheduler/abc.py
# class Trigger(Iterator[datetime], metaclass=ABCMeta):
#     """Abstract base class that defines the interface that every trigger must implement."""
# 
#     __slots__ = ()
# 
#     @abstractmethod
#     def next(self) -> datetime | None:
#         """
#         Return the next datetime to fire on.
# 
#         If no such datetime can be calculated, ``None`` is returned.
#         :raises apscheduler.exceptions.MaxIterationsReached:
#         """
# 
#     @abstractmethod
#     def __getstate__(self):
#         """Return the (JSON compatible) serializable state of the trigger."""
# 
#     @abstractmethod
#     def __setstate__(self, state):
#         """Initialize an empty instance from an existing state."""
# 
#     def __iter__(self):
#         return self
# 
#     def __next__(self) -> datetime:
#         dateval = self.next()
#         if dateval is None:
#             raise StopIteration
#         else:
#             return dateval
# 
# Path: src/apscheduler/exceptions.py
# class MaxIterationsReached(Exception):
#     """
#     Raised when a trigger has reached its maximum number of allowed computation iterations when
#     trying to calculate the next fire time.
#     """
# 
# Path: src/apscheduler/marshalling.py
# def marshal_object(obj) -> tuple[str, Any]:
#     return f'{obj.__class__.__module__}:{obj.__class__.__qualname__}', obj.__getstate__()
# 
# def unmarshal_object(ref: str, state):
#     cls = callable_from_ref(ref)
#     instance = cls.__new__(cls)
#     instance.__setstate__(state)
#     return instance
# 
# Path: src/apscheduler/validators.py
# def as_timedelta(value: timedelta | float) -> timedelta:
#     if isinstance(value, (int, float)):
#         return timedelta(seconds=value)
#     elif isinstance(value, timedelta):
#         return value
# 
#     # raise TypeError(f'{attribute.name} must be a timedelta or number of seconds, got '
#     #                 f'{value.__class__.__name__} instead')
# 
# def require_state_version(trigger: Trigger, state: dict[str, Any], max_version: int) -> None:
#     try:
#         if state['version'] > max_version:
#             raise DeserializationError(
#                 f'{trigger.__class__.__name__} received a serialized state with version '
#                 f'{state["version"]}, but it only supports up to version {max_version}. '
#                 f'This can happen when an older version of APScheduler is being used with a data '
#                 f'store that was previously used with a newer APScheduler version.'
#             )
#     except KeyError as exc:
#         raise DeserializationError('Missing "version" key in the serialized state') from exc


# Path: src/apscheduler/triggers/combining.py
from abc import abstractmethod
from datetime import datetime, timedelta
from typing import Any
from ..abc import Trigger
from ..exceptions import MaxIterationsReached
from ..marshalling import marshal_object, unmarshal_object
from ..validators import as_timedelta, require_state_version
import attrs

            'triggers': [marshal_object(trigger) for trigger in self.triggers],
            'next_fire_times': self._next_fire_times
        }

    @abstractmethod
    def __setstate__(self, state: dict[str, Any]) -> None:
        self.triggers = [unmarshal_object(*trigger_state) for trigger_state in state['triggers']]
        self._next_fire_times = state['next_fire_times']


@attrs.define
class AndTrigger(BaseCombiningTrigger):
    """
    Fires on times produced by the enclosed triggers whenever the fire times are within the given
    threshold.

    If the produced fire times are not within the given threshold of each other, the trigger(s)
    that produced the earliest fire time will be asked for their next fire time and the iteration
    is restarted. If instead all of the triggers agree on a fire time, all the triggers are asked
    for their next fire times and the earliest of the previously produced fire times will be
    returned.

    This trigger will be finished when any of the enclosed trigger has finished.

    :param triggers: triggers to combine
    :param threshold: maximum time difference between the next fire times of the triggers in order
        for the earliest of them to be returned from :meth:`next` (in seconds, or as timedelta)
    :param max_iterations: maximum number of iterations of fire time calculations before giving up
    """


    threshold: timedelta = attrs.field(converter=as_timedelta, default=1)