components/InteractiveGlobe/countryColors.jsjavascript
import { countryMetaByCca3, countriesByContinent } from "./countryMeta";

/**
 * Resolves value-partnership-globe-countries.json's continent-keyed and
 * per-country config into the ccn3-keyed color map InteractiveGlobe's
 * polygon layer needs. `continents` is applied first (colors every country
 * in that continent), then `countries` (pre-populated with every ISO
 * country, `{cca3, name, state}` - only `cca3`/`state` are read here, `name`
 * is an editor-facing label) on top as per-country overrides - so e.g.
 * continents.Europe="highlight" plus a DEU entry with state "hide"
 * highlights all of Europe except Germany.
 *
 * "normal" entries are treated as "no explicit choice" and skipped in both
 * loops rather than written into the map - `countries` is pre-populated with
 * all ~250 countries at "normal" by default (so an editor only has to change
 * the ones they care about), and since "normal" is also the ultimate
 * fallback color (`defaultCountryColor`), those untouched entries would
 * otherwise silently overwrite a continent-level highlight/hide for every
 * country in it.
 *
 * Shared between the 3D globe (GlobePage.jsx) and the print map
 * (PrintMap.jsx) so both render the exact same country colors from the same
 * content.
 *
 * @param {Object} [countryDisplay] - `content.valuePartnership.countryDisplay`.
 * @param {string} fallbackColor - Used as `defaultCountryColor` when
 *   `countryDisplay.colors.normal` isn't set (config-schema.js's
 *   `globeFallbackCountryColor`).
 * @returns {{defaultCountryColor: string, countryColorByCcn3: Map<string,string>}}
 */
export function resolveCountryColors(countryDisplay, fallbackColor) {
  const defaultCountryColor = countryDisplay?.colors?.normal ?? fallbackColor;
  const countryColorByCcn3 = new Map();
  if (!countryDisplay) return { defaultCountryColor, countryColorByCcn3 };

  const { colors } = countryDisplay;

  for (const [continent, state] of Object.entries(countryDisplay.continents ?? {})) {
    if (state === "normal") continue;
    const color = colors?.[state];
    if (!color) continue;
    for (const meta of countriesByContinent(continent)) countryColorByCcn3.set(meta.ccn3, color);
  }

  for (const { cca3, state } of countryDisplay.countries ?? []) {
    if (state === "normal") continue;
    const color = colors?.[state];
    const meta = countryMetaByCca3(cca3);
    if (color && meta) countryColorByCcn3.set(meta.ccn3, color);
  }

  // sub-national areas (currently just Alaska) that don't have an ISO
  // country code and so can't go through the `countries` loop above - see
  // ALASKA_REGION_ID.
  for (const { id, state } of countryDisplay.regions ?? []) {
    if (state === "normal") continue;
    const color = colors?.[state];
    if (color) countryColorByCcn3.set(id, color);
  }

  return { defaultCountryColor, countryColorByCcn3 };
}