code: def _map_urls(cfg, urls):
      mapping_specs = _get_url_mappings(cfg)
      if not mapping_specs:
          return urls
  
      mapped = []
      # we process the candidate in order to maintain any prioritization
      # encoded in it (e.g. _get_flexible_source_candidates_for_submodule)
      # if we have a matching mapping replace the URL in its position
      for u in urls:
          # we only permit a single match
          # TODO we likely want to RF this to pick the longest match
          mapping_applied = False
          # try one mapping set at a time
          for mapping_spec in mapping_specs:
              # process all substitution patterns in the specification
              # always operate on strings (could be a Path instance too)
              mu = str(u)
              matched = False
              for match_ex, subst_ex in mapping_spec.items():
                  if not matched:
                      matched = re.match(match_ex, mu) is not None
                  if not matched:
                      break
                  # try to map, would return unchanged, if there is no match
                  mu = re.sub(match_ex, subst_ex, mu)
              if mu != u:
                  lgr.debug("URL substitution: '%s' -> '%s'", u, mu)
                  mapped.append(mu)
                  # we could consider breaking after the for effective mapping
                  # specification. however, that would mean any generic
                  # definition of a broadly matching substitution would derail
                  # the entroe system. moreover, suddently order would matter
                  # substantially
                  mapping_applied = True
          if not mapping_applied:
              # none of the mappings matches, go with the original URL
              # (really original, not the stringified one)
              mapped.append(u)
      return mapped
  
imports: import logging
  import re
  from os.path import expanduser
  from pathlib import Path
  from typing import Dict, List, Tuple
  from urllib.parse import unquote
  from datalad.cmd import CommandError, GitWitlessRunner, StdOutCapture
  from datalad.config import ConfigManager
  from datalad.distributed.ora_remote import LocalIO, RIARemoteError, SSHRemoteIO
  from datalad.distribution.dataset import Dataset
  from datalad.distribution.utils import _get_flexible_source_candidates
  from datalad.dochelpers import single_or_plural
  from datalad.log import log_progress
  from datalad.runner.exception import CommandError
  from datalad.support.annexrepo import AnnexRepo
  from datalad.support.exceptions import CapturedException, DownloadError
  from datalad.support.gitrepo import GitRepo
  from datalad.support.network import RI, SSHRI, URL, DataLadRI, download_url, get_local_file_url, is_url
  from datalad.support.strings import get_replacement_dict
  from datalad.utils import Path, PurePosixPath, ensure_bool, ensure_list, make_tempfile, rmtree
label_desc: Use image node_id 6 for calling a global function with example usage: _map_urls(cfg, urls) and returns: mapped, urls