function calculateFallbackChain(sLocale, aSupportedLocales, sFallbackLocale, sContextInfo, bSkipFallbackLocaleAndRaw) {
		// Defines which locales are supported (BCP47 language tags or JDK locale format using underscores).
		// Normalization of the case and of the separator char simplifies later comparison, but the language
		// part is not converted to a legacy ISO639 code, in order to enable the support of modern codes as well.
		aSupportedLocales = aSupportedLocales && aSupportedLocales.map(function (sSupportedLocale) {
			return normalizePreserveEmpty(sSupportedLocale, true);
		});
		if (!bSkipFallbackLocaleAndRaw) {
			// normalize the fallback locale for sanitizing it and converting the language part to legacy ISO639
			// because it is like the locale part of the fallback chain
			var bFallbackLocaleDefined = sFallbackLocale !== undefined;
			sFallbackLocale = bFallbackLocaleDefined ? sFallbackLocale : sDefaultFallbackLocale;
			sFallbackLocale = normalizePreserveEmpty(sFallbackLocale);

			// An empty fallback locale ("") is valid and means that a generic fallback should not be loaded.
			// The supportedLocales must contain the fallbackLocale, or else it will be ignored.
			if (sFallbackLocale !== "" && !findSupportedLocale(sFallbackLocale, aSupportedLocales)) {
				var sMessage = "The fallback locale '" + sFallbackLocale + "' is not contained in the list of supported locales ['"
					+ aSupportedLocales.join("', '") + "']" + sContextInfo + " and will be ignored.";
				// configuration error should be thrown if an invalid configuration has been provided
				if (bFallbackLocaleDefined) {
					throw new Error(sMessage);
				}
				Log.error(sMessage);
			}
		}

		// Calculate the list of fallback locales, starting with the given locale.
		//
		// Note: always keep this in sync with the fallback mechanism in Java, ABAP (MIME & BSP)
		// resource handler (Java: Peter M., MIME: Sebastian A., BSP: Silke A.)


		// fallback logic:
		// locale with region -> locale language -> fallback with region -> fallback language -> raw
		// note: if no region is present, it is skipped

		// Sample fallback chains:
		//  "de_CH" -> "de" -> "en_US" -> "en" -> ""  // locale 'de_CH', fallbackLocale 'en_US'
		//  "de_CH" -> "de" -> "de_DE" -> "de" -> ""  // locale 'de_CH', fallbackLocale 'de_DE'
		//  "en_GB" -> "en"                    -> ""  // locale 'en_GB', fallbackLocale 'en'

		// note: the resulting list does neither contain any duplicates nor unsupported locales

		// fallback calculation
		var aLocales = [],
			sSupportedLocale;

		while ( sLocale != null ) {

			// check whether sLocale is supported, potentially using an alternative language code
			sSupportedLocale = findSupportedLocale(sLocale, aSupportedLocales);

			// only push if it is supported and is not already contained (avoid duplicates)
			if ( sSupportedLocale !== undefined && aLocales.indexOf(sSupportedLocale) === -1) {
				aLocales.push(sSupportedLocale);
			}

			// calculate next one
			if (!sLocale) {
				// there is no fallback for the 'raw' locale or for null/undefined
				sLocale = null;
			} else if (sLocale === "zh_HK") {
				// special (legacy) handling for zh_HK:
				// try zh_TW (for "Traditional Chinese") first before falling back to 'zh'
				sLocale = "zh_TW";
			} else if (sLocale.lastIndexOf('_') >= 0) {
				// if sLocale contains more than one segment (region, variant), remove the last one
				sLocale = sLocale.slice(0, sLocale.lastIndexOf('_'));
			} else if (bSkipFallbackLocaleAndRaw) {
				// skip fallbackLocale and raw bundle
				sLocale = null;
			} else if (sFallbackLocale) {
				// if there's a fallbackLocale, add it first before the 'raw' locale
				sLocale = sFallbackLocale;
				sFallbackLocale = null; // no more fallback in the next round
			} else {
				// last fallback to raw bundle
				sLocale = "";
			}
		}

		return aLocales;
	}
/**
	 * Determines the sequence of fallback locales, starting from the given locale.
	 *
	 * The fallback chain starts with the given <code>sLocale</code> itself. If this locale
	 * has multiple segments (region, variant), further entries are added to the fallback
	 * chain, each one omitting the last (rightmost) segment of its predecessor, making the
	 * new locale entry less specific than the previous one (e.g. "de" after "de_CH").
	 *
	 * If <code>sFallbackLocale</code> is given, it will be added to the fallback chain next.
	 * If it consists of multiple segments, multiple locales will be added, each less specific
	 * than the previous one. If <code>sFallbackLocale</code> is omitted or <code>undefined</code>,
	 * "en" (English) will be added instead. If <code>sFallbackLocale</code> is the empty string
	 * (""), no generic fallback will be added.
	 *
	 * Last but not least, the 'raw' locale will be added, represented by the empty string ("").
	 *
	 * The returned list will contain no duplicates and all entries will be in normalized JDK file suffix
	 * format (using an underscore ("_") as separator, a lowercase language and an uppercase region
	 * (if any)).
	 *
	 * If <code>aSupportedLocales</code> is provided and not empty, only locales contained
	 * in that array will be added to the result. This allows to limit the backend requests
	 * to a certain set of files (e.g. those that are known to exist).
	 *
	 * @param {string} sLocale Locale to start the fallback sequence with, must be normalized already
	 * @param {string[]} [aSupportedLocales] List of supported locales (either BCP47 or JDK legacy syntax, e.g. zh_CN, iw)
	 * @param {string} [sFallbackLocale="en"] Last fallback locale; is ignored when <code>bSkipFallbackLocaleAndRaw</code> is <code>true</code>
	 * @param {string} [sContextInfo] Describes the context in which this function is called, only used for logging
	 * @param {boolean} [bSkipFallbackLocaleAndRaw=false] Whether to skip fallbackLocale and raw bundle
	 * @returns {string[]} Sequence of fallback locales in JDK legacy syntax, decreasing priority
	 *
	 * @private
	 */
Determines the sequence of fallback locales, starting from the given locale.
The fallback chain starts with the given sLocale itself. If this locale
has multiple segments (region, variant), further entries are added to the fallback
chain, each one omitting the last (rightmost) segment of its predecessor, making the
new locale entry less specific than the previous one .

If sFallbackLocale is given, it will be added to the fallback chain next.
If it consists of multiple segments, multiple locales will be added, each less specific
than the previous one. If sFallbackLocale is omitted or undefined,
"en" (English) will be added instead. If sFallbackLocale is the empty string
(""), no generic fallback will be added.

Last but not least, the 'raw' locale will be added, represented by the empty string ("").

The returned list will contain no duplicates and all entries will be in normalized JDK file suffix
format (using an underscore ("_") as separator, a lowercase language and an uppercase region
(if any)).

If aSupportedLocales is provided and not empty, only locales contained
in that array will be added to the result. This allows to limit the backend requests
to a certain set of files .

@param {string} sLocale Locale to start the fallback sequence with, must be normalized already
@param {string[]} [aSupportedLocales] List of supported locales (either BCP47 or JDK legacy syntax, e.g. zh_CN, iw)
@param {string} [sFallbackLocale="en"] Last fallback locale; is ignored when bSkipFallbackLocaleAndRaw is true
@param {string} [sContextInfo] Describes the context in which this function is called, only used for logging
@param {boolean} [bSkipFallbackLocaleAndRaw=false] Whether to skip fallbackLocale and raw bundle
@returns {string[]} Sequence of fallback locales in JDK legacy syntax, decreasing priority

@private
Determines the sequence of fallback locales starting from the given locale . The fallback chain starts with the given sLocale itself . If this locale has multiple segments ( region variant ) further entries are added to the fallback chain each one omitting the last ( rightmost ) segment of its predecessor making the new locale entry less specific than the previous one . If sFallbackLocale is given it will be added to the fallback chain next . If it consists of multiple segments multiple locales will be added each less specific than the previous one . If sFallbackLocale is omitted or undefined " en " ( English ) will be added instead . If sFallbackLocale is the empty string ( " " ) no generic fallback will be added . Last but not least the ' raw ' locale will be added represented by the empty string ( " " ) . The returned list will contain no duplicates and all entries will be in normalized JDK file suffix format ( using an underscore ( " _ " ) as separator a lowercase language and an uppercase region ( if any )) . If aSupportedLocales is provided and not empty only locales contained in that array will be added to the result . This allows to limit the backend requests to a certain set of files . @param { string } sLocale Locale to start the fallback sequence with must be normalized already @param { string [] } [ aSupportedLocales ] List of supported locales ( either BCP47 or JDK legacy syntax e . g . zh_CN iw ) @param { string } [ sFallbackLocale = " en " ] Last fallback locale ; is ignored when bSkipFallbackLocaleAndRaw is true @param { string } [ sContextInfo ] Describes the context in which this function is called only used for logging @param { boolean } [ bSkipFallbackLocaleAndRaw = false ] Whether to skip fallbackLocale and raw bundle @returns { string [] } Sequence of fallback locales in JDK legacy syntax decreasing priority @private
function calculateFallbackChain(sLocale, aSupportedLocales, sFallbackLocale, sContextInfo, bSkipFallbackLocaleAndRaw) {
		aSupportedLocales = aSupportedLocales && aSupportedLocales.map(function (sSupportedLocale) {
			return normalizePreserveEmpty(sSupportedLocale, true);
		});
		if (!bSkipFallbackLocaleAndRaw) {
			var bFallbackLocaleDefined = sFallbackLocale !== undefined;
			sFallbackLocale = bFallbackLocaleDefined ? sFallbackLocale : sDefaultFallbackLocale;
			sFallbackLocale = normalizePreserveEmpty(sFallbackLocale);
			if (sFallbackLocale !== "" && !findSupportedLocale(sFallbackLocale, aSupportedLocales)) {
				var sMessage = "The fallback locale '" + sFallbackLocale + "' is not contained in the list of supported locales ['"
					+ aSupportedLocales.join("', '") + "']" + sContextInfo + " and will be ignored.";
				if (bFallbackLocaleDefined) {
					throw new Error(sMessage);
				}
				Log.error(sMessage);
			}
		}
		 Note: always keep this in sync with the fallback mechanism in Java, ABAP (MIME & BSP)
		 resource handler (Java: Peter M., MIME: Sebastian A., BSP: Silke A.)
		 fallback logic:
		 locale with region -> locale language -> fallback with region -> fallback language -> raw
		 note: if no region is present, it is skipped
		 Sample fallback chains:
		  "de_CH" -> "de" -> "en_US" -> "en" -> ""   locale 'de_CH', fallbackLocale 'en_US'
		  "de_CH" -> "de" -> "de_DE" -> "de" -> ""   locale 'de_CH', fallbackLocale 'de_DE'
		  "en_GB" -> "en"                    -> ""   locale 'en_GB', fallbackLocale 'en'
		 note: the resulting list does neither contain any duplicates nor unsupported locales
		 fallback calculation
		var aLocales = [],
			sSupportedLocale;
		while ( sLocale != null ) {
			 check whether sLocale is supported, potentially using an alternative language code
			sSupportedLocale = findSupportedLocale(sLocale, aSupportedLocales);
			 only push if it is supported and is not already contained (avoid duplicates)
			if ( sSupportedLocale !== undefined && aLocales.indexOf(sSupportedLocale) === -1) {
				aLocales.push(sSupportedLocale);
			}
			 calculate next one
			if (!sLocale) {
				 there is no fallback for the 'raw' locale or for null/undefined
				sLocale = null;
			} else if (sLocale === "zh_HK") {
				 special (legacy) handling for zh_HK:
				 try zh_TW (for "Traditional Chinese") first before falling back to 'zh'
				sLocale = "zh_TW";
			} else if (sLocale.lastIndexOf('_') >= 0) {
				 if sLocale contains more than one segment (region, variant), remove the last one
				sLocale = sLocale.slice(0, sLocale.lastIndexOf('_'));
			} else if (bSkipFallbackLocaleAndRaw) {
				 skip fallbackLocale and raw bundle
				sLocale = null;
			} else if (sFallbackLocale) {
				 if there's a fallbackLocale, add it first before the 'raw' locale
				sLocale = sFallbackLocale;
				sFallbackLocale = null;  no more fallback in the next round
			} else {
				 last fallback to raw bundle
				sLocale = "";
			}
		}
		return aLocales;
	}
function calculateFallbackChain ( sLocale , aSupportedLocales , sFallbackLocale , sContextInfo , bSkipFallbackLocaleAndRaw ) { aSupportedLocales = aSupportedLocales && aSupportedLocales . map ( function ( sSupportedLocale ) { return normalizePreserveEmpty ( sSupportedLocale , true ) ; } ) ; if ( ! bSkipFallbackLocaleAndRaw ) { var bFallbackLocaleDefined = sFallbackLocale !== undefined ; sFallbackLocale = bFallbackLocaleDefined ? sFallbackLocale : sDefaultFallbackLocale ; sFallbackLocale = normalizePreserveEmpty ( sFallbackLocale ) ; if ( sFallbackLocale !== "" && ! findSupportedLocale ( sFallbackLocale , aSupportedLocales ) ) { var sMessage = "The fallback locale '" + sFallbackLocale + "' is not contained in the list of supported locales ['" + aSupportedLocales . join ( "', '" ) + "']" + sContextInfo + " and will be ignored." ; if ( bFallbackLocaleDefined ) { throw new Error ( sMessage ) ; } Log . error ( sMessage ) ; } } var aLocales = [ ] , sSupportedLocale ; while ( sLocale != null ) { sSupportedLocale = findSupportedLocale ( sLocale , aSupportedLocales ) ; if ( sSupportedLocale !== undefined && aLocales . indexOf ( sSupportedLocale ) === - 1 ) { aLocales . push ( sSupportedLocale ) ; } if ( ! sLocale ) { sLocale = null ; } else if ( sLocale === "zh_HK" ) { sLocale = "zh_TW" ; } else if ( sLocale . lastIndexOf ( '_' ) >= 0 ) { sLocale = sLocale . slice ( 0 , sLocale . lastIndexOf ( '_' ) ) ; } else if ( bSkipFallbackLocaleAndRaw ) { sLocale = null ; } else if ( sFallbackLocale ) { sLocale = sFallbackLocale ; sFallbackLocale = null ; } else { sLocale = "" ; } } return aLocales ; }
Determines the sequence of fallback locales, starting from the given locale.
Determines the sequence of fallback locales starting from the given locale .
// Defines which locales are supported (BCP47 language tags or JDK locale format using underscores). // Normalization of the case and of the separator char simplifies later comparison, but the language // part is not converted to a legacy ISO639 code, in order to enable the support of modern codes as well. // normalize the fallback locale for sanitizing it and converting the language part to legacy ISO639 // because it is like the locale part of the fallback chain // An empty fallback locale ("") is valid and means that a generic fallback should not be loaded. // The supportedLocales must contain the fallbackLocale, or else it will be ignored. // configuration error should be thrown if an invalid configuration has been provided // Calculate the list of fallback locales, starting with the given locale. // // Note: always keep this in sync with the fallback mechanism in Java, ABAP (MIME & BSP) // resource handler (Java: Peter M., MIME: Sebastian A., BSP: Silke A.) // fallback logic: // locale with region -> locale language -> fallback with region -> fallback language -> raw // note: if no region is present, it is skipped // Sample fallback chains: //  "de_CH" -> "de" -> "en_US" -> "en" -> ""  // locale 'de_CH', fallbackLocale 'en_US' //  "de_CH" -> "de" -> "de_DE" -> "de" -> ""  // locale 'de_CH', fallbackLocale 'de_DE' //  "en_GB" -> "en"                    -> ""  // locale 'en_GB', fallbackLocale 'en' // note: the resulting list does neither contain any duplicates nor unsupported locales // fallback calculation // check whether sLocale is supported, potentially using an alternative language code // only push if it is supported and is not already contained (avoid duplicates) // calculate next one // there is no fallback for the 'raw' locale or for null/undefined // special (legacy) handling for zh_HK: // try zh_TW (for "Traditional Chinese") first before falling back to 'zh' // if sLocale contains more than one segment (region, variant), remove the last one // skip fallbackLocale and raw bundle // if there's a fallbackLocale, add it first before the 'raw' locale // no more fallback in the next round // last fallback to raw bundle