function requireModule(oRequestingModule, sModuleName, bAsync, bSkipShimDeps) {

		var bLoggable = log.isLoggable(),
			oSplitName = urnToBaseIDAndSubType(sModuleName),
			oShim = mShims[sModuleName],
			oModule, aExtensions, i, sMsg, bExecutedNow;

		// only for robustness, should not be possible by design (all callers append '.js')
		if ( !oSplitName ) {
			throw new Error("can only require Javascript module, not " + sModuleName);
		}

		// Module names should not start with a "/"
		if (sModuleName[0] == "/") {
			log.error("Module names that start with a slash should not be used, as they are reserved for future use.");
		}

		oModule = Module.get(sModuleName);

		// when there's a shim with dependencies for the module
		// resolve them first before requiring the module again with bSkipShimDeps = true
		if ( oShim && oShim.deps && !bSkipShimDeps ) {
			if ( bLoggable ) {
				log.debug("require dependencies of raw module " + sModuleName);
			}
			return requireAll(oModule, oShim.deps, function() {
				return requireModule(oRequestingModule, sModuleName, bAsync, /* bSkipShimDeps = */ true);
			}, function(oErr) {
				oModule.fail(oErr);
				if ( bAsync ) {
					return;
				}
				throw oErr;
			}, bAsync);
		}

		if ( bLoggable ) {
			log.debug(sLogPrefix + "require '" + sModuleName + "' of type '" + oSplitName.subType + "'");
		}

		// check if module has been loaded already
		if ( oModule.state !== INITIAL ) {
			if ( oModule.state === PRELOADED ) {
				oModule.state = LOADED;
				oModule.async = bAsync;
				bExecutedNow = true;
				measure && measure.start(sModuleName, "Require module " + sModuleName + " (preloaded)", ["require"]);
				execModule(sModuleName, bAsync);
				measure && measure.end(sModuleName);
			}

			if ( oModule.state === READY ) {
				if ( bLoggable ) {
					log.debug(sLogPrefix + "module '" + sModuleName + "' has already been loaded (skipped).");
				}
				// Note: this intentionally does not return oModule.promise() as the export might be temporary in case of cycles
				// or it might have changed after repeated module execution
				return bAsync ? Promise.resolve(oModule.value()) : oModule.value();
			} else if ( oModule.state === FAILED ) {
				if ( bAsync ) {
					return oModule.deferred().promise;
				} else {
					throw (bExecutedNow
						? oModule.error
						: makeNestedError("found in negative cache: '" + sModuleName + "' from " + oModule.url, oModule.error));
				}
			} else {
				// currently loading or executing
				if ( bAsync ) {
					// break up cyclic dependencies
					if ( oRequestingModule && oModule.dependsOn(oRequestingModule) ) {
						if ( log.isLoggable() ) {
							log.debug("cycle detected between '" + oRequestingModule.name + "' and '" + sModuleName + "', returning undefined for '" + sModuleName + "'");
						}
						// Note: this must be a separate promise as the fulfillment is not the final one
						return Promise.resolve(undefined);
					}
					return oModule.deferred().promise;
				}
				if ( !bAsync && !oModule.async ) {
					// sync pending, return undefined
					if ( log.isLoggable() ) {
						log.debug("cycle detected between '" + (oRequestingModule ? oRequestingModule.name : "unknown") + "' and '" + sModuleName + "', returning undefined for '" + sModuleName + "'");
					}
					return undefined;
				}
				// async pending, load sync again
				log.warning("Sync request triggered for '" + sModuleName + "' while async request was already pending." +
					" Loading a module twice might cause issues and should be avoided by fully migrating to async APIs.");
			}
		}

		measure && measure.start(sModuleName, "Require module " + sModuleName, ["require"]);

		// set marker for loading modules (to break cycles)
		oModule.state = LOADING;
		oModule.async = bAsync;

		// if debug is enabled, try to load debug module first
		aExtensions = bDebugSources ? ["-dbg", ""] : [""];
		if ( !bAsync ) {

			for (i = 0; i < aExtensions.length && oModule.state !== LOADED; i++) {
				// create module URL for the current extension
				oModule.url = getResourcePath(oSplitName.baseID, aExtensions[i] + oSplitName.subType);
				if ( bLoggable ) {
					log.debug(sLogPrefix + "loading " + (aExtensions[i] ? aExtensions[i] + " version of " : "") + "'" + sModuleName + "' from '" + oModule.url + "'");
				}

				if ( syncCallBehavior ) {
					sMsg = "[nosync] loading module '" + oModule.url + "'";
					if ( syncCallBehavior === 1 ) {
						log.error(sMsg);
					} else {
						throw new Error(sMsg);
					}
				}

				// call notification hook
				ui5Require.load({ completeLoad:noop, async: false }, oModule.url, oSplitName.baseID);

				loadSyncXHR(oModule);
			}

			if ( oModule.state === LOADING ) {
				// transition to FAILED
				oModule.fail(
					makeNestedError("failed to load '" + sModuleName +  "' from " + oModule.url, oModule.error));
			} else if ( oModule.state === LOADED ) {
				// execute module __after__ loading it, this reduces the required stack space!
				execModule(sModuleName, bAsync);
			}

			measure && measure.end(sModuleName);

			if ( oModule.state !== READY ) {
				// loading or executing failed for some reason, load again as script for better error reporting
				// (but without further eventing)
				if ( fnIgnorePreload ) {
					loadScript(oModule);
				}
				throw oModule.error;
			}

			return oModule.value();

		} else {

			oModule.url = getResourcePath(oSplitName.baseID, aExtensions[0] + oSplitName.subType);
			// in debug mode, fall back to the non-dbg source, otherwise try the same source again (for SSO re-connect)
			var sAltUrl = bDebugSources ? getResourcePath(oSplitName.baseID, aExtensions[1] + oSplitName.subType) : oModule.url;
			// call notification hook only once
			ui5Require.load({ completeLoad:noop, async: true }, sAltUrl, oSplitName.baseID);
			loadScript(oModule, /* sAlternativeURL= */ sAltUrl);

			// process dep cache info
			preloadDependencies(sModuleName);

			return oModule.deferred().promise;
		}
	}
function requireModule(oRequestingModule, sModuleName, bAsync, bSkipShimDeps) {

		var bLoggable = log.isLoggable(),
			oSplitName = urnToBaseIDAndSubType(sModuleName),
			oShim = mShims[sModuleName],
			oModule, aExtensions, i, sMsg, bExecutedNow;

		// only for robustness, should not be possible by design (all callers append '.js')
		if ( !oSplitName ) {
			throw new Error("can only require Javascript module, not " + sModuleName);
		}

		// Module names should not start with a "/"
		if (sModuleName[0] == "/") {
			log.error("Module names that start with a slash should not be used, as they are reserved for future use.");
		}

		oModule = Module.get(sModuleName);

		// when there's a shim with dependencies for the module
		// resolve them first before requiring the module again with bSkipShimDeps = true
		if ( oShim && oShim.deps && !bSkipShimDeps ) {
			if ( bLoggable ) {
				log.debug("require dependencies of raw module " + sModuleName);
			}
			return requireAll(oModule, oShim.deps, function() {
				return requireModule(oRequestingModule, sModuleName, bAsync, /* bSkipShimDeps = */ true);
			}, function(oErr) {
				oModule.fail(oErr);
				if ( bAsync ) {
					return;
				}
				throw oErr;
			}, bAsync);
		}

		if ( bLoggable ) {
			log.debug(sLogPrefix + "require '" + sModuleName + "' of type '" + oSplitName.subType + "'");
		}

		// check if module has been loaded already
		if ( oModule.state !== INITIAL ) {
			if ( oModule.state === PRELOADED ) {
				oModule.state = LOADED;
				oModule.async = bAsync;
				bExecutedNow = true;
				measure && measure.start(sModuleName, "Require module " + sModuleName + " (preloaded)", ["require"]);
				execModule(sModuleName, bAsync);
				measure && measure.end(sModuleName);
			}

			if ( oModule.state === READY ) {
				if ( bLoggable ) {
					log.debug(sLogPrefix + "module '" + sModuleName + "' has already been loaded (skipped).");
				}
				// Note: this intentionally does not return oModule.promise() as the export might be temporary in case of cycles
				// or it might have changed after repeated module execution
				return bAsync ? Promise.resolve(oModule.value()) : oModule.value();
			} else if ( oModule.state === FAILED ) {
				if ( bAsync ) {
					return oModule.deferred().promise;
				} else {
					throw (bExecutedNow
						? oModule.error
						: makeNestedError("found in negative cache: '" + sModuleName + "' from " + oModule.url, oModule.error));
				}
			} else {
				// currently loading or executing
				if ( bAsync ) {
					// break up cyclic dependencies
					if ( oRequestingModule && oModule.dependsOn(oRequestingModule) ) {
						if ( log.isLoggable() ) {
							log.debug("cycle detected between '" + oRequestingModule.name + "' and '" + sModuleName + "', returning undefined for '" + sModuleName + "'");
						}
						// Note: this must be a separate promise as the fulfillment is not the final one
						return Promise.resolve(undefined);
					}
					return oModule.deferred().promise;
				}
				if ( !bAsync && !oModule.async ) {
					// sync pending, return undefined
					if ( log.isLoggable() ) {
						log.debug("cycle detected between '" + (oRequestingModule ? oRequestingModule.name : "unknown") + "' and '" + sModuleName + "', returning undefined for '" + sModuleName + "'");
					}
					return undefined;
				}
				// async pending, load sync again
				log.warning("Sync request triggered for '" + sModuleName + "' while async request was already pending." +
					" Loading a module twice might cause issues and should be avoided by fully migrating to async APIs.");
			}
		}

		measure && measure.start(sModuleName, "Require module " + sModuleName, ["require"]);

		// set marker for loading modules (to break cycles)
		oModule.state = LOADING;
		oModule.async = bAsync;

		// if debug is enabled, try to load debug module first
		aExtensions = bDebugSources ? ["-dbg", ""] : [""];
		if ( !bAsync ) {

			for (i = 0; i < aExtensions.length && oModule.state !== LOADED; i++) {
				// create module URL for the current extension
				oModule.url = getResourcePath(oSplitName.baseID, aExtensions[i] + oSplitName.subType);
				if ( bLoggable ) {
					log.debug(sLogPrefix + "loading " + (aExtensions[i] ? aExtensions[i] + " version of " : "") + "'" + sModuleName + "' from '" + oModule.url + "'");
				}

				if ( syncCallBehavior ) {
					sMsg = "[nosync] loading module '" + oModule.url + "'";
					if ( syncCallBehavior === 1 ) {
						log.error(sMsg);
					} else {
						throw new Error(sMsg);
					}
				}

				// call notification hook
				ui5Require.load({ completeLoad:noop, async: false }, oModule.url, oSplitName.baseID);

				loadSyncXHR(oModule);
			}

			if ( oModule.state === LOADING ) {
				// transition to FAILED
				oModule.fail(
					makeNestedError("failed to load '" + sModuleName +  "' from " + oModule.url, oModule.error));
			} else if ( oModule.state === LOADED ) {
				// execute module __after__ loading it, this reduces the required stack space!
				execModule(sModuleName, bAsync);
			}

			measure && measure.end(sModuleName);

			if ( oModule.state !== READY ) {
				// loading or executing failed for some reason, load again as script for better error reporting
				// (but without further eventing)
				if ( fnIgnorePreload ) {
					loadScript(oModule);
				}
				throw oModule.error;
			}

			return oModule.value();

		} else {

			oModule.url = getResourcePath(oSplitName.baseID, aExtensions[0] + oSplitName.subType);
			// in debug mode, fall back to the non-dbg source, otherwise try the same source again (for SSO re-connect)
			var sAltUrl = bDebugSources ? getResourcePath(oSplitName.baseID, aExtensions[1] + oSplitName.subType) : oModule.url;
			// call notification hook only once
			ui5Require.load({ completeLoad:noop, async: true }, sAltUrl, oSplitName.baseID);
			loadScript(oModule, /* sAlternativeURL= */ sAltUrl);

			// process dep cache info
			preloadDependencies(sModuleName);

			return oModule.deferred().promise;
		}
	}
function requireModule ( oRequestingModule , sModuleName , bAsync , bSkipShimDeps ) { var bLoggable = log . isLoggable ( ) , oSplitName = urnToBaseIDAndSubType ( sModuleName ) , oShim = mShims [ sModuleName ] , oModule , aExtensions , i , sMsg , bExecutedNow ; // only for robustness, should not be possible by design (all callers append '.js') if ( ! oSplitName ) { throw new Error ( "can only require Javascript module, not " + sModuleName ) ; } // Module names should not start with a "/" if ( sModuleName [ 0 ] == "/" ) { log . error ( "Module names that start with a slash should not be used, as they are reserved for future use." ) ; } oModule = Module . get ( sModuleName ) ; // when there's a shim with dependencies for the module // resolve them first before requiring the module again with bSkipShimDeps = true if ( oShim && oShim . deps && ! bSkipShimDeps ) { if ( bLoggable ) { log . debug ( "require dependencies of raw module " + sModuleName ) ; } return requireAll ( oModule , oShim . deps , function ( ) { return requireModule ( oRequestingModule , sModuleName , bAsync , /* bSkipShimDeps = */ true ) ; } , function ( oErr ) { oModule . fail ( oErr ) ; if ( bAsync ) { return ; } throw oErr ; } , bAsync ) ; } if ( bLoggable ) { log . debug ( sLogPrefix + "require '" + sModuleName + "' of type '" + oSplitName . subType + "'" ) ; } // check if module has been loaded already if ( oModule . state !== INITIAL ) { if ( oModule . state === PRELOADED ) { oModule . state = LOADED ; oModule . async = bAsync ; bExecutedNow = true ; measure && measure . start ( sModuleName , "Require module " + sModuleName + " (preloaded)" , [ "require" ] ) ; execModule ( sModuleName , bAsync ) ; measure && measure . end ( sModuleName ) ; } if ( oModule . state === READY ) { if ( bLoggable ) { log . debug ( sLogPrefix + "module '" + sModuleName + "' has already been loaded (skipped)." ) ; } // Note: this intentionally does not return oModule.promise() as the export might be temporary in case of cycles // or it might have changed after repeated module execution return bAsync ? Promise . resolve ( oModule . value ( ) ) : oModule . value ( ) ; } else if ( oModule . state === FAILED ) { if ( bAsync ) { return oModule . deferred ( ) . promise ; } else { throw ( bExecutedNow ? oModule . error : makeNestedError ( "found in negative cache: '" + sModuleName + "' from " + oModule . url , oModule . error ) ) ; } } else { // currently loading or executing if ( bAsync ) { // break up cyclic dependencies if ( oRequestingModule && oModule . dependsOn ( oRequestingModule ) ) { if ( log . isLoggable ( ) ) { log . debug ( "cycle detected between '" + oRequestingModule . name + "' and '" + sModuleName + "', returning undefined for '" + sModuleName + "'" ) ; } // Note: this must be a separate promise as the fulfillment is not the final one return Promise . resolve ( undefined ) ; } return oModule . deferred ( ) . promise ; } if ( ! bAsync && ! oModule . async ) { // sync pending, return undefined if ( log . isLoggable ( ) ) { log . debug ( "cycle detected between '" + ( oRequestingModule ? oRequestingModule . name : "unknown" ) + "' and '" + sModuleName + "', returning undefined for '" + sModuleName + "'" ) ; } return undefined ; } // async pending, load sync again log . warning ( "Sync request triggered for '" + sModuleName + "' while async request was already pending." + " Loading a module twice might cause issues and should be avoided by fully migrating to async APIs." ) ; } } measure && measure . start ( sModuleName , "Require module " + sModuleName , [ "require" ] ) ; // set marker for loading modules (to break cycles) oModule . state = LOADING ; oModule . async = bAsync ; // if debug is enabled, try to load debug module first aExtensions = bDebugSources ? [ "-dbg" , "" ] : [ "" ] ; if ( ! bAsync ) { for ( i = 0 ; i < aExtensions . length && oModule . state !== LOADED ; i ++ ) { // create module URL for the current extension oModule . url = getResourcePath ( oSplitName . baseID , aExtensions [ i ] + oSplitName . subType ) ; if ( bLoggable ) { log . debug ( sLogPrefix + "loading " + ( aExtensions [ i ] ? aExtensions [ i ] + " version of " : "" ) + "'" + sModuleName + "' from '" + oModule . url + "'" ) ; } if ( syncCallBehavior ) { sMsg = "[nosync] loading module '" + oModule . url + "'" ; if ( syncCallBehavior === 1 ) { log . error ( sMsg ) ; } else { throw new Error ( sMsg ) ; } } // call notification hook ui5Require . load ( { completeLoad : noop , async : false } , oModule . url , oSplitName . baseID ) ; loadSyncXHR ( oModule ) ; } if ( oModule . state === LOADING ) { // transition to FAILED oModule . fail ( makeNestedError ( "failed to load '" + sModuleName + "' from " + oModule . url , oModule . error ) ) ; } else if ( oModule . state === LOADED ) { // execute module __after__ loading it, this reduces the required stack space! execModule ( sModuleName , bAsync ) ; } measure && measure . end ( sModuleName ) ; if ( oModule . state !== READY ) { // loading or executing failed for some reason, load again as script for better error reporting // (but without further eventing) if ( fnIgnorePreload ) { loadScript ( oModule ) ; } throw oModule . error ; } return oModule . value ( ) ; } else { oModule . url = getResourcePath ( oSplitName . baseID , aExtensions [ 0 ] + oSplitName . subType ) ; // in debug mode, fall back to the non-dbg source, otherwise try the same source again (for SSO re-connect) var sAltUrl = bDebugSources ? getResourcePath ( oSplitName . baseID , aExtensions [ 1 ] + oSplitName . subType ) : oModule . url ; // call notification hook only once ui5Require . load ( { completeLoad : noop , async : true } , sAltUrl , oSplitName . baseID ) ; loadScript ( oModule , /* sAlternativeURL= */ sAltUrl ) ; // process dep cache info preloadDependencies ( sModuleName ) ; return oModule . deferred ( ) . promise ; } }
Loads the given module if needed and returns the module export or a promise on it.

If loading is still ongoing for the requested module and if there is a cycle detected between
the requesting module and the module to be loaded, then <code>undefined</code> (or a promise on
<code>undefined</code>) will be returned as intermediate module export to resolve the cycle.

@param {Module} oRequestingModule The module in whose context the new module has to be loaded;
this is needed to detect cycles
@param {string} sModuleName Name of the module to be loaded, in URN form and with '.js' extension
@param {boolean} bAsync Whether the operation can be executed asynchronously
@param {boolean} bSkipShimDeps Whether shim dependencies should be ignored
@returns {any|Promise} Returns the module export in sync mode or a promise on it in async mode
@throws {Error} When loading failed in sync mode

@private
Loads the given module if needed and returns the module export or a promise on it .
require module