code:
/*
	MIT License http://www.opensource.org/licenses/mit-license.php
	Author Tobias Koppers @sokra
*/

"use strict";

const { OriginalSource, RawSource } = require("webpack-sources");
const AsyncDependenciesBlock = require("./AsyncDependenciesBlock");
const { makeWebpackError } = require("./HookWebpackError");
const Module = require("./Module");
const { JAVASCRIPT_MODULE_TYPE_DYNAMIC } = require("./ModuleTypeConstants");
const RuntimeGlobals = require("./RuntimeGlobals");
const Template = require("./Template");
const WebpackError = require("./WebpackError");
const {
	compareLocations,
	concatComparators,
	compareSelect,
	keepOriginalOrder,
	compareModulesById
} = require("./util/comparators");
const {
	contextify,
	parseResource,
	makePathsRelative
} = require("./util/identifier");
const makeSerializable = require("./util/makeSerializable");

/** @typedef {import("webpack-sources").Source} Source */
/** @typedef {import("../declarations/WebpackOptions").WebpackOptionsNormalized} WebpackOptions */
/** @typedef {import("./Chunk")} Chunk */
/** @typedef {import("./ChunkGraph")} ChunkGraph */
/** @typedef {import("./ChunkGraph").ModuleId} ModuleId */
/** @typedef {import("./ChunkGroup").RawChunkGroupOptions} RawChunkGroupOptions */
/** @typedef {import("./Compilation")} Compilation */
/** @typedef {import("./Dependency")} Dependency */
/** @typedef {import("./DependencyTemplates")} DependencyTemplates */
/** @typedef {import("./Module").BuildInfo} BuildInfo */
/** @typedef {import("./Module").BuildMeta} BuildMeta */
/** @typedef {import("./Module").CodeGenerationContext} CodeGenerationContext */
/** @typedef {import("./Module").CodeGenerationResult} CodeGenerationResult */
/** @typedef {import("./Module").LibIdentOptions} LibIdentOptions */
/** @typedef {import("./Module").NeedBuildContext} NeedBuildContext */
/** @typedef {import("./Module").SourceTypes} SourceTypes */
/** @typedef {import("./ModuleGraph")} ModuleGraph */
/** @typedef {import("./RequestShortener")} RequestShortener */
/** @typedef {import("./ResolverFactory").ResolverWithOptions} ResolverWithOptions */
/** @typedef {import("./RuntimeTemplate")} RuntimeTemplate */
/** @typedef {import("./dependencies/ContextElementDependency")} ContextElementDependency */
/** @typedef {import("./javascript/JavascriptParser").ImportAttributes} ImportAttributes */
/** @typedef {import("./serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */
/** @typedef {import("./serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */
/** @template T @typedef {import("./util/LazySet")<T>} LazySet<T> */
/** @typedef {import("./util/fs").InputFileSystem} InputFileSystem */

/** @typedef {"sync" | "eager" | "weak" | "async-weak" | "lazy" | "lazy-once"} ContextMode Context mode */

/**
 * @typedef {object} ContextOptions
 * @property {ContextMode} mode
 * @property {boolean} recursive
 * @property {RegExp} regExp
 * @property {"strict"|boolean=} namespaceObject
 * @property {string=} addon
 * @property {string=} chunkName
 * @property {RegExp=} include
 * @property {RegExp=} exclude
 * @property {RawChunkGroupOptions=} groupOptions
 * @property {string=} typePrefix
 * @property {string=} category
 * @property {(string[][] | null)=} referencedExports exports referenced from modules (won't be mangled)
 * @property {string=} layer
 * @property {ImportAttributes=} attributes
 */

/**
 * @typedef {object} ContextModuleOptionsExtras
 * @property {false|string|string[]} resource
 * @property {string=} resourceQuery
 * @property {string=} resourceFragment
 * @property {TODO} resolveOptions
 */

/** @typedef {ContextOptions & ContextModuleOptionsExtras} ContextModuleOptions */

/**
 * @callback ResolveDependenciesCallback
 * @param {(Error | null)=} err
 * @param {ContextElementDependency[]=} dependencies
 */

/**
 * @callback ResolveDependencies
 * @param {InputFileSystem} fs
 * @param {ContextModuleOptions} options
 * @param {ResolveDependenciesCallback} callback
 */

/** @typedef {1 | 3 | 7 | 9} FakeMapType */

/** @typedef {Map<string, string | number> | FakeMapType} FakeMap */

const SNAPSHOT_OPTIONS = { timestamp: true };

const TYPES = new Set(["javascript"]);

class ContextModule extends Module {
	/**
	 * @param {ResolveDependencies} resolveDependencies function to get dependencies in this context
	 * @param {ContextModuleOptions} options options object
	 */
	constructor(resolveDependencies, options) {
		if (!options || typeof options.resource === "string") {
			const parsed = parseResource(
				options ? /** @type {string} */ (options.resource) : ""
			);
			const resource = parsed.path;
			const resourceQuery = (options && options.resourceQuery) || parsed.query;
			const resourceFragment =
				(options && options.resourceFragment) || parsed.fragment;
			const layer = options && options.layer;

			super(JAVASCRIPT_MODULE_TYPE_DYNAMIC, resource, layer);
			/** @type {ContextModuleOptions} */
			this.options = {
				...options,
				resource,
				resourceQuery,
				resourceFragment
			};
		} else {
			super(JAVASCRIPT_MODULE_TYPE_DYNAMIC, undefined, options.layer);
			/** @type {ContextModuleOptions} */
			this.options = {
				...options,
				resource: options.resource,
				resourceQuery: options.resourceQuery || "",
				resourceFragment: options.resourceFragment || ""
			};
		}

		// Info from Factory
		/** @type {ResolveDependencies | undefined} */
		this.resolveDependencies = resolveDependencies;
		if (options && options.resolveOptions !== undefined) {
			this.resolveOptions = options.resolveOptions;
		}

		if (options && typeof options.mode !== "string") {
			throw new Error("options.mode is a required option");
		}

		this._identifier = this._createIdentifier();
		this._forceBuild = true;
	}

	/**
	 * @returns {SourceTypes} types available (do not mutate)
	 */
	getSourceTypes() {
		return TYPES;
	}

	/**
	 * Assuming this module is in the cache. Update the (cached) module with
	 * the fresh module from the factory. Usually updates internal references
	 * and properties.
	 * @param {Module} module fresh module
	 * @returns {void}
	 */
	updateCacheModule(module) {
		const m = /** @type {ContextModule} */ (module);
		this.resolveDependencies = m.resolveDependencies;
		this.options = m.options;
	}

	/**
	 * Assuming this module is in the cache. Remove internal references to allow freeing some memory.
	 */
	cleanupForCache() {
		super.cleanupForCache();
		this.resolveDependencies = undefined;
	}

	/**
	 * @private
	 * @param {RegExp} regexString RegExp as a string
	 * @param {boolean=} stripSlash do we need to strip a slsh
	 * @returns {string} pretty RegExp
	 */
	_prettyRegExp(regexString, stripSlash = true) {
		const str = (regexString + "").replace(/!/g, "%21").replace(/\|/g, "%7C");
		return stripSlash ? str.substring(1, str.length - 1) : str;
	}

	_createIdentifier() {
		let identifier =
			this.context ||
			(typeof this.options.resource === "string" ||
			this.options.resource === false
				? `${this.options.resource}`
				: this.options.resource.join("|"));
		if (this.options.resourceQuery) {
			identifier += `|${this.options.resourceQuery}`;
		}
		if (this.options.resourceFragment) {
			identifier += `|${this.options.resourceFragment}`;
		}
		if (this.options.mode) {
			identifier += `|${this.options.mode}`;
		}
		if (!this.options.recursive) {
			identifier += "|nonrecursive";
		}
		if (this.options.addon) {
			identifier += `|${this.options.addon}`;
		}
		if (this.options.regExp) {
			identifier += `|${this._prettyRegExp(this.options.regExp, false)}`;
		}
		if (this.options.include) {
			identifier += `|include: ${this._prettyRegExp(
				this.options.include,
				false
			)}`;
		}
		if (this.options.exclude) {
			identifier += `|exclude: ${this._prettyRegExp(
				this.options.exclude,
				false
			)}`;
		}
		if (this.options.referencedExports) {
			identifier += `|referencedExports: ${JSON.stringify(
				this.options.referencedExports
			)}`;
		}
		if (this.options.chunkName) {
			identifier += `|chunkName: ${this.options.chunkName}`;
		}
		if (this.options.groupOptions) {
			identifier += `|groupOptions: ${JSON.stringify(
				this.options.groupOptions
			)}`;
		}
		if (this.options.namespaceObject === "strict") {
			identifier += "|strict namespace object";
		} else if (this.options.namespaceObject) {
			identifier += "|namespace object";
		}
		if (this.layer) {
			identifier += `|layer: ${this.layer}`;
		}

		return identifier;
	}

	/**
	 * @returns {string} a unique identifier of the module
	 */
	identifier() {
		return this._identifier;
	}

	/**
	 * @param {RequestShortener} requestShortener the request shortener
	 * @returns {string} a user readable identifier of the module
	 */
	readableIdentifier(requestShortener) {
		let identifier;
		if (this.context) {
			identifier = requestShortener.shorten(this.context) + "/";
		} else if (
			typeof this.options.resource === "string" ||
			this.options.resource === false
		) {
			identifier = requestShortener.shorten(`${this.options.resource}`) + "/";
		} else {
			identifier = this.options.resource
				.map(r => requestShortener.shorten(r) + "/")
				.join(" ");
		}
		if (this.options.resourceQuery) {
			identifier += ` ${this.options.resourceQuery}`;
		}
		if (this.options.mode) {
			identifier += ` ${this.options.mode}`;
		}
		if (!this.options.recursive) {
			identifier += " nonrecursive";
		}
		if (this.options.addon) {
			identifier += ` ${requestShortener.shorten(this.options.addon)}`;
		}
		if (this.options.regExp) {
			identifier += ` ${this._prettyRegExp(this.options.regExp)}`;
		}
		if (this.options.include) {
			identifier += ` include: ${this._prettyRegExp(this.options.include)}`;
		}
		if (this.options.exclude) {
			identifier += ` exclude: ${this._prettyRegExp(this.options.exclude)}`;
		}
		if (this.options.referencedExports) {
			identifier += ` referencedExports: ${this.options.referencedExports
				.map(e => e.join("."))
				.join(", ")}`;
		}
		if (this.options.chunkName) {
			identifier += ` chunkName: ${this.options.chunkName}`;
		}
		if (this.options.groupOptions) {
			const groupOptions = this.options.groupOptions;
			for (const key of Object.keys(groupOptions)) {
				identifier += ` ${key}: ${
					groupOptions[/** @type {keyof RawChunkGroupOptions} */ (key)]
				}`;
			}
		}
		if (this.options.namespaceObject === "strict") {
			identifier += " strict namespace object";
		} else if (this.options.namespaceObject) {
			identifier += " namespace object";
		}

		return identifier;
	}

	/**
	 * @param {LibIdentOptions} options options
	 * @returns {string | null} an identifier for library inclusion
	 */
	libIdent(options) {
		let identifier;

		if (this.context) {
			identifier = contextify(
				options.context,
				this.context,
				options.associatedObjectForCache
			);
		} else if (typeof this.options.resource === "string") {
			identifier = contextify(
				options.context,
				this.options.resource,
				options.associatedObjectForCache
			);
		} else if (this.options.resource === false) {
			identifier = "false";
		} else {
			identifier = this.options.resource
				.map(res =>
					contextify(options.context, res, options.associatedObjectForCache)
				)
				.join(" ");
		}

		if (this.layer) identifier = `(${this.layer})/${identifier}`;
		if (this.options.mode) {
			identifier += ` ${this.options.mode}`;
		}
		if (this.options.recursive) {
			identifier += " recursive";
		}
		if (this.options.addon) {
			identifier += ` ${contextify(
				options.context,
				this.options.addon,
				options.associatedObjectForCache
			)}`;
		}
		if (this.options.regExp) {
			identifier += ` ${this._prettyRegExp(this.options.regExp)}`;
		}
		if (this.options.include) {
			identifier += ` include: ${this._prettyRegExp(this.options.include)}`;
		}
		if (this.options.exclude) {
			identifier += ` exclude: ${this._prettyRegExp(this.options.exclude)}`;
		}
		if (this.options.referencedExports) {
			identifier += ` referencedExports: ${this.options.referencedExports
				.map(e => e.join("."))
				.join(", ")}`;
		}

		return identifier;
	}

	/**
	 * @returns {void}
	 */
	invalidateBuild() {
		this._forceBuild = true;
	}

	/**
	 * @param {NeedBuildContext} context context info
	 * @param {function((WebpackError | null)=, boolean=): void} callback callback function, returns true, if the module needs a rebuild
	 * @returns {void}
	 */
	needBuild({ fileSystemInfo }, callback) {
		// build if enforced
		if (this._forceBuild) return callback(null, true);

		const buildInfo = /** @type {BuildInfo} */ (this.buildInfo);

		// always build when we have no snapshot and context
		if (!buildInfo.snapshot)
			return callback(null, Boolean(this.context || this.options.resource));

		fileSystemInfo.checkSnapshotValid(buildInfo.snapshot, (err, valid) => {
			callback(err, !valid);
		});
	}

	/**
	 * @param {WebpackOptions} options webpack options
	 * @param {Compilation} compilation the compilation
	 * @param {ResolverWithOptions} resolver the resolver
	 * @param {InputFileSystem} fs the file system
	 * @param {function(WebpackError=): void} callback callback function
	 * @returns {void}
	 */
	build(options, compilation, resolver, fs, callback) {
		this._forceBuild = false;
		/** @type {BuildMeta} */
		this.buildMeta = {
			exportsType: "default",
			defaultObject: "redirect-warn"
		};
		this.buildInfo = {
			snapshot: undefined
		};
		this.dependencies.length = 0;
		this.blocks.length = 0;
		const startTime = Date.now();
		/** @type {ResolveDependencies} */
		(this.resolveDependencies)(fs, this.options, (err, dependencies) => {
			if (err) {
				return callback(
					makeWebpackError(err, "ContextModule.resolveDependencies")
				);
			}

			// abort if something failed
			// this will create an empty context
			if (!dependencies) {
				callback();
				return;
			}

			// enhance dependencies with meta info
			for (const dep of dependencies) {
				dep.loc = {
					name: dep.userRequest
				};
				dep.request = this.options.addon + dep.request;
			}
			dependencies.sort(
				concatComparators(
					compareSelect(a => a.loc, compareLocations),
					keepOriginalOrder(this.dependencies)
				)
			);

			if (this.options.mode === "sync" || this.options.mode === "eager") {
				// if we have an sync or eager context
				// just add all dependencies and continue
				this.dependencies = dependencies;
			} else if (this.options.mode === "lazy-once") {
				// for the lazy-once mode create a new async dependency block
				// and add that block to this context
				if (dependencies.length > 0) {
					const block = new AsyncDependenciesBlock({
						...this.options.groupOptions,
						name: this.options.chunkName
					});
					for (const dep of dependencies) {
						block.addDependency(dep);
					}
					this.addBlock(block);
				}
			} else if (
				this.options.mode === "weak" ||
				this.options.mode === "async-weak"
			) {
				// we mark all dependencies as weak
				for (const dep of dependencies) {
					dep.weak = true;
				}
				this.dependencies = dependencies;
			} else if (this.options.mode === "lazy") {
				// if we are lazy create a new async dependency block per dependency
				// and add all blocks to this context
				let index = 0;
				for (const dep of dependencies) {
					let chunkName = this.options.chunkName;
					if (chunkName) {
						if (!/\[(index|request)\]/.test(chunkName)) {
							chunkName += "[index]";
						}
						chunkName = chunkName.replace(/\[index\]/g, `${index++}`);
						chunkName = chunkName.replace(
							/\[request\]/g,
							Template.toPath(dep.userRequest)
						);
					}
					const block = new AsyncDependenciesBlock(
						{
							...this.options.groupOptions,
							name: chunkName
						},
						dep.loc,
						dep.userRequest
					);
					block.addDependency(dep);
					this.addBlock(block);
				}
			} else {
				callback(
					new WebpackError(`Unsupported mode "${this.options.mode}" in context`)
				);
				return;
			}
			if (!this.context && !this.options.resource) return callback();

			compilation.fileSystemInfo.createSnapshot(
				startTime,
				null,
				this.context
					? [this.context]
					: typeof this.options.resource === "string"
						? [this.options.resource]
						: /** @type {string[]} */ (this.options.resource),
				null,
				SNAPSHOT_OPTIONS,
				(err, snapshot) => {
					if (err) return callback(err);
					/** @type {BuildInfo} */
					(this.buildInfo).snapshot = snapshot;
					callback();
				}
			);
		});
	}

	/**
	 * @param {LazySet<string>} fileDependencies set where file dependencies are added to
	 * @param {LazySet<string>} contextDependencies set where context dependencies are added to
	 * @param {LazySet<string>} missingDependencies set where missing dependencies are added to
	 * @param {LazySet<string>} buildDependencies set where build dependencies are added to
	 */
	addCacheDependencies(
		fileDependencies,
		contextDependencies,
		missingDependencies,
		buildDependencies
	) {
		if (this.context) {
			contextDependencies.add(this.context);
		} else if (typeof this.options.resource === "string") {
			contextDependencies.add(this.options.resource);
		} else if (this.options.resource === false) {
			return;
		} else {
			for (const res of this.options.resource) contextDependencies.add(res);
		}
	}

	/**
	 * @param {Dependency[]} dependencies all dependencies
	 * @param {ChunkGraph} chunkGraph chunk graph
	 * @returns {Map<string, string | number>} map with user requests
	 */
	getUserRequestMap(dependencies, chunkGraph) {
		const moduleGraph = chunkGraph.moduleGraph;
		// if we filter first we get a new array
		// therefore we don't need to create a clone of dependencies explicitly
		// therefore the order of this is !important!
		const sortedDependencies =
			/** @type {ContextElementDependency[]} */
			(dependencies)
				.filter(dependency => moduleGraph.getModule(dependency))
				.sort((a, b) => {
					if (a.userRequest === b.userRequest) {
						return 0;
					}
					return a.userRequest < b.userRequest ? -1 : 1;
				});
		const map = Object.create(null);
		for (const dep of sortedDependencies) {
			const module = /** @type {Module} */ (moduleGraph.getModule(dep));
			map[dep.userRequest] = chunkGraph.getModuleId(module);
		}
		return map;
	}

	/**
	 * @param {Dependency[]} dependencies all dependencies
	 * @param {ChunkGraph} chunkGraph chunk graph
	 * @returns {FakeMap} fake map
	 */
	getFakeMap(dependencies, chunkGraph) {
		if (!this.options.namespaceObject) {
			return 9;
		}
		const moduleGraph = chunkGraph.moduleGraph;
		// bitfield
		let hasType = 0;
		const comparator = compareModulesById(chunkGraph);
		// if we filter first we get a new array
		// therefore we don't need to create a clone of dependencies explicitly
		// therefore the order of this is !important!
		const sortedModules = dependencies
			.map(
				dependency => /** @type {Module} */ (moduleGraph.getModule(dependency))
			)
			.filter(Boolean)
			.sort(comparator);
		const fakeMap = Object.create(null);
		for (const module of sortedModules) {
			const exportsType = module.getExportsType(
				moduleGraph,
				this.options.namespaceObject === "strict"
			);
			const id = chunkGraph.getModuleId(module);
			switch (exportsType) {
				case "namespace":
					fakeMap[id] = 9;
					hasType |= 1;
					break;
				case "dynamic":
					fakeMap[id] = 7;
					hasType |= 2;
					break;
				case "default-only":
					fakeMap[id] = 1;
					hasType |= 4;
					break;
				case "default-with-named":
					fakeMap[id] = 3;
					hasType |= 8;
					break;
				default:
					throw new Error(`Unexpected exports type ${exportsType}`);
			}
		}
		if (hasType === 1) {
			return 9;
		}
		if (hasType === 2) {
			return 7;
		}
		if (hasType === 4) {
			return 1;
		}
		if (hasType === 8) {
			return 3;
		}
		if (hasType === 0) {
			return 9;
		}
		return fakeMap;
	}

	/**
	 * @param {FakeMap} fakeMap fake map
	 * @returns {string} fake map init statement
	 */
	getFakeMapInitStatement(fakeMap) {
		return typeof fakeMap === "object"
			? `var fakeMap = ${JSON.stringify(fakeMap, null, "\t")};`
			: "";
	}

	/**
	 * @param {FakeMapType} type type
	 * @param {boolean=} asyncModule is async module
	 * @returns {string} return result
	 */
	getReturn(type, asyncModule) {
		if (type === 9) {
			return `${RuntimeGlobals.require}(id)`;
		}
		return `${RuntimeGlobals.createFakeNamespaceObject}(id, ${type}${
			asyncModule ? " | 16" : ""
		})`;
	}

	/**
	 * @param {FakeMap} fakeMap fake map
	 * @param {boolean=} asyncModule us async module
	 * @param {string=} fakeMapDataExpression fake map data expression
	 * @returns {string} module object source
	 */
	getReturnModuleObjectSource(
		fakeMap,
		asyncModule,
		fakeMapDataExpression = "fakeMap[id]"
	) {
		if (typeof fakeMap === "number") {
			return `return ${this.getReturn(fakeMap, asyncModule)};`;
		}
		return `return ${
			RuntimeGlobals.createFakeNamespaceObject
		}(id, ${fakeMapDataExpression}${asyncModule ? " | 16" : ""})`;
	}

	/**
	 * @param {Dependency[]} dependencies dependencies
	 * @param {ModuleId} id module id
	 * @param {ChunkGraph} chunkGraph the chunk graph
	 * @returns {string} source code
	 */
	getSyncSource(dependencies, id, chunkGraph) {
		const map = this.getUserRequestMap(dependencies, chunkGraph);
		const fakeMap = this.getFakeMap(dependencies, chunkGraph);
		const returnModuleObject = this.getReturnModuleObjectSource(fakeMap);

		return `var map = ${JSON.stringify(map, null, "\t")};
${this.getFakeMapInitStatement(fakeMap)}

function webpackContext(req) {
	var id = webpackContextResolve(req);
	${returnModuleObject}
}
function webpackContextResolve(req) {
	if(!${RuntimeGlobals.hasOwnProperty}(map, req)) {
		var e = new Error("Cannot find module '" + req + "'");
		e.code = 'MODULE_NOT_FOUND';
		throw e;
	}
	return map[req];
}
webpackContext.keys = function webpackContextKeys() {
	return Object.keys(map);
};
webpackContext.resolve = webpackContextResolve;
module.exports = webpackContext;
webpackContext.id = ${JSON.stringify(id)};`;
	}

	/**
	 * @param {Dependency[]} dependencies dependencies
	 * @param {ModuleId} id module id
	 * @param {ChunkGraph} chunkGraph the chunk graph
	 * @returns {string} source code
	 */
	getWeakSyncSource(dependencies, id, chunkGraph) {
		const map = this.getUserRequestMap(dependencies, chunkGraph);
		const fakeMap = this.getFakeMap(dependencies, chunkGraph);
		const returnModuleObject = this.getReturnModuleObjectSource(fakeMap);

		return `var map = ${JSON.stringify(map, null, "\t")};
${this.getFakeMapInitStatement(fakeMap)}

function webpackContext(req) {
	var id = webpackContextResolve(req);
	if(!${RuntimeGlobals.moduleFactories}[id]) {
		var e = new Error("Module '" + req + "' ('" + id + "') is not available (weak dependency)");
		e.code = 'MODULE_NOT_FOUND';
		throw e;
	}
	${returnModuleObject}
}
function webpackContextResolve(req) {
	if(!${RuntimeGlobals.hasOwnProperty}(map, req)) {
		var e = new Error("Cannot find module '" + req + "'");
		e.code = 'MODULE_NOT_FOUND';
		throw e;
	}
	return map[req];
}
webpackContext.keys = function webpackContextKeys() {
	return Object.keys(map);
};
webpackContext.resolve = webpackContextResolve;
webpackContext.id = ${JSON.stringify(id)};
module.exports = webpackContext;`;
	}

	/**
	 * @param {Dependency[]} dependencies dependencies
	 * @param {ModuleId} id module id
	 * @param {object} context context
	 * @param {ChunkGraph} context.chunkGraph the chunk graph
	 * @param {RuntimeTemplate} context.runtimeTemplate the chunk graph
	 * @returns {string} source code
	 */
	getAsyncWeakSource(dependencies, id, { chunkGraph, runtimeTemplate }) {
		const arrow = runtimeTemplate.supportsArrowFunction();
		const map = this.getUserRequestMap(dependencies, chunkGraph);
		const fakeMap = this.getFakeMap(dependencies, chunkGraph);
		const returnModuleObject = this.getReturnModuleObjectSource(fakeMap, true);

		return `var map = ${JSON.stringify(map, null, "\t")};
${this.getFakeMapInitStatement(fakeMap)}

function webpackAsyncContext(req) {
	return webpackAsyncContextResolve(req).then(${
		arrow ? "id =>" : "function(id)"
	} {
		if(!${RuntimeGlobals.moduleFactories}[id]) {
			var e = new Error("Module '" + req + "' ('" + id + "') is not available (weak dependency)");
			e.code = 'MODULE_NOT_FOUND';
			throw e;
		}
		${returnModuleObject}
	});
}
function webpackAsyncContextResolve(req) {
	// Here Promise.resolve().then() is used instead of new Promise() to prevent
	// uncaught exception popping up in devtools
	return Promise.resolve().then(${arrow ? "() =>" : "function()"} {
		if(!${RuntimeGlobals.hasOwnProperty}(map, req)) {
			var e = new Error("Cannot find module '" + req + "'");
			e.code = 'MODULE_NOT_FOUND';
			throw e;
		}
		return map[req];
	});
}
webpackAsyncContext.keys = ${runtimeTemplate.returningFunction(
			"Object.keys(map)"
		)};
webpackAsyncContext.resolve = webpackAsyncContextResolve;
webpackAsyncContext.id = ${JSON.stringify(id)};
module.exports = webpackAsyncContext;`;
	}

	/**
	 * @param {Dependency[]} dependencies dependencies
	 * @param {ModuleId} id module id
	 * @param {object} context context
	 * @param {ChunkGraph} context.chunkGraph the chunk graph
	 * @param {RuntimeTemplate} context.runtimeTemplate the chunk graph
	 * @returns {string} source code
	 */
	getEagerSource(dependencies, id, { chunkGraph, runtimeTemplate }) {
		const arrow = runtimeTemplate.supportsArrowFunction();
		const map = this.getUserRequestMap(dependencies, chunkGraph);
		const fakeMap = this.getFakeMap(dependencies, chunkGraph);
		const thenFunction =
			fakeMap !== 9
				? `${arrow ? "id =>" : "function(id)"} {
		${this.getReturnModuleObjectSource(fakeMap, true)}
	}`
				: RuntimeGlobals.require;
		return `var map = ${JSON.stringify(map, null, "\t")};
${this.getFakeMapInitStatement(fakeMap)}

function webpackAsyncContext(req) {
	return webpackAsyncContextResolve(req).then(${thenFunction});
}
function webpackAsyncContextResolve(req) {
	// Here Promise.resolve().then() is used instead of new Promise() to prevent
	// uncaught exception popping up in devtools
	return Promise.resolve().then(${arrow ? "() =>" : "function()"} {
		if(!${RuntimeGlobals.hasOwnProperty}(map, req)) {
			var e = new Error("Cannot find module '" + req + "'");
			e.code = 'MODULE_NOT_FOUND';
			throw e;
		}
		return map[req];
	});
}
webpackAsyncContext.keys = ${runtimeTemplate.returningFunction(
			"Object.keys(map)"
		)};
webpackAsyncContext.resolve = webpackAsyncContextResolve;
webpackAsyncContext.id = ${JSON.stringify(id)};
module.exports = webpackAsyncContext;`;
	}

	/**
	 * @param {AsyncDependenciesBlock} block block
	 * @param {Dependency[]} dependencies dependencies
	 * @param {ModuleId} id module id
	 * @param {object} options options object
	 * @param {RuntimeTemplate} options.runtimeTemplate the runtime template
	 * @param {ChunkGraph} options.chunkGraph the chunk graph
	 * @returns {string} source code
	 */
	getLazyOnceSource(block, dependencies, id, { runtimeTemplate, chunkGraph }) {
		const promise = runtimeTemplate.blockPromise({
			chunkGraph,
			block,
			message: "lazy-once context",
			runtimeRequirements: new Set()
		});
		const arrow = runtimeTemplate.supportsArrowFunction();
		const map = this.getUserRequestMap(dependencies, chunkGraph);
		const fakeMap = this.getFakeMap(dependencies, chunkGraph);
		const thenFunction =
			fakeMap !== 9
				? `${arrow ? "id =>" : "function(id)"} {
		${this.getReturnModuleObjectSource(fakeMap, true)};
	}`
				: RuntimeGlobals.require;

		return `var map = ${JSON.stringify(map, null, "\t")};
${this.getFakeMapInitStatement(fakeMap)}

function webpackAsyncContext(req) {
	return webpackAsyncContextResolve(req).then(${thenFunction});
}
function webpackAsyncContextResolve(req) {
	return ${promise}.then(${arrow ? "() =>" : "function()"} {
		if(!${RuntimeGlobals.hasOwnProperty}(map, req)) {
			var e = new Error("Cannot find module '" + req + "'");
			e.code = 'MODULE_NOT_FOUND';
			throw e;
		}
		return map[req];
	});
}
webpackAsyncContext.keys = ${runtimeTemplate.returningFunction(
			"Object.keys(map)"
		)};
webpackAsyncContext.resolve = webpackAsyncContextResolve;
webpackAsyncContext.id = ${JSON.stringify(id)};
module.exports = webpackAsyncContext;`;
	}

	/**
	 * @param {AsyncDependenciesBlock[]} blocks blocks
	 * @param {ModuleId} id module id
	 * @param {object} context context
	 * @param {ChunkGraph} context.chunkGraph the chunk graph
	 * @param {RuntimeTemplate} context.runtimeTemplate the chunk graph
	 * @returns {string} source code
	 */
	getLazySource(blocks, id, { chunkGraph, runtimeTemplate }) {
		const moduleGraph = chunkGraph.moduleGraph;
		const arrow = runtimeTemplate.supportsArrowFunction();
		let hasMultipleOrNoChunks = false;
		let hasNoChunk = true;
		const fakeMap = this.getFakeMap(
			blocks.map(b => b.dependencies[0]),
			chunkGraph
		);
		const hasFakeMap = typeof fakeMap === "object";
		const items = blocks
			.map(block => {
				const dependency =
					/** @type {ContextElementDependency} */
					(block.dependencies[0]);
				return {
					dependency: dependency,
					module: /** @type {Module} */ (moduleGraph.getModule(dependency)),
					block: block,
					userRequest: dependency.userRequest,
					chunks: undefined
				};
			})
			.filter(item => item.module);
		for (const item of items) {
			const chunkGroup = chunkGraph.getBlockChunkGroup(item.block);
			const chunks = (chunkGroup && chunkGroup.chunks) || [];
			item.chunks = chunks;
			if (chunks.length > 0) {
				hasNoChunk = false;
			}
			if (chunks.length !== 1) {
				hasMultipleOrNoChunks = true;
			}
		}
		const shortMode = hasNoChunk && !hasFakeMap;
		const sortedItems = items.sort((a, b) => {
			if (a.userRequest === b.userRequest) return 0;
			return a.userRequest < b.userRequest ? -1 : 1;
		});
		const map = Object.create(null);
		for (const item of sortedItems) {
			const moduleId = chunkGraph.getModuleId(item.module);
			if (shortMode) {
				map[item.userRequest] = moduleId;
			} else {
				const arrayStart = [moduleId];
				if (hasFakeMap) {
					arrayStart.push(fakeMap[moduleId]);
				}
				map[item.userRequest] = arrayStart.concat(
					item.chunks.map(chunk => chunk.id)
				);
			}
		}

		const chunksStartPosition = hasFakeMap ? 2 : 1;
		const requestPrefix = hasNoChunk
			? "Promise.resolve()"
			: hasMultipleOrNoChunks
				? `Promise.all(ids.slice(${chunksStartPosition}).map(${RuntimeGlobals.ensureChunk}))`
				: `${RuntimeGlobals.ensureChunk}(ids[${chunksStartPosition}])`;
		const returnModuleObject = this.getReturnModuleObjectSource(
			fakeMap,
			true,
			shortMode ? "invalid" : "ids[1]"
		);

		const webpackAsyncContext =
			requestPrefix === "Promise.resolve()"
				? `
function webpackAsyncContext(req) {
	return Promise.resolve().then(${arrow ? "() =>" : "function()"} {
		if(!${RuntimeGlobals.hasOwnProperty}(map, req)) {
			var e = new Error("Cannot find module '" + req + "'");
			e.code = 'MODULE_NOT_FOUND';
			throw e;
		}

		${shortMode ? "var id = map[req];" : "var ids = map[req], id = ids[0];"}
		${returnModuleObject}
	});
}`
				: `function webpackAsyncContext(req) {
	if(!${RuntimeGlobals.hasOwnProperty}(map, req)) {
		return Promise.resolve().then(${arrow ? "() =>" : "function()"} {
			var e = new Error("Cannot find module '" + req + "'");
			e.code = 'MODULE_NOT_FOUND';
			throw e;
		});
	}

	var ids = map[req], id = ids[0];
	return ${requestPrefix}.then(${arrow ? "() =>" : "function()"} {
		${returnModuleObject}
	});
}`;

		return `var map = ${JSON.stringify(map, null, "\t")};
${webpackAsyncContext}
webpackAsyncContext.keys = ${runtimeTemplate.returningFunction(
			"Object.keys(map)"
		)};
webpackAsyncContext.id = ${JSON.stringify(id)};
module.exports = webpackAsyncContext;`;
	}

	/**
	 * @param {ModuleId} id module id
	 * @param {RuntimeTemplate} runtimeTemplate runtime template
	 * @returns {string} source for empty async context
	 */
	getSourceForEmptyContext(id, runtimeTemplate) {
		return `function webpackEmptyContext(req) {
	var e = new Error("Cannot find module '" + req + "'");
	e.code = 'MODULE_NOT_FOUND';
	throw e;
}
webpackEmptyContext.keys = ${runtimeTemplate.returningFunction("[]")};
webpackEmptyContext.resolve = webpackEmptyContext;
webpackEmptyContext.id = ${JSON.stringify(id)};
module.exports = webpackEmptyContext;`;
	}

	/**
	 * @param {ModuleId} id module id
	 * @param {RuntimeTemplate} runtimeTemplate runtime template
	 * @returns {string} source for empty async context
	 */
	getSourceForEmptyAsyncContext(id, runtimeTemplate) {
		const arrow = runtimeTemplate.supportsArrowFunction();
		return `function webpackEmptyAsyncContext(req) {
	// Here Promise.resolve().then() is used instead of new Promise() to prevent
	// uncaught exception popping up in devtools
	return Promise.resolve().then(${arrow ? "() =>" : "function()"} {
		var e = new Error("Cannot find module '" + req + "'");
		e.code = 'MODULE_NOT_FOUND';
		throw e;
	});
}
webpackEmptyAsyncContext.keys = ${runtimeTemplate.returningFunction("[]")};
webpackEmptyAsyncContext.resolve = webpackEmptyAsyncContext;
webpackEmptyAsyncContext.id = ${JSON.stringify(id)};
module.exports = webpackEmptyAsyncContext;`;
	}

	/**
	 * @param {string} asyncMode module mode
	 * @param {CodeGenerationContext} context context info
	 * @returns {string} the source code
	 */
	getSourceString(asyncMode, { runtimeTemplate, chunkGraph }) {
		const id = chunkGraph.getModuleId(this);
		if (asyncMode === "lazy") {
			if (this.blocks && this.blocks.length > 0) {
				return this.getLazySource(this.blocks, id, {
					runtimeTemplate,
					chunkGraph
				});
			}
			return this.getSourceForEmptyAsyncContext(id, runtimeTemplate);
		}
		if (asyncMode === "eager") {
			if (this.dependencies && this.dependencies.length > 0) {
				return this.getEagerSource(this.dependencies, id, {
					chunkGraph,
					runtimeTemplate
				});
			}
			return this.getSourceForEmptyAsyncContext(id, runtimeTemplate);
		}
		if (asyncMode === "lazy-once") {
			const block = this.blocks[0];
			if (block) {
				return this.getLazyOnceSource(block, block.dependencies, id, {
					runtimeTemplate,
					chunkGraph
				});
			}
			return this.getSourceForEmptyAsyncContext(id, runtimeTemplate);
		}
		if (asyncMode === "async-weak") {
			if (this.dependencies && this.dependencies.length > 0) {
				return this.getAsyncWeakSource(this.dependencies, id, {
					chunkGraph,
					runtimeTemplate
				});
			}
			return this.getSourceForEmptyAsyncContext(id, runtimeTemplate);
		}
		if (asyncMode === "weak") {
			if (this.dependencies && this.dependencies.length > 0) {
				return this.getWeakSyncSource(this.dependencies, id, chunkGraph);
			}
		}
		if (this.dependencies && this.dependencies.length > 0) {
			return this.getSyncSource(this.dependencies, id, chunkGraph);
		}
		return this.getSourceForEmptyContext(id, runtimeTemplate);
	}

	/**
	 * @param {string} sourceString source content
	 * @param {Compilation=} compilation the compilation
	 * @returns {Source} generated source
	 */
	getSource(sourceString, compilation) {
		if (this.useSourceMap || this.useSimpleSourceMap) {
			return new OriginalSource(
				sourceString,
				`webpack://${makePathsRelative(
					(compilation && compilation.compiler.context) || "",
					this.identifier(),
					compilation && compilation.compiler.root
				)}`
			);
		}
		return new RawSource(sourceString);
	}

	/**
	 * @param {CodeGenerationContext} context context for code generation
	 * @returns {CodeGenerationResult} result
	 */
	codeGeneration(context) {
		const { chunkGraph, compilation } = context;
		const sources = new Map();
		sources.set(
			"javascript",
			this.getSource(
				this.getSourceString(this.options.mode, context),
				compilation
			)
		);
		const set = new Set();
		const allDeps =
			this.dependencies.length > 0
				? /** @type {ContextElementDependency[]} */ (this.dependencies).slice()
				: [];
		for (const block of this.blocks)
			for (const dep of block.dependencies)
				allDeps.push(/** @type {ContextElementDependency} */ (dep));
		set.add(RuntimeGlobals.module);
		set.add(RuntimeGlobals.hasOwnProperty);
		if (allDeps.length > 0) {
			const asyncMode = this.options.mode;
			set.add(RuntimeGlobals.require);
			if (asyncMode === "weak") {
				set.add(RuntimeGlobals.moduleFactories);
			} else if (asyncMode === "async-weak") {
				set.add(RuntimeGlobals.moduleFactories);
				set.add(RuntimeGlobals.ensureChunk);
			} else if (asyncMode === "lazy" || asyncMode === "lazy-once") {
				set.add(RuntimeGlobals.ensureChunk);
			}
			if (this.getFakeMap(allDeps, chunkGraph) !== 9) {
				set.add(RuntimeGlobals.createFakeNamespaceObject);
			}
		}
		return {
			sources,
			runtimeRequirements: set
		};
	}

	/**
	 * @param {string=} type the source type for which the size should be estimated
	 * @returns {number} the estimated size of the module (must be non-zero)
	 */
	size(type) {
		// base penalty
		let size = 160;

		// if we don't have dependencies we stop here.
		for (const dependency of this.dependencies) {
			const element = /** @type {ContextElementDependency} */ (dependency);
			size += 5 + element.userRequest.length;
		}
		return size;
	}

	/**
	 * @param {ObjectSerializerContext} context context
	 */
	serialize(context) {
		const { write } = context;
		write(this._identifier);
		write(this._forceBuild);
		super.serialize(context);
	}

	/**
	 * @param {ObjectDeserializerContext} context context
	 */
	deserialize(context) {
		const { read } = context;
		this._identifier = read();
		this._forceBuild = read();
		super.deserialize(context);
	}
}

makeSerializable(ContextModule, "webpack/lib/ContextModule");

module.exports = ContextModule;


code:
/*
	MIT License http://www.opensource.org/licenses/mit-license.php
	Author Tobias Koppers @sokra
*/

"use strict";

const asyncLib = require("neo-async");
const { AsyncSeriesWaterfallHook, SyncWaterfallHook } = require("tapable");
const ContextModule = require("./ContextModule");
const ModuleFactory = require("./ModuleFactory");
const ContextElementDependency = require("./dependencies/ContextElementDependency");
const LazySet = require("./util/LazySet");
const { cachedSetProperty } = require("./util/cleverMerge");
const { createFakeHook } = require("./util/deprecation");
const { join } = require("./util/fs");

/** @typedef {import("./ContextModule").ContextModuleOptions} ContextModuleOptions */
/** @typedef {import("./ContextModule").ResolveDependenciesCallback} ResolveDependenciesCallback */
/** @typedef {import("./Module")} Module */
/** @typedef {import("./ModuleFactory").ModuleFactoryCreateData} ModuleFactoryCreateData */
/** @typedef {import("./ModuleFactory").ModuleFactoryResult} ModuleFactoryResult */
/** @typedef {import("./ResolverFactory")} ResolverFactory */
/** @typedef {import("./dependencies/ContextDependency")} ContextDependency */
/** @template T @typedef {import("./util/deprecation").FakeHook<T>} FakeHook<T> */
/** @typedef {import("./util/fs").InputFileSystem} InputFileSystem */

const EMPTY_RESOLVE_OPTIONS = {};

module.exports = class ContextModuleFactory extends ModuleFactory {
	/**
	 * @param {ResolverFactory} resolverFactory resolverFactory
	 */
	constructor(resolverFactory) {
		super();
		/** @type {AsyncSeriesWaterfallHook<[TODO[], ContextModuleOptions]>} */
		const alternativeRequests = new AsyncSeriesWaterfallHook([
			"modules",
			"options"
		]);
		this.hooks = Object.freeze({
			/** @type {AsyncSeriesWaterfallHook<[TODO]>} */
			beforeResolve: new AsyncSeriesWaterfallHook(["data"]),
			/** @type {AsyncSeriesWaterfallHook<[TODO]>} */
			afterResolve: new AsyncSeriesWaterfallHook(["data"]),
			/** @type {SyncWaterfallHook<[string[]]>} */
			contextModuleFiles: new SyncWaterfallHook(["files"]),
			/** @type {FakeHook<Pick<AsyncSeriesWaterfallHook<[TODO[]]>, "tap" | "tapAsync" | "tapPromise" | "name">>} */
			alternatives: createFakeHook(
				{
					name: "alternatives",
					/** @type {AsyncSeriesWaterfallHook<[TODO[]]>["intercept"]} */
					intercept: interceptor => {
						throw new Error(
							"Intercepting fake hook ContextModuleFactory.hooks.alternatives is not possible, use ContextModuleFactory.hooks.alternativeRequests instead"
						);
					},
					/** @type {AsyncSeriesWaterfallHook<[TODO[]]>["tap"]} */
					tap: (options, fn) => {
						alternativeRequests.tap(options, fn);
					},
					/** @type {AsyncSeriesWaterfallHook<[TODO[]]>["tapAsync"]} */
					tapAsync: (options, fn) => {
						alternativeRequests.tapAsync(options, (items, _options, callback) =>
							fn(items, callback)
						);
					},
					/** @type {AsyncSeriesWaterfallHook<[TODO[]]>["tapPromise"]} */
					tapPromise: (options, fn) => {
						alternativeRequests.tapPromise(options, fn);
					}
				},
				"ContextModuleFactory.hooks.alternatives has deprecated in favor of ContextModuleFactory.hooks.alternativeRequests with an additional options argument.",
				"DEP_WEBPACK_CONTEXT_MODULE_FACTORY_ALTERNATIVES"
			),
			alternativeRequests
		});
		this.resolverFactory = resolverFactory;
	}

	/**
	 * @param {ModuleFactoryCreateData} data data object
	 * @param {function((Error | null)=, ModuleFactoryResult=): void} callback callback
	 * @returns {void}
	 */
	create(data, callback) {
		const context = data.context;
		const dependencies = data.dependencies;
		const resolveOptions = data.resolveOptions;
		const dependency = /** @type {ContextDependency} */ (dependencies[0]);
		const fileDependencies = new LazySet();
		const missingDependencies = new LazySet();
		const contextDependencies = new LazySet();
		this.hooks.beforeResolve.callAsync(
			{
				context: context,
				dependencies: dependencies,
				layer: data.contextInfo.issuerLayer,
				resolveOptions,
				fileDependencies,
				missingDependencies,
				contextDependencies,
				...dependency.options
			},
			(err, beforeResolveResult) => {
				if (err) {
					return callback(err, {
						fileDependencies,
						missingDependencies,
						contextDependencies
					});
				}

				// Ignored
				if (!beforeResolveResult) {
					return callback(null, {
						fileDependencies,
						missingDependencies,
						contextDependencies
					});
				}

				const context = beforeResolveResult.context;
				const request = beforeResolveResult.request;
				const resolveOptions = beforeResolveResult.resolveOptions;

				let loaders,
					resource,
					loadersPrefix = "";
				const idx = request.lastIndexOf("!");
				if (idx >= 0) {
					let loadersRequest = request.slice(0, idx + 1);
					let i;
					for (
						i = 0;
						i < loadersRequest.length && loadersRequest[i] === "!";
						i++
					) {
						loadersPrefix += "!";
					}
					loadersRequest = loadersRequest
						.slice(i)
						.replace(/!+$/, "")
						.replace(/!!+/g, "!");
					if (loadersRequest === "") {
						loaders = [];
					} else {
						loaders = loadersRequest.split("!");
					}
					resource = request.slice(idx + 1);
				} else {
					loaders = [];
					resource = request;
				}

				const contextResolver = this.resolverFactory.get(
					"context",
					dependencies.length > 0
						? cachedSetProperty(
								resolveOptions || EMPTY_RESOLVE_OPTIONS,
								"dependencyType",
								dependencies[0].category
							)
						: resolveOptions
				);
				const loaderResolver = this.resolverFactory.get("loader");

				asyncLib.parallel(
					[
						callback => {
							const results = [];
							const yield_ = obj => results.push(obj);

							contextResolver.resolve(
								{},
								context,
								resource,
								{
									fileDependencies,
									missingDependencies,
									contextDependencies,
									yield: yield_
								},
								err => {
									if (err) return callback(err);
									callback(null, results);
								}
							);
						},
						callback => {
							asyncLib.map(
								loaders,
								(loader, callback) => {
									loaderResolver.resolve(
										{},
										context,
										loader,
										{
											fileDependencies,
											missingDependencies,
											contextDependencies
										},
										(err, result) => {
											if (err) return callback(err);
											callback(null, result);
										}
									);
								},
								callback
							);
						}
					],
					(err, result) => {
						if (err) {
							return callback(err, {
								fileDependencies,
								missingDependencies,
								contextDependencies
							});
						}
						let [contextResult, loaderResult] = result;
						if (contextResult.length > 1) {
							const first = contextResult[0];
							contextResult = contextResult.filter(r => r.path);
							if (contextResult.length === 0) contextResult.push(first);
						}
						this.hooks.afterResolve.callAsync(
							{
								addon:
									loadersPrefix +
									loaderResult.join("!") +
									(loaderResult.length > 0 ? "!" : ""),
								resource:
									contextResult.length > 1
										? contextResult.map(r => r.path)
										: contextResult[0].path,
								resolveDependencies: this.resolveDependencies.bind(this),
								resourceQuery: contextResult[0].query,
								resourceFragment: contextResult[0].fragment,
								...beforeResolveResult
							},
							(err, result) => {
								if (err) {
									return callback(err, {
										fileDependencies,
										missingDependencies,
										contextDependencies
									});
								}

								// Ignored
								if (!result) {
									return callback(null, {
										fileDependencies,
										missingDependencies,
										contextDependencies
									});
								}

								return callback(null, {
									module: new ContextModule(result.resolveDependencies, result),
									fileDependencies,
									missingDependencies,
									contextDependencies
								});
							}
						);
					}
				);
			}
		);
	}

	/**
	 * @param {InputFileSystem} fs file system
	 * @param {ContextModuleOptions} options options
	 * @param {ResolveDependenciesCallback} callback callback function
	 * @returns {void}
	 */
	resolveDependencies(fs, options, callback) {
		const cmf = this;
		const {
			resource,
			resourceQuery,
			resourceFragment,
			recursive,
			regExp,
			include,
			exclude,
			referencedExports,
			category,
			typePrefix,
			attributes
		} = options;
		if (!regExp || !resource) return callback(null, []);

		const addDirectoryChecked = (ctx, directory, visited, callback) => {
			fs.realpath(directory, (err, realPath) => {
				if (err) return callback(err);
				if (visited.has(realPath)) return callback(null, []);
				let recursionStack;
				addDirectory(
					ctx,
					directory,
					(_, dir, callback) => {
						if (recursionStack === undefined) {
							recursionStack = new Set(visited);
							recursionStack.add(realPath);
						}
						addDirectoryChecked(ctx, dir, recursionStack, callback);
					},
					callback
				);
			});
		};

		const addDirectory = (ctx, directory, addSubDirectory, callback) => {
			fs.readdir(directory, (err, files) => {
				if (err) return callback(err);
				const processedFiles = cmf.hooks.contextModuleFiles.call(
					/** @type {string[]} */ (files).map(file => file.normalize("NFC"))
				);
				if (!processedFiles || processedFiles.length === 0)
					return callback(null, []);
				asyncLib.map(
					processedFiles.filter(p => p.indexOf(".") !== 0),
					(segment, callback) => {
						const subResource = join(fs, directory, segment);

						if (!exclude || !subResource.match(exclude)) {
							fs.stat(subResource, (err, stat) => {
								if (err) {
									if (err.code === "ENOENT") {
										// ENOENT is ok here because the file may have been deleted between
										// the readdir and stat calls.
										return callback();
									} else {
										return callback(err);
									}
								}

								if (stat.isDirectory()) {
									if (!recursive) return callback();
									addSubDirectory(ctx, subResource, callback);
								} else if (
									stat.isFile() &&
									(!include || subResource.match(include))
								) {
									const obj = {
										context: ctx,
										request:
											"." + subResource.slice(ctx.length).replace(/\\/g, "/")
									};

									this.hooks.alternativeRequests.callAsync(
										[obj],
										options,
										(err, alternatives) => {
											if (err) return callback(err);
											alternatives = alternatives
												.filter(obj => regExp.test(obj.request))
												.map(obj => {
													const dep = new ContextElementDependency(
														`${obj.request}${resourceQuery}${resourceFragment}`,
														obj.request,
														typePrefix,
														category,
														referencedExports,
														obj.context,
														attributes
													);
													dep.optional = true;
													return dep;
												});
											callback(null, alternatives);
										}
									);
								} else {
									callback();
								}
							});
						} else {
							callback();
						}
					},
					(err, result) => {
						if (err) return callback(err);

						if (!result) return callback(null, []);

						const flattenedResult = [];

						for (const item of result) {
							if (item) flattenedResult.push(...item);
						}

						callback(null, flattenedResult);
					}
				);
			});
		};

		const addSubDirectory = (ctx, dir, callback) =>
			addDirectory(ctx, dir, addSubDirectory, callback);

		const visitResource = (resource, callback) => {
			if (typeof fs.realpath === "function") {
				addDirectoryChecked(resource, resource, new Set(), callback);
			} else {
				addDirectory(resource, resource, addSubDirectory, callback);
			}
		};

		if (typeof resource === "string") {
			visitResource(resource, callback);
		} else {
			asyncLib.map(resource, visitResource, (err, result) => {
				if (err) return callback(err);

				// result dependencies should have unique userRequest
				// ordered by resolve result
				const temp = new Set();
				const res = [];
				for (let i = 0; i < result.length; i++) {
					const inner = result[i];
					for (const el of inner) {
						if (temp.has(el.userRequest)) continue;
						res.push(el);
						temp.add(el.userRequest);
					}
				}
				callback(null, res);
			});
		}
	}
};

license: mit


code:
/*
	MIT License http://www.opensource.org/licenses/mit-license.php
	Author Tobias Koppers @sokra
*/

"use strict";

const ContextElementDependency = require("./dependencies/ContextElementDependency");
const { join } = require("./util/fs");

/** @typedef {import("./Compiler")} Compiler */
/** @typedef {import("./util/fs").InputFileSystem} InputFileSystem */

class ContextReplacementPlugin {
	/**
	 * @param {RegExp} resourceRegExp A regular expression that determines which files will be selected
	 * @param {TODO=} newContentResource A new resource to replace the match
	 * @param {TODO=} newContentRecursive If true, all subdirectories are searched for matches
	 * @param {TODO=} newContentRegExp A regular expression that determines which files will be selected
	 */
	constructor(
		resourceRegExp,
		newContentResource,
		newContentRecursive,
		newContentRegExp
	) {
		this.resourceRegExp = resourceRegExp;

		if (typeof newContentResource === "function") {
			this.newContentCallback = newContentResource;
		} else if (
			typeof newContentResource === "string" &&
			typeof newContentRecursive === "object"
		) {
			this.newContentResource = newContentResource;
			this.newContentCreateContextMap = (fs, callback) => {
				callback(null, newContentRecursive);
			};
		} else if (
			typeof newContentResource === "string" &&
			typeof newContentRecursive === "function"
		) {
			this.newContentResource = newContentResource;
			this.newContentCreateContextMap = newContentRecursive;
		} else {
			if (typeof newContentResource !== "string") {
				newContentRegExp = newContentRecursive;
				newContentRecursive = newContentResource;
				newContentResource = undefined;
			}
			if (typeof newContentRecursive !== "boolean") {
				newContentRegExp = newContentRecursive;
				newContentRecursive = undefined;
			}
			this.newContentResource = newContentResource;
			this.newContentRecursive = newContentRecursive;
			this.newContentRegExp = newContentRegExp;
		}
	}

	/**
	 * Apply the plugin
	 * @param {Compiler} compiler the compiler instance
	 * @returns {void}
	 */
	apply(compiler) {
		const resourceRegExp = this.resourceRegExp;
		const newContentCallback = this.newContentCallback;
		const newContentResource = this.newContentResource;
		const newContentRecursive = this.newContentRecursive;
		const newContentRegExp = this.newContentRegExp;
		const newContentCreateContextMap = this.newContentCreateContextMap;

		compiler.hooks.contextModuleFactory.tap("ContextReplacementPlugin", cmf => {
			cmf.hooks.beforeResolve.tap("ContextReplacementPlugin", result => {
				if (!result) return;
				if (resourceRegExp.test(result.request)) {
					if (newContentResource !== undefined) {
						result.request = newContentResource;
					}
					if (newContentRecursive !== undefined) {
						result.recursive = newContentRecursive;
					}
					if (newContentRegExp !== undefined) {
						result.regExp = newContentRegExp;
					}
					if (typeof newContentCallback === "function") {
						newContentCallback(result);
					} else {
						for (const d of result.dependencies) {
							if (d.critical) d.critical = false;
						}
					}
				}
				return result;
			});
			cmf.hooks.afterResolve.tap("ContextReplacementPlugin", result => {
				if (!result) return;
				if (resourceRegExp.test(result.resource)) {
					if (newContentResource !== undefined) {
						if (
							newContentResource.startsWith("/") ||
							(newContentResource.length > 1 && newContentResource[1] === ":")
						) {
							result.resource = newContentResource;
						} else {
							result.resource = join(
								/** @type {InputFileSystem} */ (compiler.inputFileSystem),
								result.resource,
								newContentResource
							);
						}
					}
					if (newContentRecursive !== undefined) {
						result.recursive = newContentRecursive;
					}
					if (newContentRegExp !== undefined) {
						result.regExp = newContentRegExp;
					}
					if (typeof newContentCreateContextMap === "function") {
						result.resolveDependencies =
							createResolveDependenciesFromContextMap(
								newContentCreateContextMap
							);
					}
					if (typeof newContentCallback === "function") {
						const origResource = result.resource;
						newContentCallback(result);
						if (
							result.resource !== origResource &&
							!result.resource.startsWith("/") &&
							(result.resource.length <= 1 || result.resource[1] !== ":")
						) {
							// When the function changed it to an relative path
							result.resource = join(
								/** @type {InputFileSystem} */ (compiler.inputFileSystem),
								origResource,
								result.resource
							);
						}
					} else {
						for (const d of result.dependencies) {
							if (d.critical) d.critical = false;
						}
					}
				}
				return result;
			});
		});
	}
}

const createResolveDependenciesFromContextMap = createContextMap => {
	const resolveDependenciesFromContextMap = (fs, options, callback) => {
		createContextMap(fs, (err, map) => {
			if (err) return callback(err);
			const dependencies = Object.keys(map).map(key => {
				return new ContextElementDependency(
					map[key] + options.resourceQuery + options.resourceFragment,
					key,
					options.category,
					options.referencedExports
				);
			});
			callback(null, dependencies);
		});
	};
	return resolveDependenciesFromContextMap;
};

module.exports = ContextReplacementPlugin;


code:
/*
	MIT License http://www.opensource.org/licenses/mit-license.php
	Author Alexander Krasnoyarov @alexander-akait
*/

"use strict";

const NormalModule = require("./NormalModule");
const makeSerializable = require("./util/makeSerializable");

/** @typedef {import("./Module")} Module */
/** @typedef {import("./NormalModule").NormalModuleCreateData} NormalModuleCreateData */
/** @typedef {import("./RequestShortener")} RequestShortener */
/** @typedef {import("./serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */
/** @typedef {import("./serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */

/** @typedef {string|undefined} CssLayer */
/** @typedef {string|undefined} Supports */
/** @typedef {string|undefined} Media */
/** @typedef {[CssLayer?, Supports?, Media?]} InheritanceItem */
/** @typedef {Array<InheritanceItem>} Inheritance */

/** @typedef {NormalModuleCreateData & { cssLayer: CssLayer|null, supports: Supports|null, media: Media|null, inheritance: Inheritance|null }} CSSModuleCreateData */

class CssModule extends NormalModule {
	/**
	 * @param {CSSModuleCreateData} options options object
	 */
	constructor(options) {
		super(options);

		// Avoid override `layer` for `Module` class, because it is a feature to run module in specific layer
		this.cssLayer = options.cssLayer;
		this.supports = options.supports;
		this.media = options.media;
		this.inheritance = options.inheritance;
	}

	/**
	 * @returns {string} a unique identifier of the module
	 */
	identifier() {
		let identifier = super.identifier();

		if (this.cssLayer) {
			identifier += `|${this.cssLayer}`;
		}

		if (this.supports) {
			identifier += `|${this.supports}`;
		}

		if (this.media) {
			identifier += `|${this.media}`;
		}

		if (this.inheritance) {
			const inheritance = this.inheritance.map(
				(item, index) =>
					`inheritance_${index}|${item[0] || ""}|${item[1] || ""}|${
						item[2] || ""
					}`
			);

			identifier += `|${inheritance.join("|")}`;
		}

		return identifier;
	}

	/**
	 * @param {RequestShortener} requestShortener the request shortener
	 * @returns {string} a user readable identifier of the module
	 */
	readableIdentifier(requestShortener) {
		const readableIdentifier = super.readableIdentifier(requestShortener);

		let identifier = `css ${readableIdentifier}`;

		if (this.cssLayer) {
			identifier += ` (layer: ${this.cssLayer})`;
		}

		if (this.supports) {
			identifier += ` (supports: ${this.supports})`;
		}

		if (this.media) {
			identifier += ` (media: ${this.media})`;
		}

		return identifier;
	}

	/**
	 * Assuming this module is in the cache. Update the (cached) module with
	 * the fresh module from the factory. Usually updates internal references
	 * and properties.
	 * @param {Module} module fresh module
	 * @returns {void}
	 */
	updateCacheModule(module) {
		super.updateCacheModule(module);
		const m = /** @type {CssModule} */ (module);
		this.cssLayer = m.cssLayer;
		this.supports = m.supports;
		this.media = m.media;
		this.inheritance = m.inheritance;
	}

	/**
	 * @param {ObjectSerializerContext} context context
	 */
	serialize(context) {
		const { write } = context;
		write(this.cssLayer);
		write(this.supports);
		write(this.media);
		write(this.inheritance);
		super.serialize(context);
	}

	/**
	 * @param {ObjectDeserializerContext} context context
	 * @returns {CssModule} the deserialized object
	 */
	static deserialize(context) {
		const obj = new CssModule({
			// will be deserialized by Module
			layer: null,
			type: "",
			// will be filled by updateCacheModule
			resource: "",
			context: "",
			request: null,
			userRequest: null,
			rawRequest: null,
			loaders: null,
			matchResource: null,
			parser: null,
			parserOptions: null,
			generator: null,
			generatorOptions: null,
			resolveOptions: null,
			cssLayer: null,
			supports: null,
			media: null,
			inheritance: null
		});
		obj.deserialize(context);
		return obj;
	}

	deserialize(context) {
		const { read } = context;
		this.cssLayer = read();
		this.supports = read();
		this.media = read();
		this.inheritance = read();
		super.deserialize(context);
	}
}

makeSerializable(CssModule, "webpack/lib/CssModule");

module.exports = CssModule;


code:
/*
	MIT License http://www.opensource.org/licenses/mit-license.php
	Author Tobias Koppers @sokra
*/

"use strict";

const {
	JAVASCRIPT_MODULE_TYPE_AUTO,
	JAVASCRIPT_MODULE_TYPE_ESM,
	JAVASCRIPT_MODULE_TYPE_DYNAMIC
} = require("./ModuleTypeConstants");
const RuntimeGlobals = require("./RuntimeGlobals");
const WebpackError = require("./WebpackError");
const ConstDependency = require("./dependencies/ConstDependency");
const BasicEvaluatedExpression = require("./javascript/BasicEvaluatedExpression");

const {
	evaluateToString,
	toConstantDependency
} = require("./javascript/JavascriptParserHelpers");
const createHash = require("./util/createHash");

/** @typedef {import("estree").Expression} Expression */
/** @typedef {import("./Compiler")} Compiler */
/** @typedef {import("./Module").BuildInfo} BuildInfo */
/** @typedef {import("./NormalModule")} NormalModule */
/** @typedef {import("./RuntimeTemplate")} RuntimeTemplate */
/** @typedef {import("./javascript/JavascriptParser")} JavascriptParser */
/** @typedef {import("./javascript/JavascriptParser").DestructuringAssignmentProperty} DestructuringAssignmentProperty */
/** @typedef {import("./javascript/JavascriptParser").Range} Range */
/** @typedef {import("./logging/Logger").Logger} Logger */

/** @typedef {null|undefined|RegExp|Function|string|number|boolean|bigint|undefined} CodeValuePrimitive */
/** @typedef {RecursiveArrayOrRecord<CodeValuePrimitive|RuntimeValue>} CodeValue */

/**
 * @typedef {object} RuntimeValueOptions
 * @property {string[]=} fileDependencies
 * @property {string[]=} contextDependencies
 * @property {string[]=} missingDependencies
 * @property {string[]=} buildDependencies
 * @property {string|function(): string=} version
 */

class RuntimeValue {
	/**
	 * @param {function({ module: NormalModule, key: string, readonly version: string | undefined }): CodeValuePrimitive} fn generator function
	 * @param {true | string[] | RuntimeValueOptions=} options options
	 */
	constructor(fn, options) {
		this.fn = fn;
		if (Array.isArray(options)) {
			options = {
				fileDependencies: options
			};
		}
		this.options = options || {};
	}

	get fileDependencies() {
		return this.options === true ? true : this.options.fileDependencies;
	}

	/**
	 * @param {JavascriptParser} parser the parser
	 * @param {Map<string, string | Set<string>>} valueCacheVersions valueCacheVersions
	 * @param {string} key the defined key
	 * @returns {CodeValuePrimitive} code
	 */
	exec(parser, valueCacheVersions, key) {
		const buildInfo = /** @type {BuildInfo} */ (parser.state.module.buildInfo);
		if (this.options === true) {
			buildInfo.cacheable = false;
		} else {
			if (this.options.fileDependencies) {
				for (const dep of this.options.fileDependencies) {
					buildInfo.fileDependencies.add(dep);
				}
			}
			if (this.options.contextDependencies) {
				for (const dep of this.options.contextDependencies) {
					buildInfo.contextDependencies.add(dep);
				}
			}
			if (this.options.missingDependencies) {
				for (const dep of this.options.missingDependencies) {
					buildInfo.missingDependencies.add(dep);
				}
			}
			if (this.options.buildDependencies) {
				for (const dep of this.options.buildDependencies) {
					buildInfo.buildDependencies.add(dep);
				}
			}
		}

		return this.fn({
			module: parser.state.module,
			key,
			get version() {
				return /** @type {string} */ (
					valueCacheVersions.get(VALUE_DEP_PREFIX + key)
				);
			}
		});
	}

	getCacheVersion() {
		return this.options === true
			? undefined
			: (typeof this.options.version === "function"
					? this.options.version()
					: this.options.version) || "unset";
	}
}

/**
 * @param {Set<DestructuringAssignmentProperty> | undefined} properties properties
 * @returns {Set<string> | undefined} used keys
 */
function getObjKeys(properties) {
	if (!properties) return undefined;
	return new Set([...properties].map(p => p.id));
}

/**
 * @param {any[]|{[k: string]: any}} obj obj
 * @param {JavascriptParser} parser Parser
 * @param {Map<string, string | Set<string>>} valueCacheVersions valueCacheVersions
 * @param {string} key the defined key
 * @param {RuntimeTemplate} runtimeTemplate the runtime template
 * @param {Logger} logger the logger object
 * @param {boolean|undefined|null=} asiSafe asi safe (undefined: unknown, null: unneeded)
 * @param {Set<string>|undefined=} objKeys used keys
 * @returns {string} code converted to string that evaluates
 */
const stringifyObj = (
	obj,
	parser,
	valueCacheVersions,
	key,
	runtimeTemplate,
	logger,
	asiSafe,
	objKeys
) => {
	let code;
	let arr = Array.isArray(obj);
	if (arr) {
		code = `[${
			/** @type {any[]} */ (obj)
				.map(code =>
					toCode(
						code,
						parser,
						valueCacheVersions,
						key,
						runtimeTemplate,
						logger,
						null
					)
				)
				.join(",")
		}]`;
	} else {
		let keys = Object.keys(obj);
		if (objKeys) {
			if (objKeys.size === 0) keys = [];
			else keys = keys.filter(k => objKeys.has(k));
		}
		code = `{${keys
			.map(key => {
				const code = /** @type {{[k: string]: any}} */ (obj)[key];
				return (
					JSON.stringify(key) +
					":" +
					toCode(
						code,
						parser,
						valueCacheVersions,
						key,
						runtimeTemplate,
						logger,
						null
					)
				);
			})
			.join(",")}}`;
	}

	switch (asiSafe) {
		case null:
			return code;
		case true:
			return arr ? code : `(${code})`;
		case false:
			return arr ? `;${code}` : `;(${code})`;
		default:
			return `/*#__PURE__*/Object(${code})`;
	}
};

/**
 * Convert code to a string that evaluates
 * @param {CodeValue} code Code to evaluate
 * @param {JavascriptParser} parser Parser
 * @param {Map<string, string | Set<string>>} valueCacheVersions valueCacheVersions
 * @param {string} key the defined key
 * @param {RuntimeTemplate} runtimeTemplate the runtime template
 * @param {Logger} logger the logger object
 * @param {boolean|undefined|null=} asiSafe asi safe (undefined: unknown, null: unneeded)
 * @param {Set<string>|undefined=} objKeys used keys
 * @returns {string} code converted to string that evaluates
 */
const toCode = (
	code,
	parser,
	valueCacheVersions,
	key,
	runtimeTemplate,
	logger,
	asiSafe,
	objKeys
) => {
	const transformToCode = () => {
		if (code === null) {
			return "null";
		}
		if (code === undefined) {
			return "undefined";
		}
		if (Object.is(code, -0)) {
			return "-0";
		}
		if (code instanceof RuntimeValue) {
			return toCode(
				code.exec(parser, valueCacheVersions, key),
				parser,
				valueCacheVersions,
				key,
				runtimeTemplate,
				logger,
				asiSafe
			);
		}
		if (code instanceof RegExp && code.toString) {
			return code.toString();
		}
		if (typeof code === "function" && code.toString) {
			return "(" + code.toString() + ")";
		}
		if (typeof code === "object") {
			return stringifyObj(
				code,
				parser,
				valueCacheVersions,
				key,
				runtimeTemplate,
				logger,
				asiSafe,
				objKeys
			);
		}
		if (typeof code === "bigint") {
			return runtimeTemplate.supportsBigIntLiteral()
				? `${code}n`
				: `BigInt("${code}")`;
		}
		return code + "";
	};

	const strCode = transformToCode();

	logger.log(`Replaced "${key}" with "${strCode}"`);

	return strCode;
};

/**
 * @param {CodeValue} code code
 * @returns {string | undefined} result
 */
const toCacheVersion = code => {
	if (code === null) {
		return "null";
	}
	if (code === undefined) {
		return "undefined";
	}
	if (Object.is(code, -0)) {
		return "-0";
	}
	if (code instanceof RuntimeValue) {
		return code.getCacheVersion();
	}
	if (code instanceof RegExp && code.toString) {
		return code.toString();
	}
	if (typeof code === "function" && code.toString) {
		return "(" + code.toString() + ")";
	}
	if (typeof code === "object") {
		const items = Object.keys(code).map(key => ({
			key,
			value: toCacheVersion(/** @type {Record<string, any>} */ (code)[key])
		}));
		if (items.some(({ value }) => value === undefined)) return undefined;
		return `{${items.map(({ key, value }) => `${key}: ${value}`).join(", ")}}`;
	}
	if (typeof code === "bigint") {
		return `${code}n`;
	}
	return code + "";
};

const PLUGIN_NAME = "DefinePlugin";
const VALUE_DEP_PREFIX = `webpack/${PLUGIN_NAME} `;
const VALUE_DEP_MAIN = `webpack/${PLUGIN_NAME}_hash`;
const TYPEOF_OPERATOR_REGEXP = /^typeof\s+/;
const WEBPACK_REQUIRE_FUNCTION_REGEXP = new RegExp(
	`${RuntimeGlobals.require}\\s*(!?\\.)`
);
const WEBPACK_REQUIRE_IDENTIFIER_REGEXP = new RegExp(RuntimeGlobals.require);

class DefinePlugin {
	/**
	 * Create a new define plugin
	 * @param {Record<string, CodeValue>} definitions A map of global object definitions
	 */
	constructor(definitions) {
		this.definitions = definitions;
	}

	/**
	 * @param {function({ module: NormalModule, key: string, readonly version: string | undefined }): CodeValuePrimitive} fn generator function
	 * @param {true | string[] | RuntimeValueOptions=} options options
	 * @returns {RuntimeValue} runtime value
	 */
	static runtimeValue(fn, options) {
		return new RuntimeValue(fn, options);
	}

	/**
	 * Apply the plugin
	 * @param {Compiler} compiler the compiler instance
	 * @returns {void}
	 */
	apply(compiler) {
		const definitions = this.definitions;
		compiler.hooks.compilation.tap(
			PLUGIN_NAME,
			(compilation, { normalModuleFactory }) => {
				const logger = compilation.getLogger("webpack.DefinePlugin");
				compilation.dependencyTemplates.set(
					ConstDependency,
					new ConstDependency.Template()
				);
				const { runtimeTemplate } = compilation;

				const mainHash = createHash(compilation.outputOptions.hashFunction);
				mainHash.update(
					/** @type {string} */ (
						compilation.valueCacheVersions.get(VALUE_DEP_MAIN)
					) || ""
				);

				/**
				 * Handler
				 * @param {JavascriptParser} parser Parser
				 * @returns {void}
				 */
				const handler = parser => {
					const mainValue = compilation.valueCacheVersions.get(VALUE_DEP_MAIN);
					parser.hooks.program.tap(PLUGIN_NAME, () => {
						const buildInfo = /** @type {BuildInfo} */ (
							parser.state.module.buildInfo
						);
						if (!buildInfo.valueDependencies)
							buildInfo.valueDependencies = new Map();
						buildInfo.valueDependencies.set(VALUE_DEP_MAIN, mainValue);
					});

					/**
					 * @param {string} key key
					 */
					const addValueDependency = key => {
						const buildInfo = /** @type {BuildInfo} */ (
							parser.state.module.buildInfo
						);
						buildInfo.valueDependencies.set(
							VALUE_DEP_PREFIX + key,
							compilation.valueCacheVersions.get(VALUE_DEP_PREFIX + key)
						);
					};

					const withValueDependency =
						(key, fn) =>
						(...args) => {
							addValueDependency(key);
							return fn(...args);
						};

					/**
					 * Walk definitions
					 * @param {Record<string, CodeValue>} definitions Definitions map
					 * @param {string} prefix Prefix string
					 * @returns {void}
					 */
					const walkDefinitions = (definitions, prefix) => {
						Object.keys(definitions).forEach(key => {
							const code = definitions[key];
							if (
								code &&
								typeof code === "object" &&
								!(code instanceof RuntimeValue) &&
								!(code instanceof RegExp)
							) {
								walkDefinitions(
									/** @type {Record<string, CodeValue>} */ (code),
									prefix + key + "."
								);
								applyObjectDefine(prefix + key, code);
								return;
							}
							applyDefineKey(prefix, key);
							applyDefine(prefix + key, code);
						});
					};

					/**
					 * Apply define key
					 * @param {string} prefix Prefix
					 * @param {string} key Key
					 * @returns {void}
					 */
					const applyDefineKey = (prefix, key) => {
						const splittedKey = key.split(".");
						splittedKey.slice(1).forEach((_, i) => {
							const fullKey = prefix + splittedKey.slice(0, i + 1).join(".");
							parser.hooks.canRename.for(fullKey).tap(PLUGIN_NAME, () => {
								addValueDependency(key);
								return true;
							});
						});
					};

					/**
					 * Apply Code
					 * @param {string} key Key
					 * @param {CodeValue} code Code
					 * @returns {void}
					 */
					const applyDefine = (key, code) => {
						const originalKey = key;
						const isTypeof = TYPEOF_OPERATOR_REGEXP.test(key);
						if (isTypeof) key = key.replace(TYPEOF_OPERATOR_REGEXP, "");
						let recurse = false;
						let recurseTypeof = false;
						if (!isTypeof) {
							parser.hooks.canRename.for(key).tap(PLUGIN_NAME, () => {
								addValueDependency(originalKey);
								return true;
							});
							parser.hooks.evaluateIdentifier
								.for(key)
								.tap(PLUGIN_NAME, expr => {
									/**
									 * this is needed in case there is a recursion in the DefinePlugin
									 * to prevent an endless recursion
									 * e.g.: new DefinePlugin({
									 * "a": "b",
									 * "b": "a"
									 * });
									 */
									if (recurse) return;
									addValueDependency(originalKey);
									recurse = true;
									const res = parser.evaluate(
										toCode(
											code,
											parser,
											compilation.valueCacheVersions,
											key,
											runtimeTemplate,
											logger,
											null
										)
									);
									recurse = false;
									res.setRange(/** @type {Range} */ (expr.range));
									return res;
								});
							parser.hooks.expression.for(key).tap(PLUGIN_NAME, expr => {
								addValueDependency(originalKey);
								let strCode = toCode(
									code,
									parser,
									compilation.valueCacheVersions,
									originalKey,
									runtimeTemplate,
									logger,
									!parser.isAsiPosition(/** @type {Range} */ (expr.range)[0]),
									null
								);

								if (parser.scope.inShorthand) {
									strCode = parser.scope.inShorthand + ":" + strCode;
								}

								if (WEBPACK_REQUIRE_FUNCTION_REGEXP.test(strCode)) {
									return toConstantDependency(parser, strCode, [
										RuntimeGlobals.require
									])(expr);
								} else if (WEBPACK_REQUIRE_IDENTIFIER_REGEXP.test(strCode)) {
									return toConstantDependency(parser, strCode, [
										RuntimeGlobals.requireScope
									])(expr);
								} else {
									return toConstantDependency(parser, strCode)(expr);
								}
							});
						}
						parser.hooks.evaluateTypeof.for(key).tap(PLUGIN_NAME, expr => {
							/**
							 * this is needed in case there is a recursion in the DefinePlugin
							 * to prevent an endless recursion
							 * e.g.: new DefinePlugin({
							 * "typeof a": "typeof b",
							 * "typeof b": "typeof a"
							 * });
							 */
							if (recurseTypeof) return;
							recurseTypeof = true;
							addValueDependency(originalKey);
							const codeCode = toCode(
								code,
								parser,
								compilation.valueCacheVersions,
								originalKey,
								runtimeTemplate,
								logger,
								null
							);
							const typeofCode = isTypeof
								? codeCode
								: "typeof (" + codeCode + ")";
							const res = parser.evaluate(typeofCode);
							recurseTypeof = false;
							res.setRange(/** @type {Range} */ (expr.range));
							return res;
						});
						parser.hooks.typeof.for(key).tap(PLUGIN_NAME, expr => {
							addValueDependency(originalKey);
							const codeCode = toCode(
								code,
								parser,
								compilation.valueCacheVersions,
								originalKey,
								runtimeTemplate,
								logger,
								null
							);
							const typeofCode = isTypeof
								? codeCode
								: "typeof (" + codeCode + ")";
							const res = parser.evaluate(typeofCode);
							if (!res.isString()) return;
							return toConstantDependency(
								parser,
								JSON.stringify(res.string)
							).bind(parser)(expr);
						});
					};

					/**
					 * Apply Object
					 * @param {string} key Key
					 * @param {object} obj Object
					 * @returns {void}
					 */
					const applyObjectDefine = (key, obj) => {
						parser.hooks.canRename.for(key).tap(PLUGIN_NAME, () => {
							addValueDependency(key);
							return true;
						});
						parser.hooks.evaluateIdentifier.for(key).tap(PLUGIN_NAME, expr => {
							addValueDependency(key);
							return new BasicEvaluatedExpression()
								.setTruthy()
								.setSideEffects(false)
								.setRange(/** @type {Range} */ (expr.range));
						});
						parser.hooks.evaluateTypeof
							.for(key)
							.tap(
								PLUGIN_NAME,
								withValueDependency(key, evaluateToString("object"))
							);
						parser.hooks.expression.for(key).tap(PLUGIN_NAME, expr => {
							addValueDependency(key);
							let strCode = stringifyObj(
								obj,
								parser,
								compilation.valueCacheVersions,
								key,
								runtimeTemplate,
								logger,
								!parser.isAsiPosition(/** @type {Range} */ (expr.range)[0]),
								getObjKeys(parser.destructuringAssignmentPropertiesFor(expr))
							);

							if (parser.scope.inShorthand) {
								strCode = parser.scope.inShorthand + ":" + strCode;
							}

							if (WEBPACK_REQUIRE_FUNCTION_REGEXP.test(strCode)) {
								return toConstantDependency(parser, strCode, [
									RuntimeGlobals.require
								])(expr);
							} else if (WEBPACK_REQUIRE_IDENTIFIER_REGEXP.test(strCode)) {
								return toConstantDependency(parser, strCode, [
									RuntimeGlobals.requireScope
								])(expr);
							} else {
								return toConstantDependency(parser, strCode)(expr);
							}
						});
						parser.hooks.typeof
							.for(key)
							.tap(
								PLUGIN_NAME,
								withValueDependency(
									key,
									toConstantDependency(parser, JSON.stringify("object"))
								)
							);
					};

					walkDefinitions(definitions, "");
				};

				normalModuleFactory.hooks.parser
					.for(JAVASCRIPT_MODULE_TYPE_AUTO)
					.tap(PLUGIN_NAME, handler);
				normalModuleFactory.hooks.parser
					.for(JAVASCRIPT_MODULE_TYPE_DYNAMIC)
					.tap(PLUGIN_NAME, handler);
				normalModuleFactory.hooks.parser
					.for(JAVASCRIPT_MODULE_TYPE_ESM)
					.tap(PLUGIN_NAME, handler);

				/**
				 * Walk definitions
				 * @param {Record<string, CodeValue>} definitions Definitions map
				 * @param {string} prefix Prefix string
				 * @returns {void}
				 */
				const walkDefinitionsForValues = (definitions, prefix) => {
					Object.keys(definitions).forEach(key => {
						const code = definitions[key];
						const version = toCacheVersion(code);
						const name = VALUE_DEP_PREFIX + prefix + key;
						mainHash.update("|" + prefix + key);
						const oldVersion = compilation.valueCacheVersions.get(name);
						if (oldVersion === undefined) {
							compilation.valueCacheVersions.set(name, version);
						} else if (oldVersion !== version) {
							const warning = new WebpackError(
								`${PLUGIN_NAME}\nConflicting values for '${prefix + key}'`
							);
							warning.details = `'${oldVersion}' !== '${version}'`;
							warning.hideStack = true;
							compilation.warnings.push(warning);
						}
						if (
							code &&
							typeof code === "object" &&
							!(code instanceof RuntimeValue) &&
							!(code instanceof RegExp)
						) {
							walkDefinitionsForValues(
								/** @type {Record<string, CodeValue>} */ (code),
								prefix + key + "."
							);
						}
					});
				};

				walkDefinitionsForValues(definitions, "");

				compilation.valueCacheVersions.set(
					VALUE_DEP_MAIN,
					/** @type {string} */ (mainHash.digest("hex").slice(0, 8))
				);
			}
		);
	}
}
module.exports = DefinePlugin;


code:
/*
	MIT License http://www.opensource.org/licenses/mit-license.php
	Author Tobias Koppers @sokra
*/

"use strict";

const { OriginalSource, RawSource } = require("webpack-sources");
const Module = require("./Module");
const { JAVASCRIPT_MODULE_TYPE_DYNAMIC } = require("./ModuleTypeConstants");
const RuntimeGlobals = require("./RuntimeGlobals");
const DelegatedSourceDependency = require("./dependencies/DelegatedSourceDependency");
const StaticExportsDependency = require("./dependencies/StaticExportsDependency");
const makeSerializable = require("./util/makeSerializable");

/** @typedef {import("webpack-sources").Source} Source */
/** @typedef {import("../declarations/WebpackOptions").WebpackOptionsNormalized} WebpackOptions */
/** @typedef {import("./ChunkGraph")} ChunkGraph */
/** @typedef {import("./Compilation")} Compilation */
/** @typedef {import("./Dependency").UpdateHashContext} UpdateHashContext */
/** @typedef {import("./DependencyTemplates")} DependencyTemplates */
/** @typedef {import("./LibManifestPlugin").ManifestModuleData} ManifestModuleData */
/** @typedef {import("./Module").CodeGenerationContext} CodeGenerationContext */
/** @typedef {import("./Module").CodeGenerationResult} CodeGenerationResult */
/** @typedef {import("./Module").LibIdentOptions} LibIdentOptions */
/** @typedef {import("./Module").NeedBuildContext} NeedBuildContext */
/** @typedef {import("./Module").SourceContext} SourceContext */
/** @typedef {import("./Module").SourceTypes} SourceTypes */
/** @typedef {import("./RequestShortener")} RequestShortener */
/** @typedef {import("./ResolverFactory").ResolverWithOptions} ResolverWithOptions */
/** @typedef {import("./RuntimeTemplate")} RuntimeTemplate */
/** @typedef {import("./WebpackError")} WebpackError */
/** @typedef {import("./dependencies/ModuleDependency")} ModuleDependency */
/** @typedef {import("./serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */
/** @typedef {import("./serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */
/** @typedef {import("./util/Hash")} Hash */
/** @typedef {import("./util/fs").InputFileSystem} InputFileSystem */

const TYPES = new Set(["javascript"]);
const RUNTIME_REQUIREMENTS = new Set([
	RuntimeGlobals.module,
	RuntimeGlobals.require
]);

class DelegatedModule extends Module {
	/**
	 * @param {string} sourceRequest source request
	 * @param {TODO} data data
	 * @param {"require" | "object"} type type
	 * @param {string} userRequest user request
	 * @param {string | Module} originalRequest original request
	 */
	constructor(sourceRequest, data, type, userRequest, originalRequest) {
		super(JAVASCRIPT_MODULE_TYPE_DYNAMIC, null);

		// Info from Factory
		this.sourceRequest = sourceRequest;
		this.request = data.id;
		this.delegationType = type;
		this.userRequest = userRequest;
		this.originalRequest = originalRequest;
		/** @type {ManifestModuleData | undefined} */
		this.delegateData = data;

		// Build info
		this.delegatedSourceDependency = undefined;
	}

	/**
	 * @returns {SourceTypes} types available (do not mutate)
	 */
	getSourceTypes() {
		return TYPES;
	}

	/**
	 * @param {LibIdentOptions} options options
	 * @returns {string | null} an identifier for library inclusion
	 */
	libIdent(options) {
		return typeof this.originalRequest === "string"
			? this.originalRequest
			: this.originalRequest.libIdent(options);
	}

	/**
	 * @returns {string} a unique identifier of the module
	 */
	identifier() {
		return `delegated ${JSON.stringify(this.request)} from ${
			this.sourceRequest
		}`;
	}

	/**
	 * @param {RequestShortener} requestShortener the request shortener
	 * @returns {string} a user readable identifier of the module
	 */
	readableIdentifier(requestShortener) {
		return `delegated ${this.userRequest} from ${this.sourceRequest}`;
	}

	/**
	 * @param {NeedBuildContext} context context info
	 * @param {function((WebpackError | null)=, boolean=): void} callback callback function, returns true, if the module needs a rebuild
	 * @returns {void}
	 */
	needBuild(context, callback) {
		return callback(null, !this.buildMeta);
	}

	/**
	 * @param {WebpackOptions} options webpack options
	 * @param {Compilation} compilation the compilation
	 * @param {ResolverWithOptions} resolver the resolver
	 * @param {InputFileSystem} fs the file system
	 * @param {function(WebpackError=): void} callback callback function
	 * @returns {void}
	 */
	build(options, compilation, resolver, fs, callback) {
		const delegateData = /** @type {ManifestModuleData} */ (this.delegateData);
		this.buildMeta = { ...delegateData.buildMeta };
		this.buildInfo = {};
		this.dependencies.length = 0;
		this.delegatedSourceDependency = new DelegatedSourceDependency(
			this.sourceRequest
		);
		this.addDependency(this.delegatedSourceDependency);
		this.addDependency(
			new StaticExportsDependency(delegateData.exports || true, false)
		);
		callback();
	}

	/**
	 * @param {CodeGenerationContext} context context for code generation
	 * @returns {CodeGenerationResult} result
	 */
	codeGeneration({ runtimeTemplate, moduleGraph, chunkGraph }) {
		const dep = /** @type {DelegatedSourceDependency} */ (this.dependencies[0]);
		const sourceModule = moduleGraph.getModule(dep);
		let str;

		if (!sourceModule) {
			str = runtimeTemplate.throwMissingModuleErrorBlock({
				request: this.sourceRequest
			});
		} else {
			str = `module.exports = (${runtimeTemplate.moduleExports({
				module: sourceModule,
				chunkGraph,
				request: dep.request,
				runtimeRequirements: new Set()
			})})`;

			switch (this.delegationType) {
				case "require":
					str += `(${JSON.stringify(this.request)})`;
					break;
				case "object":
					str += `[${JSON.stringify(this.request)}]`;
					break;
			}

			str += ";";
		}

		const sources = new Map();
		if (this.useSourceMap || this.useSimpleSourceMap) {
			sources.set("javascript", new OriginalSource(str, this.identifier()));
		} else {
			sources.set("javascript", new RawSource(str));
		}

		return {
			sources,
			runtimeRequirements: RUNTIME_REQUIREMENTS
		};
	}

	/**
	 * @param {string=} type the source type for which the size should be estimated
	 * @returns {number} the estimated size of the module (must be non-zero)
	 */
	size(type) {
		return 42;
	}

	/**
	 * @param {Hash} hash the hash used to track dependencies
	 * @param {UpdateHashContext} context context
	 * @returns {void}
	 */
	updateHash(hash, context) {
		hash.update(this.delegationType);
		hash.update(JSON.stringify(this.request));
		super.updateHash(hash, context);
	}

	/**
	 * @param {ObjectSerializerContext} context context
	 */
	serialize(context) {
		const { write } = context;
		// constructor
		write(this.sourceRequest);
		write(this.delegateData);
		write(this.delegationType);
		write(this.userRequest);
		write(this.originalRequest);
		super.serialize(context);
	}

	/**
	 * @param {ObjectDeserializerContext} context context\
	 * @returns {DelegatedModule} DelegatedModule
	 */
	static deserialize(context) {
		const { read } = context;
		const obj = new DelegatedModule(
			read(), // sourceRequest
			read(), // delegateData
			read(), // delegationType
			read(), // userRequest
			read() // originalRequest
		);
		obj.deserialize(context);
		return obj;
	}

	/**
	 * Assuming this module is in the cache. Update the (cached) module with
	 * the fresh module from the factory. Usually updates internal references
	 * and properties.
	 * @param {Module} module fresh module
	 * @returns {void}
	 */
	updateCacheModule(module) {
		super.updateCacheModule(module);
		const m = /** @type {DelegatedModule} */ (module);
		this.delegationType = m.delegationType;
		this.userRequest = m.userRequest;
		this.originalRequest = m.originalRequest;
		this.delegateData = m.delegateData;
	}

	/**
	 * Assuming this module is in the cache. Remove internal references to allow freeing some memory.
	 */
	cleanupForCache() {
		super.cleanupForCache();
		this.delegateData = undefined;
	}
}

makeSerializable(DelegatedModule, "webpack/lib/DelegatedModule");

module.exports = DelegatedModule;


code:
/*
	MIT License http://www.opensource.org/licenses/mit-license.php
	Author Tobias Koppers @sokra
*/

"use strict";

const DelegatedModule = require("./DelegatedModule");

/** @typedef {import("./NormalModuleFactory")} NormalModuleFactory */

// options.source
// options.type
// options.context
// options.scope
// options.content
// options.associatedObjectForCache
class DelegatedModuleFactoryPlugin {
	constructor(options) {
		this.options = options;
		options.type = options.type || "require";
		options.extensions = options.extensions || ["", ".js", ".json", ".wasm"];
	}

	/**
	 * @param {NormalModuleFactory} normalModuleFactory the normal module factory
	 * @returns {void}
	 */
	apply(normalModuleFactory) {
		const scope = this.options.scope;
		if (scope) {
			normalModuleFactory.hooks.factorize.tapAsync(
				"DelegatedModuleFactoryPlugin",
				(data, callback) => {
					const [dependency] = data.dependencies;
					const { request } = dependency;
					if (request && request.startsWith(`${scope}/`)) {
						const innerRequest = "." + request.slice(scope.length);
						let resolved;
						if (innerRequest in this.options.content) {
							resolved = this.options.content[innerRequest];
							return callback(
								null,
								new DelegatedModule(
									this.options.source,
									resolved,
									this.options.type,
									innerRequest,
									request
								)
							);
						}
						for (let i = 0; i < this.options.extensions.length; i++) {
							const extension = this.options.extensions[i];
							const requestPlusExt = innerRequest + extension;
							if (requestPlusExt in this.options.content) {
								resolved = this.options.content[requestPlusExt];
								return callback(
									null,
									new DelegatedModule(
										this.options.source,
										resolved,
										this.options.type,
										requestPlusExt,
										request + extension
									)
								);
							}
						}
					}
					return callback();
				}
			);
		} else {
			normalModuleFactory.hooks.module.tap(
				"DelegatedModuleFactoryPlugin",
				module => {
					const request = module.libIdent(this.options);
					if (request) {
						if (request in this.options.content) {
							const resolved = this.options.content[request];
							return new DelegatedModule(
								this.options.source,
								resolved,
								this.options.type,
								request,
								module
							);
						}
					}
					return module;
				}
			);
		}
	}
}
module.exports = DelegatedModuleFactoryPlugin;


code:
/*
	MIT License http://www.opensource.org/licenses/mit-license.php
	Author Tobias Koppers @sokra
*/

"use strict";

const DelegatedModuleFactoryPlugin = require("./DelegatedModuleFactoryPlugin");
const DelegatedSourceDependency = require("./dependencies/DelegatedSourceDependency");

/** @typedef {import("./Compiler")} Compiler */

class DelegatedPlugin {
	constructor(options) {
		this.options = options;
	}

	/**
	 * Apply the plugin
	 * @param {Compiler} compiler the compiler instance
	 * @returns {void}
	 */
	apply(compiler) {
		compiler.hooks.compilation.tap(
			"DelegatedPlugin",
			(compilation, { normalModuleFactory }) => {
				compilation.dependencyFactories.set(
					DelegatedSourceDependency,
					normalModuleFactory
				);
			}
		);

		compiler.hooks.compile.tap("DelegatedPlugin", ({ normalModuleFactory }) => {
			new DelegatedModuleFactoryPlugin({
				associatedObjectForCache: compiler.root,
				...this.options
			}).apply(normalModuleFactory);
		});
	}
}

module.exports = DelegatedPlugin;


code:
/*
	MIT License http://www.opensource.org/licenses/mit-license.php
	Author Tobias Koppers @sokra
*/

"use strict";

const makeSerializable = require("./util/makeSerializable");

/** @typedef {import("./AsyncDependenciesBlock")} AsyncDependenciesBlock */
/** @typedef {import("./ChunkGraph")} ChunkGraph */
/** @typedef {import("./ChunkGroup")} ChunkGroup */
/** @typedef {import("./Dependency")} Dependency */
/** @typedef {import("./Dependency").UpdateHashContext} UpdateHashContext */
/** @typedef {import("./serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */
/** @typedef {import("./serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */
/** @typedef {import("./util/Hash")} Hash */

/** @typedef {(d: Dependency) => boolean} DependencyFilterFunction */

/**
 * DependenciesBlock is the base class for all Module classes in webpack. It describes a
 * "block" of dependencies which are pointers to other DependenciesBlock instances. For example
 * when a Module has a CommonJs require statement, the DependencyBlock for the CommonJs module
 * would be added as a dependency to the Module. DependenciesBlock is inherited by two types of classes:
 * Module subclasses and AsyncDependenciesBlock subclasses. The only difference between the two is that
 * AsyncDependenciesBlock subclasses are used for code-splitting (async boundary) and Module subclasses are not.
 */
class DependenciesBlock {
	constructor() {
		/** @type {Dependency[]} */
		this.dependencies = [];
		/** @type {AsyncDependenciesBlock[]} */
		this.blocks = [];
		/** @type {DependenciesBlock | undefined} */
		this.parent = undefined;
	}

	getRootBlock() {
		/** @type {DependenciesBlock} */
		let current = this;
		while (current.parent) current = current.parent;
		return current;
	}

	/**
	 * Adds a DependencyBlock to DependencyBlock relationship.
	 * This is used for when a Module has a AsyncDependencyBlock tie (for code-splitting)
	 *
	 * @param {AsyncDependenciesBlock} block block being added
	 * @returns {void}
	 */
	addBlock(block) {
		this.blocks.push(block);
		block.parent = this;
	}

	/**
	 * @param {Dependency} dependency dependency being tied to block.
	 * This is an "edge" pointing to another "node" on module graph.
	 * @returns {void}
	 */
	addDependency(dependency) {
		this.dependencies.push(dependency);
	}

	/**
	 * @param {Dependency} dependency dependency being removed
	 * @returns {void}
	 */
	removeDependency(dependency) {
		const idx = this.dependencies.indexOf(dependency);
		if (idx >= 0) {
			this.dependencies.splice(idx, 1);
		}
	}

	/**
	 * Removes all dependencies and blocks
	 * @returns {void}
	 */
	clearDependenciesAndBlocks() {
		this.dependencies.length = 0;
		this.blocks.length = 0;
	}

	/**
	 * @param {Hash} hash the hash used to track dependencies
	 * @param {UpdateHashContext} context context
	 * @returns {void}
	 */
	updateHash(hash, context) {
		for (const dep of this.dependencies) {
			dep.updateHash(hash, context);
		}
		for (const block of this.blocks) {
			block.updateHash(hash, context);
		}
	}

	/**
	 * @param {ObjectSerializerContext} context context
	 */
	serialize({ write }) {
		write(this.dependencies);
		write(this.blocks);
	}

	/**
	 * @param {ObjectDeserializerContext} context context
	 */
	deserialize({ read }) {
		this.dependencies = read();
		this.blocks = read();
		for (const block of this.blocks) {
			block.parent = this;
		}
	}
}

makeSerializable(DependenciesBlock, "webpack/lib/DependenciesBlock");

module.exports = DependenciesBlock;