code: def raw_action_skips(
      replay: sc2_replay.SC2Replay,
  ) -> Mapping[int, List[int]]:
      """Returns player id -> list, the game loops on which each player acted.
  
      Args:
        replay: An sc2_replay.SC2Replay instance.
  
      Note that these skips are specific to the raw interface - further work will
      be needed to support visual.
      """
      action_frames = collections.defaultdict(list)
      last_game_loop = None
      # Extract per-user events of interest.
      for event in replay.game_events():
          event_type = _readable_event_type(event["_event"])
          if event_type not in _EVENT_TYPES_TO_FILTER_OUT:
              game_loop = event["_gameloop"]
              last_game_loop = game_loop
              # As soon as anyone leaves, we stop tracking events.
              if event_type == "GameUserLeave":
                  break
  
              user_id = event["_userid"]["m_userId"]
              player_id = user_id + 1
              if player_id < 1 or player_id > 2:
                  raise ValueError(f"Unexpected player_id: {player_id}")
              if (
                  action_frames[player_id]
                  and action_frames[player_id][-1].game_loop
                  == game_loop
              ):
                  # Later (non-camera) events on the same game loop take priority.
                  if event_type != "CameraUpdate":
                      action_frames[player_id][
                          -1
                      ].event_type = event_type
              else:
                  action_frames[player_id].append(
                      EventData(game_loop, event_type)
                  )
  
      for player_id in action_frames:
          # Filter out repeated camera updates.
          filtered = []
          for v in action_frames[player_id]:
              if (
                  v.event_type == "CameraUpdate"
                  and filtered
                  and filtered[-1].event_type == "CameraUpdate"
              ):
                  filtered[-1].game_loop = v.game_loop
              else:
                  filtered.append(v)
          # If the last update is a camera move, remove it (only camera moves with a
          # raw action following them should be added).
          if filtered and filtered[-1].event_type == "CameraUpdate":
              filtered.pop()
          # Extract game loops.
          action_frames[player_id] = [v.game_loop for v in filtered]
          if not action_frames[player_id] or (
              action_frames[player_id][-1] != last_game_loop
          ):
              action_frames[player_id].append(last_game_loop)
      return action_frames
  
imports: import collections
  import dataclasses
  from typing import List, Mapping
  from pysc2.lib.replay import sc2_replay
label_desc: Use image node_id 2 for calling a global function with example usage: raw_action_skips(replay) and returns: action_frames