# Path: asciinema/asciicast/events.py
# def to_relative_time(
#     events: Generator[List[Any], None, None]
# ) -> Generator[List[Any], None, None]:
# def to_absolute_time(
#     events: Generator[List[Any], None, None]
# ) -> Generator[List[Any], None, None]:
# def cap_relative_time(
#     events: Generator[List[Any], None, None], time_limit: Optional[float]
# ) -> Generator[List[Any], None, None]:
# def adjust_speed(
#     events: Generator[List[Any], None, None], speed: Any
# ) -> Generator[List[Any], None, None]:
# 
# Path: asciinema/asciicast/v1.py
# class Asciicast:
#     def __init__(self, attrs: Dict[str, Any]) -> None:
#         self.version: int = 1
#         self.__attrs = attrs
#         self.idle_time_limit = None  # v1 doesn't store it
# 
#     @property
#     def v2_header(self) -> Dict[str, Any]:
#         keys = ["width", "height", "duration", "command", "title", "env"]
#         header = {
#             k: v
#             for k, v in self.__attrs.items()
#             if k in keys and v is not None
#         }
#         return header
# 
#     def __stdout_events(self) -> Generator[List[Any], None, None]:
#         for time, data in self.__attrs["stdout"]:
#             yield [time, "o", data]
# 
#     def events(self) -> Any:
#         return self.stdout_events()
# 
#     def stdout_events(self) -> Generator[List[Any], None, None]:
#         return to_absolute_time(self.__stdout_events())
# 
# Path: asciinema/asciicast/v2.py
# class Asciicast:
#     def __init__(
#         self, f: Union[TextIO, StreamReader], header: Dict[str, Any]
#     ) -> None:
#         self.version: int = 2
#         self.__file = f
#         self.v2_header = header
#         self.idle_time_limit = header.get("idle_time_limit")
# 
#     def events(self) -> Generator[Any, None, None]:
#         for line in self.__file:
#             yield json.loads(line)
# 
#     def stdout_events(self) -> Generator[List[Any], None, None]:
#         for time, type_, data in self.events():
#             if type_ == "o":
#                 yield [time, type_, data]
# 
# Path: asciinema/term.py
# class raw:
#     def __init__(self, fd: Union[IO[str], int]) -> None:
#         self.fd = fd
#         self.restore: bool = False
#         self.mode: Optional[List[Any]] = None
# 
#     def __enter__(self) -> None:
#         try:
#             self.mode = tty.tcgetattr(self.fd)
#             setraw(self.fd)
#             self.restore = True
#         except tty.error:  # this is `termios.error`
#             pass
# 
#     def __exit__(self, type_: str, value: str, traceback: str) -> None:
#         if self.restore:
#             sleep(0.01)  # give the terminal time to send answerbacks
#             assert isinstance(self.mode, list)
#             tty.tcsetattr(self.fd, tty.TCSAFLUSH, self.mode)
# 
# def read_blocking(fd: int, timeout: Any) -> bytes:
#     if fd in select.select([fd], [], [], timeout)[0]:
#         return os.read(fd, 1024)
# 
#     return b""


import sys
import time
from typing import Any, Dict, Optional, TextIO, Union
from .asciicast import events as ev
from .asciicast.v1 import Asciicast as v1
from .asciicast.v2 import Asciicast as v2
from .term import raw, read_blocking

        base_time = time.time()
        ctrl_c = False
        paused = False
        pause_time: Optional[float] = None

        for t, _type, text in stdout:
            delay = t - (time.time() - base_time)

            while stdin and not ctrl_c and delay > 0:
                if paused:
                    while True:
                        data = read_blocking(stdin.fileno(), 1000)

                        if 0x03 in data:  # ctrl-c
                            ctrl_c = True
                            break

                        if data == pause_key:
                            paused = False
                            assert pause_time is not None
                            base_time += time.time() - pause_time
                            break

                        if data == step_key:
                            delay = 0
                            pause_time = time.time()
                            base_time = pause_time - t
                            break
                else:

# Path: asciinema/asciicast/events.py
# def to_relative_time(
#     events: Generator[List[Any], None, None]
# ) -> Generator[List[Any], None, None]:
# def to_absolute_time(
#     events: Generator[List[Any], None, None]
# ) -> Generator[List[Any], None, None]:
# def cap_relative_time(
#     events: Generator[List[Any], None, None], time_limit: Optional[float]
# ) -> Generator[List[Any], None, None]:
# def adjust_speed(
#     events: Generator[List[Any], None, None], speed: Any
# ) -> Generator[List[Any], None, None]:
# 
# Path: asciinema/asciicast/v1.py
# class Asciicast:
#     def __init__(self, attrs: Dict[str, Any]) -> None:
#         self.version: int = 1
#         self.__attrs = attrs
#         self.idle_time_limit = None  # v1 doesn't store it
# 
#     @property
#     def v2_header(self) -> Dict[str, Any]:
#         keys = ["width", "height", "duration", "command", "title", "env"]
#         header = {
#             k: v
#             for k, v in self.__attrs.items()
#             if k in keys and v is not None
#         }
#         return header
# 
#     def __stdout_events(self) -> Generator[List[Any], None, None]:
#         for time, data in self.__attrs["stdout"]:
#             yield [time, "o", data]
# 
#     def events(self) -> Any:
#         return self.stdout_events()
# 
#     def stdout_events(self) -> Generator[List[Any], None, None]:
#         return to_absolute_time(self.__stdout_events())
# 
# Path: asciinema/asciicast/v2.py
# class Asciicast:
#     def __init__(
#         self, f: Union[TextIO, StreamReader], header: Dict[str, Any]
#     ) -> None:
#         self.version: int = 2
#         self.__file = f
#         self.v2_header = header
#         self.idle_time_limit = header.get("idle_time_limit")
# 
#     def events(self) -> Generator[Any, None, None]:
#         for line in self.__file:
#             yield json.loads(line)
# 
#     def stdout_events(self) -> Generator[List[Any], None, None]:
#         for time, type_, data in self.events():
#             if type_ == "o":
#                 yield [time, type_, data]
# 
# Path: asciinema/term.py
# class raw:
#     def __init__(self, fd: Union[IO[str], int]) -> None:
#         self.fd = fd
#         self.restore: bool = False
#         self.mode: Optional[List[Any]] = None
# 
#     def __enter__(self) -> None:
#         try:
#             self.mode = tty.tcgetattr(self.fd)
#             setraw(self.fd)
#             self.restore = True
#         except tty.error:  # this is `termios.error`
#             pass
# 
#     def __exit__(self, type_: str, value: str, traceback: str) -> None:
#         if self.restore:
#             sleep(0.01)  # give the terminal time to send answerbacks
#             assert isinstance(self.mode, list)
#             tty.tcsetattr(self.fd, tty.TCSAFLUSH, self.mode)
# 
# def read_blocking(fd: int, timeout: Any) -> bytes:
#     if fd in select.select([fd], [], [], timeout)[0]:
#         return os.read(fd, 1024)
# 
#     return b""


# Path: asciinema/player.py
import sys
import time
from typing import Any, Dict, Optional, TextIO, Union
from .asciicast import events as ev
from .asciicast.v1 import Asciicast as v1
from .asciicast.v2 import Asciicast as v2
from .term import raw, read_blocking


        base_time = time.time()
        ctrl_c = False
        paused = False
        pause_time: Optional[float] = None

        for t, _type, text in stdout:
            delay = t - (time.time() - base_time)

            while stdin and not ctrl_c and delay > 0:
                if paused:
                    while True:
                        data = read_blocking(stdin.fileno(), 1000)

                        if 0x03 in data:  # ctrl-c
                            ctrl_c = True
                            break

                        if data == pause_key:
                            paused = False
                            assert pause_time is not None
                            base_time += time.time() - pause_time
                            break

                        if data == step_key:
                            delay = 0
                            pause_time = time.time()
                            base_time = pause_time - t
                            break
                else:

                    data = read_blocking(stdin.fileno(), delay)