code: def _get_feature_times(
      target_series: Optional[TimeSeries] = None,
      past_covariates: Optional[TimeSeries] = None,
      future_covariates: Optional[TimeSeries] = None,
      lags: Optional[Union[Sequence[int], Dict[str, List[int]]]] = None,
      lags_past_covariates: Optional[
          Union[Sequence[int], Dict[str, List[int]]]
      ] = None,
      lags_future_covariates: Optional[
          Union[Sequence[int], Dict[str, List[int]]]
      ] = None,
      output_chunk_length: int = 1,
      is_training: bool = True,
      return_min_and_max_lags: bool = False,
      check_inputs: bool = True,
  ) -> Union[FeatureTimes, Tuple[FeatureTimes, MinLags, MaxLags]]:
      """
      Returns a tuple containing the times in `target_series`, the times in `past_covariates`, and the times in
      `future_covariates` that *could* be used to create features. The returned tuple of times can then be passed
      to `get_shared_times` to compute the 'eligible time points' shared by all of the specified series.
  
      Notes
      -----
      For the purposes of extracting feature times from each series, we define the `min_lag` and `max_lag` of
      each series to be:
              `min_lag = -max(lags_*)`,
              `max_lag = -min(lags_*)`
      where `lags_*` denotes either `lags`, `lags_past_covariates`, or `lags_future_covariates`.
  
      For both `lags` and `lags_past_covariates`, `min_lag` and `max_lag` are guaranteed to be positive values,
      since the values in `lags` and `lags_past_covariates` must all be negative. For these two series then,
      `min_lag` and `max_lag` represent the smallest and largest magnitude lags requested by the user. For example:
              `lags = [-3, -2, -1] -> min_lag = 1, max_lag = 3`
  
      The values contained in `lags_future_covariates`, on the other hand, can be negative, zero, or positive; this
      means that there are three cases to consider:
          1. Both `min_lag` and `max_lag` are positive, which means that all the values in `lags_future_covariates`
          are negative. In this case, `min_lag` and `max_lag` correspond to the to the smallest and largest
          lag magnitudes respectively. For example:
                  `lags_future_covariates = [-3, -2, -1] -> min_lag = 1, max_lag = 3`
          2. `min_lag` is non-positive (i.e. zero or negative), but `max_lag` is positive, which means that
          `lags_future_covariates` contains both negative and non-negative (i.e. zero or positive) lag values.
          In this case, `abs(min_lag)` corresponds to the magnitude of the largest *non-negative* lag value in
          `lags_future_covariates`, whilst `max_lag` corresponds to the largest *negative* lag value in
          `lags_future_covariates`. For example:
                  `lags_future_covariates = [-2, -1, 0, 1, 3] -> min_lag = -3, max_lag = 2`
          3. Both `min_lag` and `max_lag` are non-positive, which means that `lags_future_covariates` contains
          only non-negative lag values. In this case, `abs(min_lag)` and `abs(max_lag)`, rather confusingly,
          correspond to the largest and smallest lag magnitudes respectively. For example:
                  `lags_future_covariates = [1, 2, 3] -> min_lag = -3, max_lag = -1`
      In all three cases, we have `min_lag <= max_lag`. As a direct consequence:
          1. `min_lag > 0` is a sufficient condition for `min_lag` and `max_lag` both being positive (i.e. Case 1).
          2. `max_lag <= 0` is a sufficient condition for `min_lag` and `max_lag` both being non-positive (i.e. Case 2).
  
      To extract feature times from a `target_series` when `is_training = True`, the following steps are performed:
          1. The first `max_lag` times of the series are excluded; these times have too few preceeding values to
          construct features from.
          2. The last `output_chunk_length - 1` times are excluded; these times have too few succeeding times
          to construct labels from.
  
      To extract feature times from a `target_series` when `is_training = False`, the following steps are performed:
          1. An additional `min_lag` times are appended to the end of the series; although these times are not contained
          in the original series, we're able to construct features for them since we only need the values of the series
          from time `t - max_lag` to `t - min_lag` to construct a feature for time `t`.
          2. The first `max_lag` times of the series are then excluded; these times have too few preceeding values to
          construct features from.
      The exact same procedure is performed to extract the feature times from a `past_covariates` series.
  
      To extract feature times from `future_covariates`, we perform the following steps:
          1. Depending on the signs of `min_lag` and `max_lag`, additional times are either prepended or appended
          to the original series. More specifically:
              a) If `min_lag` and `max_lag` are both positive (i.e. `min_lag > 0`), then an additional `min_lag` times
              are appended to the end of the series; as previously mentioned, we only need values up to time `t - min_lag`
              to construct a feature for time `t`.
              b) If `min_lag` and `max_lag` are both non-positive (i.e. `max_lag < 0`), then an additional `abs(max_lag)`
              times are prepended to the start of the series; this is because we only need to know the values of the
              series *after* time `t + abs(max_lag)` to construct a feature for time `t` when we're only extracting
              positive lags from `future_covariates`.
              c) If `min_lag` is non-positive and `max_lag` is positive, then *no additional times* are added to the
              series, since constructing a feature for time `t` requires knowing values from time `t - max_lag` to
              time `t + abs(min_lag)`; in other words, we need to have access to time `t` itself.
          2. If `min_lag < 0`, the last `abs(min_lag)` times are excluded, since these values have fewer
          than `abs(min_lag)` values after them, which means we're unable to construct features for these times.
          3. If `max_lag > 0`, the first `max_lag` times are excluded, since these values have fewer than `max_lag` values
          before them, which means we're unable to construct features for these times.
  
      Some additional behaviours to note about the `_get_feature_times` function are:
          1. If `return_min_and_max_lags = True`, the smallest and largest lag value for each
          series is also returned as a pair of tuples.
          2. For those series which are either unspecified, a `None` value takes the place of
          that series' feature time, minimum lag values, and maximum lag value.
          3. If `is_training = True`, then `target_series` and `output_chunk_length` must
          be provided.
  
      Parameters
      ----------
      target_series
          Optionally, the series for the regression model to predict.
      past_covariates
          Optionally, the past covariates series that the regression model will use as inputs. Unlike the
          `target_series`, `past_covariates` are *not* to be predicted by the regression model.
      future_covariates
          Optionally, the future covariates (i.e. exogenous covariates) series that the regression model will
          use as inputs.
      lags
          Optionally, the lags of the target series to be used as (auto-regressive) features. If not specified,
          auto-regressive features will *not* be added to `X`.
      lags_past_covariates
          Optionally, the lags of `past_covariates` to be used as features.
      lags_future_covariates
          Optionally, the lags of `future_covariates` to be used as features.
      output_chunk_length
          Optionally, the number of timesteps ahead into the future the regression model is to predict. This is ignored
          if `is_training = False`.
      is_training
          Optionally, specifies that training data is to be generated from the specified series. If `True`,
          `target_series`, `output_chunk_length`, and `multi_models` must all be specified.
      check_inputs
          Optionally, specifies that the `lags_*` and `series_*` inputs should be checked for validity. Should be set
          to `False` if inputs have already been checked for validity (e.g. inside the `__init__` of a class), otherwise
          should be set to `True`.
      return_min_and_max_lags
          Optionally, specifies whether the largest magnitude lag value for each series should also be returned along with
          the 'eligible' feature times
  
      Note: if the lags are provided as a dictionary for the target series or any of the covariates series, the
      component-specific lags are grouped into a single list to compute the corresponding feature time.
  
      Returns
      -------
      feature_times
          A tuple containing all the 'eligible feature times' in `target_series`, in `past_covariates`, and in
          `future_covariates`, in that order. If a particular series-lag pair isn't fully specified, then a `None`
          will take the place of that series' eligible times.
      min_lags
          Optionally, a tuple containing the smallest lag value in `lags`, `lags_past_covariates`, and
          `lags_future_covariates`, in that order. If a particular series-lag pair isn't fully specified, then a `None`
          will take the place of that series' minimum lag values.
      max_lags
          Optionally, a tuple containing the largest lag value in `lags`, `lags_past_covariates`, and
          `lags_future_covariates`, in that order. If a particular series-lag pair isn't fully specified, then a `None`
          will take the place of that series' maximum lag values.
  
      Raises
      ------
      ValueError
          If `target_series` and `output_chunk_length` are not both specified if `is_training = True`.
      ValueError
          If any of the `lags` inputs contain non-negative values or if none of the `lags` inputs have been specified.
      ValueError
          If any of the series are too short for the requested `lags` and/or `output_chunk_length` values.
      UserWarning
          If a `lags_*` input is specified without the accompanying time series or vice versa. The only expection to this
          is when `lags` isn't specified alongside `target_series` when `is_training = True`, since one may wish to fit
          a regression model without using auto-regressive features.
  
      """
      raise_if(
          is_training and (target_series is None),
          "Must specify `target_series` when `is_training = True`.",
      )
      if check_inputs:
          raise_if(
              not isinstance(output_chunk_length, int)
              or output_chunk_length < 1,
              "`output_chunk_length` must be a positive `int`.",
          )
          _check_lags(
              lags, lags_past_covariates, lags_future_covariates
          )
      feature_times, min_lags, max_lags = [], [], []
      for name_i, series_i, lags_i in zip(
          ["target_series", "past_covariates", "future_covariates"],
          [target_series, past_covariates, future_covariates],
          [lags, lags_past_covariates, lags_future_covariates],
      ):
          # union of the component-specific lags, unsorted
          if isinstance(lags_i, dict):
              lags_i = list(set(chain(*lags_i.values())))
  
          if check_inputs and (series_i is not None):
              _check_series_length(
                  series_i,
                  lags_i,
                  output_chunk_length,
                  is_training,
                  name_i,
              )
          series_specified = series_i is not None
          lags_specified = lags_i is not None
          is_label_series = is_training and name_i == "target_series"
          times_i = series_i.time_index if series_specified else None
          max_lag_i = -min(lags_i) if lags_specified else None
          min_lag_i = -max(lags_i) if lags_specified else None
          if is_label_series:
              # Exclude last `output_chunk_length - 1` times:
              end_idx = (
                  -output_chunk_length + 1
                  if output_chunk_length > 1
                  else None
              )
              times_i = times_i[:end_idx]
          elif series_specified and lags_specified:
              # Prepend times to start of series - see Step 1a for extracting
              # feature times from `future_covariates` in `Notes`:
              new_start = (
                  times_i[0] + series_i.freq * max_lag_i
                  if max_lag_i < 0
                  else None
              )
              # Append times to end of series - see Step 1b for extracting features
              # times from `future_covariates`, or Step 1 for extracting features
              # from `target_series`/`past_covariates` in `Notes`:
              new_end = (
                  times_i[-1] + series_i.freq * min_lag_i
                  if min_lag_i > 0
                  else None
              )
              times_i = _extend_time_index(
                  times_i,
                  series_i.freq,
                  new_start=new_start,
                  new_end=new_end,
              )
          if series_specified and lags_specified:
              # Exclude last `abs(min_lag)` times - see Step 2 for extracting feature
              # times from `future_covariates` in `Notes`:
              if min_lag_i < 0:
                  times_i = times_i[:min_lag_i]
              # Exclude first `max_lag` times - see Step 3 for extracting feature times
              # from `future_covariates`, or Step 2 in extracting feature times from
              # `target_series`/`past_covariates` in `Notes`:
              if max_lag_i > 0:
                  times_i = times_i[max_lag_i:]
          elif (not is_label_series) and (
              series_specified ^ lags_specified
          ):
              # Warn user that series/lags input will be ignored:
              times_i = max_lag_i = None
              lags_name = (
                  "lags"
                  if name_i == "target_series"
                  else f"lags_{name_i}"
              )
              specified = lags_name if lags_specified else name_i
              unspecified = name_i if lags_specified else lags_name
              warnings.warn(
                  f"`{specified}` was specified without accompanying `{unspecified}` and, thus, will be ignored."
              )
          feature_times.append(times_i)
          # Note `max_lag_i` and `min_lag_i` if requested:
          if series_specified and lags_specified:
              min_lags.append(min_lag_i)
              max_lags.append(max_lag_i)
          else:
              min_lags.append(None)
              max_lags.append(None)
      return (
          (feature_times, min_lags, max_lags)
          if return_min_and_max_lags
          else feature_times
      )
  
imports: import warnings
  from functools import reduce
  from math import inf
  from typing import Dict, List, Optional, Sequence, Tuple, Union
  from itertools import chain
  import numpy
  import pandas
  from numpy.lib.stride_tricks import as_strided
  from darts.logging import get_logger, raise_if, raise_if_not, raise_log
  from darts.timeseries import TimeSeries
  from darts.utils.utils import get_single_series, series2seq
label_desc: Use image node_id 9 for calling a global function with example usage: _get_feature_times(target_series, past_covariates, future_covariates, lags, lags_past_covariates, lags_future_covariates, output_chunk_length, is_training, return_min_and_max_lags, check_inputs) and returns: unknown