function remapScopeNames(mode, regexes, { key }) {
    let offset = 0;
    const scopeNames = mode[key];
    /** @type Record<number,boolean> */
    const emit = {};
    /** @type Record<number,string> */
    const positions = {};

    for (let i = 1; i <= regexes.length; i++) {
      positions[i + offset] = scopeNames[i];
      emit[i + offset] = true;
      offset += countMatchGroups(regexes[i - 1]);
    }
    // we use _emit to keep track of which match groups are "top-level" to avoid double
    // output from inside match groups
    mode[key] = positions;
    mode[key]._emit = emit;
    mode[key]._multi = true;
  }
Renumbers labeled scope names to account for additional inner match
groups that otherwise would break everything.

Lets say we 3 match scopes:

  { 1 => ..., 2 => ..., 3 => ... }

So what we need is a clean match like this:

  (a)(b)(c) => [ "a", "b", "c" ]

But this falls apart with inner match groups:

(a)(((b)))(c) => ["a", "b", "b", "b", "c" ]

Our scopes are now "out of alignment" and we're repeating `b` 3 times.
What needs to happen is the numbers are remapped:

  { 1 => ..., 2 => ..., 5 => ... }

We also need to know that the ONLY groups that should be output
are 1, 2, and 5.  This function handles this behavior.

@param {CompiledMode} mode
@param {Array<RegExp | string>} regexes
@param {{key: "beginScope"|"endScope"}} opts