# 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
    def next(self) -> datetime | None:
        if not self._next_fire_times:
            # Fill out the fire times on the first run
            self._next_fire_times = [t.next() for t in self.triggers]

        for _ in range(self.max_iterations):
            # Find the earliest and latest fire times
            earliest_fire_time: datetime | None = None
            latest_fire_time: datetime | None = None
            for fire_time in self._next_fire_times:
                # If any of the fire times is None, this trigger is finished
                if fire_time is None:
                    return None

                if earliest_fire_time is None or earliest_fire_time > fire_time:
                    earliest_fire_time = fire_time

                if latest_fire_time is None or latest_fire_time < fire_time:
                    latest_fire_time = fire_time

            # Replace all the fire times that were within the threshold
            for i, _trigger in enumerate(self.triggers):
                if self._next_fire_times[i] - earliest_fire_time <= self.threshold:
                    self._next_fire_times[i] = self.triggers[i].next()

            # If all the fire times were within the threshold, return the earliest one
            if latest_fire_time - earliest_fire_time <= self.threshold:
                self._next_fire_times = [t.next() for t in self.triggers]
                return earliest_fire_time
        else:

# 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

    def next(self) -> datetime | None:
        if not self._next_fire_times:
            # Fill out the fire times on the first run
            self._next_fire_times = [t.next() for t in self.triggers]

        for _ in range(self.max_iterations):
            # Find the earliest and latest fire times
            earliest_fire_time: datetime | None = None
            latest_fire_time: datetime | None = None
            for fire_time in self._next_fire_times:
                # If any of the fire times is None, this trigger is finished
                if fire_time is None:
                    return None

                if earliest_fire_time is None or earliest_fire_time > fire_time:
                    earliest_fire_time = fire_time

                if latest_fire_time is None or latest_fire_time < fire_time:
                    latest_fire_time = fire_time

            # Replace all the fire times that were within the threshold
            for i, _trigger in enumerate(self.triggers):
                if self._next_fire_times[i] - earliest_fire_time <= self.threshold:
                    self._next_fire_times[i] = self.triggers[i].next()

            # If all the fire times were within the threshold, return the earliest one
            if latest_fire_time - earliest_fire_time <= self.threshold:
                self._next_fire_times = [t.next() for t in self.triggers]
                return earliest_fire_time
        else:

            raise MaxIterationsReached