function parse(input, baseURL) {
  if (!isJSONObject(input)) {
    throw new TypeError('Import map JSON must be an object.');
  }

  if (!(baseURL instanceof URL)) {
    throw new TypeError('Missing base URL or base URL is not a URL');
  }

  let sortedAndNormalizedImports = /** @type {ParsedSpecifierMap} */ ({});
  if ('imports' in input) {
    if (!input.imports || !isJSONObject(input.imports)) {
      throw new TypeError("Import map's imports value must be an object.");
    }
    sortedAndNormalizedImports = sortAndNormalizeSpecifierMap(input.imports, baseURL);
  }

  let sortedAndNormalizedScopes = /** @type {ParsedScopesMap} */ ({});
  if ('scopes' in input) {
    if (!input.scopes || !isJSONObject(input.scopes)) {
      throw new TypeError("Import map's scopes value must be an object.");
    }
    sortedAndNormalizedScopes = sortAndNormalizeScopes(input.scopes, baseURL);
  }

  const badTopLevelKeys = new Set(Object.keys(input));
  badTopLevelKeys.delete('imports');
  badTopLevelKeys.delete('scopes');

  for (const badKey of badTopLevelKeys) {
    console.warn(`Invalid top-level key "${badKey}". Only "imports" and "scopes" can be present.`);
  }

  // Always have these two keys, and exactly these two keys, in the result.
  return {
    imports: sortedAndNormalizedImports,
    scopes: sortedAndNormalizedScopes,
  };
}
@param {ImportMap} input
@param {URL} baseURL
@returns {ParsedImportMap}