code: def _insample_times(
      times: np.ndarray,
      uids: Series,
      indptr: np.ndarray,
      h: int,
      freq: Union[int, str, pd.offsets.BaseOffset],
      step_size: int = 1,
      id_col: str = "unique_id",
      time_col: str = "ds",
  ) -> DataFrame:
      sizes = np.diff(indptr)
      if (sizes < h).any():
          raise ValueError("`sizes` should be greater or equal to `h`.")
      # TODO: we can just truncate here instead of raising an error
      ns, resids = np.divmod(sizes - h, step_size)
      if (resids != 0).any():
          raise ValueError(
              "`sizes - h` should be multiples of `step_size`"
          )
      windows_per_serie = ns + 1
      # determine the offsets for the cutoffs, e.g. 2 means the 3rd training date is a cutoff
      cutoffs_offsets = step_size * np.hstack(
          [np.arange(w) for w in windows_per_serie]
      )
      # start index of each serie, e.g. [0, 17] means the the second serie starts on the 18th entry
      # we repeat each of these as many times as we have windows, e.g. windows_per_serie = [2, 3]
      # would yield [0, 0, 17, 17, 17]
      start_idxs = np.repeat(indptr[:-1], windows_per_serie)
      # determine the actual indices of the cutoffs, we repeat the cutoff for the complete horizon
      # e.g. if we have two series and h=2 this could be [0, 0, 1, 1, 17, 17, 18, 18]
      # which would have the first two training dates from each serie as the cutoffs
      cutoff_idxs = np.repeat(start_idxs + cutoffs_offsets, h)
      cutoffs = times[cutoff_idxs]
      total_windows = windows_per_serie.sum()
      # determine the offsets for the actual dates. this is going to be [0, ..., h] repeated
      ds_offsets = np.tile(np.arange(h), total_windows)
      # determine the actual indices of the times
      # e.g. if we have two series and h=2 this could be [0, 1, 1, 2, 17, 18, 18, 19]
      ds_idxs = cutoff_idxs + ds_offsets
      ds = times[ds_idxs]
      if isinstance(uids, pl_Series):
          df_constructor = pl_DataFrame
      else:
          df_constructor = pd.DataFrame
      out = df_constructor(
          {
              id_col: ufp.repeat(uids, h * windows_per_serie),
              time_col: ds,
              "cutoff": cutoffs,
          }
      )
      # the first cutoff is before the first train date
      actual_cutoffs = ufp.offset_times(out["cutoff"], freq, -1)
      out = ufp.assign_columns(out, "cutoff", actual_cutoffs)
      return out
  
imports: import os
  import pickle
  import warnings
  from copy import deepcopy
  from itertools import chain
  from typing import Any, Dict, List, Optional, Union
  import numpy
  import pandas
  import torch
  import utilsforecast.processing
  from utilsforecast.compat import DataFrame, Series, pl_DataFrame, pl_Series
  from utilsforecast.grouped_array import GroupedArray
  from utilsforecast.target_transforms import BaseTargetTransform, LocalBoxCox, LocalMinMaxScaler, LocalRobustScaler, LocalStandardScaler
  from utilsforecast.validation import validate_freq
  from .tsdataset import TimeSeriesDataset
  from neuralforecast.models import GRU, LSTM, RNN, TCN, DeepAR, DilatedRNN, MLP, NHITS, NBEATS, NBEATSx, TFT, VanillaTransformer, Informer, Autoformer, FEDformer, StemGNN, PatchTST, TimesNet
label_desc: Use image node_id 1 for calling a global function with example usage: _insample_times(times, uids, indptr, h, freq, step_size, id_col, time_col) and returns: out